Ejemplo n.º 1
0
def multipanel_sim(
  CRYSTAL, DETECTOR, BEAM, Famp, energies, fluxes,
  background_wavelengths=None, background_wavelength_weights=None,
  background_total_flux=None, background_sample_thick_mm=None,
  density_gcm3=1, molecular_weight=18,
  cuda=False, oversample=0, Ncells_abc=(50, 50, 50),
  mos_dom=1, mos_spread=0, mosaic_method="double_uniform",
  mos_aniso=None, beamsize_mm=0.001,
  crystal_size_mm=0.01,
  verbose=0, default_F=0, interpolate=0, profile="gauss",
  spot_scale_override=None, show_params=False, time_panels=False,
  add_water = False, add_air=False, water_path_mm=0.005, air_path_mm=0,
  adc_offset=0, readout_noise=3, psf_fwhm=0, gain=1, mosaicity_random_seeds=None,
  include_background=True, mask_file="",skip_numpy=False,relevant_whitelist_order=None):

  from simtbx.nanoBragg.nanoBragg_beam import NBbeam
  from simtbx.nanoBragg.nanoBragg_crystal import NBcrystal
  from simtbx.nanoBragg.sim_data import SimData
  from simtbx.nanoBragg.utils import get_xray_beams
  from scitbx.array_family import flex
  from scipy import constants
  import numpy as np
  ENERGY_CONV = 10000000000.0 * constants.c * constants.h / constants.electron_volt
  assert cuda # disallow the default

  nbBeam = NBbeam()
  nbBeam.size_mm = beamsize_mm
  nbBeam.unit_s0 = BEAM.get_unit_s0()
  wavelengths = ENERGY_CONV / np.array(energies)
  nbBeam.spectrum = list(zip(wavelengths, fluxes))

  nbCrystal = NBcrystal(False)
  nbCrystal.dxtbx_crystal = CRYSTAL
  #nbCrystal.miller_array = None # use the gpu_channels_singleton mechanism instead
  nbCrystal.Ncells_abc = Ncells_abc
  nbCrystal.symbol = CRYSTAL.get_space_group().info().type().lookup_symbol()
  nbCrystal.thick_mm = crystal_size_mm
  nbCrystal.xtal_shape = profile
  nbCrystal.n_mos_domains = mos_dom
  nbCrystal.mos_spread_deg = mos_spread
  nbCrystal.anisotropic_mos_spread_deg = mos_aniso

  pid = 0 # remove the loop, use C++ iteration over detector panels
  use_exascale_api = True
  if use_exascale_api:

    S = SimData(use_default_crystal = False)
    S.detector = DETECTOR
    S.beam = nbBeam
    S.crystal = nbCrystal
    S.panel_id = pid
    S.add_air = add_air
    S.air_path_mm = air_path_mm
    S.add_water = add_water
    S.water_path_mm = water_path_mm
    S.readout_noise = readout_noise
    S.gain = gain
    S.psf_fwhm = psf_fwhm
    S.include_noise = False
    S.Umats_method = dict(double_random=0, double_uniform=5)[mosaic_method]

    if mosaicity_random_seeds is not None:
      S.mosaic_seeds = mosaicity_random_seeds

    S.instantiate_nanoBragg(verbose=verbose, oversample=oversample, interpolate=interpolate,
      device_Id=Famp.get_deviceID(),default_F=default_F, adc_offset=adc_offset)

    SIM = S.D # the nanoBragg instance
    assert Famp.get_deviceID()==SIM.device_Id
    if spot_scale_override is not None:
      SIM.spot_scale = spot_scale_override
    assert Famp.get_nchannels() == 1 # non-anomalous scenario

    from simtbx.gpu import exascale_api
    gpu_simulation = exascale_api(nanoBragg = SIM)
    gpu_simulation.allocate() # presumably done once for each image

    from simtbx.gpu import gpu_detector as gpud
    gpu_detector = gpud(deviceId=SIM.device_Id, detector=DETECTOR,
                        beam=BEAM)
    gpu_detector.each_image_allocate()

    # revisit the allocate cuda for overlap with detector, sync up please
    x = 0 # only one energy channel
    if mask_file is "": # all-pixel kernel
      P = Profiler("%40s"%"from gpu amplitudes cuda")
      gpu_simulation.add_energy_channel_from_gpu_amplitudes(
      x, Famp, gpu_detector)
    elif type(mask_file) is flex.bool: # 1D bool array, flattened from ipanel, islow, ifast
      P = Profiler("%40s"%"from gpu amplitudes cuda with bool mask")
      gpu_simulation.add_energy_channel_mask_allpanel(
        channel_number = x, gpu_amplitudes = Famp, gpu_detector = gpu_detector,
        pixel_active_mask_bools = mask_file )
    elif type(mask_file) is flex.int:
      # precalculated active_pixel_list
      P = Profiler("%40s"%"from gpu amplitudes cuda w/int whitelist")
      gpu_simulation.add_energy_channel_mask_allpanel(
        channel_number = x, gpu_amplitudes = Famp, gpu_detector = gpu_detector,
        pixel_active_list_ints = mask_file )
    else:
      assert type(mask_file) is str
      from LS49.adse13_187.adse13_221.mask_utils import mask_from_file
      boolean_mask = mask_from_file(mask_file)
      P = Profiler("%40s"%"from gpu amplitudes cuda with file mask")
      gpu_simulation.add_energy_channel_mask_allpanel(
      x, Famp, gpu_detector, boolean_mask )
    TIME_BRAGG = time()-P.start_el

    per_image_scale_factor = 1.
    gpu_detector.scale_in_place(per_image_scale_factor) # apply scale directly on GPU

    if include_background:
      t_bkgrd_start = time()
      SIM.beamsize_mm = beamsize_mm

      wavelength_weights = np.array(background_wavelength_weights)
      weights = wavelength_weights / wavelength_weights.sum() * background_total_flux
      spectrum = list(zip(background_wavelengths, weights))
      xray_beams = get_xray_beams(spectrum, BEAM)
      SIM.xray_beams = xray_beams
      SIM.Fbg_vs_stol = water
      SIM.flux=sum(weights)
      SIM.amorphous_sample_thick_mm = background_sample_thick_mm
      SIM.amorphous_density_gcm3 = density_gcm3
      SIM.amorphous_molecular_weight_Da = molecular_weight
      gpu_simulation.add_background(gpu_detector)
      TIME_BG = time()-t_bkgrd_start
    else: TIME_BG=0.

    if skip_numpy:
      P = Profiler("%40s"%"get short whitelist values")
      whitelist_only = gpu_detector.get_whitelist_raw_pixels(relevant_whitelist_order)
      # whitelist_only, flex_double pixel values
      # relevant_whitelist_order, flex.size_t detector addresses
      assert len(whitelist_only) == len(relevant_whitelist_order) # guard against shoebox overlap bug
      # when shoeboxes overlap, the overlapped pixels should be simulated once for each parent shoebox

      P = Profiler("%40s"%"each image free cuda")
      gpu_detector.each_image_free()
      return whitelist_only, TIME_BG, TIME_BRAGG, S.exascale_mos_blocks or None

    packed_numpy = gpu_detector.get_raw_pixels()
    gpu_detector.each_image_free()
    return packed_numpy.as_numpy_array(), TIME_BG, TIME_BRAGG, S.exascale_mos_blocks or None
Ejemplo n.º 2
0
def flexBeam_sim_colors(CRYSTAL,
                        DETECTOR,
                        BEAM,
                        Famp,
                        energies,
                        fluxes,
                        pids=None,
                        cuda=False,
                        oversample=0,
                        Ncells_abc=(50, 50, 50),
                        mos_dom=1,
                        mos_spread=0,
                        beamsize_mm=0.001,
                        device_Id=0,
                        omp=False,
                        show_params=False,
                        crystal_size_mm=0.01,
                        printout_pix=None,
                        time_panels=True,
                        verbose=0,
                        default_F=0,
                        interpolate=0,
                        recenter=True,
                        profile="gauss",
                        spot_scale_override=None,
                        background_raw_pixels=None,
                        include_noise=False,
                        add_water=False,
                        add_air=False,
                        water_path_mm=0.005,
                        air_path_mm=0,
                        rois_perpanel=None,
                        adc_offset=0,
                        readout_noise=3,
                        psf_fwhm=0,
                        gain=1,
                        mosaicity_random_seeds=None):
    """
  :param CRYSTAL: dxtbx Crystal model
  :param DETECTOR: dxtbx detector model
  :param BEAM: dxtbx beam model
  :param Famp: cctbx miller array (amplitudes)
  :param energies: list of energies to simulate the scattering
  :param fluxes:  list of pulse fluences per energy (same length as energies)
  :param pids: panel ids to simulate on (None means all panels)
  :param cuda: whether to use GPU (only works for nvidia builds)
  :param oversample: pixel oversample factor (0 means nanoBragg will decide)
  :param Ncells_abc: number of unit cells along each crystal direction in the mosaic block
  :param mos_dom: number of mosaic domains in used to sample mosaic spread (texture)
  :param mos_spread: mosaicity in degrees (spherical cap width)
  :param beamsize_mm: focal size of the beam
  :param device_Id: cuda device id (ignore if cuda=False)
  :param omp: whether to use open mp (required open MP build configuration)
  :param show_params: show the nanoBragg parameters
  :param crystal_size_mm: size of the crystal (increases the intensity of the spots)
  :param printout_pix: debug pixel position : tuple of (pixel_fast_coord, pixel_slow_coord)
  :param time_panels: show timing info
  :param verbose: verbosity level for nanoBragg (0-10), 0 is quiet
  :param default_F: default amplitude value for nanoBragg
  :param interpolate: whether to interpolate for small mosaic domains
  :param recenter: recenter for tilted cameras, deprecated
  :param profile: profile shape, can be : gauss, round, square, or tophat
  :param spot_scale_override: scale the simulated scattering bythis amounth (overrides value based on crystal thickness)
  :param background_raw_pixels: dictionary of {panel_id: raw_pixels}, add these background pixels to the simulated Bragg
  :param include_noise: add noise to simulated pattern
  :param add_water: add water to similated pattern
  :param add_air: add ait to simulated pattern
  :param water_path_mm: length of water the beam travels through
  :param air_path_mm: length of air the beam travels through
  :param rois_perpanel: regions of intererest on each panel
  :param adc_offset: add this value to each pixel in simulated pattern
  :param readout_noise: readout noise level (usually 3-5 ADU)
  :param psf_fwhm: point spread kernel FWHM
  :param gain: photon gain
  :param mosaicity_random_seeds: random seeds to simulating mosaic texture
  :return: list of [(panel_id0,simulated pattern0), (panel_id1, simulated_pattern1), ...]
  """

    if pids is None:
        pids = range(len(DETECTOR))

    if background_raw_pixels is None:
        background_raw_pixels = {pid: None for pid in pids}

    if rois_perpanel is None:
        rois_perpanel = {pid: None for pid in pids}

    nbBeam = NBbeam()
    nbBeam.size_mm = beamsize_mm
    nbBeam.unit_s0 = BEAM.get_unit_s0()
    wavelengths = ENERGY_CONV / np.array(energies)
    nbBeam.spectrum = list(zip(wavelengths, fluxes))

    nbCrystal = NBcrystal()
    nbCrystal.dxtbx_crystal = CRYSTAL
    nbCrystal.miller_array = Famp
    nbCrystal.Ncells_abc = Ncells_abc
    nbCrystal.symbol = CRYSTAL.get_space_group().info().type().lookup_symbol()
    nbCrystal.thick_mm = crystal_size_mm
    nbCrystal.xtal_shape = profile
    nbCrystal.n_mos_domains = mos_dom
    nbCrystal.mos_spread_deg = mos_spread

    panel_images = []

    tinit = time.time()
    S = SimData()
    S.detector = DETECTOR
    S.beam = nbBeam
    S.crystal = nbCrystal
    S.using_cuda = cuda
    S.using_omp = omp
    S.add_air = add_air
    S.air_path_mm = air_path_mm
    S.add_water = add_water
    S.water_path_mm = water_path_mm
    S.readout_noise = readout_noise
    S.gain = gain
    S.psf_fwhm = psf_fwhm
    S.include_noise = include_noise

    if mosaicity_random_seeds is not None:
        S.mosaic_seeds = mosaicity_random_seeds

    S.instantiate_nanoBragg(verbose=verbose,
                            oversample=oversample,
                            interpolate=interpolate,
                            device_Id=device_Id,
                            default_F=default_F,
                            adc_offset=adc_offset)

    if printout_pix is not None:
        S.update_nanoBragg_instance("printout_pixel_fastslow", printout_pix)
    if spot_scale_override is not None:
        S.update_nanoBragg_instance("spot_scale", spot_scale_override)

    for pid in pids:
        t_panel = time.time()
        S.background_raw_pixels = background_raw_pixels[pid]
        S.panel_id = pid
        S.rois = rois_perpanel[pid]

        S.generate_simulated_image()

        if show_params:
            S.D.show_params()
            print('spot scale: %2.7g' % S.D.spot_scale)
        panel_image = S.D.raw_pixels.as_numpy_array()
        panel_images.append([pid, panel_image])
        S.D.raw_pixels *= 0
        if time_panels:
            tdone = time.time() - tinit
            t_panel = time.time() - t_panel
            print(
                'Panel %d took %.4f seconds (Total sim time = %.4f seconds)' %
                (pid, t_panel, tdone))

    S.D.free_all()

    return panel_images
Ejemplo n.º 3
0
def flexBeam_sim_colors(CRYSTAL,
                        DETECTOR,
                        BEAM,
                        Famp,
                        energies,
                        fluxes,
                        pids=None,
                        cuda=False,
                        oversample=0,
                        Ncells_abc=(50, 50, 50),
                        mos_dom=1,
                        mos_spread=0,
                        beamsize_mm=0.001,
                        device_Id=0,
                        omp=False,
                        show_params=False,
                        crystal_size_mm=0.01,
                        printout_pix=None,
                        time_panels=True,
                        verbose=0,
                        default_F=0,
                        interpolate=0,
                        recenter=True,
                        profile="gauss",
                        spot_scale_override=None,
                        background_raw_pixels=None,
                        include_noise=False,
                        add_water=False,
                        add_air=False,
                        water_path_mm=0.005,
                        air_path_mm=0,
                        rois_perpanel=None,
                        adc_offset=0,
                        readout_noise=3,
                        psf_fwhm=0,
                        gain=1,
                        mosaicity_random_seeds=None):

    if pids is None:
        pids = range(len(DETECTOR))

    if background_raw_pixels is None:
        background_raw_pixels = {pid: None for pid in pids}

    if rois_perpanel is None:
        rois_perpanel = {pid: None for pid in pids}

    nbBeam = NBbeam()
    nbBeam.size_mm = beamsize_mm
    nbBeam.unit_s0 = BEAM.get_unit_s0()
    wavelengths = ENERGY_CONV / np.array(energies)
    nbBeam.spectrum = list(zip(wavelengths, fluxes))

    nbCrystal = NBcrystal()
    nbCrystal.dxtbx_crystal = CRYSTAL
    nbCrystal.miller_array = Famp
    nbCrystal.Ncells_abc = Ncells_abc
    nbCrystal.symbol = CRYSTAL.get_space_group().info().type().lookup_symbol()
    nbCrystal.thick_mm = crystal_size_mm
    nbCrystal.xtal_shape = profile
    nbCrystal.n_mos_domains = mos_dom
    nbCrystal.mos_spread_deg = mos_spread

    panel_images = []

    for pid in pids:
        tinit = time.time()
        S = SimData()
        S.detector = DETECTOR
        S.beam = nbBeam
        S.crystal = nbCrystal
        S.panel_id = pid
        S.using_cuda = cuda
        S.using_omp = omp
        S.add_air = add_air
        S.air_path_mm = air_path_mm
        S.add_water = add_water
        S.water_path_mm = water_path_mm
        S.background_raw_pixels = background_raw_pixels[pid]
        S.rois = rois_perpanel[pid]
        S.readout_noise = readout_noise
        S.gain = gain
        S.psf_fwhm = psf_fwhm
        S.include_noise = include_noise

        if mosaicity_random_seeds is not None:
            S.mosaic_seeds = mosaicity_random_seeds

        S.instantiate_nanoBragg(verbose=verbose,
                                oversample=oversample,
                                interpolate=interpolate,
                                device_Id=device_Id,
                                default_F=default_F,
                                adc_offset=adc_offset)
        if recenter:
            S.update_nanoBragg_instance(
                "beam_center_mm",
                DETECTOR[int(pid)].get_beam_centre(BEAM.get_s0()))
        if printout_pix is not None:
            S.update_nanoBragg_instance("printout_pixel_fastslow",
                                        printout_pix)
        if spot_scale_override is not None:
            S.update_nanoBragg_instance("spot_scale", spot_scale_override)

        S.generate_simulated_image()

        if show_params:
            S.D.show_params()
            print('spot scale: %2.7g' % S.D.spot_scale)
        panel_image = S.D.raw_pixels.as_numpy_array()
        panel_images.append([pid, panel_image])
        S.D.free_all()
        if time_panels:
            tdone = time.time() - tinit
            print('Panel %d took %.4f seconds' % (pid, tdone))
        del S.D

    return panel_images