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