Skip to content

Commit

Permalink
refactor: mv function CV inline notation to ELN spectra helper (#1956)
Browse files Browse the repository at this point in the history
Co-authored-by: Lan Le <[email protected]>
  • Loading branch information
baolanlequang and Lan Le authored Jul 23, 2024
1 parent 733407f commit cd4a793
Show file tree
Hide file tree
Showing 3 changed files with 244 additions and 11 deletions.
54 changes: 44 additions & 10 deletions app/packs/src/apps/mydb/elements/details/ViewSpectra.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import SpectraActions from 'src/stores/alt/actions/SpectraActions';
import SpectraStore from 'src/stores/alt/stores/SpectraStore';
import { SpectraOps } from 'src/utilities/quillToolbarSymbol';
import ResearchPlan from 'src/models/ResearchPlan';
import { inlineNotation } from 'src/utilities/SpectraHelper';

const rmRefreshed = (analysis) => {
if (!analysis) return analysis;
Expand Down Expand Up @@ -55,6 +56,7 @@ class ViewSpectra extends React.Component {
this.buildOthers = this.buildOthers.bind(this);
this.onSpectraDescriptionChanged = this.onSpectraDescriptionChanged.bind(this);
this.isShowMultipleSelectFile = this.isShowMultipleSelectFile.bind(this);
this.notationVoltammetry = this.notationVoltammetry.bind(this);
}

componentDidMount() {
Expand Down Expand Up @@ -358,6 +360,8 @@ class ViewSpectra extends React.Component {
ops = this.formatMpy({
multiplicity, integration, shift, isAscend, decimal, layout, curveSt
});
} else if (FN.isCyclicVoltaLayout(layout)) {
ops = this.notationVoltammetry(cyclicvoltaSt, curveSt, layout, sample);
} else {
ops = this.formatPks({
peaks,
Expand All @@ -382,7 +386,7 @@ class ViewSpectra extends React.Component {
...ops,
];
const firstOps = ai.extended_metadata.content.ops[0];
if (firstOps.insert && firstOps.insert === '\n') {
if (firstOps && firstOps.insert && firstOps.insert === '\n') {
ai.extended_metadata.content.ops.shift();
}

Expand All @@ -391,12 +395,35 @@ class ViewSpectra extends React.Component {

const cb = () => (
this.saveOp({
peaks, shift, scan, thres, analysis, keepPred, integration, multiplicity, cyclicvoltaSt, curveSt, waveLength, axesUnitsSt, detectorSt, dscMetaData,
peaks, shift, scan, thres, analysis, keepPred, integration, multiplicity, cyclicvoltaSt, curveSt, layout, waveLength, axesUnitsSt, detectorSt, dscMetaData,
})
);
handleSampleChanged(sample, cb);
}

notationVoltammetry(cyclicvoltaSt, curveSt, layout, sample) {
const { spectraList } = cyclicvoltaSt;
const { curveIdx, listCurves } = curveSt;
const selectedVolta = spectraList[curveIdx];
const selectedCurve = listCurves[curveIdx];
const { feature } = selectedCurve;
const { scanRate } = feature;
const data = {
scanRate,
voltaData: {
listPeaks: selectedVolta.list,
xyData: feature.data[0],
},
sampleName: sample.name,
concentration: null,
solvent: null,
internalRef: null,
};
const desc = inlineNotation(layout, data);
const { quillData } = desc;
return quillData;
}

writePeakOp(params) {
const isMpy = false;
this.writeCommon(params, isMpy);
Expand Down Expand Up @@ -430,8 +457,8 @@ class ViewSpectra extends React.Component {
const selectedMutiplicity = multiplicities[curveIdx];

const isSaveCombined = FN.isCyclicVoltaLayout(layout);
const { spcInfos } = this.state;
const previousSpcInfos = spcInfos.filter((spc) => spc.idDt === si.idDt);
const { spcInfos, arrSpcIdx } = this.state;
const previousSpcInfos = spcInfos.filter((spc) => (spc.idDt === si.idDt && arrSpcIdx.includes(spc.idx)));
LoadingActions.start.defer();
SpectraActions.SaveToFile.defer(
si,
Expand All @@ -457,10 +484,10 @@ class ViewSpectra extends React.Component {
}

refreshOp({
peaks, shift, scan, thres, analysis, keepPred, integration, multiplicity, waveLength, cyclicvoltaSt, curveSt, axesUnitsSt, detectorSt
peaks, shift, scan, thres, analysis, keepPred, integration, multiplicity, waveLength, cyclicvoltaSt, curveSt, layout, axesUnitsSt, detectorSt
}) {
this.saveOp({
peaks, shift, scan, thres, analysis, integration, multiplicity, waveLength, cyclicvoltaSt, curveSt, simulatenmr: true, axesUnitsSt, detectorSt
peaks, shift, scan, thres, analysis, integration, multiplicity, waveLength, cyclicvoltaSt, curveSt, simulatenmr: true, layout, axesUnitsSt, detectorSt
});
}

Expand Down Expand Up @@ -575,10 +602,17 @@ class ViewSpectra extends React.Component {
}

if (layoutsWillShowMulti.includes(et.layout)) {
return [
{ name: 'save', value: this.saveOp },
{ name: 'save & close', value: this.saveCloseOp },
];
if (FN.isCyclicVoltaLayout(et.layout)) {
return [
{ name: 'save', value: this.writeCommon },
{ name: 'save & close', value: this.writeCloseCommon },
];
} else {
return [
{ name: 'save', value: this.saveOp },
{ name: 'save & close', value: this.saveCloseOp },
];
}
}
const saveable = updatable;
if (saveable) {
Expand Down
82 changes: 81 additions & 1 deletion app/packs/src/utilities/SpectraHelper.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { FN } from '@complat/react-spectra-editor';
const acceptables = ['jdx', 'dx', 'jcamp', 'mzml', 'mzxml', 'raw', 'cdf', 'zip'];

const JcampIds = (container) => {
Expand Down Expand Up @@ -225,4 +226,83 @@ const cleaningNMRiumData = (nmriumData) => {
return cleanedNMRiumData;
};

export { BuildSpcInfos, BuildSpcInfosForNMRDisplayer, JcampIds, isNMRKind, cleaningNMRiumData }; // eslint-disable-line
const inlineNotation = (layout, data) => {
let formattedString = '';
let quillData = [];
if (!data) return { quillData, formattedString };

const {
scanRate, voltaData, sampleName,
concentration, solvent, internalRef,
} = data;
switch (layout) {
case FN.LIST_LAYOUT.CYCLIC_VOLTAMMETRY: {
if (!voltaData) {
break;
}
let refString = '';
let nonRefString = '';
let refOps = [];
const nonRefOps = [];
const { listPeaks, xyData } = voltaData;
const { x } = xyData;
listPeaks.forEach((item) => {
const {
isRef, e12, max, min,
} = item;
const e12Str = e12 ? FN.strNumberFixedLength(e12, 3) : '0';
const scanRateStr = scanRate ? FN.strNumberFixedLength(scanRate, 3) : '0';
if (isRef) {
const posNegString = x[0] > x[1] ? 'neg.' : 'pos.';
const concentrationStr = concentration ? concentration : '<conc. of sample>';
const solventStr = solvent ? solvent : '<solvent>';
let internalRefStr = "(Fc+/Fc)";
refOps = [
{ insert: `CV (${concentrationStr} mM in ${solventStr} vs. Ref ` },
{ insert: `(Fc` },
{ insert: '+', attributes: { script: 'super' } },
{ insert: `/Fc) ` },
{ insert: `= ${e12Str} V, v = ${scanRateStr} V/s, to ${posNegString}):` },
];
if (internalRef === 'decamethylferrocene') {
internalRefStr = "(Me10Fc+/Me10Fc)";
refOps = [
{ insert: `CV (${concentrationStr} mM in ${solventStr} vs. Ref ` },
{ insert: `(Me` },
{ insert: '10', attributes: { script: 'sub' } },
{ insert: `Fc` },
{ insert: '+', attributes: { script: 'super' } },
{ insert: `/Me` },
{ insert: '10', attributes: { script: 'sub' } },
{ insert: `Fc) ` },
{ insert: `= ${e12Str} V, v = ${scanRateStr} V/s, to ${posNegString}):` },
];
}
refString = `CV (${concentrationStr} mM in ${solventStr} vs. Ref ${internalRefStr} = ${e12Str} V, v = ${scanRateStr} V/s, to ${posNegString}):`;

} else {
const delta = (max && min) ? FN.strNumberFixedLength(Math.abs(max.x - min.x) * 1000, 3) : '0';
nonRefString += `\nE1/2 = ([${sampleName}] , ΔEp) = ${e12Str} V (${delta} mV)`;
const currentNoneOps = [
{ insert: '\nE' },
{ insert: '1/2', attributes: { script: 'sub' } },
{ insert: ` = ([${sampleName}] , ΔE` },
{ insert: 'p', attributes: { script: 'sub' } },
{ insert: `) = ${e12Str} V (${delta} mV)` },
];
nonRefOps.push(...currentNoneOps);
}
});

formattedString = refString + nonRefString;
quillData = [...refOps, ...nonRefOps];
break;
}
default:
break;
}

return { quillData, formattedString };
};

export { BuildSpcInfos, BuildSpcInfosForNMRDisplayer, JcampIds, isNMRKind, cleaningNMRiumData, inlineNotation }; // eslint-disable-line
119 changes: 119 additions & 0 deletions spec/javascripts/packs/src/utilities/SpectraHelper.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import expect from 'expect';
import {
describe, it, beforeEach
} from 'mocha';
import { FN } from '@complat/react-spectra-editor';
import {
isNMRKind, BuildSpcInfosForNMRDisplayer,
JcampIds, BuildSpcInfos, cleaningNMRiumData,
inlineNotation,
} from 'src/utilities/SpectraHelper';
import Sample from 'src/models/Sample';
import Container from 'src/models/Container';
Expand Down Expand Up @@ -356,4 +358,121 @@ describe('SpectraHelper', () => {
});
});
});

describe('.inlineNotation()', () => {
describe('Inline notation for Cyclic voltammetry layout', () => {
const allLayouts = FN.LIST_LAYOUT;
it('return empty string if it is not CV layout', () => {
const layouts = Object.assign({}, allLayouts);
delete layouts.CYCLIC_VOLTAMMETRY;
Object.keys(layouts).forEach((layout) => {
const formattedData = inlineNotation(allLayouts[layout], '');
const { formattedString, quillData } = formattedData;
expect(formattedString).toEqual('');
expect(quillData).toEqual([]);
})
});

it('Inline notation for Cyclic voltammetry layout without concentration', () => {
const expectedString = "CV (<conc. of sample> mM in <solvent> vs. Ref (Fc+/Fc) = -0.72 V, v = 0.10 V/s, to neg.):\nE1/2 = ([Cu(TMGqu)] , ΔEp) = -0.73 V (1650 mV)"
const expectedQuillData = [{insert:"CV (<conc. of sample> mM in <solvent> vs. Ref "},{insert:"(Fc"},{insert:"+",attributes:{script:'super'}},{insert:"/Fc) "},{insert:"= -0.72 V, v = 0.10 V/s, to neg.):"},{insert:"\nE"},{insert:"1/2",attributes:{script:'sub'}},{insert:" = ([Cu(TMGqu)] , ΔE"},{insert:"p",attributes:{script:'sub'}},{insert:") = -0.73 V (1650 mV)"},]
const layout = allLayouts.CYCLIC_VOLTAMMETRY
const data = {
scanRate: 0.1,
voltaData: {
listPeaks: [{"min":{"x":-1.5404,"y":-0.00000307144},"max":{"x":0.10003,"y":0.00000285434},"isRef":true,"e12":-0.720185,"createdAt":1716803991732,"updatedAt":1716803991733,"pecker":{"x":0.380242,"y":0.00000164361}},{"max":{"x":0.10002,"y":0.00000283434},"e12":-0.72519,"updatedAt":1716803991733,"min":{"x":-1.5504,"y":-0.00000317144},"pecker":{"x":0.480242,"y":0.00000174361},"isRef":false}],
xyData: {x:[1.49048,1.48049],y:[0.00000534724,0.00000481545],},
},
sampleName: 'Cu(TMGqu)',
};
const formattedData = inlineNotation(layout, data);
const { formattedString, quillData } = formattedData;
expect(formattedString).toEqual(expectedString);
expect(quillData).toEqual(expectedQuillData);
});

it('Inline notation for Cyclic voltammetry layout with concentration', () => {
const expectedString = "CV (10 mM in <solvent> vs. Ref (Fc+/Fc) = -0.72 V, v = 0.10 V/s, to neg.):\nE1/2 = ([Cu(TMGqu)] , ΔEp) = -0.73 V (1650 mV)"
const expectedQuillData = [{insert:"CV (10 mM in <solvent> vs. Ref "},{insert:"(Fc"},{insert:"+",attributes:{script:'super'}},{insert:"/Fc) "},{insert:"= -0.72 V, v = 0.10 V/s, to neg.):"},{insert:"\nE"},{insert:"1/2",attributes:{script:'sub'}},{insert:" = ([Cu(TMGqu)] , ΔE"},{insert:"p",attributes:{script:'sub'}},{insert:") = -0.73 V (1650 mV)"},]
const layout = allLayouts.CYCLIC_VOLTAMMETRY
const data = {
scanRate: 0.1,
voltaData: {
listPeaks: [{"min":{"x":-1.5404,"y":-0.00000307144},"max":{"x":0.10003,"y":0.00000285434},"isRef":true,"e12":-0.720185,"createdAt":1716803991732,"updatedAt":1716803991733,"pecker":{"x":0.380242,"y":0.00000164361}},{"max":{"x":0.10002,"y":0.00000283434},"e12":-0.72519,"updatedAt":1716803991733,"min":{"x":-1.5504,"y":-0.00000317144},"pecker":{"x":0.480242,"y":0.00000174361},"isRef":false}],
xyData: {x:[1.49048,1.48049],y:[0.00000534724,0.00000481545],},
},
sampleName: 'Cu(TMGqu)',
concentration: 10,
};
const formattedData = inlineNotation(layout, data);
const { formattedString, quillData } = formattedData;
expect(formattedString).toEqual(expectedString);
expect(quillData).toEqual(expectedQuillData);
});

it('Inline notation for Cyclic voltammetry layout with solvent', () => {
const expectedString = "CV (10 mM in MeCN vs. Ref (Fc+/Fc) = -0.72 V, v = 0.10 V/s, to neg.):\nE1/2 = ([Cu(TMGqu)] , ΔEp) = -0.73 V (1650 mV)"
const expectedQuillData = [{insert:"CV (10 mM in MeCN vs. Ref "},{insert:"(Fc"},{insert:"+",attributes:{script:'super'}},{insert:"/Fc) "},{insert:"= -0.72 V, v = 0.10 V/s, to neg.):"},{insert:"\nE"},{insert:"1/2",attributes:{script:'sub'}},{insert:" = ([Cu(TMGqu)] , ΔE"},{insert:"p",attributes:{script:'sub'}},{insert:") = -0.73 V (1650 mV)"},]
const layout = allLayouts.CYCLIC_VOLTAMMETRY
const data = {
scanRate: 0.1,
voltaData: {
listPeaks: [{"min":{"x":-1.5404,"y":-0.00000307144},"max":{"x":0.10003,"y":0.00000285434},"isRef":true,"e12":-0.720185,"createdAt":1716803991732,"updatedAt":1716803991733,"pecker":{"x":0.380242,"y":0.00000164361}},{"max":{"x":0.10002,"y":0.00000283434},"e12":-0.72519,"updatedAt":1716803991733,"min":{"x":-1.5504,"y":-0.00000317144},"pecker":{"x":0.480242,"y":0.00000174361},"isRef":false}],
xyData: {x:[1.49048,1.48049],y:[0.00000534724,0.00000481545],},
},
sampleName: 'Cu(TMGqu)',
concentration: 10,
solvent: 'MeCN',
};
const formattedData = inlineNotation(layout, data);
const { formattedString, quillData } = formattedData;
expect(formattedString).toEqual(expectedString);
expect(quillData).toEqual(expectedQuillData);
});

it('Inline notation for Cyclic voltammetry layout with internal reference', () => {
const internalRefValues = {
'ferrocene': {
formatedStr: '(Fc+/Fc)',
deltaVal: [{insert:"(Fc"},{insert:"+",attributes:{script:'super'}},{insert:"/Fc) "}]
},
'decamethylferrocene': {
formatedStr: '(Me10Fc+/Me10Fc)',
deltaVal: [
{insert:"(Me"},
{insert:"10",attributes:{script:'sub'}},
{insert:"Fc"},
{insert:"+",attributes:{script:'super'}},
{insert:"/Me"},
{insert:"10",attributes:{script:'sub'}},
{insert:"Fc) "},
]
}
};
const layout = allLayouts.CYCLIC_VOLTAMMETRY
const data = {
scanRate: 0.1,
voltaData: {
listPeaks: [{"min":{"x":-1.5404,"y":-0.00000307144},"max":{"x":0.10003,"y":0.00000285434},"isRef":true,"e12":-0.720185,"createdAt":1716803991732,"updatedAt":1716803991733,"pecker":{"x":0.380242,"y":0.00000164361}},{"max":{"x":0.10002,"y":0.00000283434},"e12":-0.72519,"updatedAt":1716803991733,"min":{"x":-1.5504,"y":-0.00000317144},"pecker":{"x":0.480242,"y":0.00000174361},"isRef":false}],
xyData: {x:[1.49048,1.48049],y:[0.00000534724,0.00000481545],},
},
sampleName: 'Cu(TMGqu)',
concentration: 10,
solvent: 'MeCN',
};

for (const [refKey, refValue] of Object.entries(internalRefValues)) {
const { formatedStr, deltaVal } = refValue;
data['internalRef'] = refKey;

const expectedString = `CV (10 mM in MeCN vs. Ref ${formatedStr} = -0.72 V, v = 0.10 V/s, to neg.):\nE1/2 = ([Cu(TMGqu)] , ΔEp) = -0.73 V (1650 mV)`
const expectedQuillData = [{insert:"CV (10 mM in MeCN vs. Ref "},...deltaVal,{insert:"= -0.72 V, v = 0.10 V/s, to neg.):"},{insert:"\nE"},{insert:"1/2",attributes:{script:'sub'}},{insert:" = ([Cu(TMGqu)] , ΔE"},{insert:"p",attributes:{script:'sub'}},{insert:") = -0.73 V (1650 mV)"},]
const formattedData = inlineNotation(layout, data);
const { formattedString, quillData } = formattedData;
expect(formattedString).toEqual(expectedString);
expect(quillData).toEqual(expectedQuillData);
}
});
});
});
});

0 comments on commit cd4a793

Please sign in to comment.