def _predict_one_experiment(self, experiment, reflections): B = flex.mat3_double(len(reflections), experiment.crystal.get_B()) r0 = B * reflections["miller_index"].as_vec3_double() r0len = r0.norms() wl = experiment.beam.get_wavelength() # 2theta = 2 * arcsin( |r0| / (2 * |s0| ) ) reflections["2theta_cal.rad"] = 2.0 * flex.asin(0.5 * r0len * wl) reflections.set_flags(flex.size_t(len(reflections)), reflections.flags.predicted)
def __call__(self, reflections): """Predict 2theta angles for all reflections at the current model geometry""" for iexp, e in enumerate(self._experiments): # select the reflections for this experiment only sel = reflections['id'] == iexp refs = reflections.select(sel) B = flex.mat3_double(len(reflections), e.crystal.get_B()) r0 = B * reflections['miller_index'].as_vec3_double() r0len = r0.norms() wl = e.beam.get_wavelength() # 2theta = 2 * arcsin( |r0| / (2 * |s0| ) ) twotheta = 2.0 * flex.asin(0.5 * r0len * wl) # write predictions back to overall reflections reflections['2theta_cal.rad'].set_selected(sel, twotheta) # set predicted flag reflections.set_flags(sel, reflections.flags.predicted) return reflections
def process(self, img_object): # write out DIALS info (tied to self.write_pickle) if self.write_pickle: self.params.output.indexed_filename = img_object.ridx_path self.params.output.strong_filename = img_object.rspf_path self.params.output.refined_experiments_filename = img_object.eref_path self.params.output.integrated_experiments_filename = img_object.eint_path self.params.output.integrated_filename = img_object.rint_path # Set up integration pickle path and logfile self.params.output.integration_pickle = img_object.int_file self.int_log = img_object.int_log # configure DIALS logging self.dials_log = getattr(img_object, 'dials_log', None) if self.dials_log: log.config(verbosity=1, logfile=self.dials_log) # Create output folder if one does not exist if self.write_pickle: if not os.path.isdir(img_object.int_path): os.makedirs(img_object.int_path) # Auto-set threshold and gain (not saved for target.phil) if self.iparams.cctbx_xfel.auto_threshold: center_int = img_object.center_int if img_object.center_int else 0 threshold = int(center_int) self.params.spotfinder.threshold.dispersion.global_threshold = threshold if self.iparams.image_import.estimate_gain: self.params.spotfinder.threshold.dispersion.gain = img_object.gain # Update geometry if reference geometry was applied from dials.command_line.dials_import import ManualGeometryUpdater update_geometry = ManualGeometryUpdater(self.params) try: imagesets = img_object.experiments.imagesets() update_geometry(imagesets[0]) experiment = img_object.experiments[0] experiment.beam = imagesets[0].get_beam() experiment.detector = imagesets[0].get_detector() except RuntimeError as e: print("DEBUG: Error updating geometry on {}, {}".format( img_object.img_path, e)) # Set detector if reference geometry was applied if self.reference_detector is not None: try: from dxtbx.model import Detector imageset = img_object.experiments[0].imageset imageset.set_detector( Detector.from_dict(self.reference_detector.to_dict())) img_object.experiments[0].detector = imageset.get_detector() except Exception as e: print('DEBUG: cannot set detector! ', e) # Write full params to file (DEBUG) if self.write_logs: param_string = phil_scope.format( python_object=self.params).as_str() full_param_dir = os.path.dirname(self.iparams.cctbx_xfel.target) full_param_fn = 'full_' + os.path.basename( self.iparams.cctbx_xfel.target) full_param_file = os.path.join(full_param_dir, full_param_fn) with open(full_param_file, 'w') as ftarg: ftarg.write(param_string) # **** SPOTFINDING **** # with util.Capturing() as output: try: print("{:-^100}\n".format(" SPOTFINDING: ")) print('<--->') observed = self.find_spots(img_object.experiments) img_object.final['spots'] = len(observed) except Exception as e: e_spf = str(e) observed = None else: if (self.iparams.data_selection.image_triage and len(observed) >= self.iparams.data_selection. image_triage.minimum_Bragg_peaks): msg = " FOUND {} SPOTS - IMAGE ACCEPTED!".format( len(observed)) print("{:-^100}\n\n".format(msg)) else: msg = " FOUND {} SPOTS - IMAGE REJECTED!".format( len(observed)) print("{:-^100}\n\n".format(msg)) e = 'Insufficient spots found ({})!'.format(len(observed)) return self.error_handler(e, 'triage', img_object, output) if not observed: return self.error_handler(e_spf, 'spotfinding', img_object, output) if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) # Finish if spotfinding is the last processing stage if 'spotfind' in self.last_stage: try: detector = img_object.experiments.unique_detectors()[0] beam = img_object.experiments.unique_beams()[0] except AttributeError: detector = img_object.experiments.imagesets()[0].get_detector() beam = img_object.experiments.imagesets()[0].get_beam() s1 = flex.vec3_double() for i in range(len(observed)): s1.append(detector[observed['panel'][i]].get_pixel_lab_coord( observed['xyzobs.px.value'][i][0:2])) two_theta = s1.angle(beam.get_s0()) d = beam.get_wavelength() / (2 * flex.asin(two_theta / 2)) img_object.final['res'] = np.max(d) img_object.final['lres'] = np.min(d) return img_object # **** INDEXING **** # with util.Capturing() as output: try: print("{:-^100}\n".format(" INDEXING")) print('<--->') experiments, indexed = self.index(img_object.experiments, observed) except Exception as e: e_idx = str(e) indexed = None else: if indexed: img_object.final['indexed'] = len(indexed) print("{:-^100}\n\n".format(" USED {} INDEXED REFLECTIONS " "".format(len(indexed)))) else: e_idx = "Not indexed for unspecified reason(s)" img_object.fail = 'failed indexing' if indexed: if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) else: return self.error_handler(e_idx, 'indexing', img_object, output) with util.Capturing() as output: # Bravais lattice and reindex if self.iparams.cctbx_xfel.determine_sg_and_reindex: try: print("{:-^100}\n".format(" DETERMINING SPACE GROUP")) print('<--->') experiments, indexed = self.pg_and_reindex( indexed, experiments) img_object.final['indexed'] = len(indexed) lat = experiments[0].crystal.get_space_group().info() sg = str(lat).replace(' ', '') if sg != 'P1': print("{:-^100}\n".format( " REINDEXED TO SPACE GROUP {} ".format(sg))) else: print("{:-^100}\n".format( " RETAINED TRICLINIC (P1) SYMMETRY ")) reindex_success = True except Exception as e: e_ridx = str(e) reindex_success = False if reindex_success: if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) else: return self.error_handler(e_ridx, 'indexing', img_object, output) # **** REFINEMENT **** # with util.Capturing() as output: try: experiments, indexed = self.refine(experiments, indexed) refined = True except Exception as e: e_ref = str(e) refined = False if refined: if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) else: return self.error_handler(e_ref, 'refinement', img_object, output) # **** INTEGRATION **** # with util.Capturing() as output: try: print("{:-^100}\n".format(" INTEGRATING ")) print('<--->') integrated = self.integrate(experiments, indexed) except Exception as e: e_int = str(e) integrated = None else: if integrated: img_object.final['integrated'] = len(integrated) print("{:-^100}\n\n".format( " FINAL {} INTEGRATED REFLECTIONS " "".format(len(integrated)))) if integrated: if self.write_logs: self.write_int_log(path=img_object.int_log, output=output, dials_log=self.dials_log) else: return self.error_handler(e_int, 'integration', img_object, output) # Filter if self.iparams.cctbx_xfel.filter.flag_on: self.selector = Selector( frame=self.frame, uc_tol=self.iparams.cctbx_xfel.filter.uc_tolerance, xsys=self.iparams.cctbx_xfel.filter.crystal_system, pg=self.iparams.cctbx_xfel.filter.pointgroup, uc=self.iparams.cctbx_xfel.filter.unit_cell, min_ref=self.iparams.cctbx_xfel.filter.min_reflections, min_res=self.iparams.cctbx_xfel.filter.min_resolution) fail, e = self.selector.result_filter() if fail: return self.error_handler(e, 'filter', img_object, output) int_results, log_entry = self.collect_information( img_object=img_object) # Update final entry with integration results img_object.final.update(int_results) # Update image log log_entry = "\n".join(log_entry) img_object.log_info.append(log_entry) if self.write_logs: self.write_int_log(path=img_object.int_log, log_entry=log_entry) return img_object
def plot_one_model(self, nrow, out): fig = plt.subplot(self.gs[nrow * self.ncols]) two_thetas = self.reduction.get_two_theta_deg() degrees = self.reduction.get_delta_psi_deg() if self.color_encoding == "conventional": positive = (self.reduction.i_sigi >= 0.) fig.plot(two_thetas.select(positive), degrees.select(positive), "bo") fig.plot(two_thetas.select(~positive), degrees.select(~positive), "r+") elif self.color_encoding == "I/sigma": positive = (self.reduction.i_sigi >= 0.) tt_selected = two_thetas.select(positive) dp_selected = degrees.select(positive) i_sigi_select = self.reduction.i_sigi.select(positive) order = flex.sort_permutation(i_sigi_select) tt_selected = tt_selected.select(order) dp_selected = dp_selected.select(order) i_sigi_selected = i_sigi_select.select(order) from matplotlib.colors import Normalize dnorm = Normalize() dcolors = i_sigi_selected.as_numpy_array() dnorm.autoscale(dcolors) N = len(dcolors) CMAP = plt.get_cmap("rainbow") if self.refined.get("partiality_array", None) is None: for n in xrange(N): fig.plot([tt_selected[n]], [dp_selected[n]], color=CMAP(dnorm(dcolors[n])), marker=".", markersize=10) else: partials = self.refined.get("partiality_array") partials_select = partials.select(positive) partials_selected = partials_select.select(order) assert len(partials) == len(positive) for n in xrange(N): fig.plot([tt_selected[n]], [dp_selected[n]], color=CMAP(dnorm(dcolors[n])), marker=".", markersize=20 * partials_selected[n]) # change the markersize to indicate partiality. negative = (self.reduction.i_sigi < 0.) fig.plot(two_thetas.select(negative), degrees.select(negative), "r+", linewidth=1) else: strong = (self.reduction.i_sigi >= 10.) positive = ((~strong) & (self.reduction.i_sigi >= 0.)) negative = (self.reduction.i_sigi < 0.) assert (strong.count(True) + positive.count(True) + negative.count(True) == len(self.reduction.i_sigi)) fig.plot(two_thetas.select(positive), degrees.select(positive), "bo") fig.plot(two_thetas.select(strong), degrees.select(strong), marker='.', linestyle='None', markerfacecolor='#00ee00', markersize=10) fig.plot(two_thetas.select(negative), degrees.select(negative), "r+") # indicate the imposed resolution filter wavelength = self.reduction.experiment.beam.get_wavelength() imposed_res_filter = self.reduction.get_imposed_res_filter(out) resolution_markers = [ a for a in [imposed_res_filter, self.reduction.measurements.d_min()] if a is not None ] for RM in resolution_markers: two_th = (180. / math.pi) * 2. * math.asin(wavelength / (2. * RM)) plt.plot([two_th, two_th], [self.AD1TF7B_MAXDP * -0.8, self.AD1TF7B_MAXDP * 0.8], 'k-') plt.text(two_th, self.AD1TF7B_MAXDP * -0.9, "%4.2f" % RM) #indicate the linefit mean = flex.mean(degrees) minplot = flex.min(two_thetas) plt.plot([0, minplot], [mean, mean], "k-") LR = flex.linear_regression(two_thetas, degrees) model_y = LR.slope() * two_thetas + LR.y_intercept() plt.plot(two_thetas, model_y, "k-") #Now let's take care of the red and green lines. half_mosaic_rotation_deg = self.refined["half_mosaic_rotation_deg"] mosaic_domain_size_ang = self.refined["mosaic_domain_size_ang"] red_curve_domain_size_ang = self.refined.get( "red_curve_domain_size_ang", mosaic_domain_size_ang) a_step = self.AD1TF7B_MAX2T / 50. a_range = flex.double([a_step * x for x in xrange(1, 50) ]) # domain two-theta array #Bragg law [d=L/2sinTH] d_spacing = (wavelength / (2. * flex.sin(math.pi * a_range / 360.))) # convert two_theta to a delta-psi. Formula for Deffective [Dpsi=d/2Deff] inner_phi_deg = flex.asin( (d_spacing / (2. * red_curve_domain_size_ang))) * (180. / math.pi) outer_phi_deg = flex.asin((d_spacing / (2.*mosaic_domain_size_ang)) + \ half_mosaic_rotation_deg*math.pi/180. )*(180./math.pi) plt.title("ML: mosaicity FW=%4.2f deg, Dsize=%5.0fA on %d spots\n%s" % (2. * half_mosaic_rotation_deg, mosaic_domain_size_ang, len(two_thetas), os.path.basename(self.reduction.filename))) plt.plot(a_range, inner_phi_deg, "r-") plt.plot(a_range, -inner_phi_deg, "r-") plt.plot(a_range, outer_phi_deg, "g-") plt.plot(a_range, -outer_phi_deg, "g-") plt.xlim([0, self.AD1TF7B_MAX2T]) plt.ylim([-self.AD1TF7B_MAXDP, self.AD1TF7B_MAXDP]) #second plot shows histogram fig = plt.subplot(self.gs[1 + nrow * self.ncols]) plt.xlim([-self.AD1TF7B_MAXDP, self.AD1TF7B_MAXDP]) nbins = 50 n, bins, patches = plt.hist( dp_selected, nbins, range=(-self.AD1TF7B_MAXDP, self.AD1TF7B_MAXDP), weights=self.reduction.i_sigi.select(positive), normed=0, facecolor="orange", alpha=0.75) #ersatz determine the median i_sigi point: isi_positive = self.reduction.i_sigi.select(positive) isi_order = flex.sort_permutation(isi_positive) reordered = isi_positive.select(isi_order) isi_median = reordered[int(len(isi_positive) * 0.9)] isi_top_half_selection = (isi_positive > isi_median) n, bins, patches = plt.hist( dp_selected.select(isi_top_half_selection), nbins, range=(-self.AD1TF7B_MAXDP, self.AD1TF7B_MAXDP), weights=isi_positive.select(isi_top_half_selection), normed=0, facecolor="#ff0000", alpha=0.75) plt.xlabel("(degrees)") plt.title("Weighted histogram of Delta-psi")
def compute_intensity_parameters(self): """ Create a new reflection table with all the derived parameters needed to apply corrections from RS postrefinement """ refls = self.scaler.ISIGI ct = self.scaler.crystal_table rx = flex.mat3_double() # crystal rotation around x ry = flex.mat3_double() # crystal rotation around y u = flex.mat3_double() # U matrix (orientation) b = flex.mat3_double() # B matrix (cell parameters) wavelength = flex.double() G = flex.double() # scaling gfactor B = flex.double() # wilson B factor s0 = flex.vec3_double() # beam vector deff = flex.double() # effective domain size eta = flex.double() # effective mosaic domain misorientation angle ex = col((1,0,0)) # crystal rotation x axis ey = col((0,1,0)) # crystal rotation y axis for i in xrange(len(ct)): # Need to copy crystal specific terms for each reflection. Equivalent to a JOIN in SQL. n_refl = ct['n_refl'][i] rx.extend(flex.mat3_double(n_refl, ex.axis_and_angle_as_r3_rotation_matrix(ct['thetax'][i]))) ry.extend(flex.mat3_double(n_refl, ey.axis_and_angle_as_r3_rotation_matrix(ct['thetay'][i]))) u.extend(flex.mat3_double(n_refl, ct['u_matrix'][i])) b.extend(flex.mat3_double(n_refl, ct['b_matrix'][i])) wavelength.extend(flex.double(n_refl, ct['wavelength'][i])) G.extend(flex.double(n_refl, ct['G'][i])) B.extend(flex.double(n_refl, ct['B'][i])) s0.extend(flex.vec3_double(n_refl, (0,0,-1)) * (1/ct['wavelength'][i])) deff.extend(flex.double(n_refl, ct['deff'][i])) eta.extend(flex.double(n_refl, ct['eta'][i])) iobs = refls['iobs'] h = refls['miller_index_original'].as_vec3_double() q = ry * rx * u * b * h # vector pointing from origin of reciprocal space to RLP qlen = q.norms() # length of q d = 1/q.norms() # resolution #rs = (1/deff)+(eta/(2*d)) # proper formulation of RS rs = 1/deff # assumes eta is zero rs_sq = rs*rs # square of rs s = (s0+q) # vector from center of Ewald sphere to RLP slen = s.norms() # length of s rh = slen-(1/wavelength) # distance from RLP to Ewald sphere p_n = rs_sq # numerator of partiality lorenzian expression p_d = (2. * (rh * rh)) + rs_sq # denominator of partiality lorenzian expression partiality = p_n/p_d theta = flex.asin(wavelength/(2*d)) epsilon = -8*B*(flex.sin(theta)/wavelength)**2 # exponential term in partiality eepsilon = flex.exp(epsilon) # e^epsilon D = partiality * G * eepsilon # denominator of partiality lorenzian expression thetah = flex.asin(wavelength/(2*d)) # reflecting angle sinthetah = flex.sin(thetah) er = sinthetah/wavelength # ratio term in epsilon # save all the columns r = flex.reflection_table() r['rx'] = rx r['ry'] = ry r['u'] = u r['b'] = b r['h'] = h r['q'] = q r['qlen'] = qlen r['D'] = D r['rs'] = rs r['eta'] = eta r['deff'] = deff r['d'] = d r['s'] = s r['slen'] = slen r['wavelength'] = wavelength r['p_n'] = p_n r['p_d'] = p_d r['partiality'] = partiality r['G'] = G r['B'] = B r['eepsilon'] = eepsilon r['thetah'] = thetah r['sinthetah'] = sinthetah r['er'] = er return r
def plot_one_model(self,nrow,out): fig = plt.subplot(self.gs[nrow*self.ncols]) two_thetas = self.reduction.get_two_theta_deg() degrees = self.reduction.get_delta_psi_deg() if self.color_encoding=="conventional": positive = (self.reduction.i_sigi>=0.) fig.plot(two_thetas.select(positive), degrees.select(positive), "bo") fig.plot(two_thetas.select(~positive), degrees.select(~positive), "r+") elif self.color_encoding=="I/sigma": positive = (self.reduction.i_sigi>=0.) tt_selected = two_thetas.select(positive) dp_selected = degrees.select(positive) i_sigi_select = self.reduction.i_sigi.select(positive) order = flex.sort_permutation(i_sigi_select) tt_selected = tt_selected.select(order) dp_selected = dp_selected.select(order) i_sigi_selected = i_sigi_select.select(order) from matplotlib.colors import Normalize dnorm = Normalize() dcolors = i_sigi_selected.as_numpy_array() dnorm.autoscale(dcolors) N = len(dcolors) CMAP = plt.get_cmap("rainbow") if self.refined.get("partiality_array",None) is None: for n in xrange(N): fig.plot([tt_selected[n]],[dp_selected[n]], color=CMAP(dnorm(dcolors[n])),marker=".", markersize=10) else: partials = self.refined.get("partiality_array") partials_select = partials.select(positive) partials_selected = partials_select.select(order) assert len(partials)==len(positive) for n in xrange(N): fig.plot([tt_selected[n]],[dp_selected[n]], color=CMAP(dnorm(dcolors[n])),marker=".", markersize=20*partials_selected[n]) # change the markersize to indicate partiality. negative = (self.reduction.i_sigi<0.) fig.plot(two_thetas.select(negative), degrees.select(negative), "r+", linewidth=1) else: strong = (self.reduction.i_sigi>=10.) positive = ((~strong) & (self.reduction.i_sigi>=0.)) negative = (self.reduction.i_sigi<0.) assert (strong.count(True)+positive.count(True)+negative.count(True) == len(self.reduction.i_sigi)) fig.plot(two_thetas.select(positive), degrees.select(positive), "bo") fig.plot(two_thetas.select(strong), degrees.select(strong), marker='.',linestyle='None', markerfacecolor='#00ee00', markersize=10) fig.plot(two_thetas.select(negative), degrees.select(negative), "r+") # indicate the imposed resolution filter wavelength = self.reduction.experiment.beam.get_wavelength() imposed_res_filter = self.reduction.get_imposed_res_filter(out) resolution_markers = [ a for a in [imposed_res_filter,self.reduction.measurements.d_min()] if a is not None] for RM in resolution_markers: two_th = (180./math.pi)*2.*math.asin(wavelength/(2.*RM)) plt.plot([two_th, two_th],[self.AD1TF7B_MAXDP*-0.8,self.AD1TF7B_MAXDP*0.8],'k-') plt.text(two_th,self.AD1TF7B_MAXDP*-0.9,"%4.2f"%RM) #indicate the linefit mean = flex.mean(degrees) minplot = flex.min(two_thetas) plt.plot([0,minplot],[mean,mean],"k-") LR = flex.linear_regression(two_thetas, degrees) model_y = LR.slope()*two_thetas + LR.y_intercept() plt.plot(two_thetas, model_y, "k-") #Now let's take care of the red and green lines. half_mosaic_rotation_deg = self.refined["half_mosaic_rotation_deg"] mosaic_domain_size_ang = self.refined["mosaic_domain_size_ang"] red_curve_domain_size_ang = self.refined.get("red_curve_domain_size_ang",mosaic_domain_size_ang) a_step = self.AD1TF7B_MAX2T / 50. a_range = flex.double([a_step*x for x in xrange(1,50)]) # domain two-theta array #Bragg law [d=L/2sinTH] d_spacing = (wavelength/(2.*flex.sin(math.pi*a_range/360.))) # convert two_theta to a delta-psi. Formula for Deffective [Dpsi=d/2Deff] inner_phi_deg = flex.asin((d_spacing / (2.*red_curve_domain_size_ang)) )*(180./math.pi) outer_phi_deg = flex.asin((d_spacing / (2.*mosaic_domain_size_ang)) + \ half_mosaic_rotation_deg*math.pi/180. )*(180./math.pi) plt.title("ML: mosaicity FW=%4.2f deg, Dsize=%5.0fA on %d spots\n%s"%( 2.*half_mosaic_rotation_deg, mosaic_domain_size_ang, len(two_thetas), os.path.basename(self.reduction.filename))) plt.plot(a_range, inner_phi_deg, "r-") plt.plot(a_range,-inner_phi_deg, "r-") plt.plot(a_range, outer_phi_deg, "g-") plt.plot(a_range, -outer_phi_deg, "g-") plt.xlim([0,self.AD1TF7B_MAX2T]) plt.ylim([-self.AD1TF7B_MAXDP,self.AD1TF7B_MAXDP]) #second plot shows histogram fig = plt.subplot(self.gs[1+nrow*self.ncols]) plt.xlim([-self.AD1TF7B_MAXDP,self.AD1TF7B_MAXDP]) nbins = 50 n,bins,patches = plt.hist(dp_selected, nbins, range=(-self.AD1TF7B_MAXDP,self.AD1TF7B_MAXDP), weights=self.reduction.i_sigi.select(positive), normed=0, facecolor="orange", alpha=0.75) #ersatz determine the median i_sigi point: isi_positive = self.reduction.i_sigi.select(positive) isi_order = flex.sort_permutation(isi_positive) reordered = isi_positive.select(isi_order) isi_median = reordered[int(len(isi_positive)*0.9)] isi_top_half_selection = (isi_positive>isi_median) n,bins,patches = plt.hist(dp_selected.select(isi_top_half_selection), nbins, range=(-self.AD1TF7B_MAXDP,self.AD1TF7B_MAXDP), weights=isi_positive.select(isi_top_half_selection), normed=0, facecolor="#ff0000", alpha=0.75) plt.xlabel("(degrees)") plt.title("Weighted histogram of Delta-psi")
def process(self, img_object): # write out DIALS info pfx = os.path.splitext(img_object.obj_file)[0] self.params.output.experiments_filename = pfx + '_experiments.json' self.params.output.indexed_filename = pfx + '_indexed.pickle' self.params.output.strong_filename = pfx + '_strong.pickle' self.params.output.refined_experiments_filename = pfx + '_refined_experiments.json' self.params.output.integrated_experiments_filename = pfx + '_integrated_experiments.json' self.params.output.integrated_filename = pfx + '_integrated.pickle' # Set up integration pickle path and logfile self.params.verbosity = 10 self.params.output.integration_pickle = img_object.int_file self.int_log = img_object.int_log # Create output folder if one does not exist if self.write_pickle: if not os.path.isdir(img_object.int_path): os.makedirs(img_object.int_path) if not img_object.experiments: from dxtbx.model.experiment_list import ExperimentListFactory as exp img_object.experiments = exp.from_filenames([img_object.img_path])[0] # Auto-set threshold and gain (not saved for target.phil) if self.iparams.cctbx_xfel.auto_threshold: threshold = int(img_object.center_int) self.params.spotfinder.threshold.dispersion.global_threshold = threshold if self.iparams.image_import.estimate_gain: self.params.spotfinder.threshold.dispersion.gain = img_object.gain # Update geometry if reference geometry was applied from dials.command_line.dials_import import ManualGeometryUpdater update_geometry = ManualGeometryUpdater(self.params) try: imagesets = img_object.experiments.imagesets() update_geometry(imagesets[0]) experiment = img_object.experiments[0] experiment.beam = imagesets[0].get_beam() experiment.detector = imagesets[0].get_detector() except RuntimeError as e: print("DEBUG: Error updating geometry on {}, {}".format( img_object.img_path, e)) # Set detector if reference geometry was applied if self.reference_detector is not None: try: from dxtbx.model import Detector imageset = img_object.experiments[0].imageset imageset.set_detector( Detector.from_dict(self.reference_detector.to_dict()) ) img_object.experiments[0].detector = imageset.get_detector() except Exception as e: print ('DEBUG: cannot set detector! ', e) proc_output = [] # **** SPOTFINDING **** # with util.Capturing() as output: try: print ("{:-^100}\n".format(" SPOTFINDING: ")) observed = self.find_spots(img_object.experiments) img_object.final['spots'] = len(observed) except Exception as e: return self.error_handler(e, 'spotfinding', img_object, output) else: if ( self.iparams.image_import.image_triage and len(observed) >= self.iparams.image_import.minimum_Bragg_peaks ): msg = " FOUND {} SPOTS - IMAGE ACCEPTED!".format(len(observed)) print("{:-^100}\n\n".format(msg)) else: msg = " FOUND {} SPOTS - IMAGE REJECTED!".format(len(observed)) print("{:-^100}\n\n".format(msg)) e = 'Insufficient spots found ({})!'.format(len(observed)) return self.error_handler(e, 'triage', img_object, output) proc_output.extend(output) # Finish if spotfinding is the last processing stage if 'spotfind' in self.last_stage: detector = img_object.experiments.unique_detectors()[0] beam = img_object.experiments.unique_beams()[0] s1 = flex.vec3_double() for i in range(len(observed)): s1.append(detector[observed['panel'][i]].get_pixel_lab_coord( observed['xyzobs.px.value'][i][0:2])) two_theta = s1.angle(beam.get_s0()) d = beam.get_wavelength() / (2 * flex.asin(two_theta / 2)) img_object.final['res'] = np.max(d) img_object.final['lres'] = np.min(d) return img_object # **** INDEXING **** # with util.Capturing() as output: try: print ("{:-^100}\n".format(" INDEXING ")) experiments, indexed = self.index(img_object.experiments, observed) except Exception as e: return self.error_handler(e, 'indexing', img_object, output) else: if indexed: img_object.final['indexed'] = len(indexed) print ("{:-^100}\n\n".format(" USED {} INDEXED REFLECTIONS " "".format(len(indexed)))) else: img_object.fail = 'failed indexing' return img_object # Bravais lattice and reindex if self.iparams.cctbx_xfel.determine_sg_and_reindex: try: print ("{:-^100}\n".format(" DETERMINING SPACE GROUP ")) experiments, indexed = self.pg_and_reindex(indexed, experiments) img_object.final['indexed'] = len(indexed) lat = experiments[0].crystal.get_space_group().info() sg = str(lat).replace(' ', '') if sg != 'P1': print ("{:-^100}\n".format(" REINDEXED TO SPACE GROUP {} ".format(sg))) else: print ("{:-^100}\n".format(" RETAINED TRICLINIC (P1) SYMMETRY ")) except Exception as e: return self.error_handler(e, 'indexing', img_object, output) proc_output.extend(output) # **** INTEGRATION **** # with util.Capturing() as output: try: experiments, indexed = self.refine(experiments, indexed) print ("{:-^100}\n".format(" INTEGRATING ")) integrated = self.integrate(experiments, indexed) except Exception as e: return self.error_handler(e, 'integration', img_object, output) else: if integrated: img_object.final['integrated'] = len(integrated) print ("{:-^100}\n\n".format(" FINAL {} INTEGRATED REFLECTIONS " "".format(len(integrated)))) proc_output.extend(output) # Filter if self.iparams.cctbx_xfel.filter.flag_on: self.selector = Selector(frame=self.frame, uc_tol=self.iparams.cctbx_xfel.filter.uc_tolerance, xsys=self.iparams.cctbx_xfel.filter.crystal_system, pg=self.iparams.cctbx_xfel.filter.pointgroup, uc=self.iparams.cctbx_xfel.filter.unit_cell, min_ref=self.iparams.cctbx_xfel.filter.min_reflections, min_res=self.iparams.cctbx_xfel.filter.min_resolution) fail, e = self.selector.result_filter() if fail: return self.error_handler(e, 'filter', img_object, proc_output) int_results, log_entry = self.collect_information(img_object=img_object) # Update final entry with integration results img_object.final.update(int_results) # Update image log log_entry = "\n".join(log_entry) img_object.log_info.append(log_entry) if self.write_logs: with open(img_object.int_log, 'w') as tf: for i in proc_output: if 'cxi_version' not in i: tf.write('\n{}'.format(i)) tf.write('\n{}'.format(log_entry)) return img_object