diff --git a/project-management/src/main/java/life/qbic/projectmanagement/application/measurement/validation/MeasurementProteomicsValidator.java b/project-management/src/main/java/life/qbic/projectmanagement/application/measurement/validation/MeasurementProteomicsValidator.java index c83caec57..696054645 100644 --- a/project-management/src/main/java/life/qbic/projectmanagement/application/measurement/validation/MeasurementProteomicsValidator.java +++ b/project-management/src/main/java/life/qbic/projectmanagement/application/measurement/validation/MeasurementProteomicsValidator.java @@ -180,6 +180,10 @@ public static boolean isDigestionMethod(String input) { public String getName() { return name; } + + public static List getOptions() { + return Arrays.stream(values()).map(DigestionMethod::getName).toList(); + } } private class ValidationPolicy { diff --git a/user-interface/src/main/java/life/qbic/datamanager/views/projects/project/measurements/download/NGSMeasurementContentProvider.java b/user-interface/src/main/java/life/qbic/datamanager/views/projects/project/measurements/download/NGSMeasurementContentProvider.java index 033582092..540b2cfac 100644 --- a/user-interface/src/main/java/life/qbic/datamanager/views/projects/project/measurements/download/NGSMeasurementContentProvider.java +++ b/user-interface/src/main/java/life/qbic/datamanager/views/projects/project/measurements/download/NGSMeasurementContentProvider.java @@ -8,7 +8,6 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Arrays; -import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Optional; @@ -98,27 +97,27 @@ private static void setCellStyle(Cell cell, boolean isReadOnly) { } private static void writeMeasurementIntoRow(NGSMeasurementEntry ngsMeasurementEntry, Row entry) { - var measureCol = getOrCreateCell(entry, NGSMeasurementColumns.MEASUREMENTCODE.columnIndex()); + var measureCol = getOrCreateCell(entry, NGSMeasurementColumns.MEASUREMENT_ID.columnIndex()); measureCol.setCellValue(ngsMeasurementEntry.measurementCode()); - setCellStyle(measureCol, NGSMeasurementColumns.MEASUREMENTCODE.readOnly()); + setCellStyle(measureCol, NGSMeasurementColumns.MEASUREMENT_ID.readOnly()); - var sampleIdCol = getOrCreateCell(entry, NGSMeasurementColumns.SAMPLEID.columnIndex()); + var sampleIdCol = getOrCreateCell(entry, NGSMeasurementColumns.SAMPLE_ID.columnIndex()); sampleIdCol.setCellValue(ngsMeasurementEntry.sampleInformation().sampleId()); - setCellStyle(sampleIdCol, NGSMeasurementColumns.SAMPLEID.readOnly()); + setCellStyle(sampleIdCol, NGSMeasurementColumns.SAMPLE_ID.readOnly()); - var sampleNameCol = getOrCreateCell(entry, NGSMeasurementColumns.SAMPLENAME.columnIndex()); + var sampleNameCol = getOrCreateCell(entry, NGSMeasurementColumns.SAMPLE_NAME.columnIndex()); sampleNameCol.setCellValue(ngsMeasurementEntry.sampleInformation().sampleName()); - setCellStyle(sampleNameCol, NGSMeasurementColumns.SAMPLENAME.readOnly()); + setCellStyle(sampleNameCol, NGSMeasurementColumns.SAMPLE_NAME.readOnly()); - var orgIdCol = getOrCreateCell(entry, NGSMeasurementColumns.ORGANISATIONID.columnIndex()); + var orgIdCol = getOrCreateCell(entry, NGSMeasurementColumns.ORGANISATION_ID.columnIndex()); orgIdCol.setCellValue(ngsMeasurementEntry.organisationId()); - setCellStyle(orgIdCol, NGSMeasurementColumns.ORGANISATIONID.readOnly()); + setCellStyle(orgIdCol, NGSMeasurementColumns.ORGANISATION_ID.readOnly()); var organisationNameCol = getOrCreateCell(entry, - NGSMeasurementColumns.ORGANISATIONNAME.columnIndex()); + NGSMeasurementColumns.ORGANISATION_NAME.columnIndex()); organisationNameCol.setCellValue(ngsMeasurementEntry.organisationName()); - setCellStyle(organisationNameCol, NGSMeasurementColumns.ORGANISATIONNAME.readOnly()); + setCellStyle(organisationNameCol, NGSMeasurementColumns.ORGANISATION_NAME.readOnly()); var facilityCol = getOrCreateCell(entry, NGSMeasurementColumns.FACILITY.columnIndex()); facilityCol.setCellValue(ngsMeasurementEntry.facility()); @@ -128,38 +127,39 @@ private static void writeMeasurementIntoRow(NGSMeasurementEntry ngsMeasurementEn setCellStyle(instrumentCol, NGSMeasurementColumns.INSTRUMENT.readOnly()); var instrumentNameCol = getOrCreateCell(entry, - NGSMeasurementColumns.INSTRUMENTNAME.columnIndex()); + NGSMeasurementColumns.INSTRUMENT_NAME.columnIndex()); instrumentNameCol.setCellValue(ngsMeasurementEntry.instrumentName()); - setCellStyle(instrumentNameCol, NGSMeasurementColumns.INSTRUMENTNAME.readOnly()); + setCellStyle(instrumentNameCol, NGSMeasurementColumns.INSTRUMENT_NAME.readOnly()); var readTypeCol = getOrCreateCell(entry, - NGSMeasurementColumns.SEQUENCINGREADTYPE.columnIndex()); + NGSMeasurementColumns.SEQUENCING_READ_TYPE.columnIndex()); readTypeCol.setCellValue(ngsMeasurementEntry.readType()); - setCellStyle(readTypeCol, NGSMeasurementColumns.SEQUENCINGREADTYPE.readOnly()); + setCellStyle(readTypeCol, NGSMeasurementColumns.SEQUENCING_READ_TYPE.readOnly()); - var libraryKitCol = getOrCreateCell(entry, NGSMeasurementColumns.LIBRARYKIT.columnIndex()); + var libraryKitCol = getOrCreateCell(entry, NGSMeasurementColumns.LIBRARY_KIT.columnIndex()); libraryKitCol.setCellValue(ngsMeasurementEntry.libraryKit()); - setCellStyle(libraryKitCol, NGSMeasurementColumns.LIBRARYKIT.readOnly()); + setCellStyle(libraryKitCol, NGSMeasurementColumns.LIBRARY_KIT.readOnly()); - var flowCellCol = getOrCreateCell(entry, NGSMeasurementColumns.FLOWCELL.columnIndex()); + var flowCellCol = getOrCreateCell(entry, NGSMeasurementColumns.FLOW_CELL.columnIndex()); flowCellCol.setCellValue(ngsMeasurementEntry.flowCell()); - setCellStyle(flowCellCol, NGSMeasurementColumns.FLOWCELL.readOnly()); + setCellStyle(flowCellCol, NGSMeasurementColumns.FLOW_CELL.readOnly()); - var runProtocolCol = getOrCreateCell(entry, NGSMeasurementColumns.RUNPROTOCOL.columnIndex()); + var runProtocolCol = getOrCreateCell(entry, + NGSMeasurementColumns.SEQUENCING_RUN_PROTOCOL.columnIndex()); runProtocolCol.setCellValue(ngsMeasurementEntry.runProtocol()); - setCellStyle(runProtocolCol, NGSMeasurementColumns.RUNPROTOCOL.readOnly()); + setCellStyle(runProtocolCol, NGSMeasurementColumns.SEQUENCING_RUN_PROTOCOL.readOnly()); - var poolGroupCol = getOrCreateCell(entry, NGSMeasurementColumns.POOLGROUP.columnIndex()); + var poolGroupCol = getOrCreateCell(entry, NGSMeasurementColumns.POOL_GROUP.columnIndex()); poolGroupCol.setCellValue(ngsMeasurementEntry.samplePoolGroup()); - setCellStyle(poolGroupCol, NGSMeasurementColumns.POOLGROUP.readOnly()); + setCellStyle(poolGroupCol, NGSMeasurementColumns.POOL_GROUP.readOnly()); - var indexI7Col = getOrCreateCell(entry, NGSMeasurementColumns.INDEXI7.columnIndex()); + var indexI7Col = getOrCreateCell(entry, NGSMeasurementColumns.INDEX_I7.columnIndex()); indexI7Col.setCellValue(ngsMeasurementEntry.indexI7()); - setCellStyle(indexI7Col, NGSMeasurementColumns.INDEXI7.readOnly()); + setCellStyle(indexI7Col, NGSMeasurementColumns.INDEX_I7.readOnly()); - var indexI5Col = getOrCreateCell(entry, NGSMeasurementColumns.INDEXI5.columnIndex()); + var indexI5Col = getOrCreateCell(entry, NGSMeasurementColumns.INDEX_I5.columnIndex()); indexI5Col.setCellValue(ngsMeasurementEntry.indexI5()); - setCellStyle(indexI5Col, NGSMeasurementColumns.INDEXI5.readOnly()); + setCellStyle(indexI5Col, NGSMeasurementColumns.INDEX_I5.readOnly()); var commentCol = getOrCreateCell(entry, NGSMeasurementColumns.COMMENT.columnIndex()); commentCol.setCellValue(ngsMeasurementEntry.comment()); @@ -240,9 +240,9 @@ public byte[] getContent() { assert generatedRowCount == measurements.size() : "all measurements have a corresponding row"; XLSXTemplateHelper.addDataValidation(sheet, - NGSMeasurementColumns.SEQUENCINGREADTYPE.columnIndex(), + NGSMeasurementColumns.SEQUENCING_READ_TYPE.columnIndex(), startIndex, - NGSMeasurementColumns.SEQUENCINGREADTYPE.columnIndex(), + NGSMeasurementColumns.SEQUENCING_READ_TYPE.columnIndex(), DEFAULT_GENERATED_ROW_COUNT - 1, sequencingReadTypeArea); @@ -289,36 +289,36 @@ public String getFileName() { */ enum NGSMeasurementColumns { - MEASUREMENTCODE("Measurement ID", 0, + MEASUREMENT_ID("Measurement ID", 0, true), - SAMPLEID("QBiC Sample Id", 1, + SAMPLE_ID("QBiC Sample Id", 1, true), - SAMPLENAME( + SAMPLE_NAME( "Sample Name", 2, true), - POOLGROUP("Sample Pool Group", 3, + POOL_GROUP("Sample Pool Group", 3, true), - ORGANISATIONID("Organisation ID", 4, + ORGANISATION_ID("Organisation ID", 4, false), - ORGANISATIONNAME("Organisation Name", 5, + ORGANISATION_NAME("Organisation Name", 5, true), FACILITY("Facility", 6, false), INSTRUMENT("Instrument", 7, false), - INSTRUMENTNAME("Instrument Name", 8, + INSTRUMENT_NAME("Instrument Name", 8, true), - SEQUENCINGREADTYPE("Sequencing Read Type", 9, - false, List.of("single-end", "paired-end")), - LIBRARYKIT("Library Kit", 10, + SEQUENCING_READ_TYPE("Sequencing Read Type", 9, false), - FLOWCELL("Flow Cell", 11, + LIBRARY_KIT("Library Kit", 10, false), - RUNPROTOCOL("Sequencing Run Protocol", 12, + FLOW_CELL("Flow Cell", 11, false), - INDEXI7("Index i7", 13, + SEQUENCING_RUN_PROTOCOL("Sequencing Run Protocol", 12, false), - INDEXI5("Index i5", 14, + INDEX_I7("Index i7", 13, + false), + INDEX_I5("Index i5", 14, false), COMMENT("Comment", 15, false), @@ -327,7 +327,6 @@ enum NGSMeasurementColumns { private final String headerName; private final int columnIndex; private final boolean readOnly; - private final List allowedValues; static int maxColumnIndex() { return Arrays.stream(values()) @@ -339,23 +338,11 @@ static int maxColumnIndex() { * @param headerName the name in the header * @param columnIndex the index of the column this property is in * @param readOnly is the property read only - * @param allowedValues a list of allowed values; null if not applicable */ - NGSMeasurementColumns(String headerName, int columnIndex, boolean readOnly, - List allowedValues) { + NGSMeasurementColumns(String headerName, int columnIndex, boolean readOnly) { this.headerName = headerName; this.columnIndex = columnIndex; this.readOnly = readOnly; - this.allowedValues = allowedValues; - } - - /** - * @param headerName the name in the header - * @param columnIndex the index of the column this property is in - * @param readOnly is the property read only - */ - NGSMeasurementColumns(String headerName, int columnIndex, boolean readOnly) { - this(headerName, columnIndex, readOnly, null); } public String headerName() { @@ -370,8 +357,5 @@ public boolean readOnly() { return readOnly; } - public List allowedValues() { - return Optional.ofNullable(allowedValues).orElse(Collections.emptyList()); - } } } diff --git a/user-interface/src/main/java/life/qbic/datamanager/views/projects/project/measurements/download/ProteomicsMeasurementContentProvider.java b/user-interface/src/main/java/life/qbic/datamanager/views/projects/project/measurements/download/ProteomicsMeasurementContentProvider.java index 285023830..90c29b92e 100644 --- a/user-interface/src/main/java/life/qbic/datamanager/views/projects/project/measurements/download/ProteomicsMeasurementContentProvider.java +++ b/user-interface/src/main/java/life/qbic/datamanager/views/projects/project/measurements/download/ProteomicsMeasurementContentProvider.java @@ -1,5 +1,11 @@ package life.qbic.datamanager.views.projects.project.measurements.download; +import static life.qbic.datamanager.spreadsheet.XLSXTemplateHelper.addDataValidation; +import static life.qbic.datamanager.spreadsheet.XLSXTemplateHelper.createOptionArea; +import static life.qbic.datamanager.spreadsheet.XLSXTemplateHelper.getOrCreateCell; +import static life.qbic.datamanager.spreadsheet.XLSXTemplateHelper.getOrCreateRow; +import static life.qbic.datamanager.spreadsheet.XLSXTemplateHelper.hideSheet; +import static life.qbic.datamanager.spreadsheet.XLSXTemplateHelper.lockSheet; import static life.qbic.logging.service.LoggerFactory.logger; import java.io.ByteArrayOutputStream; @@ -11,9 +17,13 @@ import life.qbic.datamanager.views.general.download.DownloadContentProvider; import life.qbic.datamanager.views.projects.project.measurements.ProteomicsMeasurementEntry; import life.qbic.logging.api.Logger; +import life.qbic.projectmanagement.application.measurement.ProteomicsMeasurementMetadata; +import life.qbic.projectmanagement.application.measurement.validation.MeasurementProteomicsValidator.DigestionMethod; +import life.qbic.projectmanagement.domain.model.measurement.ProteomicsMeasurement; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Name; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; @@ -25,8 +35,8 @@ /** Proteomics Measurement Content Provider *

* Implementation of the {@link DownloadContentProvider} providing the content and file name for any files created - * from {@link life.qbic.projectmanagement.domain.model.measurement.ProteomicsMeasurement} - * and {@link life.qbic.projectmanagement.application.measurement.ProteomicsMeasurementMetadata} + * from {@link ProteomicsMeasurement} + * and {@link ProteomicsMeasurementMetadata} *

*/ public class ProteomicsMeasurementContentProvider implements DownloadContentProvider { @@ -38,6 +48,8 @@ public class ProteomicsMeasurementContentProvider implements DownloadContentProv private final List measurements = new LinkedList<>(); private static final String DEFAULT_FILE_NAME_PREFIX = "QBiC"; private String fileNamePrefix = DEFAULT_FILE_NAME_PREFIX; + private static final int DEFAULT_GENERATED_ROW_COUNT = 200; + private static void setAutoWidth(Sheet sheet) { for (int col = 0; col <= 18; col++) { @@ -45,100 +57,36 @@ private static void setAutoWidth(Sheet sheet) { } } - private static void formatHeader(Row header, CellStyle readOnlyHeader, CellStyle boldStyle) { - var h1 = header.createCell(0); - h1.setCellValue("Measurement ID"); - h1.setCellStyle(readOnlyHeader); - - var h2 = header.createCell(1); - h2.setCellValue("QBiC Sample ID"); - h2.setCellStyle(readOnlyHeader); - - var h3 = header.createCell(2); - h3.setCellValue("Sample Name"); - h3.setCellStyle(readOnlyHeader); - - var h4 = header.createCell(3); - h4.setCellValue("Sample Pool Group"); - h4.setCellStyle(readOnlyHeader); - - var h5 = header.createCell(4); - h5.setCellValue("Organisation ID"); - h5.setCellStyle(boldStyle); - - var h6 = header.createCell(5); - h6.setCellValue("Organisation Name"); - h6.setCellStyle(readOnlyHeader); - - var h7 = header.createCell(6); - h7.setCellValue("Facility"); - h7.setCellStyle(boldStyle); - - var h8 = header.createCell(7); - h8.setCellValue("Instrument"); - h8.setCellStyle(boldStyle); - - var h9 = header.createCell(8); - h9.setCellValue("Instrument Name"); - h9.setCellStyle(readOnlyHeader); - - header.createCell(9).setCellValue("Cycle/Fraction Name"); - header.createCell(10).setCellValue("Digestion Method"); - header.createCell(11).setCellValue("Digestion Enzyme"); - header.createCell(12).setCellValue("Enrichment Method"); - header.createCell(13).setCellValue("Injection Volume (uL)"); - header.createCell(14).setCellValue("LC Column"); - header.createCell(15).setCellValue("LCMS Method"); - header.createCell(16).setCellValue("Labeling Type"); - header.createCell(17).setCellValue("Label"); - header.createCell(18).setCellValue("Comment"); - - for (int i = 9; i < 19; i++) { - header.getCell(i).setCellStyle(boldStyle); - } - } - - private static void createMeasurementEntry(ProteomicsMeasurementEntry pxpEntry, Row entry, + private static void createMeasurementEntry(ProteomicsMeasurementEntry pxpEntry, Row entryRow, CellStyle readOnlyStyle) { - var measureCol = entry.createCell(0); - measureCol.setCellValue(pxpEntry.measurementCode()); - measureCol.setCellStyle(readOnlyStyle); - - var sampleIdCol = entry.createCell(1); - sampleIdCol.setCellValue(pxpEntry.sampleInformation().sampleId()); - sampleIdCol.setCellStyle(readOnlyStyle); - - var sampleNameCol = entry.createCell(2); - sampleNameCol.setCellValue(pxpEntry.sampleInformation().sampleName()); - sampleNameCol.setCellStyle(readOnlyStyle); - - var samplePoolCol = entry.createCell(3); - samplePoolCol.setCellValue(pxpEntry.samplePoolGroup()); - samplePoolCol.setCellStyle(readOnlyStyle); - - entry.createCell(4).setCellValue(pxpEntry.organisationId()); - - var organisationNameCol = entry.createCell(5); - organisationNameCol.setCellValue(pxpEntry.organisationName()); - organisationNameCol.setCellStyle(readOnlyStyle); - - entry.createCell(6).setCellValue(pxpEntry.facility()); - entry.createCell(7).setCellValue(pxpEntry.instrumentCURI()); - - var instumentNameCol = entry.createCell(8); - instumentNameCol.setCellValue(pxpEntry.instrumentName()); - instumentNameCol.setCellStyle(readOnlyStyle); - - entry.createCell(9).setCellValue(pxpEntry.fractionName()); - entry.createCell(10).setCellValue(pxpEntry.digestionMethod()); - entry.createCell(11).setCellValue(pxpEntry.digestionEnzyme()); - entry.createCell(12).setCellValue(pxpEntry.enrichmentMethod()); - entry.createCell(13).setCellValue(Integer.parseInt(pxpEntry.injectionVolume())); - entry.createCell(14).setCellValue(pxpEntry.lcColumn()); - entry.createCell(15).setCellValue(pxpEntry.lcmsMethod()); - entry.createCell(16).setCellValue(pxpEntry.labelingType()); - entry.createCell(17).setCellValue(pxpEntry.label()); - entry.createCell(18).setCellValue(pxpEntry.comment()); + for (ProteomicsMeasurementColumns measurementColumn : ProteomicsMeasurementColumns.values()) { + var value = switch (measurementColumn) { + case MEASUREMENT_ID -> pxpEntry.measurementCode(); + case SAMPLE_ID -> pxpEntry.sampleInformation().sampleId(); + case SAMPLE_NAME -> pxpEntry.sampleInformation().sampleName(); + case POOL_GROUP -> pxpEntry.samplePoolGroup(); + case ORGANISATION_ID -> pxpEntry.organisationId(); + case ORGANISATION_NAME -> pxpEntry.organisationName(); + case FACILITY -> pxpEntry.facility(); + case MS_DEVICE -> pxpEntry.instrumentCURI(); + case MS_DEVICE_NAME -> pxpEntry.instrumentName(); + case CYCLE_FRACTION_NAME -> pxpEntry.fractionName(); + case DIGESTION_METHOD -> pxpEntry.digestionMethod(); + case DIGESTION_ENZYME -> pxpEntry.digestionEnzyme(); + case ENRICHMENT_METHOD -> pxpEntry.enrichmentMethod(); + case INJECTION_VOLUME -> pxpEntry.injectionVolume(); + case LC_COLUMN -> pxpEntry.lcColumn(); + case LCMS_METHOD -> pxpEntry.lcmsMethod(); + case LABELING_TYPE -> pxpEntry.labelingType(); + case LABEL -> pxpEntry.label(); + case COMMENT -> pxpEntry.comment(); + }; + var cell = getOrCreateCell(entryRow, measurementColumn.columnIndex()); + cell.setCellValue(value); + if (measurementColumn.readOnly()) { + cell.setCellStyle(readOnlyStyle); + } + } } public void setMeasurements(List measurements, String fileNamePrefix) { @@ -156,26 +104,21 @@ public byte[] getContent() { ByteArrayOutputStream byteArrayOutputStream; try (Workbook workbook = new XSSFWorkbook()) { - Sheet sheet = workbook.createSheet("Proteomics Measurement Metadata"); - Row header = sheet.createRow(0); - - CellStyle readOnlyHeader = workbook.createCellStyle(); - readOnlyHeader.setFillForegroundColor( + CellStyle readOnlyHeaderStyle = workbook.createCellStyle(); + readOnlyHeaderStyle.setFillForegroundColor( new XSSFColor(LIGHT_GREY, new DefaultIndexedColorMap())); - readOnlyHeader.setFillPattern(FillPatternType.SOLID_FOREGROUND); + readOnlyHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); XSSFFont fontHeader = (XSSFFont) workbook.createFont(); fontHeader.setBold(true); fontHeader.setColor(new XSSFColor(DARK_GREY, new DefaultIndexedColorMap())); - readOnlyHeader.setFont(fontHeader); + readOnlyHeaderStyle.setFont(fontHeader); CellStyle boldStyle = workbook.createCellStyle(); Font fontBold = workbook.createFont(); fontBold.setBold(true); boldStyle.setFont(fontBold); - formatHeader(header, readOnlyHeader, boldStyle); - CellStyle readOnlyStyle = workbook.createCellStyle(); readOnlyStyle.setFillForegroundColor(new XSSFColor(LIGHT_GREY, new DefaultIndexedColorMap())); readOnlyStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); @@ -183,15 +126,47 @@ public byte[] getContent() { font.setColor(new XSSFColor(DARK_GREY, new DefaultIndexedColorMap())); readOnlyStyle.setFont(font); - int rowCounter = 1; + Sheet hiddenSheet = workbook.createSheet("hidden"); + Name digestionMethodArea = createOptionArea(hiddenSheet, "Digestion Method", + DigestionMethod.getOptions()); + + Sheet sheet = workbook.createSheet("Proteomics Measurement Metadata"); + + Row header = getOrCreateRow(sheet, 0); + + for (ProteomicsMeasurementColumns measurementColumn : ProteomicsMeasurementColumns.values()) { + var cell = getOrCreateCell(header, measurementColumn.columnIndex()); + cell.setCellValue(measurementColumn.headerName()); + if (measurementColumn.readOnly()) { + cell.setCellStyle(readOnlyHeaderStyle); + } else { + cell.setCellStyle(boldStyle); + } + } + + var startIndex = 1; // start in row number 2 with index 1 skipping the header in the first row + var rowIndex = startIndex; for (ProteomicsMeasurementEntry pxpEntry : measurements) { - Row entry = sheet.createRow(rowCounter); + Row entry = getOrCreateRow(sheet, rowIndex); createMeasurementEntry(pxpEntry, entry, readOnlyStyle); - rowCounter++; + rowIndex++; } + var generatedRowCount = rowIndex - startIndex; + assert generatedRowCount == measurements.size() : "all measurements have a corresponding row"; + + addDataValidation(sheet, + ProteomicsMeasurementColumns.DIGESTION_METHOD.columnIndex(), startIndex, + ProteomicsMeasurementColumns.DIGESTION_METHOD.columnIndex(), + DEFAULT_GENERATED_ROW_COUNT - 1, + digestionMethodArea); setAutoWidth(sheet); + workbook.setSheetOrder(sheet.getSheetName(), 0); + workbook.setActiveSheet(0); + + lockSheet(hiddenSheet); + hideSheet(workbook, hiddenSheet); byteArrayOutputStream = new ByteArrayOutputStream(); workbook.write(byteArrayOutputStream); @@ -203,6 +178,52 @@ public byte[] getContent() { return byteArrayOutputStream.toByteArray(); } + enum ProteomicsMeasurementColumns { + + MEASUREMENT_ID("Measurement ID", 0, true), + SAMPLE_ID("QBiC Sample Id", 1, true), + SAMPLE_NAME( + "Sample Name", 2, true), + POOL_GROUP("Sample Pool Group", 3, true), + ORGANISATION_ID("Organisation ID", 4, false), + ORGANISATION_NAME("Organisation Name", 5, true), + FACILITY("Facility", 6, false), + MS_DEVICE("MS Device", 7, false), + MS_DEVICE_NAME("MS Device Name", 8, true), + CYCLE_FRACTION_NAME("Cycle/Fraction Name", 9, false), + DIGESTION_METHOD("Digestion Method", 10, false), + DIGESTION_ENZYME("Digestion Enzyme", 11, false), + ENRICHMENT_METHOD("Enrichment Method", 12, false), + INJECTION_VOLUME("Injection Volume (µL)", 13, false), + LC_COLUMN("LC Column", 14, false), + LCMS_METHOD("LCMS Method", 15, false), + LABELING_TYPE("Labeling Type", 16, false), + LABEL("Label", 17, false), + COMMENT("Comment", 18, false), + ; + private final String headerName; + private final int columnIndex; + private final boolean readOnly; + + ProteomicsMeasurementColumns(String headerName, int columnIndex, boolean readOnly) { + this.headerName = headerName; + this.columnIndex = columnIndex; + this.readOnly = readOnly; + } + + public String headerName() { + return headerName; + } + + public int columnIndex() { + return columnIndex; + } + + public boolean readOnly() { + return readOnly; + } + } + @Override public String getFileName() { return String.join("_", fileNamePrefix, FILE_NAME_SUFFIX);