Skip to content

Commit

Permalink
feat!: rename keepIdCode to appendIDCode and add appendNoStereoIDCode…
Browse files Browse the repository at this point in the history
…Hash and appendRacemateIDCodeHash
  • Loading branch information
lpatiny committed Apr 30, 2024
1 parent 96f5c4b commit bdb39ea
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 20 deletions.
10 changes: 5 additions & 5 deletions src/__tests__/acdPrediction/toc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,25 @@
"id": "Oz9gTP3NhSQZlWBu4aT4cizhQzg=",
"mf": "C4H8O2",
"idCodeHash": "8dce89763ab899350b4a01be188c1555",
"idCode": "gGP`@df]j`@",
"file": "./Bsp1/index.json",
"title": "Bsp1",
"idCode": "gGP`@df]j`@",
"selected": true
},
{
"id": "Il6UfZ1v3NduB9nsPgFi5RA4Xbg=",
"mf": "C4H8O2",
"idCodeHash": "134d499936f8fedb1170e3f741f72b9e",
"idCode": "gGP`@dfUj`@",
"file": "./Bsp2/index.json",
"title": "Bsp2"
"title": "Bsp2",
"idCode": "gGP`@dfUj`@"
},
{
"id": "z3uJ3OLwf2z/bAlG9yYAuADV/gA=",
"mf": "C4H8O",
"idCodeHash": "21dcc0027d441801e362cec51f90e9b9",
"idCode": "gJQ@@eKS@@",
"file": "./ethylvinylether/index.json",
"title": "ethylvinylether"
"title": "ethylvinylether",
"idCode": "gJQ@@eKS@@"
}
]
10 changes: 7 additions & 3 deletions src/__tests__/createExercisesTOC.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,26 @@ import { createExercisesTOC } from '../commands/createExercisesTOC.js';

test('createExercisesTOC', async () => {
const dataDir = join(__dirname, 'exercises');
await createExercisesTOC(__dirname, { dataDir });
await createExercisesTOC(__dirname, {
dataDir,
appendNoStereoIDCodeHash: true,
});

const files = (await readdir(dataDir)).sort();
const sizes = files
.filter((file) => file.match(/\.json$/))
.map((file) => {
return statSync(file).size;
});
expect(sizes).toStrictEqual([257, 138, 258, 746, 412]);
expect(sizes).toStrictEqual([138, 257, 138, 258, 1053, 412]);
});

test('createExercisesTOC with predicted', async () => {
const dataDir = join(__dirname, 'acdPrediction');
await createExercisesTOC(__dirname, {
dataDir,
keepIdCode: true,
appendIDCode: true,

cleanJCAMP: true,
});

Expand Down
Empty file.
12 changes: 12 additions & 0 deletions src/__tests__/exercises/Chiral/index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"spectra": [
{
"source": {
"jcampURL": "./1h.jdx"
},
"display": {
"name": ""
}
}
]
}
18 changes: 18 additions & 0 deletions src/__tests__/exercises/Chiral/structure.mol
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

Actelion Java MolfileCreator 1.0

7 6 0 0 1 0 0 0 0 0999 V2000
6.1251 -12.1252 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7.4241 -12.8752 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
8.7231 -12.1252 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
10.0222 -12.8752 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
11.3211 -12.1252 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7.4241 -14.3752 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
8.7231 -10.6252 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
1 2 1 0 0 0 0
2 3 1 0 0 0 0
3 4 1 0 0 0 0
4 5 1 0 0 0 0
2 6 1 1 0 0 0
3 7 1 1 0 0 0
M END
13 changes: 11 additions & 2 deletions src/__tests__/exercises/toc.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
[
{
"id": "XjKWTz7MPgN2x3evAUQWsjpoXNE=",
"mf": "C5H12O2",
"idCodeHash": "3d95df75d24a4142629d4a1258458cfb",
"file": "./Chiral/index.json",
"title": "Chiral",
"noStereoIDCodeHash": "21244f700a4490ed7d963ae780723fd6",
"racemateIDCodeHash": "ad594ab988e3bfd5e52f0ab5ffe4e59c",
"selected": true
},
{
"id": "8x+bblgo31zA/Y8aAYQHBwjFaZg=",
"mf": "C9H18",
"idCodeHash": "7ec5fb4efcce0c89de85193a330e6679",
"file": "./Exercises3/index.json",
"title": "Exercises3",
"selected": true
"title": "Exercises3"
},
{
"groupName": "Series1",
Expand Down
4 changes: 3 additions & 1 deletion src/commands/createExercisesTOC.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import { processExerciseFolder } from './toc/processExerciseFolder.js';
* @param {string} commandDir
* @param {object} [options={}]
* @param {string} [options.dataDir]
* @param {boolean} [options.keepIdCode] - kepp idCode in the answer to be able to provide tips
* @param {boolean} [options.appendIDCode] - append idCode in the answer to be able to provide tips
* @param {boolean} [options.appendNoStereoIDCodeHash] - append noStrereo idCode hash to check the answer without stereochemistry
* @param {boolean} [options.appendRacemateIDCodeHash] - append racemate idCode hash to check the answer as a racemate
* @param {boolean} [options.cleanJCAMP] - keep only the spectrum in the JCAMP-DX
*/
export async function createExercisesTOC(commandDir, options = {}) {
Expand Down
2 changes: 1 addition & 1 deletion src/commands/toc/createToc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const debug = debugFct('nmrium.toc');
* @param {string} commandDir
* @param {object} [options={}]
* @param {string} [options.dataDir=commandDir]
* @param {boolean} [options.keepIdCode=false] - Add the idCode to the toc
* @param {boolean} [options.appendIDCode=false] - Add the idCode to the toc
*/
export async function createToc(commandDir, folderProcessor, options = {}) {
const { dataDir = commandDir } = options;
Expand Down
54 changes: 51 additions & 3 deletions src/commands/toc/processExerciseFolder.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { hashElement } from 'folder-hash';
import { createTree } from 'jcampconverter';
import md5 from 'md5';
import OCL from 'openchemlib';
import { makeRacemic } from 'openchemlib-utils';

const { Molecule } = OCL;

Expand All @@ -21,7 +22,9 @@ let exercise = 0;
* @param {object} toc
* @param {object} [options={}]
* @param {string} [options.spectraFilter] - comma separated list of experiments to process, if not defined all experiments are processed
* @param {string} [options.keepIdCode=false] - Keep idCode in the toc
* @param {string} [options.appendIDCode=false] - Append idCode in the toc
* @param {string} [options.appendNoStereoIDCodeHash=false] - Append noStereo idCode hash to check
* @param {string} [options.appendRacemateIDCodeHash=true] - Append racemate idCode hash to check
* @param {boolean} [options.cleanJCAMP] - keep only the spectrum in the JCAMP-DX
*/

Expand All @@ -31,13 +34,20 @@ export async function processExerciseFolder(
toc,
options = {},
) {
let { spectraFilter, keepIdCode = false, cleanJCAMP = false } = options;
let {
spectraFilter,
appendIDCode = false,
cleanJCAMP = false,
appendNoStereoIDCodeHash = false,
appendRacemateIDCodeHash = true,
} = options;
if (spectraFilter) {
spectraFilter = new RegExp(
`^(${spectraFilter.split(',').join('|')}).`,
'i',
);
}

const currentFolder = join(basename, folder);
const entries = readdirSync(currentFolder);
const molfileName = readdirSync(currentFolder).filter((file) =>
Expand All @@ -51,6 +61,7 @@ export async function processExerciseFolder(
const mf = molecule.getMolecularFormula().formula;
const idCode = molecule.getIDCode();
const idCodeHash = md5(idCode);

const includedFiles = []; // we only hash the included files to find out if it is the same exercise
for (let spectrumName of entries.filter(
(file) =>
Expand Down Expand Up @@ -95,11 +106,29 @@ export async function processExerciseFolder(
id,
mf,
idCodeHash,
idCode: keepIdCode ? idCode : undefined,
file: `${URL_FOLDER}/${folder}/index.json`,
title,
selected: exercise === 1 || undefined,
};
if (appendIDCode) {
tocEntry.idCode = idCode;
}

if (appendNoStereoIDCodeHash || appendRacemateIDCodeHash) {
const { noStereoIDCodeHash, racemateIDCodeHash } = getStereoHash(molecule);
if (
appendNoStereoIDCodeHash &&
tocEntry.idCodeHash !== noStereoIDCodeHash
) {
tocEntry.noStereoIDCodeHash = noStereoIDCodeHash;
}
if (
appendRacemateIDCodeHash &&
tocEntry.idCodeHash !== racemateIDCodeHash
) {
tocEntry.racemateIDCodeHash = racemateIDCodeHash;
}
}
toc.push(tocEntry);
}

Expand Down Expand Up @@ -143,3 +172,22 @@ function flattenTree(entries, flatten) {
flatten.push(entry);
}
}

/**
* get the hash without stereo information or racemate
*
* @param {import('openchemlib').Molecule} molecule
* @returns
*/
function getStereoHash(molecule) {
const moleculeNoStereo = molecule.getCompactCopy();
moleculeNoStereo.stripStereoInformation();
const noStereoIDCode = moleculeNoStereo.getIDCode();
const noStereoIDCodeHash = md5(noStereoIDCode);

const moleculeRacemate = molecule.getCompactCopy();
makeRacemic(moleculeRacemate);
const racemateIDCode = moleculeRacemate.getIDCode();
const racemateIDCodeHash = md5(racemateIDCode);
return { noStereoIDCodeHash, racemateIDCodeHash };
}
30 changes: 25 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,31 @@ yargs(hideBin(normalizeArgv(process.argv)))
.scriptName('nmrium')
.command('createExercisesTOC [options]', 'Build toc.json for exercises', {
builder: (yargs) => {
return yargs.option('keepIdCode', {
alias: 'i',
type: 'boolean',
description: 'Add idCode in the exercise TOC',
});
return yargs
.option('appendIDCode', {
alias: 'i',
type: 'boolean',
default: false,
description: 'Add idCode in the exercise TOC',
})
.option('appendNoStereoIDCodeHash', {
alias: 's',
type: 'boolean',
default: false,
description:
'Add an idCode hash without stereo information in order to consider as correct the molecule with wrong stereo information',
})
.option('appendRacemateIDCodeHash', {
type: 'boolean',
default: true,
description:
'Allows to check the answer considering any enantiomer as correct',
})
.option('cleanJCAMP', {
type: 'boolean',
default: false,
description: 'Only keep the first spectrum in the JCAMP-DX file',
});
},
handler: (argv) => {
createExercisesTOC(homeDir, { ...argv });
Expand Down

0 comments on commit bdb39ea

Please sign in to comment.