def saveImage(self): """Dump the current frame to a file""" outfile = datetime.datetime.now().strftime( "%Y%m%d-%H%M%S.%f") + ".tiff" if self.app: module_io = self.app.get_module("io") drc = module_io.get_experiment_directory() drc.mkdir(exist_ok=True, parents=True) outfile = drc / outfile try: flatfield, h = read_tiff(module_io.get_flatfield()) frame = apply_flatfield_correction(self.frame, flatfield) except: frame = self.frame h = {} else: frame = self.frame h = {} write_tiff(outfile, frame, header=h) print(" >> Wrote file:", outfile)
def main_entry(sigma=None): if len(sys.argv) != 2: print("Program to find microscope stretch amplitude/azimuth from a powder pattern") print() print("Usage: python find_stretch_correction.py powder_pattern.tiff") exit() fname = sys.argv[1] img, h = read_tiff(fname) if max(img.shape) > 1024: img, scale = autoscale(img, 1024) print(f"Downsampling to {img.shape}") if not sigma: sigma = get_sigma_interactive(img) # edge detection edges = canny(img, sigma=sigma, low_threshold=None, high_threshold=None) # get regionprops props = get_ring_props(edges) # parse results plot_props(edges, props)
def from_montage_yaml(cls, filename: str = 'montage.yaml'): """Load montage from a series of tiff files + `montage.yaml`""" import yaml from instamatic.formats import read_tiff p = Path(filename) drc = p.parent d = yaml.safe_load(open(p, 'r')) fns = (drc / fn for fn in d['filenames']) d['stagecoords'] = np.array(d['stagecoords']) d['stagematrix'] = np.array(d['stagematrix']) images = [read_tiff(fn)[0] for fn in fns] gridspec = { k: v for k, v in d.items() if k in ('gridshape', 'direction', 'zigzag', 'flip') } m = cls(images=images, gridspec=gridspec, **d) m.update_gridspec( flip=not d['flip']) # BUG: Work-around for gridspec madness # Possibly related is that images are rotated 90 deg. in SerialEM mrc files return m
def tiff2png(interval=10, drc="movie"): fns1 = glob.glob("tiff\*.tif?") fns2 = glob.glob("tiff_image\*.tif?") if not os.path.exists(drc): os.mkdir(drc) j = 0 for i, fn1 in enumerate(fns1): if i % (interval - 1) == 0: try: fn2 = fns2[j] except IndexError: break im2, h2 = read_tiff(fn2) im2 = im2[150:320, 150:320] j += 1 im1, h1 = read_tiff(fn1) fig, (ax1, ax2) = plt.subplots(1,2) ax1.imshow(im1, vmax=np.percentile(im1, 99.0), cmap="gray") ax2.imshow(im2, vmax=np.percentile(im1, 99.5), cmap="gray") ax1.axis("off") ax2.axis("off") plt.tight_layout() plt.savefig(f"{drc}/{i:05d}.png", bbox_inches='tight', pad_inches=0, dpi=200) plt.close() print(fn1, fn2) return drc
def update_ax3(self, ind: int = 0): ind = self.mmm_ind label = self.marker_labels[ind] data_fn = self.data_fmt.format(label=label) if os.path.exists(data_fn): img = read_tiff(data_fn)[0] self.im3.set_data(img) self.ax3.set_title(label) else: self.im3.set_data(self.blank) self.ax3.set_title(f'{label}\nFile not available!')
def save_image(controller, **kwargs): frame = kwargs.get('frame') module_io = controller.app.get_module('io') drc = module_io.get_experiment_directory() drc.mkdir(exist_ok=True, parents=True) timestamp = datetime.now().strftime( '%H-%M-%S.%f')[:-3] # cut last 3 digits for ms resolution outfile = drc / f'frame_{timestamp}.tiff' try: flatfield, h = read_tiff(module_io.get_flatfield()) frame = apply_flatfield_correction(frame, flatfield) except BaseException: frame = frame h = {} write_tiff(outfile, frame, header=h) print('Wrote file:', outfile)
def reprocess(credlog, tiff_path=None, mrc_path=None, smv_path="SMV_reprocessed"): credlog = Path(credlog) drc = credlog.parent image_fns = list(drc.glob("tiff/*.tiff")) n = len(image_fns) if n == 0: print(f"No files found matching `tiff/*.tiff`") exit() else: print(n) buffer = [] rotation_axis = -2.24 # add np.pi/2 for old files acquisition_time = None # osc_angle = 0.53 with open(credlog, "r") as f: for line in f: if line.startswith("Camera length"): camera_length = float(line.split()[2]) if line.startswith("Oscillation angle"): osc_angle = float(line.split()[2]) if line.startswith("Starting angle"): start_angle = float(line.split()[2]) if line.startswith("Ending angle"): end_angle = float(line.split()[2]) if line.startswith("Rotation axis"): rotation_axis = float(line.split()[2]) if line.startswith("Acquisition time"): acquisition_time = float(line.split()[2]) if line.startswith("Exposure Time"): exposure_time = float(line.split()[2]) if line.startswith("Pixelsize"): pixelsize = float(line.split()[1]) if line.startswith("Physical pixelsize"): physical_pixelsize = float(line.split()[2]) if line.startswith("Wavelength"): wavelength = float(line.split()[1]) if line.startswith("Stretch amplitude"): stretch_azimuth = float(line.split()[2]) if line.startswith("Stretch azimuth"): stretch_amplitude = float(line.split()[2]) if not acquisition_time: acquisition_time = exposure_time + 0.015 print("camera_length:", camera_length) print("Oscillation angle:", osc_angle) print("Starting angle:", start_angle) print("Ending angle:", end_angle) print("Rotation axis:", rotation_axis) print("Acquisition time:", acquisition_time) def extract_image_number(s): p = Path(s) return int(p.stem.split("_")[-1]) for i, fn in enumerate(image_fns): j = extract_image_number(fn) img, h = read_tiff(fn) buffer.append((j, img, h)) img_conv = ImgConversion(buffer=buffer, osc_angle=self.osc_angle, start_angle=self.start_angle, end_angle=self.end_angle, rotation_axis=self.rotation_axis, acquisition_time=self.acquisition_time, flatfield=None, pixelsize=self.pixelsize, physical_pixelsize=self.physical_pixelsize, wavelength=self.wavelength, stretch_amplitude=self.stretch_amplitude, stretch_azimuth=self.stretch_azimuth ) # azimuth, amplitude = 83.37, 2.43 # add 90 to azimuth for old files # img_conv.stretch_azimuth, img_conv.stretch_amplitude = azimuth, amplitude print("Stretch amplitude", img_conv.stretch_amplitude) print("Stretch azimuth", img_conv.stretch_azimuth) # if img_conv.beam_center_std.mean() > 5: # print("Large beam center variation detected, aligning images!") # center_images(img_conv) if mrc_path: mrc_path = drc / mrc_path if smv_path: smv_path = drc / smv_path if tiff_path: smv_path = drc / tiff_path img_conv.threadpoolwriter(tiff_path=tiff_path, mrc_path=mrc_path, smv_path=smv_path, workers=8) if mrc_path: img_conv.write_ed3d(mrc_path) if smv_path: img_conv.write_xds_inp(smv_path)
def __init__( self, buffer: list, # image buffer, list of (index [int], image data [2D numpy array], header [dict]) camera_length: float, # virtual camera length read from the microscope osc_angle: float, # degrees, oscillation angle of the rotation start_angle: float, # degrees, start angle of the rotation end_angle: float, # degrees, end angle of the rotation rotation_axis: float, # radians, specifies the position of the rotation axis acquisition_time: float, # seconds, acquisition time (exposure time + overhead) flatfield: str = 'flatfield.tiff'): if flatfield is not None: flatfield, h = read_tiff(flatfield) self.flatfield = flatfield self.headers = {} self.data = {} self.smv_subdrc = "data" while len(buffer) != 0: i, img, h = buffer.pop(0) self.headers[i] = h if self.flatfield is not None: self.data[i] = apply_flatfield_correction(img, self.flatfield) else: self.data[i] = img self.untrusted_areas = [] self.observed_range = set(self.data.keys()) self.complete_range = set( range(min(self.observed_range), max(self.observed_range) + 1)) self.missing_range = self.observed_range ^ self.complete_range self.data_shape = img.shape try: self.pixelsize = config.calibration.pixelsize_diff[ camera_length] # px / Angstrom except KeyError: self.pixelsize = 1 print( f"No calibrated pixelsize for camera length={camera_length}. Setting pixelsize to 1." ) logger.warning( f"No calibrated pixelsize for camera length={camera_length}. Setting pixelsize to 1." ) self.physical_pixelsize = config.camera.physical_pixelsize # mm self.wavelength = config.microscope.wavelength # angstrom # NOTE: Stretch correction - not sure if the azimuth and amplitude are correct anymore. self.do_stretch_correction = True self.stretch_azimuth = config.camera.stretch_azimuth self.stretch_amplitude = config.camera.stretch_amplitude self.distance = (1 / self.wavelength) * (self.physical_pixelsize / self.pixelsize) self.osc_angle = osc_angle self.start_angle = start_angle self.end_angle = end_angle self.rotation_axis = rotation_axis self.acquisition_time = acquisition_time #self.rotation_speed = get_calibrated_rotation_speed(osc_angle / self.acquisition_time) self.name = "Instamatic" from .XDS_template import XDS_template # hook XDS_template here, because it is difficult to override as a global self.XDS_template = XDS_template self.check_settings( ) # check if all required parameters are present, and fill default values if needed self.mean_beam_center, self.beam_center_std = self.get_beam_centers() logger.debug(f"Primary beam at: {self.mean_beam_center}")
ax3.scatter(cy, cx, marker="+") bx, by = np.vstack((rect, rect[0])).T ax3.plot(by, bx, "r-o") fn = Path(drc) / "beamstop.png" plt.savefig(fn, dpi=150, bbox_inches='tight', pad_inches=0.1) return rect if __name__ == '__main__': drc = "." fns = list(Path(drc).glob("raw/*.tif")) print(len(fns)) imgs, hs = zip(*(read_tiff(fn) for fn in fns)) stack_mean = np.mean(imgs, axis=0) center = find_beam_center_with_beamstop(stack_mean, z=99) beamstop_rect = find_beamstop_rect(stack_mean, center, pad=1, plot=True) from instamatic.tools import to_xds_untrusted_area xds_quad = to_xds_untrusted_area("quadrilateral", beamstop_rect) print(xds_quad)
def calibrate_stage_from_file(drc: str, plot: bool = False): """Calibrate the stage from the saved log/tiff files. This is essentially the same function as below, with the exception that it reads the `log.yaml` to recalculate the stage matrix. Parameters ---------- drc : str Directory containing the `log.yaml` and tiff files. plot : bool Plot the results of the fitting. Returns ------- stagematrix: np.ndarray (2x2) Stage matrix used to transform the camera coordinates to stage coordinates """ drc = Path(drc) fn = drc / 'log.yaml' d = yaml.full_load(open(fn, 'r')) binning = d['binning'] args = d['args'] stage_shifts = [] # um pairs = [] for i, (n_steps, step) in enumerate(args): dx, dy = step for j in range(0, n_steps): img, _ = read_tiff(drc / f'{i}_{j}.tiff') if j > 0: pairs.append((last_img, img)) stage_shifts.append((dx, dy)) last_img = img translations = cross_correlate_image_pairs(pairs) # Filter outliers sel = get_outlier_filter(translations) stage_shifts = np.array(stage_shifts)[sel] translations = np.array(translations)[sel] # Fit stagematrix fit_result = fit_affine_transformation(translations, stage_shifts, verbose=True) r = fit_result.r t = fit_result.t if plot: r_i = np.linalg.inv(r) translations_ = np.dot(stage_shifts, r_i) plt.scatter(*translations.T, marker='<', label='Pixel translations (CC)') plt.scatter(*translations_.T, marker='>', label='Calculated pixel coordinates') plt.legend() plt.show() stagematrix = r / binning return stagematrix