From d9d1aae510b895f197e21418cadfd218eb18ab17 Mon Sep 17 00:00:00 2001 From: Tobias Koch Date: Wed, 23 Feb 2022 13:23:03 +0100 Subject: [PATCH 01/12] Remove everit-json from compile scope (#288) * Move everit json to test scope * Encapsulate metadata Co-authored-by: jenniferboedker --- pom.xml | 2 +- .../datasets/OxfordNanoporeMeasurement.groovy | 219 +++++++++++------- 2 files changed, 131 insertions(+), 90 deletions(-) diff --git a/pom.xml b/pom.xml index a6b3b75a06..d00a0f3f78 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ com.github.everit-org.json-schema org.everit.json.schema 1.12.2 - ${osgi.scope} + test life.qbic diff --git a/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy b/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy index 4825de3c2b..4bb9ee0cd9 100644 --- a/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy +++ b/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy @@ -1,18 +1,14 @@ package life.qbic.datamodel.datasets +import groovy.json.JsonSlurper +import groovy.util.logging.Log4j2 import life.qbic.datamodel.datasets.datastructure.files.DataFile import life.qbic.datamodel.datasets.datastructure.folders.DataFolder import life.qbic.datamodel.datasets.datastructure.folders.nanopore.* -import org.everit.json.schema.ValidationException import java.util.regex.Matcher import java.util.regex.Pattern -import org.everit.json.schema.loader.SchemaLoader -import org.json.JSONObject -import org.json.JSONTokener -import groovy.util.logging.Log4j2 - /** * A dataset that represents a Oxford Nanopore Measurement. * @@ -21,23 +17,8 @@ import groovy.util.logging.Log4j2 @Log4j2 final class OxfordNanoporeMeasurement { - private static final String LIBRARY_PREP_KIT_SCHEMA = "SQK-.*(?=:)" - - private static final enum METADATA_FIELD { - ADAPTER, - ASIC_TEMP, - BASE_CALLER, - BASE_CALLER_VERSION, - DEVICE_TYPE, - FLOWCELL_ID, - FLOWCELL_POSITION, - FLOWCELL_TYPE, - LIBRARY_PREPARATION_KIT, - MACHINE_HOST, - START_DATE - } - private final Map metadata + private final Metadata metadata private final Map folders @@ -50,12 +31,11 @@ final class OxfordNanoporeMeasurement { protected OxfordNanoporeMeasurement(String name, String path, List children, Map metadata) { this.logFilesCollection = new ArrayList<>() this.folders = new HashMap<>() - this.metadata = new HashMap() this.measurementFolder = MeasurementFolder.create(name, path, children) - validateMetaData(metadata) - readMetaData(metadata) + this.metadata = Metadata.from(metadata) + createContent() assessPooledStatus() assessState() @@ -69,16 +49,6 @@ final class OxfordNanoporeMeasurement { return new OxfordNanoporeMeasurement(name, path, children, metadata) } - private static void validateMetaData(Map metadata) throws IllegalArgumentException { - try { - MetaData.validateMetadata(metadata) - } catch (ValidationException e) { - // Aggregate the causing exceptions - def causes = e.getAllMessages().join("\n") - throw new IllegalArgumentException("The Nanopore metadata could not be collected.\nReason:\n$causes",) - } - } - private void assessPooledStatus() { this.pooledSamplesMeasurement = containsAtLeastOneBarcodedFolder(folders["fast5pass"]) // There can be still pooled samples in the failed folder, worst case is all @@ -97,33 +67,6 @@ final class OxfordNanoporeMeasurement { return false } - private void readMetaData(Map metadata) { - this.metadata[METADATA_FIELD.ADAPTER] = metadata["adapter"] - this.metadata[METADATA_FIELD.ASIC_TEMP] = metadata["asic_temp"] - this.metadata[METADATA_FIELD.BASE_CALLER] = metadata["base_caller"] - this.metadata[METADATA_FIELD.BASE_CALLER_VERSION] = metadata["base_caller_version"] - this.metadata[METADATA_FIELD.DEVICE_TYPE] = metadata["device_type"] - this.metadata[METADATA_FIELD.FLOWCELL_ID] = metadata["flow_cell_id"] - this.metadata[METADATA_FIELD.FLOWCELL_POSITION] = metadata["flow_cell_position"] - this.metadata[METADATA_FIELD.FLOWCELL_TYPE] = metadata["flow_cell_product_code"] - this.metadata[METADATA_FIELD.LIBRARY_PREPARATION_KIT] = extractLibraryKit(metadata["protocol"] ?: "") - this.metadata[METADATA_FIELD.MACHINE_HOST] = metadata["hostname"] - this.metadata[METADATA_FIELD.START_DATE] = metadata["started"] - } - - private static String extractLibraryKit(String text) { - Set result = [] - Pattern pattern = Pattern.compile(LIBRARY_PREP_KIT_SCHEMA, Pattern.CASE_INSENSITIVE) - Matcher m = pattern.matcher(text) - while (m.find()) { - result.add(m.group()) - } - if (result.isEmpty()) { - throw new MissingPropertyException("Could not find information about the library preparation kit.") - } - return result[0] - } - private void createContent() { measurementFolder.getChildren().each { element -> switch (element) { @@ -215,7 +158,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getAdapter() { - return metadata.get(METADATA_FIELD.ADAPTER) ?: "" + return metadata.getAdapter() } /** @@ -223,7 +166,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getAsicTemp() { - return metadata.get(METADATA_FIELD.ASIC_TEMP) + return metadata.getAsicTemp() } /** @@ -231,7 +174,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getDeviceType() { - return metadata.get(METADATA_FIELD.DEVICE_TYPE) + return metadata.getDeviceType() } /** @@ -239,7 +182,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getFlowcellId() { - return metadata.get(METADATA_FIELD.FLOWCELL_ID) + return metadata.getFlowcellId() } /** @@ -247,7 +190,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getFlowCellPosition() { - return metadata.get(METADATA_FIELD.FLOWCELL_POSITION) + return metadata.getFlowcellPosition() } /** @@ -255,7 +198,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getFlowCellType() { - return metadata.get(METADATA_FIELD.FLOWCELL_TYPE) + return metadata.getFlowcellType() } /** @@ -263,7 +206,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getBaseCaller() { - return metadata.get(METADATA_FIELD.BASE_CALLER) + return metadata.getBaseCaller() } /** @@ -271,7 +214,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getBaseCallerVersion() { - return metadata.get(METADATA_FIELD.BASE_CALLER_VERSION) + return metadata.getBaseCallerVersion() } /** @@ -279,7 +222,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getLibraryPreparationKit() { - return metadata.get(METADATA_FIELD.LIBRARY_PREPARATION_KIT) + metadata.getLibraryPreparationKit() } /** @@ -287,7 +230,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getMachineHost() { - return metadata.get(METADATA_FIELD.MACHINE_HOST) + metadata.getMachineHost() } /** @@ -295,7 +238,7 @@ final class OxfordNanoporeMeasurement { * @return */ String getStartDate() { - return metadata.get(METADATA_FIELD.START_DATE) + metadata.getStartDate() } private Map prepareUnclassifiedData() { @@ -369,24 +312,122 @@ final class OxfordNanoporeMeasurement { return this.measurementFolder.relativePath } - /* - Inner class that contains the logic for the metadata validation - */ - private static class MetaData { - - private static final SCHEMA = "/schemas/ont-metadata.schema.json" - - static validateMetadata(Map metaData) throws ValidationException { - // Load schema - final def metaDataJson = new JSONObject(metaData) - final def schemaStream = OxfordNanoporeMeasurement.getResourceAsStream(SCHEMA) - final def rawSchema = new JSONObject(new JSONTokener(schemaStream)) - final def jsonSchema = SchemaLoader.load(rawSchema) - // Validate against schema - jsonSchema.validate(metaDataJson) + private static class Metadata { + private static final Map SCHEMA = parseMetadataSchema() + private static final String LIBRARY_PREP_KIT_SCHEMA = "SQK-.*(?=:)" + + private String adapter + private String asicTemp + private String deviceType + private String flowcellId + private String flowcellPosition + private String flowcellType + private String baseCaller + private String baseCallerVersion + private String libraryPreparationKit + private String machineHost + private String startDate + + private Metadata() {} + + /** + * Reads metadata information from the provided map given the map is valid according to the schema. + * + * @param metadataMap a map containing all required metadata + * @return a valid Metadata instance containing relevant information from the map + */ + static Metadata from(Map metadataMap) { + validateMetaDataMap(metadataMap) + Metadata metadata = new Metadata() + metadata.readMetaData(metadataMap) + return metadata } - } + private static Map parseMetadataSchema() { + URL schemaUrl = this.getClassLoader().getResource("schemas/ont-metadata.schema.json") + return new JsonSlurper().parse(schemaUrl) as Map + } + + private static void validateMetaDataMap(Map metadata) throws IllegalArgumentException { + def expectedKeys = SCHEMA.get("required") as List + + def missingKeys = expectedKeys.stream() + .filter({ !metadata.keySet().contains(it) }) + .collect() + if (!missingKeys.isEmpty()) { + throw new IllegalArgumentException('Required metadata properties missing: ' + missingKeys.join(", ")) + } + } + + private static String extractLibraryKit(String text) { + Set result = [] + Pattern pattern = Pattern.compile(LIBRARY_PREP_KIT_SCHEMA, Pattern.CASE_INSENSITIVE) + Matcher m = pattern.matcher(text) + while (m.find()) { + result.add(m.group()) + } + if (result.isEmpty()) { + throw new MissingPropertyException("Could not find information about the library preparation kit.") + } + return result[0] + } + + private void readMetaData(Map metadata) { + this.adapter = metadata["adapter"] ?: "" + this.asicTemp = metadata["asic_temp"] + this.baseCaller = metadata["base_caller"] + this.baseCallerVersion = metadata["base_caller_version"] + this.deviceType = metadata["device_type"] + this.flowcellId = metadata["flow_cell_id"] + this.flowcellPosition = metadata["flow_cell_position"] + this.flowcellType = metadata["flow_cell_product_code"] + this.libraryPreparationKit = extractLibraryKit(metadata["protocol"] ?: "") + this.machineHost = metadata["hostname"] + this.startDate = metadata["started"] + } + + String getAdapter() { + return adapter + } + + String getAsicTemp() { + return asicTemp + } + + String getDeviceType() { + return deviceType + } + + String getFlowcellId() { + return flowcellId + } + + String getFlowcellPosition() { + return flowcellPosition + } + + String getFlowcellType() { + return flowcellType + } + + String getBaseCaller() { + return baseCaller + } + + String getBaseCallerVersion() { + return baseCallerVersion + } + + String getLibraryPreparationKit() { + return libraryPreparationKit + } + String getMachineHost() { + return machineHost + } + String getStartDate() { + return startDate + } + } } From 5c0fe9e9e1769493b3af7b6d3a8385aa808ec382 Mon Sep 17 00:00:00 2001 From: wow-such-code Date: Wed, 23 Feb 2022 19:19:55 +0100 Subject: [PATCH 02/12] add alternative nanopore data structure and tests (#289) * add alternative nanopore data structure and tests * add new nanopore model to readme Co-authored-by: jnnfr --- README.md | 6 +- doc/figures/Nanopore_Data_Structure_Model.png | Bin 119948 -> 0 bytes doc/figures/Nanopore_Data_Structure_Model.svg | 4 + .../Nanopore_Data_Structure_Model_v2.svg | 4 + .../datasets/OxfordNanoporeExperiment.groovy | 6 +- .../datasets/OxfordNanoporeMeasurement.groovy | 44 ++ .../files/nanopore/BarcodeAlignmentLog.groovy | 32 + .../nanopore/OtherReportsFolder.groovy | 40 ++ .../OxfordNanoporeInstrumentOutputV2.groovy | 22 + .../nanopore-instrument-output_v2.schema.json | 605 ++++++++++++++++++ .../schemas/ont-metadata.schema.json | 2 +- .../OxfordNanoporeExperimentSpec.groovy | 24 + src/test/resources/valid-example-newer.json | 200 ++++++ 13 files changed, 985 insertions(+), 4 deletions(-) delete mode 100644 doc/figures/Nanopore_Data_Structure_Model.png create mode 100644 doc/figures/Nanopore_Data_Structure_Model.svg create mode 100644 doc/figures/Nanopore_Data_Structure_Model_v2.svg create mode 100644 src/main/groovy/life/qbic/datamodel/datasets/datastructure/files/nanopore/BarcodeAlignmentLog.groovy create mode 100644 src/main/groovy/life/qbic/datamodel/datasets/datastructure/folders/nanopore/OtherReportsFolder.groovy create mode 100644 src/main/groovy/life/qbic/datamodel/instruments/OxfordNanoporeInstrumentOutputV2.groovy create mode 100644 src/main/resources/schemas/nanopore-instrument-output_v2.schema.json create mode 100644 src/test/resources/valid-example-newer.json diff --git a/README.md b/README.md index 2eba7ab305..d97d27b359 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,11 @@ Make sure, that you have defined the Github package Maven repository, in order f A Nanopore NGS measurement output is delivered to us as a nested folder structure, following this model: -![Nanopore Data Structure Model](./doc/figures/Nanopore_Data_Structure_Model.png) +![Nanopore Data Structure Model](./doc/figures/Nanopore_Data_Structure_Model.svg) + +A more recent model, which places two of the configuration files into a subfolder and adds the barcode alignment file, is also supported: + +![Nanopore Data Structure Model v2](./doc/figures/Nanopore_Data_Structure_Model_v2.svg) #### Nanopore usage example diff --git a/doc/figures/Nanopore_Data_Structure_Model.png b/doc/figures/Nanopore_Data_Structure_Model.png deleted file mode 100644 index 5e94d5f1497add62acaa0c1a87a8f69e730e1de0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119948 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%0AhQ?05zUnJ8ewpo|eWct^a>Of& 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 vjpX-=Zeju(4qO}WvVD2K7e`FM; + + +
Root Folder
(OxfordNanoporeExperiment)
Root Folder...
Measurement Folder
(OxfordNanoporeMeasurement)
Measurement Folder...
1
1
1..n
1..n
FastQ Fail Folder
FastQ Fail Folder
FastQ Pass Folder
FastQ Pass Folder
Fast5 Pass Folder
Fast5 Pass Folder
Fast5 Fail Folder
Fast5 Fail Folder
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
Sequencing Summary Log
Sequencing Summary Log
Duty Time Log
Duty Time Log
Final Summary Log
Final Summary Log
Throughput Log
Throughput Log
Report MD Log
Report MD Log
Report PDF Log
Report PDF Log
Drift Correction Log
Drift Correction Log
Mux Scan Data Log
Mux Scan Data Log
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
FastQ Folder
FastQ Folder
FastQ File
FastQ File
1
1
0..n
0..n
DataFile
DataFile
BarcodedFolder
BarcodedFolder
Extends
Extends
Extends
Extends
Data File
Data File
Extends
Extends
DataFolder
DataFolder
Extends
Extends
DataFolder
DataFolder
Extends
Extends
Unclassified Folder
Unclassified Folder
1
1
0..n
0..n
1
1
0..n
0..n
FastQ File
FastQ File
1
1
0..n
0..n
1
1
0..n
0..n
FastQ Folder
FastQ Folder
FastQ File
FastQ File
Unclassified Folder
Unclassified Folder
1
1
0..n
0..n
FastQ File
FastQ File
1
1
0..n
0..n
Fast5 Folder
Fast5 Folder
Fast5 File
Fast5 File
Unclassified Folder
Unclassified Folder
1
1
0..n
0..n
Fast5 File
Fast5 File
1
1
0..n
0..n
Fast5 Folder
Fast5 Folder
Fast5 File
Fast5 File
Unclassified Folder
Unclassified Folder
1
1
0..n
0..n
Fast5 File
Fast5 File
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
FastQ Folder
FastQ Folder
Fast5 Folder
Fast5 Folder
DataFolder
DataFolder
Text is not SVG - cannot display
\ No newline at end of file diff --git a/doc/figures/Nanopore_Data_Structure_Model_v2.svg b/doc/figures/Nanopore_Data_Structure_Model_v2.svg new file mode 100644 index 0000000000..330e266c8b --- /dev/null +++ b/doc/figures/Nanopore_Data_Structure_Model_v2.svg @@ -0,0 +1,4 @@ + + + +
Root Folder
(OxfordNanoporeExperiment)
Root Folder...
Measurement Folder
(OxfordNanoporeMeasurement)
Measurement Folder...
1
1
1..n
1..n
FastQ Fail Folder
FastQ Fail Folder
FastQ Pass Folder
FastQ Pass Folder
Fast5 Pass Folder
Fast5 Pass Folder
Fast5 Fail Folder
Fast5 Fail Folder
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
Barcode Alignment Log
Barcode Alignment Log
Duty Time Log
Duty Time Log
Final Summary Log
Final Summary Log
Throughput Log
Throughput Log
Report MD Log
Report MD Log
Report PDF Log
Report PDF Log
Sequencing Summary Log
Sequencing Summary Log
Mux Scan Data Log
Mux Scan Data Log
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
FastQ Folder
FastQ Folder
FastQ File
FastQ File
1
1
0..n
0..n
DataFile
DataFile
BarcodedFolder
BarcodedFolder
Extends
Extends
Extends
Extends
Data File
Data File
Extends
Extends
DataFolder
DataFolder
Extends
Extends
DataFolder
DataFolder
Extends
Extends
Unclassified Folder
Unclassified Folder
1
1
0..n
0..n
1
1
0..n
0..n
FastQ File
FastQ File
1
1
0..n
0..n
1
1
0..n
0..n
FastQ Folder
FastQ Folder
FastQ File
FastQ File
Unclassified Folder
Unclassified Folder
1
1
0..n
0..n
FastQ File
FastQ File
1
1
0..n
0..n
Fast5 Folder
Fast5 Folder
Fast5 File
Fast5 File
Unclassified Folder
Unclassified Folder
1
1
0..n
0..n
Fast5 File
Fast5 File
1
1
0..n
0..n
Fast5 Folder
Fast5 Folder
Fast5 File
Fast5 File
Unclassified Folder
Unclassified Folder
1
1
0..n
0..n
Fast5 File
Fast5 File
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
1
1
0..n
0..n
FastQ Folder
FastQ Folder
Fast5 Folder
Fast5 Folder
DataFolder
DataFolder
Drift Correction Log
Drift Correction Log
Extends
Extends
1:1
1:1
1:1
1:1
Other Reports Subfolder
Other Reports Subfolder
Text is not SVG - cannot display
\ No newline at end of file diff --git a/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeExperiment.groovy b/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeExperiment.groovy index 70a6b02c01..367fb89315 100644 --- a/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeExperiment.groovy +++ b/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeExperiment.groovy @@ -34,7 +34,8 @@ final class OxfordNanoporeExperiment implements ExperimentFolder { FQDN_FILES + ".ReportMdLog", FQDN_FILES + ".ReportPDFLog", FQDN_FILES + ".SequencingSummaryLog", - FQDN_FILES + ".ThroughputLog" + FQDN_FILES + ".ThroughputLog", + FQDN_FILES + ".BarcodeAlignmentLog" ] private final static Set nanoporeFolderTypes = [ @@ -45,7 +46,8 @@ final class OxfordNanoporeExperiment implements ExperimentFolder { FQDN_FOLDERS + ".FastQPassFolder", FQDN_FOLDERS + ".FastQFailFolder", FQDN_FOLDERS + ".UnclassifiedFast5Folder", - FQDN_FOLDERS + ".UnclassifiedFastQFolder" + FQDN_FOLDERS + ".UnclassifiedFastQFolder", + FQDN_FOLDERS + ".OtherReportsFolder" ] private OxfordNanoporeExperiment(String sampleId, List measurements) { diff --git a/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy b/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy index 4bb9ee0cd9..10915b161d 100644 --- a/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy +++ b/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy @@ -17,6 +17,21 @@ import java.util.regex.Pattern @Log4j2 final class OxfordNanoporeMeasurement { + private static final String LIBRARY_PREP_KIT_SCHEMA = "SQK-.*" + + private static final enum METADATA_FIELD { + ADAPTER, + ASIC_TEMP, + BASE_CALLER, + BASE_CALLER_VERSION, + DEVICE_TYPE, + FLOWCELL_ID, + FLOWCELL_POSITION, + FLOWCELL_TYPE, + LIBRARY_PREPARATION_KIT, + MACHINE_HOST, + START_DATE + } private final Metadata metadata @@ -67,6 +82,35 @@ final class OxfordNanoporeMeasurement { return false } + private void readMetaData(Map metadata) { + this.metadata[METADATA_FIELD.ADAPTER] = metadata["adapter"] + this.metadata[METADATA_FIELD.ASIC_TEMP] = metadata["asic_temp"] + this.metadata[METADATA_FIELD.BASE_CALLER] = metadata["base_caller"] + this.metadata[METADATA_FIELD.BASE_CALLER_VERSION] = metadata["base_caller_version"] + this.metadata[METADATA_FIELD.DEVICE_TYPE] = metadata["device_type"] + this.metadata[METADATA_FIELD.FLOWCELL_ID] = metadata["flow_cell_id"] + this.metadata[METADATA_FIELD.FLOWCELL_POSITION] = metadata["flow_cell_position"] + this.metadata[METADATA_FIELD.FLOWCELL_TYPE] = metadata["flow_cell_product_code"] + this.metadata[METADATA_FIELD.LIBRARY_PREPARATION_KIT] = extractLibraryKit(metadata["protocol"] ?: "") + this.metadata[METADATA_FIELD.MACHINE_HOST] = metadata["hostname"] + this.metadata[METADATA_FIELD.START_DATE] = metadata["started"] + } + + private static String extractLibraryKit(String text) { + // cut off optional suffix + text = text.replace(":True", "") + Set result = [] + Pattern pattern = Pattern.compile(LIBRARY_PREP_KIT_SCHEMA, Pattern.CASE_INSENSITIVE) + Matcher m = pattern.matcher(text) + while (m.find()) { + result.add(m.group()) + } + if (result.isEmpty()) { + throw new MissingPropertyException("Could not find information about the library preparation kit.") + } + return result[0] + } + private void createContent() { measurementFolder.getChildren().each { element -> switch (element) { diff --git a/src/main/groovy/life/qbic/datamodel/datasets/datastructure/files/nanopore/BarcodeAlignmentLog.groovy b/src/main/groovy/life/qbic/datamodel/datasets/datastructure/files/nanopore/BarcodeAlignmentLog.groovy new file mode 100644 index 0000000000..fa583c9ba9 --- /dev/null +++ b/src/main/groovy/life/qbic/datamodel/datasets/datastructure/files/nanopore/BarcodeAlignmentLog.groovy @@ -0,0 +1,32 @@ +package life.qbic.datamodel.datasets.datastructure.files.nanopore + +import life.qbic.datamodel.datasets.datastructure.files.DataFile + +/** + * A specialisation of a DataFile, represents an Oxford Nanopore barcode alignment log file + * + */ +class BarcodeAlignmentLog extends DataFile { + + final private static String FILE_TYPE = "tsv" + + final private static String NAME_SCHEMA = $/barcode_alignment_.*/$ + + protected BarcodeAlignmentLog() {} + + protected BarcodeAlignmentLog(String name, String relativePath) { + super(name, relativePath, FILE_TYPE) + validateName() + } + + static BarcodeAlignmentLog create(String name, String relativePath) { + return new BarcodeAlignmentLog(name, relativePath) + } + + private void validateName() { + if (!(this.name =~ NAME_SCHEMA)) { + throw new IllegalArgumentException("Name must match the Nanopore barcode alignment log name schema!") + } + } + +} diff --git a/src/main/groovy/life/qbic/datamodel/datasets/datastructure/folders/nanopore/OtherReportsFolder.groovy b/src/main/groovy/life/qbic/datamodel/datasets/datastructure/folders/nanopore/OtherReportsFolder.groovy new file mode 100644 index 0000000000..87753a56bd --- /dev/null +++ b/src/main/groovy/life/qbic/datamodel/datasets/datastructure/folders/nanopore/OtherReportsFolder.groovy @@ -0,0 +1,40 @@ +package life.qbic.datamodel.datasets.datastructure.folders.nanopore + +import life.qbic.datamodel.datasets.datastructure.folders.DataFolder + +/** + * A special case of a DataFolder. + * + * Holds information about a Oxford Nanopore NGS measurement. + * + */ +class OtherReportsFolder extends DataFolder { + + /** + * The name schema of a Oxford Nanopore "other reports" folder. + */ + final private static String NAME_SCHEMA = $/other_reports/$ + + protected OtherReportsFolder() {} + + protected OtherReportsFolder(String name, String relativePath, List children) { + super(name, relativePath, children) + validateName() + } + + /** + * Creates a new instance of a OtherReportsFolder object + * @param relativePath The relative path of the folder + * @param children A list with child elements of unknown type of the folder + * @return A new instance of a OtherReportsFolder object + */ + static OtherReportsFolder create(String name, String relativePath, List children) { + new OtherReportsFolder(name, relativePath, children) + } + + private void validateName() { + if (!(this.name =~ NAME_SCHEMA)) { + throw new IllegalArgumentException("Name must match the Nanopore other_reports folder schema!") + } + } +} diff --git a/src/main/groovy/life/qbic/datamodel/instruments/OxfordNanoporeInstrumentOutputV2.groovy b/src/main/groovy/life/qbic/datamodel/instruments/OxfordNanoporeInstrumentOutputV2.groovy new file mode 100644 index 0000000000..f615bf84b2 --- /dev/null +++ b/src/main/groovy/life/qbic/datamodel/instruments/OxfordNanoporeInstrumentOutputV2.groovy @@ -0,0 +1,22 @@ +package life.qbic.datamodel.instruments + + +/** + * Represents the Nanopore instrument output data structure schema. + * + * The original schema is defined in as resource and is + * referenced here, wrapped in a Groovy class for reference + * in applications that want to validate the instrument + * output structure against the schema. + * + * @author Sven Fillinger + * @since 1.9.0 + */ +class OxfordNanoporeInstrumentOutputV2 { + + private static final String SCHEMA_PATH = "/schemas/nanopore-instrument-output_v2.schema.json" + + static InputStream getSchemaAsStream() { + return OxfordNanoporeInstrumentOutputV2.getResourceAsStream(SCHEMA_PATH) + } +} diff --git a/src/main/resources/schemas/nanopore-instrument-output_v2.schema.json b/src/main/resources/schemas/nanopore-instrument-output_v2.schema.json new file mode 100644 index 0000000000..452feeefea --- /dev/null +++ b/src/main/resources/schemas/nanopore-instrument-output_v2.schema.json @@ -0,0 +1,605 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema", + "$id": "http://qbic.life/nanopore-instrument-output_v2.schema.json", + "title": "Nanopore Instrument Output V2", + "description": "Describes in which form Nanopore data is received from the lab.", + "definitions": { + "folder": { + "description": "Describes a folder", + "type": "object", + "required": [ + "name", + "path", + "children" + ], + "properties": { + "name": { + "description": "Folder name", + "type": "string", + "minLength": 1 + }, + "path": { + "description": "relative folderpath", + "type": "string", + "minLength": 1 + }, + "children": { + "description": "Describes files and/or sub-folders if existent", + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/definitions/folder" + }, + { + "$ref": "#/definitions/file" + } + ] + } + } + } + }, + "file": { + "description": "Describes a file", + "type": "object", + "required": [ + "name", + "path", + "file_type" + ], + "properties": { + "name": { + "type": "string", + "minLength": 1 + }, + "path": { + "type": "string", + "minLength": 1 + }, + "file_type": { + "type": "string", + "minLength": 1 + } + } + }, + "qbic_code": { + "description": "Describes a QBiC code used as a prefix", + "type": "string", + "pattern": "Q\\w{4}\\d{3}[A-X][A-X0-9].*" + }, + "barcoded_folder": { + "description": "folder starting with qbic barcode prefix", + "allOf": [ + { + "$ref": "#/definitions/folder" + }, + { + "properties": { + "name": { + "$ref": "#/definitions/qbic_code" + } + } + } + ] + }, + "other_reports_folder": { + "description": "subfolder containing some of the report files", + "allOf": [ + { + "$ref": "#/definitions/folder" + }, + { + "properties": { + "name": { + "pattern": "other_reports" + }, + "children": { + "items": { + "oneOf": [ + { + "$ref": "#/definitions/drift_correction_log" + }, + { + "$ref": "#/definitions/mux_scan_data_log" + } + ] + }, + "minItems": 2 + } + } + } + ] + }, + "fast5_file": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "file_type": { + "pattern": "fast5" + } + } + } + ] + }, + "fastqgz_file": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "file_type": { + "pattern": "fastq.gz" + } + } + } + ] + }, + "fastq_file": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "file_type": { + "pattern": "fastq" + } + } + } + ] + }, + "unclassified_folder": { + "description": "folder containing unassigned read file(s)", + "allOf": [ + { + "$ref": "#/definitions/folder" + }, + { + "properties": { + "name": { + "pattern": "unclassified" + } + } + } + ] + }, + "fast5_unclassified_folder": { + "description": "folder containing fast5 data from a pooling experiment, that could not be assigned to one of the known samples", + "allOf": [ + { + "$ref": "#/definitions/unclassified_folder" + }, + { + "properties": { + "children": { + "items": { + "$ref": "#/definitions/fast5_file" + }, + "minItems": 0 + } + } + } + ] + }, + "fastq_unclassified_folder": { + "description": "folder containing fastq and/or fastq.gz data from a pooling experiment, that could not be assigned to one of the known samples", + "allOf": [ + { + "$ref": "#/definitions/unclassified_folder" + }, + { + "properties": { + "children": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/fastqgz_file" + }, + { + "$ref": "#/definitions/fastq_file" + } + ] + }, + "minItems": 0 + } + } + } + ] + }, + "fast5_subfolder": { + "description": "folder containing fast5 data from a single sample (only when pooling is used)", + "allOf": [ + { + "$ref": "#/definitions/barcoded_folder" + }, + { + "properties": { + "children": { + "items": { + "$ref": "#/definitions/fast5_file" + }, + "minItems": 1 + } + } + } + ] + }, + "fast5_fail": { + "allOf": [ + { + "$ref": "#/definitions/folder" + }, + { + "properties": { + "name": { + "pattern": "fast5_fail" + }, + "children": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/fast5_subfolder" + }, + { + "$ref": "#/definitions/fast5_unclassified_folder" + }, + { + "$ref": "#/definitions/fast5_file" + } + ] + } + } + } + } + ] + }, + "fast5_pass": { + "allOf": [ + { + "$ref": "#/definitions/folder" + }, + { + "properties": { + "name": { + "pattern": "fast5_pass" + }, + "children": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/fast5_subfolder" + }, + { + "$ref": "#/definitions/fast5_unclassified_folder" + }, + { + "$ref": "#/definitions/fast5_file" + } + ] + } + } + } + } + ] + }, + "fastq_fail": { + "allOf": [ + { + "$ref": "#/definitions/folder" + }, + { + "properties": { + "name": { + "pattern": "fastq_fail" + }, + "children": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/fastq_subfolder" + }, + { + "$ref": "#/definitions/fastq_unclassified_folder" + }, + { + "$ref": "#/definitions/fastqgz_file" + } + ] + } + } + } + } + ] + }, + "fastq_pass": { + "allOf": [ + { + "$ref": "#/definitions/folder" + }, + { + "properties": { + "name": { + "pattern": "fastq_pass" + }, + "children": { + "items": { + "anyOf": [ + { + "$ref": "#/definitions/fastq_subfolder" + }, + { + "$ref": "#/definitions/fastq_unclassified_folder" + }, + { + "$ref": "#/definitions/fastqgz_file" + } + ] + } + } + } + } + ] + }, + "fastq_subfolder": { + "description": "folder containing gzipped fastq data from a single sample (only when pooling is used)", + "allOf": [ + { + "$ref": "#/definitions/barcoded_folder" + }, + { + "properties": { + "children": { + "items": { + "$ref": "#/definitions/fastqgz_file" + }, + "minItems": 1 + } + } + } + ] + }, + "measurements": { + "description": "Top folder generated by the facility, containing one or more timestamped measurements", + "allOf": [ + { + "$ref": "#/definitions/barcoded_folder" + }, + { + "properties": { + "children": { + "items": { + "allOf": [ + { + "$ref": "#/definitions/measurement" + } + ] + }, + "minItems": 1 + } + } + } + ] + }, + "measurement": { + "allOf": [ + { + "$ref": "#/definitions/folder" + }, + { + "properties": { + "name": { + "pattern": "\\d{4}(0?[1-9]|1[012])(0?[1-9]|[12][0-9]|3[01])_([01][0-9]|2[0-3])([0-5][0-9]).*", + "description": "Name of measurement subfolder. Starts with date and time of measurement." + }, + "children": { + "uniqueItems": true, + "minItems": 12, + "items": { + "oneOf": [ + { + "$ref": "#/definitions/fastq_fail" + }, + { + "$ref": "#/definitions/fastq_pass" + }, + { + "$ref": "#/definitions/fast5_pass" + }, + { + "$ref": "#/definitions/fast5_fail" + }, + { + "$ref": "#/definitions/duty_time_log" + }, + { + "$ref": "#/definitions/barcode_alignment_log" + }, + { + "$ref": "#/definitions/final_summary_log" + }, + { + "$ref": "#/definitions/report_md_log" + }, + { + "$ref": "#/definitions/report_pdf_log" + }, + { + "$ref": "#/definitions/sequencing_summary_log" + }, + { + "$ref": "#/definitions/throughput_log" + }, + { + "$ref": "#/definitions/other_reports_folder" + } + ] + } + } + } + } + ] + }, + "drift_correction_log": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "name": { + "pattern": "drift_correction_.*" + }, + "file_type": { + "pattern": "csv" + } + } + } + ] + }, + "duty_time_log": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "name": { + "pattern": "duty_time_.*" + }, + "file_type": { + "pattern": "csv" + } + } + } + ] + }, + "barcode_alignment_log": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "name": { + "pattern": "barcode_alignment_.*" + }, + "file_type": { + "pattern": "tsv" + } + } + } + ] + }, + "final_summary_log": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "name": { + "pattern": "final_summary_.*" + }, + "file_type": { + "pattern": "txt" + } + } + } + ] + }, + "mux_scan_data_log": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "name": { + "pattern": "mux_scan_data_.*" + }, + "file_type": { + "pattern": "csv" + } + } + } + ] + }, + "report_md_log": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "name": { + "pattern": "report_.*" + }, + "file_type": { + "pattern": "md" + } + } + } + ] + }, + "report_pdf_log": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "name": { + "pattern": "report_.*" + }, + "file_type": { + "pattern": "pdf" + } + } + } + ] + }, + "sequencing_summary_log": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "name": { + "pattern": "sequencing_summary_.*" + }, + "file_type": { + "pattern": "txt" + } + } + } + ] + }, + "throughput_log": { + "allOf": [ + { + "$ref": "#/definitions/file" + }, + { + "properties": { + "name": { + "pattern": "throughput_.*" + }, + "file_type": { + "pattern": "csv" + } + } + } + ] + } + }, + "allOf": [ + { + "$ref": "#/definitions/measurements" + } + ] +} diff --git a/src/main/resources/schemas/ont-metadata.schema.json b/src/main/resources/schemas/ont-metadata.schema.json index 98101d2149..6294d002e9 100644 --- a/src/main/resources/schemas/ont-metadata.schema.json +++ b/src/main/resources/schemas/ont-metadata.schema.json @@ -43,7 +43,7 @@ }, "protocol": { "type": "string", - "pattern": "SQK-.*(?=:)" + "pattern": "SQK-.*" }, "started": { "type": "string", diff --git a/src/test/groovy/life/qbic/datamodel/datasets/datastructure/OxfordNanoporeExperimentSpec.groovy b/src/test/groovy/life/qbic/datamodel/datasets/datastructure/OxfordNanoporeExperimentSpec.groovy index 3be25dd3df..7a404849b7 100644 --- a/src/test/groovy/life/qbic/datamodel/datasets/datastructure/OxfordNanoporeExperimentSpec.groovy +++ b/src/test/groovy/life/qbic/datamodel/datasets/datastructure/OxfordNanoporeExperimentSpec.groovy @@ -17,6 +17,12 @@ class OxfordNanoporeExperimentSpec extends Specification { */ @Shared Map minimalWorkingSimpleDataStructure + /** + * Newer map that stores the Oxford Nanopore folder structure + * according to the schema that puts some reports in its own folder and adds a new report + */ + @Shared + Map minimalWorkingSimpleDataStructureWithReportsFolder /** * Map that that stores the Oxford Nanopore folder structure * according to the schema containing unclassified read information @@ -33,6 +39,9 @@ class OxfordNanoporeExperimentSpec extends Specification { def setupSpec() { InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("valid-example.json") minimalWorkingSimpleDataStructure = (Map) new JsonSlurper().parse(stream) + // new example with slightly different structure + stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("valid-example-newer.json") + minimalWorkingSimpleDataStructureWithReportsFolder = (Map) new JsonSlurper().parse(stream) // read in unclassified example stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("valid-example-unclassified.json") unclassifiedWorkingDataStructure = (Map) new JsonSlurper().parse(stream) @@ -53,6 +62,21 @@ class OxfordNanoporeExperimentSpec extends Specification { then: assert experiment.sampleCode == "QABCD001AB" assert measurements.size() == 1 + assert measurements[0].libraryPreparationKit == "SQK-LSK109" + } + + def "Create simple sample Oxford Nanopore experiment successfully for newer structure"() { + given: + final def example = minimalWorkingSimpleDataStructureWithReportsFolder + + when: + final def experiment = OxfordNanoporeExperiment.create(example) + final def measurements = experiment.getMeasurements() + + then: + assert experiment.sampleCode == "QABCD001AB" + assert measurements.size() == 1 + assert measurements[0].libraryPreparationKit == "SQK-LSK109-XL" } def "Create a simple pooled Oxford Nanopore experiment successfully"() { diff --git a/src/test/resources/valid-example-newer.json b/src/test/resources/valid-example-newer.json new file mode 100644 index 0000000000..346a0ef617 --- /dev/null +++ b/src/test/resources/valid-example-newer.json @@ -0,0 +1,200 @@ +{ + "name": "QABCD001AB_E12A345a01_PAE12345", + "path": "./", + "children": [ + { + "name": "20200122_1217_1-A1-B1-PAE12345_1234567a", + "metadata": { + "adapter": "flongle", + "asic_temp": "32.631687", + "base_caller": "Guppy", + "base_caller_version": "3.2.8+bd67289", + "device_type" : "promethion", + "flow_cell_id": "PAE26306", + "flow_cell_product_code": "FLO-PRO002", + "flow_cell_position": "2-A3-D3", + "hostname": "PCT0094", + "protocol": "protocol=sequencing/sequencing_PRO002_DNA:FLO-PRO002:SQK-LSK109-XL", + "started": "2020-02-11T15:52:10.465982+01:00" + }, + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a", + "children": [ + { + "name": "throughput_.csv", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/throughput_.csv", + "file_type": "csv" + }, + { + "name": "report_.md", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/report_.md", + "file_type": "md" + }, + { + "name": "final_summary_.txt", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/final_summary_.txt", + "file_type": "txt" + }, + { + "name": "barcode_alignment_.tsv", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/barcode_alignment_.tsv", + "file_type": "tsv" + }, + { + "name": "other_reports", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/other_reports", + "children": [ + { + "name": "mux_scan_data.csv", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/other_reports/mux_scan_data.csv", + "file_type": "csv" + }, + { + "name": "drift_correction_.csv", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/other_reports/drift_correction_.csv", + "file_type": "csv" + } + ] + }, + { + "name": "fastq_pass", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_pass", + "children": [ + { + "name": "myfile3.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_pass/myfile3.fastq.gz", + "file_type": "fastq.gz" + }, + { + "name": "myfile2.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_pass/myfile2.fastq.gz", + "file_type": "fastq.gz" + }, + { + "name": "myfile4.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_pass/myfile4.fastq.gz", + "file_type": "fastq.gz" + }, + { + "name": "myfile5.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_pass/myfile5.fastq.gz", + "file_type": "fastq.gz" + }, + { + "name": "myfile1.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_pass/myfile1.fastq.gz", + "file_type": "fastq.gz" + } + ] + }, + { + "name": "fastq_fail", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_fail/", + "children": [ + { + "name": "myfile3.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_fail/myfile3.fastq.gz", + "file_type": "fastq.gz" + }, + { + "name": "myfile2.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_fail/myfile2.fastq.gz", + "file_type": "fastq.gz" + }, + { + "name": "myfile4.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_fail/myfile4.fastq.gz", + "file_type": "fastq.gz" + }, + { + "name": "myfile5.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_fail/myfile5.fastq.gz", + "file_type": "fastq.gz" + }, + { + "name": "myfile.fastq.gz", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fastq_fail/myfile.fastq.gz", + "file_type": "fastq.gz" + } + ] + }, + { + "name": "duty_time_.csv", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/duty_time_.csv", + "file_type": "csv" + }, + { + "name": "sequencing_summary_.txt", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/sequencing_summary_.txt", + "file_type": "txt" + }, + { + "name": "report_test.pdf", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/report_test.pdf", + "file_type": "pdf" + }, + { + "name": "fast5_fail", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_fail/", + "children": [ + { + "name": "myfile2.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_fail/myfile2.fast5", + "file_type": "fast5" + }, + { + "name": "myfile4.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_fail/myfile4.fast5", + "file_type": "fast5" + }, + { + "name": "myfile3.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_fail/myfile3.fast5", + "file_type": "fast5" + }, + { + "name": "myfile5.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_fail/myfile5.fast5", + "file_type": "fast5" + }, + { + "name": "myfile.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_fail/myfile.fast5", + "file_type": "fast5" + } + ] + }, + { + "name": "fast5_pass", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_pass/", + "children": [ + { + "name": "myfile2.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_pass/myfile2.fast5", + "file_type": "fast5" + }, + { + "name": "myfile4.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_pass/myfile4.fast5", + "file_type": "fast5" + }, + { + "name": "myfile3.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_pass/myfile3.fast5", + "file_type": "fast5" + }, + { + "name": "myfile5.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_pass/myfile5.fast5", + "file_type": "fast5" + }, + { + "name": "myfile.fast5", + "path": "./20200122_1217_1-A1-B1-PAE12345_1234567a/fast5_pass/myfile.fast5", + "file_type": "fast5" + } + ] + } + ] + } + ] +} From 75e08638cf8452b3f483d9f9c6a0b02cb22aa497 Mon Sep 17 00:00:00 2001 From: wow-such-code Date: Thu, 24 Feb 2022 16:09:00 +0100 Subject: [PATCH 03/12] Feature/update nanopore (#290) * Remove duplicate code Co-authored-by: Tobias Koch --- .../datasets/OxfordNanoporeMeasurement.groovy | 47 ++----------------- 1 file changed, 3 insertions(+), 44 deletions(-) diff --git a/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy b/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy index 10915b161d..5d79cf489d 100644 --- a/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy +++ b/src/main/groovy/life/qbic/datamodel/datasets/OxfordNanoporeMeasurement.groovy @@ -19,20 +19,6 @@ final class OxfordNanoporeMeasurement { private static final String LIBRARY_PREP_KIT_SCHEMA = "SQK-.*" - private static final enum METADATA_FIELD { - ADAPTER, - ASIC_TEMP, - BASE_CALLER, - BASE_CALLER_VERSION, - DEVICE_TYPE, - FLOWCELL_ID, - FLOWCELL_POSITION, - FLOWCELL_TYPE, - LIBRARY_PREPARATION_KIT, - MACHINE_HOST, - START_DATE - } - private final Metadata metadata private final Map folders @@ -82,35 +68,6 @@ final class OxfordNanoporeMeasurement { return false } - private void readMetaData(Map metadata) { - this.metadata[METADATA_FIELD.ADAPTER] = metadata["adapter"] - this.metadata[METADATA_FIELD.ASIC_TEMP] = metadata["asic_temp"] - this.metadata[METADATA_FIELD.BASE_CALLER] = metadata["base_caller"] - this.metadata[METADATA_FIELD.BASE_CALLER_VERSION] = metadata["base_caller_version"] - this.metadata[METADATA_FIELD.DEVICE_TYPE] = metadata["device_type"] - this.metadata[METADATA_FIELD.FLOWCELL_ID] = metadata["flow_cell_id"] - this.metadata[METADATA_FIELD.FLOWCELL_POSITION] = metadata["flow_cell_position"] - this.metadata[METADATA_FIELD.FLOWCELL_TYPE] = metadata["flow_cell_product_code"] - this.metadata[METADATA_FIELD.LIBRARY_PREPARATION_KIT] = extractLibraryKit(metadata["protocol"] ?: "") - this.metadata[METADATA_FIELD.MACHINE_HOST] = metadata["hostname"] - this.metadata[METADATA_FIELD.START_DATE] = metadata["started"] - } - - private static String extractLibraryKit(String text) { - // cut off optional suffix - text = text.replace(":True", "") - Set result = [] - Pattern pattern = Pattern.compile(LIBRARY_PREP_KIT_SCHEMA, Pattern.CASE_INSENSITIVE) - Matcher m = pattern.matcher(text) - while (m.find()) { - result.add(m.group()) - } - if (result.isEmpty()) { - throw new MissingPropertyException("Could not find information about the library preparation kit.") - } - return result[0] - } - private void createContent() { measurementFolder.getChildren().each { element -> switch (element) { @@ -358,7 +315,7 @@ final class OxfordNanoporeMeasurement { private static class Metadata { private static final Map SCHEMA = parseMetadataSchema() - private static final String LIBRARY_PREP_KIT_SCHEMA = "SQK-.*(?=:)" + private static final String LIBRARY_PREP_KIT_SCHEMA = "SQK-.*" private String adapter private String asicTemp @@ -404,6 +361,8 @@ final class OxfordNanoporeMeasurement { } private static String extractLibraryKit(String text) { + // cut off optional, unused suffix + text = text.replace(":True", "") Set result = [] Pattern pattern = Pattern.compile(LIBRARY_PREP_KIT_SCHEMA, Pattern.CASE_INSENSITIVE) Matcher m = pattern.matcher(text) From 803daa63a1a3199d0b215e2f0c8d1380d70ecc3d Mon Sep 17 00:00:00 2001 From: Tobias Koch Date: Thu, 24 Feb 2022 16:29:58 +0100 Subject: [PATCH 04/12] Remove outdated dependabot yml (#294) --- .dependabot/config.yml | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 .dependabot/config.yml diff --git a/.dependabot/config.yml b/.dependabot/config.yml deleted file mode 100644 index a0a1799d10..0000000000 --- a/.dependabot/config.yml +++ /dev/null @@ -1,10 +0,0 @@ -version: 2 -updates_configs: - - package_manager: "java:maven" - directory: "/" - update_schedule: "daily" - target-branch: development - default_labels: "dependabot" - commit-message: - prefix: "[DEPENDABOT]" - From 642a6af591b7b53631c393fee13ef22d63fe933d Mon Sep 17 00:00:00 2001 From: wow-such-code Date: Thu, 24 Feb 2022 16:30:22 +0100 Subject: [PATCH 05/12] update maven plugin versions (#293) --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index d00a0f3f78..12891139cd 100644 --- a/pom.xml +++ b/pom.xml @@ -181,7 +181,7 @@ org.codehaus.gmavenplus gmavenplus-plugin - 1.12.1 + 1.13.1 @@ -217,12 +217,12 @@ org.apache.maven.plugins maven-site-plugin - 3.9.1 + 3.11.0 org.apache.maven.plugins maven-project-info-reports-plugin - 3.1.1 + 3.2.1 life.qbic @@ -269,7 +269,7 @@ biz.aQute.bnd bnd-maven-plugin - 5.1.2 + 6.1.0 From bf02efdf4237489a6018204f74d981957912aa29 Mon Sep 17 00:00:00 2001 From: Tobias Koch Date: Fri, 25 Feb 2022 13:42:08 +0100 Subject: [PATCH 06/12] update groovy versions (#295) * update groovy versions * use snapshot of xml-manager-lib * move groovy to dependencies * Bump spock * update spock version * use java 11 Co-authored-by: wow-such-code --- .github/workflows/build_package.yml | 4 ++-- .github/workflows/create-release.yml | 4 ++-- .github/workflows/nexus-publish-snapshots.yml | 4 ++-- pom.xml | 20 +++++++++---------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build_package.yml b/.github/workflows/build_package.yml index 9d334b8fa9..4fcf03e9bf 100644 --- a/.github/workflows/build_package.yml +++ b/.github/workflows/build_package.yml @@ -8,10 +8,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 1.8 + - name: Set up JDK 1.11 uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 1.11 - name: Load local Maven repository cache uses: actions/cache@v2 with: diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 57d5afed65..bf7062cf09 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -12,10 +12,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up JDK 1.8 + - name: Set up JDK 1.11 uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 1.11 settings-path: ${{ github.workspace }} - name: Load local Maven repository cache diff --git a/.github/workflows/nexus-publish-snapshots.yml b/.github/workflows/nexus-publish-snapshots.yml index 8b8c411c16..78bf80734c 100644 --- a/.github/workflows/nexus-publish-snapshots.yml +++ b/.github/workflows/nexus-publish-snapshots.yml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 1.8 + - name: Set up JDK 1.11 uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 1.11 server-id: github # Value of the distributionManagement/repository/id field of the pom.xml settings-path: ${{ github.workspace }} diff --git a/pom.xml b/pom.xml index 12891139cd..9c83b954a0 100644 --- a/pom.xml +++ b/pom.xml @@ -81,20 +81,20 @@ org.codehaus.groovy groovy-bom - 2.5.14 + 3.0.9 pom import - - org.codehaus.groovy - groovy-all - 2.5.14 - pom - ${osgi.scope} - + + org.codehaus.groovy + groovy-all + 3.0.9 + pom + ${osgi.scope} + org.osgi osgi.core @@ -111,7 +111,7 @@ life.qbic xml-manager-lib - 1.6.0 + 1.7.0-SNAPSHOT ${osgi.scope} @@ -144,7 +144,7 @@ org.spockframework spock-core - 2.0-groovy-2.5 + 2.0-groovy-3.0 test From 6fb4bf844738c85518cd3d6061583d2d54ec1ff6 Mon Sep 17 00:00:00 2001 From: Tobias Koch Date: Fri, 25 Feb 2022 13:42:52 +0100 Subject: [PATCH 07/12] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d97d27b359..f8b104d50f 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ _Data Model Library - A collection of QBiC data models._ ## How to Run -Create a runable version of this code with maven and java 8: +Create a runable version of this code with maven and java 11: ``` mvn clean package From d23183c9540eaf888a36fa5b8b4089dfd6d1e693 Mon Sep 17 00:00:00 2001 From: Tobias Koch Date: Fri, 25 Feb 2022 13:50:23 +0100 Subject: [PATCH 08/12] Update codeql-analysis.yml (#296) --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ef963f52a2..e4cfe4013a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,10 +39,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 - - name: Set up JDK 1.8 + - name: Set up JDK 1.11 uses: actions/setup-java@v1 with: - java-version: 1.8 + java-version: 1.11 settings-path: ${{ github.workspace }} - name: Load local Maven repository cache From f0ac79ec5c33eb4fd6a1b49b8ad3fa244a431edd Mon Sep 17 00:00:00 2001 From: wow-such-code Date: Fri, 25 Feb 2022 14:36:52 +0100 Subject: [PATCH 09/12] compile using java 1.8 (#297) --- .github/workflows/build_package.yml | 4 ++-- .github/workflows/create-release.yml | 4 ++-- .github/workflows/java_checkstyle.yml | 4 ++-- .github/workflows/nexus-publish-snapshots.yml | 4 ++-- .github/workflows/run_tests.yml | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_package.yml b/.github/workflows/build_package.yml index 4fcf03e9bf..9d334b8fa9 100644 --- a/.github/workflows/build_package.yml +++ b/.github/workflows/build_package.yml @@ -8,10 +8,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 1.11 + - name: Set up JDK 1.8 uses: actions/setup-java@v1 with: - java-version: 1.11 + java-version: 1.8 - name: Load local Maven repository cache uses: actions/cache@v2 with: diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index bf7062cf09..57d5afed65 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -12,10 +12,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up JDK 1.11 + - name: Set up JDK 1.8 uses: actions/setup-java@v1 with: - java-version: 1.11 + java-version: 1.8 settings-path: ${{ github.workspace }} - name: Load local Maven repository cache diff --git a/.github/workflows/java_checkstyle.yml b/.github/workflows/java_checkstyle.yml index a41426e130..67094d5ada 100644 --- a/.github/workflows/java_checkstyle.yml +++ b/.github/workflows/java_checkstyle.yml @@ -8,10 +8,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 1.11 + - name: Set up JDK 1.8 uses: actions/setup-java@v1 with: - java-version: 1.11 + java-version: 1.8 - name: Download Checkstyle run: wget https://github.com/checkstyle/checkstyle/releases/download/checkstyle-8.31/checkstyle-8.31-all.jar diff --git a/.github/workflows/nexus-publish-snapshots.yml b/.github/workflows/nexus-publish-snapshots.yml index 78bf80734c..8b8c411c16 100644 --- a/.github/workflows/nexus-publish-snapshots.yml +++ b/.github/workflows/nexus-publish-snapshots.yml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 1.11 + - name: Set up JDK 1.8 uses: actions/setup-java@v1 with: - java-version: 1.11 + java-version: 1.8 server-id: github # Value of the distributionManagement/repository/id field of the pom.xml settings-path: ${{ github.workspace }} diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml index 452314f2b0..23fafb97b1 100644 --- a/.github/workflows/run_tests.yml +++ b/.github/workflows/run_tests.yml @@ -8,10 +8,10 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Set up JDK 1.11 + - name: Set up JDK 1.8 uses: actions/setup-java@v1 with: - java-version: 1.11 + java-version: 1.8 - name: Load local Maven repository cache uses: actions/cache@v2 From 936e2f1a468fd19ee99a2e23377e7f7fd563e9c3 Mon Sep 17 00:00:00 2001 From: Tobias Koch Date: Fri, 25 Feb 2022 14:38:27 +0100 Subject: [PATCH 10/12] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8b104d50f..d97d27b359 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ _Data Model Library - A collection of QBiC data models._ ## How to Run -Create a runable version of this code with maven and java 11: +Create a runable version of this code with maven and java 8: ``` mvn clean package From cd2670673c707ce2988aec47ca694f597ad90db2 Mon Sep 17 00:00:00 2001 From: Tobias Koch Date: Fri, 25 Feb 2022 15:51:17 +0100 Subject: [PATCH 11/12] downgrade codeql to java 8 (#298) --- .github/workflows/codeql-analysis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e4cfe4013a..ef963f52a2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,10 +39,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v2 - - name: Set up JDK 1.11 + - name: Set up JDK 1.8 uses: actions/setup-java@v1 with: - java-version: 1.11 + java-version: 1.8 settings-path: ${{ github.workspace }} - name: Load local Maven repository cache From 839b29ae5708aab77e0d19c4ce869b43e7af5126 Mon Sep 17 00:00:00 2001 From: Tobias Koch Date: Fri, 25 Feb 2022 17:23:08 +0100 Subject: [PATCH 12/12] Bump xml-manager-lib to 1.7.0 (#301) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 9c83b954a0..15e0618835 100644 --- a/pom.xml +++ b/pom.xml @@ -111,7 +111,7 @@ life.qbic xml-manager-lib - 1.7.0-SNAPSHOT + 1.7.0 ${osgi.scope}