From 068a56963d6ace3d03a6601e8876c6b5489f935e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Sat, 28 Mar 2020 10:21:01 +0100 Subject: [PATCH 01/10] Change RecordDisplay from monospace to verdana --- MassBank-Project/MassBank/src/main/webapp/RecordDisplay2.jsp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MassBank-Project/MassBank/src/main/webapp/RecordDisplay2.jsp b/MassBank-Project/MassBank/src/main/webapp/RecordDisplay2.jsp index a368410c..193ac3b1 100755 --- a/MassBank-Project/MassBank/src/main/webapp/RecordDisplay2.jsp +++ b/MassBank-Project/MassBank/src/main/webapp/RecordDisplay2.jsp @@ -114,7 +114,7 @@ ${structureddata} -
+

${recordstring}
From 0500bd29d1a1d4ed97cea45035effea2b4a8d857 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Tue, 5 May 2020 13:50:06 +0200 Subject: [PATCH 02/10] Update deps --- MassBank-Project/MassBank-OpenAPI/pom.xml | 2 +- MassBank-Project/MassBank-lib/pom.xml | 6 +++--- MassBank-Project/pom.xml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/MassBank-Project/MassBank-OpenAPI/pom.xml b/MassBank-Project/MassBank-OpenAPI/pom.xml index 5f7f04f6..846113b9 100644 --- a/MassBank-Project/MassBank-OpenAPI/pom.xml +++ b/MassBank-Project/MassBank-OpenAPI/pom.xml @@ -15,7 +15,7 @@ MassBank-OpenAPI REST interface - 2.1.1 + 2.1.2 2.30 2.10.2 9.4.24.v20191120 diff --git a/MassBank-Project/MassBank-lib/pom.xml b/MassBank-Project/MassBank-lib/pom.xml index ded613f1..4bef937d 100644 --- a/MassBank-Project/MassBank-lib/pom.xml +++ b/MassBank-Project/MassBank-lib/pom.xml @@ -16,7 +16,7 @@ org.apache.logging.log4j log4j-core - 2.13.1 + 2.13.2 javax.servlet @@ -36,12 +36,12 @@ org.apache.commons commons-lang3 - 3.9 + 3.10 org.apache.commons commons-configuration2 - 2.6 + 2.7 commons-cli diff --git a/MassBank-Project/pom.xml b/MassBank-Project/pom.xml index 8f683c23..4befb2ee 100644 --- a/MassBank-Project/pom.xml +++ b/MassBank-Project/pom.xml @@ -20,7 +20,7 @@ 4.0.1 org.openscience.cdk 2.3 - 2.5.4 + 2.6.0 ${project.version} 2.3.1 From 6708ffe9465e06620fbc20f8d37130f30f412495 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Tue, 5 May 2020 13:53:07 +0200 Subject: [PATCH 03/10] Use version number for maven container --- compose/full-service.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compose/full-service.yml b/compose/full-service.yml index 5ee34b1b..487e8704 100644 --- a/compose/full-service.yml +++ b/compose/full-service.yml @@ -29,16 +29,16 @@ services: - "mariadb:massbank_mariadb" maven: - image: maven:latest + image: maven:3-jdk-11 volumes: - - $HOME/.m2:/var/maven/.m2 + # - $HOME/.m2:/var/maven/.m2 - $PWD/MassBank-Project:/project - environment: - MAVEN_CONFIG: /var/maven/.m2 - user: ${CURRENT_UID} + #environment: + # MAVEN_CONFIG: /var/maven/.m2 + #user: ${CURRENT_UID} dbupdate: - image: maven:latest + image: maven:3-jdk-11 volumes: - $PWD/MassBank-Project:/project - $PWD/conf/full-service.conf:/etc/massbank.conf From 7447c2f502ad70af5122885971b31f7d049cdcd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Wed, 6 May 2020 10:08:07 +0200 Subject: [PATCH 04/10] Revert to _M/Z in tags as discussed in #235 --- Documentation/MassBankRecordFormat.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Documentation/MassBankRecordFormat.md b/Documentation/MassBankRecordFormat.md index 4f1be395..7363abb6 100644 --- a/Documentation/MassBankRecordFormat.md +++ b/Documentation/MassBankRecordFormat.md @@ -904,12 +904,12 @@ Example: AC$MASS_SPECTROMETRY: MASS_ACCURACY 50 ppm over a range of about m/z 100-1000 ``` -##### 2.4.5 Subtag: MASS\_RANGE\_MZ` +##### 2.4.5 Subtag: MASS\_RANGE\_M/Z` Mass Range of the Scan (aka Scanning Range or Scan Range) in m/z. Example: ``` -AC$MASS_SPECTROMETRY: MASS_RANGE_MZ 100-1000 +AC$MASS_SPECTROMETRY: MASS_RANGE_M/Z 100-1000 ``` ##### 2.4.5 Subtag: REAGENT\_GAS @@ -1321,12 +1321,12 @@ Example: MS$FOCUSED_ION: PRECURSOR_INT 10000 ``` -##### 2.5.1 Subtag: PRECURSOR\_MZ +##### 2.5.1 Subtag: PRECURSOR\_M/Z m/z of Precursor Ion in MSn spectrum. Example: ``` -MS$FOCUSED_ION: PRECURSOR_MZ 289.07123 +MS$FOCUSED_ION: PRECURSOR_M/Z 289.07123 ``` Calculated exact mass is preferred to the measured accurate mass of the precursor ion. @@ -1485,8 +1485,8 @@ PK$PEAK: m/z int. rel.int. Line 1: fixed string which denotes the format of Line 2 or later. `PK$PEAK: m/z int. rel.int.` -Line 2 or later: `space` `space` `MZ` `space` `INT` `space` `REL` -- MZ: m/z of the peak. +Line 2 or later: `space` `space` `M/Z` `space` `INT` `space` `REL` +- M/Z: m/z of the peak. - INT: intensity of the peak. - REL: an integer from 1 to 999 which denotes relative intensity of the peak. From b533b7cf3001a5967564f5be426f353422ac2920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Fri, 8 May 2020 08:57:59 +0200 Subject: [PATCH 05/10] Fix numerical issue #242 --- .../main/java/massbank/DatabaseManager.java | 16 ++++----- .../java/massbank/RecordParserDefinition.java | 33 +++++++++---------- .../main/resources/create_massbank_scheme.sql | 8 ++--- .../01-init-massbank.sql | 8 ++--- 4 files changed, 27 insertions(+), 38 deletions(-) diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java index f6afd1cb..1a942269 100755 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java @@ -401,9 +401,9 @@ public Record getAccessionData(String accessionId) { } tmp = this.statementPEAK.executeQuery(); -// acc.add("PK$PEAK", null, "m/z int. rel.int."); while (tmp.next()) { - acc.PK_PEAK_ADD_LINE(Arrays.asList((Double) tmp.getDouble("PK_PEAK_MZ"), (Double) (double) tmp.getFloat("PK_PEAK_INTENSITY"), (Double) (double) tmp.getShort("PK_PEAK_RELATIVE"))); + System.out.println(Arrays.asList(tmp.getDouble("PK_PEAK_MZ"), tmp.getDouble("PK_PEAK_INTENSITY"), Double.valueOf(tmp.getInt("PK_PEAK_RELATIVE")))); + acc.PK_PEAK_ADD_LINE(Arrays.asList(tmp.getDouble("PK_PEAK_MZ"), tmp.getDouble("PK_PEAK_INTENSITY"), Double.valueOf(tmp.getInt("PK_PEAK_RELATIVE")))); String PK_ANNOTATION = tmp.getString("PK_ANNOTATION"); if(PK_ANNOTATION != null) acc.PK_ANNOTATION_ADD_LINE(Arrays.asList(PK_ANNOTATION.split(" "))); @@ -552,6 +552,7 @@ public Record.Structure getStructureOfAccession(String accessionId) { public void persistAccessionFile(Record acc) { boolean bulk=false; + // get contributor ID Integer conId = -1; try { String sql = "SELECT ID FROM CONTRIBUTOR WHERE SHORT_NAME = ?"; @@ -849,16 +850,13 @@ public void persistAccessionFile(Record acc) { } //System.out.println(System.nanoTime()); + for (List peak : acc.PK_PEAK()) { statementInsertPEAK.setString(1, accession); - statementInsertPEAK.setDouble(2, peak.get(0)); - statementInsertPEAK.setFloat(3, (float)(double) peak.get(1)); - statementInsertPEAK.setShort(4, (short)(double) peak.get(2)); + statementInsertPEAK.setDouble(2, peak.get(0).doubleValue()); + statementInsertPEAK.setDouble(3, peak.get(1).doubleValue()); + statementInsertPEAK.setInt(4, peak.get(2).intValue()); statementInsertPEAK.setNull(5, java.sql.Types.VARCHAR); - // statementInsertPEAK.setNull(5, java.sql.Types.VARCHAR); - // statementInsertPEAK.setNull(6, java.sql.Types.SMALLINT); - // statementInsertPEAK.setNull(7, java.sql.Types.FLOAT); - // statementInsertPEAK.setNull(8, java.sql.Types.FLOAT); // statementInsertPEAK.executeUpdate(); statementInsertPEAK.addBatch(); } diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java index 7f8c7368..333c3985 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java @@ -107,6 +107,17 @@ public RecordParserDefinition(Record callback, boolean strict) { def("multiline_start", StringParser.of(" ")); def("uint_primitive", digit().plus().flatten()); + def("number_primitive", + digit().plus() + .seq( + CharacterParser.of('.') + .seq(digit().plus()).optional() + ) + .seq( + CharacterParser.anyOf("eE") + .seq(digit().plus()).optional() + ).flatten() + ); // 2.1 Record Specific Information // 2.1.1 ACCESSION @@ -633,23 +644,11 @@ public RecordParserDefinition(Record callback, boolean strict) { // Example // CH$EXACT_MASS: 430.38108 // A value with 5 digits after the decimal point is recommended. - def("number", - digit().plus() - .seq( - CharacterParser.of('.') - .seq(digit().plus()).optional() - ) - .seq( - CharacterParser.anyOf("eE") - .seq(digit().plus()).optional() - ).flatten() - ); - def("ch_exact_mass", StringParser.of("CH$EXACT_MASS") .seq(ref("tagsep")) .seq( - ref("number") + ref("number_primitive") .map((String value) -> { double d = Double.parseDouble(value); callback.CH_EXACT_MASS(d); @@ -1514,7 +1513,7 @@ else if (ret != INCHI_RET.OKAY) { ) .seq( StringParser.of(" ") - .seq(ref("number").trim()) + .seq(ref("number_primitive").trim()) .pick(1) .seq( CharacterParser.word().or(CharacterParser.anyOf("-+,()[]{}\\/.:$^'`_*?<>=")) @@ -1580,16 +1579,16 @@ else if (ret != INCHI_RET.OKAY) { .seq( StringParser.of(" ") .seq( - ref("number") + ref("number_primitive") .seq(CharacterParser.of(' ')).pick(0) ) .pick(1) .seq( - ref("number") + ref("number_primitive") .seq(CharacterParser.of(' ')).pick(0) ) .seq( - ref("number") + ref("uint_primitive") ) .map((List value) -> { //System.out.println(value); diff --git a/MassBank-Project/MassBank-lib/src/main/resources/create_massbank_scheme.sql b/MassBank-Project/MassBank-lib/src/main/resources/create_massbank_scheme.sql index 475cbcb0..593c3fe6 100644 --- a/MassBank-Project/MassBank-lib/src/main/resources/create_massbank_scheme.sql +++ b/MassBank-Project/MassBank-lib/src/main/resources/create_massbank_scheme.sql @@ -220,12 +220,8 @@ CREATE TABLE MS_DATA_PROCESSING ( CREATE TABLE PEAK ( RECORD VARCHAR(255) NOT NULL, PK_PEAK_MZ DOUBLE NOT NULL, - PK_PEAK_INTENSITY FLOAT NOT NULL, - PK_PEAK_RELATIVE SMALLINT NOT NULL, - -- PK_ANNOTATION_TENTATIVE_FORMULA VARCHAR(600), - -- PK_ANNOTATION_FORMULA_COUNT SMALLINT, - -- PK_ANNOTATION_THEORETICAL_MASS FLOAT, - -- PK_ANNTOATION_ERROR_PPM FLOAT, + PK_PEAK_INTENSITY DOUBLE NOT NULL, + PK_PEAK_RELATIVE INTEGER NOT NULL, PK_ANNOTATION VARCHAR(600), PRIMARY KEY (RECORD,PK_PEAK_MZ), FOREIGN KEY (RECORD) diff --git a/modules/sql/docker-entrypoint-initdb.d/01-init-massbank.sql b/modules/sql/docker-entrypoint-initdb.d/01-init-massbank.sql index 8ccd814f..b85f8366 100644 --- a/modules/sql/docker-entrypoint-initdb.d/01-init-massbank.sql +++ b/modules/sql/docker-entrypoint-initdb.d/01-init-massbank.sql @@ -225,12 +225,8 @@ CREATE TABLE MS_DATA_PROCESSING ( CREATE TABLE PEAK ( RECORD VARCHAR(255) NOT NULL, PK_PEAK_MZ DOUBLE NOT NULL, - PK_PEAK_INTENSITY FLOAT NOT NULL, - PK_PEAK_RELATIVE SMALLINT NOT NULL, - -- PK_ANNOTATION_TENTATIVE_FORMULA VARCHAR(600), - -- PK_ANNOTATION_FORMULA_COUNT SMALLINT, - -- PK_ANNOTATION_THEORETICAL_MASS FLOAT, - -- PK_ANNTOATION_ERROR_PPM FLOAT, + PK_PEAK_INTENSITY DOUBLE NOT NULL, + PK_PEAK_RELATIVE INTEGER NOT NULL, PK_ANNOTATION VARCHAR(600), PRIMARY KEY (RECORD,PK_PEAK_MZ), FOREIGN KEY (RECORD) From 6ca84fe854121ba3eb67d2f79ac98a26af20ed7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Fri, 8 May 2020 17:04:40 +0200 Subject: [PATCH 06/10] Fix numerical issue #242 by using BigDecimal, add serialisation test to Validator --- .../main/java/massbank/DatabaseManager.java | 23 ++- .../src/main/java/massbank/Record.java | 177 ++++++++++-------- .../java/massbank/RecordParserDefinition.java | 18 +- .../src/main/java/massbank/Validator.java | 54 ++++-- .../massbank/web/export/RecordExporter.java | 10 +- .../main/resources/create_massbank_scheme.sql | 2 + .../01-init-massbank.sql | 6 +- 7 files changed, 171 insertions(+), 119 deletions(-) diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java index 1a942269..e401e63d 100755 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java @@ -25,6 +25,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.StringReader; +import java.math.BigDecimal; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -36,6 +37,7 @@ import java.util.List; import org.apache.commons.configuration2.ex.ConfigurationException; import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.LogManager; @@ -128,7 +130,7 @@ public class DatabaseManager { private final static String insertAC_CHROMATOGRAPHY = "INSERT INTO AC_CHROMATOGRAPHY VALUES(?,?,?)"; private final static String insertMS_FOCUSED_ION = "INSERT INTO MS_FOCUSED_ION VALUES(?,?,?)"; private final static String insertMS_DATA_PROCESSING = "INSERT INTO MS_DATA_PROCESSING VALUES(?,?,?)"; - private final static String insertPEAK = "INSERT INTO PEAK VALUES(?,?,?,?,?)"; + private final static String insertPEAK = "INSERT INTO PEAK VALUES(?,?,?,?,?,?,?)"; private final static String updatePEAKs = "UPDATE PEAK SET PK_ANNOTATION = ? WHERE RECORD = ? AND PK_PEAK_MZ = ?"; private final static String insertANNOTATION_HEADER = "INSERT INTO ANNOTATION_HEADER VALUES(?,?)"; @@ -402,8 +404,9 @@ public Record getAccessionData(String accessionId) { tmp = this.statementPEAK.executeQuery(); while (tmp.next()) { - System.out.println(Arrays.asList(tmp.getDouble("PK_PEAK_MZ"), tmp.getDouble("PK_PEAK_INTENSITY"), Double.valueOf(tmp.getInt("PK_PEAK_RELATIVE")))); - acc.PK_PEAK_ADD_LINE(Arrays.asList(tmp.getDouble("PK_PEAK_MZ"), tmp.getDouble("PK_PEAK_INTENSITY"), Double.valueOf(tmp.getInt("PK_PEAK_RELATIVE")))); + BigDecimal mz = (new BigDecimal(String.valueOf(tmp.getDouble("PK_PEAK_MZ")))).setScale(tmp.getInt("PK_PEAK_MZ_SIGNIFICANT")); + BigDecimal intensity = (new BigDecimal(String.valueOf(tmp.getDouble("PK_PEAK_INTENSITY")))).setScale(tmp.getInt("PK_PEAK_INTENSITY_SIGNIFICANT")); + acc.PK_PEAK_ADD_LINE(Triple.of(mz, intensity, tmp.getInt("PK_PEAK_RELATIVE"))); String PK_ANNOTATION = tmp.getString("PK_ANNOTATION"); if(PK_ANNOTATION != null) acc.PK_ANNOTATION_ADD_LINE(Arrays.asList(PK_ANNOTATION.split(" "))); @@ -851,12 +854,16 @@ public void persistAccessionFile(Record acc) { //System.out.println(System.nanoTime()); - for (List peak : acc.PK_PEAK()) { + for (Triple peak : acc.PK_PEAK()) { statementInsertPEAK.setString(1, accession); - statementInsertPEAK.setDouble(2, peak.get(0).doubleValue()); - statementInsertPEAK.setDouble(3, peak.get(1).doubleValue()); - statementInsertPEAK.setInt(4, peak.get(2).intValue()); - statementInsertPEAK.setNull(5, java.sql.Types.VARCHAR); + statementInsertPEAK.setDouble(2, peak.getLeft().doubleValue()); + statementInsertPEAK.setInt(3, peak.getLeft().scale()); + + statementInsertPEAK.setDouble(4, peak.getMiddle().doubleValue()); + statementInsertPEAK.setInt(5, peak.getMiddle().scale()); + + statementInsertPEAK.setInt(6, peak.getRight().intValue()); + statementInsertPEAK.setNull(7, java.sql.Types.VARCHAR); // statementInsertPEAK.executeUpdate(); statementInsertPEAK.addBatch(); } diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/Record.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/Record.java index a9b3b530..6081e343 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/Record.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/Record.java @@ -1,5 +1,26 @@ +/******************************************************************************* + * Copyright (C) 2017 MassBank consortium + * + * This file is part of MassBank. + * + * MassBank is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + ******************************************************************************/ package massbank; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -9,6 +30,7 @@ import java.util.regex.Pattern; import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.json.JSONArray; @@ -26,21 +48,26 @@ import net.sf.jniinchi.INCHI_RET; +/** + * This class keeps all data of a record. + * @author rmeier + * @version 05-05-2020 + */ public class Record { private static final Logger logger = LogManager.getLogger(Record.class); private final String contributor; private String accession; - private boolean deprecated = false; - private String deprecated_content = null; + private boolean deprecated; + private String deprecated_content; private List record_title; private String date; private String authors; private String license; private String copyright; // optional - private String project; // optional private String publication; // optional + private String project; // optional private List comment; // optional private List ch_name; private List ch_compound_class; @@ -65,7 +92,7 @@ public class Record { private List pk_annotation_header; // optional private final List> pk_annotation; // optional private int pk_num_peak; - private final List> pk_peak; + private final List> pk_peak; public Record(String contributor) { this.contributor = contributor; @@ -81,12 +108,10 @@ public Record(String contributor) { ms_data_processing = new ArrayList>(); pk_annotation_header = new ArrayList(); pk_annotation = new ArrayList>(); - copyright = null; - publication = null; // set default values for mandatory fields pk_num_peak = -1; - pk_peak = new ArrayList>(); + pk_peak = new ArrayList>(); } public String CONTRIBUTOR() { @@ -413,12 +438,12 @@ public void PK_NUM_PEAK(int value) { pk_num_peak = value; } - // PK_PEAK is a two-dimensional List - public List> PK_PEAK() { + // PK_PEAK is a List with Triple values M/Z, intensity, rel. intensity + public List> PK_PEAK() { return pk_peak; } - public void PK_PEAK_ADD_LINE(List value) { - pk_peak.add(new ArrayList(value)); + public void PK_PEAK_ADD_LINE(Triple peak) { + pk_peak.add(peak); } public String toString() { @@ -440,61 +465,43 @@ public String toString() { sb.append("PUBLICATION: " + PUBLICATION() + "\n"); if (PROJECT() != null) sb.append("PROJECT: " + PROJECT() + "\n"); - if (CH_NAME() != null) { - for (String ch_name : CH_NAME()) - sb.append("CH$NAME: " + ch_name + "\n"); - } + for (String comment : COMMENT()) + sb.append("COMMENT: " + comment + "\n"); - sb.append("CH$COMPOUND_CLASS: " + CH_COMPOUND_CLASS().get(0)); - for (String ch_compound_class : CH_COMPOUND_CLASS().subList(1, CH_COMPOUND_CLASS().size())) { - sb.append("; " + ch_compound_class ); - } - sb.append("\n"); - + for (String ch_name : CH_NAME()) + sb.append("CH$NAME: " + ch_name + "\n"); + sb.append("CH$COMPOUND_CLASS: " + String.join("; ", CH_COMPOUND_CLASS()) + "\n"); sb.append("CH$FORMULA: " + CH_FORMULA() + "\n"); sb.append("CH$EXACT_MASS: " + CH_EXACT_MASS() + "\n"); sb.append("CH$SMILES: " + CH_SMILES() + "\n"); sb.append("CH$IUPAC: " + CH_IUPAC() + "\n"); + for (Pair link : CH_LINK()) + sb.append("CH$LINK: " + link.getKey() + " " + link.getValue() + "\n"); - if (CH_LINK() != null) { - for (Pair link : CH_LINK()) - sb.append("CH$LINK: " + link.getKey() + " " + link.getValue() + "\n"); - } if (SP_SCIENTIFIC_NAME() != null) sb.append("SP$SCIENTIFIC_NAME: " + SP_SCIENTIFIC_NAME() + "\n"); if (SP_LINEAGE() != null) sb.append("SP$LINEAGE: " + SP_LINEAGE() + "\n"); - if (SP_LINK() != null) { - for (Pair link : SP_LINK()) - sb.append("SP$LINK: " + link.getKey() + " " + link.getValue() + "\n"); - } - if (SP_SAMPLE() != null) { - for (String sample : SP_SAMPLE()) - sb.append("SP$SAMPLE: " + sample + "\n"); - } + for (Pair link : SP_LINK()) + sb.append("SP$LINK: " + link.getKey() + " " + link.getValue() + "\n"); + for (String sample : SP_SAMPLE()) + sb.append("SP$SAMPLE: " + sample + "\n"); + sb.append("AC$INSTRUMENT: " + AC_INSTRUMENT() + "\n"); sb.append("AC$INSTRUMENT_TYPE: " + AC_INSTRUMENT_TYPE() + "\n"); - sb.append("AC$MASS_SPECTROMETRY: MS_TYPE: " + AC_MASS_SPECTROMETRY_MS_TYPE() + "\n"); - sb.append("AC$MASS_SPECTROMETRY: ION_MODE: " + AC_MASS_SPECTROMETRY_ION_MODE() + "\n"); - if (AC_MASS_SPECTROMETRY() != null) { - for (Pair ac_mass_spectrometry : AC_MASS_SPECTROMETRY()) - sb.append("AC$MASS_SPECTROMETRY: " + ac_mass_spectrometry.getKey() + " " + ac_mass_spectrometry.getValue() + "\n"); - } - if (AC_CHROMATOGRAPHY() != null) { - for (Pair ac_chromatography : AC_CHROMATOGRAPHY()) - sb.append("AC$CHROMATOGRAPHY: " + ac_chromatography.getKey() + " " + ac_chromatography.getValue() + "\n"); - } - if (MS_FOCUSED_ION() != null) { - for (Pair ms_focued_ion : MS_FOCUSED_ION()) - sb.append("MS$FOCUSED_ION: " + ms_focued_ion.getKey() + " " + ms_focued_ion.getValue() + "\n"); - } - if (MS_DATA_PROCESSING() != null) { - for (Pair ms_data_processing : MS_DATA_PROCESSING()) - sb.append("MS$DATA_PROCESSING: " + ms_data_processing.getKey() + " " + ms_data_processing.getValue() + "\n"); - } + sb.append("AC$MASS_SPECTROMETRY: MS_TYPE " + AC_MASS_SPECTROMETRY_MS_TYPE() + "\n"); + sb.append("AC$MASS_SPECTROMETRY: ION_MODE " + AC_MASS_SPECTROMETRY_ION_MODE() + "\n"); + for (Pair ac_mass_spectrometry : AC_MASS_SPECTROMETRY()) + sb.append("AC$MASS_SPECTROMETRY: " + ac_mass_spectrometry.getKey() + " " + ac_mass_spectrometry.getValue() + "\n"); + for (Pair ac_chromatography : AC_CHROMATOGRAPHY()) + sb.append("AC$CHROMATOGRAPHY: " + ac_chromatography.getKey() + " " + ac_chromatography.getValue() + "\n"); + for (Pair ms_focued_ion : MS_FOCUSED_ION()) + sb.append("MS$FOCUSED_ION: " + ms_focued_ion.getKey() + " " + ms_focued_ion.getValue() + "\n"); + for (Pair ms_data_processing : MS_DATA_PROCESSING()) + sb.append("MS$DATA_PROCESSING: " + ms_data_processing.getKey() + " " + ms_data_processing.getValue() + "\n"); + sb.append("PK$SPLASH: " + PK_SPLASH() + "\n"); - - if (PK_ANNOTATION_HEADER() != null) { + if (!PK_ANNOTATION_HEADER().isEmpty()) { sb.append("PK$ANNOTATION:"); for (String annotation_header_item : PK_ANNOTATION_HEADER()) sb.append(" " + annotation_header_item); @@ -509,26 +516,42 @@ public String toString() { sb.append("PK$NUM_PEAK: " + PK_NUM_PEAK() + "\n"); sb.append("PK$PEAK: m/z int. rel.int.\n"); - for (List peak_line : PK_PEAK()) { - sb.append(" "); - for (Double peak_line_item : peak_line ) - sb.append(" " + peak_line_item.toString()); - sb.append("\n"); + for (Triple peak : PK_PEAK()) { + sb.append(" " + peak.getLeft() + " " + peak.getMiddle() + " " + peak.getRight() + "\n"); } - - sb.append("//"); + sb.append("//\n"); return sb.toString(); } public String createRecordString() { StringBuilder sb = new StringBuilder(); + + + + + + + + + + + + + + + + + + + sb.append("ACCESSION: " + ACCESSION() + "
\n"); sb.append("RECORD_TITLE: " + RECORD_TITLE1() + "
\n"); sb.append("DATE: " + DATE() + "
\n"); sb.append("AUTHORS: " + AUTHORS() + "
\n"); sb.append("LICENSE: " + LICENSE() + "
\n"); - if (COPYRIGHT() != null) sb.append("COPYRIGHT: " + COPYRIGHT() + "
\n"); + if (COPYRIGHT() != null) + sb.append("COPYRIGHT: " + COPYRIGHT() + "
\n"); if (PUBLICATION() != null) { String pub=PUBLICATION(); String regex_doi = "10\\.\\d{3,9}\\/[\\-\\._;\\(\\)\\/:a-zA-Z0-9]+[a-zA-Z0-9]"; @@ -553,6 +576,7 @@ public String createRecordString() { for (String comment : COMMENT()) sb.append("COMMENT: " + comment + "
\n"); sb.append("
\n"); + for (String ch_name : CH_NAME()) sb.append("CH$NAME: " + ch_name + "
\n"); sb.append("CH$COMPOUND_CLASS: " + String.join("; ", CH_COMPOUND_CLASS()) + "
\n"); @@ -560,7 +584,6 @@ public String createRecordString() { sb.append("CH$EXACT_MASS: " + CH_EXACT_MASS() + "
\n"); sb.append("CH$SMILES: " + CH_SMILES() + "
\n"); sb.append("CH$IUPAC: " + CH_IUPAC() + "
\n"); - for (Pair link : CH_LINK()) { switch(link.getKey()){ case "CAS": @@ -622,29 +645,25 @@ public String createRecordString() { sb.append("SP$LINK: " + link.getKey() + " " + link.getValue() + "
\n"); for (String sample : SP_SAMPLE()) sb.append("SP$SAMPLE: " + sample + "
\n"); - - sb.append("
\n"); + sb.append("AC$INSTRUMENT: " + AC_INSTRUMENT() + "
\n"); sb.append("AC$INSTRUMENT_TYPE: " + AC_INSTRUMENT_TYPE() + "
\n"); - sb.append("AC$MASS_SPECTROMETRY: MS_TYPE: " + AC_MASS_SPECTROMETRY_MS_TYPE() + "
\n"); - sb.append("AC$MASS_SPECTROMETRY: ION_MODE: " + AC_MASS_SPECTROMETRY_ION_MODE() + "
\n"); + sb.append("AC$MASS_SPECTROMETRY: MS_TYPE " + AC_MASS_SPECTROMETRY_MS_TYPE() + "
\n"); + sb.append("AC$MASS_SPECTROMETRY: ION_MODE " + AC_MASS_SPECTROMETRY_ION_MODE() + "
\n"); for (Pair ac_mass_spectrometry : AC_MASS_SPECTROMETRY()) sb.append("AC$MASS_SPECTROMETRY: " + ac_mass_spectrometry.getKey() + " " + ac_mass_spectrometry.getValue() + "
\n"); for (Pair ac_chromatography : AC_CHROMATOGRAPHY()) sb.append("AC$CHROMATOGRAPHY: " + ac_chromatography.getKey() + " " + ac_chromatography.getValue() + "
\n"); + sb.append("
\n"); - - if (!MS_FOCUSED_ION().isEmpty() || !MS_DATA_PROCESSING().isEmpty()) sb.append("
\n"); for (Pair ms_focued_ion : MS_FOCUSED_ION()) sb.append("MS$FOCUSED_ION: " + ms_focued_ion.getKey() + " " + ms_focued_ion.getValue() + "
\n"); for (Pair ms_data_processing : MS_DATA_PROCESSING()) sb.append("MS$DATA_PROCESSING: " + ms_data_processing.getKey() + " " + ms_data_processing.getValue() + "
\n"); + if (!MS_FOCUSED_ION().isEmpty() || !MS_DATA_PROCESSING().isEmpty()) sb.append("
\n"); - sb.append("
\n"); sb.append("PK$SPLASH: " + PK_SPLASH() + "
\n"); - - if (!PK_ANNOTATION_HEADER().isEmpty()) { sb.append("PK$ANNOTATION:"); for (String annotation_header_item : PK_ANNOTATION_HEADER()) @@ -657,14 +676,10 @@ public String createRecordString() { sb.append("
\n"); } } - sb.append("PK$NUM_PEAK: " + PK_NUM_PEAK() + "
\n"); sb.append("PK$PEAK: m/z int. rel.int.
\n"); - for (List peak_line : PK_PEAK()) { - sb.append(" "); - for (Double peak_line_item : peak_line ) - sb.append(" " + peak_line_item.toString()); - sb.append("
\n"); + for (Triple peak : PK_PEAK()) { + sb.append("  " + peak.getLeft() + " " + peak.getMiddle() + " " + peak.getRight() + "
\n"); } sb.append("//"); @@ -719,8 +734,8 @@ public String createPeakListForSpectrumViewer() { // convert a list of lists [[mz, int, rel.int], [...], ...] // to String "mz,rel.int@mz,rel.int@..." List peaks = new ArrayList<>(); - for (List peak : PK_PEAK()) { - peaks.add(peak.get(0)+","+peak.get(2)); + for (Triple peak : PK_PEAK()) { + peaks.add(peak.getRight()+","+peak.getLeft()); } return String.join("@", peaks); } @@ -728,8 +743,8 @@ public String createPeakListForSpectrumViewer() { public JSONObject createPeakListData() { JSONObject result = new JSONObject(); JSONArray peaklist = new JSONArray(); - for (List peak : PK_PEAK()) { - peaklist.put(new JSONObject().put("intensity", peak.get(2)).put("mz", peak.get(0))); + for (Triple peak : PK_PEAK()) { + peaklist.put(new JSONObject().put("intensity", peak.getRight()).put("mz", peak.getLeft())); } result.put("peaks", peaklist); return result; diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java index 333c3985..50c38b41 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java @@ -3,6 +3,7 @@ import static org.petitparser.parser.primitive.CharacterParser.digit; import static org.petitparser.parser.primitive.CharacterParser.letter; +import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -13,6 +14,7 @@ import java.util.function.Function; import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.lang3.tuple.Triple; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.openscience.cdk.DefaultChemObjectBuilder; @@ -1592,10 +1594,10 @@ else if (ret != INCHI_RET.OKAY) { ) .map((List value) -> { //System.out.println(value); - List list = new ArrayList(); - for(String val : value) - list.add(Double.parseDouble(val)); - callback.PK_PEAK_ADD_LINE(list); + Triple peak = Triple.of(new BigDecimal(value.get(0)), + new BigDecimal(value.get(1)), + Integer.parseInt(value.get(2))); + callback.PK_PEAK_ADD_LINE(peak); return value; }) .seq(Token.NEWLINE_PARSER).plus() @@ -1750,7 +1752,7 @@ else if (ret != INCHI_RET.OKAY) { // validate the number of peaks in the peaklist Integer num_peak= callback.PK_NUM_PEAK(); - List> pk_peak = callback.PK_PEAK(); + List> pk_peak = callback.PK_PEAK(); if (pk_peak.size() != num_peak) { StringBuilder sb = new StringBuilder(); sb.append("Incorrect number of peaks in peaklist. "); @@ -1761,8 +1763,8 @@ else if (ret != INCHI_RET.OKAY) { // validate the SPLASH List ions = new ArrayList(); - for (List peak_line : pk_peak) { - ions.add(new Ion(peak_line.get(0), peak_line.get(1))); + for (Triple peak : pk_peak) { + ions.add(new Ion(peak.getLeft().doubleValue(), peak.getMiddle().doubleValue())); } Splash splashFactory = SplashFactory.create(); Spectrum spectrum = new SpectrumImpl(ions, SpectraType.MS); @@ -1778,7 +1780,7 @@ else if (ret != INCHI_RET.OKAY) { // check peak sorting for (int i=0; i=0) { + if ((pk_peak.get(i).getLeft().compareTo(pk_peak.get(i+1).getLeft()))>=0) { StringBuilder sb = new StringBuilder(); sb.append("The peaks in the peak list are not sorted.\n"); sb.append("Error in line " + pk_peak.get(i).toString() + ".\n"); diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/Validator.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/Validator.java index ddb49b1b..b07aff6f 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/Validator.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/Validator.java @@ -26,15 +26,15 @@ public class Validator { private static final Logger logger = LogManager.getLogger(Validator.class); /** - * Returns true if there is any suspicious character in recordstring. + * Returns true if there is any suspicious character in recordString. */ - public static boolean hasNonStandardChars(String recordstring) { + public static boolean hasNonStandardChars(String recordString) { // the following are allowed char[] myCharSet = new char[] {'–', 'ä', 'ö', 'ü', 'ó', 'é', 'µ', 'á', 'É'}; Arrays.sort(myCharSet); - for (int i = 0; i < recordstring.length(); i++) { - if (recordstring.charAt(i) > 0x7F && (Arrays.binarySearch(myCharSet, recordstring.charAt(i))<0)) { - String[] tokens = recordstring.split("\\r?\\n"); + for (int i = 0; i < recordString.length(); i++) { + if (recordString.charAt(i) > 0x7F && (Arrays.binarySearch(myCharSet, recordString.charAt(i))<0)) { + String[] tokens = recordString.split("\\r?\\n"); logger.warn("Non standard ASCII character found. This might be an error. Please check carefully."); int line = 0, col = 0, offset = 0; for (String token : tokens) { @@ -55,26 +55,26 @@ public static boolean hasNonStandardChars(String recordstring) { } /** - * Validate a recordstring and return the parsed information in a {@link Record} + * Validate a recordString and return the parsed information in a {@link Record} * or null if the validation was not successful. Be strict in validation. */ - public static Record validate(String recordstring, String contributor) { - return validate(recordstring, contributor, true); + public static Record validate(String recordString, String contributor) { + return validate(recordString, contributor, true); } /** - * Validate a recordstring and return the parsed information in a {@link Record} + * Validate a recordString and return the parsed information in a {@link Record} * or null if the validation was not successful. Be less strict if * strict is false. This is useful in automatic repair routines. */ - public static Record validate(String recordstring, String contributor, boolean strict) { + public static Record validate(String recordString, String contributor, boolean strict) { Record record = new Record(contributor); Parser recordparser = new RecordParser(record, strict); - Result res = recordparser.parse(recordstring); + Result res = recordparser.parse(recordString); if (res.isFailure()) { logger.error(res.getMessage()); int position = res.getPosition(); - String[] tokens = recordstring.split("\\n"); + String[] tokens = recordString.split("\\n"); int line = 0, col = 0, offset = 0; for (String token : tokens) { @@ -125,12 +125,12 @@ else if (argumentf.isDirectory()) { AtomicBoolean haserror = new AtomicBoolean(false); recordfiles.parallelStream().forEach(filename -> { - String recordstring; + String recordString; Record record=null; try { - recordstring = FileUtils.readFileToString(filename, StandardCharsets.UTF_8); - hasNonStandardChars(recordstring); - record = validate(recordstring, ""); + recordString = FileUtils.readFileToString(filename, StandardCharsets.UTF_8); + hasNonStandardChars(recordString); + record = validate(recordString, ""); if (record == null) { logger.error("error in " + filename); haserror.set(true); @@ -138,6 +138,28 @@ record = validate(recordstring, ""); else { logger.trace("validation passed for " + filename); } + + // validate correct serialisation String -> Record class -> String + String recordStringFromRecord = record.toString(); + int position = StringUtils.indexOfDifference(new String [] {recordString, recordStringFromRecord}); + if (position != -1) { + logger.error("File content differs from generated record string.\nThis might be a code problem. Please Report!"); + String[] tokens = recordStringFromRecord.split("\\n"); + int line = 0, col = 0, offset = 0; + for (String token : tokens) { + offset = offset + token.length() + 1; + if (position < offset) { + col = position - (offset - (token.length() + 1)); + logger.error("Error in line " + line + "."); + logger.error(tokens[line]); + StringBuilder error_at = new StringBuilder(StringUtils.repeat(" ", col)); + error_at.append('^'); + logger.error(error_at); + break; + } + line++; + } + } } catch (IOException e) { e.printStackTrace(); System.exit(1); diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/web/export/RecordExporter.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/web/export/RecordExporter.java index b42dd100..a927a4b6 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/web/export/RecordExporter.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/web/export/RecordExporter.java @@ -4,6 +4,7 @@ import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.math.BigDecimal; import java.nio.charset.Charset; import java.sql.SQLException; import java.util.ArrayList; @@ -14,6 +15,7 @@ import org.apache.commons.configuration2.ex.ConfigurationException; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.tuple.Triple; import org.openscience.cdk.exception.CDKException; import org.openscience.cdk.inchi.InChIGeneratorFactory; import org.openscience.cdk.smiles.SmilesGenerator; @@ -331,13 +333,13 @@ public static List recordToNIST_MSP(Record record) throws CDKException{ list.add("Splash" + ": " + record.PK_SPLASH()); list.add("Num Peaks" + ": " + record.PK_NUM_PEAK()); - for(List peak : record.PK_PEAK()){ + for(Triple peak : record.PK_PEAK()){ // StringBuilder peakS = new StringBuilder(); // peakS.append(peak.get(0)); // for(int i = 1; i < peak.size(); i++) // peakS.append(" " + peak.get(i)); // list.add(peakS.toString()); - list.add(peak.get(0) + " " + peak.get(2)); + list.add(peak.getLeft() + " " + peak.getRight()); } return list; @@ -458,8 +460,8 @@ public static List recordToRIKEN_MSP(Record record) throws CDKException{ list.add("LINKS" + ": " + links); list.add("Comment" + ": " + comment); list.add("Num Peaks" + ": " + record.PK_NUM_PEAK()); - for(List peak : record.PK_PEAK()) - list.add(peak.get(0) + "\t" + peak.get(2)); + for(Triple peak : record.PK_PEAK()) + list.add(peak.getLeft() + "\t" + peak.getRight()); return list; } diff --git a/MassBank-Project/MassBank-lib/src/main/resources/create_massbank_scheme.sql b/MassBank-Project/MassBank-lib/src/main/resources/create_massbank_scheme.sql index 593c3fe6..2ff81e1c 100644 --- a/MassBank-Project/MassBank-lib/src/main/resources/create_massbank_scheme.sql +++ b/MassBank-Project/MassBank-lib/src/main/resources/create_massbank_scheme.sql @@ -220,7 +220,9 @@ CREATE TABLE MS_DATA_PROCESSING ( CREATE TABLE PEAK ( RECORD VARCHAR(255) NOT NULL, PK_PEAK_MZ DOUBLE NOT NULL, + PK_PEAK_MZ_SIGNIFICANT INTEGER NOT NULL, PK_PEAK_INTENSITY DOUBLE NOT NULL, + PK_PEAK_INTENSITY_SIGNIFICANT INTEGER NOT NULL, PK_PEAK_RELATIVE INTEGER NOT NULL, PK_ANNOTATION VARCHAR(600), PRIMARY KEY (RECORD,PK_PEAK_MZ), diff --git a/modules/sql/docker-entrypoint-initdb.d/01-init-massbank.sql b/modules/sql/docker-entrypoint-initdb.d/01-init-massbank.sql index b85f8366..00746e73 100644 --- a/modules/sql/docker-entrypoint-initdb.d/01-init-massbank.sql +++ b/modules/sql/docker-entrypoint-initdb.d/01-init-massbank.sql @@ -223,9 +223,11 @@ CREATE TABLE MS_DATA_PROCESSING ( ); CREATE TABLE PEAK ( - RECORD VARCHAR(255) NOT NULL, - PK_PEAK_MZ DOUBLE NOT NULL, + RECORD VARCHAR(255) NOT NULL, + PK_PEAK_MZ DOUBLE NOT NULL, + PK_PEAK_MZ_SIGNIFICANT INTEGER NOT NULL, PK_PEAK_INTENSITY DOUBLE NOT NULL, + PK_PEAK_INTENSITY_SIGNIFICANT INTEGER NOT NULL, PK_PEAK_RELATIVE INTEGER NOT NULL, PK_ANNOTATION VARCHAR(600), PRIMARY KEY (RECORD,PK_PEAK_MZ), From 6cdcf8dae5ced4b9d0d0b30ec38904908e00881d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Mon, 11 May 2020 15:46:40 +0200 Subject: [PATCH 07/10] Add option to read in a record and write it out again from internal representation. --- .../MassBank-lib/src/main/java/massbank/AddMetaData.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/AddMetaData.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/AddMetaData.java index 2c1b2230..39d60466 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/AddMetaData.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/AddMetaData.java @@ -392,6 +392,7 @@ public static void main(String[] arguments) throws Exception { options.addOption("p", "publication", false, "format PUBLICATION tag from given DOI to follow the guidelines of ACS"); options.addOption("n", "name", false, "fix common problems in CH$NAME tag"); options.addOption("l", "link", false, "add links to CH$LINK tag"); + options.addOption("r", "rewrite", false, "read and rewrite the file."); options.addOption("ms_focused_ion", false, "Inspect MS$FOCUSED_ION"); CommandLine cmd = null; try { @@ -446,6 +447,8 @@ else if (record.DEPRECATED()) { if (cmd.hasOption("l") || cmd.hasOption("a")) recordstring2=doLink(record, recordstring2); if (cmd.hasOption("ms_focused_ion") || cmd.hasOption("a")) recordstring2=doFocusedIon(record, recordstring2); + if (cmd.hasOption("r")) recordstring2=record.toString(); + if (!recordstring.equals(recordstring2)) { Record record2 = Validator.validate(recordstring2, ""); if (record2 == null) { From 985a68a17b2cad221ff9377d4555d7c0b3a6505f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Mon, 11 May 2020 15:54:33 +0200 Subject: [PATCH 08/10] Change exact mass to BigDecimal for correct serialization. --- .../main/java/massbank/DatabaseManager.java | 4 +-- .../src/main/java/massbank/Record.java | 29 +++++-------------- .../java/massbank/RecordParserDefinition.java | 29 ++++++++++--------- .../src/main/java/massbank/Validator.java | 5 ++-- .../massbank/web/export/RecordExporter.java | 2 +- 5 files changed, 28 insertions(+), 41 deletions(-) diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java index e401e63d..7f9d1308 100755 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/DatabaseManager.java @@ -435,7 +435,7 @@ public Record getAccessionData(String accessionId) { set = this.statementCOMPOUND.executeQuery(); while (set.next()) { acc.CH_FORMULA(set.getString("CH_FORMULA")); - acc.CH_EXACT_MASS(set.getDouble("CH_EXACT_MASS")); + acc.CH_EXACT_MASS(new BigDecimal(set.getDouble("CH_EXACT_MASS"))); acc.CH_SMILES(set.getString("CH_SMILES")); acc.CH_IUPAC(set.getString("CH_IUPAC")); @@ -606,7 +606,7 @@ public void persistAccessionFile(Record acc) { //System.out.println(System.nanoTime()); statementInsertCompound.setNull(1, java.sql.Types.INTEGER); statementInsertCompound.setString(2, acc.CH_FORMULA()); - statementInsertCompound.setDouble(3, acc.CH_EXACT_MASS()); + statementInsertCompound.setDouble(3, acc.CH_EXACT_MASS().doubleValue()); statementInsertCompound.setString(4, acc.CH_SMILES()); statementInsertCompound.setString(5, acc.CH_IUPAC()); diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/Record.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/Record.java index 6081e343..acd095d6 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/Record.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/Record.java @@ -72,7 +72,7 @@ public class Record { private List ch_name; private List ch_compound_class; private String ch_formula; - private double ch_exact_mass; + private BigDecimal ch_exact_mass; private String ch_smiles; private String ch_iupac; private List> ch_link; // optional @@ -253,10 +253,10 @@ public void CH_FORMULA(String value) { } - public double CH_EXACT_MASS() { + public BigDecimal CH_EXACT_MASS() { return ch_exact_mass; } - public void CH_EXACT_MASS(double value) { + public void CH_EXACT_MASS(BigDecimal value) { ch_exact_mass=value; } @@ -517,7 +517,10 @@ public String toString() { sb.append("PK$NUM_PEAK: " + PK_NUM_PEAK() + "\n"); sb.append("PK$PEAK: m/z int. rel.int.\n"); for (Triple peak : PK_PEAK()) { - sb.append(" " + peak.getLeft() + " " + peak.getMiddle() + " " + peak.getRight() + "\n"); + String intensity1 = peak.getMiddle().toPlainString(); + String intensity2 = peak.getMiddle().toString(); + String intensity = (intensity1.length() < intensity2.length() ) ? intensity1 : intensity2; + sb.append(" " + peak.getLeft() + " " + intensity + " " + peak.getRight() + "\n"); } sb.append("//\n"); @@ -527,24 +530,6 @@ public String toString() { public String createRecordString() { StringBuilder sb = new StringBuilder(); - - - - - - - - - - - - - - - - - - sb.append("ACCESSION: " + ACCESSION() + "
\n"); sb.append("RECORD_TITLE: " + RECORD_TITLE1() + "
\n"); sb.append("DATE: " + DATE() + "
\n"); diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java index 50c38b41..a443ef05 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/RecordParserDefinition.java @@ -110,16 +110,17 @@ public RecordParserDefinition(Record callback, boolean strict) { def("uint_primitive", digit().plus().flatten()); def("number_primitive", - digit().plus() - .seq( - CharacterParser.of('.') - .seq(digit().plus()).optional() - ) - .seq( - CharacterParser.anyOf("eE") - .seq(digit().plus()).optional() - ).flatten() - ); + digit().plus() + .seq( + CharacterParser.of('.') + .seq(digit().plus()).optional() + ) + .seq( + CharacterParser.anyOf("eE") + .seq(CharacterParser.anyOf("+-").optional()) + .seq(digit().plus()).optional() + ).flatten() + ); // 2.1 Record Specific Information // 2.1.1 ACCESSION @@ -652,10 +653,10 @@ public RecordParserDefinition(Record callback, boolean strict) { .seq( ref("number_primitive") .map((String value) -> { - double d = Double.parseDouble(value); - callback.CH_EXACT_MASS(d); - return value; - }) + BigDecimal d = new BigDecimal(value); + callback.CH_EXACT_MASS(d); + return value; + }) ) .seq(Token.NEWLINE_PARSER) // .map((List value) -> { diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/Validator.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/Validator.java index b07aff6f..2ab1018a 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/Validator.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/Validator.java @@ -132,7 +132,7 @@ else if (argumentf.isDirectory()) { hasNonStandardChars(recordString); record = validate(recordString, ""); if (record == null) { - logger.error("error in " + filename); + logger.error("Error in \'" + filename + "\'."); haserror.set(true); } else { @@ -143,6 +143,7 @@ record = validate(recordString, ""); String recordStringFromRecord = record.toString(); int position = StringUtils.indexOfDifference(new String [] {recordString, recordStringFromRecord}); if (position != -1) { + logger.error("Error in \'" + filename + "\'."); logger.error("File content differs from generated record string.\nThis might be a code problem. Please Report!"); String[] tokens = recordStringFromRecord.split("\\n"); int line = 0, col = 0, offset = 0; @@ -150,7 +151,7 @@ record = validate(recordString, ""); offset = offset + token.length() + 1; if (position < offset) { col = position - (offset - (token.length() + 1)); - logger.error("Error in line " + line + "."); + logger.error("Error in line " + line+1 + "."); logger.error(tokens[line]); StringBuilder error_at = new StringBuilder(StringUtils.repeat(" ", col)); error_at.append('^'); diff --git a/MassBank-Project/MassBank-lib/src/main/java/massbank/web/export/RecordExporter.java b/MassBank-Project/MassBank-lib/src/main/java/massbank/web/export/RecordExporter.java index a927a4b6..08995adf 100644 --- a/MassBank-Project/MassBank-lib/src/main/java/massbank/web/export/RecordExporter.java +++ b/MassBank-Project/MassBank-lib/src/main/java/massbank/web/export/RecordExporter.java @@ -259,7 +259,7 @@ public static List recordToNIST_MSP(Record record) throws CDKException{ list.add("Collision_energy" + ": " + record.AC_MASS_SPECTROMETRY_asMap().get("COLLISION_ENERGY")); list.add("Formula" + ": " + record.CH_FORMULA()); - list.add("MW" + ": " + Math.round(record.CH_EXACT_MASS())); + list.add("MW" + ": " + Math.round(record.CH_EXACT_MASS().floatValue())); list.add("ExactMass" + ": " + record.CH_EXACT_MASS()); // remaining stuff: From b453230dccf9cf540b36335761f347c393aa323e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Mon, 18 May 2020 16:05:09 +0200 Subject: [PATCH 09/10] Fixing #244. --- .../main/java/massbank/SiteMapServlet.java | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/MassBank-Project/MassBank/src/main/java/massbank/SiteMapServlet.java b/MassBank-Project/MassBank/src/main/java/massbank/SiteMapServlet.java index 7525a78c..c047d489 100644 --- a/MassBank-Project/MassBank/src/main/java/massbank/SiteMapServlet.java +++ b/MassBank-Project/MassBank/src/main/java/massbank/SiteMapServlet.java @@ -37,6 +37,7 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.configuration2.ex.ConfigurationException; +import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -46,13 +47,13 @@ /** * * This servlet generates dynamic sitemap.xml files. It serves a index - * at /sitemap_index.xml and the actual sitemaps at /sitemap/sitemap*.xml + * at /sitemap.xml and the actual sitemaps at /sitemap/sitemap*.xml * * @author rmeier - * @version 23-04-2019 + * @version 18-05-2020 * */ -@WebServlet({"/sitemap_index.xml","/sitemap/*"}) +@WebServlet({"/sitemap.xml","/sitemap/*"}) public class SiteMapServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final Logger logger = LogManager.getLogger(SiteMapServlet.class); @@ -63,17 +64,22 @@ public void init() throws ServletException { logger.trace("ServletContext.TEMPDIR: " + getServletContext().getAttribute(ServletContext.TEMPDIR)); File tmpdir = (File)getServletContext().getAttribute(ServletContext.TEMPDIR); // remove old index - for (File file : tmpdir.listFiles()) { - if (file.getName().matches("sitemap.*\\.xml$")) { - logger.trace("Remove old sitemap: " + file.toString()); - file.delete(); - } + try { + FileUtils.deleteQuietly(new File(tmpdir, "sitemap.xml")); + File sitemapDir = new File(tmpdir, "sitemap"); + if (sitemapDir.exists()) FileUtils.forceDelete(new File(tmpdir, "sitemap")); + } catch (IOException e) { + logger.error(e.getMessage()); + throw new ServletException("Could not clean sitemp directory."); } try { // create sitemap generator String sitemapbaseurl = Config.get().SitemapBaseURL(); - WebSitemapGenerator wsg = new WebSitemapGenerator(sitemapbaseurl, tmpdir); + if (!sitemapbaseurl.endsWith("/")) sitemapbaseurl = sitemapbaseurl + "/"; + File sitemapDir = new File(tmpdir, "sitemap"); + sitemapDir.mkdir(); + WebSitemapGenerator wsg = new WebSitemapGenerator(sitemapbaseurl, sitemapDir); // add static content wsg.addUrl(sitemapbaseurl); @@ -92,9 +98,10 @@ public void init() throws ServletException { // write new sitemaps List sitemaps=wsg.write(); + logger.trace("Files written:\n" + sitemaps); // write sitemap index - SitemapIndexGenerator sig = new SitemapIndexGenerator(sitemapbaseurl, new File(tmpdir, "sitemap_index.xml")); + SitemapIndexGenerator sig = new SitemapIndexGenerator(sitemapbaseurl, new File(tmpdir, "sitemap.xml")); for (File sitemap : sitemaps) { sig.addUrl(sitemapbaseurl+"sitemap/"+sitemap.getName()); } @@ -119,15 +126,17 @@ protected void processRequest(HttpServletRequest request, HttpServletResponse re } File sitemap; - if ((request.getPathInfo() == null) && "/sitemap_index.xml".equals(request.getServletPath())) { - sitemap=new File((File)getServletContext().getAttribute(ServletContext.TEMPDIR), "sitemap_index.xml"); + if ((request.getPathInfo() == null) && "/sitemap.xml".equals(request.getServletPath())) { + sitemap=new File((File)getServletContext().getAttribute(ServletContext.TEMPDIR), "sitemap.xml"); if (!sitemap.exists()) { // send 404 if index is missing response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404. return; } } else if (request.getServletPath().equals("/sitemap")) { - sitemap=new File((File)getServletContext().getAttribute(ServletContext.TEMPDIR), request.getPathInfo()); + + sitemap=new File(((File)getServletContext().getAttribute(ServletContext.TEMPDIR)).toString() + File.separator + "sitemap" + File.separator + request.getPathInfo()); + if (!sitemap.exists()) { // send 404 if index is missing response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404. From 3cc65a570af85323a8b478233199ebe0f2caad44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Meier?= Date: Tue, 19 May 2020 14:58:21 +0200 Subject: [PATCH 10/10] Bumped version number to 2.1.4 --- MassBank-Project/MassBank-OpenAPI/pom.xml | 2 +- MassBank-Project/MassBank-lib/pom.xml | 2 +- MassBank-Project/MassBank/pom.xml | 2 +- MassBank-Project/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MassBank-Project/MassBank-OpenAPI/pom.xml b/MassBank-Project/MassBank-OpenAPI/pom.xml index 846113b9..e6674686 100644 --- a/MassBank-Project/MassBank-OpenAPI/pom.xml +++ b/MassBank-Project/MassBank-OpenAPI/pom.xml @@ -6,7 +6,7 @@ MassBank-Project de.ipb-halle.msbi - 2.1.3-SNAPSHOT + 2.1.4 MassBank-OpenAPI diff --git a/MassBank-Project/MassBank-lib/pom.xml b/MassBank-Project/MassBank-lib/pom.xml index 4bef937d..33d39b0f 100644 --- a/MassBank-Project/MassBank-lib/pom.xml +++ b/MassBank-Project/MassBank-lib/pom.xml @@ -6,7 +6,7 @@ MassBank-Project de.ipb-halle.msbi - 2.1.3-SNAPSHOT + 2.1.4 MassBank-lib diff --git a/MassBank-Project/MassBank/pom.xml b/MassBank-Project/MassBank/pom.xml index eb4b73ec..7cd57ef8 100644 --- a/MassBank-Project/MassBank/pom.xml +++ b/MassBank-Project/MassBank/pom.xml @@ -6,7 +6,7 @@ MassBank-Project de.ipb-halle.msbi - 2.1.3-SNAPSHOT + 2.1.4 MassBank diff --git a/MassBank-Project/pom.xml b/MassBank-Project/pom.xml index 4befb2ee..fce4bb41 100644 --- a/MassBank-Project/pom.xml +++ b/MassBank-Project/pom.xml @@ -5,7 +5,7 @@ 4.0.0 de.ipb-halle.msbi MassBank-Project - 2.1.3-SNAPSHOT + 2.1.4 MassBank Project https://github.com/MassBank/MassBank-web pom