def write_map(self, file_name=None, # Name of file to be written verbose=None, ): ''' Simple version of write file_name is output file name map_data is map_data object with 3D values for map. If not supplied, use self.map_data() Normally call with file_name (file to be written) Output labels are generated from existing self.labels, self.program_name, and self.limitations ''' if not file_name: raise Sorry("Need file_name for write_map") if not self.map_data(): raise Sorry("Need map_data for write_map") map_data=self.map_data() from iotbx.mrcfile import create_output_labels labels=create_output_labels( program_name=self.program_name, input_file_name=self.input_file_name, input_labels=self.labels, limitations=self.limitations) crystal_symmetry=self.unit_cell_crystal_symmetry() unit_cell_grid=self.unit_cell_grid origin_shift_grid_units=self.origin_shift_grid_units if map_data.origin() == (0,0,0): # Usual self._print("Writing map with origin at %s and size of %s to %s" %( str(origin_shift_grid_units),str(map_data.all()),file_name)) write_ccp4_map( file_name = file_name, crystal_symmetry = crystal_symmetry, # unit cell and space group map_data = map_data, unit_cell_grid=unit_cell_grid, # optional gridding of full unit cell origin_shift_grid_units=origin_shift_grid_units, # optional origin shift labels = labels, verbose=verbose) else: # map_data has not been shifted to (0,0,0). Shift it and then write self._print("Writing map after shifting origin") if self.origin_shift_grid_units and origin_shift_grid_units!=(0,0,0): self._print ( "WARNING: map_data has origin at %s " %(str(map_data.origin())), " and this map_manager will apply additional origin shift of %s " %( str(self.origin_shift_grid_units))) new_mm=self.deep_copy() new_mm.set_log(self.log) new_mm.shift_origin() new_mm.write_map(file_name=file_name)
def run(args, crystal_symmetry=None, ncs_object=None, pdb_hierarchy=None, map_data=None, mask_data=None, half_map_data_list=None, half_map_labels_list=None, lower_bounds=None, upper_bounds=None, write_output_files=True, log=None): h = "phenix.map_box: extract box with model and map around selected atoms" if(log is None): log = sys.stdout print_statistics.make_header(h, out=log) default_message="""\ %s. Usage: phenix.map_box model.pdb map_coefficients.mtz selection="chain A and resseq 1:10" or phenix.map_box map.ccp4 density_select=True Parameters:"""%h if(len(args) == 0 and not pdb_hierarchy): print(default_message) master_phil.show(prefix=" ") return # Process inputs ignoring symmetry conflicts just to get the value of # ignore_symmetry_conflicts... inputs = mmtbx.utils.process_command_line_args(args = args, cmd_cs=crystal_symmetry, master_params = master_phil, suppress_symmetry_related_errors=True) params = inputs.params.extract() # Now process inputs for real and write a nice error message if necessary. try: inputs = mmtbx.utils.process_command_line_args(args = args, cmd_cs=crystal_symmetry, master_params = master_phil, suppress_symmetry_related_errors=params.ignore_symmetry_conflicts) except Exception as e: if str(e).find("symmetry mismatch ")>1: raise Sorry(str(e)+"\nTry 'ignore_symmetry_conflicts=True'") else: raise e params = inputs.params.extract() master_phil.format(python_object=params).show(out=log) # Overwrite params with parameters in call if available if lower_bounds: params.lower_bounds=lower_bounds if upper_bounds: params.upper_bounds=upper_bounds # PDB file if params.pdb_file and not inputs.pdb_file_names and not pdb_hierarchy: inputs.pdb_file_names=[params.pdb_file] if(len(inputs.pdb_file_names)!=1 and not params.density_select and not params.mask_select and not pdb_hierarchy and not params.keep_map_size and not params.upper_bounds and not params.extract_unique and not params.bounds_match_this_file): raise Sorry("PDB file is needed unless extract_unique, "+ "density_select, mask_select, keep_map_size \nor bounds are set .") if (len(inputs.pdb_file_names)!=1 and not pdb_hierarchy and \ (params.mask_atoms )): raise Sorry("PDB file is needed for mask_atoms") if params.soft_mask and (not params.resolution) and \ (len(inputs.pdb_file_names)!=1 and not pdb_hierarchy): raise Sorry("Need resolution for soft_mask without PDB file") if ((params.density_select or params.mask_select) and params.keep_map_size): raise Sorry("Cannot set both density_select/mask_select and keep_map_size") if ((params.density_select or params.mask_select) and params.upper_bounds): raise Sorry("Cannot set both density_select/mask_select and bounds") if (params.keep_map_size and params.upper_bounds): raise Sorry("Cannot set both keep_map_size and bounds") if (params.upper_bounds and not params.lower_bounds): raise Sorry("Please set lower_bounds if you set upper_bounds") if (params.extract_unique): if (not params.resolution): raise Sorry("Please set resolution for extract_unique") if (not params.symmetry) and (not params.symmetry_file) and \ (not ncs_object): raise Sorry( "Please supply a symmetry file or symmetry for extract_unique (you "+ "\ncan try symmetry=ALL if you do not know your symmetry or "+ "symmetry=C1 if \nthere is none)") from mmtbx.ncs.ncs import ncs ncs_object=ncs() ncs_object.set_unit_ncs() if params.keep_input_unit_cell_and_grid and ( (params.output_unit_cell_grid is not None ) or (params.output_unit_cell is not None ) ): raise Sorry("If you set keep_input_unit_cell_and_grid then you cannot "+\ "set \noutput_unit_cell_grid or output_unit_cell") if (write_output_files) and ("mtz" in params.output_format) and ( (params.keep_origin) and (not params.keep_map_size)): print("\nNOTE: Skipping write of mtz file as keep_origin=True and \n"+\ "keep_map_size is False\n") params.output_format=remove_element(params.output_format,element='mtz') if (write_output_files) and ("mtz" in params.output_format) and ( (params.extract_unique)): print("\nNOTE: Skipping write of mtz file as extract_unique=True\n") params.output_format=remove_element(params.output_format,element='mtz') if params.output_origin_match_this_file or params.bounds_match_this_file: if params.output_origin_match_this_file: fn=params.output_origin_match_this_file if params.bounds_match_this_file: raise Sorry("Cannot match origin and bounds at same time") else: fn=params.bounds_match_this_file if not params.ccp4_map_file: raise Sorry( "Need to specify your input file with ccp4_map_file=xxx if you use "+ "output_origin_match_this_file=xxxx or bounds_match_this_file=xxxx") af = any_file(fn) if (af.file_type == 'ccp4_map'): origin=af.file_content.data.origin() if params.output_origin_match_this_file: params.output_origin_grid_units=origin print("Origin of (%s,%s,%s) taken from %s" %( origin[0],origin[1],origin[2],fn)) else: all=af.file_content.data.all() params.lower_bounds=origin print("Lower bounds of (%s,%s,%s) taken from %s" %( params.lower_bounds[0],params.lower_bounds[1], params.lower_bounds[2],fn)) params.upper_bounds=list(col(origin)+col(all)-col((1,1,1))) print("upper bounds of (%s,%s,%s) taken from %s" %( params.upper_bounds[0],params.upper_bounds[1], params.upper_bounds[2],fn)) params.bounds_are_absolute=True else: raise Sorry("Unable to interpret %s as map file" %(fn)) if params.output_origin_grid_units is not None and params.keep_origin: params.keep_origin=False print("Setting keep_origin=False as output_origin_grid_units is set") print_statistics.make_sub_header("pdb model", out=log) if len(inputs.pdb_file_names)>0: pdb_inp = iotbx.pdb.input(file_name=inputs.pdb_file_names[0]) pdb_hierarchy = pdb_inp.construct_hierarchy() if pdb_hierarchy: pdb_atoms = pdb_hierarchy.atoms() pdb_atoms.reset_i_seq() else: pdb_hierarchy=None # Map or map coefficients map_coeff = None input_unit_cell_grid=None input_unit_cell=None input_map_labels=None if (not map_data): # read first mtz file if ( (len(inputs.reflection_file_names) > 0) or (params.map_coefficients_file is not None) ): # file in phil takes precedent if (params.map_coefficients_file is not None): if (len(inputs.reflection_file_names) == 0): inputs.reflection_file_names.append(params.map_coefficients_file) else: inputs.reflection_file_names[0] = params.map_coefficients_file map_coeff = reflection_file_utils.extract_miller_array_from_file( file_name = inputs.reflection_file_names[0], label = params.label, type = "complex", log = log) if not crystal_symmetry: crystal_symmetry=map_coeff.crystal_symmetry() fft_map = map_coeff.fft_map(resolution_factor=params.resolution_factor) fft_map.apply_sigma_scaling() map_data = fft_map.real_map_unpadded() map_or_map_coeffs_prefix=os.path.basename( inputs.reflection_file_names[0][:-4]) # or read CCP4 map elif ( (inputs.ccp4_map is not None) or (params.ccp4_map_file is not None) ): if (params.ccp4_map_file is not None): af = any_file(params.ccp4_map_file) if (af.file_type == 'ccp4_map'): inputs.ccp4_map = af.file_content inputs.ccp4_map_file_name = params.ccp4_map_file print_statistics.make_sub_header("CCP4 map", out=log) ccp4_map = inputs.ccp4_map ccp4_map.show_summary(prefix=" ",out=log) if not crystal_symmetry: crystal_symmetry=ccp4_map.crystal_symmetry() map_data = ccp4_map.data #map_data() input_unit_cell_grid=ccp4_map.unit_cell_grid input_unit_cell=ccp4_map.unit_cell_parameters input_map_labels=ccp4_map.get_labels() if inputs.ccp4_map_file_name.endswith(".ccp4"): map_or_map_coeffs_prefix=os.path.basename( inputs.ccp4_map_file_name[:-5]) else: map_or_map_coeffs_prefix=os.path.basename( inputs.ccp4_map_file_name[:-4]) else: # have map_data map_or_map_coeffs_prefix=None if params.half_map_list and (not half_map_data_list): if not params.extract_unique: raise Sorry("Can only use half_map_with extract_unique") print ("Reading half-maps",params.half_map_list) half_map_data_list=[] half_map_labels_list=[] for fn in params.half_map_list: print("Reading half map from %s" %(fn),file=log) af = any_file(fn) print_statistics.make_sub_header("CCP4 map", out=log) h_ccp4_map = af.file_content h_ccp4_map.show_summary(prefix=" ",out=log) h_map_data = h_ccp4_map.data half_map_data_list.append(h_map_data) half_map_labels_list.append(h_ccp4_map.get_labels()) if params.map_scale_factor: print("Applying scale factor of %s to map data on read-in" %( params.map_scale_factor)) map_data=map_data*params.map_scale_factor if params.output_origin_grid_units is not None: origin_to_match=tuple(params.output_origin_grid_units) else: origin_to_match=None if origin_to_match: sc=[] for x,o,a in zip(crystal_symmetry.unit_cell().parameters()[:3], origin_to_match, map_data.all()): sc.append(-x*o/a) shift_cart_for_origin_to_match=tuple(sc) else: origin_to_match=None shift_cart_for_origin_to_match=None if crystal_symmetry and not inputs.crystal_symmetry: inputs.crystal_symmetry=crystal_symmetry # final check that map_data exists if(map_data is None): raise Sorry("Map or map coefficients file is needed.") if len(inputs.pdb_file_names)>0: output_prefix=os.path.basename(inputs.pdb_file_names[0])[:-4] else: output_prefix=map_or_map_coeffs_prefix if not pdb_hierarchy: # get an empty hierarchy from cctbx.array_family import flex pdb_hierarchy=iotbx.pdb.input( source_info='',lines=flex.split_lines('')).construct_hierarchy() xray_structure = pdb_hierarchy.extract_xray_structure( crystal_symmetry=inputs.crystal_symmetry) xray_structure.show_summary(f=log) # if not params.selection: params.selection="all" selection = pdb_hierarchy.atom_selection_cache().selection( string = params.selection) if selection.size(): print_statistics.make_sub_header("atom selection", out=log) print("Selection string: selection='%s'"%params.selection, file=log) print(" selects %d atoms from total %d atoms."%(selection.count(True), selection.size()), file=log) sites_cart_all = xray_structure.sites_cart() sites_cart = sites_cart_all.select(selection) selection = xray_structure.selection_within( radius = params.selection_radius, selection = selection) if not ncs_object: from mmtbx.ncs.ncs import ncs ncs_object=ncs() if params.symmetry_file: ncs_object.read_ncs(params.symmetry_file,log=log) print("Total of %s operators read" %(ncs_object.max_operators()), file=log) if not ncs_object or ncs_object.max_operators()<1: print("No symmetry available", file=log) if ncs_object: n_ops=max(1,ncs_object.max_operators()) else: n_ops=1 # Get sequence if extract_unique is set sequence=None if params.extract_unique or params.mask_select: if params.sequence_file: if n_ops > 1: # get unique part of sequence remove_duplicates=True else: remove_duplicates=False from iotbx.bioinformatics import get_sequences sequence=(" ".join(get_sequences(file_name=params.sequence_file, remove_duplicates=remove_duplicates))) if params.chain_type in ['None',None]: params.chain_type=None if sequence and not params.molecular_mass: # get molecular mass from sequence from iotbx.bioinformatics import text_from_chains_matching_chain_type if params.chain_type in [None,'PROTEIN']: n_protein=len(text_from_chains_matching_chain_type( text=sequence,chain_type='PROTEIN')) else: n_protein=0 if params.chain_type in [None,'RNA']: n_rna=len(text_from_chains_matching_chain_type( text=sequence,chain_type='RNA')) else: n_rna=0 if params.chain_type in [None,'DNA']: n_dna=len(text_from_chains_matching_chain_type( text=sequence,chain_type='DNA')) else: n_dna=0 params.molecular_mass=n_ops*(n_protein*110+(n_rna+n_dna)*330) print("\nEstimate of molecular mass is %.0f " %(params.molecular_mass), file=log) if params.density_select or params.mask_select: print_statistics.make_sub_header( "Extracting box around selected density and writing output files", out=log) else: print_statistics.make_sub_header( "Extracting box around selected atoms and writing output files", out=log) # if params.value_outside_atoms=='mean': print("\nValue outside atoms mask will be set to mean inside mask", file=log) if params.get_half_height_width and params.density_select: print("\nHalf width at half height will be used to id boundaries", file=log) if params.soft_mask and sites_cart_all.size()>0: print("\nSoft mask will be applied to model-based mask", file=log) elif params.soft_mask: print ("\nSoft mask will be applied to outside of map box",file=log) if params.keep_map_size: print("\nEntire map will be kept (not cutting out region)", file=log) if params.restrict_map_size: print("\nOutput map will be within input map", file=log) if params.lower_bounds and params.upper_bounds: print("Bounds for cut out map are (%s,%s,%s) to (%s,%s,%s)" %( tuple(list(params.lower_bounds)+list(params.upper_bounds))), file=log) if mask_data: mask_data=mask_data.as_double() box = mmtbx.utils.extract_box_around_model_and_map( xray_structure = xray_structure, map_data = map_data.as_double(), mask_data = mask_data, box_cushion = params.box_cushion, selection = selection, mask_select = params.mask_select, density_select = params.density_select, threshold = params.density_select_threshold, get_half_height_width = params.get_half_height_width, mask_atoms = params.mask_atoms, soft_mask = params.soft_mask, soft_mask_radius = params.soft_mask_radius, mask_atoms_atom_radius = params.mask_atoms_atom_radius, value_outside_atoms = params.value_outside_atoms, keep_map_size = params.keep_map_size, restrict_map_size = params.restrict_map_size, lower_bounds = params.lower_bounds, upper_bounds = params.upper_bounds, bounds_are_absolute = params.bounds_are_absolute, zero_outside_original_map = params.zero_outside_original_map, extract_unique = params.extract_unique, target_ncs_au_file = params.target_ncs_au_file, regions_to_keep = params.regions_to_keep, box_buffer = params.box_buffer, soft_mask_extract_unique = params.soft_mask_extract_unique, mask_expand_ratio = params.mask_expand_ratio, keep_low_density = params.keep_low_density, chain_type = params.chain_type, sequence = sequence, solvent_content = params.solvent_content, molecular_mass = params.molecular_mass, resolution = params.resolution, ncs_object = ncs_object, symmetry = params.symmetry, half_map_data_list = half_map_data_list, ) ph_box = pdb_hierarchy.select(selection) ph_box.adopt_xray_structure(box.xray_structure_box) box.hierarchy=ph_box if params.mask_select: print("\nSolvent content used in mask_select: %.3f " %( box.get_solvent_content()),file=log) if (inputs and inputs.crystal_symmetry and inputs.ccp4_map and inputs.crystal_symmetry.unit_cell().parameters() and inputs.ccp4_map.unit_cell_parameters ) and ( inputs.crystal_symmetry.unit_cell().parameters() != inputs.ccp4_map.unit_cell_parameters): print("\nNOTE: Input CCP4 map is only part of unit cell:", file=log) print("Full unit cell ('unit cell parameters'): "+\ "(%.1f, %.1f, %.1f, %.1f, %.1f, %.1f) A" %tuple( inputs.ccp4_map.unit_cell_parameters), file=log) print("Size of CCP4 map 'map unit cell': "+\ "(%.1f, %.1f, %.1f, %.1f, %.1f, %.1f) A" %tuple( inputs.crystal_symmetry.unit_cell().parameters()), file=log) print("Full unit cell as grid units: (%s, %s, %s)" %( inputs.ccp4_map.unit_cell_grid), file=log) print("Map unit cell as grid units: (%s, %s, %s)" %( map_data.all()), file=log) box.unit_cell_parameters_from_ccp4_map=inputs.ccp4_map.unit_cell_parameters box.unit_cell_parameters_deduced_from_map_grid=\ inputs.crystal_symmetry.unit_cell().parameters() else: box.unit_cell_parameters_from_ccp4_map=None box.unit_cell_parameters_deduced_from_map_grid=None if box.pdb_outside_box_msg: print(box.pdb_outside_box_msg, file=log) # NOTE: box object is always shifted to place origin at (0,0,0) # NOTE ON ORIGIN SHIFTS: The shifts are applied locally here. The box # object is not affected and always has the origin at (0,0,0) # output_box is copy of box with shift_cart corresponding to the output # files. Normally this is the same as the original shift_cart. However # if user has specified a new output origin it will differ. # For output files ONLY: # keep_origin==False leave origin at (0,0,0) # keep_origin==True: we shift everything back to where it was, # output_origin_grid_units=10,10,10: output origin is at (10,10,10) # ncs_object is original # box.ncs_object is shifted by shift_cart # output_box.ncs_object is shifted back by -new shift_cart # Additional note on output unit_cell and grid_units. # The ccp4-style output map can specify the unit cell and grid units # corresponding to that cell. This can be separate from the origin and # number of grid points in the map as written. If specified, write these # out to the output ccp4 map and also use this unit cell for writing # any output PDB files from copy import deepcopy output_box=deepcopy(box) # won't use box below here except to return it print("\nBox cell dimensions: (%.2f, %.2f, %.2f) A" %( box.box_crystal_symmetry.unit_cell().parameters()[:3]), file=log) if box.shift_cart: print("Working origin moved from grid position of"+\ ": (%d, %d, %d) to (0,0,0) " %( tuple(box.origin_shift_grid_units(reverse=True))), file=log) print("Working origin moved from coordinates of:"+\ " (%.2f, %.2f, %.2f) A to (0,0,0)\n" %( tuple(-col(box.shift_cart))), file=log) if (params.keep_origin): print("\nRestoring original position for output files", file=log) print("Origin will be at grid position of"+\ ": (%d, %d, %d) " %( tuple(box.origin_shift_grid_units(reverse=True))), file=log) print("\nOutput files will be in same location as original", end=' ', file=log) if not params.keep_map_size: print("just cut out.", file=log) else: print("keeping entire map", file=log) print("Note that output maps are only valid in the cut out region.\n", file=log) else: if origin_to_match: output_box.shift_cart=shift_cart_for_origin_to_match if params.output_origin_grid_units: print("Output map origin to be shifted to match target", file=log) print("Placing origin at grid point (%s, %s, %s)" %( origin_to_match)+"\n"+ \ "Final coordinate shift for output files: (%.2f,%.2f,%.2f) A\n" %( tuple(col(output_box.shift_cart)-col(box.shift_cart))), file=log) elif box.shift_cart: output_box.shift_cart=(0,0,0) # not shifting back print("Final origin will be at (0,0,0)", file=log) print("Final coordinate shift for output files: (%.2f,%.2f,%.2f) A\n" %( tuple(col(output_box.shift_cart)-col(box.shift_cart))), file=log) else: print("\nOutput files are in same location as original and origin "+\ "is at (0,0,0)\n", file=log) print("\nBox grid: (%s, %s, %s) " %(output_box.map_box.all()),file=log) ph_output_box_output_location = ph_box.deep_copy() if output_box.shift_cart: # shift coordinates and NCS back by shift_cart # NOTE output_box.shift_cart could be different than box.shift_cart if # there is a target position for the origin and it is not the same as the # original origin. sites_cart = output_box.shift_sites_cart_back( output_box.xray_structure_box.sites_cart()) xrs_offset = ph_output_box_output_location.extract_xray_structure( crystal_symmetry=output_box.xray_structure_box.crystal_symmetry() ).replace_sites_cart(new_sites = sites_cart) ph_output_box_output_location.adopt_xray_structure(xrs_offset) if output_box.ncs_object: output_box.ncs_object=output_box.ncs_object.coordinate_offset( tuple(-col(output_box.shift_cart))) shift_back=True else: shift_back=False if params.keep_input_unit_cell_and_grid and \ (input_unit_cell_grid is not None) and \ (input_unit_cell is not None): params.output_unit_cell=input_unit_cell params.output_unit_cell_grid=input_unit_cell_grid print("Setting output unit cell parameters and unit cell grid to"+\ " match\ninput map file", file=log) if params.output_unit_cell: # Set output unit cell parameters from cctbx import crystal output_crystal_symmetry=crystal.symmetry( unit_cell=params.output_unit_cell, space_group="P1") output_unit_cell=output_crystal_symmetry.unit_cell() print("Output unit cell set to: %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)" %tuple( output_crystal_symmetry.unit_cell().parameters()), file=log) else: output_crystal_symmetry=None # ============= Check/set output unit cell grid and cell parameters ======= if params.output_unit_cell_grid or output_crystal_symmetry: if params.output_unit_cell_grid: output_unit_cell_grid=params.output_unit_cell_grid else: output_unit_cell_grid=output_box.map_box.all() print("Output unit cell grid set to: (%s, %s, %s)" %tuple( output_unit_cell_grid), file=log) expected_output_abc=[] box_spacing=[] output_spacing=[] box_abc=output_box.xray_structure_box.\ crystal_symmetry().unit_cell().parameters()[:3] if output_crystal_symmetry: output_abc=output_crystal_symmetry.unit_cell().parameters()[:3] else: output_abc=[None,None,None] for a_box,a_output,n_box,n_output in zip( box_abc, output_abc, output_box.map_box.all(), output_unit_cell_grid): expected_output_abc.append(a_box*n_output/n_box) box_spacing.append(a_box/n_box) if output_crystal_symmetry: output_spacing.append(a_output/n_output) else: output_spacing.append(a_box/n_box) if output_crystal_symmetry: # make sure it is compatible... r0=expected_output_abc[0]/output_abc[0] r1=expected_output_abc[1]/output_abc[1] r2=expected_output_abc[2]/output_abc[2] from libtbx.test_utils import approx_equal if not approx_equal(r0,r1,eps=0.001) or not approx_equal(r0,r2,eps=0.001): print("WARNING: output_unit_cell and cell_grid will "+\ "change ratio of grid spacing.\nOld spacings: "+\ "(%.2f, %.2f, %.2f) A " %(tuple(box_spacing))+\ "\nNew spacings: (%.2f, %.2f, %.2f) A \n" %(tuple(output_spacing)), file=log) else: output_abc=expected_output_abc from cctbx import crystal output_crystal_symmetry=crystal.symmetry( unit_cell=list(output_abc)+[90,90,90], space_group="P1") print("Output unit cell will be: (%.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n"%( tuple(output_crystal_symmetry.unit_cell().parameters())), file=log) else: output_unit_cell_grid = output_box.map_box.all() output_crystal_symmetry=output_box.xray_structure_box.crystal_symmetry() # ========== Done check/set output unit cell grid and cell parameters ===== if write_output_files: # Write PDB file if ph_box.overall_counts().n_residues>0: if(params.output_file_name_prefix is None): file_name = "%s_box.pdb"%output_prefix else: file_name = "%s.pdb"%params.output_file_name_prefix ph_output_box_output_location.write_pdb_file(file_name=file_name, crystal_symmetry = output_crystal_symmetry) print("Writing boxed PDB with box unit cell to %s" %( file_name), file=log) # Write NCS file if NCS if output_box.ncs_object and output_box.ncs_object.max_operators()>0: if(params.output_file_name_prefix is None): output_symmetry_file = "%s_box.ncs_spec"%output_prefix else: output_symmetry_file = "%s.ncs_spec"%params.output_file_name_prefix output_box.ncs_object.format_all_for_group_specification( file_name=output_symmetry_file) print("\nWriting symmetry to %s" %( output_symmetry_file), file=log) # Write ccp4 map. if("ccp4" in params.output_format): if(params.output_file_name_prefix is None): file_name = "%s_box.ccp4"%output_prefix else: file_name = "%s.ccp4"%params.output_file_name_prefix from iotbx.mrcfile import create_output_labels if params.extract_unique: program_name='map_box using extract_unique' limitations=["extract_unique"] else: program_name='map_box' limitations=[] labels=create_output_labels(program_name=program_name, input_file_name=inputs.ccp4_map_file_name, input_labels=input_map_labels, limitations=limitations, output_labels=params.output_map_labels) output_box.write_ccp4_map(file_name=file_name, output_crystal_symmetry=output_crystal_symmetry, output_mean=params.output_ccp4_map_mean, output_sd=params.output_ccp4_map_sd, output_unit_cell_grid=output_unit_cell_grid, shift_back=shift_back, output_map_labels=labels, output_external_origin=params.output_external_origin) print("Writing boxed map "+\ "to CCP4 formatted file: %s"%file_name, file=log) if not params.half_map_list: params.half_map_list=[] if not output_box.map_box_half_map_list: output_box.map_box_half_map_list=[] if not half_map_labels_list: half_map_labels_list=len(output_box.map_box_half_map_list)*[None] for hm,labels,fn in zip( output_box.map_box_half_map_list, half_map_labels_list, params.half_map_list): # half maps matching labels=create_output_labels(program_name=program_name, input_file_name=fn, input_labels=labels, limitations=limitations, output_labels=params.output_map_labels) hm_fn="%s_box.ccp4" %( ".".join(os.path.basename(fn).split(".")[:-1])) output_box.write_ccp4_map(file_name=hm_fn, map_data=hm, output_crystal_symmetry=output_crystal_symmetry, output_mean=params.output_ccp4_map_mean, output_sd=params.output_ccp4_map_sd, output_unit_cell_grid=output_unit_cell_grid, shift_back=shift_back, output_map_labels=labels, output_external_origin=params.output_external_origin) print ("Writing boxed half map to: %s " %(hm_fn),file=log) # Write xplor map. Shift back if keep_origin=True if("xplor" in params.output_format): if(params.output_file_name_prefix is None): file_name = "%s_box.xplor"%output_prefix else: file_name = "%s.xplor"%params.output_file_name_prefix output_box.write_xplor_map(file_name=file_name, output_crystal_symmetry=output_crystal_symmetry, output_unit_cell_grid=output_unit_cell_grid, shift_back=shift_back,) print("Writing boxed map "+\ "to X-plor formatted file: %s"%file_name, file=log) # Write mtz map coeffs. Shift back if keep_origin=True if("mtz" in params.output_format): if(params.output_file_name_prefix is None): file_name = "%s_box.mtz"%output_prefix else: file_name = "%s.mtz"%params.output_file_name_prefix print("Writing map coefficients "+\ "to MTZ file: %s"%file_name, file=log) if(map_coeff is not None): d_min = map_coeff.d_min() elif params.resolution is not None: d_min = params.resolution else: d_min = maptbx.d_min_from_map(map_data=output_box.map_box, unit_cell=output_box.xray_structure_box.unit_cell()) output_box.map_coefficients(d_min=d_min, scale_max=params.scale_max, resolution_factor=params.resolution_factor, file_name=file_name, shift_back=shift_back) print(file=log) return box
def exercise_writer(use_mrcfile=None,output_axis_order=[3,2,1]): from cctbx import uctbx, sgtbx from scitbx.array_family import flex mt = flex.mersenne_twister(0) nxyz = (4,5,6,) grid = flex.grid(nxyz) real_map_data = mt.random_double(size=grid.size_1d()) real_map_data.reshape(grid) unit_cell=uctbx.unit_cell((10,10,10,90,90,90)) if use_mrcfile: from iotbx.mrcfile import create_output_labels labels=create_output_labels( program_name='test', limitations=['extract_unique'], output_labels=['test label'], ) iotbx.mrcfile.write_ccp4_map( file_name="four_five_six.mrc", unit_cell=unit_cell, space_group=sgtbx.space_group_info("P1").group(), map_data=real_map_data, labels=labels, output_axis_order=output_axis_order) input_real_map = iotbx.mrcfile.map_reader(file_name="four_five_six.mrc") for x in input_real_map.labels: print("LABEL: ",x) assert str(input_real_map.labels).find('extract_unique')>-1 else: iotbx.ccp4_map.write_ccp4_map( file_name="four_five_six.map", unit_cell=unit_cell, space_group=sgtbx.space_group_info("P1").group(), map_data=real_map_data, labels=flex.std_string(["iotbx.ccp4_map.tst"])) input_real_map = iotbx.ccp4_map.map_reader(file_name="four_five_six.map") input_map_data=input_real_map.map_data() real_map_mmm = real_map_data.as_1d().min_max_mean() input_map_mmm = input_map_data.as_double().as_1d().min_max_mean() cc=flex.linear_correlation(real_map_data.as_1d(),input_map_data.as_double().as_1d()).coefficient() assert cc > 0.999 print("\nMRCFILE with 4x5x6 map and axis order %s %s" %(output_axis_order,cc)) assert approx_equal(input_real_map.unit_cell().parameters(), unit_cell.parameters()) assert approx_equal(real_map_mmm.min, input_real_map.header_min,eps=0.001) assert approx_equal(real_map_mmm.min, input_map_mmm.min,eps=0.001) # random small maps of different sizes for nxyz in flex.nested_loop((2,1,1),(4,4,4)): mt = flex.mersenne_twister(0) grid = flex.grid(nxyz) real_map = mt.random_double(size=grid.size_1d()) real_map=real_map-0.5 real_map.reshape(grid) if use_mrcfile: iotbx.mrcfile.write_ccp4_map( file_name="random.mrc", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), gridding_first=(0,0,0), gridding_last=tuple(grid.last(False)), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.mrcfile.map_reader(file_name="random.mrc") else: iotbx.ccp4_map.write_ccp4_map( file_name="random.map", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), gridding_first=(0,0,0), gridding_last=tuple(grid.last(False)), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.ccp4_map.map_reader(file_name="random.map") mmm = flex.double(list(real_map)).min_max_mean() m1=real_map.as_1d() m2=m.map_data().as_double().as_1d() cc=flex.linear_correlation(m1,m2).coefficient() assert cc > 0.999 assert approx_equal(m.unit_cell().parameters(), (1,1,1,90,90,90)) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) # # write unit_cell_grid explicitly to map iotbx.ccp4_map.write_ccp4_map( file_name="random_b.map", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), unit_cell_grid=real_map.all(), map_data=real_map, labels=flex.std_string(["iotbx.ccp4_map.tst"])) m = iotbx.ccp4_map.map_reader(file_name="random_b.map") m1=real_map.as_1d() m2=m.map_data().as_double().as_1d() cc=flex.linear_correlation(m1,m2).coefficient() assert cc > 0.999 mmm = flex.double(list(real_map)).min_max_mean() assert approx_equal(m.unit_cell_parameters, (1,1,1,90,90,90)) assert approx_equal(mmm.min, m.header_min) assert approx_equal(mmm.max, m.header_max) # # gridding_first = (0,0,0) gridding_last=tuple(grid.last(False)) map_box = maptbx.copy(real_map, gridding_first, gridding_last) map_box.reshape(flex.grid(map_box.all())) if use_mrcfile: iotbx.mrcfile.write_ccp4_map( file_name="random_box.mrc", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), map_data=map_box, labels=flex.std_string(["iotbx.ccp4_map.tst"])) else: iotbx.ccp4_map.write_ccp4_map( file_name="random_box.map", unit_cell=uctbx.unit_cell((1,1,1,90,90,90)), space_group=sgtbx.space_group_info("P1").group(), map_data=map_box, labels=flex.std_string(["iotbx.ccp4_map.tst"])) print("OK")
def run(args=None,params=None, map_data=None,crystal_symmetry=None, write_output_files=True, pdb_inp=None, ncs_obj=None, return_map_data_only=False, return_unshifted_map=False, half_map_data_list=None, ncs_copies=None, n_residues=None, out=sys.stdout): # Get the parameters if not params: params=get_params(args,out=out) if not ncs_copies: ncs_copies=params.crystal_info.ncs_copies # get map_data and crystal_symmetry pdb_inp,map_data,half_map_data_list,ncs_obj,crystal_symmetry,acc,\ original_crystal_symmetry,original_unit_cell_grid,map_labels=\ get_map_and_model( map_data=map_data, half_map_data_list=half_map_data_list, pdb_inp=pdb_inp, ncs_obj=ncs_obj, map_coords_inside_cell=False, crystal_symmetry=crystal_symmetry, get_map_labels=True, params=params,out=out) # NOTE: map_data is now relative to origin at (0,0,0). # Use map_data.reshape(acc) to put it back where it was if acc is not None # auto-sharpen the map from cctbx.maptbx.segment_and_split_map import auto_sharpen_map_or_map_coeffs si=auto_sharpen_map_or_map_coeffs( resolution=params.crystal_info.resolution, # required crystal_symmetry=crystal_symmetry, is_crystal=params.crystal_info.is_crystal, verbose=params.control.verbose, resolve_size=params.control.resolve_size, multiprocessing=params.control.multiprocessing, nproc=params.control.nproc, queue_run_command=params.control.queue_run_command, map=map_data, half_map_data_list=half_map_data_list, solvent_content=params.crystal_info.solvent_content, molecular_mass=params.crystal_info.molecular_mass, input_weight_map_pickle_file=\ params.input_files.input_weight_map_pickle_file, output_weight_map_pickle_file=\ params.output_files.output_weight_map_pickle_file, read_sharpened_maps=params.map_modification.read_sharpened_maps, write_sharpened_maps=params.map_modification.write_sharpened_maps, select_sharpened_map=params.map_modification.select_sharpened_map, auto_sharpen=params.map_modification.auto_sharpen, local_sharpening=params.map_modification.local_sharpening, output_directory=params.output_files.output_directory, smoothing_radius=params.map_modification.smoothing_radius, local_aniso_in_local_sharpening=\ params.map_modification.local_aniso_in_local_sharpening, overall_before_local=\ params.map_modification.overall_before_local, box_in_auto_sharpen=params.map_modification.box_in_auto_sharpen, density_select_in_auto_sharpen=params.map_modification.density_select_in_auto_sharpen, density_select_threshold_in_auto_sharpen=params.map_modification.density_select_threshold_in_auto_sharpen, use_weak_density=params.map_modification.use_weak_density, discard_if_worse=params.map_modification.discard_if_worse, box_center=params.map_modification.box_center, box_size=params.map_modification.box_size, target_n_overlap=params.map_modification.target_n_overlap, restrict_map_size=params.map_modification.restrict_map_size, remove_aniso=params.map_modification.remove_aniso, auto_sharpen_methods=params.map_modification.auto_sharpen_methods, residual_target=params.map_modification.residual_target, region_weight=params.map_modification.region_weight, sa_percent=params.map_modification.sa_percent, eps=params.map_modification.eps, n_bins=params.map_modification.n_bins, max_regions_to_test=params.map_modification.max_regions_to_test, regions_to_keep=params.map_modification.regions_to_keep, fraction_occupied=params.map_modification.fraction_occupied, sharpening_target=params.map_modification.sharpening_target, d_min_ratio=params.map_modification.d_min_ratio, scale_max=params.map_modification.scale_max, input_d_cut=params.map_modification.input_d_cut, b_blur_hires=params.map_modification.b_blur_hires, max_box_fraction=params.map_modification.max_box_fraction, cc_cut=params.map_modification.cc_cut, max_cc_for_rescale=params.map_modification.max_cc_for_rescale, scale_using_last=params.map_modification.scale_using_last, density_select_max_box_fraction=params.map_modification.density_select_max_box_fraction, mask_atoms=params.map_modification.mask_atoms, mask_atoms_atom_radius=params.map_modification.mask_atoms_atom_radius, value_outside_atoms=params.map_modification.value_outside_atoms, k_sharpen=params.map_modification.k_sharpen, optimize_b_blur_hires=params.map_modification.optimize_b_blur_hires, iterate=params.map_modification.iterate, optimize_d_cut=params.map_modification.optimize_d_cut, soft_mask=params.map_modification.soft_mask, allow_box_if_b_iso_set=params.map_modification.allow_box_if_b_iso_set, search_b_min=params.map_modification.search_b_min, search_b_max=params.map_modification.search_b_max, search_b_n=params.map_modification.search_b_n, adjust_region_weight=params.map_modification.adjust_region_weight, region_weight_method=params.map_modification.region_weight_method, region_weight_factor=params.map_modification.region_weight_factor, region_weight_buffer=\ params.map_modification.region_weight_buffer, target_b_iso_ratio=params.map_modification.target_b_iso_ratio, signal_min=params.map_modification.signal_min, buffer_radius=params.crystal_info.buffer_radius, wang_radius=params.crystal_info.wang_radius, pseudo_likelihood=params.crystal_info.pseudo_likelihood, target_b_iso_model_scale=params.map_modification.target_b_iso_model_scale, b_iso=params.map_modification.b_iso, b_sharpen=params.map_modification.b_sharpen, resolution_dependent_b=\ params.map_modification.resolution_dependent_b, normalize_amplitudes_in_resdep=\ params.map_modification.normalize_amplitudes_in_resdep, pdb_inp=pdb_inp, ncs_obj=ncs_obj, rmsd=params.map_modification.rmsd, rmsd_resolution_factor=params.map_modification.rmsd_resolution_factor, b_sol=params.map_modification.b_sol, k_sol=params.map_modification.k_sol, fraction_complete=params.map_modification.fraction_complete, seq_file=params.input_files.seq_file, ncs_copies=ncs_copies, n_residues=n_residues, out=out) # get map_data and map_coeffs of final map new_map_data=si.as_map_data() new_map_coeffs=si.as_map_coeffs() from cctbx.maptbx.segment_and_split_map import get_b_iso,map_coeffs_as_fp_phi f,phi=map_coeffs_as_fp_phi(new_map_coeffs) temp_b_iso=get_b_iso(f,d_min=params.crystal_info.resolution) if not si.is_model_sharpening(): print >>out print >>out,80*"=","\n",80*"=" print >>out,"\n Summary of sharpening information\n " si.show_summary(verbose=params.control.verbose,out=out) print >>out,80*"=","\n",80*"=" # write out the new map_coeffs and map if requested: offset_map_data=new_map_data.deep_copy() if acc is not None: # offset the map to match original if possible offset_map_data.reshape(acc) if write_output_files and params.output_files.sharpened_map_file and \ offset_map_data: output_map_file=os.path.join(params.output_files.output_directory, params.output_files.sharpened_map_file) from cctbx.maptbx.segment_and_split_map import write_ccp4_map if acc is not None: # we offset the map to match original print >>out,\ "\nWrote sharpened map in original location with origin at %s\nto %s" %( str(offset_map_data.origin()),output_map_file) write_ccp4_map(original_crystal_symmetry, output_map_file, offset_map_data, output_unit_cell_grid=original_unit_cell_grid) else: print >>out,"\nWrote sharpened map with origin at 0,0,0 "+\ "(NOTE: may be boxed map and may not be "+\ "\nsame as original location) to %s\n" %( output_map_file) from iotbx.mrcfile import create_output_labels program_name='auto_sharpen' limitations=["map_is_sharpened"] labels=create_output_labels(program_name=program_name, input_file_name=params.input_files.map_file, input_labels=map_labels, limitations=limitations, output_labels=None) write_ccp4_map(crystal_symmetry, output_map_file, offset_map_data, labels=labels) if write_output_files and params.output_files.shifted_sharpened_map_file: output_map_file=os.path.join(params.output_files.output_directory, params.output_files.shifted_sharpened_map_file) from cctbx.maptbx.segment_and_split_map import write_ccp4_map write_ccp4_map(crystal_symmetry, output_map_file, new_map_data) print >>out,"\nWrote sharpened map (origin at %s)\nto %s" %( str(new_map_data.origin()),output_map_file) if write_output_files and params.output_files.sharpened_map_coeffs_file and \ new_map_coeffs: output_map_coeffs_file=os.path.join(params.output_files.output_directory, params.output_files.sharpened_map_coeffs_file) new_map_coeffs.as_mtz_dataset(column_root_label='FWT').mtz_object().write( file_name=output_map_coeffs_file) print >>out,"\nWrote sharpened map_coeffs (origin at 0,0,0)\n to %s\n" %( output_map_coeffs_file) if return_unshifted_map: map_to_return=offset_map_data else: map_to_return=new_map_data if return_map_data_only: return map_to_return else: #usual return map_to_return,new_map_coeffs,crystal_symmetry,si
# Write ccp4 map. if ("ccp4" in params.output_format): if (params.output_file_name_prefix is None): file_name = "%s_box.ccp4" % output_prefix else: file_name = "%s.ccp4" % params.output_file_name_prefix from iotbx.mrcfile import create_output_labels if params.extract_unique: program_name = 'map_box using extract_unique' limitations = ["extract_unique"] else: program_name = 'map_box' limitations = [] labels = create_output_labels( program_name=program_name, input_file_name=inputs.ccp4_map_file_name, input_labels=input_map_labels, limitations=limitations, output_labels=None) output_box.write_ccp4_map( file_name=file_name, output_crystal_symmetry=output_crystal_symmetry, output_mean=params.output_ccp4_map_mean, output_sd=params.output_ccp4_map_sd, output_unit_cell_grid=output_unit_cell_grid, shift_back=shift_back, output_map_labels=labels, output_external_origin=params.output_external_origin) print >> log, "Writing boxed map "+\ "to CCP4 formatted file: %s"%file_name