Skip to content

Commit

Permalink
Fixes #44 - Retrieve unit from .ch file (#45)
Browse files Browse the repository at this point in the history
Read unit from .ch file and convert from it to picoampere when reading values
  • Loading branch information
kevin-belellou authored Nov 17, 2024
1 parent 6863724 commit 5742b5c
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 48 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@
<artifactId>ASMUtils</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.jscience</groupId>
<artifactId>jscience</artifactId>
<version>4.3.1</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -9,24 +13,29 @@

public abstract class ChFile {

protected static final Unit<ElectricCurrent> PICO_AMPERE_UNIT = SI.PICO(SI.AMPERE);

protected List<Double> values;
protected Float startTime;
protected Float endTime;
protected Unit<ElectricCurrent> unit;
protected Double yScaling;
protected Double yOffset;
protected String detector;

int dataStart;
int startTimePosition;
int endTimePosition;
int yOffsetPosition;
int yScalingPosition;
int detectorPosition;
protected final int dataStart; // Has no use for now
protected final int startTimePosition;
protected final int endTimePosition;
protected final int unitsPosition;
protected final int yOffsetPosition;
protected final int yScalingPosition;
protected final 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;
Expand All @@ -37,48 +46,54 @@ protected ChFile(RandomAccessFile input, int dataStart, int startTimePosition, i

protected abstract void parseData(RandomAccessFile input) throws IOException;

/**
* Returns the values found in the .ch file, converted to picoampere as the standard imposes.
*/
public List<Double> getValues() {
return values;
}

protected void setValues(List<Double> values) {
this.values = values;
}

public Float getStartTime() {
return startTime;
}

private void setStartTime(Float startTime) {
this.startTime = startTime;
}

public Float getEndTime() {
return endTime;
}

private void setEndTime(Float endTime) {
this.endTime = endTime;
}

public String getDetector() {
return detector;
}

private void setDetector(String detector) {
this.detector = detector;
/**
* Returns the unit found in the .ch file.<br>
* Warning: the values stored in this class are converted to picoampere, as the standard imposes.
*/
protected Unit<ElectricCurrent> getUnit() {
return unit;
}

private void setUnit(String unit) {
Unit<? extends Quantity> localUnit = Unit.valueOf(unit);

if (!PICO_AMPERE_UNIT.isCompatible(localUnit)) {
throw new IllegalArgumentException("Unsupported unit: " + unit);
}

this.unit = localUnit.asType(ElectricCurrent.class);
}

protected void readMetadata(RandomAccessFile input) throws IOException {
setStartTime(readMetadataTime(input, startTimePosition));
setEndTime(readMetadataTime(input, endTimePosition));
startTime = readMetadataTime(input, startTimePosition);
endTime = readMetadataTime(input, endTimePosition);
setUnit(readStringAtPosition(input, unitsPosition, true));

input.seek(yOffsetPosition);
yOffset = input.readDouble();

input.seek(yScalingPosition);
yScaling = input.readDouble();

setDetector(readStringAtPosition(input, detectorPosition, true));
detector = readStringAtPosition(input, detectorPosition, true);
}
}
Original file line number Diff line number Diff line change
@@ -1,33 +1,40 @@
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 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");
}

values = new ArrayList<>((int) numberOfPoints);
UnitConverter unitConverter = unit.getConverterTo(PICO_AMPERE_UNIT);

input.seek(DATA_START);

setValues(new ArrayList<>());
for(int i=0; i<numberOfPoints;i++){
getValues().add(readLittleEndianDouble(input) * yScaling);
for (int i = 0; i < numberOfPoints; i++) {
values.add(unitConverter.convert(readLittleEndianDouble(input) * yScaling));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,48 +1,51 @@
package fr.ifpen.allotropeconverters.gc.chemstation.chfile;

import javax.measure.converter.UnitConverter;
import java.io.EOFException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;

class ChFile181 extends ChFile {

private static final int DATA_START = 6144; // https://github.com/chemplexity/chromatography/blob/master/Development/File%20Conversion/ImportAgilentFID.m
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;

ChFile181(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 {
input.seek(DATA_START);

values = new ArrayList<>();
long[] buffer = new long[]{0,0,0};
long[] buffer = new long[]{0, 0, 0};

UnitConverter unitConverter = unit.getConverterTo(PICO_AMPERE_UNIT);

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];
buffer[1] = 0;
}

values.add(buffer[0] * yScaling + yOffset);

}
catch (EOFException e){
values.add(unitConverter.convert(buffer[0] * yScaling + yOffset));
} catch (EOFException e) {
endOfFile = true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
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;
import java.net.URI;
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);
Expand All @@ -20,5 +22,7 @@ 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());
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
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;
import java.net.URI;
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);
Expand All @@ -22,5 +22,7 @@ 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());
}
}
}

0 comments on commit 5742b5c

Please sign in to comment.