Skip to content

Commit

Permalink
Update well paths to use row and column names instead of indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
melissalinkert committed Dec 9, 2021
1 parent 16ef0bb commit 4722e96
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 49 deletions.
22 changes: 11 additions & 11 deletions src/main/java/com/glencoesoftware/bioformats2raw/Converter.java
Original file line number Diff line number Diff line change
Expand Up @@ -627,7 +627,7 @@ public void convert()
}

if (!noHCS) {
scaleFormatString = "%d/%d/%d/%d";
scaleFormatString = "%s/%s/%d/%d";
}

for (Integer index : seriesList) {
Expand Down Expand Up @@ -711,8 +711,8 @@ private Object[] getScaleFormatStringArgs(
List<Object> args = new ArrayList<Object>();
if (!noHCS) {
HCSIndex index = hcsIndexes.get(series);
args.add(index.getWellRowIndex());
args.add(index.getWellColumnIndex());
args.add(index.getRowPath());
args.add(index.getColumnPath());
args.add(index.getFieldIndex());
args.add(resolution);
}
Expand Down Expand Up @@ -1343,7 +1343,7 @@ private void saveHCSMetadata(IMetadata meta) throws IOException {
}
for (int r=0; r<plateRows.getValue(); r++) {
Map<String, Object> row = new HashMap<String, Object>();
String rowName = String.valueOf(r);
String rowName = HCSIndex.getRowName(r);
row.put("name", rowName);
rows.add(row);
}
Expand All @@ -1358,7 +1358,7 @@ private void saveHCSMetadata(IMetadata meta) throws IOException {
}
for (int c=0; c<plateColumns.getValue(); c++) {
Map<String, Object> column = new HashMap<String, Object>();
String columnName = String.valueOf(c);
String columnName = HCSIndex.getColumnName(c);
column.put("name", columnName);
columns.add(column);
}
Expand Down Expand Up @@ -1413,33 +1413,33 @@ private void saveHCSMetadata(IMetadata meta) throws IOException {

// make sure the row/column indexes are added to the plate attributes
// this is necessary when Plate.Rows or Plate.Columns is not set
int column = index.getWellColumnIndex();
int row = index.getWellRowIndex();
String column = index.getColumnPath();
String row = index.getRowPath();

int columnIndex = -1;
for (int c=0; c<columns.size(); c++) {
if (columns.get(c).get("name").equals(String.valueOf(column))) {
if (columns.get(c).get("name").equals(column)) {
columnIndex = c;
break;
}
}
if (columnIndex < 0) {
Map<String, Object> colMap = new HashMap<String, Object>();
colMap.put("name", String.valueOf(column));
colMap.put("name", column);
columnIndex = columns.size();
columns.add(colMap);
}

int rowIndex = -1;
for (int r=0; r<rows.size(); r++) {
if (rows.get(r).get("name").equals(String.valueOf(row))) {
if (rows.get(r).get("name").equals(row)) {
rowIndex = r;
break;
}
}
if (rowIndex < 0) {
Map<String, Object> rowMap = new HashMap<String, Object>();
rowMap.put("name", String.valueOf(row));
rowMap.put("name", row);
rowIndex = rows.size();
rows.add(rowMap);
}
Expand Down
33 changes: 31 additions & 2 deletions src/main/java/com/glencoesoftware/bioformats2raw/HCSIndex.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,14 @@ public int getFieldIndex() {
* @return row path relative to the plate group
*/
public String getRowPath() {
return String.format("%d", getWellRowIndex());
return getRowName(getWellRowIndex());
}

/**
* @return column path relative to the row group
*/
public String getColumnPath() {
return String.format("%d", getWellColumnIndex());
return getColumnName(getWellColumnIndex());
}

/**
Expand All @@ -125,4 +125,33 @@ public String toString() {
getFieldIndex());
}

/**
* Get a row name for the specified 0-based row index.
* The name is a single upper-case letter starting with A
* if the row index is less than 26, and two upper-case letters
* starting with AA for indexes greater than or equal to 26.
*
* @param rowIndex row index
* @return row name
*/
public static String getRowName(int rowIndex) {
String name = String.valueOf((char) ('A' + (rowIndex % 26)));
if (rowIndex >= 26) {
name = (char) ('A' + ((rowIndex / 26) - 1)) + name;
}
return name;
}

/**
* Get a column name for the specified 0-based column index.
* The name is a string representation of the corresponding
* 1-based index.
*
* @param colIndex column index
* @return column name
*/
public static String getColumnName(int colIndex) {
return String.format("%d", colIndex + 1);
}

}
68 changes: 32 additions & 36 deletions src/test/java/com/glencoesoftware/bioformats2raw/test/ZarrTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -824,8 +824,8 @@ public void testHCSMetadata() throws Exception {
int colCount = 3;
int fieldCount = 2;
Map<String, List<String>> plateMap = new HashMap<String, List<String>>();
plateMap.put("0", Arrays.asList("0", "1", "2"));
plateMap.put("1", Arrays.asList("0", "1", "2"));
plateMap.put("A", Arrays.asList("1", "2", "3"));
plateMap.put("B", Arrays.asList("1", "2", "3"));
checkPlateGroupLayout(output, rowCount, colCount,
plateMap, fieldCount, 512, 512);

Expand All @@ -846,14 +846,16 @@ public void testHCSMetadata() throws Exception {
assertEquals(1, acquisitions.size());
assertEquals("0", acquisitions.get(0).get("id"));

checkDimension(rows, rowCount);
checkDimension(columns, colCount);
assertEquals(rows.size(), rowCount);
assertEquals(columns.size(), colCount);

assertEquals(rows.size() * columns.size(), wells.size());
for (int row=0; row<rows.size(); row++) {
for (int col=0; col<columns.size(); col++) {
int well = row * columns.size() + col;
assertEquals(row + "/" + col, wells.get(well).get("path"));
String rowName = rows.get(row).get("name").toString();
String colName = columns.get(col).get("name").toString();
assertEquals(rowName + "/" + colName, wells.get(well).get("path"));
}
}

Expand Down Expand Up @@ -890,8 +892,8 @@ public void testHCSMetadataNoAcquisitions() throws Exception {

// Only two rows are filled out with one column each (two Wells total)
Map<String, List<String>> plateMap = new HashMap<String, List<String>>();
plateMap.put("0", Arrays.asList("0"));
plateMap.put("1", Arrays.asList("0"));
plateMap.put("A", Arrays.asList("1"));
plateMap.put("B", Arrays.asList("1"));
checkPlateGroupLayout(output, rowCount, colCount,
plateMap, fieldCount, 2, 2);

Expand All @@ -909,16 +911,18 @@ public void testHCSMetadataNoAcquisitions() throws Exception {

assertFalse(plate.containsKey("acquisitions"));

checkDimension(rows, rowCount);
checkDimension(columns, colCount);
assertEquals(rows.size(), rowCount);
assertEquals(columns.size(), colCount);

assertEquals(2, wells.size());
for (Map<String, Object> well : wells) {
int row = ((Number) well.get("rowIndex")).intValue();
int col = ((Number) well.get("columnIndex")).intValue();
String rowName = rows.get(row).get("name").toString();
String colName = columns.get(col).get("name").toString();

String wellPath = well.get("path").toString();
assertEquals(row + "/" + col, wellPath);
assertEquals(rowName + "/" + colName, wellPath);

ZarrGroup wellGroup = ZarrGroup.open(output.resolve(wellPath));
checkWell(wellGroup, fieldCount, null);
Expand All @@ -944,7 +948,7 @@ public void testSingleWell() throws IOException {
int fieldCount = 1;

Map<String, List<String>> plateMap = new HashMap<String, List<String>>();
plateMap.put("4", Arrays.asList("5"));
plateMap.put("E", Arrays.asList("6"));

checkPlateGroupLayout(output, rowCount, colCount,
plateMap, fieldCount, 2, 2);
Expand All @@ -966,13 +970,13 @@ public void testSingleWell() throws IOException {
assertEquals(1, acquisitions.size());
assertEquals("0", acquisitions.get(0).get("id"));

checkDimension(rows, rowCount);
checkDimension(columns, colCount);
assertEquals(rows.size(), rowCount);
assertEquals(columns.size(), colCount);

assertEquals(1, wells.size());
Map<String, Object> well = wells.get(0);
String wellPath = (String) well.get("path");
assertEquals("4/5", wellPath);
assertEquals("E/6", wellPath);
assertEquals(4, ((Number) well.get("rowIndex")).intValue());
assertEquals(5, ((Number) well.get("columnIndex")).intValue());

Expand Down Expand Up @@ -1004,8 +1008,8 @@ public void testTwoWells(String resourceName) throws IOException {
int fieldCount = 1;

Map<String, List<String>> plateMap = new HashMap<String, List<String>>();
plateMap.put("2", Arrays.asList("11"));
plateMap.put("7", Arrays.asList("1"));
plateMap.put("C", Arrays.asList("12"));
plateMap.put("H", Arrays.asList("2"));
checkPlateGroupLayout(output, rowCount, colCount,
plateMap, fieldCount, 2, 2);

Expand All @@ -1026,21 +1030,21 @@ public void testTwoWells(String resourceName) throws IOException {
assertEquals(1, acquisitions.size());
assertEquals("0", acquisitions.get(0).get("id"));

checkDimension(rows, rowCount);
checkDimension(columns, colCount);
assertEquals(rows.size(), rowCount);
assertEquals(columns.size(), colCount);

assertEquals(2, wells.size());
Map<String, Object> well = wells.get(0);
String wellPath = (String) well.get("path");
assertEquals("2/11", wellPath);
assertEquals("C/12", wellPath);
assertEquals(2, ((Number) well.get("rowIndex")).intValue());
assertEquals(11, ((Number) well.get("columnIndex")).intValue());
ZarrGroup wellGroup = ZarrGroup.open(output.resolve(wellPath));
checkWell(wellGroup, fieldCount, 0);

well = wells.get(1);
wellPath = (String) well.get("path");
assertEquals("7/1", wellPath);
assertEquals("H/2", wellPath);
assertEquals(7, ((Number) well.get("rowIndex")).intValue());
assertEquals(1, ((Number) well.get("columnIndex")).intValue());
wellGroup = ZarrGroup.open(output.resolve(wellPath));
Expand All @@ -1062,8 +1066,8 @@ public void testOnePlateRow() throws IOException {
int fieldCount = 1;

Map<String, List<String>> plateMap = new HashMap<String, List<String>>();
plateMap.put("5", Arrays.asList(
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"));
plateMap.put("F", Arrays.asList(
"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"));
checkPlateGroupLayout(output, rowCount, colCount,
plateMap, fieldCount, 2, 2);

Expand All @@ -1084,14 +1088,15 @@ public void testOnePlateRow() throws IOException {
assertEquals(1, acquisitions.size());
assertEquals("0", acquisitions.get(0).get("id"));

checkDimension(rows, rowCount);
checkDimension(columns, colCount);
assertEquals(rows.size(), rowCount);
assertEquals(columns.size(), colCount);

assertEquals(colCount, wells.size());
for (int col=0; col<wells.size(); col++) {
Map<String, Object> well = wells.get(col);
String wellPath = (String) well.get("path");
assertEquals("5/" + col, wellPath);
String colName = columns.get(col).get("name").toString();
assertEquals("F/" + colName, wellPath);
assertEquals(5, ((Number) well.get("rowIndex")).intValue());
assertEquals(col, ((Number) well.get("columnIndex")).intValue());
ZarrGroup wellGroup = ZarrGroup.open(output.resolve(wellPath));
Expand Down Expand Up @@ -1314,7 +1319,7 @@ private void checkPlateGroupLayout(Path root, int rowCount, int colCount,
// if there are any wells with data in the row, the row path must exist
// if there are no wells with data in the row, the row path cannot exist
for (int row=0; row<rowCount; row++) {
String rowString = Integer.toString(row);
String rowString = String.format("%s", 'A' + row);
if (validPaths.containsKey(rowString)) {
Path rowPath = root.resolve(rowString);
// .zgroup (Row) and columns
Expand All @@ -1325,7 +1330,7 @@ private void checkPlateGroupLayout(Path root, int rowCount, int colCount,
// if this row/column is a well with data, the column path must exist
// otherwise, the column path cannot exist
for (int col=0; col<colCount; col++) {
String colString = Integer.toString(col);
String colString = Integer.toString(col + 1);
if (validColumns.contains(colString)) {
Path colPath = rowPath.resolve(colString);
ZarrGroup colGroup = ZarrGroup.open(colPath);
Expand All @@ -1349,15 +1354,6 @@ private void checkPlateGroupLayout(Path root, int rowCount, int colCount,
}
}

private void checkDimension(List<Map<String, Object>> dims, int dimCount)
throws IOException
{
assertEquals(dimCount, dims.size());
for (int dim=0; dim<dims.size(); dim++) {
assertEquals(String.valueOf(dim), dims.get(dim).get("name"));
}
}

private void checkWell(
ZarrGroup wellGroup, int fieldCount, Integer acquisition)
throws IOException
Expand Down

0 comments on commit 4722e96

Please sign in to comment.