예제 #1
0
def macro_cycle(xray_structure,
                target_map,
                geometry_restraints,
                max_iterations=50,
                expload=False,
                n_expload=1,
                log=None):
    if (not log):
        if (log is None): log = sys.stdout
    d_min = maptbx.d_min_from_map(map_data=target_map,
                                  unit_cell=xray_structure.unit_cell())
    all_selection = flex.bool(xray_structure.scatterers().size(), True)
    rsr_simple_refiner = individual_sites.simple(
        target_map=target_map,
        selection=all_selection,
        real_space_gradients_delta=d_min / 4,
        max_iterations=max_iterations,
        geometry_restraints_manager=geometry_restraints)
    xray_structure = shift_to_center_of_mass(xray_structure=xray_structure,
                                             target_map=target_map)
    cm = xray_structure.center_of_mass()
    sites_cart = xray_structure.sites_cart()
    sc = scorer(unit_cell=xray_structure.unit_cell(),
                sites_frac=xray_structure.sites_frac(),
                target_map=target_map,
                log=log)
    weights = flex.double()
    sampling_range = [0, 90, 180, 270]
    for the in sampling_range:
        for psi in sampling_range:
            for phi in sampling_range:
                sites_cart_new = apply_rigid_body_shift(sites_cart=sites_cart,
                                                        cm=cm,
                                                        x=0,
                                                        y=0,
                                                        z=0,
                                                        the=the,
                                                        psi=psi,
                                                        phi=phi)
                xray_structure = xray_structure.replace_sites_cart(
                    new_sites=sites_cart_new)
                w = run_refine(rsr_simple_refiner=rsr_simple_refiner,
                               xray_structure=xray_structure,
                               scorer=sc,
                               log=log,
                               weight=flex.mean_default(weights, 1.0))
                weights.append(w)
                if (expload):
                    for i in xrange(n_expload):
                        xray_structure_ = xray_structure.deep_copy_scatterers()
                        xray_structure_.shake_sites_in_place(mean_distance=1.0)
                        run_refine(rsr_simple_refiner=rsr_simple_refiner,
                                   xray_structure=xray_structure_,
                                   scorer=sc,
                                   log=log)
    if (log): print >> log, "Final target:", sc.target
    return xray_structure.replace_sites_frac(new_sites=sc.sites_frac_best)
예제 #2
0
def macro_cycle(
      xray_structure,
      target_map,
      geometry_restraints,
      max_iterations = 50,
      expload        = False,
      n_expload      = 1,
      log            = None):
  if(not log):
    if(log is None): log = sys.stdout
  d_min = maptbx.d_min_from_map(
      map_data  = target_map,
      unit_cell = xray_structure.unit_cell())
  all_selection = flex.bool(xray_structure.scatterers().size(),True)
  rsr_simple_refiner = individual_sites.simple(
    target_map                  = target_map,
    selection                   = all_selection,
    real_space_gradients_delta  = d_min/4,
    max_iterations              = max_iterations,
    geometry_restraints_manager = geometry_restraints)
  xray_structure = shift_to_center_of_mass(xray_structure=xray_structure,
    target_map=target_map)
  cm = xray_structure.center_of_mass()
  sites_cart = xray_structure.sites_cart()
  sc = scorer(
    unit_cell  = xray_structure.unit_cell(),
    sites_frac = xray_structure.sites_frac(),
    target_map = target_map,
    log        = log)
  weights = flex.double()
  sampling_range = [0, 90, 180, 270]
  for the in sampling_range:
    for psi in sampling_range:
      for phi in sampling_range:
        sites_cart_new = apply_rigid_body_shift(
          sites_cart=sites_cart,
          cm=cm, x=0,y=0,z=0, the=the, psi=psi, phi=phi)
        xray_structure = xray_structure.replace_sites_cart(
          new_sites=sites_cart_new)
        w = run_refine(
          rsr_simple_refiner = rsr_simple_refiner,
          xray_structure     = xray_structure,
          scorer             = sc,
          log                = log,
          weight             = flex.mean_default(weights, 1.0))
        weights.append(w)
        if(expload):
          for i in xrange(n_expload):
            xray_structure_ = xray_structure.deep_copy_scatterers()
            xray_structure_.shake_sites_in_place(mean_distance=1.0)
            run_refine(
              rsr_simple_refiner = rsr_simple_refiner,
              xray_structure     = xray_structure_,
              scorer             = sc,
              log                = log)
  if(log): print >> log, "Final target:", sc.target
  return xray_structure.replace_sites_frac(new_sites=sc.sites_frac_best)
예제 #3
0
def run(args,
        log=None,
        ccp4_map=None,
        return_as_miller_arrays=False,
        nohl=False,
        return_f_obs=False,
        space_group_number=None,
        out=sys.stdout):
    if log is None: log = out
    inputs = mmtbx.utils.process_command_line_args(
        args=args, master_params=master_params())
    got_map = False
    if ccp4_map: got_map = True
    broadcast(m="Parameters:", log=log)
    inputs.params.show(prefix="  ", out=out)
    params = inputs.params.extract()
    if (ccp4_map is None and inputs.ccp4_map is not None):
        broadcast(m="Processing input CCP4 map file: %s" %
                  inputs.ccp4_map_file_name,
                  log=log)
        ccp4_map = inputs.ccp4_map
        ccp4_map.show_summary(prefix="  ", out=out)
        got_map = True
    if (not got_map):
        raise Sorry("Map file is needed.")
    #
    m = ccp4_map
    if (m.space_group_number > 1):
        raise Sorry("Input map space group: %d. Must be P1." %
                    m.space_group_number)
    broadcast(m="Input map information:", log=log)
    print("m.all()   :", m.data.all(), file=out)
    print("m.focus() :", m.data.focus(), file=out)
    print("m.origin():", m.data.origin(), file=out)
    print("m.nd()    :", m.data.nd(), file=out)
    print("m.size()  :", m.data.size(), file=out)
    print("m.focus_size_1d():", m.data.focus_size_1d(), file=out)
    print("m.is_0_based()   :", m.data.is_0_based(), file=out)
    print("map: min/max/mean:",
          flex.min(m.data),
          flex.max(m.data),
          flex.mean(m.data),
          file=out)
    print("unit cell:", m.unit_cell_parameters, file=out)
    #
    if not space_group_number:
        space_group_number = 1
    if space_group_number <= 1:
        symmetry_flags = None
    else:
        symmetry_flags = maptbx.use_space_group_symmetry,

    #cs = crystal.symmetry(m.unit_cell_parameters, space_group_number)
    # this will not work if m.unit_cell_grid != m.data.all()

    # Instead use ccp4 map crystal_symmetry and classify according to the case
    cs = m.crystal_symmetry()

    if m.unit_cell_grid == m.data.all():
        print("\nOne unit cell of data is present in map", file=out)
    else:
        if params.keep_origin:
            print("\nNOTE: This map does not have exactly one unit cell of data, so \n"+\
              "keep_origin is not available\n", file=out)
            print(
                "--> Setting keep_origin=False and creating a new cell and gridding.\n",
                file=out)
            params.keep_origin = False
        print("Moving origin of input map to (0,0,0)", file=out)
        print("New cell will be: (%.3f, %.3f, %.3f, %.1f, %.1f, %.1f) A " %
              (cs.unit_cell().parameters()),
              file=out)
        print("New unit cell grid will be: (%s, %s, %s) " % (m.data.all()),
              file=out)

    map_data = m.data

    # Get origin in grid units and new position of origin in grid units
    original_origin = map_data.origin()
    print("\nInput map has origin at grid point (%s,%s,%s)" %
          (tuple(original_origin)),
          file=out)

    if params.output_origin_grid_units is not None:
        params.keep_origin = False
        new_origin = tuple(params.output_origin_grid_units)
        print("User-specified origin at grid point (%s,%s,%s)" %
              (tuple(params.output_origin_grid_units)),
              file=out)
        if tuple(params.output_origin_grid_units) == tuple(original_origin):
            print("This is the same as the input origin. No origin shift.",
                  file=out)
    elif params.keep_origin:
        new_origin = original_origin
        print("Keeping origin at grid point  (%s,%s,%s)" %
              (tuple(original_origin)),
              file=out)
    else:
        new_origin = (
            0,
            0,
            0,
        )
        print("New origin at grid point (%s,%s,%s)" % (tuple((
            0,
            0,
            0,
        ))),
              file=out)

    # shift_cart is shift away from (0,0,0)
    if new_origin != (
            0,
            0,
            0,
    ):
        shift_cart = get_shift_cart(map_data=map_data,
                                    crystal_symmetry=cs,
                                    origin=new_origin)
    else:
        shift_cart = (
            0,
            0,
            0,
        )

    map_data = maptbx.shift_origin_if_needed(map_data=map_data).map_data
    # generate complete set of Miller indices up to given high resolution d_min
    n_real = map_data.focus()
    crystal_gridding = maptbx.crystal_gridding(
        unit_cell=cs.unit_cell(),
        space_group_info=cs.space_group_info(),
        symmetry_flags=symmetry_flags,
        pre_determined_n_real=n_real)
    #
    d_min = params.d_min
    if (d_min is None and not params.box):
        d_min = maptbx.d_min_from_map(
            map_data=map_data,
            unit_cell=cs.unit_cell(),
            resolution_factor=params.resolution_factor)
        print("\nResolution of map coefficients using "+\
           "resolution_factor of %.2f: %.1f A\n" %(params.resolution_factor,d_min), file=out)
    if (d_min is None):
        # box of reflections in |h|<N1/2, |k|<N2/2, 0<=|l|<N3/2
        f_obs_cmpl = miller.structure_factor_box_from_map(
            map=map_data.as_double(), crystal_symmetry=cs, include_000=True)
    else:
        complete_set = miller.build_set(crystal_symmetry=cs,
                                        anomalous_flag=False,
                                        d_min=d_min)
        try:
            f_obs_cmpl = complete_set.structure_factors_from_map(
                map=map_data.as_double(),
                use_scale=True,
                anomalous_flag=False,
                use_sg=False)
        except Exception as e:
            if (str(e) ==
                    "cctbx Error: Miller index not in structure factor map."):
                msg = "Too high resolution requested. Try running with larger d_min."
                raise Sorry(msg)
            else:
                raise Sorry(str(e))

    if params.scale_max is not None:
        f_obs_cmpl = f_obs_cmpl.apply_scaling(target_max=params.scale_max)

    from scitbx.matrix import col
    if col(shift_cart) != col((
            0,
            0,
            0,
    )):
        print("Output origin is at: (%.3f, %.3f, %.3f) A " %
              (tuple(-col(shift_cart))),
              file=out)
        f_obs_cmpl = f_obs_cmpl.translational_shift(
            cs.unit_cell().fractionalize(-col(shift_cart)), deg=False)
    else:
        print("Output origin is at (0.000, 0.000, 0.000) A", file=out)

    if nohl and return_as_miller_arrays and not return_f_obs:
        return f_obs_cmpl

    mtz_dataset = f_obs_cmpl.as_mtz_dataset(column_root_label="F")
    f_obs = abs(f_obs_cmpl)
    f_obs.set_sigmas(sigmas=flex.double(f_obs_cmpl.data().size(), 1))
    if nohl and return_as_miller_arrays and return_f_obs:
        return f_obs
    mtz_dataset.add_miller_array(miller_array=f_obs, column_root_label="F-obs")
    mtz_dataset.add_miller_array(miller_array=f_obs.generate_r_free_flags(),
                                 column_root_label="R-free-flags")
    if not nohl:
        # convert phases into HL coefficeints
        broadcast(m="Convert phases into HL coefficients:", log=log)
        hl = get_hl(f_obs_cmpl=f_obs_cmpl,
                    k_blur=params.k_blur,
                    b_blur=params.b_blur)
        cc = get_cc(f=f_obs_cmpl, hl=hl)
        print("cc:", cc, file=out)
        if (abs(1. - cc) > 1.e-3):
            print(
                "Supplied b_blur is not good. Attempting to find optimal b_blur.",
                file=out)
            cc_best = 999.
            b_blur_best = params.b_blur
            for b_blur in range(1, 100):
                hl = get_hl(f_obs_cmpl=f_obs_cmpl,
                            k_blur=params.k_blur,
                            b_blur=b_blur)
                cc = get_cc(f=f_obs_cmpl, hl=hl)
                if (cc < cc_best):
                    cc_best = cc
                    b_blur_best = b_blur
                if (abs(1. - cc) < 1.e-3):
                    b_blur_best = b_blur
                    break
            hl = get_hl(f_obs_cmpl=f_obs_cmpl,
                        k_blur=params.k_blur,
                        b_blur=b_blur_best)
            print("cc:", get_cc(f=f_obs_cmpl, hl=hl), file=out)
            print("b_blur_best:", b_blur_best, file=out)
        mtz_dataset.add_miller_array(miller_array=hl, column_root_label="HL")
    else:
        hl = None
    if return_as_miller_arrays:
        if return_f_obs:
            return f_obs, hl
        else:
            return f_obs_cmpl, hl
    else:
        # write output MTZ file with all the data
        broadcast(m="Writing output MTZ file:", log=log)
        print("  file name:", params.output_file_name, file=log)
        mtz_object = mtz_dataset.mtz_object()
        mtz_object.write(file_name=params.output_file_name)
def run(args,
        log=None,
        ccp4_map=None,
        return_as_miller_arrays=False,
        nohl=False,
        return_f_obs=False,
        space_group_number=None,
        out=sys.stdout):
    if log is None: log = out
    inputs = mmtbx.utils.process_command_line_args(
        args=args, master_params=master_params())
    got_map = False
    if ccp4_map: got_map = True
    broadcast(m="Parameters:", log=log)
    inputs.params.show(prefix="  ", out=out)
    params = inputs.params.extract()
    if (ccp4_map is None and inputs.ccp4_map is not None):
        broadcast(m="Processing input CCP4 map file: %s" %
                  inputs.ccp4_map_file_name,
                  log=log)
        ccp4_map = inputs.ccp4_map
        ccp4_map.show_summary(prefix="  ", out=out)
        got_map = True
    if (not got_map):
        raise Sorry("Map file is needed.")
    #
    m = ccp4_map
    if (m.space_group_number > 1):
        raise Sorry("Input map space group: %d. Must be P1." %
                    m.space_group_number)
    broadcast(m="Input map information:", log=log)
    print >> out, "m.all()   :", m.data.all()
    print >> out, "m.focus() :", m.data.focus()
    print >> out, "m.origin():", m.data.origin()
    print >> out, "m.nd()    :", m.data.nd()
    print >> out, "m.size()  :", m.data.size()
    print >> out, "m.focus_size_1d():", m.data.focus_size_1d()
    print >> out, "m.is_0_based()   :", m.data.is_0_based()
    print >> out, "map: min/max/mean:", flex.min(m.data), flex.max(
        m.data), flex.mean(m.data)
    print >> out, "unit cell:", m.unit_cell_parameters
    #
    if not space_group_number:
        space_group_number = 1
    if space_group_number <= 1:
        symmetry_flags = None
    else:
        symmetry_flags = maptbx.use_space_group_symmetry,

    cs = crystal.symmetry(m.unit_cell_parameters, space_group_number)
    map_data = m.data

    # Get origin in grid units and new position of origin in grid units
    original_origin = map_data.origin()
    print >> out, "Input map has origin at grid point (%s,%s,%s)" % (
        tuple(original_origin))

    if params.output_origin_grid_units is not None:
        params.keep_origin = False
        new_origin = tuple(params.output_origin_grid_units)
        print >> out, "User-specified origin at grid point (%s,%s,%s)" % (
            tuple(params.output_origin_grid_units))
        if tuple(params.output_origin_grid_units) == tuple(original_origin):
            print >> out, "This is the same as the input origin. No origin shift."
    elif params.keep_origin:
        new_origin = original_origin
        print >> out, "Keeping origin at grid point  (%s,%s,%s)" % (
            tuple(original_origin))
    else:
        new_origin = (
            0,
            0,
            0,
        )
        print >> out, "New origin at grid point (%s,%s,%s)" % (tuple((
            0,
            0,
            0,
        )))

    # shift_cart is shift away from (0,0,0)
    if new_origin != (
            0,
            0,
            0,
    ):
        shift_cart = get_shift_cart(map_data=map_data,
                                    crystal_symmetry=cs,
                                    origin=new_origin)
    else:
        shift_cart = (
            0,
            0,
            0,
        )

    map_data = maptbx.shift_origin_if_needed(map_data=map_data).map_data
    # generate complete set of Miller indices up to given high resolution d_min
    n_real = map_data.focus()
    crystal_gridding = maptbx.crystal_gridding(
        unit_cell=cs.unit_cell(),
        space_group_info=cs.space_group_info(),
        symmetry_flags=symmetry_flags,
        pre_determined_n_real=n_real)
    #
    d_min = params.d_min
    if (d_min is None and not params.box):
        d_min = maptbx.d_min_from_map(map_data=map_data,
                                      unit_cell=cs.unit_cell())
    if (d_min is None):
        # box of reflections in |h|<N1/2, |k|<N2/2, 0<=|l|<N3/2
        f_obs_cmpl = miller.structure_factor_box_from_map(
            map=map_data.as_double(), crystal_symmetry=cs, include_000=True)
    else:
        complete_set = miller.build_set(crystal_symmetry=cs,
                                        anomalous_flag=False,
                                        d_min=d_min)
        try:
            f_obs_cmpl = complete_set.structure_factors_from_map(
                map=map_data.as_double(),
                use_scale=True,
                anomalous_flag=False,
                use_sg=False)
        except Exception, e:
            if (str(e) ==
                    "cctbx Error: Miller index not in structure factor map."):
                msg = "Too high resolution requested. Try running with larger d_min."
                raise Sorry(msg)
            else:
                raise Sorry(str(e))
예제 #5
0
    def __init__(self,
                 map_manager=None,
                 resolution=None,
                 buffer_radius=5,
                 minimum_fraction_of_max=0.01):
        '''
     Create a mask (map object) with values of 1 expanded by buffer_radius

     Parameters are:
       map_manager: source of previous mask.
       resolution : optional resolution of map
       buffer_radius:  radius to expand in A
       minimum_fraction_of_max: smallest-sized region to expand
         as ratio to biggest
    '''

        assert (map_manager is not None)

        if not resolution:
            from cctbx.maptbx import d_min_from_map
            resolution = d_min_from_map(
                map_data=map_manager.map_data(),
                unit_cell=map_manager.crystal_symmetry().unit_cell())

        self._crystal_symmetry = map_manager.crystal_symmetry()

        from cctbx.maptbx.segment_and_split_map import estimate_expand_size, get_co

        expand_size = estimate_expand_size(
            crystal_symmetry=map_manager.crystal_symmetry(),
            map_data=map_manager.map_data(),
            expand_target=buffer_radius,
            minimum_expand_size=0,
            out=null_out())

        if expand_size < 1:
            return  # do nothing
        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:
            return  # do nothing

        minimum_size = sorted_by_volume[1][0] * minimum_fraction_of_max
        s = None
        for v1, i1 in sorted_by_volume[1:]:
            if v1 < minimum_size: break
            bool_region_mask = co.expand_mask(id_to_expand=i1,
                                              expand_size=expand_size)
            if s is None:
                s = (bool_region_mask == True)
            else:
                s |= (bool_region_mask == True)
        self._mask = map_manager.deep_copy().map_data()
        self._mask.set_selected(s, 1)
        self._mask.set_selected(~s, 0)

        self._solvent_content = s.count(False) / s.size()

        # Set up map_manager with this mask
        self._map_manager = map_manager.customized_copy(map_data=self._mask)
        self._map_manager.set_is_mask(True)

        # Initialize soft mask
        self._is_soft_mask = False
        self._is_soft_mask_around_edges = False
예제 #6
0
    def __init__(self,
                 map_manager=None,
                 resolution=None,
                 molecular_mass=None,
                 sequence=None,
                 solvent_content=None):
        '''
     Create a mask (map object) with values of 1 near molecule

     Parameters are:
       map_manager: source of information about density
       resolution : optional resolution of map
       molecular_mass: optional mass (Da) of object in density
       sequence: optional sequence of object in density
       solvent_content : optional solvent_content of map
    '''

        assert (map_manager is not None)

        if not resolution:
            from cctbx.maptbx import d_min_from_map
            resolution = d_min_from_map(
                map_data=map_manager.map_data(),
                unit_cell=map_manager.crystal_symmetry().unit_cell())

        self._crystal_symmetry = map_manager.crystal_symmetry()

        if (molecular_mass or sequence) and (not solvent_content):
            # Try to get a good starting value of solvent_content

            from cctbx.maptbx.segment_and_split_map import get_solvent_fraction
            solvent_content = get_solvent_fraction(
                params=None,
                molecular_mass=molecular_mass,
                sequence=sequence,
                do_not_adjust_dalton_scale=True,
                crystal_symmetry=self._crystal_symmetry,
                out=null_out())

        # Now use automatic procedure to get a mask
        from cctbx.maptbx.segment_and_split_map import \
              get_iterated_solvent_fraction
        self._mask, self._solvent_content = get_iterated_solvent_fraction(
            crystal_symmetry=self._crystal_symmetry,
            fraction_of_max_mask_threshold=0.05,  #
            solvent_content=solvent_content,
            cell_cutoff_for_solvent_from_mask=1,  # Use low-res method always
            use_solvent_content_for_threshold=True,
            mask_resolution=resolution,
            return_mask_and_solvent_fraction=True,
            map=map_manager.map_data(),
            verbose=False,
            out=null_out())

        if self._solvent_content is None:
            from libtbx.utils import Sorry
            raise Sorry("Unable to get solvent content in auto-masking")

        # Set up map_manager with this mask
        self._map_manager = map_manager.customized_copy(map_data=self._mask)
        self._map_manager.set_is_mask(True)

        # Initialize soft mask
        self._is_soft_mask = False
        self._is_soft_mask_around_edges = False
예제 #7
0
def run(args,
        crystal_symmetry=None,
        ncs_object=None,
        pdb_hierarchy=None,
        map_data=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
    inputs = mmtbx.utils.process_command_line_args(args=args,
                                                   cmd_cs=crystal_symmetry,
                                                   master_params=master_phil)
    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 pdb_hierarchy and not params.keep_map_size
            and not params.upper_bounds and not params.extract_unique):
        raise Sorry("PDB file is needed unless extract_unique, " +
                    "density_select, keep_map_size \nor bounds are set .")
    if (len(inputs.pdb_file_names)!=1 and not pdb_hierarchy and \
         (params.mask_atoms or params.soft_mask )):
        raise Sorry("PDB file is needed for mask_atoms or soft_mask")
    if (params.density_select and params.keep_map_size):
        raise Sorry("Cannot set both density_select and keep_map_size")
    if (params.density_select and params.upper_bounds):
        raise Sorry("Cannot set both density_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 and not params.resolution):
        raise Sorry("Please set resolution for extract_unique")
    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
    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()
            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 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)
    #
    selection = pdb_hierarchy.atom_selection_cache().selection(
        string=params.selection)
    if selection.size():
        print_statistics.make_sub_header("atom selection", out=log)
        print >> log, "Selection string: selection='%s'" % params.selection
        print >> log, \
            "  selects %d atoms from total %d atoms."%(selection.count(True),
            selection.size())
    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 >> log, "Total of %s operators read" % (
                ncs_object.max_operators())
    if not ncs_object or ncs_object.max_operators() < 1:
        print >> log, "No symmetry available"
    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:
        if params.sequence_file:
            if n_ops > 1:  # get unique part of sequence and multiply
                remove_duplicates = True
            else:
                remove_duplicates = False
            from iotbx.bioinformatics import get_sequences
            sequence = n_ops * (" ".join(
                get_sequences(file_name=params.sequence_file,
                              remove_duplicates=remove_duplicates)))

        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_protein * 110 + (n_rna + n_dna) * 330
        elif not params.molecular_mass:
            raise Sorry(
                "Need a sequence file or molecular mass for extract_unique")
    else:
        molecular_mass = None
#
    if params.density_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 >> log, "\nValue outside atoms mask will be set to mean inside mask"
    if params.get_half_height_width and params.density_select:
        print >> log, "\nHalf width at half height will be used to id boundaries"
    if params.soft_mask and sites_cart_all.size() > 0:
        print >> log, "\nSoft mask will be applied to model-based mask"
    if params.keep_map_size:
        print >> log, "\nEntire map will be kept (not cutting out region)"
    if params.restrict_map_size:
        print >> log, "\nOutput map will be within input map"
    if params.lower_bounds and params.upper_bounds:
        print >> log, "Bounds for cut out map are (%s,%s,%s) to (%s,%s,%s)" % (
            tuple(list(params.lower_bounds) + list(params.upper_bounds)))

    box = mmtbx.utils.extract_box_around_model_and_map(
        xray_structure=xray_structure,
        map_data=map_data.as_double(),
        box_cushion=params.box_cushion,
        selection=selection,
        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,
        extract_unique=params.extract_unique,
        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,
    )

    ph_box = pdb_hierarchy.select(selection)
    ph_box.adopt_xray_structure(box.xray_structure_box)
    box.hierarchy = ph_box

    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 >> log, "\nNOTE: Mismatch of unit cell parameters from CCP4 map:"
        print >>log,"Unit cell from CCP4 map 'unit cell parameters': "+\
          "%.1f, %.1f, %.1f, %.1f, %.1f, %.1f)" %tuple(
            inputs.ccp4_map.unit_cell_parameters)
        print >>log,"Unit cell from CCP4 map 'map grid':             "+\
          "%.1f, %.1f, %.1f, %.1f, %.1f, %.1f)" %tuple(
           inputs.crystal_symmetry.unit_cell().parameters())
        print >>log,"\nInterpreting this as the 'unit cell parameters' was "+\
          "original map \ndimension and 'map grid' is the "+\
          "portion actually in the map that was supplied here.\n"
        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

    # ncs_object is original
    #  box.ncs_object is shifted by shift_cart

    print >> log, "Box cell dimensions: (%.2f, %.2f, %.2f) A" % (
        box.box_crystal_symmetry.unit_cell().parameters()[:3])
    if params.keep_origin:
        print >> log, "Box origin is at grid position of : (%d, %d, %d) " % (
            tuple(box.origin_shift_grid_units(reverse=True)))
        print >> log, "Box origin is at coordinates: (%.2f, %.2f, %.2f) A" % (
            tuple(-col(box.shift_cart)))

    if box.pdb_outside_box_msg:
        print >> log, box.pdb_outside_box_msg

    # NOTE: box object is always shifted to place origin at (0,0,0)

    # For output files ONLY:
    #   keep_origin==False leave origin at (0,0,0)
    #  keep_origin==True: we shift everything back to where it was,

    if (not params.keep_origin):
        if box.shift_cart:
            print >>log,\
              "Final coordinate shift for output files: (%.2f,%.2f,%.2f) A" %(
              tuple(box.shift_cart))
        else:
            print >>log,"\nOutput files are in same location as original: origin "+\
              "is at (0,0,0)"
    else:  # keep_origin
        print >> log, "\nOutput files are in same location as original, just cut out."
        print >> log, "Note that output maps are only valid in the cut out region.\n"

    if params.keep_origin:
        ph_box_original_location = ph_box.deep_copy()
        sites_cart = box.shift_sites_cart_back(
            box.xray_structure_box.sites_cart())
        xrs_offset = ph_box_original_location.extract_xray_structure(
            crystal_symmetry=box.xray_structure_box.crystal_symmetry(
            )).replace_sites_cart(new_sites=sites_cart)
        ph_box_original_location.adopt_xray_structure(xrs_offset)
        box.hierarchy_original_location = ph_box_original_location
    else:
        box.hierarchy_original_location = None

    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

            if params.keep_origin:  # Keeping origin
                print >> log, "Writing boxed PDB with box unit cell and in "+\
                  "original\n    position to:   %s"%(
                  file_name)
                ph_box_original_location.write_pdb_file(
                    file_name=file_name,
                    crystal_symmetry=box.xray_structure_box.crystal_symmetry())

            else:  # write box PDB in box cell
                print >> log, "Writing shifted boxed PDB to file:   %s" % file_name
                ph_box.write_pdb_file(
                    file_name=file_name,
                    crystal_symmetry=box.xray_structure_box.crystal_symmetry())

        # Write NCS file if NCS
        if ncs_object and 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

            if params.keep_origin:
                if params.symmetry_file:
                    print >> log, "\nDuplicating symmetry in %s and writing to %s" % (
                        params.symmetry_file, output_symmetry_file)
                else:
                    print >> log, "\nWriting symmetry to %s" % (
                        output_symmetry_file)
                ncs_object.format_all_for_group_specification(
                    file_name=output_symmetry_file)

            else:
                print >> log, "\nOffsetting symmetry in %s and writing to %s" % (
                    params.symmetry_file, output_symmetry_file)
                box.ncs_object.format_all_for_group_specification(
                    file_name=output_symmetry_file)

        # Write ccp4 map.  Shift back to original location if keep_origin=True
        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

            if params.keep_origin:
                print >> log, "Writing boxed map with box unit_cell and "+\
                   "original\n    position to CCP4 formatted file:   %s"%file_name
            else:
                print >> log, "Writing box map shifted to (0,0,0) to CCP4 "+\
                   "formatted file:   %s"%file_name

            box.write_ccp4_map(file_name=file_name,
                               shift_back=params.keep_origin)

        # 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
            if params.keep_origin:
                print >> log, "Writing boxed map with box unit_cell and original "+\
                  "position\n    to X-plor formatted file: %s"%file_name
            else:
                print >> log, "Writing box_map shifted to (0,0,0) to X-plor "+\
                  "formatted file: %s"%file_name
            box.write_xplor_map(file_name=file_name,
                                shift_back=params.keep_origin)

        # 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

            if params.keep_origin:
                print >> log, "Writing map coefficients with box_map unit_cell"+\
                  " but position matching\n   "+\
                  " original position to MTZ file: %s"%file_name
            else:
                print >> log, "Writing box_map coefficients shifted to (0,0,0) "+\
                   "to MTZ file: %s"%file_name
            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=box.map_box,
                    unit_cell=box.xray_structure_box.unit_cell())
            box.map_coefficients(d_min=d_min,
                                 resolution_factor=params.resolution_factor,
                                 file_name=file_name,
                                 shift_back=params.keep_origin)

    print >> log
    return box
예제 #8
0
def run(args, crystal_symmetry=None,
     ncs_object=None,
     pdb_hierarchy=None,
     map_data=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
  inputs = mmtbx.utils.process_command_line_args(args = args,
    cmd_cs=crystal_symmetry,
    master_params = master_phil)
  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
    pdb_hierarchy and not params.keep_map_size and not params.upper_bounds
     and not params.extract_unique):
    raise Sorry("PDB file is needed unless extract_unique, "+
      "density_select, keep_map_size \nor bounds are set .")
  if (len(inputs.pdb_file_names)!=1 and not pdb_hierarchy and \
       (params.mask_atoms or params.soft_mask )):
    raise Sorry("PDB file is needed for mask_atoms or soft_mask")
  if (params.density_select and params.keep_map_size):
    raise Sorry("Cannot set both density_select and keep_map_size")
  if (params.density_select and params.upper_bounds):
    raise Sorry("Cannot set both density_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 and not params.resolution):
    raise Sorry("Please set resolution for extract_unique")
  if (write_output_files) and ("mtz" in params.output_format) and (
       (params.keep_origin) and (not params.keep_map_size)):
    raise Sorry("Please set output_format=ccp4 to skip mtz or set "+\
      "keep_origin=False or keep_map_size=True")

  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 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
  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

      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.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)
  #
  selection = pdb_hierarchy.atom_selection_cache().selection(
    string = params.selection)
  if selection.size():
    print_statistics.make_sub_header("atom selection", out=log)
    print >> log, "Selection string: selection='%s'"%params.selection
    print >> log, \
        "  selects %d atoms from total %d atoms."%(selection.count(True),
        selection.size())
  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 >>log,"Total of %s operators read" %(ncs_object.max_operators())
  if not ncs_object or ncs_object.max_operators()<1:
      print >>log,"No symmetry available"
  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:
    if params.sequence_file:
      if n_ops > 1: # get unique part of sequence and multiply
        remove_duplicates=True
      else:
        remove_duplicates=False
      from iotbx.bioinformatics import get_sequences
      sequence=n_ops * (" ".join(get_sequences(file_name=params.sequence_file,
        remove_duplicates=remove_duplicates)))

    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_protein*110+(n_rna+n_dna)*330
    elif not params.molecular_mass:
      raise Sorry("Need a sequence file or molecular mass for extract_unique")
  else:
    molecular_mass=None
#
  if params.density_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 >>log,"\nValue outside atoms mask will be set to mean inside mask"
  if params.get_half_height_width and params.density_select:
    print >>log,"\nHalf width at half height will be used to id boundaries"
  if params.soft_mask and sites_cart_all.size()>0:
    print >>log,"\nSoft mask will be applied to model-based mask"
  if params.keep_map_size:
    print >>log,"\nEntire map will be kept (not cutting out region)"
  if params.restrict_map_size:
    print >>log,"\nOutput map will be within input map"
  if params.lower_bounds and params.upper_bounds:
    print >>log,"Bounds for cut out map are (%s,%s,%s) to (%s,%s,%s)" %(
     tuple(list(params.lower_bounds)+list(params.upper_bounds)))

  box = mmtbx.utils.extract_box_around_model_and_map(
    xray_structure   = xray_structure,
    map_data         = map_data.as_double(),
    box_cushion      = params.box_cushion,
    selection        = selection,
    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,
    extract_unique        = params.extract_unique,
    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,

    )

  ph_box = pdb_hierarchy.select(selection)
  ph_box.adopt_xray_structure(box.xray_structure_box)
  box.hierarchy=ph_box

  if (inputs and  # XXX fix or remove this
    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 >>log,"\nNOTE: Mismatch of unit cell parameters from CCP4 map:"
    print >>log,"Unit cell from CCP4 map 'unit cell parameters': "+\
      "%.1f, %.1f, %.1f, %.1f, %.1f, %.1f)" %tuple(
        inputs.ccp4_map.unit_cell_parameters)
    print >>log,"Unit cell from CCP4 map 'map grid':             "+\
      "%.1f, %.1f, %.1f, %.1f, %.1f, %.1f)" %tuple(
       inputs.crystal_symmetry.unit_cell().parameters())
    print >>log,"\nInterpreting this as the 'unit cell parameters' was "+\
      "original map \ndimension and 'map grid' is the "+\
      "portion actually in the map that was supplied here.\n"
    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 >> log, box.pdb_outside_box_msg

  # 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 >>log,"\nBox cell dimensions: (%.2f, %.2f, %.2f) A" %(
      box.box_crystal_symmetry.unit_cell().parameters()[:3])
  if box.shift_cart:
     print>>log,"Working origin moved from grid position of"+\
        ": (%d, %d, %d) to (0,0,0) " %(
        tuple(box.origin_shift_grid_units(reverse=True)))
     print>>log,"Working origin moved from  coordinates of:"+\
        " (%.2f, %.2f, %.2f) A to (0,0,0)\n" %(
         tuple(-col(box.shift_cart)))

  if (params.keep_origin):
    print >>log,"\nRestoring original position for output files"
    print >>log,"Origin will be at grid position of"+\
        ": (%d, %d, %d) " %(
        tuple(box.origin_shift_grid_units(reverse=True)))
    print >>log,\
       "\nOutput files will be in same location as original",
    if not params.keep_map_size:
      print >>log,"just cut out."
    else:
      print >>log,"keeping entire map"
    print >>log,"Note that output maps are only valid in the cut out region.\n"

  else:
    if origin_to_match:
      output_box.shift_cart=shift_cart_for_origin_to_match
      if params.output_origin_grid_units:
        print >>log,"Output map origin to be shifted to match target"
      print >>log, "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)))
    elif box.shift_cart:
      output_box.shift_cart=(0,0,0) # not shifting back
      print >>log,"Final origin will be at (0,0,0)"
      print >>log,\
        "Final coordinate shift for output files: (%.2f,%.2f,%.2f) A\n" %(
        tuple(col(output_box.shift_cart)-col(box.shift_cart)))
    else:
      print >>log,\
       "\nOutput files are in same location as original and origin "+\
        "is at (0,0,0)\n"

  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 >>log,"Setting output unit cell parameters and unit cell grid to"+\
      " match\ninput map file"

  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 >>log,\
       "Output unit cell set to: %.2f, %.2f, %.2f, %.2f, %.2f, %.2f)" %tuple(
        output_crystal_symmetry.unit_cell().parameters())
  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 >>log,\
       "Output unit cell grid set to: (%s, %s, %s)" %tuple(
        output_unit_cell_grid)

    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 >>log,"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))
    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 >>log, \
      "Output unit cell will be:  (%.2f, %.2f, %.2f, %.2f, %.2f, %.2f)\n"%(
       tuple(output_crystal_symmetry.unit_cell().parameters()))

  else:
    output_unit_cell_grid = map_data=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 >> log, "Writing boxed PDB with box unit cell to %s" %(
          file_name)

    # 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 >>log,"\nWriting symmetry to %s" %( output_symmetry_file)

    # 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
     output_box.write_ccp4_map(file_name=file_name,
       output_crystal_symmetry=output_crystal_symmetry,
       output_unit_cell_grid=output_unit_cell_grid,
       shift_back=shift_back)
     print >> log, "Writing boxed map "+\
          "to CCP4 formatted file:   %s"%file_name

    # 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 >> log, "Writing boxed map "+\
         "to X-plor formatted file: %s"%file_name

    # 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 >> log, "Writing map coefficients "+\
         "to MTZ file: %s"%file_name
     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,
       resolution_factor=params.resolution_factor, file_name=file_name,
       shift_back=shift_back)

  print >> log
  return box
예제 #9
0
def calculate_inverse_fft(map_data=None,
                          crystal_symmetry=None,
                          d_min=None,
                          box=False,
                          resolution_factor=0.333,
                          out=sys.stdout):
    '''
    Combines two possible methods of generating the complete set of
      indices.  Box means supply all possible reflections that can be
      calculated using the gridding in map_data in the FFT.
      Otherwise, generate Miller indices inside a sphere of resolution.
      This may be faster if the box is large and most indices in the box
      are not going to be used.
    If box=True, supply full box of reflections (all possible)
    Otherwise, generate complete set of Miller indices up to
     given high resolution d_min. If d_min not specified,
     use minimum resolution allowed with gridding available and
     requested resolution_factor (1/2 is finest available, 1/3 is typical)
  '''

    n_real = map_data.focus()

    # Choose d_min and make sure it is bigger than smallest allowed

    if (d_min is None and not box):
        d_min = maptbx.d_min_from_map(map_data=map_data,
                                      unit_cell=crystal_symmetry.unit_cell(),
                                      resolution_factor=resolution_factor)
        print("\nResolution of map coefficients using "+\
         "resolution_factor of %.2f: %.1f A\n" %(resolution_factor,d_min), file=out)
    elif (not box):  # make sure d_min is big enough
        d_min_allowed = maptbx.d_min_from_map(
            map_data=map_data,
            unit_cell=crystal_symmetry.unit_cell(),
            resolution_factor=0.5)
        if d_min < d_min_allowed:
            print(
                "\nResolution of map coefficients allowed by gridding is %.3f "
                % (d_min_allowed),
                file=out)
            d_min = d_min_allowed

    if (d_min is None):
        # box of reflections in |h|<N1/2, |k|<N2/2, 0<=|l|<N3/2
        f_obs_cmpl = miller.structure_factor_box_from_map(
            map=map_data.as_double(),
            crystal_symmetry=crystal_symmetry,
            include_000=True)
    else:
        complete_set = miller.build_set(crystal_symmetry=crystal_symmetry,
                                        anomalous_flag=False,
                                        d_min=d_min)
        try:
            f_obs_cmpl = complete_set.structure_factors_from_map(
                map=map_data.as_double(),
                use_scale=True,
                anomalous_flag=False,
                use_sg=False)
        except Exception as e:
            if (str(e) ==
                    "cctbx Error: Miller index not in structure factor map."):
                msg = "Too high resolution requested. Try running with larger d_min."
                raise Sorry(msg)
            else:
                raise Sorry(str(e))
    return f_obs_cmpl
예제 #10
0
def run(args, crystal_symmetry=None, 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):
    print default_message
    master_phil.show(prefix="  ")
    return
  inputs = mmtbx.utils.process_command_line_args(args = args,
    cmd_cs=crystal_symmetry,
    master_params = master_phil)
  params = inputs.params.extract()
  # PDB file
  if params.pdb_file and not inputs.pdb_file_names:
    inputs.pdb_file_names=[params.pdb_file]
  if(len(inputs.pdb_file_names)!=1 and not params.density_select):
    raise Sorry("PDB file is needed unless density_select 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()
    pdb_atoms = pdb_hierarchy.atoms()
    pdb_atoms.reset_i_seq()
  else:
    pdb_hierarchy=None
  # Map or map coefficients
  map_coeff = None
  if(inputs.ccp4_map is None):
    if(len(inputs.reflection_file_names)!=1):
      raise Sorry("Map or map coefficients file is needed.")
    map_coeff = reflection_file_utils.extract_miller_array_from_file(
      file_name = inputs.reflection_file_names[0],
      label     = params.label,
      type      = "complex",
      log       = log)
    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])
  else:
    print_statistics.make_sub_header("CCP4 map", out=log)
    ccp4_map = inputs.ccp4_map
    ccp4_map.show_summary(prefix="  ")
    map_data = ccp4_map.map_data()
    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])
  #
  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)
  #
  selection = pdb_hierarchy.atom_selection_cache().selection(
    string = params.selection)
  if selection.size():
    print_statistics.make_sub_header("atom selection", out=log)
    print >> log, "Selection string: selection='%s'"%params.selection
    print >> log, \
        "  selects %d atoms from total %d atoms."%(selection.count(True),
        selection.size())
  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 params.density_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)
  #
  box = mmtbx.utils.extract_box_around_model_and_map(
    xray_structure   = xray_structure,
    map_data         = map_data.as_double(),
    box_cushion      = params.box_cushion,
    selection        = selection,
    density_select   = params.density_select,
    threshold        = params.density_select_threshold)

  if box.initial_shift_cart:
    print >>log,"\nInitial coordinate shift will be (%.1f,%.1f,%.1f)\n" %(
     box.initial_shift_cart)
  if box.total_shift_cart:
    print >>log,"Final coordinate shift: (%.1f,%.1f,%.1f)" %(
      box.total_shift_cart)

  print >>log,"Final cell dimensions: (%.1f,%.1f,%.1f)\n" %(
      box.box_crystal_symmetry.unit_cell().parameters()[:3])

  if box.pdb_outside_box_msg:
    print >> log, box.pdb_outside_box_msg

  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_box = pdb_hierarchy.select(selection)
  ph_box.adopt_xray_structure(box.xray_structure_box)
  ph_box.write_pdb_file(file_name=file_name, crystal_symmetry =
    box.xray_structure_box.crystal_symmetry())

  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
    print >> log, "writing map to CCP4 formatted file:   %s"%file_name
    box.write_ccp4_map(file_name=file_name)
  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
    print >> log, "writing map to X-plor formatted file: %s"%file_name
    box.write_xplor_map(file_name=file_name)
  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 >> log, "writing map coefficients to MTZ file: %s"%file_name
    if(map_coeff is not None): d_min = map_coeff.d_min()
    else:
      d_min = maptbx.d_min_from_map(map_data=box.map_box,
        unit_cell=box.xray_structure_box.unit_cell())
    box.map_coefficients(d_min=d_min,
      resolution_factor=params.resolution_factor, file_name=file_name)

  if params.ncs_file:

    if(params.output_file_name_prefix is None):
      output_ncs_file = "%s_box.ncs_spec"%output_prefix
    else: output_ncs_file = "%s.ncs_spec"%params.output_file_name_prefix
    print >>log,"\nOffsetting NCS in %s and writing to %s" %(
       params.ncs_file,output_ncs_file)
    from mmtbx.ncs.ncs import ncs
    ncs_object=ncs()
    ncs_object.read_ncs(params.ncs_file,log=log)
    ncs_object.display_all(log=log)
    if not ncs_object or ncs_object.max_operators()<1:
      print >>log,"Skipping...no NCS available"
    elif box.total_shift_cart:
      from scitbx.math import  matrix
      print >>log,"Shifting NCS operators "+\
        "based on coordinate shift of (%7.1f,%7.1f,%7.1f)" %(
        tuple(box.total_shift_cart))
      ncs_object=ncs_object.coordinate_offset(
       coordinate_offset=matrix.col(box.total_shift_cart))
      ncs_object.display_all(log=log)
    ncs_object.format_all_for_group_specification(
       file_name=output_ncs_file)
    box.ncs_object=ncs_object
  else:
    box.ncs_object=None
  print >> log
  return box
예제 #11
0
def run(args,
        crystal_symmetry=None,
        pdb_hierarchy=None,
        map_data=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
    inputs = mmtbx.utils.process_command_line_args(args=args,
                                                   cmd_cs=crystal_symmetry,
                                                   master_params=master_phil)
    params = inputs.params.extract()
    # 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 pdb_hierarchy):
        raise Sorry("PDB file is needed unless density_select 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
    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)
            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)
            map_data = ccp4_map.data  #map_data()
            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

    # 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)
    #
    selection = pdb_hierarchy.atom_selection_cache().selection(
        string=params.selection)
    if selection.size():
        print_statistics.make_sub_header("atom selection", out=log)
        print >> log, "Selection string: selection='%s'" % params.selection
        print >> log, \
            "  selects %d atoms from total %d atoms."%(selection.count(True),
            selection.size())
    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 params.density_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 >> log, "\nValue outside atoms mask will be set to mean inside mask"
    if params.get_half_height_width:
        print >> log, "\nHalf width at half height will be used to id boundaries"

    box = mmtbx.utils.extract_box_around_model_and_map(
        xray_structure=xray_structure,
        map_data=map_data.as_double(),
        box_cushion=params.box_cushion,
        selection=selection,
        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,
    )

    if box.initial_shift_cart:
        print >> log, "\nInitial coordinate shift will be (%.1f,%.1f,%.1f)\n" % (
            box.initial_shift_cart)
    if box.total_shift_cart:
        print >> log, "Final coordinate shift: (%.1f,%.1f,%.1f)" % (
            box.total_shift_cart)

    print >> log, "Final cell dimensions: (%.1f,%.1f,%.1f)\n" % (
        box.box_crystal_symmetry.unit_cell().parameters()[:3])

    if box.pdb_outside_box_msg:
        print >> log, box.pdb_outside_box_msg

    ph_box = pdb_hierarchy.select(selection)
    ph_box.adopt_xray_structure(box.xray_structure_box)

    box.hierarchy = ph_box
    if not write_output_files:
        return box

    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_box = pdb_hierarchy.select(selection)
    ph_box.adopt_xray_structure(box.xray_structure_box)
    ph_box.write_pdb_file(
        file_name=file_name,
        crystal_symmetry=box.xray_structure_box.crystal_symmetry())

    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
        print >> log, "writing map to CCP4 formatted file:   %s" % file_name
        box.write_ccp4_map(file_name=file_name)
    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
        print >> log, "writing map to X-plor formatted file: %s" % file_name
        box.write_xplor_map(file_name=file_name)
    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 >> log, "writing map coefficients to MTZ file: %s" % file_name
        if (map_coeff is not None): d_min = map_coeff.d_min()
        else:
            d_min = maptbx.d_min_from_map(
                map_data=box.map_box,
                unit_cell=box.xray_structure_box.unit_cell())
        box.map_coefficients(d_min=d_min,
                             resolution_factor=params.resolution_factor,
                             file_name=file_name)

    if params.ncs_file:

        if (params.output_file_name_prefix is None):
            output_ncs_file = "%s_box.ncs_spec" % output_prefix
        else:
            output_ncs_file = "%s.ncs_spec" % params.output_file_name_prefix
        print >> log, "\nOffsetting NCS in %s and writing to %s" % (
            params.ncs_file, output_ncs_file)
        from mmtbx.ncs.ncs import ncs
        ncs_object = ncs()
        ncs_object.read_ncs(params.ncs_file, log=log)
        ncs_object.display_all(log=log)
        if not ncs_object or ncs_object.max_operators() < 1:
            print >> log, "Skipping...no NCS available"
        elif box.total_shift_cart:
            from scitbx.math import matrix
            print >>log,"Shifting NCS operators "+\
              "based on coordinate shift of (%7.1f,%7.1f,%7.1f)" %(
              tuple(box.total_shift_cart))
            ncs_object = ncs_object.coordinate_offset(
                coordinate_offset=matrix.col(box.total_shift_cart))
            ncs_object.display_all(log=log)
        ncs_object.format_all_for_group_specification(
            file_name=output_ncs_file)
        box.ncs_object = ncs_object
    else:
        box.ncs_object = None
    print >> log
    return box
def run(args, log=None, ccp4_map=None, return_as_miller_arrays=False, nohl=False,
    out=sys.stdout):
  if log is None: log=out

  inputs = mmtbx.utils.process_command_line_args(args = args,
    master_params = master_params())
  got_map = False
  if ccp4_map: got_map=True
  broadcast(m="Parameters:", log=log)
  inputs.params.show(prefix="  ",out=out)
  params = inputs.params.extract()
  if(ccp4_map is None and inputs.ccp4_map is not None):
    broadcast(m="Processing input CCP4 map file: %s"%inputs.ccp4_map_file_name,
      log=log)
    ccp4_map = inputs.ccp4_map
    ccp4_map.show_summary(prefix="  ",out=out)
    got_map = True
  if(not got_map):
    raise Sorry("Map file is needed.")
  #
  m = ccp4_map
  broadcast(m="Input map information:", log=log)
  print >>out,"m.all()   :", m.data.all()
  print >>out,"m.focus() :", m.data.focus()
  print >>out,"m.origin():", m.data.origin()
  print >>out,"m.nd()    :", m.data.nd()
  print >>out,"m.size()  :", m.data.size()
  print >>out,"m.focus_size_1d():", m.data.focus_size_1d()
  print >>out,"m.is_0_based()   :", m.data.is_0_based()
  print >>out,"map: min/max/mean:", flex.min(m.data), flex.max(m.data), flex.mean(m.data)
  print >>out,"unit cell:", m.unit_cell_parameters
  #
  map_data=m.data
  shift_needed = not \
     (map_data.focus_size_1d() > 0 and map_data.nd() == 3 and
      map_data.is_0_based())
  if(shift_needed):
    map_data = map_data.shift_origin()

  # generate complete set of Miller indices up to given high resolution d_min
  n_real = map_data.focus()
  cs = crystal.symmetry(m.unit_cell_parameters, 1)
  crystal_gridding = maptbx.crystal_gridding(
    unit_cell         = cs.unit_cell(),
    space_group_info  = cs.space_group_info(),
    #symmetry_flags     = maptbx.use_space_group_symmetry,
    pre_determined_n_real = n_real)
  #
  d_min = params.d_min
  if(d_min is None and not params.box):
    d_min = maptbx.d_min_from_map(
      map_data  = map_data,
      unit_cell = cs.unit_cell())
  if(d_min is None):
    # box of reflections in |h|<N1/2, |k|<N2/2, 0<=|l|<N3/2
    max_index = [(i-1)//2 for i in n_real]
    print >>out,"max_index:", max_index
    complete_set = miller.build_set(
      crystal_symmetry = cs,
      anomalous_flag   = False,
      max_index        = max_index)
    indices = complete_set.indices()
    indices.append((0,0,0))
    complete_set = complete_set.customized_copy(indices = indices)
    #if(not params.box):
    #  # XXX What is sphere resolution corresponding to given box?
    #  uc = complete_set.unit_cell()
    #  d1 = uc.d([0,0,max_index[2]])
    #  d2 = uc.d([0,max_index[1],0])
    #  d3 = uc.d([max_index[0],1,0])
    #  print >>out, d1,d2,d3
    #  complete_set_sp = miller.build_set(
    #    crystal_symmetry = cs,
    #    anomalous_flag   = False,
    #    d_min            = min(d1,d2,d3))
    #  complete_set = complete_set.common_set(complete_set_sp)
  else:
    complete_set = miller.build_set(
      crystal_symmetry = cs,
      anomalous_flag   = False,
      d_min            = d_min)
  broadcast(m="Complete set information:", log=log)
  complete_set.show_comprehensive_summary(prefix="  ",f=out)
  try:
    f_obs_cmpl = complete_set.structure_factors_from_map(
      map            = map_data.as_double(),
      use_scale      = True,
      anomalous_flag = False,
      use_sg         = False)
  except Exception, e:
    if(str(e) == "cctbx Error: Miller index not in structure factor map."):
      msg = "Too high resolution requested. Try running with larger d_min."
      raise Sorry(msg)
    else:
      raise Sorry(str(e))
예제 #13
0
def run(args,
        log=None,
        ccp4_map=None,
        return_as_miller_arrays=False,
        nohl=False,
        space_group_number=None,
        out=sys.stdout):
    if log is None: log = out
    inputs = mmtbx.utils.process_command_line_args(
        args=args, master_params=master_params())
    got_map = False
    if ccp4_map: got_map = True
    broadcast(m="Parameters:", log=log)
    inputs.params.show(prefix="  ", out=out)
    params = inputs.params.extract()
    if (ccp4_map is None and inputs.ccp4_map is not None):
        broadcast(m="Processing input CCP4 map file: %s" %
                  inputs.ccp4_map_file_name,
                  log=log)
        ccp4_map = inputs.ccp4_map
        ccp4_map.show_summary(prefix="  ", out=out)
        got_map = True
    if (not got_map):
        raise Sorry("Map file is needed.")
    #
    m = ccp4_map
    if (m.space_group_number > 1):
        raise Sorry("Input map space group: %d. Must be P1." %
                    m.space_group_number)
    broadcast(m="Input map information:", log=log)
    print >> out, "m.all()   :", m.data.all()
    print >> out, "m.focus() :", m.data.focus()
    print >> out, "m.origin():", m.data.origin()
    print >> out, "m.nd()    :", m.data.nd()
    print >> out, "m.size()  :", m.data.size()
    print >> out, "m.focus_size_1d():", m.data.focus_size_1d()
    print >> out, "m.is_0_based()   :", m.data.is_0_based()
    print >> out, "map: min/max/mean:", flex.min(m.data), flex.max(
        m.data), flex.mean(m.data)
    print >> out, "unit cell:", m.unit_cell_parameters
    #
    map_data = m.data
    shift_needed = not \
       (map_data.focus_size_1d() > 0 and map_data.nd() == 3 and
        map_data.is_0_based())
    if (shift_needed):
        map_data = map_data.shift_origin()

    # generate complete set of Miller indices up to given high resolution d_min
    n_real = map_data.focus()
    if not space_group_number:
        space_group_number = 1
    if space_group_number <= 1:
        symmetry_flags = None
    else:
        symmetry_flags = maptbx.use_space_group_symmetry,

    cs = crystal.symmetry(m.unit_cell_parameters, space_group_number)
    crystal_gridding = maptbx.crystal_gridding(
        unit_cell=cs.unit_cell(),
        space_group_info=cs.space_group_info(),
        symmetry_flags=symmetry_flags,
        pre_determined_n_real=n_real)
    #
    d_min = params.d_min
    if (d_min is None and not params.box):
        d_min = maptbx.d_min_from_map(map_data=map_data,
                                      unit_cell=cs.unit_cell())
    if (d_min is None):
        # box of reflections in |h|<N1/2, |k|<N2/2, 0<=|l|<N3/2
        max_index = [(i - 1) // 2 for i in n_real]
        print >> out, "max_index:", max_index
        complete_set = miller.build_set(crystal_symmetry=cs,
                                        anomalous_flag=False,
                                        max_index=max_index)
        indices = complete_set.indices()
        indices.append((0, 0, 0))
        complete_set = complete_set.customized_copy(indices=indices)
        #if(not params.box):
        #  # XXX What is sphere resolution corresponding to given box?
        #  uc = complete_set.unit_cell()
        #  d1 = uc.d([0,0,max_index[2]])
        #  d2 = uc.d([0,max_index[1],0])
        #  d3 = uc.d([max_index[0],1,0])
        #  print >>out, d1,d2,d3
        #  complete_set_sp = miller.build_set(
        #    crystal_symmetry = cs,
        #    anomalous_flag   = False,
        #    d_min            = min(d1,d2,d3))
        #  complete_set = complete_set.common_set(complete_set_sp)
    else:
        complete_set = miller.build_set(crystal_symmetry=cs,
                                        anomalous_flag=False,
                                        d_min=d_min)
    broadcast(m="Complete set information:", log=log)
    complete_set.show_comprehensive_summary(prefix="  ", f=out)
    try:
        f_obs_cmpl = complete_set.structure_factors_from_map(
            map=map_data.as_double(),
            use_scale=True,
            anomalous_flag=False,
            use_sg=False)
    except Exception, e:
        if (str(e) == "cctbx Error: Miller index not in structure factor map."
            ):
            msg = "Too high resolution requested. Try running with larger d_min."
            raise Sorry(msg)
        else:
            raise Sorry(str(e))