11package ubic .gemma .core .datastructure .matrix ;
22
3+ import ubic .gemma .core .util .ListUtils ;
34import ubic .gemma .model .common .description .Characteristic ;
45import ubic .gemma .model .expression .bioAssay .BioAssay ;
56import ubic .gemma .model .expression .bioAssayData .CellLevelCharacteristics ;
1112import ubic .gemma .model .util .SparseRangeArrayList ;
1213
1314import javax .annotation .Nullable ;
14- import java .util .ArrayList ;
15- import java .util .Collections ;
16- import java .util .List ;
15+ import java .util .*;
1716
1817public class SingleCellDesignMatrixImpl implements SingleCellDesignMatrix {
1918
19+ // rows
2020 private final SparseRangeArrayList <BioAssay > assays ;
2121 private final List <String > cellIds ;
22+ private final Map <BioAssay , Map <String , Integer >> index ;
23+
24+ // columns
2225 private final List <ExperimentalFactor > factors ;
26+ private final Map <ExperimentalFactor , Integer > factorsIndex ;
27+
28+ /**
29+ * This is technically a matrix, but using {@link List} allows for sparse range array to be used for sample-level
30+ * factors.
31+ * <p>
32+ * Also, this is transposed w.r.t. to rows/columns that the interface requires. This is due to the fact that
33+ * sparsity is better handled along factors
34+ */
35+ private final List <List <FactorValue >> factorValues ;
2336
2437 public SingleCellDesignMatrixImpl ( SingleCellDimension dimension , List <BioAssay > assays , List <ExperimentalFactor > factors , List <CellLevelCharacteristics > cellLevelCharacteristics ) {
2538 int [] bioAssayOffsets = new int [assays .size ()];
2639 int k = 0 ;
2740 List <String > cellIdsL = new ArrayList <>( dimension .getNumberOfCells () );
41+ Map <BioAssay , Map <String , Integer >> index = new HashMap <>( assays .size () );
2842 for ( int i = 0 ; i < assays .size (); i ++ ) {
2943 BioAssay assay = assays .get ( i );
3044 int sampleIndex = dimension .getBioAssays ().indexOf ( assay );
@@ -34,17 +48,26 @@ public SingleCellDesignMatrixImpl( SingleCellDimension dimension, List<BioAssay>
3448 List <String > sampleCellIds = dimension .getCellIdsBySample ( sampleIndex );
3549 bioAssayOffsets [i ] = k ;
3650 cellIdsL .addAll ( sampleCellIds );
51+ Map <String , Integer > cellid2pos = new HashMap <>();
52+ for ( int j = 0 ; j < sampleCellIds .size (); j ++ ) {
53+ cellid2pos .put ( sampleCellIds .get ( j ), k + j );
54+ }
55+ index .put ( assay , cellid2pos );
3756 k += sampleCellIds .size ();
3857 }
3958 this .assays = new SparseRangeArrayList <>( assays , bioAssayOffsets , k );
4059 this .cellIds = cellIdsL ;
60+ this .index = index ;
4161 ArrayList <ExperimentalFactor > factorsL = new ArrayList <>( factors .size () + cellLevelCharacteristics .size () );
4262 factorsL .addAll ( factors );
4363 for ( CellLevelCharacteristics clc : cellLevelCharacteristics ) {
4464 ExperimentalFactor factor = createFactorFromCellLevelCharacteristics ( clc );
4565 factorsL .add ( factor );
4666 }
4767 this .factors = Collections .unmodifiableList ( factorsL );
68+ this .factorsIndex = Collections .unmodifiableMap ( ListUtils .indexOfElements ( factorsL ) );
69+ // TODO: fill the matrix
70+ this .factorValues = new ArrayList <>( factors .size () );
4871 }
4972
5073 @ Override
@@ -69,13 +92,17 @@ public int columns() {
6992
7093 @ Override
7194 public List <FactorValue > getColumn ( int column ) {
72- return new FactorValue [ 0 ] ;
95+ return factorValues . get ( column ) ;
7396 }
7497
7598 @ Nullable
7699 @ Override
77100 public List <FactorValue > getColumn ( ExperimentalFactor factor ) {
78- return new FactorValue [0 ];
101+ int index = factors .indexOf ( factor );
102+ if ( index == -1 ) {
103+ return null ;
104+ }
105+ return getColumn ( index );
79106 }
80107
81108 @ Override
@@ -91,22 +118,30 @@ public ExperimentalFactor getFactorForColumn( int column ) {
91118 @ Nullable
92119 @ Override
93120 public List <FactorValue > getRow ( BioAssay bioAssay , String cellId ) {
94- return new FactorValue [0 ];
121+ int row = getRowIndex ( bioAssay , cellId );
122+ if ( row == -1 ) {
123+ return null ;
124+ }
125+ return getRow ( row );
95126 }
96127
97128 @ Override
98129 public List <FactorValue > getRow ( int row ) {
99- return new FactorValue [0 ];
130+ List <FactorValue > fvs = new ArrayList <>( factors .size () );
131+ for ( int i = 0 ; i < factors .size (); i ++ ) {
132+ fvs .add ( factorValues .get ( i ).get ( row ) );
133+ }
134+ return fvs ;
100135 }
101136
102137 @ Override
103138 public int rows () {
104- return 0 ;
139+ return cellIds . size () ;
105140 }
106141
107142 @ Override
108143 public BioAssay getBioAssayForRow ( int row ) {
109- return null ;
144+ return assays . get ( row ) ;
110145 }
111146
112147 @ Override
@@ -116,12 +151,16 @@ public BioMaterial getBioMaterialForRow( int row ) {
116151
117152 @ Override
118153 public String getCellIdForRow ( int row ) {
119- return "" ;
154+ return cellIds . get ( row ) ;
120155 }
121156
122157 @ Override
123158 public int getRowIndex ( BioAssay bioAssay , String cellId ) {
124- return 0 ;
159+ Map <String , Integer > cell2pos = index .get ( bioAssay );
160+ if ( cell2pos == null ) {
161+ return -1 ;
162+ }
163+ return cell2pos .getOrDefault ( cellId , -1 );
125164 }
126165
127166 private ExperimentalFactor createFactorFromCellLevelCharacteristics ( CellLevelCharacteristics characteristics ) {
0 commit comments