def test_all(dirpath, timer=False): for file in generate_paths(dirpath): from iotbx.detectors.pilatus_minicbf import PilatusImage if timer: print(os.path.basename(file)) P = PilatusImage(file) if timer: G = Profiler("cbflib no-opt read") P.read(algorithm="cbflib") read1 = P.linearintdata if timer: G = Profiler("cbflib optimized read") P.linearintdata = None #won't read again without resetting first P.read(algorithm="cbflib_optimized") read2 = P.linearintdata if timer: G = Profiler("buffer-based read") P.linearintdata = None #won't read again without resetting first P.read(algorithm="buffer_based") read3 = P.linearintdata if timer: del G expected_image_size = { "Pilatus-6M": (2527, 2463), "Pilatus-2M": (1679, 1475), "Pilatus-300K": (619, 487) }[P.vendortype] assert read1.accessor().focus() == read2.accessor().focus( ) == expected_image_size from cbflib_adaptbx import assert_equal #print "Equality of arrays from two decompress methods", assert_equal(read1,read2), "\n" assert assert_equal(read1, read2) assert assert_equal(read1, read3)
def channel_pixels(wavelength_A, flux, N, UMAT_nm, Amatrix_rot, fmodel_generator, local_data): fmodel_generator.reset_wavelength(wavelength_A) fmodel_generator.reset_specific_at_wavelength( label_has="FE1", tables=local_data.get("Fe_oxidized_model"), newvalue=wavelength_A) fmodel_generator.reset_specific_at_wavelength( label_has="FE2", tables=local_data.get("Fe_reduced_model"), newvalue=wavelength_A) print("USING scatterer-specific energy-dependent scattering factors") sfall_channel = fmodel_generator.get_amplitudes() SIM = nanoBragg(detpixels_slowfast=(3000, 3000), pixel_size_mm=0.11, Ncells_abc=(N, N, N), wavelength_A=wavelength_A, verbose=0) 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 SIM.mosaic_domains = 25 # 77 seconds. With 100 energy points, 7700 seconds (2 hours) per image SIM.distance_mm = 141.7 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 SIM.default_F = 0 SIM.Fhkl = sfall_channel SIM.Amatrix_RUB = Amatrix_rot SIM.xtal_shape = shapetype.Gauss # both crystal & RLP are Gaussian SIM.progress_meter = False # flux is always in photons/s SIM.flux = flux 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 from libtbx.development.timers import Profiler P = Profiler("nanoBragg") if add_spots_algorithm == "NKS": from boost_adaptbx.boost.python import streambuf # will deposit printout into dummy StringIO as side effect SIM.add_nanoBragg_spots_nks(streambuf(StringIO())) elif add_spots_algorithm == "JH": SIM.add_nanoBragg_spots() elif add_spots_algorithm == "cuda": SIM.add_nanoBragg_spots_cuda() else: raise Exception("unknown spots algorithm") del P return SIM
def channel_pixels(ROI,wavelength_A,flux,N,UMAT_nm,Amatrix_rot,fmodel_generator,output): energy_dependent_fmodel=False if energy_dependent_fmodel: fmodel_generator.reset_wavelength(wavelength_A) fmodel_generator.reset_specific_at_wavelength( label_has="FE1",tables=Fe_oxidized_model,newvalue=wavelength_A) fmodel_generator.reset_specific_at_wavelength( label_has="FE2",tables=Fe_reduced_model,newvalue=wavelength_A) print("USING scatterer-specific energy-dependent scattering factors") sfall_channel = fmodel_generator.get_amplitudes() elif use_g_sfall: global g_sfall if g_sfall is None: g_sfall = fmodel_generator.get_amplitudes() sfall_channel = g_sfall else: sfall_channel = sfall_7122 SIM = nanoBragg(detpixels_slowfast=(3000,3000),pixel_size_mm=0.11,Ncells_abc=(N,N,N), wavelength_A=wavelength_A,verbose=0) SIM.adc_offset_adu = 10 # Do not offset by 40 SIM.region_of_interest = ROI SIM.mosaic_spread_deg = 0.05 # interpreted by UMAT_nm as a half-width stddev SIM.mosaic_domains = 50 # 77 seconds. With 100 energy points, 7700 seconds (2 hours) per image SIM.distance_mm=141.7 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 SIM.default_F=0 SIM.Fhkl=sfall_channel SIM.Amatrix_RUB = Amatrix_rot SIM.xtal_shape=shapetype.Gauss # both crystal & RLP are Gaussian SIM.progress_meter=False # flux is always in photons/s SIM.flux=flux 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 from libtbx.development.timers import Profiler P = Profiler("nanoBragg") SIM.printout=True fast = ROI[1][0] + (ROI[1][1]-ROI[1][0])//2 slow = ROI[0][0] + (ROI[0][1]-ROI[0][0])//2 SIM.printout_pixel_fastslow=(slow,fast) from boost_adaptbx.boost.python import streambuf # will deposit printout into output as side effect SIM.add_nanoBragg_spots_nks(streambuf(output)) del P print(("SIM count > 0",(SIM.raw_pixels>0).count(True))) return SIM
def create_gpu_channels(cpu_channels, utilize): from libtbx.mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() devices_per_node = int(os.environ.get("DEVICES_PER_NODE", 1)) this_device = rank % devices_per_node from simtbx.gpu import gpu_energy_channels gpu_channels_singleton = gpu_energy_channels(deviceId=this_device) assert gpu_channels_singleton.get_deviceID() == this_device print("QQQ to gpu %d channels" % gpu_channels_singleton.get_nchannels(), "rank", rank) if gpu_channels_singleton.get_nchannels() == 0: # if uninitialized P = Profiler("Initialize the channels singleton rank %d, device %d" % (rank, this_device)) for x in range(len(cpu_channels)): print("starting with ", x) gpu_channels_singleton.structure_factors_to_GPU_direct( x, cpu_channels[x].indices(), cpu_channels[x].data()) print("Finished sending to gpu %d channels" % gpu_channels_singleton.get_nchannels()) del P assert len(cpu_channels) == utilize
def channel_pixels(wavelength_A, flux, N, UMAT_nm, Amatrix_rot, rank, sfall_channel): if rank in [0, 7]: print("USING scatterer-specific energy-dependent scattering factors") SIM = nanoBragg(detpixels_slowfast=(3000, 3000), pixel_size_mm=0.11, Ncells_abc=(N, N, N), wavelength_A=wavelength_A, verbose=0) 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 SIM.mosaic_domains = 25 # 77 seconds. With 100 energy points, 7700 seconds (2 hours) per image SIM.distance_mm = 141.7 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 SIM.default_F = 0 SIM.Fhkl = sfall_channel SIM.Amatrix_RUB = Amatrix_rot SIM.xtal_shape = shapetype.Gauss # both crystal & RLP are Gaussian SIM.progress_meter = False # flux is always in photons/s SIM.flux = flux 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 if rank in [0, 7]: print("Ncells_abc=", SIM.Ncells_abc) SIM.Ncells_abc = temp if rank in [0, 7]: P = Profiler("nanoBragg C++ rank %d" % (rank)) if add_spots_algorithm == "NKS": from boost_adaptbx.boost.python import streambuf # will deposit printout into dummy StringIO as side effect SIM.add_nanoBragg_spots_nks(streambuf(StringIO())) elif add_spots_algorithm == "JH": SIM.add_nanoBragg_spots() elif add_spots_algorithm == "cuda": SIM.xtal_shape = shapetype.Gauss_argchk devices_per_node = int(os.environ["DEVICES_PER_NODE"]) SIM.device_Id = rank % devices_per_node #if rank==7: # os.system("nvidia-smi") SIM.add_nanoBragg_spots_cuda() else: raise Exception("unknown spots algorithm") if rank in [0, 7]: del P return SIM
def __call__(self, N, UMAT_nm, Amatrix_rot, sfall_channel): SIM = nanoBragg(detpixels_slowfast=(3000, 3000), pixel_size_mm=0.11, Ncells_abc=(N, N, N), wavelength_A=self.wavlen[0], verbose=0) SIM.adc_offset_adu = 10 # Do not offset by 40 SIM.mosaic_domains = n_mosaic_domains # 77 seconds. With 100 energy points, 7700 seconds (2 hours) per image SIM.mosaic_spread_deg = mosaic_spread_deg # interpreted by UMAT_nm as a half-width stddev SIM.distance_mm = distance_mm 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.polarization = 1 SIM.default_F = 0 SIM.Fhkl = sfall_channel SIM.Amatrix_RUB = Amatrix_rot SIM.xtal_shape = shapetype.Gauss # both crystal & RLP are Gaussian SIM.progress_meter = False # flux is always in photons/s #SIM.flux=0.8E10 # number of photons per 100 ps integrated pulse, 24-bunch APS SIM.flux = 0.8E12 # number of photons per 100 ps integrated pulse, 24-bunch APS SIM.xray_source_wavelengths_A = self.wavlen SIM.xray_source_intensity_fraction = self.norm_intensity SIM.xray_source_XYZ = self.source_XYZ 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 from libtbx.development.timers import Profiler P = Profiler("nanoBragg") if add_spots_algorithm is "NKS": print("USING NKS") from boost.python import streambuf # will deposit printout into dummy StringIO as side effect SIM.add_nanoBragg_spots_nks(streambuf(StringIO())) elif add_spots_algorithm is "JH": print("USING JH") SIM.add_nanoBragg_spots() elif add_spots_algorithm is "cuda": print("USING cuda") SIM.add_nanoBragg_spots_cuda() else: raise Exception("unknown spots algorithm") del P return SIM
def mask_from_file(mask_file): P = Profiler("fast mask from file as boolean array") from scitbx.array_family import flex import pickle with open(mask_file, "rb") as M: mask = pickle.load(M) monolithic_mask = flex.bool() for ipnl in range(len(mask)): pnl = mask[ipnl] monolithic_mask.extend(pnl.as_1d()) assert len(monolithic_mask) == 256 * 254 * 254 return monolithic_mask
def basic_tests(verbose=True): initial_intdata = create_random_data_with_gaussian_distribution(0.0, 100.0) #special deltas to test the compression algorithm addresses = [3, 6, 9, 12, 15, 18] deltas = [-127, 128, -32767, 32768, -2147483647, 2147483647] for x in range(6): initial_intdata[addresses[x] - 1] = 0 initial_intdata[addresses[x]] = deltas[x] if verbose: P = Profiler("compress") array_shape = initial_intdata.focus() if verbose: print(array_shape) compressed = compress(initial_intdata) if verbose: print(len(compressed)) if verbose: P = Profiler("uncompress") decompressed_dat = uncompress(packed=compressed, fast=array_shape[1], slow=array_shape[0]) if verbose: del P assert assert_equal(initial_intdata, decompressed_dat)
def get_lunus_repl(self): P = Profiler("LUNUS") # first get the lunus image from lunus.command_line.filter_peaks import get_image_params from lunus import LunusDIFFIMAGE imageset = self.expt.imageset data = imageset[0] assert isinstance( data, tuple) # assume a tuple of flex::double over detector panels # Instantiate a LUNUS diffraction image A = LunusDIFFIMAGE(len(data)) # Populate the image with multipanel data for pidx in range(len(data)): A.set_image(pidx, data[pidx]) # Define the LUNUS image parameters deck = ''' #lunus input deck #punchim_xmin=1203 #punchim_ymin=1250 #punchim_xmax=2459 #punchim_ymax=1314 #windim_xmin=100 #windim_ymin=100 #windim_xmax=2362 #windim_ymax=2426 #thrshim_min=0 #thrshim_max=50 modeim_bin_size=1 modeim_kernel_width=15 ''' image_params = get_image_params(imageset) # Set the LUNUS image parameters for pidx in range(len(image_params)): deck_and_extras = deck + image_params[pidx] A.LunusSetparamsim(pidx, deck_and_extras) A.LunusModeim() # Get the processed image lunus_filtered_data = flex.double() assert len(data) == 256 # Jungfrau for pidx in range(len(data)): aye_panel = A.get_image_double(pidx) assert aye_panel.focus() == (254, 254) lunus_filtered_data.extend(aye_panel.as_1d()) lunus_filtered_data.reshape(flex.grid((256, 254, 254))) self.lunus_filtered_data = lunus_filtered_data.as_numpy_array()
def create_gpu_channels_one_rank(cpu_channels, utilize): this_device = 0 from simtbx.gpu import gpu_energy_channels gpu_channels_singleton = gpu_energy_channels(deviceId=this_device) assert gpu_channels_singleton.get_deviceID() == this_device print("QQQ to gpu %d channels" % gpu_channels_singleton.get_nchannels(), "one rank") if gpu_channels_singleton.get_nchannels() == 0: # if uninitialized P = Profiler("Initialize the channels singleton rank None, device %d" % (this_device)) for x in range(len(cpu_channels)): print("starting with ", x) gpu_channels_singleton.structure_factors_to_GPU_direct( x, cpu_channels[x].indices(), cpu_channels[x].data()) print("Finished sending to gpu %d channels" % gpu_channels_singleton.get_nchannels()) del P assert len(cpu_channels) == utilize
def channel_pixels(wavelength_A, flux, N, UMAT_nm, Amatrix_rot, sfall): SIM = nanoBragg(detpixels_slowfast=(3000, 3000), pixel_size_mm=0.11, Ncells_abc=(N, N, N), wavelength_A=wavelength_A, verbose=0) 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 SIM.mosaic_domains = 25 # 77 seconds. With 100 energy points, 7700 seconds (2 hours) per image SIM.distance_mm = 141.7 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 SIM.default_F = 0 SIM.Fhkl = sfall SIM.Amatrix_RUB = Amatrix_rot SIM.xtal_shape = shapetype.Gauss # both crystal & RLP are Gaussian SIM.progress_meter = False # flux is always in photons/s SIM.flux = flux 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 from libtbx.development.timers import Profiler P = Profiler("nanoBragg") SIM.add_nanoBragg_spots_nks() del P return SIM
def add_channel_pixels(self, wavelength_A, flux, rank, algo="cuda"): """ :param wavelength_A: :param flux: :param rank: :param algo: :return: """ self.SIM.flux=flux self.SIM.wavelength_A = wavelength_A P = Profiler("nanoBragg C++ rank %d"%(rank)) if algo == "NKS": self.SIM.add_nanoBragg_spots_nks(streambuf(StringIO())) self.raw_pixels = self.SIM.raw_pixels # NOTE: this actually incremenents hack for now, because cuda doesnt add spots elif algo == "JH": self.SIM.add_nanoBragg_spots() self.raw_pixels = self.SIM.raw_pixels elif algo == "cuda": self.SIM.add_nanoBragg_spots_cuda() #self.SIM.add_nanoBragg_spots_cuda_light() # FIXME: this should be updated to not initialize self.raw_pixels += self.SIM.raw_pixels # NOTE: will be on GPU else: raise Exception("unknown spots algorithm '%s' " % algo)
def run_sim2smv(prefix, crystal, spectra, rotation, rank): local_data = data() smv_fileout = prefix + ".img" 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 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()) mosaic_spread_deg = 0.05 mosaic_domains = 25 channel_sim = ChannelSimulator(rotation=rotation, sfall_main=sfall_main, N=N, mosaic_spread_deg=mosaic_spread_deg, mosaic_domains=mosaic_domains) for x in range(len(flux)): P = Profiler("nanoBragg Python and C++ rank %d" % (rank)) print("+++++++++++++++++++++++++++++++++++++++ Wavelength", x) channel_sim.add_channel_pixels(wavlen[x], flux[x], rank, algo=ADD_SPOTS_ALGORITHM) # whats this ? CHDBG_singleton.extract(channel_no=x, data=channel_sim.raw_pixels) del P SIM = channel_sim.SIM # FIXME: this hsould already be done by kernel... SIM.raw_pixels = channel_sim.raw_pixels * crystal.domains_per_crystal 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() # 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. 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) SIM.free_all()
def run_detail(show_plot, save_plot): P = Profiler("0. Read data") import sys file_name = sys.argv[1] from xfel.clustering.singleframe import CellOnlyFrame cells = [] for line in open(file_name, "r").xreadlines(): tokens = line.strip().split() cells.append(CellOnlyFrame(args=tokens, path=None)) MM = [c.mm for c in cells] # get all metrical matrices MM_double = flex.double() for i in xrange(len(MM)): Tup = MM[i] for j in xrange(6): MM_double.append(Tup[j]) print("There are %d cells X" % (len(MM))) CX = 0 CY = 3 coord_x = flex.double([c.uc[CX] for c in cells]) coord_y = flex.double([c.uc[CY] for c in cells]) if show_plot or save_plot: import matplotlib if not show_plot: # http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear matplotlib.use('Agg') # use a non-interactive backend from matplotlib import pyplot as plt plt.plot(coord_x, coord_y, "k.", markersize=3.) #plt.axes().set_aspect("equal") if save_plot: plt.savefig(plot_name, size_inches=(10, 10), dpi=300, bbox_inches='tight') if show_plot: plt.show() print "Now constructing a Dij matrix." P = Profiler("1. compute Dij matrix") NN = len(MM) from cctbx.uctbx.determine_unit_cell import NCDist_matrix, NCDist_flatten #Dij = NCDist_matrix(MM_double) Dij = NCDist_flatten(MM_double) #from cctbx.uctbx.determine_unit_cell import NCDist # can this be refactored with MPI? #Dij = flex.double(flex.grid(NN,NN)) #for i in xrange(NN): # for j in xrange(i+1,NN): # Dij[i,j] = NCDist(MM[i], MM[j]) del P d_c = 10000 # the distance cutoff, such that average item neighbors 1-2% of all items CM = clustering_manager(Dij=Dij, d_c=d_c) # Summarize the results here n_cluster = 1 + flex.max(CM.cluster_id_final) print len(cells), "have been analyzed" print("# ------------ %d CLUSTERS ----------------" % (n_cluster)) for i in xrange(n_cluster): item = flex.first_index(CM.cluster_id_maxima, i) print "Cluster %d. Central unit cell: item %d" % (i, item) cells[item].crystal_symmetry.show_summary() print "Cluster has %d items, or %d after trimming borders" % ( (CM.cluster_id_full == i).count(True), (CM.cluster_id_final == i).count(True)) print appcolors = [ 'b', 'r', '#ff7f0e', '#2ca02c', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf' ] if show_plot: #Decision graph from matplotlib import pyplot as plt plt.plot(CM.rho, CM.delta, "r.", markersize=3.) for x in xrange(NN): if CM.cluster_id_maxima[x] >= 0: plt.plot([CM.rho[x]], [CM.delta[x]], "ro") plt.show() #No-halo plot from matplotlib import pyplot as plt colors = [appcolors[i % 10] for i in CM.cluster_id_full] plt.scatter(coord_x, coord_y, marker='o', color=colors, linewidths=0.4, edgecolor='k') for i in xrange(n_cluster): item = flex.first_index(CM.cluster_id_maxima, i) plt.plot([cells[item].uc[CX]], [cells[item].uc[CY]], 'y.') #plt.axes().set_aspect("equal") plt.show() #Final plot halo = (CM.cluster_id_final == -1) core = ~halo plt.plot(coord_x.select(halo), coord_y.select(halo), "k.") colors = [appcolors[i % 10] for i in CM.cluster_id_final.select(core)] plt.scatter(coord_x.select(core), coord_y.select(core), marker="o", color=colors, linewidths=0.4, edgecolor='k') for i in xrange(n_cluster): item = flex.first_index(CM.cluster_id_maxima, i) plt.plot([cells[item].uc[CX]], [cells[item].uc[CY]], 'y.') #plt.axes().set_aspect("equal") plt.show()
def multipanel_sim( CRYSTAL, DETECTOR, BEAM, Famp, energies, fluxes, background_wavelengths=None, background_wavelength_weights=None, background_total_flux=None, background_sample_thick_mm=None, density_gcm3=1, molecular_weight=18, cuda=False, oversample=0, Ncells_abc=(50, 50, 50), mos_dom=1, mos_spread=0, mosaic_method="double_uniform", mos_aniso=None, beamsize_mm=0.001, crystal_size_mm=0.01, verbose=0, default_F=0, interpolate=0, profile="gauss", spot_scale_override=None, show_params=False, time_panels=False, add_water = False, add_air=False, water_path_mm=0.005, air_path_mm=0, adc_offset=0, readout_noise=3, psf_fwhm=0, gain=1, mosaicity_random_seeds=None, include_background=True, mask_file="",skip_numpy=False,relevant_whitelist_order=None): from simtbx.nanoBragg.nanoBragg_beam import NBbeam from simtbx.nanoBragg.nanoBragg_crystal import NBcrystal from simtbx.nanoBragg.sim_data import SimData from simtbx.nanoBragg.utils import get_xray_beams from scitbx.array_family import flex from scipy import constants import numpy as np ENERGY_CONV = 10000000000.0 * constants.c * constants.h / constants.electron_volt assert cuda # disallow the default nbBeam = NBbeam() nbBeam.size_mm = beamsize_mm nbBeam.unit_s0 = BEAM.get_unit_s0() wavelengths = ENERGY_CONV / np.array(energies) nbBeam.spectrum = list(zip(wavelengths, fluxes)) nbCrystal = NBcrystal(False) nbCrystal.dxtbx_crystal = CRYSTAL #nbCrystal.miller_array = None # use the gpu_channels_singleton mechanism instead nbCrystal.Ncells_abc = Ncells_abc nbCrystal.symbol = CRYSTAL.get_space_group().info().type().lookup_symbol() nbCrystal.thick_mm = crystal_size_mm nbCrystal.xtal_shape = profile nbCrystal.n_mos_domains = mos_dom nbCrystal.mos_spread_deg = mos_spread nbCrystal.anisotropic_mos_spread_deg = mos_aniso pid = 0 # remove the loop, use C++ iteration over detector panels use_exascale_api = True if use_exascale_api: S = SimData(use_default_crystal = False) S.detector = DETECTOR S.beam = nbBeam S.crystal = nbCrystal S.panel_id = pid S.add_air = add_air S.air_path_mm = air_path_mm S.add_water = add_water S.water_path_mm = water_path_mm S.readout_noise = readout_noise S.gain = gain S.psf_fwhm = psf_fwhm S.include_noise = False S.Umats_method = dict(double_random=0, double_uniform=5)[mosaic_method] if mosaicity_random_seeds is not None: S.mosaic_seeds = mosaicity_random_seeds S.instantiate_nanoBragg(verbose=verbose, oversample=oversample, interpolate=interpolate, device_Id=Famp.get_deviceID(),default_F=default_F, adc_offset=adc_offset) SIM = S.D # the nanoBragg instance assert Famp.get_deviceID()==SIM.device_Id if spot_scale_override is not None: SIM.spot_scale = spot_scale_override assert Famp.get_nchannels() == 1 # non-anomalous scenario from simtbx.gpu import exascale_api gpu_simulation = exascale_api(nanoBragg = SIM) gpu_simulation.allocate() # presumably done once for each image from simtbx.gpu import gpu_detector as gpud gpu_detector = gpud(deviceId=SIM.device_Id, detector=DETECTOR, beam=BEAM) gpu_detector.each_image_allocate() # revisit the allocate cuda for overlap with detector, sync up please x = 0 # only one energy channel if mask_file is "": # all-pixel kernel P = Profiler("%40s"%"from gpu amplitudes cuda") gpu_simulation.add_energy_channel_from_gpu_amplitudes( x, Famp, gpu_detector) elif type(mask_file) is flex.bool: # 1D bool array, flattened from ipanel, islow, ifast P = Profiler("%40s"%"from gpu amplitudes cuda with bool mask") gpu_simulation.add_energy_channel_mask_allpanel( channel_number = x, gpu_amplitudes = Famp, gpu_detector = gpu_detector, pixel_active_mask_bools = mask_file ) elif type(mask_file) is flex.int: # precalculated active_pixel_list P = Profiler("%40s"%"from gpu amplitudes cuda w/int whitelist") gpu_simulation.add_energy_channel_mask_allpanel( channel_number = x, gpu_amplitudes = Famp, gpu_detector = gpu_detector, pixel_active_list_ints = mask_file ) else: assert type(mask_file) is str from LS49.adse13_187.adse13_221.mask_utils import mask_from_file boolean_mask = mask_from_file(mask_file) P = Profiler("%40s"%"from gpu amplitudes cuda with file mask") gpu_simulation.add_energy_channel_mask_allpanel( x, Famp, gpu_detector, boolean_mask ) TIME_BRAGG = time()-P.start_el per_image_scale_factor = 1. gpu_detector.scale_in_place(per_image_scale_factor) # apply scale directly on GPU if include_background: t_bkgrd_start = time() SIM.beamsize_mm = beamsize_mm wavelength_weights = np.array(background_wavelength_weights) weights = wavelength_weights / wavelength_weights.sum() * background_total_flux spectrum = list(zip(background_wavelengths, weights)) xray_beams = get_xray_beams(spectrum, BEAM) SIM.xray_beams = xray_beams SIM.Fbg_vs_stol = water SIM.flux=sum(weights) SIM.amorphous_sample_thick_mm = background_sample_thick_mm SIM.amorphous_density_gcm3 = density_gcm3 SIM.amorphous_molecular_weight_Da = molecular_weight gpu_simulation.add_background(gpu_detector) TIME_BG = time()-t_bkgrd_start else: TIME_BG=0. if skip_numpy: P = Profiler("%40s"%"get short whitelist values") whitelist_only = gpu_detector.get_whitelist_raw_pixels(relevant_whitelist_order) # whitelist_only, flex_double pixel values # relevant_whitelist_order, flex.size_t detector addresses assert len(whitelist_only) == len(relevant_whitelist_order) # guard against shoebox overlap bug # when shoeboxes overlap, the overlapped pixels should be simulated once for each parent shoebox P = Profiler("%40s"%"each image free cuda") gpu_detector.each_image_free() return whitelist_only, TIME_BG, TIME_BRAGG, S.exascale_mos_blocks or None packed_numpy = gpu_detector.get_raw_pixels() gpu_detector.each_image_free() return packed_numpy.as_numpy_array(), TIME_BG, TIME_BRAGG, S.exascale_mos_blocks or None
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(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(ROI,prefix,crystal,spectra,rotation,rank,quick=False): smv_fileout = prefix + ".img" direct_algo_res_limit = 1.7 wavlen, flux, wavelength_A = next(spectra) # list of lambdas, list of fluxes, average wavelength tophat_spectrum = True if tophat_spectrum: sum_flux = flex.sum(flux) #from IPython import embed; embed() ave_flux = sum_flux/60. # 60 energy channels for ix in range(len(wavlen)): energy = 12398.425 / wavlen[ix] if energy>=7090 and energy <=7150: flux[ix]=ave_flux else: flux[ix]=0. 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=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 = 50 # 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! output = StringIO() # open("myfile","w") for x in range(0,100,2): #len(flux)): if flux[x]==0.0:continue print("+++++++++++++++++++++++++++++++++++++++ Wavelength",x) CH = channel_pixels(ROI,wavlen[x],flux[x],N,UMAT_nm,Amatrix_rot,GF,output) SIM.raw_pixels += CH.raw_pixels * crystal.domains_per_crystal; print(SIM.raw_pixels) CH.free_all() message = output.getvalue().split() miller = (int(message[4]),int(message[5]),int(message[6])) intensity = float(message[9]); #SIM.to_smv_format(fileout=prefix + "_intimage_001.img") pixels = SIM.raw_pixels roi_pixels = pixels[ROI[1][0]:ROI[1][1], ROI[0][0]:ROI[0][1]] print("Reducing full shape of",pixels.focus(),"to ROI of",roi_pixels.focus()) SIM.free_all() return dict(roi_pixels=roi_pixels,miller=miller,intensity=intensity)
if __name__ == "__main__": import sys print("test with thin bandpass and tophat spectrum") test_cpu_gpu_equivalence() print("test with thin bandpass and tophat spectrum, more channels") test_cpu_gpu_equivalence(n_chan=10) print("test with wider bandpass and tophat spectrum") test_cpu_gpu_equivalence(wave_interval=(0.98, 1.02)) print("test with thin bandpass and gaussian spectrum") test_cpu_gpu_equivalence(n_chan=5, spectrum='gaussian', single=2) print("Scale-up the GPU channels--prints timing") from libtbx.development.timers import Profiler for n_chan in [20, 40, 80, 160, 320, 640, 1280, 2560, 5120]: P = Profiler("%d channels" % n_chan) gpu_run = gpu_run_background_simulation() beam = gpu_run.make_multichannel_beam_simulation(n_chan, wave_interval=(0.90, 1.1)) gpu_run.set_beam(beam) gpu_run.gpu_background() del P print("OK")
def __init__(self, **kwargs): group_args.__init__(self, **kwargs) # require Dij, d_c P = Profiler("2. calculate rho density") print("finished Dij, now calculating rho_i, the density") from xfel.clustering import Rodriguez_Laio_clustering_2014 R = Rodriguez_Laio_clustering_2014(distance_matrix=self.Dij, d_c=self.d_c) self.rho = rho = R.get_rho() ave_rho = flex.mean(rho.as_double()) NN = self.Dij.focus()[0] print("The average rho_i is %5.2f, or %4.1f%%" % (ave_rho, 100 * ave_rho / NN)) i_max = flex.max_index(rho) P = Profiler("3.transition") print("the index with the highest density is %d" % (i_max)) delta_i_max = flex.max( flex.double([self.Dij[i_max, j] for j in range(NN)])) print("delta_i_max", delta_i_max) rho_order = flex.sort_permutation(rho, reverse=True) rho_order_list = list(rho_order) P = Profiler("4. delta") self.delta = delta = R.get_delta(rho_order=rho_order, delta_i_max=delta_i_max) P = Profiler("5. find cluster maxima") #---- Now hunting for clusters cluster_id = flex.int(NN, -1) # default -1 means no cluster delta_order = flex.sort_permutation(delta, reverse=True) N_CLUST = 10 # maximum of 10 points to be considered as possible clusters MAX_PERCENTILE_DELTA = 0.10 # cluster centers have to be in the top 10% percentile delta MAX_PERCENTILE_RHO = 0.75 # cluster centers have to be in the top 75% percentile rho n_cluster = 0 max_n_delta = min(N_CLUST, int(MAX_PERCENTILE_DELTA * NN)) for ic in range(max_n_delta): # test the density, rho item_idx = delta_order[ic] if delta[item_idx] < 0.25 * delta[ delta_order[0]]: # too low (another heuristic!) continue item_rho_order = rho_order_list.index(item_idx) if item_rho_order / NN < MAX_PERCENTILE_RHO: cluster_id[item_idx] = n_cluster print(ic, item_idx, item_rho_order, cluster_id[item_idx]) n_cluster += 1 print("Found %d clusters" % n_cluster) for x in range(NN): if cluster_id[x] >= 0: print("XC", x, cluster_id[x], rho[x], delta[x]) self.cluster_id_maxima = cluster_id.deep_copy() P = Profiler("6. assign all points") R.cluster_assignment(rho_order, cluster_id) self.cluster_id_full = cluster_id.deep_copy() # assign the halos P = Profiler("7. assign halos") halo = flex.bool(NN, False) border = R.get_border(cluster_id=cluster_id) for ic in range(n_cluster ): #loop thru all border regions; find highest density print("cluster", ic, "in border", border.count(True)) this_border = (cluster_id == ic) & (border == True) print(len(this_border), this_border.count(True)) if this_border.count(True) > 0: highest_density = flex.max(rho.select(this_border)) halo_selection = (rho < highest_density) & (this_border == True) if halo_selection.count(True) > 0: cluster_id.set_selected(halo_selection, -1) core_selection = (cluster_id == ic) & ~halo_selection highest_density = flex.max(rho.select(core_selection)) too_sparse = core_selection & ( rho.as_double() < highest_density / 10. ) # another heuristic if too_sparse.count(True) > 0: cluster_id.set_selected(too_sparse, -1) self.cluster_id_final = cluster_id.deep_copy() print("%d in the excluded halo" % ((cluster_id == -1).count(True)))
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_detail(show_plot, save_plot): P = Profiler("0. Read data") import pickle DP = pickle.load(open("mbhresults.pickle", "rb")) coord_x = DP.get("coord_x") coord_y = DP.get("coord_y") del P print(("There are %d points" % (len(coord_x)))) if show_plot or save_plot: import matplotlib if not show_plot: # http://matplotlib.org/faq/howto_faq.html#generate-images-without-having-a-window-appear matplotlib.use('Agg') # use a non-interactive backend from matplotlib import pyplot as plt plt.plot(coord_x, coord_y, "k.", markersize=3.) plt.axes().set_aspect("equal") if save_plot: plt.savefig(plot_name, size_inches=(10, 10), dpi=300, bbox_inches='tight') if show_plot: plt.show() print("Now constructing a Dij matrix.") P = Profiler("1. compute Dij matrix") NN = len(coord_x) embedded_vec2 = flex.vec2_double(coord_x, coord_y) Dij = embedded_vec2.distance_matrix(embedded_vec2) del P d_c = 0.04 # the distance cutoff, such that average item neighbors 1-2% of all items CM = clustering_manager(Dij=Dij, d_c=d_c) appcolors = [ 'b', 'r', '#ff7f0e', '#2ca02c', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf' ] if show_plot: #Decision graph from matplotlib import pyplot as plt plt.plot(CM.rho, CM.delta, "r.", markersize=3.) for x in range(NN): if CM.cluster_id_maxima[x] >= 0: plt.plot([CM.rho[x]], [CM.delta[x]], "ro") plt.show() #No-halo plot from matplotlib import pyplot as plt colors = [appcolors[i % 10] for i in CM.cluster_id_full] plt.scatter(coord_x, coord_y, marker='o', color=colors, linewidths=0.4, edgecolor='k') plt.axes().set_aspect("equal") plt.show() #Final plot halo = (CM.cluster_id_final == -1) core = ~halo plt.plot(coord_x.select(halo), coord_y.select(halo), "k.") colors = [appcolors[i % 10] for i in CM.cluster_id_final.select(core)] plt.scatter(coord_x.select(core), coord_y.select(core), marker="o", color=colors, linewidths=0.4, edgecolor='k') plt.axes().set_aspect("equal") plt.show()
def __init__(self, **kwargs): group_args.__init__(self, **kwargs) # require Dij, d_c P = Profiler("2. calculate rho density") print "finished Dij, now calculating rho_i, the density" from xfel.clustering import Rodriguez_Laio_clustering_2014 # alternative clustering algorithms: see http://scikit-learn.org/stable/modules/clustering.html # also see https://cran.r-project.org/web/packages/dbscan/vignettes/hdbscan.html # see also https://en.wikipedia.org/wiki/Hausdorff_dimension R = Rodriguez_Laio_clustering_2014(distance_matrix=self.Dij, d_c=self.d_c) self.rho = rho = R.get_rho() ave_rho = flex.mean(rho.as_double()) NN = self.Dij.focus()[0] print "The average rho_i is %5.2f, or %4.1f%%" % (ave_rho, 100 * ave_rho / NN) i_max = flex.max_index(rho) P = Profiler("3.transition") print "the index with the highest density is %d" % (i_max) delta_i_max = flex.max( flex.double([self.Dij[i_max, j] for j in xrange(NN)])) print "delta_i_max", delta_i_max rho_order = flex.sort_permutation(rho, reverse=True) rho_order_list = list(rho_order) P = Profiler("4. delta") self.delta = delta = R.get_delta(rho_order=rho_order, delta_i_max=delta_i_max) P = Profiler("5. find cluster maxima") #---- Now hunting for clusters ---Lot's of room for improvement (or simplification) here!!! cluster_id = flex.int(NN, -1) # default -1 means no cluster delta_order = flex.sort_permutation(delta, reverse=True) N_CLUST = 10 # maximum of 10 points to be considered as possible clusters #MAX_PERCENTILE_DELTA = 0.99 # cluster centers have to be in the top 10% percentile delta MAX_PERCENTILE_RHO = 0.99 # cluster centers have to be in the top 75% percentile rho n_cluster = 0 #max_n_delta = min(N_CLUST, int(MAX_PERCENTILE_DELTA*NN)) for ic in xrange(NN): # test the density, rho item_idx = delta_order[ic] if delta[item_idx] > 100: print "A: iteration", ic, "delta", delta[ item_idx], delta[item_idx] < 0.25 * delta[delta_order[0]] if delta[item_idx] < 0.25 * delta[ delta_order[0]]: # too low (another heuristic!) continue item_rho_order = rho_order_list.index(item_idx) if delta[item_idx] > 100: print "B: iteration", ic, item_rho_order, item_rho_order / NN, MAX_PERCENTILE_RHO if item_rho_order / NN < MAX_PERCENTILE_RHO: cluster_id[item_idx] = n_cluster print ic, item_idx, item_rho_order, cluster_id[item_idx] n_cluster += 1 print "Found %d clusters" % n_cluster for x in xrange(NN): if cluster_id[x] >= 0: print "XC", x, cluster_id[x], rho[x], delta[x] self.cluster_id_maxima = cluster_id.deep_copy() P = Profiler("6. assign all points") R.cluster_assignment(rho_order, cluster_id) self.cluster_id_full = cluster_id.deep_copy() # assign the halos P = Profiler("7. assign halos") halo = flex.bool(NN, False) border = R.get_border(cluster_id=cluster_id) for ic in range(n_cluster ): #loop thru all border regions; find highest density print "cluster", ic, "in border", border.count(True) this_border = (cluster_id == ic) & (border == True) print len(this_border), this_border.count(True) if this_border.count(True) > 0: highest_density = flex.max(rho.select(this_border)) halo_selection = (rho < highest_density) & (this_border == True) if halo_selection.count(True) > 0: cluster_id.set_selected(halo_selection, -1) core_selection = (cluster_id == ic) & ~halo_selection highest_density = flex.max(rho.select(core_selection)) too_sparse = core_selection & ( rho.as_double() < highest_density / 10. ) # another heuristic if too_sparse.count(True) > 0: cluster_id.set_selected(too_sparse, -1) self.cluster_id_final = cluster_id.deep_copy() print "%d in the excluded halo" % ((cluster_id == -1).count(True))