def _getBasisAtoms(self, ilayer): atom_numbers = Uniqify( [atom.GetAtomicNum() for atom in self._fragmentation.getAtoms()]) atom_numbers.sort() atoms = [ self._elements.GetSymbol(atom_number) for atom_number in atom_numbers ] return "".join( [self._formatSingleAtomBasis(ilayer, atom) for atom in atoms])
def _setupActiveFragmentsInformation(self): active_atoms = self._getActiveAtomsFromFragments() if self._active_atoms_distance > 0.0: active_atoms = self._getActiveAtomsFromDistance() if self._verbose: print("Info: FragIt [GAMESS-FMO] found {0:d} atoms which should be active".format(len(active_atoms))) self._active_atoms = active_atoms[:] atoms = self._active_atoms[:] frags = self._fragmentation.getFragments() fragment_layers = self._fragment_layers[:] if self._central_fragment == 0: self._active_frags = [] return # 1) If there are active atoms, we must find the associated fragments # 2) The associated fragments are labelled active # 3) The active fragments have their atoms made flexible # we now have region A if len(self._active_atoms) > 0: active_frags = [] #self._active_fragments[:] active_frags.append(self._central_fragment -1) # central must also be active for atom in atoms: ifrg = self._getFragmentFromAtom(atom) active_frags.extend([ifrg]) active_frags = Uniqify(active_frags) active_frags = sorted(active_frags) self._active_fragments = active_frags[:] # promote active fragments to layer 2 for active_fragment_id in active_frags: self._fragment_layers[active_fragment_id] = 2 # add active fragment atoms to list of active atoms fragments = self._fragmentation.getFragments() for frag in active_frags: atoms.extend(fragments[frag]) atoms = Uniqify(atoms) atoms = sorted(atoms) if self._verbose and len(atoms) != len(self._active_atoms): print("Info: FragIt [GAMESS-FMO] active region is now {0:d} atoms ({1:d} fragments) ".format(len(active_atoms), len(active_frags))) # Optionally freeze backbone atoms in the active region if self._freeze_backbone: for item in self._fragmentation.getBackboneAtoms(): if item in atoms: atoms.remove(item) continue atoms = Uniqify(atoms) atoms = sorted(atoms) self._active_atoms = atoms[:]
def _setupActiveFragmentsInformation(self): active_atoms = self._getActiveAtomsFromFragments() if self._active_atoms_distance > 0.0: active_atoms = self._getActiveAtomsFromDistance() #print "found %i atoms which should be active" % (len(active_atoms)) self._active_atoms = active_atoms[:] atoms = self._active_atoms[:] frags = self._fragmentation.getFragments() fragment_layers = self._fragment_layers[:] if self._central_fragment == 0: self._active_frags = [] return if len(self._active_atoms) > 0: #print "extending region A to include all atoms of close fragments" active_frags = [] #self._active_fragments[:] active_frags.append(self._central_fragment -1) # central must also be active for atom in atoms: ifrg = self._getFragmentFromAtom(atom) active_frags.extend([ifrg]) active_frags = Uniqify(active_frags) active_frags = sorted(active_frags) self._active_fragments = active_frags[:] # promote active fragments to layer 2 for active_fragment_id in active_frags: self._fragment_layers[active_fragment_id] = 2 # add active fragment atoms to list of active atoms fragments = self._fragmentation.getFragments() for frag in active_frags: atoms.extend(fragments[frag]) atoms = Uniqify(atoms) atoms = sorted(atoms) #print "active region is now %i atoms large (%i fragments)" % (len(atoms),len(active_frags)) #print atoms if self._freeze_backbone: #print "attempting to find and freeze backbone atoms in the active region" for item in self._fragmentation.getBackboneAtoms(): if item in atoms: atoms.remove(item) continue #print "active region is now %i atoms large (%i fragments)" % (len(atoms),len(active_frags)) #print atoms atoms = Uniqify(atoms) atoms = sorted(atoms) self._active_atoms = atoms[:]
def _getActiveAtomsFromDistance(self): atoms = [] central_atoms = self._fragmentation.getFragments()[ self._central_fragment - 1] atoms.extend(central_atoms) all_atoms = range(1, len(self._fragmentation.getAtoms()) + 1) for atom_idx in central_atoms: for atom_jdx in all_atoms: if atom_jdx in central_atoms: continue if atom_jdx in atoms: continue R = self._getDistanceBetweenAtoms(atom_idx, atom_jdx) if R < self._active_atoms_distance: atoms.append(atom_jdx) continue atoms = Uniqify(atoms) return sorted(atoms)
def _setupActiveFragmentsInformation(self): active_atoms = self._getActiveAtomsFromFragments() if self._active_atoms_distance > 0.0: active_atoms = self._getActiveAtomsFromDistance() #print "found %i atoms which should be active" % (len(active_atoms)) self._active_atoms = active_atoms[:] atoms = self._active_atoms[:] frags = self._fragmentation.getFragments() fragment_layers = self._fragment_layers[:] if self._central_fragment == 0: self._active_frags = [] return if len(self._active_atoms) > 0: #print "extending region A to include all atoms of close fragments" active_frags = [] #self._active_fragments[:] active_frags.append(self._central_fragment - 1) # central must also be active for atom in atoms: ifrg = self._getFragmentFromAtom(atom) active_frags.extend([ifrg]) active_frags = Uniqify(active_frags) active_frags = sorted(active_frags) self._active_fragments = active_frags[:] # promote active fragments to layer 2 for active_fragment_id in active_frags: self._fragment_layers[active_fragment_id] = 2 # add active fragment atoms to list of active atoms fragments = self._fragmentation.getFragments() for frag in active_frags: atoms.extend(fragments[frag]) atoms = Uniqify(atoms) atoms = sorted(atoms) #print "active region is now %i atoms large (%i fragments)" % (len(atoms),len(active_frags)) #print atoms if self._freeze_backbone: #print "attempting to find and freeze backbone atoms in the active region" for item in self._fragmentation.getBackboneAtoms(): if item in atoms: atoms.remove(item) continue #print "active region is now %i atoms large (%i fragments)" % (len(atoms),len(active_frags)) #print atoms atoms = Uniqify(atoms) atoms = sorted(atoms) self._active_atoms = atoms[:]
def pop_qm_fragment(self): """ Remove the qm fragments from the fragmentation. Adds hydrogens to both the qm-fragment that is returned and to the neighbouring fragments if bonds were cut. """ # at this point, fragments have been generated fragments = self._fragmentation.getFragments() # investigate which fragments should be included in the QM-region qmfrags = self._qmfrags[:] distance = self._fragmentation.getActiveAtomsDistance() qmfrags = Uniqify(self._add_fragments_to_QM(qmfrags)) qmfrags.sort() qmfrags.reverse() qm_region_charge = 0 fragments_for_qm_no_hydrogens = [] # instead of removing the qm-fragment, we rather adopt a quite novel approach # in which we signal to the user of the API that the fragment is not to be used # further by setting its original atom numbers to -1 for idx in qmfrags: qm_region_charge += self._qm_charges[idx] old_fragment = fragments.pop(idx) fragments.insert(idx, [-1 for i in old_fragment]) fragments_for_qm_no_hydrogens.insert(0,old_fragment[:]) # for simplicity, let us just squash the qm fragments into one big fragment fragments_for_qm_no_hydrogens = ravel2D(fragments_for_qm_no_hydrogens) breaks = self._fragmentation.getExplicitlyBreakAtomPairs() if len(breaks) == 0: return (fragments_for_qm_no_hydrogens, qm_region_charge) # below here: add hydrogens to qm-fragment and to the rest of the capped structure fragment_for_qm = fragments_for_qm_no_hydrogens[:] # first, fix the QM-fragment, removing any bond-breaks that reside # inside (or bordering) the qm-fragment. if breaks are bordering, # add appropriate hydrogen atoms. lenqmfrags = len(fragments_for_qm_no_hydrogens) remove_breaks = [] for ibreak, bbreak in enumerate(breaks): lendiff = len(listDiff(fragments_for_qm_no_hydrogens, list(bbreak))) difflen = lenqmfrags - lendiff # the break is not present in the qm-region, leave it if difflen == 0: continue # mark the ibreak'th item for removal. no hydrogens to be added if difflen == 2: remove_breaks.append(ibreak) # the break is bordering the qm-region and the mm-region if difflen == 1: for iibreak in bbreak: # fix the qm-fragment first if iibreak in fragments_for_qm_no_hydrogens: new_atoms = self.satisfyValency(fragments_for_qm_no_hydrogens, iibreak, bbreak) if len(new_atoms) > 0: print("Info: FragIt adds", len(new_atoms), "atom(s) to the QM fragment.") self._fragmentation._atom_names.extend([' H '] * len(new_atoms)) fragment_for_qm.extend(new_atoms) # then fix the fragments themselves # INFO/WARNING: this is a lists of lists thing. BE CAREFULL for ifragment, fragment in enumerate(fragments): if iibreak in fragment: new_atoms = self.satisfyValency(fragment, iibreak, bbreak) print("Info: FragIt adds", len(new_atoms), "atom(s) to MM fragment", ifragment+1) self._fragmentation._atom_names.extend([' H '] * len(new_atoms)) fragments[ifragment].extend(new_atoms) # also mark the ibreak'th item for removal remove_breaks.append(ibreak) for ibreak in remove_breaks: self._fragmentation.popExplicitlyBreakAtomPairs(breaks[ibreak]) #print("FRAGIT: [qm] {0}".format(fragment_for_qm)) return (fragment_for_qm, qm_region_charge)
def _getBasisAtoms(self, ilayer): atom_numbers = Uniqify([atom.GetAtomicNum() for atom in self._fragmentation.getAtoms()]) atom_numbers.sort() atoms = [self._elements.GetSymbol(atom_number) for atom_number in atom_numbers] return "".join([self._formatSingleAtomBasis(ilayer,atom) for atom in atoms])