Esempio n. 1
0
 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
Esempio n. 2
0
 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