Beispiel #1
0
    def select_atoms(self, atoms):
        subset = None
        subset_map = {}
        subset_weights = []
        k = 0
        ids = Mixer.get_atom_ids(atoms)
        for i in range(len(atoms)):
            if ids[i] not in self._atom_ids:
                continue

            if not subset:
                subset = Atoms(atoms[i:i+1])
            else:
                subset.extend(atoms[i:i+1])

            subset_map[k] = i
            subset_weights.append(self._weights[ids[i]])
            k += 1
        wa = np.zeros((len(subset_weights), 3))
        for i in range(len(subset_weights)):
            wa[i] += subset_weights[i]
        return subset, subset_map, wa
Beispiel #2
0
    def select_atoms(self, atoms):
        subset = None
        subset_map = {}
        subset_weights = []
        k = 0
        ids = Mixer.get_atom_ids(atoms)
        for i in range(len(atoms)):
            if ids[i] not in self._atom_ids:
                continue

            if not subset:
                subset = Atoms(atoms[i:i + 1])
            else:
                subset.extend(atoms[i:i + 1])

            subset_map[k] = i
            subset_weights.append(self._weights[ids[i]])
            k += 1
        wa = np.zeros((len(subset_weights), 3))
        for i in range(len(subset_weights)):
            wa[i] += subset_weights[i]
        return subset, subset_map, wa
Beispiel #3
0
    def select_atoms(self, atoms):
        """
        Return an Atoms object containing only those from atoms that
        are within the CalcRegion and that don't have an interaction-
        chain to an atom outside the CalcRegion. This interaction-chain
        is a chain of atoms within cutoff distance from each other.

        @type atoms:        Atoms
        @param atoms:       the normal ASE Atoms object

        @rtype:             (Atoms, dict, list)
        @return:            Atoms provides an ASE Atoms object with the
                            selected atoms. Dict contains a map, where map[i]
                            gives the original index of Atoms[i]. List provides
                            force calculation weights for each atom in Atoms.
        """
        subset = None
        subset_map = {}
        weights = []
        cutoff2 = self._cutoff**2 # use square for comparison with length2()
        
        p, d = self.get_bounding_box() # get the rectangular bounding box

        # create Octree with atoms inside or within cutoff distance from
        # CalcRegion
        root = OctreeNode(pos=p,
                dim=(d[0] + 2*self._cutoff,
                     d[1] + 2*self._cutoff,
                     d[2] + 2*self._cutoff),
                res=max(self._cutoff/2.0, 0.1))

        atom_ids = Mixer.get_atom_ids(atoms) # extract atomids from atoms
        rev_map = {} # reverse map used to get from atom_ids to atoms[] indexes
        
        for i in range(len(atoms)):
            root.add_object(atom_ids[i], atoms[i].position)
            rev_map[atom_ids[i]] = i
        
        black_list = {} # blacklist of atoms with interaction-chain to outside
        for k in root.get_objects():
            black_list[k] = False

        wrk = [] # stack for holding blacklisted atoms whose neighbours
                 # need to be checked 

        # populate wrk with those atoms outside CalcRegion that are still
        # within cutoff distance from it
        for atom_id in root.get_objects():
            if self.atom_inside(atoms[rev_map[atom_id]].position):
                continue
            wrk.append(atom_id)
            black_list[atom_id] = True

        # loop until wrk is empty, any not-blacklisted neighbours within
        # cutoff distance from atoms that are blacklisted will be blacklisted
        # and pushed to wrk
        while len(wrk) > 0:
            atom_id = wrk.pop()
            
            # find neighbours approximately within cutoff
            ns = root.find_objects(atoms[rev_map[atom_id]].position,
                                     self._cutoff)
            for n in ns:
                if black_list[n]: # already blacklisted, ignore
                    continue
                if (self.length2(atoms[rev_map[n]].position,
                    atoms[rev_map[atom_id]].position) > cutoff2):
                    # outside cutoff distance, ignore
                    continue
                # not blacklisted, within cutoff, add to wrk
                # and blacklist
                wrk.append(n)
                black_list[n] = True

        k = 0
        subset = Atoms()
        # construct cleaned up subset of atoms within the CalcRegion
        for atom_id in root.get_objects():
            if black_list[atom_id]: # exclude blacklisted atom
                if self._debug > 2:
                    print("excluding atom: %i" % atom_id)
                continue
            subset.extend(atoms[rev_map[atom_id]:rev_map[atom_id]+1])
            weights.append(
                    self.get_weight(atoms[rev_map[atom_id]].position))
            subset_map[k] = rev_map[atom_id]
            k += 1

        # create weights array that matches subset
        wa = np.zeros((len(weights), 3))
        for i in range(len(weights)):
            wa[i] += weights[i]
        
        # set periodic boundary condition
        if self._pbc:
            subset.set_pbc(self._pbc)

        # dump CalcRegion contents to a trajectory file if debugging
        if self._debug_file != None:
            ase.io.pdb.write_pdb(self._debug_file, subset)

        return subset, subset_map, wa
Beispiel #4
0
    def select_atoms(self, atoms):
        """
        Return an Atoms object containing only those from atoms that
        are within the CalcRegion and that don't have an interaction-
        chain to an atom outside the CalcRegion. This interaction-chain
        is a chain of atoms within cutoff distance from each other.

        @type atoms:        Atoms
        @param atoms:       the normal ASE Atoms object

        @rtype:             (Atoms, dict, list)
        @return:            Atoms provides an ASE Atoms object with the
                            selected atoms. Dict contains a map, where map[i]
                            gives the original index of Atoms[i]. List provides
                            force calculation weights for each atom in Atoms.
        """
        subset = None
        subset_map = {}
        weights = []
        cutoff2 = self._cutoff**2  # use square for comparison with length2()

        p, d = self.get_bounding_box()  # get the rectangular bounding box

        # create Octree with atoms inside or within cutoff distance from
        # CalcRegion
        root = OctreeNode(pos=p,
                          dim=(d[0] + 2 * self._cutoff,
                               d[1] + 2 * self._cutoff,
                               d[2] + 2 * self._cutoff),
                          res=max(self._cutoff / 2.0, 0.1))

        atom_ids = Mixer.get_atom_ids(atoms)  # extract atomids from atoms
        rev_map = {
        }  # reverse map used to get from atom_ids to atoms[] indexes

        for i in range(len(atoms)):
            root.add_object(atom_ids[i], atoms[i].position)
            rev_map[atom_ids[i]] = i

        black_list = {}  # blacklist of atoms with interaction-chain to outside
        for k in root.get_objects():
            black_list[k] = False

        wrk = []  # stack for holding blacklisted atoms whose neighbours
        # need to be checked

        # populate wrk with those atoms outside CalcRegion that are still
        # within cutoff distance from it
        for atom_id in root.get_objects():
            if self.atom_inside(atoms[rev_map[atom_id]].position):
                continue
            wrk.append(atom_id)
            black_list[atom_id] = True

        # loop until wrk is empty, any not-blacklisted neighbours within
        # cutoff distance from atoms that are blacklisted will be blacklisted
        # and pushed to wrk
        while len(wrk) > 0:
            atom_id = wrk.pop()

            # find neighbours approximately within cutoff
            ns = root.find_objects(atoms[rev_map[atom_id]].position,
                                   self._cutoff)
            for n in ns:
                if black_list[n]:  # already blacklisted, ignore
                    continue
                if (self.length2(atoms[rev_map[n]].position,
                                 atoms[rev_map[atom_id]].position) > cutoff2):
                    # outside cutoff distance, ignore
                    continue
                # not blacklisted, within cutoff, add to wrk
                # and blacklist
                wrk.append(n)
                black_list[n] = True

        k = 0
        subset = Atoms()
        # construct cleaned up subset of atoms within the CalcRegion
        for atom_id in root.get_objects():
            if black_list[atom_id]:  # exclude blacklisted atom
                if self._debug > 2:
                    print("excluding atom: %i" % atom_id)
                continue
            subset.extend(atoms[rev_map[atom_id]:rev_map[atom_id] + 1])
            weights.append(self.get_weight(atoms[rev_map[atom_id]].position))
            subset_map[k] = rev_map[atom_id]
            k += 1

        # create weights array that matches subset
        wa = np.zeros((len(weights), 3))
        for i in range(len(weights)):
            wa[i] += weights[i]

        # set periodic boundary condition
        if self._pbc:
            subset.set_pbc(self._pbc)

        # dump CalcRegion contents to a trajectory file if debugging
        if self._debug_file != None:
            ase.io.pdb.write_pdb(self._debug_file, subset)

        return subset, subset_map, wa