ir-spectrum 4.1.0 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,19 +12,35 @@
12
12
  ## Usage
13
13
 
14
14
  ```js
15
- import IRSpectrum from 'ir-spectrum';
15
+ import { readFileSync } from 'node:fs';
16
16
 
17
- let analysis = IRSpectrum.fromJcamp(jcamp);
17
+ import { fromJcamp } from 'ir-spectrum';
18
+
19
+ const analysis = fromJcamp(readFileSync('absorbance.jdx', 'utf8'));
20
+ const spectrum = analysis.getSpectrum();
18
21
  ```
19
22
 
20
- When loading an IRSpectrum from Jcamp we will systamatically add 2 new variables:
23
+ Other loaders are `fromSPC` (SPC files) and `fromText` (CSV, TSV and other x,y text). `peakPicking` and `autoPeakPicking` return peaks with their wavenumber, absorbance and transmittance.
24
+
25
+ When loading an IR spectrum from JCAMP or SPC, two additional variables are systematically added:
26
+
27
+ | Key | Label | Units | Description | Always present |
28
+ | --- | ------------------ | ----- | ---------------------------- | -------------- |
29
+ | x | Wavenumber | cm⁻¹ | Infrared wavenumber | Yes |
30
+ | y | (from source file) | | Original y-axis data | Yes |
31
+ | a | Absorbance | | Absorbance values | Yes |
32
+ | t | Transmittance | % | Percent transmittance values | Yes |
21
33
 
22
- - a: containing the absorbance
23
- - t: containing the percent transmittance
34
+ The conversion is automatic: if the y label or units name a transmittance ("Transmittance", "Transmission", "%T", "T"), absorbance is calculated; otherwise y is taken as an absorbance and transmittance is calculated. A transmittance is read as a percentage when its label or units contain '%' or 'percent', or, failing that, when its values go above 2.
24
35
 
25
- In order to calculate those 2 variables we will check the Y label. If it contains
26
- transmittance we calculate absorbance, if it contains absorbance we calculate transmittance.
27
- For transmittance we also check for the presence of a '%' sign.:w
36
+ ### Selector for visualization
37
+
38
+ ```html
39
+ <select name="selector.variables">
40
+ <option value="a vs x">Absorbance versus wavenumber</option>
41
+ <option value="t vs x">Transmittance versus wavenumber</option>
42
+ </select>
43
+ ```
28
44
 
29
45
  ## [API Documentation](https://cheminfo.github.io/ir-spectrum/)
30
46
 
@@ -1 +1 @@
1
- {"version":3,"file":"fromSPC.d.ts","sourceRoot":"","sources":["../../src/from/fromSPC.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAK5C,UAAU,cAAc;IACtB,0CAA0C;IAC1C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6HAA6H;IAC7H,gBAAgB,CAAC,EAAE,CACjB,SAAS,EAAE,sBAAsB,KAC9B,sBAAsB,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,cAAmB,GAC3B,QAAQ,CAiBV"}
1
+ {"version":3,"file":"fromSPC.d.ts","sourceRoot":"","sources":["../../src/from/fromSPC.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAK5C,UAAU,cAAc;IACtB,0CAA0C;IAC1C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6HAA6H;IAC7H,gBAAgB,CAAC,EAAE,CACjB,SAAS,EAAE,sBAAsB,KAC9B,sBAAsB,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,cAAmB,GAC3B,QAAQ,CAkBV"}
@@ -11,7 +11,8 @@ export function fromSPC(buffer, options = {}) {
11
11
  const { spectrumCallback = defaultSpectrumCallback, ...rest } = options;
12
12
  const analysis = new Analysis({ ...rest, spectrumCallback });
13
13
  const result = parse(buffer);
14
- const { parameters: _resultParameters, ...resultMeta } = result.meta;
14
+ const resultMeta = { ...result.meta };
15
+ delete resultMeta.parameters;
15
16
  for (const spectrum of result.spectra) {
16
17
  const { parameters: _spectrumParameters, ...spectrumMeta } = spectrum.meta ?? {};
17
18
  analysis.pushSpectrum(spectrum.variables, {
@@ -1 +1 @@
1
- {"version":3,"file":"fromSPC.js","sourceRoot":"","sources":["../../src/from/fromSPC.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAa1F;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CACrB,MAAiB,EACjB,UAA0B,EAAE;IAE5B,MAAM,EAAE,gBAAgB,GAAG,uBAAuB,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACxE,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAE7B,MAAM,EAAE,UAAU,EAAE,iBAAiB,EAAE,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC;IAErE,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACtC,MAAM,EAAE,UAAU,EAAE,mBAAmB,EAAE,GAAG,YAAY,EAAE,GACxD,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,SAAS,EAAE;YACxC,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,EAAE,GAAG,UAAU,EAAE,GAAG,YAAY,EAAE;SACzC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"fromSPC.js","sourceRoot":"","sources":["../../src/from/fromSPC.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,gBAAgB,IAAI,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAa1F;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CACrB,MAAiB,EACjB,UAA0B,EAAE;IAE5B,MAAM,EAAE,gBAAgB,GAAG,uBAAuB,EAAE,GAAG,IAAI,EAAE,GAAG,OAAO,CAAC;IACxE,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAE7B,MAAM,UAAU,GAA4B,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC/D,OAAO,UAAU,CAAC,UAAU,CAAC;IAE7B,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACtC,MAAM,EAAE,UAAU,EAAE,mBAAmB,EAAE,GAAG,YAAY,EAAE,GACxD,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,SAAS,EAAE;YACxC,QAAQ,EAAE,aAAa;YACvB,KAAK,EAAE,EAAE;YACT,IAAI,EAAE,EAAE,GAAG,UAAU,EAAE,GAAG,YAAY,EAAE;SACzC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { TextData } from 'cheminfo-types';
2
+ import type { FromTextOptions as CommonFromTextOptions } from 'common-spectrum';
3
+ import { Analysis } from 'common-spectrum';
4
+ interface FromTextOptions extends CommonFromTextOptions {
5
+ /** Unique identifier for the analysis. */
6
+ id?: string;
7
+ /** Human-readable label for the analysis. */
8
+ label?: string;
9
+ }
10
+ /**
11
+ * Creates a new Analysis from text data (CSV, TSV, etc.).
12
+ * @param data - Text data containing x,y values.
13
+ * @param options - Options for parsing and analysis creation.
14
+ * @returns New Analysis element with the given data.
15
+ */
16
+ export declare function fromText(data: TextData, options?: FromTextOptions): Analysis;
17
+ export {};
18
+ //# sourceMappingURL=fromText.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fromText.d.ts","sourceRoot":"","sources":["../../src/from/fromText.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,IAAI,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAG3C,UAAU,eAAgB,SAAQ,qBAAqB;IACrD,0CAA0C;IAC1C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,QAAQ,EACd,OAAO,GAAE,eAAoB,GAC5B,QAAQ,CA4BV"}
@@ -0,0 +1,28 @@
1
+ import { Analysis } from 'common-spectrum';
2
+ import { parseXYAndKeepInfo } from 'xy-parser';
3
+ /**
4
+ * Creates a new Analysis from text data (CSV, TSV, etc.).
5
+ * @param data - Text data containing x,y values.
6
+ * @param options - Options for parsing and analysis creation.
7
+ * @returns New Analysis element with the given data.
8
+ */
9
+ export function fromText(data, options = {}) {
10
+ const { info = {}, parser = {}, dataType = 'IR spectrum', title = '', ...rest } = options;
11
+ const analysis = new Analysis(rest);
12
+ const parsed = parseXYAndKeepInfo(data, parser);
13
+ const variables = {
14
+ x: {
15
+ data: parsed.data.x,
16
+ units: info.xUnits || '',
17
+ label: info.xLabel || '',
18
+ },
19
+ y: {
20
+ data: parsed.data.y,
21
+ units: info.yUnits || '',
22
+ label: info.yLabel || '',
23
+ },
24
+ };
25
+ analysis.pushSpectrum(variables, { dataType, title });
26
+ return analysis;
27
+ }
28
+ //# sourceMappingURL=fromText.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fromText.js","sourceRoot":"","sources":["../../src/from/fromText.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAS/C;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAc,EACd,UAA2B,EAAE;IAE7B,MAAM,EACJ,IAAI,GAAG,EAAE,EACT,MAAM,GAAG,EAAE,EACX,QAAQ,GAAG,aAAa,EACxB,KAAK,GAAG,EAAE,EACV,GAAG,IAAI,EACR,GAAG,OAAO,CAAC;IAEZ,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEpC,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG;QAChB,CAAC,EAAE;YACD,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YACnB,KAAK,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;YACxB,KAAK,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;SACzB;QACD,CAAC,EAAE;YACD,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;YACnB,KAAK,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;YACxB,KAAK,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;SACzB;KACF,CAAC;IAEF,QAAQ,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAEtD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { MeasurementVariable, NumberArray } from 'cheminfo-types';
2
+ /**
3
+ * Checks whether a variable holds a transmittance rather than an absorbance.
4
+ * Spectrometers spell the unit in many ways and `%T` is as common as
5
+ * `TRANSMITTANCE`, so both the label and the units are tested.
6
+ * @param variable - Variable to inspect, usually the y of an IR spectrum.
7
+ * @returns True when the data is a transmittance.
8
+ */
9
+ export declare function isTransmittance(variable: Pick<MeasurementVariable, 'label' | 'units'>): boolean;
10
+ /**
11
+ * Checks whether a transmittance is expressed as a percentage rather than as a
12
+ * fraction of 1. The label and the units are tested first; when neither says
13
+ * so, the data decides, since a fraction never goes much above 1.
14
+ * @param variable - Variable known to hold a transmittance.
15
+ * @returns True when the data runs from 0 to 100.
16
+ */
17
+ export declare function isPercent(variable: Pick<MeasurementVariable, 'label' | 'units'> & {
18
+ data?: NumberArray;
19
+ }): boolean;
20
+ //# sourceMappingURL=isTransmittance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isTransmittance.d.ts","sourceRoot":"","sources":["../../../src/from/utils/isTransmittance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAQvE;;;;;;GAMG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,IAAI,CAAC,mBAAmB,EAAE,OAAO,GAAG,OAAO,CAAC,GACrD,OAAO,CAOT;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,IAAI,CAAC,mBAAmB,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG;IACvD,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB,GACA,OAAO,CAST"}
@@ -0,0 +1,41 @@
1
+ import { xMaxValue } from 'ml-spectra-processing';
2
+ /** Any spelling built on the word itself: `TRANSMITTANCE`, `%Transmission`. */
3
+ const spelledOut = /trans/i;
4
+ /** The abbreviated forms, which share no substring with `transmittance`. */
5
+ const abbreviated = /^\s*%?\s*t\s*%?\s*$/i;
6
+ /**
7
+ * Checks whether a variable holds a transmittance rather than an absorbance.
8
+ * Spectrometers spell the unit in many ways and `%T` is as common as
9
+ * `TRANSMITTANCE`, so both the label and the units are tested.
10
+ * @param variable - Variable to inspect, usually the y of an IR spectrum.
11
+ * @returns True when the data is a transmittance.
12
+ */
13
+ export function isTransmittance(variable) {
14
+ const { label, units } = variable;
15
+ for (const value of [label, units]) {
16
+ if (!value)
17
+ continue;
18
+ if (spelledOut.test(value) || abbreviated.test(value))
19
+ return true;
20
+ }
21
+ return false;
22
+ }
23
+ /**
24
+ * Checks whether a transmittance is expressed as a percentage rather than as a
25
+ * fraction of 1. The label and the units are tested first; when neither says
26
+ * so, the data decides, since a fraction never goes much above 1.
27
+ * @param variable - Variable known to hold a transmittance.
28
+ * @returns True when the data runs from 0 to 100.
29
+ */
30
+ export function isPercent(variable) {
31
+ const { label, units, data } = variable;
32
+ for (const value of [label, units]) {
33
+ if (!value)
34
+ continue;
35
+ if (value.includes('%') || value.toLowerCase().includes('percent')) {
36
+ return true;
37
+ }
38
+ }
39
+ return data !== undefined && data.length > 0 && xMaxValue(data) > 2;
40
+ }
41
+ //# sourceMappingURL=isTransmittance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isTransmittance.js","sourceRoot":"","sources":["../../../src/from/utils/isTransmittance.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD,+EAA+E;AAC/E,MAAM,UAAU,GAAG,QAAQ,CAAC;AAC5B,4EAA4E;AAC5E,MAAM,WAAW,GAAG,sBAAsB,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAsD;IAEtD,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;IACrE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS,CACvB,QAEC;IAED,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACnE,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"spectrumCallback.d.ts","sourceRoot":"","sources":["../../../src/from/utils/spectrumCallback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAE7D;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,sBAAsB,GAChC,sBAAsB,CAqDxB"}
1
+ {"version":3,"file":"spectrumCallback.d.ts","sourceRoot":"","sources":["../../../src/from/utils/spectrumCallback.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAI7D;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,sBAAsB,GAChC,sBAAsB,CAgDxB"}
@@ -1,3 +1,4 @@
1
+ import { isPercent, isTransmittance } from "./isTransmittance.js";
1
2
  /**
2
3
  * Callback that adds absorbance (a) and transmittance (t) variables to the spectrum.
3
4
  * If the y variable is absorbance, transmittance is computed and vice versa.
@@ -9,11 +10,7 @@ export function spectrumCallback(variables) {
9
10
  // variable a = absorbance
10
11
  // variable t = transmittance
11
12
  const yVariable = variables.y;
12
- let isAbsorbance = true;
13
- if (yVariable.label.toLowerCase().includes('trans')) {
14
- isAbsorbance = false;
15
- }
16
- if (isAbsorbance) {
13
+ if (!isTransmittance(yVariable)) {
17
14
  variables.a = {
18
15
  ...yVariable,
19
16
  symbol: 'a',
@@ -27,26 +24,25 @@ export function spectrumCallback(variables) {
27
24
  };
28
25
  }
29
26
  else {
30
- const factor = yVariable.label.includes('%') ||
31
- yVariable.label.toLowerCase().includes('percent')
32
- ? 100
33
- : 1;
27
+ const factor = isPercent(yVariable) ? 100 : 1;
34
28
  variables.a = {
35
29
  data: yVariable.data.map((transmittance) => -Math.log10(transmittance / factor)),
36
30
  symbol: 'a',
37
31
  label: 'Absorbance',
38
32
  units: '',
39
33
  };
40
- if (factor === 100) {
41
- variables.t = { ...yVariable, symbol: 't' };
42
- variables.t.data = variables.t.data.slice();
34
+ const { label, units, data } = yVariable;
35
+ if (isPercent({ label, units })) {
36
+ variables.t = { ...yVariable, symbol: 't', data: data.slice() };
43
37
  }
44
38
  else {
45
39
  variables.t = {
46
40
  units: '',
47
41
  label: 'Transmittance (%)',
48
42
  symbol: 't',
49
- data: yVariable.data.map((transmittance) => transmittance * 100),
43
+ data: factor === 100
44
+ ? data.slice()
45
+ : data.map((transmittance) => transmittance * 100),
50
46
  };
51
47
  }
52
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"spectrumCallback.js","sourceRoot":"","sources":["../../../src/from/utils/spectrumCallback.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,SAAiC;IAEjC,4CAA4C;IAC5C,0BAA0B;IAC1B,6BAA6B;IAC7B,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC;IAC9B,IAAI,YAAY,GAAG,IAAI,CAAC;IACxB,IAAI,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,YAAY,GAAG,KAAK,CAAC;IACvB,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QACjB,SAAS,CAAC,CAAC,GAAG;YACZ,GAAG,SAAS;YACZ,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK,EAAc;SACzC,CAAC;QACF,SAAS,CAAC,CAAC,GAAG;YACZ,IAAI,EAAG,SAAS,CAAC,IAAiB,CAAC,GAAG,CACpC,CAAC,UAAkB,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,GAAG,GAAG,CAChD;YACD,KAAK,EAAE,mBAAmB;YAC1B,MAAM,EAAE,GAAG;YACX,KAAK,EAAE,EAAE;SACV,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GACV,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC;YAC7B,SAAS,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;YAC/C,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,CAAC,CAAC;QAER,SAAS,CAAC,CAAC,GAAG;YACZ,IAAI,EAAG,SAAS,CAAC,IAAiB,CAAC,GAAG,CACpC,CAAC,aAAqB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,CAC/D;YACD,MAAM,EAAE,GAAG;YACX,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,EAAE;SACV,CAAC;QACF,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,SAAS,CAAC,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;YAC5C,SAAS,CAAC,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAc,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,CAAC,GAAG;gBACZ,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,mBAAmB;gBAC1B,MAAM,EAAE,GAAG;gBACX,IAAI,EAAG,SAAS,CAAC,IAAiB,CAAC,GAAG,CACpC,CAAC,aAAqB,EAAE,EAAE,CAAC,aAAa,GAAG,GAAG,CAC/C;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"spectrumCallback.js","sourceRoot":"","sources":["../../../src/from/utils/spectrumCallback.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAElE;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAC9B,SAAiC;IAEjC,4CAA4C;IAC5C,0BAA0B;IAC1B,6BAA6B;IAC7B,MAAM,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,SAAS,CAAC,CAAC,GAAG;YACZ,GAAG,SAAS;YACZ,MAAM,EAAE,GAAG;YACX,IAAI,EAAE,SAAS,CAAC,IAAI,CAAC,KAAK,EAAc;SACzC,CAAC;QACF,SAAS,CAAC,CAAC,GAAG;YACZ,IAAI,EAAG,SAAS,CAAC,IAAiB,CAAC,GAAG,CACpC,CAAC,UAAkB,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,UAAU,GAAG,GAAG,CAChD;YACD,KAAK,EAAE,mBAAmB;YAC1B,MAAM,EAAE,GAAG;YACX,KAAK,EAAE,EAAE;SACV,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAE9C,SAAS,CAAC,CAAC,GAAG;YACZ,IAAI,EAAG,SAAS,CAAC,IAAiB,CAAC,GAAG,CACpC,CAAC,aAAqB,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,GAAG,MAAM,CAAC,CAC/D;YACD,MAAM,EAAE,GAAG;YACX,KAAK,EAAE,YAAY;YACnB,KAAK,EAAE,EAAE;SACV,CAAC;QACF,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC;QACzC,IAAI,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;YAChC,SAAS,CAAC,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;QAClE,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,CAAC,GAAG;gBACZ,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE,mBAAmB;gBAC1B,MAAM,EAAE,GAAG;gBACX,IAAI,EACF,MAAM,KAAK,GAAG;oBACZ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE;oBACd,CAAC,CAAE,IAAiB,CAAC,GAAG,CACpB,CAAC,aAAqB,EAAE,EAAE,CAAC,aAAa,GAAG,GAAG,CAC/C;aACR,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
package/lib/index.d.ts CHANGED
@@ -22,6 +22,7 @@ export declare function peakPicking(spectrum: MeasurementXY, target: number, opt
22
22
  export declare function autoPeakPicking(spectrum: MeasurementXY, options?: AutoPeakPickingOptions): ConvertedPeak[];
23
23
  export { fromJcamp } from './from/fromJcamp.ts';
24
24
  export { fromSPC } from './from/fromSPC.ts';
25
+ export { fromText } from './from/fromText.ts';
25
26
  export declare const JSGraph: typeof OriginalJSGraph & {
26
27
  getAnnotations: typeof getAnnotations;
27
28
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,OAAO,IAAI,eAAe,EAG3B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,aAAa,GAAG,SAAS,CAO3B;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,aAAa,EAAE,CASjB;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,eAAO,MAAM,OAAO,EAAE,OAAO,eAAe,GAAG;IAC7C,cAAc,EAAE,OAAO,cAAc,CAAC;CACE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EACnB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,OAAO,IAAI,eAAe,EAG3B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,aAAa,EACvB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,kBAAkB,GAC3B,aAAa,GAAG,SAAS,CAO3B;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,aAAa,EACvB,OAAO,CAAC,EAAE,sBAAsB,GAC/B,aAAa,EAAE,CASjB;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,eAAO,MAAM,OAAO,EAAE,OAAO,eAAe,GAAG;IAC7C,cAAc,EAAE,OAAO,cAAc,CAAC;CACE,CAAC"}
package/lib/index.js CHANGED
@@ -29,5 +29,6 @@ export function autoPeakPicking(spectrum, options) {
29
29
  }
30
30
  export { fromJcamp } from "./from/fromJcamp.js";
31
31
  export { fromSPC } from "./from/fromSPC.js";
32
+ export { fromText } from "./from/fromText.js";
32
33
  export const JSGraph = { ...OriginalJSGraph, getAnnotations };
33
34
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,IAAI,eAAe,EAC1B,eAAe,IAAI,uBAAuB,EAC1C,WAAW,IAAI,mBAAmB,GACnC,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAErE;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,QAAuB,EACvB,MAAc,EACd,OAA4B;IAE5B,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,WAAW,CAChB,IAAkE,EAClE,QAAQ,CACT,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAuB,EACvB,OAAgC;IAEhC,MAAM,KAAK,GAAG,uBAAuB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACxB,WAAW,CACT,IAAkE,EAClE,QAAQ,CACT,CACF,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,MAAM,CAAC,MAAM,OAAO,GAEhB,EAAE,GAAG,eAAe,EAAE,cAAc,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,OAAO,IAAI,eAAe,EAC1B,eAAe,IAAI,uBAAuB,EAC1C,WAAW,IAAI,mBAAmB,GACnC,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAG7D,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAErE;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,QAAuB,EACvB,MAAc,EACd,OAA4B;IAE5B,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5D,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,WAAW,CAChB,IAAkE,EAClE,QAAQ,CACT,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAuB,EACvB,OAAgC;IAEhC,MAAM,KAAK,GAAG,uBAAuB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACxB,WAAW,CACT,IAAkE,EAClE,QAAQ,CACT,CACF,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C,MAAM,CAAC,MAAM,OAAO,GAEhB,EAAE,GAAG,eAAe,EAAE,cAAc,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ir-spectrum",
3
- "version": "4.1.0",
3
+ "version": "4.2.1",
4
4
  "description": "Package used to handle IR spectra in SciPeaks.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -13,12 +13,12 @@
13
13
  "scripts": {
14
14
  "build": "npm run tsc && cheminfo-build --entry lib/index.js --root IRSpectrum",
15
15
  "check-types": "tsc --noEmit",
16
- "clean": "rimraf lib",
17
- "eslint": "eslint src",
18
- "eslint-fix": "npm run eslint -- --fix",
16
+ "clean": "rimraf coverage lib",
17
+ "eslint": "eslint .",
18
+ "eslint-fix": "eslint . --fix",
19
19
  "prepack": "npm run tsc",
20
- "prettier": "prettier --check src",
21
- "prettier-write": "prettier --write src",
20
+ "prettier": "prettier --check .",
21
+ "prettier-write": "prettier --write .",
22
22
  "test": "npm run test-only && npm run check-types && npm run eslint && npm run prettier",
23
23
  "test-only": "vitest run --coverage",
24
24
  "tsc": "npm run clean && npm run tsc-build",
@@ -36,25 +36,27 @@
36
36
  },
37
37
  "homepage": "https://github.com/cheminfo/ir-spectrum#readme",
38
38
  "dependencies": {
39
- "common-spectrum": "3.1.0",
40
- "ml-gsd": "^13.1.1",
41
- "spc-parser": "^1.0.0"
39
+ "common-spectrum": "4.0.1",
40
+ "ml-gsd": "^14.3.0",
41
+ "ml-spectra-processing": "^14.35.1",
42
+ "spc-parser": "^2.1.1",
43
+ "xy-parser": "^6.0.1"
42
44
  },
43
45
  "devDependencies": {
44
- "@types/node": "^25.3.0",
45
- "@vitest/coverage-v8": "^4.0.18",
46
- "@zakodium/tsconfig": "^1.0.2",
47
- "cheminfo-build": "^1.3.2",
46
+ "@types/node": "^26.6.1",
47
+ "@vitest/coverage-v8": "^4.1.11",
48
+ "@zakodium/tsconfig": "^1.0.5",
49
+ "cheminfo-build": "^1.4.0",
48
50
  "eslint": "^9.39.2",
49
- "eslint-config-cheminfo-typescript": "^21.1.0",
51
+ "eslint-config-cheminfo-typescript": "^22.0.0",
50
52
  "jest-matcher-deep-close-to": "^3.0.2",
51
- "prettier": "^3.8.1",
53
+ "prettier": "^3.9.8",
52
54
  "rimraf": "^6.1.3",
53
- "typescript": "^5.9.3",
54
- "vitest": "^4.0.18"
55
+ "typescript": "^6.0.3",
56
+ "vitest": "^4.1.11"
55
57
  },
56
58
  "info": {
57
- "logo": "https://raw.githubusercontent.com/cheminfo/font/master/src/ir/assignment.svg",
59
+ "logo": "https://raw.githubusercontent.com/cheminfo/font/main/src/ir/assignment.svg",
58
60
  "domain": [
59
61
  "Physical Chemistry",
60
62
  "Materials Science",
@@ -70,7 +72,7 @@
70
72
  {
71
73
  "extension": "jdx",
72
74
  "manufacturer": "IUPAC",
73
- "example": "https://raw.githubusercontent.com/cheminfo/ir-spectrum/master/testFiles/absorbance.jdx"
75
+ "example": "https://raw.githubusercontent.com/cheminfo/ir-spectrum/main/src/from/__tests__/data/absorbance.jdx"
74
76
  }
75
77
  ]
76
78
  }
@@ -30,7 +30,8 @@ export function fromSPC(
30
30
  const analysis = new Analysis({ ...rest, spectrumCallback });
31
31
  const result = parse(buffer);
32
32
 
33
- const { parameters: _resultParameters, ...resultMeta } = result.meta;
33
+ const resultMeta: Record<string, unknown> = { ...result.meta };
34
+ delete resultMeta.parameters;
34
35
 
35
36
  for (const spectrum of result.spectra) {
36
37
  const { parameters: _spectrumParameters, ...spectrumMeta } =
@@ -0,0 +1,50 @@
1
+ import type { TextData } from 'cheminfo-types';
2
+ import type { FromTextOptions as CommonFromTextOptions } from 'common-spectrum';
3
+ import { Analysis } from 'common-spectrum';
4
+ import { parseXYAndKeepInfo } from 'xy-parser';
5
+
6
+ interface FromTextOptions extends CommonFromTextOptions {
7
+ /** Unique identifier for the analysis. */
8
+ id?: string;
9
+ /** Human-readable label for the analysis. */
10
+ label?: string;
11
+ }
12
+
13
+ /**
14
+ * Creates a new Analysis from text data (CSV, TSV, etc.).
15
+ * @param data - Text data containing x,y values.
16
+ * @param options - Options for parsing and analysis creation.
17
+ * @returns New Analysis element with the given data.
18
+ */
19
+ export function fromText(
20
+ data: TextData,
21
+ options: FromTextOptions = {},
22
+ ): Analysis {
23
+ const {
24
+ info = {},
25
+ parser = {},
26
+ dataType = 'IR spectrum',
27
+ title = '',
28
+ ...rest
29
+ } = options;
30
+
31
+ const analysis = new Analysis(rest);
32
+
33
+ const parsed = parseXYAndKeepInfo(data, parser);
34
+ const variables = {
35
+ x: {
36
+ data: parsed.data.x,
37
+ units: info.xUnits || '',
38
+ label: info.xLabel || '',
39
+ },
40
+ y: {
41
+ data: parsed.data.y,
42
+ units: info.yUnits || '',
43
+ label: info.yLabel || '',
44
+ },
45
+ };
46
+
47
+ analysis.pushSpectrum(variables, { dataType, title });
48
+
49
+ return analysis;
50
+ }
@@ -0,0 +1,47 @@
1
+ import type { MeasurementVariable, NumberArray } from 'cheminfo-types';
2
+ import { xMaxValue } from 'ml-spectra-processing';
3
+
4
+ /** Any spelling built on the word itself: `TRANSMITTANCE`, `%Transmission`. */
5
+ const spelledOut = /trans/i;
6
+ /** The abbreviated forms, which share no substring with `transmittance`. */
7
+ const abbreviated = /^\s*%?\s*t\s*%?\s*$/i;
8
+
9
+ /**
10
+ * Checks whether a variable holds a transmittance rather than an absorbance.
11
+ * Spectrometers spell the unit in many ways and `%T` is as common as
12
+ * `TRANSMITTANCE`, so both the label and the units are tested.
13
+ * @param variable - Variable to inspect, usually the y of an IR spectrum.
14
+ * @returns True when the data is a transmittance.
15
+ */
16
+ export function isTransmittance(
17
+ variable: Pick<MeasurementVariable, 'label' | 'units'>,
18
+ ): boolean {
19
+ const { label, units } = variable;
20
+ for (const value of [label, units]) {
21
+ if (!value) continue;
22
+ if (spelledOut.test(value) || abbreviated.test(value)) return true;
23
+ }
24
+ return false;
25
+ }
26
+
27
+ /**
28
+ * Checks whether a transmittance is expressed as a percentage rather than as a
29
+ * fraction of 1. The label and the units are tested first; when neither says
30
+ * so, the data decides, since a fraction never goes much above 1.
31
+ * @param variable - Variable known to hold a transmittance.
32
+ * @returns True when the data runs from 0 to 100.
33
+ */
34
+ export function isPercent(
35
+ variable: Pick<MeasurementVariable, 'label' | 'units'> & {
36
+ data?: NumberArray;
37
+ },
38
+ ): boolean {
39
+ const { label, units, data } = variable;
40
+ for (const value of [label, units]) {
41
+ if (!value) continue;
42
+ if (value.includes('%') || value.toLowerCase().includes('percent')) {
43
+ return true;
44
+ }
45
+ }
46
+ return data !== undefined && data.length > 0 && xMaxValue(data) > 2;
47
+ }
@@ -1,5 +1,7 @@
1
1
  import type { MeasurementXYVariables } from 'cheminfo-types';
2
2
 
3
+ import { isPercent, isTransmittance } from './isTransmittance.ts';
4
+
3
5
  /**
4
6
  * Callback that adds absorbance (a) and transmittance (t) variables to the spectrum.
5
7
  * If the y variable is absorbance, transmittance is computed and vice versa.
@@ -13,11 +15,7 @@ export function spectrumCallback(
13
15
  // variable a = absorbance
14
16
  // variable t = transmittance
15
17
  const yVariable = variables.y;
16
- let isAbsorbance = true;
17
- if (yVariable.label.toLowerCase().includes('trans')) {
18
- isAbsorbance = false;
19
- }
20
- if (isAbsorbance) {
18
+ if (!isTransmittance(yVariable)) {
21
19
  variables.a = {
22
20
  ...yVariable,
23
21
  symbol: 'a',
@@ -32,11 +30,7 @@ export function spectrumCallback(
32
30
  units: '',
33
31
  };
34
32
  } else {
35
- const factor =
36
- yVariable.label.includes('%') ||
37
- yVariable.label.toLowerCase().includes('percent')
38
- ? 100
39
- : 1;
33
+ const factor = isPercent(yVariable) ? 100 : 1;
40
34
 
41
35
  variables.a = {
42
36
  data: (yVariable.data as number[]).map(
@@ -46,17 +40,20 @@ export function spectrumCallback(
46
40
  label: 'Absorbance',
47
41
  units: '',
48
42
  };
49
- if (factor === 100) {
50
- variables.t = { ...yVariable, symbol: 't' };
51
- variables.t.data = variables.t.data.slice() as number[];
43
+ const { label, units, data } = yVariable;
44
+ if (isPercent({ label, units })) {
45
+ variables.t = { ...yVariable, symbol: 't', data: data.slice() };
52
46
  } else {
53
47
  variables.t = {
54
48
  units: '',
55
49
  label: 'Transmittance (%)',
56
50
  symbol: 't',
57
- data: (yVariable.data as number[]).map(
58
- (transmittance: number) => transmittance * 100,
59
- ),
51
+ data:
52
+ factor === 100
53
+ ? data.slice()
54
+ : (data as number[]).map(
55
+ (transmittance: number) => transmittance * 100,
56
+ ),
60
57
  };
61
58
  }
62
59
  }
package/src/index.ts CHANGED
@@ -58,6 +58,7 @@ export function autoPeakPicking(
58
58
 
59
59
  export { fromJcamp } from './from/fromJcamp.ts';
60
60
  export { fromSPC } from './from/fromSPC.ts';
61
+ export { fromText } from './from/fromText.ts';
61
62
 
62
63
  export const JSGraph: typeof OriginalJSGraph & {
63
64
  getAnnotations: typeof getAnnotations;