def _analyze(self): """Guesses the mmtypes, bonds and pointgroup""" dummies = ase.Atoms([x for x in self.atoms if x.symbol == "X"]) if len(dummies) > 0: pg = symmetry.PointGroup(mol=dummies.copy(), tol=0.1) max_order = min(8, len(dummies)) shape = symmetry.get_symmetry_elements(mol=dummies.copy(), max_order=max_order) self.shape = shape self.pg = pg.schoenflies bonds, mmtypes = analyze_mm(self.get_atoms()) self.bonds = bonds self.mmtypes = mmtypes return None
def _analyze(self): """Analyze the topology to cut the fragments out.""" # separate the dummies from the rest logger.debug("Analyzing fragments of topology {0}.".format(self.name)) numbers = numpy.asarray(self.atoms.get_atomic_numbers()) Xis = numpy.where(numbers == 0)[0] Ais = numpy.where(numbers > 0)[0] # setup the tags tags = numpy.zeros(len(self.atoms)) tags[Xis] = Xis + 1 self.atoms.set_tags(tags) tags = self.atoms.get_tags() # analyze # first build the neighborlist cutoffs = self._get_cutoffs(Xis=Xis, Ais=Ais) neighborlist = NeighborList(cutoffs=cutoffs, bothways=True, self_interaction=False, skin=0.0) neighborlist.update(self.atoms) # iterate over non-dummies to find dummy neighbors for ai in Ais: # get indices and offsets of dummies only! ni, no = neighborlist.get_neighbors(ai) ni, no = zip(*[(idx, off) for idx, off in list(zip(ni, no)) if idx in Xis]) ni = numpy.asarray(ni) no = numpy.asarray(no) # get absolute positions, no offsets positions = self.atoms.positions[ni] + no.dot(self.atoms.cell) # create the Atoms object fragment = Atoms("X" * len(ni), positions, tags=tags[ni]) # calculate the point group properties max_order = min(8, len(ni)) shape = symmetry.get_symmetry_elements(mol=fragment.copy(), max_order=max_order) pg = symmetry.PointGroup(mol=fragment.copy(), tol=0.1) # save that info self.fragments[ai] = fragment self.shapes[ai] = shape self.pointgroups[ai] = pg.schoenflies # now getting the equivalent sites using the Spacegroup object sg = self.atoms.info["spacegroup"] if not isinstance(sg, Spacegroup): sg = Spacegroup(sg) scaled_positions = self.atoms.get_scaled_positions() seen_indices = [] symbols = numpy.array(self.atoms.get_chemical_symbols()) for ai in Ais: if ai in seen_indices: continue sites, _ = sg.equivalent_sites(scaled_positions[ai]) these_indices = [] for site in sites: norms = numpy.linalg.norm(scaled_positions - site, axis=1) if norms.min() < 1e-6: these_indices.append(norms.argmin()) # take pbc into account norms = numpy.abs(norms - 1.0) if norms.min() < 1e-6: these_indices.append(norms.argmin()) these_indices = [idx for idx in these_indices if idx in Ais] seen_indices += these_indices self.equivalent_sites.append(these_indices) logger.info("{es} equivalent sites kinds.".format( es=len(self.equivalent_sites))) return None