📄 fragment.java
字号:
this.cnt = 1; /* of embeddings per molecule */ this.size = ext.size; /* note the extension type, */ this.chns = ext.chns; /* the number of carbon chains, */ this.src = ext.src; /* the source atom index, and */ this.dst = ext.dst; /* the destination atom index */ this.idx = ext.base.bonds.length; this.flgs = DEFAULT; /* set the default properties */ this.supp = new int[3]; /* create the support counters */ this.supp[2] = this.supp[i = this.list.mol.group] = 1; this.supp[1-i] = 0; /* init. the support counters */ if (ext.size <= 0) return; /* count molecule and embedding */ this.ris = new int[((ext.bdnew -1) << 1) +3]; na = ext.base.atoms.length; /* get the next atom index */ for (k = 0, i = 1; i < ext.size; i++) { if (ext.bonds[i].mark >= 0) continue; a = ext.atoms[i]; /* note atom indices of new bonds */ this.ris[k++] = (a.mark >= 0) ? a.mark : na++; a = ext.atoms[(i+1) % this.size]; this.ris[k++] = (a.mark >= 0) ? a.mark : na; } /* (needed for Extension.compareRing) */ this.ris[k++] = ext.pos1; /* note the insertion positions */ this.ris[k++] = ext.pos2; /* (distinguish equivalent rings) */ this.ris[k++] = ext.pmax; /* and the maximal position */ } /* Fragment() */ /*------------------------------------------------------------------*/ protected boolean add (Extension ext) { /* --- add an extended embedding */ int i, k; /* loop variables */ Embedding emb; /* created/packed embedding */ Bond b; /* to traverse the ring bonds */ if ((this.size < 0) /* if this is a chain fragment, */ && (ext.size != this.size))/* check the chain sizes for pruning */ if (this.size < ext.size) this.size = ext.size; if ((ext.size > 0) /* if ring extension in same molecule */ && (ext.base.mol == this.tail.mol)) { for (emb = this.curr; emb != null; emb = emb.succ) { if (emb.base != ext.base) continue; /* traverse embeddings with same base */ k = emb.bonds.length; /* the new bonds are at the end */ for (i = ext.size; --i >= 0; ) { b = ext.bonds[i]; /* traverse the added bonds */ if (b.mark >= 0) continue; if (b != emb.bonds[--k]) break; } /* if a bond differs, abort the loop */ if (i < 0) return false;/* if all bonds are identical, */ } /* the new embedding would be */ } /* a duplicate, so do not add it */ if (ext.base.mol != this.tail.mol) { this.supp[ext.base.mol.group]++; this.cnt = 0; /* count a new molecule and */ } /* (re)init. the embedding counter */ this.cnt++; /* count the new embedding */ this.supp[2]++; /* (per molecule and globally) */ if ((this.cnt <= this.max) /* check conditions for normal append */ || (ext.base.mol == this.list.mol)) { emb = new Embedding(ext); /* create a new embedding */ if (emb.mol != this.tail.mol) this.curr = emb; /* note embedding as first for mol. */ this.tail = this.tail.succ = emb; return true; /* append new embedding to the list */ } /* and abort the function */ if (this.curr.atoms == null) return true; /* check for already packed embedding */ if (this.mol == null) /* create molecule if necessary */ this.mol = new Molecule(this); /* Note that creating this molecule works only, because it is */ /* certain that the current embedding refers to a different */ /* molecule than the one that is used to create this molecule. */ /* This is also the reason why the embeddings for the first */ /* molecules cannot be packed, at least not at this point. */ this.tail = emb = this.curr; emb.base = null; /* if there are too many embeddings */ emb.atoms = null; /* for the current molecules, */ emb.bonds = null; /* delete them and only keep */ emb.succ = null; /* a reference to the molecule */ return true; /* return 'embedding was added' */ } /* add() */ /*------------------------------------------------------------------*/ protected Fragment (Fragment frag, int idx, int src, int dst) { /* --- create an initial fragment */ this.mol = null; /* not yet available as a molecule */ this.base = frag; /* store the base fragment */ this.list = null; /* there is no embedding yet */ this.tail = this.curr = null; this.max = frag.max; /* set memory usage parameters */ this.cnt = 0; /* (number of embeddings per mol.) */ this.chns = frag.chns; /* copy the number of carbon chains */ this.idx = idx; /* store the parameters */ this.src = src; /* of the extension bond */ this.dst = dst; /* (bond and atom indices) */ this.size = 0; /* set the type to single bond ext. */ this.flgs = DEFAULT; /* set the default properties */ this.supp = new int[3]; /* create the support counters */ this.supp[0] = this.supp[1] = this.supp[2] = 0; } /* Fragment() */ /*------------------------------------------------------------------*/ protected int size () /* --- get the size of the fragment */ { return this.list.atoms.length +this.chns; } /* The size of the fragment is the number of atoms in an output, */ /* which is why the number of carbon chains, each of which will be */ /* represented as a pseudo-atom has to be added. */ /*------------------------------------------------------------------*/ protected Molecule getAsMolecule () { /* --- get fragment as a molecule */ if (this.mol == null) /* create molecule if necessary */ this.mol = new Molecule(this); return this.mol; /* return created molecule */ } /* getAsMolecule() */ /*------------------------------------------------------------------*/ protected Embedding first () { /* --- get the first embedding */ this.ris = null; /* "delete" atom index vector */ this.tail = null; /* clear the packed embeddings cursor */ return this.curr = this.list; } /* first() */ /* return the first list element */ /*------------------------------------------------------------------*/ protected Embedding next () { /* --- get the next embedding */ this.curr = this.curr.succ; /* advance the embedding cursor */ if (this.curr == null) { /* if at end of (current) list */ this.curr = this.tail; /* check for another packed element */ this.tail = null; /* clear the packed element cursor */ if (this.curr == null) /* if there is none, this is */ return null; /* really the end of the list */ } if (this.curr.atoms != null)/* if this is not a packed element, */ return this.curr; /* it can be returned directly */ this.tail = this.curr.succ; /* advance packed element pointer */ return this.curr = this.curr.mol.embed(this.mol); } /* next() */ /* reembed fragment into molecule */ /*-------------------------------------------------------------------- Note that the first and next functions modify the tail pointer, which is reused as a cursor for packed embeddings, and thus it is impossible to add embeddings after one of these functions has been called. --------------------------------------------------------------------*/ protected Molecule firstMol () { /* --- get the first molecule */ this.curr = this.list; /* get the first embedding */ return (this.curr != null) ? this.curr.mol : null; } /* firstMol() */ /* return the embedding's molecule */ /*------------------------------------------------------------------*/ protected Molecule nextMol () { /* --- get the next molecule */ Molecule m = this.curr.mol; /* note the current molecule */ do { /* find embedding with new molecule */ this.curr = this.curr.succ; if (this.curr == null) return null; } while (this.curr.mol == m); return this.curr.mol; /* return the embedding's molecule */ } /* nextMol() */ /*------------------------------------------------------------------*/ protected void unembed () { /* --- remove embeddings */ if (this.mol == null) /* turn fragment into a molecule */ this.mol = new Molecule(this); /* (for later reembedding) */ this.list = this.curr = null; /* clear the embedding list */ } /* unembed() */ /*------------------------------------------------------------------*/ protected void reembed () { /* --- reembed a fragment */ int i, m; /* loop variable, buffer for marker */ int bt, dt; /* types of bond and dest. atom */ Atom a, d; /* to traverse/access the atoms */ Bond b; /* to traverse/access the bonds */ Embedding emb; /* to traverse the embeddings */ if (this.list != null) return; /* check for existing embeddings */ emb = this.base.first(); /* get base and its extension */ m = (this.dst < emb.atoms.length) ? this.dst : -1; bt = this.mol.bonds[this.idx].type; dt = this.mol.atoms[this.dst].type; for ( ; emb != null; emb = this.base.next()) { emb.markId(); /* traverse and mark the base embeds. */ a = emb.atoms[this.src]; /* get the source atom of the ext. */ for (i = 0; i < a.bondcnt; i++) { b = a.bonds[i]; /* traverse the unmarked bonds */ if (b.mark >= 0) continue; if (b.type > bt) break; /* compare the */ if (b.type < bt) continue; /* bond type */ d = (b.src != a) ? b.src : b.dst; if (d.type > dt) break; /* compare destination */ if (d.type < dt) continue; /* atom type */ if (d.mark != m) continue; /* and index */ this.add(new Embedding(emb, b)); } /* add reembedding to the fragment */ emb.unmark(); /* unmark the base embedding again */ } /* (clear atom and bond markers) */ } /* reembed() */ /*-------------------------------------------------------------------- With the above function a list of embeddings can quickly be recreated from a list of embeddings of the base fragment that was extended. --------------------------------------------------------------------*/ protected void setValid (boolean valid) { if (valid) this.flgs |= VALID; else this.flgs &= ~VALID; } /*------------------------------------------------------------------*/ protected boolean isValid () { return (this.flgs & VALID) != 0; } /*------------------------------------------------------------------*/ protected void setUnique (boolean unique) { if (unique) this.flgs |= UNIQUE; else this.flgs &= ~UNIQUE; } /*------------------------------------------------------------------*/ protected boolean isUnique () { return (this.flgs & UNIQUE) != 0; } /*------------------------------------------------------------------*/ protected boolean isRingExt () { return this.size > 0; } /*------------------------------------------------------------------*/ protected boolean isRingBondExt () { return (this.list.bonds[this.idx].type & Bond.RINGBOND) != 0; } /*------------------------------------------------------------------*/ protected boolean isPerfect (boolean chain) { /* --- check for a perfect extension */ int k, n, a, b; /* number of molecules, buffers */ Fragment frag; /* base fragment */ Embedding bas, bel; /* to traverse the base embeddings */ Embedding emb, nxt; /* to traverse the embeddings */ boolean tonew; /* whether bond leads to a new atom */ if ((this.base == null) /* if there is no base structure or */ || (this.size != 0)) /* this is a ring or chain extension, */ return false; /* the extension is not perfect */ frag = this.base; /* get the extension base (parent) */ if ((this.supp[0] != frag.supp[0]) /* (support in focus) */ || (this.supp[1] != frag.supp[1]) /* (support in complement) */ || (this.supp[2] % frag.supp[2] != 0)) /* (number of embeds.) */ return false; /* check for same counter values */ emb = this.list; /* get the first embedding */ if (chain /* if this is a chain start */ && (emb.bonds[this.idx].type == Bond.SINGLE) && emb.bonds[this.idx].isBridge()) { k = emb.atoms[this.dst].getElement(); if (emb.mol.map != null) k = emb.mol.map.decode(k); if ((k & Atom.TYPEMASK) == Atom.CARBON) return false; } /* this is not a perfect extension */ tonew = (this.dst >= emb.base.atoms.length); n = this.supp[0] +this.supp[1]; /* get number of molecules */ if ((n == 1) /* if there is only one molecule */ || (n == this.supp[2])) { /* or one embedding per molecule */ if (tonew) { /* if new bond leads to a new atom */ for (emb = this.first(); emb != null; emb = this.next()) if (!emb.bonds[this.idx].isBridge()) return false; /* check whether the new bond */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -