From 869c992a03ee4e48aafcd44976bab584b467679e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Belellou?= Date: Fri, 15 Nov 2024 14:32:08 +0100 Subject: [PATCH] Fixes #44 - Retrieve unit from .ch file --- pom.xml | 5 ++++ .../gc/chemstation/chfile/ChFile.java | 30 ++++++++++++++++++- .../gc/chemstation/chfile/ChFile179.java | 24 ++++++++++----- .../gc/chemstation/chfile/ChFile181.java | 21 ++++++------- .../gc/chemstation/chfile/ChFile179Tests.java | 7 ++++- .../gc/chemstation/chfile/ChFile181Tests.java | 11 ++++--- 6 files changed, 75 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index 5dfb92f..9d3cfee 100644 --- a/pom.xml +++ b/pom.xml @@ -81,6 +81,11 @@ ASMUtils 1.0 + + org.jscience + jscience + 4.3.1 + diff --git a/src/main/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile.java b/src/main/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile.java index 78992b7..40d0742 100644 --- a/src/main/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile.java +++ b/src/main/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile.java @@ -1,5 +1,9 @@ package fr.ifpen.allotropeconverters.gc.chemstation.chfile; +import javax.measure.quantity.ElectricCurrent; +import javax.measure.quantity.Quantity; +import javax.measure.unit.SI; +import javax.measure.unit.Unit; import java.io.IOException; import java.io.RandomAccessFile; import java.util.List; @@ -9,9 +13,12 @@ public abstract class ChFile { + protected static final Unit PICO_AMPERE_UNIT = SI.PICO(SI.AMPERE); + protected List values; protected Float startTime; protected Float endTime; + protected Unit unit; protected Double yScaling; protected Double yOffset; protected String detector; @@ -19,14 +26,16 @@ public abstract class ChFile { int dataStart; int startTimePosition; int endTimePosition; + int unitsPosition; int yOffsetPosition; int yScalingPosition; int detectorPosition; - protected ChFile(RandomAccessFile input, int dataStart, int startTimePosition, int endTimePosition, int yOffsetPosition, int yScalingPosition, int detectorPosition) throws IOException { + protected ChFile(RandomAccessFile input, int dataStart, int startTimePosition, int endTimePosition, int unitsPosition, int yOffsetPosition, int yScalingPosition, int detectorPosition) throws IOException { this.dataStart = dataStart; this.startTimePosition = startTimePosition; this.endTimePosition = endTimePosition; + this.unitsPosition = unitsPosition; this.yOffsetPosition = yOffsetPosition; this.yScalingPosition = yScalingPosition; this.detectorPosition = detectorPosition; @@ -61,6 +70,24 @@ private void setEndTime(Float endTime) { this.endTime = endTime; } + protected Unit getUnit() { + return unit; + } + + public String getUnitSymbol() { + return unit.toString(); + } + + private void setUnit(String unit) { + Unit localUnit = Unit.valueOf(unit); + + if (!PICO_AMPERE_UNIT.isCompatible(localUnit)) { + throw new IllegalArgumentException("Unsupported unit: " + localUnit); + } + + this.unit = localUnit.asType(ElectricCurrent.class); + } + public String getDetector() { return detector; } @@ -72,6 +99,7 @@ private void setDetector(String detector) { protected void readMetadata(RandomAccessFile input) throws IOException { setStartTime(readMetadataTime(input, startTimePosition)); setEndTime(readMetadataTime(input, endTimePosition)); + setUnit(readStringAtPosition(input, unitsPosition, true)); input.seek(yOffsetPosition); yOffset = input.readDouble(); diff --git a/src/main/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile179.java b/src/main/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile179.java index 0ec423c..c9bd6ec 100644 --- a/src/main/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile179.java +++ b/src/main/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile179.java @@ -1,33 +1,43 @@ package fr.ifpen.allotropeconverters.gc.chemstation.chfile; -import java.io.*; +import javax.measure.converter.UnitConverter; +import java.io.IOException; +import java.io.RandomAccessFile; import java.util.ArrayList; +import java.util.List; import static fr.ifpen.allotropeconverters.gc.chemstation.chfile.ReadHelpers.readLittleEndianDouble; class ChFile179 extends ChFile { + private static final int DATA_START = 6144; // https://github.com/CINF/PyExpLabSys/blob/master/PyExpLabSys/file_parsers/chemstation.py private static final int START_TIME_POSITION = 282; private static final int END_TIME_POSITION = 286; + private static final int UNITS_POSITION = 4172; private static final int Y_OFFSET_POSITION = 4724; private static final int Y_SCALING_POSITION = 4732; private static final int DETECTOR_POSITION = 4213; ChFile179(RandomAccessFile input) throws IOException { - super(input, DATA_START, START_TIME_POSITION, END_TIME_POSITION, Y_OFFSET_POSITION, Y_SCALING_POSITION, DETECTOR_POSITION); + super(input, DATA_START, START_TIME_POSITION, END_TIME_POSITION, UNITS_POSITION, Y_OFFSET_POSITION, Y_SCALING_POSITION, DETECTOR_POSITION); } - @Override protected void parseData(RandomAccessFile input) throws IOException { - long numberOfPoints = (input.length() - DATA_START) / 8; + if (numberOfPoints > Integer.MAX_VALUE) { + throw new IllegalArgumentException("Input too large to parse"); + } + + List values = new ArrayList<>((int) numberOfPoints); + UnitConverter unitConverter = getUnit().getConverterTo(PICO_AMPERE_UNIT); input.seek(DATA_START); - setValues(new ArrayList<>()); - for(int i=0; i(); - long[] buffer = new long[]{0,0,0}; + long[] buffer = new long[]{0, 0, 0}; boolean endOfFile = false; - while(!endOfFile){ - try{ - buffer[2]= input.readShort(); + while (!endOfFile) { + try { + buffer[2] = input.readShort(); - if(buffer[2] != 32767){ - buffer[1]=buffer[2]+buffer[1]; - buffer[0]=buffer[1]+buffer[0]; + if (buffer[2] != 32767) { + buffer[1] = buffer[2] + buffer[1]; + buffer[0] = buffer[1] + buffer[0]; } else { buffer[0] = (long) input.readShort() << 32; buffer[0] = input.readInt() + buffer[0]; @@ -41,8 +43,7 @@ protected void parseData(RandomAccessFile input) throws IOException { values.add(buffer[0] * yScaling + yOffset); - } - catch (EOFException e){ + } catch (EOFException e) { endOfFile = true; } } diff --git a/src/test/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile179Tests.java b/src/test/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile179Tests.java index c1f2eab..73da39e 100644 --- a/src/test/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile179Tests.java +++ b/src/test/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile179Tests.java @@ -3,6 +3,7 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import javax.measure.unit.SI; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; @@ -10,8 +11,9 @@ import java.util.List; class ChFile179Tests { + @Test - void GetVersionReturnsExpected() throws IOException { + void getVersionReturnsExpected() throws IOException { URI uri = new File("src/test/resources/V179.D/FID1A.ch").toURI(); RandomAccessFile file = new RandomAccessFile(uri.getPath(), "r"); ChFile chFile = new ChFile179(file); @@ -20,5 +22,8 @@ void GetVersionReturnsExpected() throws IOException { Assertions.assertEquals(71840, values.size()); Assertions.assertEquals(2.165234, values.get(0), 0.001); + + Assertions.assertEquals(SI.PICO(SI.AMPERE), chFile.getUnit()); + Assertions.assertEquals("pA", chFile.getUnitSymbol()); } } diff --git a/src/test/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile181Tests.java b/src/test/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile181Tests.java index 3152242..8698416 100644 --- a/src/test/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile181Tests.java +++ b/src/test/java/fr/ifpen/allotropeconverters/gc/chemstation/chfile/ChFile181Tests.java @@ -1,10 +1,9 @@ package fr.ifpen.allotropeconverters.gc.chemstation.chfile; -import fr.ifpen.allotropeconverters.gc.chemstation.chfile.ChFile; -import fr.ifpen.allotropeconverters.gc.chemstation.chfile.ChFile181; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import javax.measure.unit.SI; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; @@ -12,8 +11,9 @@ import java.util.List; class ChFile181Tests { + @Test - void GetVersionReturnsExpected() throws IOException { + void getVersionReturnsExpected() throws IOException { URI uri = new File("src/test/resources/V181.D/V181.ch").toURI(); RandomAccessFile file = new RandomAccessFile(uri.getPath(), "r"); ChFile chFile = new ChFile181(file); @@ -22,5 +22,8 @@ void GetVersionReturnsExpected() throws IOException { Assertions.assertEquals(5914, values.size()); Assertions.assertEquals(2.1010, values.get(0), 0.001); + + Assertions.assertEquals(SI.PICO(SI.AMPERE), chFile.getUnit()); + Assertions.assertEquals("pA", chFile.getUnitSymbol()); } -} \ No newline at end of file +}