Пример #1
0
def run_sim2smv(prefix, crystal, spectra, rotation, rank, quick=False):
    local_data = data()
    smv_fileout = prefix + ".img"
    if quick is not True:
        if not write_safe(smv_fileout):
            print("File %s already exists, skipping in rank %d" %
                  (smv_fileout, rank))
            return

    direct_algo_res_limit = 1.7

    wavlen, flux, wavelength_A = next(
        spectra)  # list of lambdas, list of fluxes, average wavelength
    if quick:
        wavlen = flex.double([wavelength_A])
        flux = flex.double([flex.sum(flux)])
        print("Quick sim, lambda=%f, flux=%f" % (wavelength_A, flux[0]))

    GF = gen_fmodel(resolution=direct_algo_res_limit,
                    pdb_text=local_data.get("pdb_lines"),
                    algorithm="fft",
                    wavelength=wavelength_A)
    GF.set_k_sol(0.435)
    GF.make_P1_primitive()
    sfall_main = GF.get_amplitudes()

    # use crystal structure to initialize Fhkl array
    sfall_main.show_summary(prefix="Amplitudes used ")
    N = crystal.number_of_cells(sfall_main.unit_cell())

    #SIM = nanoBragg(detpixels_slowfast=(2000,2000),pixel_size_mm=0.11,Ncells_abc=(5,5,5),verbose=0)
    SIM = nanoBragg(
        detpixels_slowfast=(3000, 3000),
        pixel_size_mm=0.11,
        Ncells_abc=(N, N, N),
        # workaround for problem with wavelength array, specify it separately in constructor.
        wavelength_A=wavelength_A,
        verbose=0)
    SIM.adc_offset_adu = 0  # Do not offset by 40
    SIM.adc_offset_adu = 10  # Do not offset by 40
    import sys
    if len(sys.argv) > 2:
        SIM.seed = -int(sys.argv[2])
        print("GOTHERE seed=", SIM.seed)
    if len(sys.argv) > 1:
        if sys.argv[1] == "random": SIM.randomize_orientation()
    SIM.mosaic_spread_deg = 0.05  # interpreted by UMAT_nm as a half-width stddev
    SIM.mosaic_domains = n_mosaic_domains  # 77 seconds.  With 100 energy points, 7700 seconds (2 hours) per image
    # 3000000 images would be 100000 hours on a 60-core machine (dials), or 11.4 years
    # using 2 nodes, 5.7 years.  Do this at SLAC? NERSC? combination of all?
    # SLAC downtimes: Tues Dec 5 (24 hrs), Mon Dec 11 (72 hrs), Mon Dec 18 light use, 24 days
    # mosaic_domains setter must come after mosaic_spread_deg setter
    SIM.distance_mm = 141.7

    UMAT_nm = flex.mat3_double()
    mersenne_twister = flex.mersenne_twister(seed=0)
    scitbx.random.set_random_seed(1234)
    rand_norm = scitbx.random.normal_distribution(mean=0,
                                                  sigma=SIM.mosaic_spread_deg *
                                                  math.pi / 180.)
    g = scitbx.random.variate(rand_norm)
    mosaic_rotation = g(SIM.mosaic_domains)
    for m in mosaic_rotation:
        site = col(mersenne_twister.random_double_point_on_sphere())
        UMAT_nm.append(site.axis_and_angle_as_r3_rotation_matrix(m, deg=False))
    SIM.set_mosaic_blocks(UMAT_nm)

    #SIM.detector_thick_mm = 0.5 # = 0 for Rayonix
    #SIM.detector_thicksteps = 1 # should default to 1 for Rayonix, but set to 5 for CSPAD
    #SIM.detector_attenuation_length_mm = default is silicon

    # get same noise each time this test is run
    SIM.seed = 1
    SIM.oversample = 1
    SIM.wavelength_A = wavelength_A
    SIM.polarization = 1
    # this will become F000, marking the beam center
    SIM.default_F = 0
    #SIM.missets_deg= (10,20,30)
    print("mosaic_seed=", SIM.mosaic_seed)
    print("seed=", SIM.seed)
    print("calib_seed=", SIM.calib_seed)
    print("missets_deg =", SIM.missets_deg)
    SIM.Fhkl = sfall_main
    print("Determinant", rotation.determinant())
    Amatrix_rot = (
        rotation *
        sqr(sfall_main.unit_cell().orthogonalization_matrix())).transpose()
    print("RAND_ORI", prefix, end=' ')
    for i in Amatrix_rot:
        print(i, end=' ')
    print()

    SIM.Amatrix_RUB = Amatrix_rot
    #workaround for failing init_cell, use custom written Amatrix setter
    print("unit_cell_Adeg=", SIM.unit_cell_Adeg)
    print("unit_cell_tuple=", SIM.unit_cell_tuple)
    Amat = sqr(SIM.Amatrix).transpose()  # recovered Amatrix from SIM
    from cctbx import crystal_orientation
    Ori = crystal_orientation.crystal_orientation(
        Amat, crystal_orientation.basis_type.reciprocal)
    print("Python unit cell from SIM state", Ori.unit_cell())

    # fastest option, least realistic
    #SIM.xtal_shape=shapetype.Tophat # RLP = hard sphere
    #SIM.xtal_shape=shapetype.Square # gives fringes
    SIM.xtal_shape = shapetype.Gauss  # both crystal & RLP are Gaussian
    #SIM.xtal_shape=shapetype.Round # Crystal is a hard sphere
    # only really useful for long runs
    SIM.progress_meter = False
    # prints out value of one pixel only.  will not render full image!
    #SIM.printout_pixel_fastslow=(500,500)
    #SIM.printout=True
    SIM.show_params()
    # flux is always in photons/s
    SIM.flux = 1e12
    SIM.exposure_s = 1.0  # so total fluence is e12
    # assumes round beam
    SIM.beamsize_mm = 0.003  #cannot make this 3 microns; spots are too intense
    temp = SIM.Ncells_abc
    print("Ncells_abc=", SIM.Ncells_abc)
    SIM.Ncells_abc = temp
    print("Ncells_abc=", SIM.Ncells_abc)
    print("xtal_size_mm=", SIM.xtal_size_mm)
    print("unit_cell_Adeg=", SIM.unit_cell_Adeg)
    print("unit_cell_tuple=", SIM.unit_cell_tuple)
    print("missets_deg=", SIM.missets_deg)
    print("Amatrix=", SIM.Amatrix)
    print("beam_center_mm=", SIM.beam_center_mm)
    print("XDS_ORGXY=", SIM.XDS_ORGXY)
    print("detector_pivot=", SIM.detector_pivot)
    print("xtal_shape=", SIM.xtal_shape)
    print("beamcenter_convention=", SIM.beamcenter_convention)
    print("fdet_vector=", SIM.fdet_vector)
    print("sdet_vector=", SIM.sdet_vector)
    print("odet_vector=", SIM.odet_vector)
    print("beam_vector=", SIM.beam_vector)
    print("polar_vector=", SIM.polar_vector)
    print("spindle_axis=", SIM.spindle_axis)
    print("twotheta_axis=", SIM.twotheta_axis)
    print("distance_meters=", SIM.distance_meters)
    print("distance_mm=", SIM.distance_mm)
    print("close_distance_mm=", SIM.close_distance_mm)
    print("detector_twotheta_deg=", SIM.detector_twotheta_deg)
    print("detsize_fastslow_mm=", SIM.detsize_fastslow_mm)
    print("detpixels_fastslow=", SIM.detpixels_fastslow)
    print("detector_rot_deg=", SIM.detector_rot_deg)
    print("curved_detector=", SIM.curved_detector)
    print("pixel_size_mm=", SIM.pixel_size_mm)
    print("point_pixel=", SIM.point_pixel)
    print("polarization=", SIM.polarization)
    print("nopolar=", SIM.nopolar)
    print("oversample=", SIM.oversample)
    print("region_of_interest=", SIM.region_of_interest)
    print("wavelength_A=", SIM.wavelength_A)
    print("energy_eV=", SIM.energy_eV)
    print("fluence=", SIM.fluence)
    print("flux=", SIM.flux)
    print("exposure_s=", SIM.exposure_s)
    print("beamsize_mm=", SIM.beamsize_mm)
    print("dispersion_pct=", SIM.dispersion_pct)
    print("dispsteps=", SIM.dispsteps)
    print("divergence_hv_mrad=", SIM.divergence_hv_mrad)
    print("divsteps_hv=", SIM.divsteps_hv)
    print("divstep_hv_mrad=", SIM.divstep_hv_mrad)
    print("round_div=", SIM.round_div)
    print("phi_deg=", SIM.phi_deg)
    print("osc_deg=", SIM.osc_deg)
    print("phisteps=", SIM.phisteps)
    print("phistep_deg=", SIM.phistep_deg)
    print("detector_thick_mm=", SIM.detector_thick_mm)
    print("detector_thicksteps=", SIM.detector_thicksteps)
    print("detector_thickstep_mm=", SIM.detector_thickstep_mm)
    print("***mosaic_spread_deg=", SIM.mosaic_spread_deg)
    print("***mosaic_domains=", SIM.mosaic_domains)
    print("indices=", SIM.indices)
    print("amplitudes=", SIM.amplitudes)
    print("Fhkl_tuple=", SIM.Fhkl_tuple)
    print("default_F=", SIM.default_F)
    print("interpolate=", SIM.interpolate)
    print("integral_form=", SIM.integral_form)

    from libtbx.development.timers import Profiler
    P = Profiler("nanoBragg")
    # now actually burn up some CPU
    #SIM.add_nanoBragg_spots()
    del P

    # simulated crystal is only 125 unit cells (25 nm wide)
    # amplify spot signal to simulate physical crystal of 4000x larger: 100 um (64e9 x the volume)
    print(crystal.domains_per_crystal)
    SIM.raw_pixels *= crystal.domains_per_crystal
    # must calculate the correct scale!

    # Use single wavelength for all energy channels for the purpose of Fcalc
    wavelength_hi_remote = wavlen[-1]
    GF.reset_wavelength(wavelength_hi_remote)
    GF.reset_specific_at_wavelength(label_has="FE1",
                                    tables=local_data.get("Fe_oxidized_model"),
                                    newvalue=wavelength_hi_remote)
    GF.reset_specific_at_wavelength(label_has="FE2",
                                    tables=local_data.get("Fe_reduced_model"),
                                    newvalue=wavelength_hi_remote)
    sfall_channel = GF.get_amplitudes()

    # sources
    channel_source_XYZ = flex.vec3_double(len(flux), SIM.xray_source_XYZ[0])

    CP = channel_pixels(
        wavlen, flux,
        channel_source_XYZ)  # class interface for multi-wavelength
    print("+++++++++++++++++++++++++++++++++++++++ Multiwavelength call")
    CH = CP(N=N,
            UMAT_nm=UMAT_nm,
            Amatrix_rot=Amatrix_rot,
            sfall_channel=sfall_channel)
    SIM.raw_pixels += CH.raw_pixels * crystal.domains_per_crystal
    CH.free_all()
    if quick: SIM.to_smv_format(fileout=prefix + "_intimage_001.img")

    # rough approximation to water: interpolation points for sin(theta/lambda) vs structure factor
    bg = flex.vec2_double([(0, 2.57), (0.0365, 2.58), (0.07, 2.8), (0.12, 5),
                           (0.162, 8), (0.2, 6.75),
                           (0.18, 7.32), (0.216, 6.75), (0.236, 6.5),
                           (0.28, 4.5), (0.3, 4.3), (0.345, 4.36),
                           (0.436, 3.77), (0.5, 3.17)])
    SIM.Fbg_vs_stol = bg
    SIM.amorphous_sample_thick_mm = 0.1
    SIM.amorphous_density_gcm3 = 1
    SIM.amorphous_molecular_weight_Da = 18
    SIM.flux = 1e12
    SIM.beamsize_mm = 0.003  # square (not user specified)
    SIM.exposure_s = 1.0  # multiplies flux x exposure
    SIM.add_background()
    if quick: SIM.to_smv_format(fileout=prefix + "_intimage_002.img")

    # rough approximation to air
    bg = flex.vec2_double([(0, 14.1), (0.045, 13.5), (0.174, 8.35),
                           (0.35, 4.78), (0.5, 4.22)])
    SIM.Fbg_vs_stol = bg
    #SIM.amorphous_sample_thick_mm = 35 # between beamstop and collimator
    SIM.amorphous_sample_thick_mm = 10  # between beamstop and collimator
    SIM.amorphous_density_gcm3 = 1.2e-3
    SIM.amorphous_sample_molecular_weight_Da = 28  # nitrogen = N2
    print("amorphous_sample_size_mm=", SIM.amorphous_sample_size_mm)
    print("amorphous_sample_thick_mm=", SIM.amorphous_sample_thick_mm)
    print("amorphous_density_gcm3=", SIM.amorphous_density_gcm3)
    print("amorphous_molecular_weight_Da=", SIM.amorphous_molecular_weight_Da)
    SIM.add_background()

    #apply beamstop mask here

    # set this to 0 or -1 to trigger automatic radius.  could be very slow with bright images
    # settings for CCD
    SIM.detector_psf_kernel_radius_pixels = 5
    #SIM.detector_psf_fwhm_mm=0.08;
    #SIM.detector_psf_type=shapetype.Fiber # rayonix=Fiber, CSPAD=None (or small Gaussian)
    SIM.detector_psf_type = shapetype.Unknown  # for CSPAD
    SIM.detector_psf_fwhm_mm = 0
    #SIM.apply_psf()
    print("One pixel-->", SIM.raw_pixels[500000])

    # at this point we scale the raw pixels so that the output array is on an scale from 0 to 50000.
    # that is the default behavior (intfile_scale<=0), otherwise it applies intfile_scale as a multiplier on an abs scale.
    if quick: SIM.to_smv_format(fileout=prefix + "_intimage_003.img")

    print("quantum_gain=",
          SIM.quantum_gain)  #defaults to 1. converts photons to ADU
    print("adc_offset_adu=", SIM.adc_offset_adu)
    print("detector_calibration_noise_pct=",
          SIM.detector_calibration_noise_pct)
    print("flicker_noise_pct=", SIM.flicker_noise_pct)
    print("readout_noise_adu=", SIM.readout_noise_adu
          )  # gaussian random number to add to every pixel (0 for PAD)
    # apply Poissonion correction, then scale to ADU, then adc_offset.
    # should be 10 for most Rayonix, Pilatus should be 0, CSPAD should be 0.

    print("detector_psf_type=", SIM.detector_psf_type)
    print("detector_psf_fwhm_mm=", SIM.detector_psf_fwhm_mm)
    print("detector_psf_kernel_radius_pixels=",
          SIM.detector_psf_kernel_radius_pixels)
    SIM.add_noise()  #converts phtons to ADU.

    print("raw_pixels=", SIM.raw_pixels)
    extra = "PREFIX=%s;\nRANK=%d;\n" % (prefix, rank)
    SIM.to_smv_format_py(fileout=smv_fileout,
                         intfile_scale=1,
                         rotmat=True,
                         extra=extra,
                         gz=True)

    # try to write as CBF
    if False:
        import dxtbx
        from dxtbx.format.FormatCBFMiniPilatus import FormatCBFMiniPilatus
        img = dxtbx.load(prefix + ".img")
        print(img)
        FormatCBFMiniPilatus.as_file(detector=img.get_detector(),
                                     beam=img.get_beam(),
                                     gonio=img.get_goniometer(),
                                     scan=img.get_scan(),
                                     data=img.get_raw_data(),
                                     path=prefix + ".cbf")
    SIM.free_all()
Пример #2
0
def run_sim2smv(img_prefix=None, simparams=None,pdb_lines=None,crystal=None,spectra=None,rotation=None,rank=None,fsave=None,sfall_cluster=None,quick=False):
    smv_fileout = fsave

    direct_algo_res_limit = simparams.direct_algo_res_limit

    wavlen, flux, real_wavelength_A = next(spectra) # list of lambdas, list of fluxes, average wavelength
    real_flux = flex.sum(flux)
    assert real_wavelength_A > 0
    # print(rank, " ## real_wavelength_A/real_flux = ", real_wavelength_A, real_flux*1.0/simparams.flux)

    if quick:
        wavlen = flex.double([real_wavelength_A])
        flux = flex.double([real_flux])

    # GF = gen_fmodel(resolution=simparams.direct_algo_res_limit,pdb_text=pdb_lines,algorithm=simparams.fmodel_algorithm,wavelength=real_wavelength_A)
    # GF.set_k_sol(simparams.k_sol) 
    # GF.make_P1_primitive()
    sfall_main = sfall_cluster["main"] #GF.get_amplitudes() 

    # use crystal structure to initialize Fhkl array
    # sfall_main.show_summary(prefix = "Amplitudes used ")
    N = crystal.number_of_cells(sfall_main.unit_cell())

    #print("## number of N = ", N)
    SIM = nanoBragg(detpixels_slowfast=(simparams.detector_size_ny,simparams.detector_size_nx),pixel_size_mm=simparams.pixel_size_mm,\
                Ncells_abc=(N,N,N),wavelength_A=real_wavelength_A,verbose=0)
        # workaround for problem with wavelength array, specify it separately in constructor.
        
    # SIM.adc_offset_adu = 0 # Do not offset by 40
    SIM.adc_offset_adu = 10 # Do not offset by 40
    
    
    SIM.seed = 0
    # SIM.randomize_orientation()
    SIM.mosaic_spread_deg = simparams.mosaic_spread_deg # interpreted by UMAT_nm as a half-width stddev
    SIM.mosaic_domains = simparams.mosaic_domains    # 77 seconds.                                                         
    SIM.distance_mm = simparams.distance_mm

    ## setup the mosaicity
    UMAT_nm = flex.mat3_double()
    mersenne_twister = flex.mersenne_twister(seed=0)
    scitbx.random.set_random_seed(1234)
    rand_norm = scitbx.random.normal_distribution(mean=0, sigma=SIM.mosaic_spread_deg * math.pi/180.)
    g = scitbx.random.variate(rand_norm)
    mosaic_rotation = g(SIM.mosaic_domains)
    for m in mosaic_rotation:
        site = col(mersenne_twister.random_double_point_on_sphere())
        UMAT_nm.append( site.axis_and_angle_as_r3_rotation_matrix(m,deg=False) )
    SIM.set_mosaic_blocks(UMAT_nm)

    ######################
    SIM.beamcenter_convention=convention.ADXV
    SIM.beam_center_mm=(simparams.beam_center_x_mm, simparams.beam_center_y_mm)  # 95.975 96.855
    ######################

    # get same noise each time this test is run
    SIM.seed = 0
    SIM.oversample=simparams.oversample
    SIM.wavelength_A = real_wavelength_A
    SIM.polarization=simparams.polarization
    # this will become F000, marking the beam center
    SIM.default_F=simparams.default_F
    #SIM.missets_deg= (10,20,30)
    
    SIM.Fhkl=sfall_main
    
    Amatrix_rot = (rotation * sqr(sfall_main.unit_cell().orthogonalization_matrix())).transpose()

    SIM.Amatrix_RUB = Amatrix_rot
    #workaround for failing init_cell, use custom written Amatrix setter
    # print("## inside run_sim2smv, Amat_rot = ", Amatrix_rot)
    
    Amat = sqr(SIM.Amatrix).transpose() # recovered Amatrix from SIM
    
    Ori = crystal_orientation.crystal_orientation(Amat, crystal_orientation.basis_type.reciprocal)
    
    SIM.xtal_shape=shapetype.Gauss # both crystal & RLP are Gaussian

    SIM.progress_meter=False

    # SIM.show_params()
    # flux is always in photons/s
    SIM.flux=real_flux
    SIM.exposure_s=simparams.exposure_s 
    # assumes round beam
    SIM.beamsize_mm=simparams.beamsize_mm #cannot make this 3 microns; spots are too intense
    temp=SIM.Ncells_abc
    SIM.Ncells_abc=temp
    

    # print("## domains_per_crystal = ", crystal.domains_per_crystal)
    SIM.raw_pixels *= crystal.domains_per_crystal # must calculate the correct scale!

    # print("## Initial raw_pixels = ", flex.sum(SIM.raw_pixels))

    for x in range(len(flux)):
        # CH = channel_pixels(wavlen[x],flux[x],N,UMAT_nm,Amatrix_rot,sfall_cluster[x],rank)
        # print("## in loop wavlen/flux/real_wavelength_A = ", wavlen[x], flux[x]/real_flux, real_wavelength_A)
        CH = channel_pixels(simparams=simparams,single_wavelength_A=wavlen[x],single_flux=flux[x],N=N,UMAT_nm=UMAT_nm, \
                Amatrix_rot=Amatrix_rot,sfall_channel=sfall_cluster[x],rank=rank)
        SIM.raw_pixels += CH.raw_pixels * crystal.domains_per_crystal
        CHDBG_singleton.extract(channel_no=x, data=CH.raw_pixels)
        CH.free_all()
        # print("## sum raw_pixels after ", x, "is", flex.sum(SIM.raw_pixels))

        
    # rough approximation to water: interpolation points for sin(theta/lambda) vs structure factor
    bg = flex.vec2_double([(0,2.57),(0.0365,2.58),(0.07,2.8),(0.12,5),(0.162,8),(0.2,6.75),(0.18,7.32),(0.216,6.75),(0.236,6.5),(0.28,4.5),(0.3,4.3),(0.345,4.36),(0.436,3.77),(0.5,3.17)])
    SIM.Fbg_vs_stol = bg
    SIM.amorphous_sample_thick_mm = simparams.water_sample_thick_mm
    SIM.amorphous_density_gcm3 = simparams.water_density_gcm3
    SIM.amorphous_molecular_weight_Da = simparams.water_molecular_weight_Da
    SIM.flux=real_flux
    SIM.beamsize_mm=simparams.beamsize_mm   # square (not user specified)
    SIM.exposure_s=simparams.exposure_s     # multiplies flux x exposure
    SIM.add_background()
    

    # rough approximation to air
    bg = flex.vec2_double([(0,14.1),(0.045,13.5),(0.174,8.35),(0.35,4.78),(0.5,4.22)])
    SIM.Fbg_vs_stol = bg 
    SIM.amorphous_sample_thick_mm = simparams.air_sample_thick_mm # between beamstop and collimator
    SIM.amorphous_density_gcm3 = simparams.air_density_gcm3
    SIM.amorphous_sample_molecular_weight_Da = simparams.air_molecular_weight_Da  # nitrogen = N2
    SIM.add_background()

    #apply beamstop mask here

    # settings for CCD
    SIM.detector_psf_kernel_radius_pixels=simparams.detector_psf_kernel_radius_pixels
    SIM.detector_psf_type=shapetype.Unknown # for CSPAD
    SIM.detector_psf_fwhm_mm=simparams.detector_psf_fwhm_mm
    SIM.apply_psf()

    SIM.add_noise() 

    extra = "PREFIX=%s;\nRANK=%d;\n"%(img_prefix,rank)
    SIM.to_smv_format_py(fileout=smv_fileout,intfile_scale=1,rotmat=True,extra=extra,gz=True)
    SIM.free_all()
def run_sim2smv(img_prefix=None,
                simparams=None,
                pdb_lines=None,
                crystal=None,
                spectra=None,
                rotation=None,
                rank=None,
                fsave=None,
                sfall_cluster=None,
                quick=False):
    smv_fileout = fsave

    direct_algo_res_limit = simparams.direct_algo_res_limit

    wavlen, flux, real_wavelength_A = next(
        spectra)  # list of lambdas, list of fluxes, average wavelength
    real_flux = flex.sum(flux)
    assert real_wavelength_A > 0
    # print(rank, " ## real_wavelength_A/real_flux = ", real_wavelength_A, real_flux*1.0/simparams.flux)

    if quick:
        wavlen = flex.double([real_wavelength_A])
        flux = flex.double([real_flux])

    # GF = gen_fmodel(resolution=simparams.direct_algo_res_limit,pdb_text=pdb_lines,algorithm=simparams.fmodel_algorithm,wavelength=real_wavelength_A)
    # GF.set_k_sol(simparams.k_sol)
    # GF.make_P1_primitive()
    sfall_main = sfall_cluster["main"]  #GF.get_amplitudes()

    # use crystal structure to initialize Fhkl array
    # sfall_main.show_summary(prefix = "Amplitudes used ")
    N = crystal.number_of_cells(sfall_main.unit_cell())

    #print("## number of N = ", N)
    SIM = nanoBragg(detpixels_slowfast=(simparams.detector_size_ny,simparams.detector_size_nx),pixel_size_mm=simparams.pixel_size_mm,\
                Ncells_abc=(N,N,N),wavelength_A=real_wavelength_A,verbose=0)
    # workaround for problem with wavelength array, specify it separately in constructor.

    # SIM.adc_offset_adu = 0 # Do not offset by 40
    SIM.adc_offset_adu = 10  # Do not offset by 40

    SIM.seed = 0
    # SIM.randomize_orientation()
    SIM.mosaic_spread_deg = simparams.mosaic_spread_deg  # interpreted by UMAT_nm as a half-width stddev
    SIM.mosaic_domains = simparams.mosaic_domains  # 77 seconds.
    SIM.distance_mm = simparams.distance_mm

    ## setup the mosaicity
    UMAT_nm = flex.mat3_double()
    mersenne_twister = flex.mersenne_twister(seed=0)
    scitbx.random.set_random_seed(1234)
    rand_norm = scitbx.random.normal_distribution(mean=0,
                                                  sigma=SIM.mosaic_spread_deg *
                                                  math.pi / 180.)
    g = scitbx.random.variate(rand_norm)
    mosaic_rotation = g(SIM.mosaic_domains)
    for m in mosaic_rotation:
        site = col(mersenne_twister.random_double_point_on_sphere())
        UMAT_nm.append(site.axis_and_angle_as_r3_rotation_matrix(m, deg=False))
    SIM.set_mosaic_blocks(UMAT_nm)

    ######################
    SIM.beamcenter_convention = convention.ADXV
    SIM.beam_center_mm = (simparams.beam_center_x_mm,
                          simparams.beam_center_y_mm)  # 95.975 96.855
    ######################

    # get same noise each time this test is run
    SIM.seed = 0
    SIM.oversample = simparams.oversample
    SIM.wavelength_A = real_wavelength_A
    SIM.polarization = simparams.polarization
    # this will become F000, marking the beam center
    SIM.default_F = simparams.default_F
    #SIM.missets_deg= (10,20,30)

    SIM.Fhkl = sfall_main

    Amatrix_rot = (
        rotation *
        sqr(sfall_main.unit_cell().orthogonalization_matrix())).transpose()

    SIM.Amatrix_RUB = Amatrix_rot
    #workaround for failing init_cell, use custom written Amatrix setter
    # print("## inside run_sim2smv, Amat_rot = ", Amatrix_rot)

    Amat = sqr(SIM.Amatrix).transpose()  # recovered Amatrix from SIM

    Ori = crystal_orientation.crystal_orientation(
        Amat, crystal_orientation.basis_type.reciprocal)

    print(fsave, "Amatrix_rot", Amatrix_rot)
    print(fsave, "Amat", Amat)
    print(fsave, "Ori", Ori)
    print(fsave, "rotation", rotation)
    print(fsave, "sqr(sfall_main.unit_cell().orthogonalization_matrix())",
          sqr(sfall_main.unit_cell().orthogonalization_matrix()))

    SIM.free_all()
Пример #4
0
def run_sim2smv(Nshot_max, odir, prefix, rank, n_jobs, save_bragg=False, 
            save_smv=True, save_h5 =False, return_pixels=False):

  from six.moves import range, StringIO
  from six.moves import cPickle as pickle
  from cxid9114.sim import sim_utils
  import os
  import h5py
  import math
  import sys
  import numpy as np
  from IPython import embed
  from cxid9114.bigsim.bigsim_geom import DET,BEAM
  import scitbx
  from scitbx.array_family import flex
  from scitbx.matrix import sqr,col
  from simtbx.nanoBragg import shapetype
  from simtbx.nanoBragg import nanoBragg
  import libtbx.load_env # possibly implicit
  from libtbx.development.timers import Profiler
  from cctbx import crystal,crystal_orientation
  from LS49.sim.step4_pad import microcrystal
  from cxid9114 import utils
  from cxid9114.parameters import ENERGY_CONV, ENERGY_HIGH, ENERGY_LOW
  from cxid9114.bigsim import sim_spectra
 
  
  odir_j = os.path.join( odir, "job%d" % rank)
  if not os.path.exists(odir_j):
      os.makedirs(odir_j)

  add_noise = False
  add_background = False
  overwrite = True #$False
  sample_thick_mm = 0.005  # 50 micron GDVN nozzle makes a ~5ish micron jet
  air_thick_mm =0  # mostly vacuum, maybe helium layer of 1 micron
  flux_ave=2e11
  add_spots_algorithm="cuda"
  big_data = "." # directory location for reference files
  detpixels_slowfast = (1800,1800)
  pixsize_mm=0.11
  distance_mm = 125
  offset_adu=30
  mos_spread_deg=0.015
  mos_doms=1000
  beam_size_mm=0.001
  exposure_s=1
  use_microcrystal=True #False
  Ncells_abc=(120,120,120)
  Deff_A = 2200
  length_um = 2.2
  timelog = False
  background = utils.open_flex("background")
 
  crystal = microcrystal(Deff_A = Deff_A, length_um = length_um, 
        beam_diameter_um = beam_size_mm*1000, verbose=False) 
  spec_file =  h5py.File("simMe_data_run62.h5", "r")
  spec_data = spec_file["hist_spec"]
  Umat_data = spec_file["Umats"]
  en_chans = spec_file["energy_bins"][()]
  ilow = np.abs(en_chans - ENERGY_LOW).argmin()
  ihigh = np.abs(en_chans - ENERGY_HIGH).argmin()
  wave_chans = ENERGY_CONV/en_chans
  sfall_main = sim_spectra.load_spectra("test_sfall.h5")
    
  Nshot = spec_data.shape[0]
    
  idx_range = np.array_split(np.arange(Nshot), n_jobs)
    
  Nshot_per_job = len(idx_range[rank])
  if Nshot_max  > 0 :
    Nshot_per_job = min( Nshot_max, Nshot_per_job)
  
  print ("Job %d: Simulating %d shots" % (rank, Nshot_per_job))
 
  istart = idx_range[rank][0]
  istop = istart + Nshot_per_job
  smi_stride = 10
  for idx in range( istart, istop): 
    print ("<><><><><><><><><><><><><><>")
    print ("Job %d; Image %d (%d - %d)" % (rank, idx+1, istart, istop))
    print ("<><><><><><><><><><><><><><>")
    
    smv_fileout = os.path.join( odir_j, prefix % idx + ".img")
    h5_fileout = smv_fileout + ".h5"
    
    if os.path.exists(smv_fileout) and not overwrite and save_smv:
        print("Shot %s exists: moving on" % smv_fileout)
        continue
    
    if os.path.exists(h5_fileout) and not overwrite and save_h5:
        print("Shot %s exists: moving on" % h5_fileout)
        continue
    
    if (rank==0 and idx % smi_stride==0):
      print("GPU status")
      os.system("nvidia-smi")
      
      print("\n\n")
      print("CPU memory usage")
      mem_usg= """ps -U dermen --no-headers -o rss | awk '{ sum+=$1} END {print int(sum/1024) "MB consumed by CPU user"}'"""
      os.system(mem_usg)
    spec = spec_data[2]
    rotation = sqr(Umat_data[2])
    wavelength_A = np.mean(wave_chans)
  
    spectra = iter([(wave_chans, spec, wavelength_A)])
  
    direct_algo_res_limit = 1.7

    wavlen, flux, wavelength_A = next(spectra) # list of lambdas, list of fluxes, average wavelength
    assert wavelength_A > 0
    assert (len(wavlen)==len(flux)==len(sfall_main))

    N = crystal.number_of_cells(sfall_main[0].unit_cell())
    if use_mcrocrystal:
      Ncells_abc = (N,N,N)  
    
    flux *= 0
    flux[ilow] = 1e12
    flux[ihigh]=1e12
    
    UMAT_nm = flex.mat3_double()
    mersenne_twister = flex.mersenne_twister(seed=0)
    scitbx.random.set_random_seed(1234)
    rand_norm = scitbx.random.normal_distribution(mean=0, sigma=mos_spread_deg * math.pi/180.)
    g = scitbx.random.variate(rand_norm)
    mosaic_rotation = g(mos_doms)
    for m in mosaic_rotation:
      site = col(mersenne_twister.random_double_point_on_sphere())
      UMAT_nm.append( site.axis_and_angle_as_r3_rotation_matrix(m,deg=False) )
    
    Amatrix_rot = (rotation * sqr(sfall_main[0].unit_cell().orthogonalization_matrix())).transpose()
    
    #SIM = nanoBragg(detpixels_slowfast=detpixels_slowfast,
    #      pixel_size_mm=pixsize_mm,Ncells_abc=Ncells_abc,
    #      wavelength_A=wavelength_A,verbose=verbose)
    SIM = nanoBragg(detector=DET, beam=BEAM, panel_id=0,verbose=verbose)

    SIM.adc_offset_adu = offset_adu # Do not offset by 40
    SIM.mosaic_spread_deg = mos_spread_deg # interpreted by UMAT_nm as a half-width stddev
    SIM.mosaic_domains = mos_doms
    SIM.distance_mm=distance_mm
    SIM.set_mosaic_blocks(UMAT_nm)
    SIM.seed = 1
    SIM.oversample=1
    SIM.wavelength_A = wavelength_A
    SIM.polarization=1
    SIM.default_F=0
    SIM.Fhkl=sfall_main[0].amplitudes()
    SIM.progress_meter=False
    SIM.flux=flux_ave
    SIM.exposure_s=exposure_s 
    SIM.beamsize_mm=beam_size_mm 
    SIM.Ncells_abc=Ncells_abc
    SIM.xtal_shape=shapetype.Gauss 
    
    idxpath = "try3_idx2/job0/dump_0_data.pkl"
    Amat = sim_utils.Amatrix_dials2nanoBragg(utils.open_flex(idxpath)["crystalAB"])
    #SIM.Umatrix = rotation.elems
    #SIM.unit_cell_Adeg = sfall_main[0].unit_cell()
    
    #SIM2 = nanoBragg(detector=DET, beam=BEAM, panel_id=0,verbose=verbose)

    #SIM2.adc_offset_adu = offset_adu # Do not offset by 40
    #SIM2.mosaic_spread_deg = mos_spread_deg # interpreted by UMAT_nm as a half-width stddev
    #SIM2.mosaic_domains = mos_doms
    #SIM2.distance_mm=distance_mm
    #SIM2.set_mosaic_blocks(UMAT_nm)
    #SIM2.seed = 1
    #SIM2.oversample=1
    #SIM2.wavelength_A = wavelength_A
    #SIM2.polarization=1
    #SIM2.default_F=0
    #SIM2.Fhkl=sfall_main[0].amplitudes()
    #SIM2.progress_meter=False
    #SIM2.flux=flux_ave
    #SIM2.exposure_s=exposure_s 
    #SIM2.beamsize_mm=beam_size_mm 
    #SIM2.Ncells_abc=Ncells_abc
    #SIM2.xtal_shape=shapetype.Gauss 
    #SIM2.Umatrix = rotation.elems
    #SIM2.unit_cell_Adeg = sfall_main[0].unit_cell()
    
    #SIM.Amatrix_RUB = Amatrix_rot
    #SIM.Amatrix = Amatrix_rot.inverse()
    
    raw_pixel_sum = flex.double(len(SIM.raw_pixels))
    Nflux = len(flux)
    print("Beginning the loop")
    for x in range(Nflux):
      if x % 10==0:
        print("+++++++++++++++++++++++++++++++++++++++ Wavelength %d / %d" % (x+1, Nflux) , end="\r")
      if flux[x] ==0:
        continue
      #SIM.Amatrix = Amatrix_rot.inverse() 
      print (SIM.Ncells_abc)
      SIM.wavelength_A=wavlen[x]
      SIM.flux=flux[x]
      SIM.Fhkl=sfall_main[x].amplitudes()
      SIM.Amatrix = Amat#Amatrix_rot.inverse()
      
      #sim_utils.compare_sims(SIM, SIM2)
      #SIM.Ncells_abc=Ncells_abc
      #SIM.adc_offset_adu = offset_adu
      #SIM.mosaic_spread_deg = mos_spread_deg # interpreted by UMAT_nm as a half-width stddev
      #SIM.mosaic_domains = mos_doms  #
      #SIM.distance_mm=distance_mm
      #SIM.set_mosaic_blocks(UMAT_nm)
      #SIM.seed = 1
      #SIM.polarization=1
      #SIM.default_F=0
      #SIM.xtal_shape=shapetype.Gauss 
      #SIM.progress_meter=False 
      #SIM.exposure_s = exposure_s
      #SIM.beamsize_mm=beam_size_mm 

      SIM.timelog=timelog
      SIM.device_Id=rank
      SIM.raw_pixels *= 0  # just in case!
      SIM.add_nanoBragg_spots_cuda()
    
      if use_microcrystal:
        raw_pixel_sum += SIM.raw_pixels * crystal.domains_per_crystal

    print()

    SIM.raw_pixels = raw_pixel_sum
    if add_background:
        SIM.raw_pixels = SIM.raw_pixels + background 
    
    SIM.detector_psf_kernel_radius_pixels=5;
    #SIM.detector_psf_fwhm_mm=0.08;
    #SIM.detector_psf_type=shapetype.Fiber # rayonix=Fiber, CSPAD=None (or small Gaussian)
    SIM.detector_psf_type=shapetype.Unknown # for CSPAD
    SIM.detector_psf_fwhm_mm=0
    SIM.quantum_gain = 28.
    #SIM.apply_psf()
    if add_noise:
        SIM.add_noise() #converts phtons to ADU.
    extra = "PREFIX=%s;\nRANK=%d;\n"%(prefix,rank)
  
    out =  SIM.raw_pixels.as_numpy_array() 
  
    if save_smv:
      SIM.to_smv_format_py(fileout=smv_fileout,intfile_scale=1,rotmat=True,extra=extra,gz=True)
    elif save_h5:
      f = h5py.File(h5_fileout, "w")
      f.create_dataset("bigsim_d9114", 
        data=SIM.raw_pixels.as_numpy_array().astype(np.uint16).reshape(detpixels_slowfast), 
        compression="lzf")
      f.close()
 
    if npout is not None: 
        np.save(npout, SIM.raw_pixels.as_numpy_array())
    SIM.free_all()
Пример #5
0
def run_paramList(Ntrials, odir, tag, rank, n_jobs, pkl_file):

  import os
  import sys
  from copy import deepcopy  
  
  import numpy as np
  import h5py
  from IPython import embed
  from scipy.ndimage.morphology import binary_dilation
  
  import scitbx
  from scitbx.array_family import flex
  from scitbx.matrix import sqr,col
  from simtbx.nanoBragg import shapetype
  from simtbx.nanoBragg import nanoBragg
  import libtbx.load_env  # possibly implicit
  from libtbx.development.timers import Profiler
  from dxtbx.model.crystal import CrystalFactory 
  from cctbx import crystal,crystal_orientation
  
  from cxid9114 import utils
  from cxid9114.sim import sim_utils
  from cxid9114.spots import spot_utils
  from cxid9114.bigsim.bigsim_geom import DET,BEAM
  from cxid9114.parameters import ENERGY_CONV, ENERGY_HIGH, ENERGY_LOW
  from cxid9114.refine.jitter_refine import make_param_list
  from cxid9114.bigsim import sim_spectra
  
  from LS49.sim.step4_pad import microcrystal

  data_pack = utils.open_flex(pkl_file)
  CRYST = data_pack['crystalAB']

  mos_spread_deg=0.015
  mos_doms=1000
  beam_size_mm=0.001
  exposure_s=1
  use_microcrystal=True 
  Deff_A = 2200
  length_um = 2.2
  timelog = False
 
  crystal = microcrystal(Deff_A = Deff_A, length_um = length_um, 
        beam_diameter_um = beam_size_mm*1000, verbose=False) 
  spec_file =  h5py.File("simMe_data_run62.h5", "r")
  spec_data = spec_file["hist_spec"]
  Umat_data = spec_file["Umats"]
  en_chans = spec_file["energy_bins"][()]
  ilow = np.abs(en_chans - ENERGY_LOW).argmin()
  ihigh = np.abs(en_chans - ENERGY_HIGH).argmin()
  wave_chans = ENERGY_CONV/en_chans
  sfall_main = sim_spectra.load_spectra("test_sfall.h5")
  
  refls_strong = data_pack['refls_strong'] 
  strong_mask_img = spot_utils.strong_spot_mask(
                refls_strong, (1800,1800) ) 

  # edge detection in the ground truth strong mask image
  reference_img = (binary_dilation(strong_mask_img, iterations=1).astype(int) - 
                strong_mask_img.astype(int) ).astype(bool)
  
  param_fileout = os.path.join( odir, "rank%d_%s.pkl" % (rank, tag))

  param_list = make_param_list(
            CRYST, DET, BEAM, Ntrials, 
              rot=0.09, cell=0.1, eq=(1,1,0), 
            min_Ncell=20, max_Ncell=40, 
              min_mos_spread=0.005, max_mos_spread=0.02)

  for p in param_list:
      print(p['crystal'].get_unit_cell().parameters())
  shot_idx = int(data_pack['img_f'].split("_")[-1].split(".")[0])
  Fluxes = spec_data[2] #shot_idx]
  Pmax = param_list[0]
  F1max = 0
  for i_trial in range(Ntrials):
    print ("<><><><><><><><><><><><><><>")
    print ("Job %d; Trial %d / %d" % (rank, i_trial+1, Ntrials))
    print ("<><><><><><><><><><><><><><>")
    
    if (rank==0 and i_trial % smi_stride==0):
      print("GPU status")
      os.system("nvidia-smi")
      
      print("\n\n")
      print("CPU memory usage")
      mem_usg= """ps -U dermen --no-headers -o rss | awk '{ sum+=$1} END {print int(sum/1024) "MB consumed by CPU user"}'"""
      os.system(mem_usg)
    
 
    assert (len(wave_chans)==len(Fluxes)==len(sfall_main))
    if np.sum(Fluxes)==0:
        print ("Cannot simulate with an all-zeros spectrum!")
        sys.exit()
    
    N = crystal.number_of_cells(sfall_main[0].unit_cell())
    Ncells_abc = (N,N,N)  
    
    if force_twocolor: 
        Fluxes *= 0
        Fluxes[ilow] = 1e12
        Fluxes[ihigh]=1e12
    
    P = param_list[i_trial]
    simsAB = sim_utils.sim_twocolors2(
        P['crystal'],
        DET,
        BEAM,
        sfall_main,
        en_chans,
        Fluxes,
        pids = None,
        profile="gauss",
        oversample=0,
        Ncells_abc = Ncells_abc, #P['Ncells_abc'],
        mos_dom=mos_doms,
        verbose=verbose,
        mos_spread=mos_spread_deg, 
        #@mos_spread=P['mos_spread'],
        cuda=True, 
        device_Id=rank,
        beamsize_mm=beamsize_mm,
        exposure_s=exposure_s,
        boost=crystal.domains_per_crystal)
    
    out = np.sum( [ simsAB[i][0] for i in simsAB.keys() if simsAB[i]], axis=0)
    if out.shape==():
        print("This simsAB output has an empty shape, something is wrong!")
        sys.exit()
    
    trial_refls = spot_utils.refls_from_sims([out], DET, BEAM, thresh=thresh)

    trial_spotmask = spot_utils.strong_spot_mask(
                 trial_refls, (1800,1800) ) 

    trial_img = (binary_dilation(trial_spotmask, iterations=1).astype(int) - 
                trial_spotmask.astype(int) ).astype(bool)

    comp_img = trial_img.astype(int) + reference_img.astype(int)*2

    Nfalse_neg = (comp_img==2).sum()  # reference has signal but trial doesnt
    Nfalse_pos = (comp_img==1).sum()  # trial has signal but reference doesnt
    Ntrue_pos = (comp_img==3).sum()  #

    Precision = float(Ntrue_pos) / (Ntrue_pos + Nfalse_pos)
    Recall = float(Ntrue_pos) / (Ntrue_pos + Nfalse_neg)
    
    F1 = 2.*(Precision*Recall) / (Precision+Recall)
    if F1 > F1max:
        Pmax = {'crystal': P['crystal'], 
                'mos_spread': P['mos_spread'], 
                'Ncells_abc': P['Ncells_abc'], "F1": F1}
        F1max = F1

    print("Rank %d, Trial %d: F1score = %.5f" % (rank, i_trial, F1))
    
  utils.save_flex(Pmax, param_fileout)
  return F1max 
Пример #6
0
def run_sim2smv(Nshot_max, odir, tag, rank, n_jobs, save_bragg=False, 
            save_smv=True, save_h5 =False, return_pixels=False):

  import os
  import h5py
  import math
  import sys
  import numpy as np
  from IPython import embed
  from cxid9114.bigsim.bigsim_geom import DET,BEAM
  import scitbx
  from scitbx.array_family import flex
  from scitbx.matrix import sqr,col
  from simtbx.nanoBragg import shapetype
  from simtbx.nanoBragg import nanoBragg
  import libtbx.load_env # possibly implicit
  from libtbx.development.timers import Profiler
  from cctbx import crystal,crystal_orientation
  from LS49.sim.step4_pad import microcrystal
  from cxid9114 import utils
  from cxid9114.sim import sim_utils
  from cxid9114.parameters import ENERGY_CONV, ENERGY_HIGH, ENERGY_LOW
  from cxid9114.bigsim import sim_spectra
  from dxtbx.model.crystal import CrystalFactory 
  
  odir_j = os.path.join( odir, "job%d" % rank)
  if not os.path.exists(odir_j):
      os.makedirs(odir_j)

  cryst_descr = {'__id__': 'crystal',
              'real_space_a': (79, 0, 0),
              'real_space_b': (0, 79, 0),
              'real_space_c': (0, 0, 38),
              'space_group_hall_symbol': '-P 4 2'} 
  Crystal = CrystalFactory.from_dict(cryst_descr)

  mos_spread_deg=0.015
  mos_doms=1000
  beam_size_mm=0.001
  exposure_s=1
  use_microcrystal=True 
  Deff_A = 2200
  length_um = Deff_A/1000.
  timelog = False
  if add_background:
    background = utils.open_flex("background").as_numpy_array()
 
  crystal = microcrystal(Deff_A = Deff_A, length_um = length_um, 
        beam_diameter_um = beam_size_mm*1000, verbose=False) 
  spec_file =  h5py.File("simMe_data_run62.h5", "r")
  spec_data = spec_file["hist_spec"]
  Umat_data = spec_file["Umats"]
  en_chans = spec_file["energy_bins"][()]
  ilow = np.abs(en_chans - ENERGY_LOW).argmin()
  ihigh = np.abs(en_chans - ENERGY_HIGH).argmin()
  wave_chans = ENERGY_CONV/en_chans
  sfall_main = sim_spectra.load_spectra("test_sfall.h5")
    
  Nshot = spec_data.shape[0]
    
  idx_range = np.array_split(np.arange(Nshot), n_jobs)
    
  Nshot_per_job = len(idx_range[rank])
  if Nshot_max  > 0 :
    Nshot_per_job = min( Nshot_max, Nshot_per_job)
  
  print ("Job %d: Simulating %d shots" % (rank, Nshot_per_job))
 
  istart = idx_range[rank][0]
  istop = istart + Nshot_per_job
  smi_stride = 10
  for idx in range( istart, istop): 
    print ("<><><><><><><><><><><><><><>")
    print ("Job %d; Image %d (%d - %d)" % (rank, idx+1, istart, istop))
    print ("<><><><><><><><><><><><><><>")
    
    smv_fileout = os.path.join( odir_j, "%s_%d.img" % (tag,idx))
    h5_fileout = smv_fileout + ".h5"
    
    if os.path.exists(smv_fileout) and not overwrite and save_smv:
        print("Shot %s exists: moving on" % smv_fileout)
        continue
    
    if os.path.exists(h5_fileout) and not overwrite and save_h5:
        print("Shot %s exists: moving on" % h5_fileout)
        continue
    
    if (rank==0 and idx % smi_stride==0):
      print("GPU status")
      os.system("nvidia-smi")
      
      print("\n\n")
      print("CPU memory usage")
      mem_usg= """ps -U dermen --no-headers -o rss | awk '{ sum+=$1} END {print int(sum/1024) "MB consumed by CPU user"}'"""
      os.system(mem_usg)
    if force_index is not None:
        spec = spec_data[force_index]
        rotation = sqr(Umat_data[force_index])
    else:
        spec = spec_data[idx]
        rotation = sqr(Umat_data[idx])
    wavelength_A = np.mean(wave_chans)
  
    spectra = iter([(wave_chans, spec, wavelength_A)])
    wavlen, flux, wavelength_A = next(spectra) # list of lambdas, list of fluxes, average wavelength
    assert wavelength_A > 0
    assert (len(wavlen)==len(flux)==len(sfall_main))
    if np.sum(flux)==0:
        continue
    N = crystal.number_of_cells(sfall_main[0].unit_cell())
    Ncells_abc = (N,N,N)  
    if not on_axis:
        Crystal.set_U(rotation)
    
    if idx_path is not None:
        assert( model_file is None)
        Crystal = utils.open_flex(idx_path)['crystalAB']
    
    if model_file is not None:
        assert( idx_path is None)
        P = utils.open_flex(model_file)
        Crystal = P['crystal']
        #mos_spread_deg = P['mos_spread']
        #Ncells_abc = P['Ncells_abc']
    
    if force_twocolor: 
        flux *= 0
        flux[ilow] = 1e11
        flux[ihigh]=1e11
    
    simsAB = sim_utils.sim_twocolors2(
        Crystal,
        DET,
        BEAM,
        sfall_main,
        en_chans,
        flux,
        pids = None,
        profile="gauss",
        oversample=1,
        Ncells_abc = Ncells_abc,
        mos_dom=mos_doms,
        verbose=verbose,
        mos_spread=mos_spread_deg,
        cuda=True, 
        device_Id =rank,
        beamsize_mm=beamsize_mm,
        exposure_s=exposure_s,
        accumulate=True,
        boost=crystal.domains_per_crystal)
   
    if not simsAB:
        continue
    
    out = simsAB[0] 
    
    if add_background:
        out = out + background
    
    if add_noise:
        SIM = nanoBragg(detector=DET, beam=BEAM)
        SIM.exposure_s = exposure_s
        SIM.flux = np.sum(flux)
        SIM.raw_pixels = flex.double(out.ravel())
        SIM.detector_psf_kernel_radius_pixels=5;
        SIM.detector_psf_type=shapetype.Unknown  # for CSPAD
        SIM.detector_psf_fwhm_mm=0
        SIM.quantum_gain = 28 
        SIM.add_noise()
        out = SIM.raw_pixels.as_numpy_array().reshape(out.shape)

    f = h5py.File(h5_fileout, "w")
    f.create_dataset("bigsim_d9114", 
        data=out, 
        compression="lzf")

    ua,ub,uc = Crystal.get_real_space_vectors()
    f.create_dataset("real_space_a", data=ua)
    f.create_dataset("real_space_b", data=ub)
    f.create_dataset("real_space_c", data=uc)
    f.create_dataset("space_group_hall_symbol", 
                data=Crystal.get_space_group().info().type().hall_symbol())
    f.create_dataset("Umatrix", data=Crystal.get_U())
    f.create_dataset("fluxes",data=flux)
    f.create_dataset("energies", data=en_chans)
    f.close()
 
    if npout is not None: 
        np.save(npout, out) # SIM.raw_pixels.as_numpy_array())
Пример #7
0
def run_sim2smv(prefix,
                crystal,
                spectra,
                rotation,
                rank,
                gpu_channels_singleton,
                params,
                quick=False,
                save_bragg=False,
                sfall_channels=None):
    smv_fileout = prefix + ".img"
    burst_buffer_expand_dir = os.path.expandvars(params.logger.outdir)
    burst_buffer_fileout = os.path.join(burst_buffer_expand_dir, smv_fileout)
    reference_fileout = os.path.join(".", smv_fileout)
    if not quick:
        if not write_safe(reference_fileout):
            print("File %s already exists, skipping in rank %d" %
                  (reference_fileout, rank))
            return

    direct_algo_res_limit = 1.7

    wavlen, flux, wavelength_A = next(
        spectra)  # list of lambdas, list of fluxes, average wavelength
    assert wavelength_A > 0

    # use crystal structure to initialize Fhkl array
    N = crystal.number_of_cells(sfall_channels[0].unit_cell())

    #SIM = nanoBragg(detpixels_slowfast=(2000,2000),pixel_size_mm=0.11,Ncells_abc=(5,5,5),verbose=0)
    SIM = nanoBragg(
        detpixels_slowfast=(3000, 3000),
        pixel_size_mm=0.11,
        Ncells_abc=(N, N, N),
        # workaround for problem with wavelength array, specify it separately in constructor.
        wavelength_A=wavelength_A,
        verbose=0)
    SIM.adc_offset_adu = 0  # Do not offset by 40
    SIM.adc_offset_adu = 10  # Do not offset by 40
    import sys
    if len(sys.argv) > 2:
        SIM.seed = -int(sys.argv[2])
    if len(sys.argv) > 1:
        if sys.argv[1] == "random": SIM.randomize_orientation()
    SIM.mosaic_spread_deg = 0.05  # interpreted by UMAT_nm as a half-width stddev
    SIM.mosaic_domains = 25  # 77 seconds.  With 100 energy points, 7700 seconds (2 hours) per image
    # 3000000 images would be 100000 hours on a 60-core machine (dials), or 11.4 years
    # using 2 nodes, 5.7 years.  Do this at SLAC? NERSC? combination of all?
    # SLAC downtimes: Tues Dec 5 (24 hrs), Mon Dec 11 (72 hrs), Mon Dec 18 light use, 24 days
    # mosaic_domains setter must come after mosaic_spread_deg setter
    SIM.distance_mm = 141.7

    UMAT_nm = flex.mat3_double()
    mersenne_twister = flex.mersenne_twister(seed=0)
    scitbx.random.set_random_seed(1234)
    rand_norm = scitbx.random.normal_distribution(mean=0,
                                                  sigma=SIM.mosaic_spread_deg *
                                                  math.pi / 180.)
    g = scitbx.random.variate(rand_norm)
    mosaic_rotation = g(SIM.mosaic_domains)
    for m in mosaic_rotation:
        site = col(mersenne_twister.random_double_point_on_sphere())
        UMAT_nm.append(site.axis_and_angle_as_r3_rotation_matrix(m, deg=False))
    SIM.set_mosaic_blocks(UMAT_nm)

    #SIM.detector_thick_mm = 0.5 # = 0 for Rayonix
    #SIM.detector_thicksteps = 1 # should default to 1 for Rayonix, but set to 5 for CSPAD
    #SIM.detector_attenuation_length_mm = default is silicon

    # get same noise each time this test is run
    SIM.seed = 1
    SIM.oversample = 1
    SIM.wavelength_A = wavelength_A
    SIM.polarization = 1
    # this will become F000, marking the beam center
    SIM.default_F = 0
    SIM.Fhkl = sfall_channels[0]  # instead of sfall_main
    Amatrix_rot = (rotation * sqr(
        sfall_channels[0].unit_cell().orthogonalization_matrix())).transpose()

    SIM.Amatrix_RUB = Amatrix_rot
    #workaround for failing init_cell, use custom written Amatrix setter
    print("unit_cell_Adeg=", SIM.unit_cell_Adeg)
    print("unit_cell_tuple=", SIM.unit_cell_tuple)
    Amat = sqr(SIM.Amatrix).transpose()  # recovered Amatrix from SIM
    from cctbx import crystal_orientation
    Ori = crystal_orientation.crystal_orientation(
        Amat, crystal_orientation.basis_type.reciprocal)

    # fastest option, least realistic
    SIM.xtal_shape = shapetype.Gauss_argchk  # both crystal & RLP are Gaussian
    # only really useful for long runs
    SIM.progress_meter = False
    # prints out value of one pixel only.  will not render full image!
    # flux is always in photons/s
    SIM.flux = 1e12
    SIM.exposure_s = 1.0  # so total fluence is e12
    # assumes round beam
    SIM.beamsize_mm = 0.003  #cannot make this 3 microns; spots are too intense
    temp = SIM.Ncells_abc
    SIM.Ncells_abc = temp

    # rough approximation to water: interpolation points for sin(theta/lambda) vs structure factor
    water_bg = flex.vec2_double([(0, 2.57), (0.0365, 2.58), (0.07, 2.8),
                                 (0.12, 5), (0.162, 8), (0.18, 7.32),
                                 (0.2, 6.75), (0.216, 6.75), (0.236, 6.5),
                                 (0.28, 4.5), (0.3, 4.3), (0.345, 4.36),
                                 (0.436, 3.77), (0.5, 3.17)])
    assert [a[0] for a in water_bg] == sorted([a[0] for a in water_bg])
    # rough approximation to air
    air_bg = flex.vec2_double([(0, 14.1), (0.045, 13.5), (0.174, 8.35),
                               (0.35, 4.78), (0.5, 4.22)])
    assert [a[0] for a in air_bg] == sorted([a[0] for a in air_bg])

    # simulated crystal is only 125 unit cells (25 nm wide)
    # amplify spot signal to simulate physical crystal of 4000x larger: 100 um (64e9 x the volume)
    SIM.raw_pixels *= crystal.domains_per_crystal
    # must calculate the correct scale!

    use_exascale_api = os.environ.get("USE_EXASCALE_API", "True")
    cache_fhkl_on_gpu = os.environ.get("CACHE_FHKL_ON_GPU", "True")
    assert use_exascale_api in ["True", "False"
                                ] and cache_fhkl_on_gpu in ["True", "False"]
    use_exascale_api = (use_exascale_api == "True")
    cache_fhkl_on_gpu = (cache_fhkl_on_gpu == "True")
    QQ = Profiler("nanoBragg Bragg spots rank %d" % (rank))
    if use_exascale_api:
        #something new
        devices_per_node = int(os.environ["DEVICES_PER_NODE"])
        SIM.device_Id = rank % devices_per_node

        assert gpu_channels_singleton.get_deviceID() == SIM.device_Id
        if cache_fhkl_on_gpu:  #flag to switch on GPU energy channels
            if gpu_channels_singleton.get_nchannels() == 0:  # if uninitialized
                P = Profiler("Initialize the channels singleton rank %d" %
                             (rank))
                for x in range(len(flux)):
                    gpu_channels_singleton.structure_factors_to_GPU_direct(
                        x, sfall_channels[x].indices(),
                        sfall_channels[x].data())
                del P
                import time
                print("datetime for channels singleton rank %d" % (rank),
                      time.time())

        # allocate GPU arrays
        SIM.allocate()

        # loop over energies
        for x in range(len(flux)):
            P = Profiler("USE_EXASCALE_API nanoBragg Python and C++ rank %d" %
                         (rank))

            print("USE_EXASCALE_API+++++++++++++++++++++++ Wavelength", x)
            # from channel_pixels function
            SIM.wavelength_A = wavlen[x]
            SIM.flux = flux[x]
            if cache_fhkl_on_gpu:  # new interface, use singleton to store all-image energy channels
                SIM.add_energy_channel_from_gpu_amplitudes(
                    x, gpu_channels_singleton)
            else:  # old interface, host-to-device each energy channel, each image
                SIM.Fhkl = sfall_channels[x]
                SIM.add_energy_channel_cuda()
            del P
        SIM.scale_in_place(
            crystal.domains_per_crystal)  # apply scale directly on GPU
        SIM.wavelength_A = wavelength_A  # return to canonical energy for subsequent background

        if add_background_algorithm == "cuda":
            QQ = Profiler("nanoBragg background rank %d" % (rank))
            SIM.Fbg_vs_stol = water_bg
            SIM.amorphous_sample_thick_mm = 0.1
            SIM.amorphous_density_gcm3 = 1
            SIM.amorphous_molecular_weight_Da = 18
            SIM.flux = 1e12
            SIM.beamsize_mm = 0.003  # square (not user specified)
            SIM.exposure_s = 1.0  # multiplies flux x exposure
            SIM.add_background()
            SIM.Fbg_vs_stol = air_bg
            SIM.amorphous_sample_thick_mm = 10  # between beamstop and collimator
            SIM.amorphous_density_gcm3 = 1.2e-3
            SIM.amorphous_sample_molecular_weight_Da = 28  # nitrogen = N2
            SIM.add_background()

        # deallocate GPU arrays
        SIM.get_raw_pixels()  # updates SIM.raw_pixels from GPU
        SIM.deallocate()
        SIM.Amatrix_RUB = Amatrix_rot  # return to canonical orientation
        del QQ
    else:
        for x in range(len(flux)):
            if rank in [0, 7]:
                P = Profiler("nanoBragg Python and C++ rank %d" % (rank))

            if rank in [0, 7]:
                print("+++++++++++++++++++++++++++++++++++++++ Wavelength", x)
            CH = channel_pixels(wavlen[x], flux[x], N, UMAT_nm, Amatrix_rot,
                                rank, sfall_channels[x])
            SIM.raw_pixels += CH.raw_pixels * crystal.domains_per_crystal
            CHDBG_singleton.extract(channel_no=x, data=CH.raw_pixels)
            CH.free_all()

            if rank in [0, 7]: del P

    if add_background_algorithm in ["jh", "sort_stable"]:
        QQ = Profiler("nanoBragg background rank %d" % (rank))

        SIM.Fbg_vs_stol = water_bg
        SIM.amorphous_sample_thick_mm = 0.1
        SIM.amorphous_density_gcm3 = 1
        SIM.amorphous_molecular_weight_Da = 18
        SIM.flux = 1e12
        SIM.beamsize_mm = 0.003  # square (not user specified)
        SIM.exposure_s = 1.0  # multiplies flux x exposure
        SIM.add_background(
            sort_stable=(add_background_algorithm == "sort_stable"))

        SIM.Fbg_vs_stol = air_bg
        SIM.amorphous_sample_thick_mm = 10  # between beamstop and collimator
        SIM.amorphous_density_gcm3 = 1.2e-3
        SIM.amorphous_sample_molecular_weight_Da = 28  # nitrogen = N2
        SIM.add_background(
            sort_stable=(add_background_algorithm == "sort_stable"))
        del QQ

    SIM.detector_psf_kernel_radius_pixels = 5
    SIM.detector_psf_type = shapetype.Unknown  # for CSPAD
    SIM.detector_psf_fwhm_mm = 0
    #SIM.apply_psf()

    QQ = Profiler("nanoBragg noise rank %d" % (rank))
    #SIM.add_noise() #converts phtons to ADU.
    del QQ

    extra = "PREFIX=%s;\nRANK=%d;\n" % (prefix, rank)
    SIM.to_smv_format_py(fileout=burst_buffer_fileout,
                         intfile_scale=1,
                         rotmat=True,
                         extra=extra,
                         gz=True)

    SIM.free_all()
Пример #8
0
def run_sim2smv(prefix,
                crystal,
                spectra,
                rotation,
                rank,
                gpu_channels_singleton,
                params,
                quick=False,
                save_bragg=False,
                sfall_channels=None):
    smv_fileout = prefix + ".img"
    burst_buffer_expand_dir = os.path.expandvars(params.logger.outdir)
    burst_buffer_fileout = os.path.join(burst_buffer_expand_dir, smv_fileout)
    reference_fileout = os.path.join(".", smv_fileout)
    if not quick:
        if not write_safe(reference_fileout):
            print("File %s already exists, skipping in rank %d" %
                  (reference_fileout, rank))
            return

    direct_algo_res_limit = 1.7

    wavlen, flux, wavelength_A = next(
        spectra)  # list of lambdas, list of fluxes, average wavelength
    assert wavelength_A > 0
    # os.system("nvidia-smi") # printout might severely impact performance

    # use crystal structure to initialize Fhkl array
    N = crystal.number_of_cells(sfall_channels[0].unit_cell())

    #SIM = nanoBragg(detpixels_slowfast=(2000,2000),pixel_size_mm=0.11,Ncells_abc=(5,5,5),verbose=0)
    SIM = nanoBragg(
        detpixels_slowfast=(3840, 3840),
        pixel_size_mm=0.088,
        Ncells_abc=(N, N, N),
        # workaround for problem with wavelength array, specify it separately in constructor.
        wavelength_A=wavelength_A,
        verbose=0)
    SIM.adc_offset_adu = 0  # Do not offset by 40
    #SIM.adc_offset_adu = 10 # Do not offset by 40
    SIM.mosaic_spread_deg = 0.05  # interpreted by UMAT_nm as a half-width stddev
    # mosaic_domains setter MUST come after mosaic_spread_deg setter
    SIM.mosaic_domains = int(os.environ.get("MOS_DOM", "25"))
    print("MOSAIC", SIM.mosaic_domains)
    SIM.distance_mm = 141.7

    UMAT_nm = flex.mat3_double()
    mersenne_twister = flex.mersenne_twister(seed=0)
    scitbx.random.set_random_seed(1234)
    rand_norm = scitbx.random.normal_distribution(mean=0,
                                                  sigma=SIM.mosaic_spread_deg *
                                                  math.pi / 180.)
    g = scitbx.random.variate(rand_norm)
    mosaic_rotation = g(SIM.mosaic_domains)
    for m in mosaic_rotation:
        site = col(mersenne_twister.random_double_point_on_sphere())
        UMAT_nm.append(site.axis_and_angle_as_r3_rotation_matrix(m, deg=False))
    SIM.set_mosaic_blocks(UMAT_nm)

    if params.attenuation:
        SIM.detector_thick_mm = 0.032  # = 0 for Rayonix
        SIM.detector_thicksteps = 1  # should default to 1 for Rayonix, but set to 5 for CSPAD
        SIM.detector_attenuation_length_mm = 0.017  # default is silicon

    # get same noise each time this test is run
    SIM.seed = 1
    SIM.oversample = 1
    SIM.wavelength_A = wavelength_A
    SIM.polarization = 1
    # this will become F000, marking the beam center
    SIM.default_F = 0
    SIM.Fhkl = sfall_channels[0]  # instead of sfall_main
    Amatrix_rot = (rotation * sqr(
        sfall_channels[0].unit_cell().orthogonalization_matrix())).transpose()

    SIM.Amatrix_RUB = Amatrix_rot
    #workaround for failing init_cell, use custom written Amatrix setter
    print("unit_cell_Adeg=", SIM.unit_cell_Adeg)
    print("unit_cell_tuple=", SIM.unit_cell_tuple)
    Amat = sqr(SIM.Amatrix).transpose()  # recovered Amatrix from SIM
    from cctbx import crystal_orientation
    Ori = crystal_orientation.crystal_orientation(
        Amat, crystal_orientation.basis_type.reciprocal)

    # fastest option, least realistic
    SIM.xtal_shape = shapetype.Gauss_argchk  # both crystal & RLP are Gaussian
    # only really useful for long runs
    SIM.progress_meter = False
    # prints out value of one pixel only.  will not render full image!
    # flux is always in photons/s
    SIM.flux = 1e12
    SIM.exposure_s = 1.0  # so total fluence is e12
    # assumes round beam
    SIM.beamsize_mm = 0.003  #cannot make this 3 microns; spots are too intense
    temp = SIM.Ncells_abc
    SIM.Ncells_abc = temp

    # rough approximation to water: interpolation points for sin(theta/lambda) vs structure factor
    water_bg = flex.vec2_double([(0, 2.57), (0.0365, 2.58), (0.07, 2.8),
                                 (0.12, 5), (0.162, 8), (0.18, 7.32),
                                 (0.2, 6.75), (0.216, 6.75), (0.236, 6.5),
                                 (0.28, 4.5), (0.3, 4.3), (0.345, 4.36),
                                 (0.436, 3.77), (0.5, 3.17)])
    assert [a[0] for a in water_bg] == sorted([a[0] for a in water_bg])
    # rough approximation to air
    air_bg = flex.vec2_double([(0, 14.1), (0.045, 13.5), (0.174, 8.35),
                               (0.35, 4.78), (0.5, 4.22)])
    assert [a[0] for a in air_bg] == sorted([a[0] for a in air_bg])

    # simulated crystal is only 125 unit cells (25 nm wide)
    # amplify spot signal to simulate physical crystal of 4000x larger: 100 um (64e9 x the volume)
    SIM.raw_pixels *= crystal.domains_per_crystal
    # must calculate the correct scale!

    QQ = Profiler("nanoBragg Bragg spots rank %d" % (rank))
    if True:
        #something new
        devices_per_node = int(os.environ["DEVICES_PER_NODE"])
        SIM.device_Id = rank % devices_per_node

        assert gpu_channels_singleton.get_deviceID() == SIM.device_Id
        if gpu_channels_singleton.get_nchannels() == 0:  # if uninitialized
            P = Profiler("Initialize the channels singleton rank %d" % (rank))
            for x in range(len(flux)):
                gpu_channels_singleton.structure_factors_to_GPU_direct(
                    x, sfall_channels[x].indices(), sfall_channels[x].data())
            del P
            import time
            print("datetime for channels singleton rank %d" % (rank),
                  time.time())

        exascale_api = get_exascale("exascale_api", params.context)
        gpud = get_exascale("gpu_detector", params.context)

        gpu_simulation = exascale_api(nanoBragg=SIM)
        gpu_simulation.allocate()

        gpu_detector = gpud(deviceId=SIM.device_Id, nanoBragg=SIM)
        gpu_detector.each_image_allocate()

        # loop over energies
        for x in range(len(flux)):
            P = Profiler("USE_EXASCALE_API nanoBragg Python and C++ rank %d" %
                         (rank))

            print("USE_EXASCALE_API+++++++++++++++++++++++ Wavelength", x)
            # from channel_pixels function
            SIM.wavelength_A = wavlen[x]
            SIM.flux = flux[x]
            gpu_simulation.add_energy_channel_from_gpu_amplitudes(
                x, gpu_channels_singleton, gpu_detector)
            del P
        gpu_detector.scale_in_place(
            crystal.domains_per_crystal)  # apply scale directly on GPU
        SIM.wavelength_A = wavelength_A  # return to canonical energy for subsequent background

        if add_background_algorithm == "cuda":
            QQ = Profiler("nanoBragg background rank %d" % (rank))
            SIM.Fbg_vs_stol = water_bg
            SIM.amorphous_sample_thick_mm = 0.1
            SIM.amorphous_density_gcm3 = 1
            SIM.amorphous_molecular_weight_Da = 18
            SIM.flux = 1e12
            SIM.beamsize_mm = 0.003  # square (not user specified)
            SIM.exposure_s = 1.0  # multiplies flux x exposure
            gpu_simulation.add_background(gpu_detector)
            SIM.Fbg_vs_stol = air_bg
            SIM.amorphous_sample_thick_mm = 10  # between beamstop and collimator
            SIM.amorphous_density_gcm3 = 1.2e-3
            SIM.amorphous_sample_molecular_weight_Da = 28  # nitrogen = N2
            gpu_simulation.add_background(gpu_detector)

        # deallocate GPU arrays
        gpu_detector.write_raw_pixels(SIM)  # updates SIM.raw_pixels from GPU
        gpu_detector.each_image_free()
        SIM.Amatrix_RUB = Amatrix_rot  # return to canonical orientation
        del QQ

    if add_background_algorithm in ["jh", "sort_stable"]:
        QQ = Profiler("nanoBragg background rank %d" % (rank))

        SIM.Fbg_vs_stol = water_bg
        SIM.amorphous_sample_thick_mm = 0.1
        SIM.amorphous_density_gcm3 = 1
        SIM.amorphous_molecular_weight_Da = 18
        SIM.flux = 1e12
        SIM.beamsize_mm = 0.003  # square (not user specified)
        SIM.exposure_s = 1.0  # multiplies flux x exposure
        SIM.add_background(
            sort_stable=(add_background_algorithm == "sort_stable"))

        SIM.Fbg_vs_stol = air_bg
        SIM.amorphous_sample_thick_mm = 10  # between beamstop and collimator
        SIM.amorphous_density_gcm3 = 1.2e-3
        SIM.amorphous_sample_molecular_weight_Da = 28  # nitrogen = N2
        SIM.add_background(
            sort_stable=(add_background_algorithm == "sort_stable"))
        del QQ

    if params.psf:
        SIM.detector_psf_kernel_radius_pixels = 10
        SIM.detector_psf_type = shapetype.Fiber  # for Rayonix
        SIM.detector_psf_fwhm_mm = 0.08
        #SIM.apply_psf() # the actual application is called within the C++ SIM.add_noise()
    else:
        #SIM.detector_psf_kernel_radius_pixels=5;
        SIM.detector_psf_type = shapetype.Unknown  # for CSPAD
        SIM.detector_psf_fwhm_mm = 0

    if params.noise:
        SIM.adc_offset_adu = 10  # Do not offset by 40
        SIM.detector_calibration_noise_pct = 1.0
        SIM.readout_noise_adu = 1.

    QQ = Profiler("nanoBragg noise rank %d" % (rank))
    if params.noise or params.psf:
        from LS49.sim.step6_pad import estimate_gain
        print("quantum_gain=",
              SIM.quantum_gain)  #defaults to 1. converts photons to ADU
        print("adc_offset_adu=", SIM.adc_offset_adu)
        print("detector_calibration_noise_pct=",
              SIM.detector_calibration_noise_pct)
        print("flicker_noise_pct=", SIM.flicker_noise_pct)
        print("readout_noise_adu=", SIM.readout_noise_adu
              )  # gaussian random number to add to every pixel (0 for PAD)
        # apply Poissonion correction, then scale to ADU, then adc_offset.
        # should be 10 for most Rayonix, Pilatus should be 0, CSPAD should be 0.
        print("detector_psf_type=", SIM.detector_psf_type)
        print("detector_psf_fwhm_mm=", SIM.detector_psf_fwhm_mm)
        print("detector_psf_kernel_radius_pixels=",
              SIM.detector_psf_kernel_radius_pixels)
        #estimate_gain(SIM.raw_pixels,offset=0)
        SIM.add_noise()  #converts photons to ADU.
        #estimate_gain(SIM.raw_pixels,offset=SIM.adc_offset_adu,algorithm="slow")
        #estimate_gain(SIM.raw_pixels,offset=SIM.adc_offset_adu,algorithm="kabsch")
    del QQ

    print("FULLY")
    print(burst_buffer_expand_dir, params.logger.outdir)
    print(burst_buffer_fileout, smv_fileout)

    extra = "PREFIX=%s;\nRANK=%d;\n" % (prefix, rank)
    SIM.to_smv_format_py(fileout=burst_buffer_fileout,
                         intfile_scale=1,
                         rotmat=True,
                         extra=extra,
                         gz=True)

    SIM.free_all()
Пример #9
0
def run_sim2smv(prefix,
                crystal,
                spectra,
                rotation,
                rank,
                sfall_main,
                quick=False,
                save_bragg=False,
                save_smv=True,
                save_h5=False,
                return_pixels=False):
    smv_fileout = prefix + ".img"

    #if not quick:
    #  if not write_safe(smv_fileout):
    #    print("File %s already exists, skipping in rank %d"%(smv_fileout,rank))
    #    return

    direct_algo_res_limit = 1.7

    wavlen, flux, wavelength_A = next(
        spectra)  # list of lambdas, list of fluxes, average wavelength
    assert wavelength_A > 0
    assert (len(wavlen) == len(flux) == len(sfall_main))
    if quick:
        wavlen = flex.double([wavelength_A])
        flux = flex.double([flex.sum(flux)])
        print("Quick sim, lambda=%f, flux=%f" % (wavelength_A, flux[0]))

    # use crystal structure to initialize Fhkl array
    #sfall_main[0].show_summary(prefix = "Amplitudes used ")
    N = crystal.number_of_cells(sfall_main[0].unit_cell())
    if use_microcrystal:
        global Ncells_abc
        Ncells_abc = (N, N, N)
    SIM = nanoBragg(detpixels_slowfast=detpixels_slowfast,
                    pixel_size_mm=pixsize_mm,
                    Ncells_abc=Ncells_abc,
                    wavelength_A=wavelength_A,
                    verbose=verbose)
    SIM.adc_offset_adu = offset_adu  # Do not offset by 40
    SIM.mosaic_spread_deg = mos_spread_deg  # interpreted by UMAT_nm as a half-width stddev
    SIM.mosaic_domains = mos_doms
    SIM.distance_mm = distance_mm
    UMAT_nm = flex.mat3_double()
    mersenne_twister = flex.mersenne_twister(seed=0)
    scitbx.random.set_random_seed(1234)
    rand_norm = scitbx.random.normal_distribution(mean=0,
                                                  sigma=SIM.mosaic_spread_deg *
                                                  math.pi / 180.)
    g = scitbx.random.variate(rand_norm)
    mosaic_rotation = g(SIM.mosaic_domains)
    for m in mosaic_rotation:
        site = col(mersenne_twister.random_double_point_on_sphere())
        UMAT_nm.append(site.axis_and_angle_as_r3_rotation_matrix(m, deg=False))
    SIM.set_mosaic_blocks(UMAT_nm)

    # get same noise each time this test is run
    SIM.seed = 1
    SIM.oversample = 1
    SIM.wavelength_A = wavelength_A
    SIM.polarization = 1
    # this will become F000, marking the beam center
    SIM.default_F = 0
    #SIM.missets_deg= (10,20,30)
    if verbose:
        print("mosaic_seed=", SIM.mosaic_seed)
        print("seed=", SIM.seed)
        print("calib_seed=", SIM.calib_seed)
        print("missets_deg =", SIM.missets_deg)
    SIM.Fhkl = sfall_main[0].amplitudes()
    if verbose: print("Determinant", rotation.determinant())
    Amatrix_rot = (
        rotation *
        sqr(sfall_main[0].unit_cell().orthogonalization_matrix())).transpose()

    if verbose:
        print("RAND_ORI", prefix, end=' ')
        for i in Amatrix_rot:
            print(i, end=' ')
        print()

    SIM.Amatrix_RUB = Amatrix_rot
    #workaround for failing init_cell, use custom written Amatrix setter
    if verbose:
        print("unit_cell_Adeg=", SIM.unit_cell_Adeg)
        print("unit_cell_tuple=", SIM.unit_cell_tuple)
    Amat = sqr(SIM.Amatrix).transpose()  # recovered Amatrix from SIM
    Ori = crystal_orientation.crystal_orientation(
        Amat, crystal_orientation.basis_type.reciprocal)
    if verbose: print("Python unit cell from SIM state", Ori.unit_cell())

    SIM.xtal_shape = shapetype.Gauss
    SIM.progress_meter = False
    #SIM.show_params()
    SIM.flux = flux_ave
    SIM.exposure_s = exposure_s
    SIM.beamsize_mm = beam_size_mm
    temp = SIM.Ncells_abc
    if verbose: print("Ncells_abc=", SIM.Ncells_abc)
    SIM.Ncells_abc = temp
    if verbose:
        print("Ncells_abc=", SIM.Ncells_abc)
        print("xtal_size_mm=", SIM.xtal_size_mm)
        print("unit_cell_Adeg=", SIM.unit_cell_Adeg)
        print("unit_cell_tuple=", SIM.unit_cell_tuple)
        print("missets_deg=", SIM.missets_deg)
        print("Amatrix=", SIM.Amatrix)
        print("beam_center_mm=", SIM.beam_center_mm)
        print("XDS_ORGXY=", SIM.XDS_ORGXY)
        print("detector_pivot=", SIM.detector_pivot)
        print("xtal_shape=", SIM.xtal_shape)
        print("beamcenter_convention=", SIM.beamcenter_convention)
        print("fdet_vector=", SIM.fdet_vector)
        print("sdet_vector=", SIM.sdet_vector)
        print("odet_vector=", SIM.odet_vector)
        print("beam_vector=", SIM.beam_vector)
        print("polar_vector=", SIM.polar_vector)
        print("spindle_axis=", SIM.spindle_axis)
        print("twotheta_axis=", SIM.twotheta_axis)
        print("distance_meters=", SIM.distance_meters)
        print("distance_mm=", SIM.distance_mm)
        print("close_distance_mm=", SIM.close_distance_mm)
        print("detector_twotheta_deg=", SIM.detector_twotheta_deg)
        print("detsize_fastslow_mm=", SIM.detsize_fastslow_mm)
        print("detpixels_fastslow=", SIM.detpixels_fastslow)
        print("detector_rot_deg=", SIM.detector_rot_deg)
        print("curved_detector=", SIM.curved_detector)
        print("pixel_size_mm=", SIM.pixel_size_mm)
        print("point_pixel=", SIM.point_pixel)
        print("polarization=", SIM.polarization)
        print("nopolar=", SIM.nopolar)
        print("oversample=", SIM.oversample)
        print("region_of_interest=", SIM.region_of_interest)
        print("wavelength_A=", SIM.wavelength_A)
        print("energy_eV=", SIM.energy_eV)
        print("fluence=", SIM.fluence)
        print("flux=", SIM.flux)
        print("exposure_s=", SIM.exposure_s)
        print("beamsize_mm=", SIM.beamsize_mm)
        print("dispersion_pct=", SIM.dispersion_pct)
        print("dispsteps=", SIM.dispsteps)
        print("divergence_hv_mrad=", SIM.divergence_hv_mrad)
        print("divsteps_hv=", SIM.divsteps_hv)
        print("divstep_hv_mrad=", SIM.divstep_hv_mrad)
        print("round_div=", SIM.round_div)
        print("phi_deg=", SIM.phi_deg)
        print("osc_deg=", SIM.osc_deg)
        print("phisteps=", SIM.phisteps)
        print("phistep_deg=", SIM.phistep_deg)
        print("detector_thick_mm=", SIM.detector_thick_mm)
        print("detector_thicksteps=", SIM.detector_thicksteps)
        print("detector_thickstep_mm=", SIM.detector_thickstep_mm)
        print("***mosaic_spread_deg=", SIM.mosaic_spread_deg)
        print("***mosaic_domains=", SIM.mosaic_domains)
        print("indices=", SIM.indices)
        print("amplitudes=", SIM.amplitudes)
        print("Fhkl_tuple=", SIM.Fhkl_tuple)
        print("default_F=", SIM.default_F)
        print("interpolate=", SIM.interpolate)
        print("integral_form=", SIM.integral_form)

    # simulated crystal is only 125 unit cells (25 nm wide)
    # amplify spot signal to simulate physical crystal of 4000x larger: 100 um (64e9 x the volume)
    if verbose: print(crystal.domains_per_crystal)
    SIM.raw_pixels *= crystal.domains_per_crystal
    # must calculate the correct scale!

    Nflux = len(flux)
    for x in range(Nflux):
        #P = Profiler("nanoBragg Python and C++ rank %d"%(rank))

        if x % 10 == 0:
            print(
                "+++++++++++++++++++++++++++++++++++++++ Wavelength %d / %d" %
                (x + 1, Nflux),
                end="\r")
        if flux[x] == 0:
            continue

        CH = channel_pixels(wavlen[x], flux[x], UMAT_nm, Amatrix_rot, rank,
                            sfall_main[x])

        if use_microcrystal:
            SIM.raw_pixels += CH.raw_pixels * crystal.domains_per_crystal
        else:
            SIM.raw_pixels += CH.raw_pixels
        CH.free_all()

        #del P

    print()
    # image 1: crystal Bragg scatter
    if quick or save_bragg:
        SIM.to_smv_format(fileout=prefix + "_intimage_001.img")

    if save_bragg:
        raw_to_pickle(SIM.raw_pixels, fileout=prefix + "_dblprec_001.pickle")

    SIM.raw_pixels = SIM.raw_pixels + background
    #SIM.raw_pixels = SIM.raw_pixels*0
    ## rough approximation to water: interpolation points for sin(theta/lambda) vs structure factor
    #bg = flex.vec2_double([(0,2.57),(0.0365,2.58),(0.07,2.8),(0.12,5),(0.162,8),(0.2,6.75),(0.18,7.32),(0.216,6.75),(0.236,6.5),(0.28,4.5),(0.3,4.3),(0.345,4.36),(0.436,3.77),(0.5,3.17)])
    #SIM.Fbg_vs_stol = bg
    #SIM.amorphous_sample_thick_mm = sample_thick_mm
    #SIM.amorphous_density_gcm3 = 1
    #SIM.amorphous_molecular_weight_Da = 18
    #SIM.flux=flux_ave
    #SIM.beamsize_mm=beam_size_mm
    #SIM.exposure_s=exposure_s
    #SIM.add_background()
    #if quick:  SIM.to_smv_format(fileout=prefix + "_intimage_002.img")

    ## rough approximation to air
    #bg = flex.vec2_double([(0,14.1),(0.045,13.5),(0.174,8.35),(0.35,4.78),(0.5,4.22)])
    #SIM.Fbg_vs_stol = bg
    #SIM.amorphous_sample_thick_mm = air_thick_mm # between beamstop and collimator
    #SIM.amorphous_density_gcm3 = 1.2e-3
    #SIM.amorphous_sample_molecular_weight_Da = 28 # nitrogen = N2
    #print("amorphous_sample_size_mm=",SIM.amorphous_sample_size_mm)
    #print("amorphous_sample_thick_mm=",SIM.amorphous_sample_thick_mm)
    #print("amorphous_density_gcm3=",SIM.amorphous_density_gcm3)
    #print("amorphous_molecular_weight_Da=",SIM.amorphous_molecular_weight_Da)
    #SIM.add_background()

    ##apply beamstop mask here

    ## set this to 0 or -1 to trigger automatic radius.  could be very slow with bright images
    ## settings for CCD
    #utils.save_flex(SIM.raw_pixels, "background")

    SIM.detector_psf_kernel_radius_pixels = 5
    #SIM.detector_psf_fwhm_mm=0.08;
    #SIM.detector_psf_type=shapetype.Fiber # rayonix=Fiber, CSPAD=None (or small Gaussian)
    SIM.detector_psf_type = shapetype.Unknown  # for CSPAD
    SIM.detector_psf_fwhm_mm = 0
    SIM.quantum_gain = 28.
    #SIM.apply_psf()
    if verbose: print("One pixel-->", SIM.raw_pixels[500000])

    # at this point we scale the raw pixels so that the output array is on an scale from 0 to 50000.
    # that is the default behavior (intfile_scale<=0), otherwise it applies intfile_scale as a multiplier on an abs scale.
    if quick: SIM.to_smv_format(fileout=prefix + "_intimage_003.img")

    if verbose:
        print("quantum_gain=",
              SIM.quantum_gain)  #defaults to 1. converts photons to ADU
        print("adc_offset_adu=", SIM.adc_offset_adu)
        print("detector_calibration_noise_pct=",
              SIM.detector_calibration_noise_pct)
        print("flicker_noise_pct=", SIM.flicker_noise_pct)
        print("readout_noise_adu=", SIM.readout_noise_adu
              )  # gaussian random number to add to every pixel (0 for PAD)
        # apply Poissonion correction, then scale to ADU, then adc_offset.
        # should be 10 for most Rayonix, Pilatus should be 0, CSPAD should be 0.

        print("detector_psf_type=", SIM.detector_psf_type)
        print("detector_psf_fwhm_mm=", SIM.detector_psf_fwhm_mm)
        print("detector_psf_kernel_radius_pixels=",
              SIM.detector_psf_kernel_radius_pixels)

    SIM.add_noise()  #converts phtons to ADU.
    if verbose: print("raw_pixels=", SIM.raw_pixels)
    extra = "PREFIX=%s;\nRANK=%d;\n" % (prefix, rank)

    out = SIM.raw_pixels.as_numpy_array()

    if save_smv:
        SIM.to_smv_format_py(fileout=smv_fileout,
                             intfile_scale=1,
                             rotmat=True,
                             extra=extra,
                             gz=True)
    elif save_h5:
        h5_fileout = smv_fileout + ".h5"
        f = h5py.File(h5_fileout, "w")
        f.create_dataset("data",
                         data=SIM.raw_pixels.as_numpy_array().astype(
                             np.uint16),
                         compression="lzf")
        f.close()

    SIM.free_all()