def fix(self, mode=None, microscope=None, out=None, pad=0, start=1): """ Fixes wrong data in headers. Mode determines which values are fixed. Currently defined modes are: - 'polara_fei-tomo': images obtained on Polara (at MPI of Biochemistry) using FEI tomography package and saved in EM format. - 'krios_fei-tomo': images obtained on Krios (at MPI of Biochemistry) using FEI tomography package and saved in EM format. - 'cm300': images from cm300 in EM format - None: doesn't do anyhing If mode is 'polara_fei-tomo', then arg microscope has to be specified. The allowed values are specified in microscope_db.py. Currently (r564) these are: 'polara-1_01-07', 'polara-1_01-09' and 'polara-2_01-09'. Works for individual images only (not for stacks), because stacks are typically recorded by SerialEM and do not need fixing. Arguments: - out: directory where the fixed images are written. The fixed and the original images have the same base names. - mode: fix mode """ # parse arguments #if path is None: path = self.path #if mode is None: mode = self.mode # check for out, pad and start also? # make out directory if it doesn't exists if (out is not None) and (not os.path.isdir(out)): os.makedirs(out) # loop over images images_iter = self.images(out=out, pad=pad, start=start) for (in_path, out_path) in images_iter: # read image file image = ImageIO(file=in_path) image.read() # fix image.fix(mode=mode, microscope=microscope) # write fixed files image.write(file=out_path)
def sort(self, seq=None, out=None, pad=0, start=1, fix_mode=None, microscope=None, limit=None, limit_mode='std', size=5, byte_order=None, test=False): """ Sorts series, fixes image headers, corrects the data and writes the sorted and corrected images. A series is sorted by tilt angle that is read from each image, or by the elements of seq (not necessarily angles) if given. Sorted images names have the form: directory/name + number + extension. where out is: directory/name_.extension and numbers start with start argument and are padded with pad (argument) number of zeros (see self.images). Argument fix_mode detemines how the headers are fixed: - None: no fixing - 'polara_fei-tomo': for series obtained on polara with the FEI tomo software - 'krios_fei-tomo': for series obtained on krios with the FEI tomo software - 'cm300': for series from CM300 (see pyto.io.image_io). If fix_mode is 'polara_fei-tomo', then arg microscope has to be specified. The allowed values are specified in microscope_db.py. Currently (r564) these are: 'polara-1_01-07', 'polara-1_01-09' and 'polara-2_01-09'. If fix_mode is None, microscope does nor need to be specified. Series recorded by SerialEM typically do not need fixing. Works for individual images only (not for stacks). Arguments: - seq: if specified this sequence used for sorting projection, otherwise tilt angles are used - out: sorted series path - pad: number of digits of a projection number in the sorted series file name - start: start number for sorted series file names - fix_mode: determined if and how headers are fixed - microscope: microscope type, see pyto.io.microscope_db - limit_mode: 'abs' or 'std' - limit: absolute greyscale limit if limit_mode is 'abs', or the number of stds above and below the mean - size: size of the subarray used to find the replacement value for a voxel that's out of the limits - byte_order: '<' or '>', default is the byte order of the machine - test: if True all steps are done except writing corrected images """ # shortcuts path = self.path match_mode = self.mode # make tilt angles - file names dictionary # ToDo: use self.sortPath() instead in_paths = [] images_iter = self.images(mode=match_mode) if seq is None: seq = [] # get tilt angles from file headers for in_path in images_iter: image = ImageIO(file=in_path) image.readHeader() seq.append(image.tiltAngle) in_paths.append(in_path) image.file_.close() else: # use seq to sort for in_path in images_iter: in_paths.append(in_path) # sort (note: dictionary angle:in_path fails for multiple files with # same angles) seq_arr = numpy.array(seq) in_paths_arr = numpy.array(in_paths) sort_ind = seq_arr.argsort() sorted_seq = seq_arr[sort_ind] sorted_in_paths = in_paths_arr[sort_ind] # parse out and make out directory if it doesn't exists if out is not None: out_dir, out_base_pat = os.path.split(out) if out_dir == '': out_dir = '.' if (not test) and (not os.path.isdir(out_dir)): os.makedirs(out_dir) else: out_path = None # initialize file counter if start is None: ind = None else: ind = start - 1 # loop over sorted in files for (item, in_path) in zip(sorted_seq, sorted_in_paths): if ind is not None: ind += 1 # parse in file path in_dir, in_base = os.path.split(in_path) if out is not None: # make out file path out_base = self.convertBase(in_base=in_base, out_base=out_base_pat, pad=pad, index=ind) out_path = os.path.join(out_dir, out_base) # read files im_io = ImageIO(file=in_path) im_io.read() # log logging.info("%5.1f: %s -> %s %6.1f %6.1f" \ % (item, in_path, out_path, \ im_io.data.mean(), im_io.data.std())) # fix if fix_mode is not None: im_io.fix(mode=fix_mode, microscope=microscope) # limit if limit is not None: image = Image(im_io.data) image.limit(limit=limit, mode=limit_mode, size=size) # write fixed file if not test: if byte_order is None: byte_order = im_io.machineByteOrder im_io.write(file=out_path, byteOrder=byte_order, data=image.data) else: logging.info(" " + str(item) + ": " + in_path + " -> "\ + str(out_path))