Skip to content
Snippets Groups Projects
Commit b8f168eb authored by JonStargaryen's avatar JonStargaryen
Browse files

iterators

parent 560c26c7
No related branches found
No related tags found
No related merge requests found
...@@ -9,12 +9,12 @@ import { LigandEncoder } from '../ligand-encoder'; ...@@ -9,12 +9,12 @@ import { LigandEncoder } from '../ligand-encoder';
import { StringBuilder } from '../../../mol-util'; import { StringBuilder } from '../../../mol-util';
import { getCategoryInstanceData } from '../cif/encoder/util'; import { getCategoryInstanceData } from '../cif/encoder/util';
import { BondType } from '../../../mol-model/structure/model/types'; import { BondType } from '../../../mol-model/structure/model/types';
// import { ComponentBond } from '../../../mol-model-formats/structure/property/bonds/comp'; import { ComponentBond } from '../../../mol-model-formats/structure/property/bonds/comp';
// // type MOL_TYPE = 'SMALL' | 'BIOPOLYMER' | 'PROTEIN' | 'NUCLEIC_ACID' | 'SACCHARIDE'; // type MOL_TYPE = 'SMALL' | 'BIOPOLYMER' | 'PROTEIN' | 'NUCLEIC_ACID' | 'SACCHARIDE';
// // type CHARGE_TYPE = 'NO_CHARGES' | 'DEL_RE' | 'GASTEIGER' | 'GAST_HUCK' | 'HUCKEL' | 'PULLMAN' | 'GAUSS80_CHARGES' | 'AMPAC_CHARGES' | 'MULLIKEN_CHARGES' | 'DICT_ CHARGES' | 'MMFF94_CHARGES' | 'USER_CHARGES'; // type CHARGE_TYPE = 'NO_CHARGES' | 'DEL_RE' | 'GASTEIGER' | 'GAST_HUCK' | 'HUCKEL' | 'PULLMAN' | 'GAUSS80_CHARGES' | 'AMPAC_CHARGES' | 'MULLIKEN_CHARGES' | 'DICT_ CHARGES' | 'MMFF94_CHARGES' | 'USER_CHARGES';
// const NON_METAL_ATOMS = 'H D B C N O F Si P S Cl As Se Br Te I At He Ne Ar Kr Xe Rn'.split(' '); const NON_METAL_ATOMS = 'H D B C N O F Si P S Cl As Se Br Te I At He Ne Ar Kr Xe Rn'.split(' ');
// type BondData = { label_atom_id: string, order: number, aromatic: boolean }; type BondMap = Map<string, { order: number, flags: number }>;
// specification: http://chemyang.ccnu.edu.cn/ccb/server/AIMMS/mol2.pdf // specification: http://chemyang.ccnu.edu.cn/ccb/server/AIMMS/mol2.pdf
export class Mol2Encoder extends LigandEncoder { export class Mol2Encoder extends LigandEncoder {
...@@ -50,8 +50,7 @@ export class Mol2Encoder extends LigandEncoder { ...@@ -50,8 +50,7 @@ export class Mol2Encoder extends LigandEncoder {
} }
}); });
// const sybyl = this.mapToSybyl(label_atom_id1, atom1.type_symbol, bondMap); const sybyl = this.mapToSybyl(label_atom_id1, atom1.type_symbol, bondMap);
const sybyl = '?';
StringBuilder.writeSafe(a, `${i1 + 1} ${label_atom_id1} ${atom1.Cartn_x.toFixed(3)} ${atom1.Cartn_y.toFixed(3)} ${atom1.Cartn_z.toFixed(3)} ${sybyl} 1 ${name} 0.000\n`); StringBuilder.writeSafe(a, `${i1 + 1} ${label_atom_id1} ${atom1.Cartn_x.toFixed(3)} ${atom1.Cartn_y.toFixed(3)} ${atom1.Cartn_z.toFixed(3)} ${sybyl} 1 ${name} 0.000\n`);
}); });
...@@ -62,146 +61,224 @@ export class Mol2Encoder extends LigandEncoder { ...@@ -62,146 +61,224 @@ export class Mol2Encoder extends LigandEncoder {
StringBuilder.writeSafe(this.out, `@<TRIPOS>SUBSTRUCTURE\n1 ${name} 1\n`); StringBuilder.writeSafe(this.out, `@<TRIPOS>SUBSTRUCTURE\n1 ${name} 1\n`);
} }
// private toArray(map: Map<string, { order: number, flags: number }>): BondData[] { private count<K, V>(map: Map<K, V>, predicate: (k: K, v: V) => boolean): number {
// const array: BondData[] = []; let count = 0;
// map.forEach((v, k) => array.push({ label_atom_id: k, order: v.order, aromatic: BondType.is(BondType.Flag.Aromatic, v.flags) })); const iter = map.entries();
// return array; let result = iter.next();
// } while (!result.done) {
if (predicate(result.value[0], result.value[1])) {
count++;
}
result = iter.next();
}
return count;
}
private orderSum(map: BondMap): number {
let sum = 0;
const iter = map.values();
let result = iter.next();
while (!result.done) {
sum += result.value.order;
result = iter.next();
}
return sum;
}
private isNonMetalBond(label_atom_id: string): boolean {
return NON_METAL_ATOMS.some(a => label_atom_id.startsWith(a));
}
private extractNonmets(map: BondMap): BondMap {
const ret = new Map<string, { order: number, flags: number }>();
const iter = map.entries();
let result = iter.next();
while (!result.done) {
const [k, v] = result.value;
if (NON_METAL_ATOMS.some(a => k.startsWith(a))) {
ret.set(k, v);
}
result = iter.next();
}
return ret;
}
// see https://www.sdsc.edu/CCMS/Packages/cambridge/pluto/atom_types.html // see https://www.sdsc.edu/CCMS/Packages/cambridge/pluto/atom_types.html
// cannot account for covalently bound amino acids etc // cannot account for covalently bound amino acids etc
// private mapToSybyl(label_atom_id: string, type_symbol: string, bondMap: ComponentBond.Entry) { private mapToSybyl(label_atom_id1: string, type_symbol1: string, bondMap: ComponentBond.Entry) {
// const partialBondMap = bondMap.map.get(label_atom_id)!; // TODO if altLoc: 'Du' // 1.1
// const bond = this.toArray(partialBondMap); // TODO if end of polymeric bond: 'Du' // 1.2
if (type_symbol1 === 'D') return 'H'; // 1.3
// const num_bond = bond.length; if (type_symbol1 === 'P') return 'P.3'; // 1.4, 4mpo/ligand?encoding=mol2&auth_seq_id=203 (PO4)
// const nonmet = bond.filter(b => this.isNonMetalBond(b)); if (type_symbol1 === 'Co' || type_symbol1 === 'Ru') return type_symbol1 + '.oh'; // 1.5
// const num_nonmet = nonmet.length;
// const arom = bond.filter(e => e.aromatic); const bonds = bondMap.map.get(label_atom_id1)!;
// const num_arom = arom.length; const numBonds = bonds.size;
// // TODO if altLoc: 'Du' // 1.1 if (type_symbol1 === 'Ti' || type_symbol1 === 'Cr') { // 1.10
// // TODO if end of polymeric bond: 'Du' // 1.2 return type_symbol1 + (numBonds <= 4 ? '.th' : '.oh'); // 1.10.1 & 1.10.2
// if (type_symbol === 'D') return 'H'; // 1.3 }
// if (type_symbol === 'P') return 'P.3'; // 1.4, 4mpo/ligand?encoding=mol2&auth_seq_id=203 (PO4) if (type_symbol1 === 'C') { // 1.6
// if (type_symbol === 'Co' || type_symbol === 'Ru') return type_symbol + '.oh'; // 1.5 if (numBonds >= 4 && this.count(bonds, (_k, v) => v.order === 1) >= 4) return 'C.3'; // 1.6.1, 3rga/ligand?encoding=mol2&auth_seq_id=307 (MOH)
// if (type_symbol === 'C') { // 1.6 if (numBonds === 3 && this.isCat(bonds, bondMap)) return 'C.cat'; // 1.6.2, 1acj/ligand?encoding=mol2&auth_seq_id=44 (ARG), 5vjb/ligand?encoding=mol2&auth_seq_id=101 (GAI)
// if (num_bond >= 4 && bond.every(b => b.order === 1)) return 'C.3'; // 1.6.1, 3rga/ligand?encoding=mol2&auth_seq_id=307 (MOH) if (numBonds >= 2 && this.count(bonds, (_k, v) => BondType.is(BondType.Flag.Aromatic, v.flags)) >= 2) return 'C.ar'; // 1.6.3, 1acj/ligand?encoding=mol2&auth_seq_id=30 (PHE), 1acj/ligand?encoding=mol2&auth_seq_id=63 (TYR), 1acj/ligand?encoding=mol2&auth_seq_id=84 (TRP), 1acj/ligand?encoding=mol2&auth_seq_id=999 (THA)
// if (num_bond === 3 && this.isCat(label_atom_id, bond, bondMap)) return 'C.cat'; // 1.6.2, 1acj/ligand?encoding=mol2&auth_seq_id=44 (ARG), 5vjb/ligand?encoding=mol2&auth_seq_id=101 (GAI) if ((numBonds === 1 || numBonds === 2) && this.count(bonds, (_k, v) => v.order === 3)) return 'C.1'; // 1.6.4, 3i04/ligand?encoding=mol2&auth_asym_id=C&auth_seq_id=900 (CYN)
// if (num_bond >= 2 && num_arom >= 2) return 'C.ar'; // 1.6.3, 1acj/ligand?encoding=mol2&auth_seq_id=30 (PHE), 1acj/ligand?encoding=mol2&auth_seq_id=63 (TYR), 1acj/ligand?encoding=mol2&auth_seq_id=84 (TRP), 1acj/ligand?encoding=mol2&auth_seq_id=999 (THA) return 'C.2'; // 1.6.5
// if ((num_bond === 1 || num_bond === 2) && bond.filter(b => b.order === 3).length === 1) return 'C.1'; // 1.6.4, 3i04/ligand?encoding=mol2&auth_asym_id=C&auth_seq_id=900 (CYN) }
// return 'C.2'; // 1.6.5
// } // most of the time, bonds will equal non-metal bonds
// if (type_symbol === 'O') { // 1.7 const nonmets = this.count(bonds, (k, _v) => this.isNonMetalBond(k)) === bonds.size ? bonds : this.extractNonmets(bonds);
// if (num_nonmet === 1) { // 1.7.1 const numNonmets = nonmets.size;
// if (this.isOC(nonmet[0], bondMap)) return 'O.co2'; // 1.7.1.1, 4h2v/ligand?encoding=mol2&auth_seq_id=403 (ACT)
// if (this.isOP(nonmet[0], bondMap)) return 'O.co2'; // 1.7.1.2, 4mpo/ligand?encoding=mol2&auth_seq_id=203 (PO4) if (type_symbol1 === 'O') { // 1.7
// } if (numNonmets === 1) { // 1.7.1
// if (num_nonmet >= 2 && bond.every(b => b.order === 1)) return 'O.3'; // 1.7.2, 1acj/ligand?encoding=mol2&auth_seq_id=601 (HOH), 3rga/ligand?encoding=mol2&auth_seq_id=307 (MOH) if (this.isOC(nonmets, bondMap)) return 'O.co2'; // 1.7.1.1, 4h2v/ligand?encoding=mol2&auth_seq_id=403 (ACT)
// return 'O.2'; // 1.7.3, 1acj/ligand?encoding=mol2&auth_seq_id=4 (SER) if (this.isOP(nonmets, bondMap)) return 'O.co2'; // 1.7.1.2, 4mpo/ligand?encoding=mol2&auth_seq_id=203 (PO4)
// } }
// if (type_symbol === 'N') { // 1.8 if (numNonmets >= 2 && this.count(bonds, (_k, v) => v.order === 1) === bonds.size) return 'O.3'; // 1.7.2, 1acj/ligand?encoding=mol2&auth_seq_id=601 (HOH), 3rga/ligand?encoding=mol2&auth_seq_id=307 (MOH)
// if (num_nonmet === 4 && bond.every(b => b.order === 1)) return 'N.4'; // 1.8.1, 4ikf/ligand?encoding=mol2&auth_seq_id=403 (NH4) return 'O.2'; // 1.7.3, 1acj/ligand?encoding=mol2&auth_seq_id=4 (SER)
// if (num_bond >= 2 && num_arom === 2) return 'N.ar'; // 1.8.2, 1acj/ligand?encoding=mol2&auth_seq_id=84 (TRP), 1acj/ligand?encoding=mol2&auth_seq_id=999 (THA) }
// if (num_nonmet === 1 && nonmet.some(b => b.order === 3)) return 'N.1'; // 1.8.3, 3i04/ligand?encoding=mol2&auth_asym_id=C&auth_seq_id=900 (CYN) if (type_symbol1 === 'N') { // 1.8
// if (num_nonmet === 2 && (nonmet[0].order + nonmet[1].order === 4)) return 'N.1'; // 1.8.4, 3sbr/ligand?encoding=mol2&auth_seq_id=640&auth_asym_id=D (N2O) if (numNonmets === 4 && this.count(nonmets, (_k, v) => v.order === 1) === 4) return 'N.4'; // 1.8.1, 4ikf/ligand?encoding=mol2&auth_seq_id=403 (NH4)
// if (num_nonmet === 3 && this.hasCOCS(nonmet, bondMap)) return 'N.am'; // 1.8.5, 3zfz/ligand?encoding=mol2&auth_seq_id=1669 (1W8) if (numBonds >= 2 && this.count(bonds, (_k, v) => BondType.is(BondType.Flag.Aromatic, v.flags)) >= 2) return 'N.ar'; // 1.8.2, 1acj/ligand?encoding=mol2&auth_seq_id=84 (TRP), 1acj/ligand?encoding=mol2&auth_seq_id=999 (THA)
// if (num_nonmet === 3) { // 1.8.6 if (numNonmets === 1 && this.count(nonmets, (_k, v) => v.order === 3)) return 'N.1'; // 1.8.3, 3i04/ligand?encoding=mol2&auth_asym_id=C&auth_seq_id=900 (CYN)
// if (nonmet.filter(b => b.order > 1).length === 1) return 'N.pl3'; // 1.8.6.1, 4hon/ligand?encoding=mol2&auth_seq_id=407 (NO3) if (numNonmets === 2 && this.orderSum(nonmets) === 4) return 'N.1'; // 1.8.4, 3sbr/ligand?encoding=mol2&auth_seq_id=640&auth_asym_id=D (N2O)
// if (nonmet.every(b => b.order === 1)) { if (numNonmets === 3 && this.hasCOCS(nonmets, bondMap)) return 'N.am'; // 1.8.5, 3zfz/ligand?encoding=mol2&auth_seq_id=1669 (1W8)
// if (this.isNpl3(nonmet, bondMap)) return 'N.pl3'; // 1.8.6.1.1 & 1.8.6.1.2, 1acj/ligand?encoding=mol2&auth_seq_id=44 (ARG), 5vjb/ligand?encoding=mol2&auth_seq_id=101 (GAI) if (numNonmets === 3) { // 1.8.6
// } if (this.count(nonmets, (_k, v) => v.order > 1) === 1) return 'N.pl3'; // 1.8.6.1, 4hon/ligand?encoding=mol2&auth_seq_id=407 (NO3)
// return 'N.3'; if (this.count(nonmets, (_k, v) => v.order === 1) === 3) {
// } if (this.isNpl3(nonmets, bondMap)) return 'N.pl3'; // 1.8.6.1.1 & 1.8.6.1.2, 1acj/ligand?encoding=mol2&auth_seq_id=44 (ARG), 5vjb/ligand?encoding=mol2&auth_seq_id=101 (GAI)
// return 'N.2'; // 1.8.7, 1acj/ligand?encoding=mol2&auth_seq_id=4 (SER) }
// } return 'N.3';
// if (type_symbol === 'S') { // 1.9 }
// if (num_nonmet === 3 && this.countOfOxygenWithSingleNonmet(nonmet, bondMap) === 1) return 'S.o'; // 1.9.1, 4i03/ligand?encoding=mol2&auth_seq_id=312 (DMS) return 'N.2'; // 1.8.7, 1acj/ligand?encoding=mol2&auth_seq_id=4 (SER)
// if (num_nonmet === 4 && this.countOfOxygenWithSingleNonmet(nonmet, bondMap) === 2) return 'S.o2'; // 1.9.2, 1udt/ligand?encoding=mol2&auth_seq_id=1000 (VIA) }
// if (num_nonmet >= 2 && bond.every(b => b.order === 1)) return 'S.3'; // 1.9.3, 3zfz/ligand?encoding=mol2&auth_seq_id=1669 (1W8) if (type_symbol1 === 'S') { // 1.9
// return 'S.2'; // 1.9.4, 4gpc/ligand?encoding=mol2&auth_seq_id=902 (SO4) if (numNonmets === 3 && this.countOfOxygenWithSingleNonmet(nonmets, bondMap) === 1) return 'S.o'; // 1.9.1, 4i03/ligand?encoding=mol2&auth_seq_id=312 (DMS)
// } if (numNonmets === 4 && this.countOfOxygenWithSingleNonmet(nonmets, bondMap) === 2) return 'S.o2'; // 1.9.2, 1udt/ligand?encoding=mol2&auth_seq_id=1000 (VIA)
// if (type_symbol === 'Ti' || type_symbol === 'Cr') { // 1.10 if (numNonmets >= 2 && this.count(bonds, (_k, v) => v.order === 1) >= 2) return 'S.3'; // 1.9.3, 3zfz/ligand?encoding=mol2&auth_seq_id=1669 (1W8), 4gpc/ligand?encoding=mol2&auth_seq_id=902 (SO4)
// return type_symbol + (num_bond <= 4 ? '.th' : '.oh'); // 1.10.1 & 1.10.2 return 'S.2'; // 1.9.4
// } }
// return type_symbol; // 1.11 return type_symbol1; // 1.11
// } }
// private isNonMetalBond(b: BondData): boolean { // 1.8.6.2.1: If one single bond is to an atom that forms a bond of type double, triple, aromatic or
// // would be nice to have type_symbol here... // delocalised .AND. one other single bond is to H then atom_type is N.pl3
// return NON_METAL_ATOMS.some(a => this.getLabel(b.label_atom_id).startsWith(a)); // 1.8.6.2.2: If one single bond is to an atom that forms a bond of type double, triple, aromatic or
// } // delocalised .AND. neither of the other single bonds are to H .AND. sum_of_angles around N .ge. 350 deg then atom_type is N.pl3
// TODO cannot check accurately for delocalized bonds
// // 1.8.6.2.1: If one single bond is to an atom that forms a bond of type double, triple, aromatic or private isNpl3(nonmets: BondMap, bondMap: ComponentBond.Entry): boolean {
// // delocalised .AND. one other single bond is to H then atom_type is N.pl3 const iter = nonmets.keys();
// // 1.8.6.2.2: If one single bond is to an atom that forms a bond of type double, triple, aromatic or let result = iter.next();
// // delocalised .AND. neither of the other single bonds are to H .AND. sum_of_angles around N .ge. 350 deg then atom_type is N.pl3 while (!result.done) {
// // TODO cannot check accurately for delocalized bonds const label_atom_id = result.value;
// // TODO cannot check accurately for 2nd criterion without coordinates const adjacentBonds = bondMap.map.get(label_atom_id)!;
// private isNpl3(nonmet: BondData[], bondMap: ComponentBond.Entry): boolean { if (this.count(adjacentBonds, (_k, v) => v.order > 1 || BondType.is(BondType.Flag.Aromatic, v.flags))) {
// for (let i = 0, il = nonmet.length; i < il; i++) { // TODO check accurately for 2nd criterion with coordinates
// const consumed = nonmet[i]; return true;
// // determine index that fulfills 1st criterion }
// if (this.toArray(bondMap.map.get(consumed.label_atom_id)!).some(b => b.order > 1 || b.aromatic)) { result = iter.next();
// if (nonmet.filter(b => b !== consumed).filter(b => this.getLabel(b.label_atom_id).startsWith('H')).length === 1) return true; // 1.8.6.2.1 }
// if (nonmet.filter(b => b !== consumed).every(b => !this.getLabel(b.label_atom_id).startsWith('H'))) return true; // 1.8.6.2.2 return false;
// } }
// }
// return false; // If bond is to carbon .AND. carbon forms a total of 3 bonds, 2 of which are to an oxygen
// } // forming only 1 non-metal bond then atom_type is O.co2
private isOC(nonmets: BondMap, bondMap: ComponentBond.Entry): boolean {
// // If bond is to carbon .AND. carbon forms a total of 3 bonds, 2 of which are to an oxygen const nonmet = nonmets.entries().next()!.value as [string, { order: number, flags: number }];
// // forming only 1 non-metal bond then atom_type is O.co2 if (!nonmet[0].startsWith('C')) return false;
// private isOC(nonmet: BondData, bondMap: ComponentBond.Entry): boolean { const carbonBonds = bondMap.map.get(nonmet[0])!;
// if (!this.getLabel(nonmet.label_atom_id).startsWith('C')) return false; if (carbonBonds.size !== 3) return false;
// const carbonBonds = this.toArray(bondMap.map.get(nonmet.label_atom_id)!);
// if (carbonBonds.length !== 3) return false; let count = 0;
// return carbonBonds.filter(b => this.getLabel(b.label_atom_id).startsWith('O') && const iter = carbonBonds.keys();
// this.toArray(bondMap.map.get(b.label_atom_id)!).filter(ob => this.isNonMetalBond(ob)).length === 1).length === 2; let result = iter.next();
// } while (!result.done) {
const label_atom_id = result.value;
// // If bond is to phosphorus .AND. phosphorus forms at least 2 bonds to an oxygen forming if (label_atom_id.startsWith('O')) {
// // only 1 non-metal bond then atom_type is O.co2 const adjacentBonds = bondMap.map.get(label_atom_id)!;
// private isOP(nonmet: BondData, bondMap: ComponentBond.Entry): boolean { if (this.count(adjacentBonds, (k, _v) => this.isNonMetalBond(k)) === 1) count++;
// if (!this.getLabel(nonmet.label_atom_id).startsWith('P')) return false; }
// const phosphorusBonds = this.toArray(bondMap.map.get(nonmet.label_atom_id)!); result = iter.next();
// if (phosphorusBonds.length < 2) return false; }
// return phosphorusBonds.filter(b => this.getLabel(b.label_atom_id).startsWith('O') && return count === 2;
// this.toArray(bondMap.map.get(b.label_atom_id)!).filter(ob => this.isNonMetalBond(ob)).length === 1).length >= 2; }
// }
// If bond is to phosphorus .AND. phosphorus forms at least 2 bonds to an oxygen forming
// // If num_bond .eq. 3 .AND. all bonds are acyclic .AND. all bonds are to nitrogen .AND. each // only 1 non-metal bond then atom_type is O.co2
// // nitrogen forms bonds to 2 other atoms both of which are not oxygen then atom_type is C.cat. private isOP(nonmets: BondMap, bondMap: ComponentBond.Entry): boolean {
// private isCat(root: string, bond: BondData[], bondMap: ComponentBond.Entry): boolean { const nonmet = nonmets.entries().next()!.value as [string, { order: number, flags: number }];
// if (bond.some(b => !this.getLabel(b.label_atom_id).startsWith('N'))) return false; if (!nonmet[0].startsWith('P')) return false;
// const nitrogenBonds = bond.map(b => b.label_atom_id).map(label_atom_id => this.toArray(bondMap.map.get(label_atom_id)!)); const phosphorusBonds = bondMap.map.get(nonmet[0])!;
if (phosphorusBonds.size < 2) return false;
// // ensure no cycles
// const all = []; let count = 0;
// const unique = new Set(); const iter = phosphorusBonds.keys();
// nitrogenBonds.forEach(a => a.map(b => b.label_atom_id).filter(lai => lai !== root).forEach(lai => { all.push(lai); unique.add(lai); })); let result = iter.next();
// if (all.length !== unique.size) return false; while (!result.done) {
const label_atom_id = result.value;
// return nitrogenBonds.every(a => a.length >= 2 && a.every(b => b.label_atom_id !== 'O')); if (label_atom_id.startsWith('O')) {
// } const adjacentBonds = bondMap.map.get(label_atom_id)!;
if (this.count(adjacentBonds, (k, _v) => this.isNonMetalBond(k)) === 1) count++;
// private countOfOxygenWithSingleNonmet(nonmet: BondData[], bondMap: ComponentBond.Entry): number { }
// return nonmet.map(b => b.label_atom_id) result = iter.next();
// .filter(label_atom_id => this.getLabel(label_atom_id).startsWith('O')) }
// .map(label_atom_id => this.toArray(bondMap.map.get(label_atom_id)!) return count >= 2;
// .filter(b => this.isNonMetalBond(b)).length === 1) }
// .length;
// } // If num_bond .eq. 3 .AND. all bonds are acyclic .AND. all bonds are to nitrogen .AND. each
// nitrogen forms bonds to 2 other atoms both of which are not oxygen then atom_type is C.cat.
// // If num_nonmet .eq. 3 .AND. one bond is to C=O or C=S then atom_type is N.am private isCat(currentBondMap: BondMap, bondMap: ComponentBond.Entry): boolean {
// private hasCOCS(nonmet: BondData[], bondMap: ComponentBond.Entry): boolean { const iter1 = currentBondMap.keys();
// return nonmet.map(b => b.label_atom_id) let result1 = iter1.next();
// .filter(label_atom_id => this.getLabel(label_atom_id).startsWith('C')) while (!result1.done) {
// .filter(label_atom_id => this.toArray(bondMap.map.get(label_atom_id)!) const label_atom_id = result1.value;
// .filter(b => b.order === 2) if (!label_atom_id.startsWith('N')) return false;
// .filter(b => this.getLabel(b.label_atom_id).startsWith('O') || this.getLabel(b.label_atom_id).startsWith('S')))
// .length === 1; const adjacentBonds = bondMap.map.get(label_atom_id)!;
// } if (adjacentBonds.size < 2) return false;
const iter2 = adjacentBonds.keys();
let result2 = iter2.next();
while (!result2.done) {
if (result2.value.startsWith('O')) return false;
result2 = iter2.next();
}
result1 = iter1.next();
}
// TODO ensure no cycles
return true;
}
private countOfOxygenWithSingleNonmet(nonmets: BondMap, bondMap: ComponentBond.Entry): number {
let count = 0;
const iter = nonmets.keys();
let result = iter.next();
while (!result.done) {
const label_atom_id = result.value;
if (label_atom_id.startsWith('O')) {
const adjacentBonds = bondMap.map.get(label_atom_id)!;
if (this.count(adjacentBonds, (k, _v) => this.isNonMetalBond(k))) count++;
}
result = iter.next();
}
return count;
}
// If num_nonmet .eq. 3 .AND. one bond is to C=O or C=S then atom_type is N.am
private hasCOCS(nonmets: BondMap, bondMap: ComponentBond.Entry): boolean {
const iter = nonmets.keys();
let result = iter.next();
while (!result.done) {
const label_atom_id = result.value;
if (label_atom_id.startsWith('C')) {
const adjacentBonds = bondMap.map.get(label_atom_id)!;
if (this.count(adjacentBonds, (k, v) => k.startsWith('O') || k.startsWith('S') && v.order === 2)) return true;
}
result = iter.next();
}
return false;
}
protected writeFullCategory<Ctx>(sb: StringBuilder, category: Category<Ctx>, context?: Ctx) { protected writeFullCategory<Ctx>(sb: StringBuilder, category: Category<Ctx>, context?: Ctx) {
const { instance, source } = getCategoryInstanceData(category, context); const { instance, source } = getCategoryInstanceData(category, context);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment