def write_xds_inp(self, path: str) -> None: """Write XDS.INP input file for XDS in directory `path`""" path.mkdir(exist_ok=True) nframes = max(self.complete_range) invert_rotation_axis = self.start_angle > self.end_angle rot_x, rot_y, rot_z = rotation_axis_to_xyz(self.rotation_axis, invert=invert_rotation_axis) shape_x, shape_y = self.data_shape if self.do_stretch_correction: self.write_geometric_correction_files(path) stretch_correction = "DETECTOR= PILATUS ! Pretend to be PILATUS detector to enable geometric corrections\nX-GEO_CORR= XCORR.cbf ! X stretch correction\nY-GEO_CORR= YCORR.cbf ! Y stretch correction\n" else: stretch_correction = "" if self.missing_range: exclude = "\n".join([ f"EXCLUDE_DATA_RANGE={i} {j}" for i, j in find_subranges(self.missing_range) ]) else: exclude = "!EXCLUDE_DATA_RANGE=" untrusted_areas = "" for kind, coords in self.untrusted_areas: untrusted_areas += to_xds_untrusted_area(kind, coords) + "\n" s = self.XDS_template.format( date=str(time.ctime()), data_drc=self.smv_subdrc, data_begin=1, data_end=nframes, exclude=exclude, stretch_correction=stretch_correction, starting_angle=self.start_angle, wavelength=self.wavelength, # reverse XY coordinates for XDS origin_x=self.mean_beam_center[1], origin_y=self.mean_beam_center[0], untrusted_areas=untrusted_areas, NX=shape_y, NY=shape_x, sign="+", detector_distance=self.distance, QX=self.physical_pixelsize, QY=self.physical_pixelsize, osc_angle=self.osc_angle, rot_x=rot_x, rot_y=rot_y, rot_z=rot_z) with open(path / 'XDS.INP', 'w') as f: print(s, file=f) logger.info("XDS INP file created.")
def get_drifts_per_scan_range(xy): i = np.nansum(xy, axis=1) == 0 rng = np.arange(len(i))[i != True] # noqa subranges = find_subranges(rng) normalized_xy = [] drifts = [] for sbr in subranges: r = np.arange(*sbr) sub_xy = xy[r] if len(sub_xy) == 0: continue o = sub_xy[0] drift = np.linalg.norm(sub_xy - o, axis=1) distance = drift.max() - drift.min() drifts.append(distance) normalized_xy.append(sub_xy - o) normalized_xy.append([np.NaN, np.NaN]) normalized_xy = np.vstack(normalized_xy) drifts = np.array(drifts) # plt.plot(normalized_xy[:,0], label="X") # plt.plot(normalized_xy[:,1], label="Y") # plt.legend() # plt.show() return drifts
def export_dials_variables(path, *, sequence=(), missing=(), rotation_xyz=None): """Export variables for DIALS to account for missing frames writes dials_variables.sh (bash) and dials_variables.bat (cmd) `sequence` is a tuple of sequence numbers of the data frames `missing `is a tuple of sequence numbers of the missing frames """ import io scanranges = find_subranges(sequence) scanrange = " ".join(f"scan_range={i},{j}" for i, j in scanranges) excludeimages = ",".join((str(n) for n in missing)) if rotation_xyz: rot_x, rot_y, rot_z = rotation_xyz # newline='\n' to have unix line endings with open(path / "dials_variables.sh", "w", newline='\n') as f: print(f"#!/usr/bin/env bash", file=f) print(f"scan_range='{scanrange}'", file=f) print(f"exclude_images='exclude_images={excludeimages}'", file=f) if rotation_xyz: print( f"rotation_axis='geometry.goniometer.axes={rot_x:.4f},{rot_y:.4f},{rot_z:.4f}'", file=f) print("#", file=f) print("# To run:", file=f) print("# source dials_variables.sh", file=f) print("#", file=f) print("# and:", file=f) print("# dials.import directory=data $rotation_axis", file=f) print("# dials.find_spots datablock.json $scan_range", file=f) print( "# dials.integrate $exclude_images refined.pickle refined.json", file=f) print("#", file=f) with open(path / "dials_variables.bat", "w", newline='\n') as f: print("@echo off", file=f) print("", file=f) print(f"set scan_range={scanrange}", file=f) print(f"set exclude_images=exclude_images={excludeimages}", file=f) if rotation_xyz: print( f"set rotation_axis=geometry.goniometer.axes={rot_x:.4f},{rot_y:.4f},{rot_z:.4f}", file=f) print("", file=f) print(":: To run:", file=f) print(":: call dials_variables.bat", file=f) print("::", file=f) print(":: dials.import directory=data %rotation_axis%", file=f) print(":: dials.find_spots datablock.json %scan_range%", file=f) print( ":: dials.integrate %exclude_images% refined.pickle refined.json", file=f)