openchemlib-utils
Advanced tools
Comparing version 5.18.0 to 5.19.0
@@ -30,4 +30,4 @@ import { isCsp3 } from '../util/isCsp3.js'; | ||
let max = 0; | ||
const atomMask = new Array(molecule.getAllAtoms()); | ||
const atomList = new Array(molecule.getAllAtoms()); | ||
const atomMask = new Uint8Array(molecule.getAllAtoms()); | ||
const atomList = new Uint8Array(molecule.getAllAtoms()); | ||
for (let sphere = 0; sphere <= maxSphereSize; sphere++) { | ||
@@ -34,0 +34,0 @@ if (max === 0) { |
import type { Molecule } from 'openchemlib'; | ||
import { AtomPath } from '../path/getAllAtomsPaths.js'; | ||
import { HoseCodesOptions } from './HoseCodesOptions.js'; | ||
@@ -6,2 +7,26 @@ interface ToMolfileOptions { | ||
} | ||
interface TopicMoleculeOptions extends HoseCodesOptions { | ||
/** | ||
* The maximum path length to consider when calculating the paths between atoms | ||
* @default 5 | ||
*/ | ||
maxPathLength?: number; | ||
} | ||
type TopicMoleculeInternalOptions = Omit<TopicMoleculeOptions, 'maxPathLength'> & Required<Pick<TopicMoleculeOptions, 'maxPathLength'>>; | ||
interface GetAtomPathOptions { | ||
distance?: number; | ||
} | ||
interface GetHoseFragmentOptions { | ||
sphereSize?: number; | ||
/** | ||
* The atoms to tag in the fragment | ||
* @default rootAtoms | ||
*/ | ||
tagAtoms?: number[]; | ||
/** | ||
* The function to tag the atoms in place ! | ||
* @default tagAtom | ||
*/ | ||
tagAtomFct?: (molecule: Molecule, iAtom: number) => undefined; | ||
} | ||
/** | ||
@@ -15,6 +40,9 @@ * This class deals with topicity information and hose codes | ||
idCode: string; | ||
options: HoseCodesOptions; | ||
options: TopicMoleculeInternalOptions; | ||
private cache; | ||
constructor(molecule: Molecule, options?: HoseCodesOptions); | ||
constructor(molecule: Molecule, options?: TopicMoleculeOptions); | ||
ensureMapNo(): void; | ||
getHoseFragment(rootAtoms: number[], options?: GetHoseFragmentOptions): Molecule; | ||
getAtomPaths(atom1: number, atom2: number, options?: GetAtomPathOptions): number[][]; | ||
get atomsPaths(): AtomPath[][][]; | ||
toMolfile(options?: ToMolfileOptions): string; | ||
@@ -33,3 +61,3 @@ getMolecule(): Molecule; | ||
*/ | ||
get moleculeWithH(): any; | ||
get moleculeWithH(): Molecule; | ||
private get xMolecule(); | ||
@@ -72,3 +100,3 @@ /** | ||
get finalRanks(): any; | ||
toMolfileWithH(options?: ToMolfileOptions): any; | ||
toMolfileWithH(options?: ToMolfileOptions): string; | ||
/** | ||
@@ -75,0 +103,0 @@ * Returns an array of objects containing the oclID and the corresponding hydrogens and atoms |
@@ -0,2 +1,4 @@ | ||
import { getAllAtomsPaths } from '../path/getAllAtomsPaths.js'; | ||
import { getConnectivityMatrix } from '../util/getConnectivityMatrix.js'; | ||
import { tagAtom } from '../util/tagAtom.js'; | ||
import { getCanonizedDiaIDs } from './getCanonizedDiaIDs'; | ||
@@ -15,3 +17,3 @@ import { getCanonizedHoseCodes } from './getCanonizedHoseCodes'; | ||
this.originalMolecule = molecule; | ||
this.options = options; | ||
this.options = { maxPathLength: 5, ...options }; | ||
this.idCode = molecule.getIDCode(); | ||
@@ -46,2 +48,77 @@ this.molecule = this.originalMolecule.getCompactCopy(); | ||
} | ||
getHoseFragment(rootAtoms, options = {}) { | ||
const { sphereSize = 2, tagAtoms = rootAtoms, tagAtomFct = tagAtom, } = options; | ||
this.moleculeWithH.ensureHelperArrays(this.moleculeWithH.getOCL().Molecule.cHelperNeighbours); | ||
const copy = this.moleculeWithH.getCompactCopy(); | ||
copy.ensureHelperArrays(copy.getOCL().Molecule.cHelperNeighbours); | ||
for (let i = 0; i < copy.getAllAtoms(); i++) { | ||
copy.setAtomMass(i, copy.getAtomMass(i) + 2); | ||
} | ||
const atomMask = new Array(copy.getAllAtoms()).fill(false); | ||
const atomList = new Uint8Array(copy.getAllAtoms()); | ||
const atomMapping = new Array(copy.getAllAtoms()).fill(-1); | ||
const Molecule = copy.getOCL().Molecule; | ||
const fragment = new Molecule(0, 0); | ||
fragment.setFragment(true); | ||
let min = 0; | ||
let max = 0; | ||
for (let sphere = 0; sphere <= sphereSize; sphere++) { | ||
if (max === 0) { | ||
for (const rootAtom of rootAtoms) { | ||
atomList[max] = rootAtom; | ||
atomMask[rootAtom] = 1; | ||
max++; | ||
} | ||
} | ||
else { | ||
let newMax = max; | ||
for (let i = min; i < max; i++) { | ||
const atom = atomList[i]; | ||
for (let j = 0; j < this.moleculeWithH.getAllConnAtoms(atom); j++) { | ||
const connAtom = this.moleculeWithH.getConnAtom(atom, j); | ||
if (!atomMask[connAtom]) { | ||
atomMask[connAtom] = 1; | ||
atomList[newMax++] = connAtom; | ||
} | ||
} | ||
} | ||
min = max; | ||
max = newMax; | ||
} | ||
} | ||
copy.copyMoleculeByAtoms(fragment, atomMask, true, atomMapping); | ||
for (let i = 0; i < fragment.getAllAtoms(); i++) { | ||
fragment.setAtomMass(i, fragment.getAtomMass(i) - 2); | ||
} | ||
for (const atom of tagAtoms) { | ||
tagAtomFct(fragment, atomMapping[atom]); | ||
} | ||
return fragment; | ||
} | ||
getAtomPaths(atom1, atom2, options = {}) { | ||
const { distance } = options; | ||
if (distance !== undefined && distance > this.options.maxPathLength) { | ||
throw new Error('The distance is too long, you should increase the maxPathLength when instanciating the TopicMolecule'); | ||
} | ||
const atomPaths = this.atomsPaths[atom1]; | ||
const minDistance = distance || 0; | ||
const maxDistance = distance || this.options.maxPathLength; | ||
const paths = []; | ||
for (let i = minDistance; i <= maxDistance; i++) { | ||
for (const atomPath of atomPaths[i]) { | ||
if (atomPath.path.at(-1) === atom2) { | ||
paths.push(atomPath.path); | ||
} | ||
} | ||
} | ||
return paths; | ||
} | ||
get atomsPaths() { | ||
if (this.cache.atomsPaths) | ||
return this.cache.atomsPaths; | ||
this.cache.atomsPaths = getAllAtomsPaths(this.moleculeWithH, { | ||
maxPathLength: this.options.maxPathLength, | ||
}); | ||
return this.cache.atomsPaths; | ||
} | ||
toMolfile(options = {}) { | ||
@@ -48,0 +125,0 @@ const { version = 2 } = options; |
@@ -33,4 +33,4 @@ "use strict"; | ||
let max = 0; | ||
const atomMask = new Array(molecule.getAllAtoms()); | ||
const atomList = new Array(molecule.getAllAtoms()); | ||
const atomMask = new Uint8Array(molecule.getAllAtoms()); | ||
const atomList = new Uint8Array(molecule.getAllAtoms()); | ||
for (let sphere = 0; sphere <= maxSphereSize; sphere++) { | ||
@@ -37,0 +37,0 @@ if (max === 0) { |
import type { Molecule } from 'openchemlib'; | ||
import { AtomPath } from '../path/getAllAtomsPaths.js'; | ||
import { HoseCodesOptions } from './HoseCodesOptions.js'; | ||
@@ -6,2 +7,26 @@ interface ToMolfileOptions { | ||
} | ||
interface TopicMoleculeOptions extends HoseCodesOptions { | ||
/** | ||
* The maximum path length to consider when calculating the paths between atoms | ||
* @default 5 | ||
*/ | ||
maxPathLength?: number; | ||
} | ||
type TopicMoleculeInternalOptions = Omit<TopicMoleculeOptions, 'maxPathLength'> & Required<Pick<TopicMoleculeOptions, 'maxPathLength'>>; | ||
interface GetAtomPathOptions { | ||
distance?: number; | ||
} | ||
interface GetHoseFragmentOptions { | ||
sphereSize?: number; | ||
/** | ||
* The atoms to tag in the fragment | ||
* @default rootAtoms | ||
*/ | ||
tagAtoms?: number[]; | ||
/** | ||
* The function to tag the atoms in place ! | ||
* @default tagAtom | ||
*/ | ||
tagAtomFct?: (molecule: Molecule, iAtom: number) => undefined; | ||
} | ||
/** | ||
@@ -15,6 +40,9 @@ * This class deals with topicity information and hose codes | ||
idCode: string; | ||
options: HoseCodesOptions; | ||
options: TopicMoleculeInternalOptions; | ||
private cache; | ||
constructor(molecule: Molecule, options?: HoseCodesOptions); | ||
constructor(molecule: Molecule, options?: TopicMoleculeOptions); | ||
ensureMapNo(): void; | ||
getHoseFragment(rootAtoms: number[], options?: GetHoseFragmentOptions): Molecule; | ||
getAtomPaths(atom1: number, atom2: number, options?: GetAtomPathOptions): number[][]; | ||
get atomsPaths(): AtomPath[][][]; | ||
toMolfile(options?: ToMolfileOptions): string; | ||
@@ -33,3 +61,3 @@ getMolecule(): Molecule; | ||
*/ | ||
get moleculeWithH(): any; | ||
get moleculeWithH(): Molecule; | ||
private get xMolecule(); | ||
@@ -72,3 +100,3 @@ /** | ||
get finalRanks(): any; | ||
toMolfileWithH(options?: ToMolfileOptions): any; | ||
toMolfileWithH(options?: ToMolfileOptions): string; | ||
/** | ||
@@ -75,0 +103,0 @@ * Returns an array of objects containing the oclID and the corresponding hydrogens and atoms |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.groupDiastereotopicAtomIDs = exports.TopicMolecule = void 0; | ||
const getAllAtomsPaths_js_1 = require("../path/getAllAtomsPaths.js"); | ||
const getConnectivityMatrix_js_1 = require("../util/getConnectivityMatrix.js"); | ||
const tagAtom_js_1 = require("../util/tagAtom.js"); | ||
const getCanonizedDiaIDs_1 = require("./getCanonizedDiaIDs"); | ||
@@ -18,3 +20,3 @@ const getCanonizedHoseCodes_1 = require("./getCanonizedHoseCodes"); | ||
this.originalMolecule = molecule; | ||
this.options = options; | ||
this.options = { maxPathLength: 5, ...options }; | ||
this.idCode = molecule.getIDCode(); | ||
@@ -49,2 +51,77 @@ this.molecule = this.originalMolecule.getCompactCopy(); | ||
} | ||
getHoseFragment(rootAtoms, options = {}) { | ||
const { sphereSize = 2, tagAtoms = rootAtoms, tagAtomFct = tagAtom_js_1.tagAtom, } = options; | ||
this.moleculeWithH.ensureHelperArrays(this.moleculeWithH.getOCL().Molecule.cHelperNeighbours); | ||
const copy = this.moleculeWithH.getCompactCopy(); | ||
copy.ensureHelperArrays(copy.getOCL().Molecule.cHelperNeighbours); | ||
for (let i = 0; i < copy.getAllAtoms(); i++) { | ||
copy.setAtomMass(i, copy.getAtomMass(i) + 2); | ||
} | ||
const atomMask = new Array(copy.getAllAtoms()).fill(false); | ||
const atomList = new Uint8Array(copy.getAllAtoms()); | ||
const atomMapping = new Array(copy.getAllAtoms()).fill(-1); | ||
const Molecule = copy.getOCL().Molecule; | ||
const fragment = new Molecule(0, 0); | ||
fragment.setFragment(true); | ||
let min = 0; | ||
let max = 0; | ||
for (let sphere = 0; sphere <= sphereSize; sphere++) { | ||
if (max === 0) { | ||
for (const rootAtom of rootAtoms) { | ||
atomList[max] = rootAtom; | ||
atomMask[rootAtom] = 1; | ||
max++; | ||
} | ||
} | ||
else { | ||
let newMax = max; | ||
for (let i = min; i < max; i++) { | ||
const atom = atomList[i]; | ||
for (let j = 0; j < this.moleculeWithH.getAllConnAtoms(atom); j++) { | ||
const connAtom = this.moleculeWithH.getConnAtom(atom, j); | ||
if (!atomMask[connAtom]) { | ||
atomMask[connAtom] = 1; | ||
atomList[newMax++] = connAtom; | ||
} | ||
} | ||
} | ||
min = max; | ||
max = newMax; | ||
} | ||
} | ||
copy.copyMoleculeByAtoms(fragment, atomMask, true, atomMapping); | ||
for (let i = 0; i < fragment.getAllAtoms(); i++) { | ||
fragment.setAtomMass(i, fragment.getAtomMass(i) - 2); | ||
} | ||
for (const atom of tagAtoms) { | ||
tagAtomFct(fragment, atomMapping[atom]); | ||
} | ||
return fragment; | ||
} | ||
getAtomPaths(atom1, atom2, options = {}) { | ||
const { distance } = options; | ||
if (distance !== undefined && distance > this.options.maxPathLength) { | ||
throw new Error('The distance is too long, you should increase the maxPathLength when instanciating the TopicMolecule'); | ||
} | ||
const atomPaths = this.atomsPaths[atom1]; | ||
const minDistance = distance || 0; | ||
const maxDistance = distance || this.options.maxPathLength; | ||
const paths = []; | ||
for (let i = minDistance; i <= maxDistance; i++) { | ||
for (const atomPath of atomPaths[i]) { | ||
if (atomPath.path.at(-1) === atom2) { | ||
paths.push(atomPath.path); | ||
} | ||
} | ||
} | ||
return paths; | ||
} | ||
get atomsPaths() { | ||
if (this.cache.atomsPaths) | ||
return this.cache.atomsPaths; | ||
this.cache.atomsPaths = (0, getAllAtomsPaths_js_1.getAllAtomsPaths)(this.moleculeWithH, { | ||
maxPathLength: this.options.maxPathLength, | ||
}); | ||
return this.cache.atomsPaths; | ||
} | ||
toMolfile(options = {}) { | ||
@@ -51,0 +128,0 @@ const { version = 2 } = options; |
{ | ||
"name": "openchemlib-utils", | ||
"version": "5.18.0", | ||
"version": "5.19.0", | ||
"description": "Various utilities that extends openchemlib-js like HOSE codes or diastereotopic IDs", | ||
@@ -43,19 +43,19 @@ "main": "./lib/index.js", | ||
"devDependencies": { | ||
"@types/node": "^20.12.6", | ||
"@vitest/coverage-v8": "^1.4.0", | ||
"@types/node": "^20.12.11", | ||
"@vitest/coverage-v8": "^1.6.0", | ||
"cheminfo-build": "^1.2.0", | ||
"cheminfo-types": "^1.7.3", | ||
"eslint": "^8.57.0", | ||
"eslint-config-cheminfo-typescript": "^12.2.0", | ||
"eslint-config-cheminfo-typescript": "^12.4.0", | ||
"fifo-logger": "^1.0.0", | ||
"mf-parser": "^3.1.0", | ||
"mf-parser": "^3.1.1", | ||
"openchemlib": "^8.9.0", | ||
"prettier": "^3.2.5", | ||
"rimraf": "^5.0.5", | ||
"rimraf": "^5.0.7", | ||
"ts-node": "^10.9.2", | ||
"typescript": "^5.4.4", | ||
"vitest": "^1.4.0" | ||
"typescript": "^5.4.5", | ||
"vitest": "^1.6.0" | ||
}, | ||
"dependencies": { | ||
"atom-sorter": "^2.0.0", | ||
"atom-sorter": "^2.0.1", | ||
"ensure-string": "^1.2.0", | ||
@@ -62,0 +62,0 @@ "get-value": "^3.0.1", |
@@ -42,4 +42,4 @@ import { isCsp3 } from '../util/isCsp3.js'; | ||
let max = 0; | ||
const atomMask = new Array(molecule.getAllAtoms()); | ||
const atomList = new Array(molecule.getAllAtoms()); | ||
const atomMask = new Uint8Array(molecule.getAllAtoms()); | ||
const atomList = new Uint8Array(molecule.getAllAtoms()); | ||
@@ -46,0 +46,0 @@ for (let sphere = 0; sphere <= maxSphereSize; sphere++) { |
import type { Molecule } from 'openchemlib'; | ||
import { AtomPath, getAllAtomsPaths } from '../path/getAllAtomsPaths.js'; | ||
import { getConnectivityMatrix } from '../util/getConnectivityMatrix.js'; | ||
import { tagAtom } from '../util/tagAtom.js'; | ||
@@ -20,2 +22,40 @@ import { HoseCodesOptions } from './HoseCodesOptions.js'; | ||
interface TopicMoleculeOptions extends HoseCodesOptions { | ||
/** | ||
* The maximum path length to consider when calculating the paths between atoms | ||
* @default 5 | ||
*/ | ||
maxPathLength?: number; | ||
} | ||
type TopicMoleculeInternalOptions = Omit< | ||
TopicMoleculeOptions, | ||
'maxPathLength' | ||
> & | ||
Required<Pick<TopicMoleculeOptions, 'maxPathLength'>>; | ||
interface GetAtomPathOptions { | ||
/* | ||
* The distance between the two atoms. If not specified, all the distances will be considered | ||
*/ | ||
distance?: number; | ||
} | ||
interface GetHoseFragmentOptions { | ||
/* | ||
* The sphere size around any selected atoms to consider. Default is 2 | ||
*/ | ||
sphereSize?: number; | ||
/** | ||
* The atoms to tag in the fragment | ||
* @default rootAtoms | ||
*/ | ||
tagAtoms?: number[]; | ||
/** | ||
* The function to tag the atoms in place ! | ||
* @default tagAtom | ||
*/ | ||
tagAtomFct?: (molecule: Molecule, iAtom: number) => undefined; | ||
} | ||
/** | ||
@@ -29,9 +69,9 @@ * This class deals with topicity information and hose codes | ||
idCode: string; | ||
options: HoseCodesOptions; | ||
options: TopicMoleculeInternalOptions; | ||
private cache: any; | ||
constructor(molecule: Molecule, options: HoseCodesOptions = {}) { | ||
constructor(molecule: Molecule, options: TopicMoleculeOptions = {}) { | ||
this.originalMolecule = molecule; | ||
this.options = options; | ||
this.options = { maxPathLength: 5, ...options }; | ||
this.idCode = molecule.getIDCode(); | ||
@@ -74,3 +114,95 @@ this.molecule = this.originalMolecule.getCompactCopy(); | ||
toMolfile(options: ToMolfileOptions = {}) { | ||
getHoseFragment( | ||
rootAtoms: number[], | ||
options: GetHoseFragmentOptions = {}, | ||
): Molecule { | ||
const { | ||
sphereSize = 2, | ||
tagAtoms = rootAtoms, | ||
tagAtomFct = tagAtom, | ||
} = options; | ||
this.moleculeWithH.ensureHelperArrays( | ||
this.moleculeWithH.getOCL().Molecule.cHelperNeighbours, | ||
); | ||
const copy = this.moleculeWithH.getCompactCopy(); | ||
copy.ensureHelperArrays(copy.getOCL().Molecule.cHelperNeighbours); | ||
for (let i = 0; i < copy.getAllAtoms(); i++) { | ||
copy.setAtomMass(i, copy.getAtomMass(i) + 2); | ||
} | ||
const atomMask = new Array(copy.getAllAtoms()).fill(false); | ||
const atomList = new Uint8Array(copy.getAllAtoms()); | ||
const atomMapping = new Array(copy.getAllAtoms()).fill(-1); | ||
const Molecule = copy.getOCL().Molecule; | ||
const fragment = new Molecule(0, 0); | ||
fragment.setFragment(true); | ||
let min = 0; | ||
let max = 0; | ||
for (let sphere = 0; sphere <= sphereSize; sphere++) { | ||
if (max === 0) { | ||
for (const rootAtom of rootAtoms) { | ||
atomList[max] = rootAtom; | ||
atomMask[rootAtom] = 1; | ||
max++; | ||
} | ||
} else { | ||
let newMax = max; | ||
for (let i = min; i < max; i++) { | ||
const atom = atomList[i]; | ||
for (let j = 0; j < this.moleculeWithH.getAllConnAtoms(atom); j++) { | ||
const connAtom = this.moleculeWithH.getConnAtom(atom, j); | ||
if (!atomMask[connAtom]) { | ||
atomMask[connAtom] = 1; | ||
atomList[newMax++] = connAtom; | ||
} | ||
} | ||
} | ||
min = max; | ||
max = newMax; | ||
} | ||
} | ||
copy.copyMoleculeByAtoms(fragment, atomMask, true, atomMapping); | ||
for (let i = 0; i < fragment.getAllAtoms(); i++) { | ||
fragment.setAtomMass(i, fragment.getAtomMass(i) - 2); | ||
} | ||
for (const atom of tagAtoms) { | ||
tagAtomFct(fragment, atomMapping[atom]); | ||
} | ||
return fragment; | ||
} | ||
getAtomPaths(atom1: number, atom2: number, options: GetAtomPathOptions = {}) { | ||
const { distance } = options; | ||
if (distance !== undefined && distance > this.options.maxPathLength) { | ||
throw new Error( | ||
'The distance is too long, you should increase the maxPathLength when instanciating the TopicMolecule', | ||
); | ||
} | ||
const atomPaths = this.atomsPaths[atom1]; | ||
const minDistance = distance || 0; | ||
const maxDistance = distance || this.options.maxPathLength; | ||
const paths = []; | ||
for (let i = minDistance; i <= maxDistance; i++) { | ||
for (const atomPath of atomPaths[i]) { | ||
if (atomPath.path.at(-1) === atom2) { | ||
paths.push(atomPath.path); | ||
} | ||
} | ||
} | ||
return paths; | ||
} | ||
get atomsPaths(): AtomPath[][][] { | ||
if (this.cache.atomsPaths) return this.cache.atomsPaths; | ||
this.cache.atomsPaths = getAllAtomsPaths(this.moleculeWithH, { | ||
maxPathLength: this.options.maxPathLength, | ||
}); | ||
return this.cache.atomsPaths; | ||
} | ||
toMolfile(options: ToMolfileOptions = {}): string { | ||
const { version = 2 } = options; | ||
@@ -111,3 +243,3 @@ if (version === 2) { | ||
*/ | ||
get moleculeWithH() { | ||
get moleculeWithH(): Molecule { | ||
if (this.cache.moleculeWithH) return this.cache.moleculeWithH; | ||
@@ -118,3 +250,3 @@ this.cache.moleculeWithH = getMoleculeWithH(this.molecule); | ||
private get xMolecule() { | ||
private get xMolecule(): Molecule { | ||
if (this.cache.xMolecule) return this.cache.xMolecule; | ||
@@ -121,0 +253,0 @@ this.cache.xMolecule = getXMolecule(this.moleculeWithH); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1128843
828
16996
Updatedatom-sorter@^2.0.1