def __init__(self, map_manager, model, box_cushion, wrapping=None, log=sys.stdout): self._map_manager = map_manager self._model = model self._force_wrapping = wrapping if wrapping is None: wrapping = self.map_manager().wrapping() self.basis_for_boxing_string = 'using_model, wrapping = %s' % ( wrapping) # safeguards assert isinstance(map_manager, iotbx.map_manager.map_manager) assert isinstance(model, mmtbx.model.manager) assert self._map_manager.map_data().accessor().origin() == (0, 0, 0) # Make sure working model and map_manager crystal_symmetry match assert map_manager.is_compatible_model(model) assert box_cushion >= 0 if self.map_manager().wrapping(): # map must be entire unit cell assert map_manager.unit_cell_grid == map_manager.map_data().all() # NOTE: We are going to use crystal_symmetry and sites_frac based on # the map_manager (the model could still have different crystal_symmetry) # get items needed to do the shift cs = map_manager.crystal_symmetry() uc = cs.unit_cell() sites_cart = model.get_sites_cart() sites_frac = uc.fractionalize(sites_cart) map_data = map_manager.map_data() # convert box_cushion into fractional vector cushion_frac = flex.double(uc.fractionalize((box_cushion, ) * 3)) # find fractional corners frac_min = sites_frac.min() frac_max = sites_frac.max() frac_max = list(flex.double(frac_max) + cushion_frac) frac_min = list(flex.double(frac_min) - cushion_frac) # find corner grid nodes all_orig = map_data.all() self.gridding_first = [ ifloor(f * n) for f, n in zip(frac_min, all_orig) ] self.gridding_last = [iceil(f * n) for f, n in zip(frac_max, all_orig)] # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() # Apply boxing to model, ncs, and map (if available) self.apply_to_model_ncs_and_map()
def apply_to_map(self, map_manager): assert map_manager is not None # Apply to a map_manager that is similar to the one used to generate # this around_model object assert map_manager.crystal_symmetry().is_similar_symmetry( self.original_crystal_symmetry) ma1 = map_manager.map_data().accessor() ma2 = self.original_accessor assert ma1.all() == ma2.all() assert ma1.origin() == ma2.origin() assert ma1.focus() == ma2.focus() map_data = map_manager.map_data() # Check if map is all valid bounds_info = get_bounds_of_valid_region( map_data=map_data, gridding_first=self.gridding_first, gridding_last=self.gridding_last) if self.wrapping or bounds_info.inside_allowed_bounds: # Just copy everything map_box = maptbx.copy(map_data, self.gridding_first, self.gridding_last) # Note: map_box gridding is self.gridding_first to self.gridding_last else: # Need to copy and then zero outside of defined region map_box = copy_and_zero_map_outside_bounds(map_data=map_data, bounds_info=bounds_info) # Now reshape map_box to put origin at (0,0,0) map_box.reshape(flex.grid(self.box_all)) # Create new map_manager object: # Use original values for: # unit_cell_grid (gridding of original full unit cell) # unit_cell_crystal_symmetry (symmetry of original full unit cell) # input_file_name # Use new (boxed) values for: # map_data # crystal_symmetry (symmetry of the part of the map that is present) # Update: # origin_shift_grid_units (position in the original map of the # (0,0,0) grid point in map_box) # labels (add label specifying boxing operation) # # New origin_shift_grid_units: origin_shift_grid_units = [ self.gridding_first[i] + map_manager.origin_shift_grid_units[i] for i in range(3) ] # New labels: new_label = "Boxed %s to %s %s" % (str(tuple( self.gridding_first)), str(tuple( self.gridding_last)), self.basis_for_boxing_string) # Set up new map_manager. # NOTE: origin_shift_grid_units is required as bounds have changed new_map_manager = map_manager.customized_copy( map_data=map_box, origin_shift_grid_units=origin_shift_grid_units) # Add the label new_map_manager.add_label(new_label) return new_map_manager
def get_bounds_around_model( map_manager=None, model=None, box_cushion=None, ): ''' Calculate the lower and upper bounds to box around a model Allow bounds to go outside the available box (this has to be dealt with at the boxing stage) ''' # get items needed to do the shift cs = map_manager.crystal_symmetry() uc = cs.unit_cell() sites_cart = model.get_sites_cart() sites_frac = uc.fractionalize(sites_cart) map_data = map_manager.map_data() # convert box_cushion into fractional vector cushion_frac = flex.double(uc.fractionalize((box_cushion, ) * 3)) # find fractional corners frac_min = sites_frac.min() frac_max = sites_frac.max() frac_max = list(flex.double(frac_max) + cushion_frac) frac_min = list(flex.double(frac_min) - cushion_frac) # find corner grid nodes all_orig = map_data.all() lower_bounds = [ifloor(f * n) for f, n in zip(frac_min, all_orig)] upper_bounds = [iceil(f * n) for f, n in zip(frac_max, all_orig)] return group_args( lower_bounds=lower_bounds, upper_bounds=upper_bounds, )
def __init__(self, map_manager=None, lower_bounds=None, upper_bounds=None, wrapping=None): self.map_manager = map_manager self.wrapping = wrapping self.basis_for_boxing_string = 'supplied bounds, wrapping=%s' % ( wrapping) # safeguards assert wrapping is not None assert isinstance(map_manager, iotbx.map_manager.map_manager) assert self.map_manager.map_data().accessor().origin() == (0, 0, 0) assert lower_bounds is not None assert upper_bounds is not None if wrapping: assert map_manager.unit_cell_grid == map_manager.map_data().all() self.gridding_first = lower_bounds self.gridding_last = upper_bounds # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry()
def __init__(self, map_manager, model, cushion, wrapping, log=sys.stdout): adopt_init_args(self, locals()) self.basis_for_boxing_string = 'using model, wrapping=%s' % (wrapping) # safeguards assert isinstance(wrapping, bool) assert isinstance(map_manager, iotbx.map_manager.map_manager) assert isinstance(model, mmtbx.model.manager) assert self.map_manager.map_data().accessor().origin() == (0, 0, 0) # Make sure original map_manager symmetry matches model or original model original_uc_symmetry = map_manager.original_unit_cell_crystal_symmetry assert (original_uc_symmetry.is_similar_symmetry( model.crystal_symmetry()) or (model.get_shift_manager() and original_uc_symmetry.is_similar_symmetry( model.get_shift_manager().get_original_cs()))) assert cushion >= 0 if wrapping: assert map_manager.unit_cell_grid == map_manager.map_data().all() # get items needed to do the shift cs = map_manager.crystal_symmetry() uc = cs.unit_cell() sites_frac = model.get_sites_frac() map_data = map_manager.map_data() # convert cushion into fractional vector cushion_frac = flex.double(uc.fractionalize((cushion, ) * 3)) # find fractional corners frac_min = sites_frac.min() frac_max = sites_frac.max() frac_max = list(flex.double(frac_max) + cushion_frac) frac_min = list(flex.double(frac_min) - cushion_frac) # find corner grid nodes all_orig = map_data.all() self.gridding_first = [ ifloor(f * n) for f, n in zip(frac_min, all_orig) ] self.gridding_last = [iceil(f * n) for f, n in zip(frac_max, all_orig)] # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() # Apply to model and to map_manager so that self.model() # and self.map_manager are boxed versions self.map_manager = self.apply_to_map(self.map_manager) self.model = self.apply_to_model(self.model)
def __init__(self, map_manager=None, model=None, cushion=None, wrapping=None): self.map_manager = map_manager self.model = model self.wrapping = wrapping self.basis_for_boxing_string = 'using model, wrapping=%s' % (wrapping) # safeguards assert wrapping is not None assert isinstance(map_manager, iotbx.map_manager.map_manager) assert isinstance(model, mmtbx.model.manager) assert self.map_manager.map_data().accessor().origin() == (0, 0, 0) assert map_manager.crystal_symmetry().is_similar_symmetry( model.crystal_symmetry()) assert cushion >= 0 if wrapping: assert map_manager.unit_cell_grid == map_manager.map_data().all() # get items needed to do the shift cs = map_manager.crystal_symmetry() uc = cs.unit_cell() sites_frac = model.get_sites_frac() map_data = map_manager.map_data() # convert cushion into fractional vector cushion_frac = flex.double(uc.fractionalize((cushion, ) * 3)) # find fractional corners frac_min = sites_frac.min() frac_max = sites_frac.max() frac_max = list(flex.double(frac_max) + cushion_frac) frac_min = list(flex.double(frac_min) - cushion_frac) # find corner grid nodes all_orig = map_data.all() self.gridding_first = [ ifloor(f * n) for f, n in zip(frac_min, all_orig) ] self.gridding_last = [iceil(f * n) for f, n in zip(frac_max, all_orig)] # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry()
def __init__(self, map_manager, wrapping, log=sys.stdout): adopt_init_args(self, locals()) # safeguards assert isinstance(wrapping, bool) assert isinstance(map_manager, iotbx.map_manager.map_manager) assert self.map_manager.map_data().accessor().origin() == (0, 0, 0) if wrapping: assert map_manager.unit_cell_grid == map_manager.map_data().all() self.basis_for_boxing_string = 'around_mask bounds, wrapping=%s' % ( wrapping) # Get a connectivity object that marks all the connected regions in map from cctbx.maptbx.segment_and_split_map import get_co co, sorted_by_volume, min_b, max_b = get_co( map_data=map_manager.map_data(), threshold=0.5, wrapping=False) if len(sorted_by_volume) < 2: # didn't work raise Sorry("No mask obtained...") # Get the biggest connected region in the map original_id_from_id = {} for i in range(1, len(sorted_by_volume)): v, id = sorted_by_volume[i] original_id_from_id[i] = id id = 1 orig_id = original_id_from_id[id] # Get lower and upper bounds of this region in grid units self.gridding_first = min_b[orig_id] self.gridding_last = max_b[orig_id] # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() # Apply to map_manager so that self.map_manager is boxed version self.map_manager = self.apply_to_map(self.map_manager)
def __init__(self, map_manager, model, box_cushion, wrapping=None, model_can_be_outside_bounds=False, stay_inside_current_map=None, log=sys.stdout): self._map_manager = map_manager self._model = model self.model_can_be_outside_bounds = model_can_be_outside_bounds self._force_wrapping = wrapping if wrapping is None: wrapping = self.map_manager().wrapping() self.basis_for_boxing_string = 'using_model, wrapping = %s' % ( wrapping) # safeguards assert isinstance(map_manager, iotbx.map_manager.map_manager) assert isinstance(model, mmtbx.model.manager) assert self._map_manager.map_data().accessor().origin() == (0, 0, 0) # Make sure working model and map_manager crystal_symmetry match assert map_manager.is_compatible_model(model) assert box_cushion >= 0 if self.map_manager().wrapping(): # map must be entire unit cell assert map_manager.unit_cell_grid == map_manager.map_data().all() # NOTE: We are going to use crystal_symmetry and sites_frac based on # the map_manager (the model could still have different crystal_symmetry) info = get_bounds_around_model( map_manager=map_manager, model=model, box_cushion=box_cushion, stay_inside_current_map=stay_inside_current_map) self.gridding_first = info.lower_bounds self.gridding_last = info.upper_bounds # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() # Apply boxing to model, ncs, and map (if available) self.apply_to_model_ncs_and_map()
def __init__( self, map_manager, wrapping=None, ncs_object=None, target_ncs_au_model=None, regions_to_keep=None, solvent_content=None, resolution=None, sequence=None, molecular_mass=None, symmetry=None, chain_type='PROTEIN', keep_low_density=True, # default from map_box box_buffer=5, soft_mask_extract_unique=True, mask_expand_ratio=1, log=sys.stdout): adopt_init_args(self, locals()) assert isinstance(wrapping, bool) assert isinstance(map_manager, iotbx.map_manager.map_manager) assert self.map_manager.map_data().accessor().origin() == (0, 0, 0) assert resolution # Get crystal_symmetry self.crystal_symmetry = map_manager.crystal_symmetry() # Convert to map_data self.map_data = map_manager.map_data() boxed_au_map_data = self.run_segment_and_split_map() if not boxed_au_map_data: raise Sorry("Unable to obtain unique part of map") # Apply to model (if present) and to map_manager so that self.model # and self.map_manager are boxed versions self.map_manager = self.apply_to_map(self.map_manager) # And replace map data with boxed asymmetric unit self.map_manager.set_map_data(map_data=boxed_au_map_data)
def __init__(self, map_manager, lower_bounds, upper_bounds, wrapping, model=None, log=sys.stdout): adopt_init_args(self, locals()) # safeguards assert lower_bounds is not None assert upper_bounds is not None assert upper_bounds is not None assert isinstance(wrapping, bool) assert isinstance(map_manager, iotbx.map_manager.map_manager) assert self.map_manager.map_data().accessor().origin() == (0, 0, 0) if model: assert isinstance(model, mmtbx.model.manager) assert map_manager.crystal_symmetry().is_similar_symmetry( model.crystal_symmetry()) if wrapping: assert map_manager.unit_cell_grid == map_manager.map_data().all() self.basis_for_boxing_string = 'supplied bounds, wrapping=%s' % ( wrapping) self.gridding_first = lower_bounds self.gridding_last = upper_bounds # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() # Apply to model (if present) and to map_manager so that self.model # and self.map_manager are boxed versions self.map_manager = self.apply_to_map(self.map_manager) if self.model: self.model = self.apply_to_model(self.model)
def __init__(self, map_manager, threshold=0.05, box_cushion=3., get_half_height_width=True, model=None, wrapping=None, model_can_be_outside_bounds=False, log=sys.stdout): self._map_manager = map_manager self._model = model self.model_can_be_outside_bounds = model_can_be_outside_bounds # safeguards assert threshold is not None assert box_cushion is not None assert isinstance(map_manager, iotbx.map_manager.map_manager) assert self._map_manager.map_data().accessor().origin() == (0, 0, 0) if self.map_manager().wrapping(): assert map_manager.unit_cell_grid == map_manager.map_data().all() self._force_wrapping = wrapping if wrapping is None: wrapping = self.map_manager().wrapping() self.basis_for_boxing_string = 'around_density, wrapping = %s' % ( wrapping) # Select box where data are positive (> threshold*max) map_data = map_manager.map_data() origin = list(map_data.origin()) assert origin == [0, 0, 0] all = list(map_data.all()) # Get max value vs x, y, z value_list = flex.double() for i in range(0, all[0]): new_map_data = maptbx.copy(map_data, tuple((i, 0, 0)), tuple((i, all[1], all[2]))) value_list.append( new_map_data.as_1d().as_double().min_max_mean().max) ii = 0 for z in value_list: ii += 1 x_min, x_max = get_range(value_list, threshold=threshold, get_half_height_width=get_half_height_width) value_list = flex.double() for j in range(0, all[1]): new_map_data = maptbx.copy(map_data, tuple((0, j, 0)), tuple((all[0], j, all[2]))) value_list.append( new_map_data.as_1d().as_double().min_max_mean().max) y_min, y_max = get_range(value_list, threshold=threshold, get_half_height_width=get_half_height_width) value_list = flex.double() for j in range(0, all[1]): new_map_data = maptbx.copy(map_data, tuple((0, j, 0)), tuple((all[0], j, all[2]))) value_list.append( new_map_data.as_1d().as_double().min_max_mean().max) y_min, y_max = get_range(value_list, threshold=threshold, get_half_height_width=get_half_height_width) value_list = flex.double() for k in range(0, all[2]): new_map_data = maptbx.copy(map_data, tuple((0, 0, k)), tuple((all[0], all[1], k))) value_list.append( new_map_data.as_1d().as_double().min_max_mean().max) z_min, z_max = get_range(value_list, threshold=threshold, get_half_height_width=get_half_height_width) # Get lower and upper bounds of this region in grid units frac_min = (x_min, y_min, z_min) frac_max = (x_max, y_max, z_max) cs = map_manager.crystal_symmetry() cushion = flex.double(cs.unit_cell().fractionalize( (box_cushion, ) * 3)) all_orig = map_data.all() self.gridding_first = [ max(0, ifloor((f - c) * n)) for c, f, n in zip(cushion, frac_min, all_orig) ] self.gridding_last = [ min(n - 1, iceil((f + c) * n)) for c, f, n in zip(cushion, frac_max, all_orig) ] # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() # Apply boxing to model, ncs, and map (if available) self.apply_to_model_ncs_and_map()
def __init__(self, map_manager, mask_as_map_manager, model=None, box_cushion=3, wrapping=None, model_can_be_outside_bounds=False, log=sys.stdout): self._map_manager = map_manager self._model = model self.model_can_be_outside_bounds = model_can_be_outside_bounds assert map_manager.shift_cart() == mask_as_map_manager.shift_cart() # safeguards assert isinstance(map_manager, iotbx.map_manager.map_manager) assert isinstance(mask_as_map_manager, iotbx.map_manager.map_manager) assert self._map_manager.map_data().accessor().origin() == (0, 0, 0) assert map_manager.is_similar(mask_as_map_manager) if self.map_manager().wrapping(): assert map_manager.unit_cell_grid == map_manager.map_data().all() self._force_wrapping = wrapping if wrapping is None: wrapping = self.map_manager().wrapping() self.basis_for_boxing_string = 'around_mask bounds, wrapping = %s' % ( wrapping) # Make sure the map goes from 0 to 1 map_data = mask_as_map_manager.map_data() mmm = map_data.as_1d().min_max_mean() minimum = mmm.min range_of_values = mmm.max - mmm.min map_data = (map_data - minimum) / max(1.e-10, range_of_values) # Get a connectivity object that marks all the connected regions in map from cctbx.maptbx.segment_and_split_map import get_co co, sorted_by_volume, min_b, max_b = get_co(map_data=map_data, threshold=0.5, wrapping=False) if len(sorted_by_volume) < 2: # didn't work raise Sorry("No mask obtained...") # Get the biggest connected region in the map original_id_from_id = {} for i in range(1, len(sorted_by_volume)): v, id = sorted_by_volume[i] original_id_from_id[i] = id id = 1 orig_id = original_id_from_id[id] # Get lower and upper bounds of this region in grid units self.gridding_first = min_b[orig_id] self.gridding_last = max_b[orig_id] # Increase range of bounds by box_cushion cs = map_manager.crystal_symmetry() cushion = flex.double(cs.unit_cell().fractionalize( (box_cushion, ) * 3)) all_orig = map_manager.map_data().all() self.gridding_first = [ max(0, ifloor(gf - c * n)) for c, gf, n in zip(cushion, self.gridding_first, all_orig) ] self.gridding_last = [ min(n - 1, iceil(gl + c * n)) for c, gl, n in zip(cushion, self.gridding_last, all_orig) ] # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() self.apply_to_model_ncs_and_map() # Also apply to mask_as_map_manager so that mask_as_map_manager is boxed mask_as_map_manager = self.apply_to_map(mask_as_map_manager) self.mask_as_map_manager = mask_as_map_manager # save it
def __init__( self, map_manager, model=None, target_ncs_au_model=None, regions_to_keep=None, solvent_content=None, resolution=None, sequence=None, molecular_mass=None, symmetry=None, chain_type='PROTEIN', keep_low_density=True, # default from map_box box_cushion=5, soft_mask=True, mask_expand_ratio=1, wrapping=None, log=None): self.model_can_be_outside_bounds = None # not used but required to be set self._map_manager = map_manager self._model = model self._mask_data = None self._force_wrapping = wrapping if wrapping is None: wrapping = self.map_manager().wrapping() self.basis_for_boxing_string = 'around_unique, wrapping = %s' % ( wrapping) if log is None: log = null_out() # Print only if a log is supplied assert isinstance(map_manager, iotbx.map_manager.map_manager) assert self._map_manager.map_data().accessor().origin() == (0, 0, 0) assert resolution is not None if model is not None: assert isinstance(model, mmtbx.model.manager) assert map_manager.is_compatible_model(model) if self.map_manager().wrapping(): # map must be entire unit cell assert map_manager.unit_cell_grid == map_manager.map_data().all() # Get crystal_symmetry self.crystal_symmetry = map_manager.crystal_symmetry() # Convert to map_data from cctbx.maptbx.segment_and_split_map import run as segment_and_split_map assert self._map_manager.map_data().origin() == (0, 0, 0) args = [] ncs_group_obj, remainder_ncs_group_obj, tracking_data = \ segment_and_split_map(args, map_data = self._map_manager.map_data(), crystal_symmetry = self.crystal_symmetry, ncs_obj = self._map_manager.ncs_object(), target_model = target_ncs_au_model, write_files = False, auto_sharpen = False, add_neighbors = False, density_select = False, save_box_map_ncs_au = True, resolution = resolution, solvent_content = solvent_content, chain_type = chain_type, sequence = sequence, molecular_mass = molecular_mass, symmetry = symmetry, keep_low_density = keep_low_density, regions_to_keep = regions_to_keep, box_buffer = box_cushion, soft_mask_extract_unique = soft_mask, mask_expand_ratio = mask_expand_ratio, out = log) from scitbx.matrix import col if not hasattr(tracking_data, 'box_mask_ncs_au_map_data'): raise Sorry(" Extraction of unique part of map failed...") ncs_au_mask_data = tracking_data.box_mask_ncs_au_map_data lower_bounds = ncs_au_mask_data.origin() upper_bounds = tuple(col(ncs_au_mask_data.focus()) - col((1, 1, 1))) print("\nBounds for unique part of map: %s to %s " % (str(lower_bounds), str(upper_bounds)), file=log) # shift the map so it is in the same position as the box map will be in ncs_au_mask_data.reshape(flex.grid(ncs_au_mask_data.all())) assert col(ncs_au_mask_data.all()) == \ col(upper_bounds)-col(lower_bounds)+col((1, 1, 1)) self.gridding_first = lower_bounds self.gridding_last = upper_bounds # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() # Apply boxing to model, ncs, and map (if available) self.apply_to_model_ncs_and_map() # Note that at this point, self._map_manager has been boxed assert ncs_au_mask_data.all() == self._map_manager.map_data().all() self._mask_data = ncs_au_mask_data # Now separately apply the mask to the boxed map self.apply_around_unique_mask(self._map_manager, resolution=resolution, soft_mask=soft_mask)
def apply_to_map(self, map_manager): ''' Apply boxing to a map_manager that is similar to the one used to generate this around_model object Also apply to its ncs_object, if any ''' assert isinstance(map_manager, iotbx.map_manager.map_manager) # This one should just have similar unit_cell_crystal_symmetry # crystal_symmetry should match self.map_crystal_symmetry_at_initialization assert map_manager.unit_cell_crystal_symmetry().is_similar_symmetry( self._map_manager.unit_cell_crystal_symmetry()) assert map_manager.crystal_symmetry().is_similar_symmetry( self.map_crystal_symmetry_at_initialization) ma1 = map_manager.map_data().accessor() ma2 = self.accessor_at_initialization assert ma1.all() == ma2.all() assert ma1.origin() == ma2.origin() assert ma1.focus() == ma2.focus() map_data = map_manager.map_data() # Check if map is all valid bounds_info = get_bounds_of_valid_region(map_data, self.gridding_first, self.gridding_last) # Allow override of wrapping if isinstance(self._force_wrapping, bool): wrapping = self._force_wrapping else: # Get wrapping from map_manager. If it is not defined and # bounds are outside allowed, try to get the wrapping wrapping = map_manager.wrapping() if wrapping or bounds_info.inside_allowed_bounds: # Just copy everything map_box = maptbx.copy(map_data, self.gridding_first, self.gridding_last) # Note: map_box gridding is self.gridding_first to self.gridding_last elif not bounds_info.some_valid_points: # No valid points, Just copy everything and zero map_box = maptbx.copy(map_data, self.gridding_first, self.gridding_last) map_box = map_box * 0. self._warning_message += "\nWARNING: boxed map is entirely outside map"+\ " and wrapping=%s\n...setting all values to zero" %(wrapping) else: # Need to copy and then zero outside of defined region map_box = copy_and_zero_map_outside_bounds(map_data, bounds_info) self._warning_message += \ "\nWARNING: boxed map goes outside original map"+\ " and wrapping=%s\n...setting unknown values to zero" %(wrapping) # Now reshape map_box to put origin at (0, 0, 0) map_box.reshape(flex.grid(self.box_all)) # Create new map_manager object: # Use original values for: # unit_cell_grid (gridding of original full unit cell) # unit_cell_crystal_symmetry (symmetry of original full unit cell) # input_file_name # Use new (boxed) values for: # map_data # crystal_symmetry (symmetry of the part of the map that is present) # Update: # origin_shift_grid_units (position in the original map of the # (0, 0, 0) grid point in map_box) # labels (add label specifying boxing operation) # # New origin_shift_grid_units: origin_shift_grid_units = [ self.gridding_first[i] + map_manager.origin_shift_grid_units[i] for i in range(3) ] # New labels: new_label = "Boxed %s to %s %s" % (str(tuple( self.gridding_first)), str(tuple( self.gridding_last)), self.basis_for_boxing_string) # Set up new map_manager. This will contain new data and not overwrite # original # NOTE: origin_shift_grid_units is required as bounds have changed new_map_manager = map_manager.customized_copy( map_data=map_box, origin_shift_grid_units=origin_shift_grid_units) if self._force_wrapping: # Set the wrapping of the new map if it is possible if (self._force_wrapping and (new_map_manager.is_full_size())) or \ ( (not self._force_wrapping) and (not new_map_manager.is_full_size())): new_map_manager.set_wrapping(self._force_wrapping) # Add the label new_map_manager.add_label(new_label) return new_map_manager
def __init__(self, map_manager, model, box_cushion, wrapping=None, force_cube=False, log=sys.stdout): self._map_manager = map_manager self._model = model self._force_wrapping = wrapping if wrapping is None: wrapping = self.map_manager().wrapping() self.basis_for_boxing_string = 'using_model, wrapping = %s' % ( wrapping) # safeguards assert isinstance(map_manager, iotbx.map_manager.map_manager) assert isinstance(model, mmtbx.model.manager) assert self._map_manager.map_data().accessor().origin() == (0, 0, 0) # Make sure working model and map_manager crystal_symmetry match assert map_manager.is_compatible_model(model) assert box_cushion >= 0 if self.map_manager().wrapping(): # map must be entire unit cell assert map_manager.unit_cell_grid == map_manager.map_data().all() # NOTE: We are going to use crystal_symmetry and sites_frac based on # the map_manager (the model could still have different crystal_symmetry) # get items needed to do the shift cs = map_manager.crystal_symmetry() uc = cs.unit_cell() sites_cart = model.get_sites_cart() sites_frac = uc.fractionalize(sites_cart) map_data = map_manager.map_data() # convert box_cushion into fractional vector cushion_frac = flex.double(uc.fractionalize((box_cushion, ) * 3)) # find fractional corners frac_min = sites_frac.min() frac_max = sites_frac.max() frac_max = list(flex.double(frac_max) + cushion_frac) frac_min = list(flex.double(frac_min) - cushion_frac) # find corner grid nodes all_orig = map_data.all() gridding_first = [ifloor(f * n) for f, n in zip(frac_min, all_orig)] gridding_last = [iceil(f * n) for f, n in zip(frac_max, all_orig)] # if forcing a cube, expand the box to be the size of the largest dimension if force_cube: # a simple adjustment of the gridding ranges to enforce a cube. # Note that this might fail if the molecule takes up a large fraction of a non-cube box # so that the smallest dimension cannot be enlarged enough to match the largest. # At the moment no checking occurs for this case # make data number arrays gr_first = np.array(gridding_first) gr_last = np.array(gridding_last) gr_range = gr_last - gr_first gr_diff = np.max( gr_range ) - gr_range # the difference between the three box dimensions and the largest dimension gr_padding = ( gr_diff / 2 ) # The space we would need to add to make all sides equal gr_first_pad = gr_first - gr_padding # The new target values for "gridding_first" gr_last_pad = gr_last + gr_padding # The new target values for "gridding_last" gr_range_pad = gr_last_pad - gr_first_pad # The new range, this should now all be equal and whole assert (np.all(gr_range_pad == gr_range_pad[0]) ) # assert the new box dims will all be the same gr_first_pad = np.floor(gr_first_pad).astype( int) # round the "gridding_first" values down to nearest int gr_last_pad = gr_first_pad + gr_range_pad.astype( int) # add the new grid range to the "gridding_first values self.gridding_first = list(gr_first_pad) self.gridding_last = list(gr_last_pad) else: self.gridding_first = gridding_first self.gridding_last = gridding_last # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() # Apply boxing to model, ncs, and map (if available) self.apply_to_model_ncs_and_map()
def __init__(self, map_manager, wrapping, threshold=0.05, get_half_height_width=True, log=sys.stdout): adopt_init_args(self, locals()) # safeguards assert threshold is not None assert isinstance(wrapping, bool) assert isinstance(map_manager, iotbx.map_manager.map_manager) assert self.map_manager.map_data().accessor().origin() == (0, 0, 0) if wrapping: assert map_manager.unit_cell_grid == map_manager.map_data().all() self.basis_for_boxing_string = 'around_density, wrapping=%s' % ( wrapping) # Select box where data are positive (> threshold*max) map_data = map_manager.map_data() origin = list(map_data.origin()) assert origin == [0, 0, 0] all = list(map_data.all()) # Get max value vs x,y,z value_list = flex.double() for i in range(0, all[0]): new_map_data = maptbx.copy(map_data, tuple((i, 0, 0)), tuple((i, all[1], all[2]))) value_list.append( new_map_data.as_1d().as_double().min_max_mean().max) ii = 0 for z in value_list: ii += 1 x_min, x_max = get_range(value_list, threshold=threshold, get_half_height_width=get_half_height_width) value_list = flex.double() for j in range(0, all[1]): new_map_data = maptbx.copy(map_data, tuple((0, j, 0)), tuple((all[0], j, all[2]))) value_list.append( new_map_data.as_1d().as_double().min_max_mean().max) y_min, y_max = get_range(value_list, threshold=threshold, get_half_height_width=get_half_height_width) value_list = flex.double() for j in range(0, all[1]): new_map_data = maptbx.copy(map_data, tuple((0, j, 0)), tuple((all[0], j, all[2]))) value_list.append( new_map_data.as_1d().as_double().min_max_mean().max) y_min, y_max = get_range(value_list, threshold=threshold, get_half_height_width=get_half_height_width) value_list = flex.double() for k in range(0, all[2]): new_map_data = maptbx.copy(map_data, tuple((0, 0, k)), tuple((all[0], all[1], k))) value_list.append( new_map_data.as_1d().as_double().min_max_mean().max) z_min, z_max = get_range(value_list, threshold=threshold, get_half_height_width=get_half_height_width) # Get lower and upper bounds of this region in grid units frac_min = (x_min, y_min, z_min) frac_max = (x_max, y_max, z_max) all_orig = map_data.all() self.gridding_first = [ ifloor(f * n) for f, n in zip(frac_min, all_orig) ] self.gridding_last = [iceil(f * n) for f, n in zip(frac_max, all_orig)] # Ready with gridding...set up shifts and box crystal_symmetry self.set_shifts_and_crystal_symmetry() # Apply to map_manager so that self.map_manager is boxed version self.map_manager = self.apply_to_map(self.map_manager)