forked from enviPath/enviPy
Current Dev State
This commit is contained in:
144
static/js/ketcher2/script/ui/structformat.js
Normal file
144
static/js/ketcher2/script/ui/structformat.js
Normal file
@ -0,0 +1,144 @@
|
||||
/****************************************************************************
|
||||
* Copyright 2017 EPAM Systems
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
***************************************************************************/
|
||||
|
||||
import molfile from '../chem/molfile';
|
||||
|
||||
export const map = {
|
||||
'mol': {
|
||||
name: 'MDL Molfile',
|
||||
mime: 'chemical/x-mdl-molfile',
|
||||
ext: ['.mol'],
|
||||
supportsCoords: true
|
||||
},
|
||||
'rxn': {
|
||||
name: 'MDL Rxnfile',
|
||||
mime:'chemical/x-mdl-rxnfile',
|
||||
ext: ['.rxn'],
|
||||
supportsCoords: true
|
||||
},
|
||||
'cml': {
|
||||
name: 'CML',
|
||||
mime: 'chemical/x-cml',
|
||||
ext: ['.cml', '.mrv'],
|
||||
supportsCoords: true
|
||||
},
|
||||
'smiles': {
|
||||
name: 'Daylight SMILES',
|
||||
mime: 'chemical/x-daylight-smiles',
|
||||
ext: ['.smi', '.smiles']
|
||||
},
|
||||
'smarts': {
|
||||
name: 'Daylight SMARTS',
|
||||
mime: 'chemical/x-daylight-smarts',
|
||||
ext: ['.smarts']
|
||||
},
|
||||
'inchi': {
|
||||
name: 'InChI String',
|
||||
mime: 'chemical/x-inchi',
|
||||
ext: ['.inchi']
|
||||
}
|
||||
};
|
||||
|
||||
export function guess (structStr, strict) {
|
||||
// Mimic Indigo/molecule_auto_loader.cpp as much as possible
|
||||
const molStr = structStr.trim();
|
||||
|
||||
if (molStr.indexOf('$RXN') !== -1)
|
||||
return 'rxn';
|
||||
|
||||
const molMatch = molStr.match(/^(M END|\$END MOL)$/m);
|
||||
|
||||
if (molMatch) {
|
||||
const end = molMatch.index + molMatch[0].length;
|
||||
if (end === molStr.length ||
|
||||
molStr.slice(end, end + 20).search(/^\$(MOL|END CTAB)$/m) !== -1)
|
||||
return 'mol';
|
||||
}
|
||||
if (molStr[0] === '<' && molStr.indexOf('<molecule') !== -1)
|
||||
return 'cml';
|
||||
|
||||
if (molStr.slice(0, 5) === 'InChI')
|
||||
return 'inchi';
|
||||
|
||||
if (molStr.indexOf('\n') === -1) // TODO: smiles regexp
|
||||
return 'smiles';
|
||||
|
||||
// Molfile by default as Indigo does
|
||||
return strict ? null : 'mol';
|
||||
}
|
||||
|
||||
export function toString (struct, format, server, serverOpts) {
|
||||
console.assert(map[format], 'No such format');
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
var moldata = molfile.stringify(struct);
|
||||
if (format === 'mol' || format === 'rxn')
|
||||
resolve(moldata);
|
||||
else
|
||||
resolve(server.then(() => (
|
||||
server.convert({
|
||||
struct: moldata,
|
||||
output_format: map[format].mime
|
||||
}, serverOpts)
|
||||
), () => {
|
||||
throw Error(map[format].name + ' is not supported in the standalone mode');
|
||||
}).then(res => res.struct));
|
||||
});
|
||||
}
|
||||
|
||||
export function fromString (structStr, opts, server, serverOpts) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const format = guess(structStr);
|
||||
console.assert(map[format], 'No such format');
|
||||
|
||||
if (format === 'mol' || format === 'rxn') {
|
||||
const struct = molfile.parse(structStr, opts);
|
||||
resolve(struct);
|
||||
} else {
|
||||
let withCoords = map[format].supportsCoords;
|
||||
resolve(server.then(() => (
|
||||
withCoords ? server.convert({
|
||||
struct: structStr,
|
||||
output_format: map['mol'].mime
|
||||
}, serverOpts) : server.layout({
|
||||
struct: structStr.trim(),
|
||||
output_format: map['mol'].mime
|
||||
}, serverOpts)
|
||||
), () => {
|
||||
throw Error(map[format].name + ' is not supported in the standalone mode');
|
||||
}).then(res => {
|
||||
let struct = molfile.parse(res.struct);
|
||||
if (!withCoords)
|
||||
struct.rescale();
|
||||
return struct;
|
||||
}));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Pretty stupid Inchi check (extract from save)
|
||||
export function couldBeSaved(struct, format) {
|
||||
if (format === 'inchi') {
|
||||
if (struct.rgroups.count() !== 0)
|
||||
throw 'R-group fragments are not supported and will be discarded';
|
||||
struct = struct.clone(); // need this: .getScaffold()
|
||||
struct.sgroups.each((sgid, sg) => {
|
||||
// ? Not sure we should check it client side
|
||||
if (sg.type !== 'MUL' && !/^INDIGO_.+_DESC$/i.test(sg.data.fieldName))
|
||||
throw Error('InChi data format doesn\'t support s-groups');
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user