def do_molgrid(self): self.molgrid = Grid.from_prefix("molecule", self.work) if self.molgrid is not None: self.molgrid.weights = self.molgrid.load("weights") else: # we have to generate a new grid. The grid is constructed taking # into account the following considerations: # 1) Grid points within the cusp region are discarded # 2) The rest of the molecular and surrounding volume is sampled # with spherical grids centered on the atoms. Around each atom, # 'scale_steps' of shells are placed with lebedev grid points # (num_lebedev). The lebedev weights are used in the fit to # avoid preferential directions within one shell. # 3) The radii of the shells start from scale_min*(cusp_radius+0.2) # and go up to scale_max*(cusp_radius+0.2). # 4) Each shell will be randomly rotated around the atom to avoid # global preferential directions in the grid. # 5) The default parameters for the grid should be sufficient for # sane ESP fitting. The ESP cost function should discard points # with a density larger than a threshold, i.e. 1e-5 a.u. A # gradual transition between included and discarded points around # this threshold will improve the quality of the fit. lebedev_xyz, lebedev_weights = get_lebedev_grid(50) self.do_noble_radii() scale_min = 1.5 scale_max = 30.0 scale_steps = 30 scale_factor = (scale_max/scale_min)**(1.0/(scale_steps-1)) scales = scale_min*scale_factor**numpy.arange(scale_steps) points = [] weights = [] pb = log.pb("Constructing molecular grid", scale_steps) for scale in scales: pb() radii = scale*self.noble_radii for i in xrange(self.molecule.size): rot = Rotation.random() for j in xrange(len(lebedev_xyz)): my_point = radii[i]*numpy.dot(rot.r, lebedev_xyz[j]) + self.molecule.coordinates[i] distances = numpy.sqrt(((self.molecule.coordinates - my_point)**2).sum(axis=1)) if (distances < scales[0]*self.noble_radii).any(): continue points.append(my_point) weights.append(lebedev_weights[j]) pb() points = numpy.array(points) weights = numpy.array(weights) self.molgrid = Grid("molecule", self.work, points) self.molgrid.weights = weights self.molgrid.dump("weights", weights)
def __init__(self, num_lebedev, do_random=True): self.num_lebedev = num_lebedev self.do_random = do_random self.lebedev_xyz, self.lebedev_weights = get_lebedev_grid(num_lebedev)