def get_moments_for_scaled_model(map, np_on_grid, grid, nmax, rmax, external_rmax): ### default params for moments calculation ### splat_range = 1 uniform = True fix_dx = False default_dx = 0.7 fraction = 0.9 ### end of default params for moments calculation ### #threshold = flex.max( map )/3.0 threshold = map.standard_deviation_of_the_sample() select = flex.bool(map.as_1d() >= threshold) xyz = grid.select(select) xyz_norms = xyz.norms() select = flex.bool(xyz_norms <= rmax) xyz = xyz.select(select) density = flex.double(xyz.size(), 1.0) vox_obj = math.sphere_voxel(np_on_grid, splat_range, uniform, fix_dx, external_rmax, default_dx, fraction, xyz, density) grid_obj = math.sphere_grid(np_on_grid, nmax) grid_obj.clean_space(vox_obj, False) grid_obj.construct_space_sum() moment_obj = math.zernike_moments(grid_obj, nmax) nlm_array = moment_obj.moments() return nlm_array.coefs()
def build_with_map(self, mapfile): this_xplor = xplor_map.reader(mapfile) self.np_on_grid = (this_xplor.gridding.n[0]-1 ) /2 ## this is the np_on_grid stored in xplor map self.np_on_grid = int(self.np_on_grid) self.raw_map = this_xplor.data self.map = flex.double( this_xplor.data.size(), 0) self.id = mapfile.split('.')[0] this_rmax = this_xplor.unit_cell.parameters()[0]/2.0 if(self.rmax is not None and ( self.rmax != this_rmax ) ): # do the scaling grid=build_3d_grid(self.np_on_grid, this_rmax) self.nlm_coefs = get_moments_for_scaled_model( self.raw_map, self.np_on_grid, grid, self.nmax, this_rmax, self.rmax) self.nlm_array = math.nlm_array(self.nmax) self.nlm_array.load_coefs(self.nlm_array.nlm(), self.nlm_coefs ) else: self.rmax = this_rmax print self.rmax,"test" threshold = flex.max( self.raw_map )/3.0 select = flex.bool( this_xplor.data.as_1d() >= threshold ) self.map.set_selected( select, 1) self.ngp = self.map.size() # number of grid point in 3D box self.all_indx = flex.int(range( self.ngp )) self.molecule = self.all_indx.select( select ) self.grid_obj=math.sphere_grid(self.np_on_grid, self.nmax) ss = self.grid_obj.construct_space_sum_via_list( self.molecule.as_1d(), self.map.as_1d() ) self.moment_obj = math.zernike_moments( self.grid_obj, self.nmax ) self.moment_obj.calc_moments( ss.as_1d() ) self.nlm_array = self.moment_obj.moments() self.nlm_coefs = self.nlm_array.coefs()
def build_starting_model(self): grids = flex.grid([self.np_on_grid * 2 + 1] * 3) self.start_model = flex.double(grids, 0.0) #### BUILD STARTING MODEL ##### self.ngp = self.start_model.size() for ii in self.indx_list: self.start_model[ii] = 1.0 self.molecule = self.indx_list self.raw_map = self.start_model.deep_copy() # a sphere print self.rmax, "RMAX" self.working_model = self.start_model.deep_copy( ) # Make a working model self.best_model = self.start_model.deep_copy() # Make a starting model #### Reusable Objects for moments calculation #### self.grid_obj = math.sphere_grid(self.np_on_grid, self.nmax) self.grid_obj.construct_space_sum_via_list(self.molecule) self.moment_obj = math.zernike_moments(self.grid_obj, self.nmax) moments = self.moment_obj.moments() self.zm = zm.zernike_model(moments, self.data.q, self.rmax, self.nmax) nn = self.moment_obj.fnn() self.calc_i = self.zm.calc_intensity(nn) self.calc_i = self.calc_i / self.calc_i[0] self.start_i = self.calc_i.deep_copy() self.start_nlm_coefs = moments.coefs().deep_copy() self.best_nlm_coefs = self.start_nlm_coefs.deep_copy() self.start_score = ((self.calc_i - self.data.i) / self.data.s).norm() out = open(self.prefix + 'start.iq', 'w') for qq, ic, io in zip(self.data.q, self.calc_i * self.scale_2_expt, self.data.i * self.scale_2_expt): print >> out, qq, ic, io out.close() self.nlm_array.load_coefs(self.nlm, self.start_nlm_coefs) self.start_m, self.start_s = get_mean_sigma(self.nlm_array) if (self.pdb_nlm is not None): self.pdb_m, self.pdb_s = get_mean_sigma(self.pdb_nlm) align_obj = fft_align.align(self.pdb_nlm, self.nlm_array, nmax=self.nmax, refine=True) cc = align_obj.best_score cc = (cc - self.start_m * self.pdb_m) / (self.start_s * self.pdb_s) print "C.C. (PDB, Start) = %8.5f, Score = %8.5f" % ( cc, self.start_score) xplor_map_type(self.raw_map, self.np_on_grid, self.rmax, file_name=self.prefix + 'start.xplor') print "Fraction: ", flex.sum(self.start_model) / (self.np_on_grid** 3.0) / 8.0
def build_starting_model(self): grids = flex.grid([self.np_on_grid*2+1]*3) self.start_model = flex.double(grids,0.0) #### BUILD STARTING MODEL ##### max_map = flex.max( self.raw_map ) self.molecule = flex.int() self.mod_list_1d = flex.int() self.mod_list = flex.vec3_double() cutoff = self.nmodel/2.0 distance_indx = flex.vec3_double() for ii in range(self.ngp ): if(self.raw_map[ii] >= cutoff): self.start_model[ii]=1.0 self.molecule.append( ii ) ## Need to be moved to mark region distance_indx.append( self.convert_indx_1_3( ii ) ) center_indx = (self.np_on_grid, self.np_on_grid, self.np_on_grid) distance = (distance_indx - center_indx).norms() max_dist = flex.max( distance ) / self.np_on_grid self.rmax = self.rmax*self.fraction/max_dist self.working_model= self.start_model.deep_copy() # Make a working model self.best_model = self.start_model.deep_copy() # Make a starting model #### Reusable Objects for moments calculation #### self.grid_obj=math.sphere_grid(self.np_on_grid, self.nmax) self.grid_obj.construct_space_sum_via_list( self.molecule, self.start_model.as_1d() ) self.moment_obj = math.zernike_moments( self.grid_obj, self.nmax ) moments = self.moment_obj.moments() self.zm = zm.zernike_model( moments, self.data.q, self.rmax, self.nmax) nn = self.moment_obj.fnn() self.calc_i = self.zm.calc_intensity(nn) self.calc_i = self.calc_i / self.calc_i[0] self.start_i = self.calc_i.deep_copy() self.start_nlm_coefs = moments.coefs().deep_copy() self.best_nlm_coefs = self.start_nlm_coefs.deep_copy() self.start_score= ( (self.calc_i-self.data.i)/self.data.s ).norm() out = open(self.prefix+'start.iq', 'w') for qq,ic,io in zip( self.data.q, self.calc_i*self.scale_2_expt, self.data.i*self.scale_2_expt): print>>out, qq, ic, io out.close() self.nlm_array.load_coefs( self.nlm, self.start_nlm_coefs ) self.start_m, self.start_s = get_mean_sigma( self.nlm_array ) if (self.pdb_nlm is not None): self.pdb_m, self.pdb_s = get_mean_sigma( self.pdb_nlm ) align_obj = fft_align.align(self.pdb_nlm, self.nlm_array, nmax=self.nmax, refine=True) cc = align_obj.best_score cc = ( cc - self.start_m*self.pdb_m ) / ( self.start_s*self.pdb_s ) print "C.C. (PDB, Start) = %8.5f, Score = %8.5f"%(cc, self.start_score) xplor_map_type( self.raw_map, self.np_on_grid, self.rmax, file_name=self.prefix+'start.xplor') print "Fraction: ", flex.sum(self.start_model)/(self.np_on_grid**3.0)/8.0
def tst_moments(nmax,np): grid_obj = tst_grid(nmax,np) mom_obj = math.zernike_moments(grid_obj, nmax) moments = mom_obj.moments() Fnl= mom_obj.fnl() Fnn= mom_obj.fnn() Fnnl= mom_obj.fnnl() eps = 1e-8 #print list(Fnl.coefs()) check_nl = [2.3370760050376607e-05, 2.1910087547227873e-07, 1.1145167882067956e-05, 1.1552795255443502e-05, 1.8332528001413832e-07, 2.7291537694166531e-07, 7.2474025554586763e-06, 2.3917327527551719e-05, 4.2203807328102694e-05] for i_pre, i_cal in zip( check_nl, Fnl.coefs()): assert abs(i_pre-i_cal) < eps check_nn = [1.1685380025188304e-05, 1.0955043773613935e-07, 1.6139115350383189e-05, 1.134898156875573e-05, 1.7412731546555787e-08, 2.2812032847790184e-07, 1.3014503682895901e-05, -4.7928189112959946e-06, 3.668426870555654e-05] for i_pre, i_cal in zip( check_nn, Fnn.coefs()): assert abs(i_pre-i_cal) < eps check_nnl=[(1.1685380025188304e-05+0j), 0j, 0j, (1.0955043773613935e-07+0j), (-1.6139115350383189e-05+0j), 0j, 0j, (5.5725839410339778e-06+0j), 0j, (5.7763976277217503e-06+0j), 0j, 0j, (-1.7412731546555787e-08+0j), 0j, 0j, 0j, 0j, (9.1662640007069148e-08+0j), 0j, (1.3645768847083266e-07+0j), (1.3014503682895901e-05+0j), 0j, 0j, (-8.9874088696083742e-06+0j), 0j, (1.3780227780904368e-05+0j), 0j, 0j, 0j, 0j, (3.6237012777293381e-06+0j), 0j, (1.1958663763775861e-05+0j), 0j, (2.1101903664051344e-05+0j)] for i_pre, i_cal in zip( check_nnl, Fnnl.coefs()): assert abs(i_pre-i_cal) < eps mom_0_0_0 = (0.00483433139642-0j) mom_1_1_0 = (0.000270247340704-0j) mom_1_1_1 = (-0.000191093727209+0.000191093727209j) mom_2_0_0 = (-0.00333843794042-0j) mom_2_2_1 = (-1.26396619825e-05+1.26396619825e-05j) mom_4_2_0 = (-0.00371195771764-0j) mom_4_4_0 = (0.00317650549416-0j) assert abs( moments.get_coef(0,0,0) - mom_0_0_0 ) < eps assert abs( moments.get_coef(1,1,0) - mom_1_1_0 ) < eps assert abs( moments.get_coef(1,1,1) - mom_1_1_1 ) < eps assert abs( moments.get_coef(2,0,0) - mom_2_0_0 ) < eps assert abs( moments.get_coef(2,2,1) - mom_2_2_1 ) < eps assert abs( moments.get_coef(4,2,0) - mom_4_2_0 ) < eps assert abs( moments.get_coef(4,4,0) - mom_4_4_0 ) < eps # do some alignment please from scitbx.math import zernike_align_fft as zafft fixed = mom_obj.moments() moving = mom_obj.moments() al_obj = zafft.align( fixed, moving) assert abs(al_obj.get_cc()-1) < 1e-3 return True
def build_starting_model(self): grids = flex.grid([self.np_on_grid*2+1]*3) self.start_model = flex.double(grids,0.0) #### BUILD STARTING MODEL ##### self.ngp = self.start_model.size() for ii in self.indx_list: self.start_model[ii]=1.0 self.molecule = self.indx_list self.raw_map = self.start_model.deep_copy() # a sphere print self.rmax #### Reusable Objects for moments calculation #### self.grid_obj=math.sphere_grid(self.np_on_grid, self.nmax) self.grid_obj.construct_space_sum_via_list( self.molecule ) #, self.start_model.as_1d() ) self.moment_obj = math.zernike_moments( self.grid_obj, self.nmax ) self.moments = self.moment_obj.moments() self.blq_calculator = fxs_tools.znk_blq(self.moments,self.data.q,self.rmax,self.nmax,self.lmax) self.calc_blq = self.blq_calculator.get_all_blq2() print self.calc_blq[0], "self.calc_blq[0]" self.calc_blq = self.calc_blq / self.calc_blq[0] # normalized to b00 (largest, probably) self.start_blq = self.calc_blq.deep_copy() self.start_nlm_coefs = self.moments.coefs().deep_copy() self.best_nlm_coefs = self.start_nlm_coefs.deep_copy() self.sigma = flex.sqrt( flex.abs(self.data.blq) + 1e-10) #self.sigma=self.data.blq+1e-10 self.start_score= ( (self.calc_blq-self.data.blq)/self.sigma).norm() print "---- Starting Score ---- %f"%self.start_score self.nlm_array.load_coefs( self.nlm, self.start_nlm_coefs ) self.start_m, self.start_s = get_mean_sigma( self.nlm_array ) if (self.pdb_nlm is not None): self.pdb_m, self.pdb_s = get_mean_sigma( self.pdb_nlm ) align_obj = fft_align.align(self.pdb_nlm, self.nlm_array, nmax=self.nmax, refine=True) cc = align_obj.best_score cc = ( cc - self.start_m*self.pdb_m ) / ( self.start_s*self.pdb_s ) print "C.C. (PDB, Start) = %8.5f, Score = %8.5f"%(cc, self.start_score) xplor_map_type( self.raw_map, self.np_on_grid, self.rmax, file_name=self.prefix+'start.xplor') print "Fraction: ", flex.sum(self.start_model)/(self.np_on_grid**3.0)/8.0
def zernike_moments(pdbfile, nmax=20, np=50, fix_dx=False, np_on_grid=20, shift=False, buildmap=False, coef_out=True, calc_intensity=True, external_rmax=-1): base = pdbfile.split('.')[0] splat_range = 0 fraction = 0.9 default_dx = 0.7 uniform = True pdbi = pdb.hierarchy.input(file_name=pdbfile) # pdbi = iotbx.pdb.hierarchy.input(pdb_string='''ATOM 1 N ASP A 37 10.710 14.456 9.568 1.00 15.78 N''') if (len(pdbi.hierarchy.models()) == 0): return None, None, None atoms = pdbi.hierarchy.models()[0].atoms() # predefine some arrays we will need atom_types = flex.std_string() radius = flex.double() b_values = flex.double() occs = flex.double() # xyz = flex.vec3_double() xyz = get_xyz_using_split(pdbfile) # keep track of the atom types we have encountered # for atom in atoms: # print"---==================atom=================---",atom.xyz # if(not atom.hetero): # xyz.append( atom.xyz ) # b_values.append( atom.b ) # occs.append( atom.occ ) #print time.time() if (xyz.size() == 0): return None, None, None density = flex.double(xyz.size(), 1.0) voxel_obj = math.sphere_voxel(np, splat_range, uniform, fix_dx, external_rmax, default_dx, fraction, xyz, density) np = voxel_obj.np() # print "*********************voxel_obj.rmax(): ",voxel_obj.rmax() rmax = voxel_obj.rmax() / fraction # print "*********************fraction: ",fraction # print "*********************rmax=voxel_obj.rmax()/fraction: ",rmax #print base, "RMAX: ", voxel_obj.rmax() #print time.time() grid_obj = math.sphere_grid(np, nmax) pdb_out = False grid_obj.clean_space(voxel_obj, pdb_out) #print time.time(), "END GRID CONST" grid_obj.construct_space_sum() #print time.time(), "SS CALC" mom_obj = math.zernike_moments(grid_obj, nmax) #print time.time(), "END MOM CALC" moments = mom_obj.moments() if (coef_out): nn = mom_obj.fnn() easy_pickle.dump(base + '.nlm.pickle', moments.coefs()) easy_pickle.dump(base + '.nn.pickle', nn.coefs()) # ####### The following will be optional ### if (shift): shift = [rmax, rmax, rmax] centered_xyz = voxel_obj.xyz() + shift out_pdb_name = base + '_centered.pdb' for a, xyz in zip(atoms, centered_xyz): a.set_xyz(new_xyz=xyz) pdbi.hierarchy.write_pdb_file(file_name=out_pdb_name, open_append=False) original_map = voxel_obj.map() xplor_map_type(original_map, np, rmax, file_name=base + '_pdb.xplor') ######## Calculate Intnesity Profile ############ if (calc_intensity): q_array = flex.double(range(51)) / 100.0 z_model = zm.zernike_model(moments, q_array, rmax, nmax) nn = mom_obj.fnn() intensity = z_model.calc_intensity(nn) #iq_file = open(base+"_"+str(nmax)+"_"+str(int(rmax*fraction))+".zi", 'w') iq_file = open(base + "_" + str(nmax) + ".zi", 'w') for qq, ii in zip(q_array, intensity): print >> iq_file, qq, ii iq_file.close() ####### END of Intensity Calculation ########### if (buildmap): print("grid setting up...") zga = math.zernike_grid(np_on_grid, nmax, False) print("grid setting up...Done") zga.load_coefs(moments.nlm(), moments.coefs()) print("start reconstruction") map = flex.abs(zga.f()) print("finished reconstruction") xplor_map_type(map, np_on_grid, rmax, file_name=base + '.xplor') ccp4_map_type(map, np_on_grid, rmax, file_name=base + '.ccp4') return mom_obj, voxel_obj, pdbi
def zernike_moments(mol2_file, nmax=20, np=50, uniform=True, fix_dx=False, np_on_grid=20, shift=False, buildmap=False, coef_out=True, calc_intensity=True, external_rmax=-1): base = mol2_file.split('.')[0] splat_range = 0 fraction = 0.9 default_dx = 0.5 models = mol2.read_Mol2_file( mol2_file ) if(len( models )== 0): return None,None,None ## for testing purpose, here only the first model in the mol2 file is converted ## this_molecule = models[0] ## models should be a list of molecules, same ligand at different conformations ## all_atoms = this_molecule.atom_list if(len( all_atoms )== 0): return None,None,None # predefine some arrays we will need xyz = flex.vec3_double() charges = flex.double() # keep track of the atom types we have encountered for atom in all_atoms: xyz.append( ( atom.X, atom.Y, atom.Z ) ) charges.append( atom.Q ) if(xyz.size() == 0): return None,None,None if (uniform): density=flex.double(xyz.size(),1.0) else: # use charges density=charges voxel_obj = math.sphere_voxel(np,splat_range,uniform,fix_dx,external_rmax, default_dx, fraction,xyz,density) np = voxel_obj.np() rmax=voxel_obj.rmax()/fraction #print base, "RMAX: ", voxel_obj.rmax() #print time.time() grid_obj = math.sphere_grid(np, nmax) pdb_out = False grid_obj.clean_space(voxel_obj, pdb_out) #print time.time(), "END GRID CONST" grid_obj.construct_space_sum() #print time.time(), "SS CALC" mom_obj = math.zernike_moments(grid_obj, nmax) #print time.time(), "END MOM CALC" moments = mom_obj.moments() if(coef_out): nn = mom_obj.fnn() easy_pickle.dump(base+'.nlm.pickle', moments.coefs() ) easy_pickle.dump(base+'.nn.pickle', nn.coefs() ) # ####### The following will be optional ### if(shift): shift = [rmax, rmax, rmax] centered_xyz = voxel_obj.xyz() + shift out_mol2_filename =base+'_centered.mol2' for a,xyz in zip( all_atoms, centered_xyz): a.X = xyz[0] a.Y = xyz[1] a.Z = xyz[2] mol2.write_mol2( this_molecule, out_mol2_filename ) original_map = voxel_obj.map() xplor_map_type( original_map, np, rmax, file_name=base+'_pdb.xplor') ######## Calculate Intnesity Profile ############ if(calc_intensity): q_array = flex.double( range(51) )/100.0 z_model = zm.zernike_model( moments, q_array, rmax, nmax) nn = mom_obj.fnn() intensity = z_model.calc_intensity(nn) #iq_file = open(base+"_"+str(nmax)+"_"+str(int(rmax*fraction))+".zi", 'w') iq_file = open(base+"_"+str(nmax)+".zi", 'w') for qq, ii in zip(q_array, intensity): print>>iq_file, qq,ii iq_file.close() ####### END of Intensity Calculation ########### if(buildmap): print "grid setting up..." zga = math.zernike_grid(np_on_grid, nmax, False) print "grid setting up...Done" zga.load_coefs(moments.nlm(), moments.coefs() ) print "start reconstruction" map=flex.abs(zga.f() ) print "finished reconstruction" xplor_map_type( map, np_on_grid, rmax, file_name=base+'.xplor') ccp4_map_type( map, np_on_grid, rmax, file_name=base+'.ccp4' ) return mom_obj, voxel_obj, models
def calc_mom(self, np, splat_range, uniform, fix_dx, default_dx, fraction, pdb_out=False): if (self.xyz.size() == 0): print "no atom found, double check the model" return self.voxel_obj = math.sphere_voxel(np, splat_range + self.layer_thick, uniform, fix_dx, self.external_rmax, default_dx, fraction, self.xyz, self.density) self.volume_unit = self.default_dx**3.0 self.total_volume = self.voxel_obj.occupied_sites() * self.volume_unit np = self.voxel_obj.np() self.rmax = self.voxel_obj.rmax() / fraction dx_used = self.rmax / np new_layer_thick = int(self.rmax * (1 - fraction) / dx_used) - 1 if (new_layer_thick < self.layer_thick): print "solvent layer extended too much, and thickness is reset to ", new_layer_thick self.layer_thick = new_layer_thick self.grid_obj = math.sphere_grid(np, self.nmax) ## displaced solvent ## border_list = self.voxel_obj.border(self.layer_thick - 1) ## only inner section left now inner_sites = self.voxel_obj.occupied_sites() self.grid_obj.clean_space(self.voxel_obj, pdb_out) self.grid_obj.construct_space_sum() self.mom_obj_s = math.zernike_moments(self.grid_obj, self.nmax) self.zernike_mom_s = self.mom_obj_s.moments() ## protein ## self.voxel_obj = math.sphere_voxel(np, splat_range, uniform, fix_dx, self.external_rmax, default_dx, fraction, self.xyz, self.density) real_inner_sites = self.voxel_obj.occupied_sites() self.grid_obj.clean_space(self.voxel_obj, pdb_out) ## output protein self.grid_obj.construct_space_sum() self.mom_obj_p = math.zernike_moments(self.grid_obj, self.nmax) self.zernike_mom_p = self.mom_obj_p.moments() ## border layer ## self.inner_volume = inner_sites * self.volume_unit self.grid_obj.construct_space_sum_via_list(border_list) self.mom_obj_b = math.zernike_moments(self.grid_obj, self.nmax) self.zernike_mom_b = self.mom_obj_b.moments() ## scale the densities ## self.density_scale = self.voxel_obj.weight_sum() print self.density_scale #self.density_scale=float(real_inner_sites)/inner_sites self.sol_layer = self.sol_layer / self.density_scale #self.solvent = self.solvent*self.density_scale ##self.protein=self.protein*(1.0+0.1*smath.exp(-inner_sites/134000.0) ) ### adding moment vectors ## self.zernike_mom_coef = self.zernike_mom_p.coefs( ) * self.protein #-self.solvent) self.zernike_mom_coef -= self.zernike_mom_s.coefs() * self.solvent self.zernike_mom_coef += self.zernike_mom_b.coefs() * self.sol_layer self.nlm = self.zernike_mom.nlm() self.zernike_mom.load_coefs(self.nlm, self.zernike_mom_coef) return
def initialize_reusable_objects(self): #### Reusable Objects for moments calculation #### self.grid_obj = math.sphere_grid(self.np_on_grid, self.nmax) self.moment_obj = math.zernike_moments(self.grid_obj, self.nmax) moments = self.moment_obj.moments() self.zm = zm.zernike_model(moments, self.data.q, self.rmax, self.nmax)