def get_raw_data(self, index): # Use mrcfile to open the dataset and extract slice index from the stack. # Note MRC files use z, y, x ordering with mrcfile.mmap(self._image_file) as mrc: raw_data = mrc.data[index, ...] return flex.double(raw_data.astype("double")) + self.pedestal
def __init__(self, Data, filename, stats=None): self._data_obj = Data self.filename = filename super(MRC, self).__init__() self.file = mrcfile.mmap(filename, 'r') self.dtype = self.file.data.dtype
def _start(self): """Open the MRC file, read the metadata into an internal dictionary self._header_dictionary, add FEI extended metadata if available""" with mrcfile.mmap(self._image_file) as mrc: h = mrc.header #xh = mrc.extended_header self._header_dictionary = self._unpack_header(h) if h['exttyp'].tobytes() == b'FEI1': try: xh = self._read_ext_header(self._image_file) self._header_dictionary.update(xh) except KeyError: pass # Add a positive pedestal level to images to avoid negative # pixel values if a value is set by the environment variable # ADD_PEDESTAL. This is a nasty workaround! Suitable values might be # +128 for Ceta and +8 for Falcon III (https://doi.org/10.1101/615484) self.pedestal = float(os.environ.get("ADD_PEDESTAL", 0)) # Set all negative pixel values to zero (after applying the pedestal). # Another nasty hack, while we explore what is the best practice for # images that have negative-valued pixels self.truncate = "TRUNCATE_PIXELS" in os.environ
def scale(origin_path, new_path, scale_rate=1): origin_mrc = mrcfile.mmap(origin_path, 'r') origin_shape = np.array(origin_mrc.data.shape) ox, oy, oz = origin_shape scale = SCALE_BASE**scale_rate new_shape = (origin_shape + scale - 1) // scale nx, ny, nz = new_shape new_mrc = mrcfile.new_mmap(new_path, (nz, nx, ny), mrc_mode=mrcfile.utils.mode_from_dtype( mrcfile.utils.data_dtype_from_header( origin_mrc.header)), overwrite=True) print('scaling data') for z in tqdm(range(nz)): sz = z * scale for x in range(nx): sx = x * scale for y in range(ny): sy = y * scale new_mrc.data[z, x, y] = np.mean( origin_mrc.data[sz:min(sz + scale, oz), sx:min(sx + scale, ox), sy:min(sy + scale, oy)]) print('updating header') new_mrc.update_header_stats() print('header updated') origin_mrc.close() new_mrc.close()
def get_raw_data(self, index): # Note MRC files use z, y, x ordering with mrcfile.mmap(self._image_file) as mrc: image = flex.double(mrc.data[index, ...].astype("double")) return image
def _init_data(self, nx, ny=None, nz=None): ''' Init data with zeros. All arguments are truncated to int silently. Args: nx: A `int`. The x dimension of the image ny: A `int`. The y dimension of the image. default is 1 nz: A `int`. The z dimension of the image. Default is 1 ''' nx = int(nx) if nx <= 0: raise ValueError("Wrong value for x dimension") dims = [nx] if ny is not None: ny = int(ny) if ny <= 0: raise ValueError("Wrong value for y dimension") dims = [ny] + dims if nz is not None: nz = int(nz) if nz <= 0: raise ValueError("Wrong value for z dimension") dims = [nz] + dims if not self._mmap: self.data = np.zeros(dims, self.dtype) else: mrc = mrcfile.mmap(self._mmap_file, mode=self._mmap_mode) mrc._open_memmap(np.float32, tuple(dims)) mrc.update_header_from_data() self.data = mrc.data
def from_mrcfile(Class, filename): """ Read the simulated data from a mrc file Args: filename (str): The input filename """ # Read the data handle = mrcfile.mmap(filename, "r") # Check the header info if handle.header.exttyp == b"FEI1": assert handle.extended_header.dtype == FEI_EXTENDED_HEADER_DTYPE assert len(handle.extended_header.shape) == 1 assert handle.extended_header.shape[0] == handle.data.shape[0] # Read the angles angle = np.zeros(handle.data.shape[0], dtype=np.float32) for i in range(handle.extended_header.shape[0]): angle[i] = handle.extended_header[i]["Alpha tilt"] position = np.zeros(shape=(handle.data.shape[0], 3), dtype=np.float32) drift = np.zeros(shape=(handle.data.shape[0], 2), dtype=np.float32) defocus = np.zeros(shape=(handle.data.shape[0]), dtype=np.float32) for i in range(handle.extended_header.shape[0]): # Read the positions position[i, 0] = handle.extended_header[i]["Shift X"] position[i, 1] = handle.extended_header[i]["Shift Y"] position[i, 2] = handle.extended_header[i]["Z-Stage"] # Read the drift drift[i, 0] = handle.extended_header[i]["Shift offset X"] drift[i, 1] = handle.extended_header[i]["Shift offset Y"] # Read the defocus defocus[i] = handle.extended_header[i]["Defocus"] else: angle = np.zeros(handle.data.shape[0], dtype=np.float32) position = np.zeros(shape=(handle.data.shape[0], 3), dtype=np.float32) drift = np.zeros(shape=(handle.data.shape[0], 2), dtype=np.float32) defocus = np.zeros(handle.data.shape[0], dtype=np.float32) # Get the pixel size pixel_size = handle.voxel_size["x"] # Create the reader return Reader( handle, handle.data, angle, position, pixel_size, drift=drift, defocus=defocus, )
def volread(self, path): """Helper to return a file handle to an HDF5 file. Args: path (str): Path to the HDF5 file. Raises: Exception: If the file is not and HDF5 file. Returns: h5py.File: File handle to an HDF5 file. """ _, file_extension = os.path.splitext(path) data = None logger.info("Loading file handle") if file_extension in [".hdf5", ".h5"]: data = h5.File(path, "r") elif file_extension in [".tif", ".tiff"]: data = io.imread(path) elif file_extension in [".rec", ".mrc"]: mrc = mrcfile.mmap(path, mode="r+") data = mrc.data else: raise Exception("File format not supported") return data
def __init__(self, path, scale_rate=0): self.base_path = path self.scale_rate = scale_rate self.path = self.get_path(self.base_path, self.scale_rate) self.next = None self.mrc = mrcfile.mmap(self.path, 'r') self._check_scale()
def write(cls, filename, data, filepath=None, mrcfh=None, exheader=None): ''' Return writed mrc filehandle ------------------------------- This class method write will write an mrcfile by copy parameters from existing mrc or mannually input ''' print(mrcfh) if filepath == None: filepath = os.getcwd() if not (mrcfh or exheader): raise ValueError('Not enough parameters to \ write mrcfile') if exheader: pass else: _mrc = mrcfile.mmap(mrcfh) # header = _mrc.header exheader = _mrc.extended_header # volsize = _mrc.voxel_size _mrc.close() filehandle = os.path.join(filepath, filename) with mrcfile.new(filehandle) as mrc: mrc.set_data(data) # print(mrc._check_writeable()) # mrc._set_voxel_size(volsize) mrc.set_extended_header(exheader) return filehandle
def loader(imageblock): if mmap is True: mrc = mrcfile.mmap(image_path) else: mrc = mrcfile.open(image_path) imageblock.data = mrc.data pixel_size = structured_to_unstructured(mrc.voxel_size)[::-1] imageblock.pixel_size = pixel_size
def mrc_from_uri(uri, mode="a", shape=None, dtype="float32", fill=0): """ Loads a MRC dataset from an uri of the form: `[mrc://]file` Where `file` is the path to the `.mrc` or `.rec` file. Parameters ---------- uri: string A file URI for a dataset in MRC format. mode: one of ['a', 'r', 'r+', 'w'] The opening mode. See `open` for more details. shape: tuple Shape of the ND-Array. Only valid if `mode='a'`. dtype: numpy-accepted data type Data type of the ND-Array. Only valid if `mode='a'`. Default: float32. fill: int or float Value used to fill the array. Default: 0. """ match = re.match(MRC_REGEXP, uri) if match is None: raise ValueError("Invalid mrc:// uri: `{}`".format(uri)) fpath = match.group("fpath") if mode != "r": if mode in ["a", "r+"] and op.isfile(fpath): f = mrc.mmap(fpath, "r+") if not sameshape(f.data.shape, shape) or not samedtype(f.data.dtype, dtype): msg = ( "Dataset already exists with different" " shape or dype. Expected {} and {}, got {} and {}".format( shape, dtype, f.data.shape, f.data.dtype ) ) raise ValueError(msg) else: f = mrc.MrcMemmap(fpath, mode="w+", overwrite=True) f._open_memmap(dtype, shape) f.update_header_from_data() f.data[...] = fill else: f = mrc.mmap(fpath, "r") return DatasetWrapper(f, f.data)
def __init__(self, path, mode='r'): self.path = path self.mode = mode if mrcfile is None: raise AttributeError("mrcfile is not available") try: self._f = mrcfile.mmap(self.path, self.mode) except ValueError: self._f = mrcfile.open(self.path, self.mode)
def Input_read(dir, suffix): files = glob(dir + '/*.' + suffix) L = len(files) if L == 0: print('no file exists') return -1, -1, -1, -1, -1 else: print(str(len(files)) + ' files in ', dir) (x, y, z) = mrcfile.mmap(files[0]).data.shape raw_input = np.zeros(dtype=np.uint8, shape=[L, x, y, z, 1]) for filei in range(L): mrc = mrcfile.mmap(files[filei]) content = np.array(mrc.data) mrc = 0 rshape = np.array(content).reshape([1, x, y, z, 1]) # print(rshape) raw_input[filei, :] = rshape[:] return raw_input, L, files
def showCtfMicrographs(self, projectDirectory, ctfs): allMicrographs = [] for i in range(len(ctfs)): fileName = ctfs[i]['ctfImage'].replace(':mrc', '') try: mrc = mrcfile.mmap(projectDirectory + fileName) except (FileNotFoundError, ValueError) as err: self.errorText.value = "Unable to load Micrograph: {0}".format( err) self.errorText.layout = self.errorLayout else: #extract data, convert values to 0 - 255 int8 format formatted = (mrc.data[0] * 255 / np.max(mrc.data)).astype('uint8') img = Image.fromarray(formatted) img.thumbnail(self.thumbNailSize) imagePng = self.convertToPNG(img) mrc.close() #Dynamically build the Ctf mrcs and buttons. img = widgets.Image(value=imagePng, format='PNG', width=self.thumbNailSize[0], height=self.thumbNailSize[1]) dataButton = widgets.Button(description='Data', disabled=False, button_style='', tooltip='Show data', icon='check') mrcButton = widgets.Button(description='Raw mrc', disabled=False, button_style='', tooltip='Show micrograph', icon='check') buttonOutput = widgets.Output(layout={'border': '2px solid black'}) dataButton.add_traits(showData=traitlets.Any(buttonOutput)) mrcButton.add_traits(showMrc=traitlets.Any(buttonOutput)) #adding on_click actions to buttons dynamically, lambda is an anonymous function #lambda arguments: function dataButton.on_click(lambda dataButton, num=i: self.dynamicOnClick( ctfs[num], dataButton)) mrcButton.on_click(lambda mrcButton, num=i: self.dynamicOnClick( ctfs[num], mrcButton)) micrograph = VBox( [img, HBox([dataButton, mrcButton]), buttonOutput]) allMicrographs.append(micrograph) return allMicrographs
def crop_mrc(mrc_path, crop_path, x=0, y=0, z=0, dx=100, dy=100, dz=100, print_header_diff=False): """Crop specified part of a 3d mrc file, position cropped: mrc.data[x:x+dx, y:y+dy, z:z+dz]. Note that the axis order of mrc data is (x, y, z), different from that downstream tasks use, eg. read_mrc_data and imod: (z, y, x). Arguments: mrc_path -- source mrc file path crop_path -- destination path of cropped mrc file Keyword Arguments: x {int} -- lowerbound x coordinate to crop (default: {0}) y {int} -- lowerbound y coordinate to crop (default: {0}) z {int} -- lowerbound z coordinate to crop (default: {0}) dx {int} -- length of x to crop (default: {100}) dy {int} -- length of y to crop (default: {100}) dz {int} -- length of z to crop (default: {100}) print_header_diff {bool} -- whether to print difference between the cropped and original (default: {False}) """ # Use mmap for faster reading large mrcfile with mrcfile.mmap(mrc_path, mode='r') as mrc, mrcfile.new(crop_path) as mrc_crop: mrc_crop.set_data( mrc.data[x:x + dx, y:y + dy, z:z + dz]) # set_data automatically syncs header info with data mrc_crop.voxel_size = mrc.voxel_size mrcfile.validate(crop_path) # Print header diff if print_header_diff: mrc_header = io_file.read_mrc_header(mrc_path) crop_header = io_file.read_mrc_header(crop_path) diffs = [] for (k1, v1), (k2, v2) in zip(mrc_header.items(), crop_header.items()): if k1 == k2 and v1 != v2: if isinstance(v1, dict): assert len(v1) == len( v2), "Different dict size: {}, {}".format( len(v1), len(v2)) diff_dict = { k: (v1[k], v2[k]) for k in v1 if k in v2 and v1[k] != v2[k] } print("diff key: ", k1, "\ndiff_dict:\n", diff_dict) else: print("diff key: ", k1, "\n", v1, "\n", v2, "\n") diffs.append((v1, v2)) print("# diffs: ", len(diffs))
def run(body): # body is reference to the main Import class files_map = [] for f in body.files_all: fl = f.lower(); if fl.endswith(('.map', '.mrc')): files_map.append ( f ) if len(files_map) <= 0: return body.file_stdout.write ( "\n" + "%"*80 + "\n" ) body.file_stdout.write ( "%%%%% Map volume data\n" ) body.file_stdout.write ( "%"*80 + "\n" ) mapSecId = "map_sec_" + str(body.widget_no) body.widget_no += 1 pyrvapi.rvapi_add_section ( mapSecId, "Map", body.report_page_id(), body.rvrow, 0, 1, 1, False ) k = 0 for f in files_map: body.files_all.remove ( f ) pyrvapi.rvapi_put_table_string ( body.import_summary_id(), f, body.summary_row, 0 ) fpath = os.path.join ( body.importDir(), f ); with mrcfile.mmap(fpath) as mrc: msg = "MAP {0} x {1} x {2}".format(mrc.header.nx, mrc.header.ny, mrc.header.nz) pyrvapi.rvapi_put_table_string ( body.import_summary_id(), msg, body.summary_row, 1 ) map_ = dtype_map.DType ( body.job_id ) map_.subtype = ['final_map'] map_.setFile ( f ) body.dataSerialNo += 1 map_.makeDName ( body.dataSerialNo ) body.outputDataBox.add_data ( map_ ) # Essential to rename uploaded file to put it in output directory # Might be better to use the standard register() method instead if possible? # Currently the file ends up remaining in the upload directory on the front end, # even though it's removed on the number cruncher... os.rename ( fpath, os.path.join(body.outputDir(), f) ) body.file_stdout.write ( "... processed: " + f + "\n" ) k += 1 body.rvrow += 1 pyrvapi.rvapi_flush() return
def get_raw_data(self): # Use mrcfile to open the dataset and the image. # Note MRC files use z, y, x ordering with mrcfile.mmap(self._image_file) as mrc: image = flex.double(mrc.data.astype("double")) image += self.pedestal if self.truncate: image.set_selected((image < 0), 0) return image
def dynamicOnClick(self, ctfData, button): if hasattr(button, 'showData'): button.showData.clear_output() with button.showData: print('Defocus U: ' + str(ctfData['defocusU']) + '\n' + \ 'Defocus V: ' + str(ctfData['defocusV']) + '\n' + \ 'Defocus Angle: ' + str(ctfData['defocusAngle']) + '\n' + \ 'Voltage: ' + str(ctfData['voltage']) + '\n' + \ 'Spherical Aberration: ' + str(ctfData['sphericalAberration']) + '\n' + \ 'Amplitude Contrast: ' + str(ctfData['ampContrast']) + '\n' + \ 'Magnification: ' + str(ctfData['magnification']) + '\n' + \ 'Detector Pixel Size: ' + str(ctfData['detectorPixelSize']) + '\n' + \ 'Figure of Merit: ' + str(ctfData['figOfMerit']) + '\n' + \ 'Ctf Max Resolution: ' + str(ctfData['maxResolution'])) if hasattr(button, 'showMrc'): button.showMrc.clear_output() with button.showMrc: fileName = ctfData['micrographNameNoDW'] #Problem, MotionCorr2 created mrcs have an issue with the MAP ID string in the header, it should be 'MAP ' but MotionCorr ones have 'MAP'. #Opening in permissive mode and catching the warning, we can get around this. try: with warnings.catch_warnings(record=True) as w: mrc = mrcfile.mmap(self.projectDirectory.value + fileName, permissive=True) except FileNotFoundError as err: self.errorText.value = "Unable to load Micrograph: {0}".format( err) self.errorText.layout = self.errorLayout else: mrcArray = np.array(mrc.data) #extract data, convert values to 0 - 255 int8 format formatted = (mrcArray * 255 / np.max(mrcArray)).astype('uint8') img = Image.fromarray(formatted) img.thumbnail(self.rawThumbNailSize) #increase contast to aid visibility enhancer = ImageEnhance.Contrast(img) img = enhancer.enhance(6) imagePng = self.convertToPNG(img) mrc.close() img = widgets.Image(value=imagePng, format='PNG', width=self.rawThumbNailSize[0], height=self.rawThumbNailSize[1]) display(img)
def read(filename, mode="r"): """ Read the input map file Args: filename (str): The map filename Return object: The map file """ logger.info("Reading %s" % filename) return mrcfile.mmap(filename, mode=mode)
def __init__(self, filehandle, validate=False): ''' This initialize function only open .mrc file with mmap read-only ''' super(Mrc, self).__init__() self.filehandle = filehandle self.mrc = mrcfile.mmap(filehandle, mode='r') if validate: print('*' * 20 + 'Validating start' + '*' * 20) if not mrcfile.validate(filehandle): raise ValueError('Initial Mrc File is not validated') print('*' * 20 + 'Validating finished' + '*' * 20) '''
def reader_function(path): """Take a path or list of paths and return a list of LayerData tuples. Readers are expected to return data as a list of tuples, where each tuple is (data, [add_kwargs, [layer_type]]), "add_kwargs" and "layer_type" are both optional. Parameters ---------- path : str or list of str Path to file, or list of paths. Returns ------- layer_data : list of tuples A list of LayerData tuples where each tuple in the list contains (data, metadata, layer_type), where data is a numpy array, metadata is a dict of keyword arguments for the corresponding viewer.add_* method in napari, and layer_type is a lower-case string naming the type of layer. Both "meta", and "layer_type" are optional. napari will default to layer_type=="image" if not provided """ # handle both a string and a list of strings paths = [path] if isinstance(path, str) else path # optional kwargs for the corresponding viewer.add_* method # https://napari.org/docs/api/napari.components.html#module-napari.components.add_layers_mixin add_kwargs = {} # optional, default is "image" layer_type = "image" # load all files into array layer_data = [] for _path in paths: # Read mrcfile as a memory mapped file data = mrcfile.mmap(_path, permissive=True).data # Append two layers if the data type is complex if data.dtype in [np.complex64, np.complex128]: layer_data.append((np.abs(data), { "name": "amplitude" }, layer_type)) layer_data.append((np.angle(data), {"name": "phase"}, layer_type)) else: layer_data.append((data, add_kwargs, layer_type)) return layer_data
def load_image(self, drc: str=None) -> "np.array": """Loads the image corresponding to this item""" import mrcfile if not drc: drc = "." drc = Path(drc) map_file = Path(self.MapFile) if not map_file.exists(): map_file = drc / Path(self.MapFile).name m = mrcfile.mmap(map_file) s = self.MapSection return np.array(m.data[s])
def read_ptcl_mrc(ptcl_star, transform=False, fft_mask=None, clipbox=None, background_mask=None, recenter=False): ''' Particle mrc data ''' # Read particle data particle_image_num, particle_image_name = ptcl_star['rlnImageName'].split( '@') with mrcfile.mmap(particle_image_name, mode='r') as mrc_data: if len(mrc_data.data.shape) == 3: img2D = mrc_data.data[int(particle_image_num) - 1] else: img2D = mrc_data.data # If transform is ON, transform the ptcl image and rest the offset distance and angles if transform: img2D = transform_ptcl_img2D(img2D, ptcl_star) # Check pass filter options if fft_mask is not None: img2D = fft_filter(img2D, fft_mask) # Get img center img_origin = [0, 0] # If recenter option is on if recenter: fracX, intX = math.modf(ptcl_star['rlnOriginX']) fracY, intY = math.modf(ptcl_star['rlnOriginY']) img_origin = [intX, intY] # Check for clip img2D = clip_img2D(img2D, clipbox, origin=img_origin) # Normalize using the background mask if background_mask is not None: img2D = norm_intensity(img2D, background_mask, new_mean=0.0, new_std=1.0) return np.copy(img2D)
def __getitem__(self, idx): if self.data_type == 'even': idx = 2 * idx elif self.data_type == 'odd': idx = 2 * idx + 1 with torch.no_grad(): if self.dataset == 'Betagal': with mrcfile.open(self.ParticlePath + str(idx).zfill(6) + ".mrc") as m: image = np.array(m.data, dtype=np.float32) if self.args.GaussianFilterProjection: image = scipy.ndimage.gaussian_filter( image, self.args.GaussianSigma, ) image = Tensor(image).unsqueeze(0).cuda() elif self.dataset in ['Betagal-Synthetic']: with mrcfile.mmap(self.ImageStack[idx], permissive=True, mode='r+') as m: image = m.data if self.args.GaussianFilterProjection: image = scipy.ndimage.gaussian_filter( image, self.args.GaussianSigma) image = Tensor(image).unsqueeze(0).cuda() else: image = self.ImageStack[idx] image = Tensor(image).unsqueeze(0).cuda() downsampling = image.shape[-1] // self.args.RawProjectionSize if downsampling > 1: image = torch.nn.functional.avg_pool2d(image, kernel_size=downsampling, stride=downsampling, padding=0) if self.args.NormalizeProjections: image = (image - image.mean()) / image.std() return image
def read_mrc(image_path, name_regex=None, lazy=True, **kwargs): """ read an mrc file and return an ImageBlock """ name = guess_name(image_path, name_regex) with mrcfile.mmap(image_path) as mrc: if lazy: data = da.from_array(mrc.data) else: data = np.asarray(mrc.data) pixel_size = structured_to_unstructured(mrc.voxel_size)[::-1] ib = ImageBlock(data=data, pixel_size=pixel_size, name=name) logger.debug(f'succesfully read "{image_path}", {lazy=}') return ib
def load_image(self, drc: str = None) -> 'np.array': """Loads the image corresponding to this item.""" import mrcfile if not drc: drc = self.data_drc drc = Path(drc) map_file = Path(self.MapFile) if not map_file.exists(): map_file = drc / Path(self.MapFile).name m = mrcfile.mmap(map_file) s = self.MapSection if m.is_single_image() and s == 0: return np.array(m.data) else: return np.array(m.data[s])
def read_mrc(self, filename): ''' Read mrc file through ''' # permissive is to go throught invalid mrc file like generated by # motioncor2.... MotionCor2 does not write "MAP" into header... with warnings.catch_warnings(): warnings.simplefilter("ignore") mrc = mrcfile.mmap(filename, self._mmap_mode, permissive=True) if self._mmap: # logger.debug("Using mmaped file: %s" % filename) self._mmap_file = filename self.data = np.memmap(self._mmap_file, dtype=mrc.data.dtype, mode=self._mmap_mode, offset=mrc.data.offset, shape=mrc.data.shape) else: self.data = mrc.data.copy() return self
def mrc_central_slice(filename): # MrcMemmap reads dtype and shape from header # https://github.com/ccpem/mrcfile/blob/master/mrcfile/mrcmemmap.py#L92 f = mrcfile.mmap(filename, permissive=True) # mrcfile can be 2D, should check for that ndim = len(f.data.shape) if ndim == 2: data = f.data elif ndim == 3: central_slice = f.data.shape[0] // 2 data = f.data[central_slice] else: f.close() sys.exit(-1) f.close() return data
def __init__(self, path_to_mrc, tile_size, tile_stride, shuffled=False, verbose=False): self.path_to_mrc = path_to_mrc self.mmap = mrcfile.mmap(path_to_mrc) if verbose: print(path_to_mrc) self._depleted = False length, width, height = self.mmap.data.shape self.cols = (width // tile_stride) self.rows = (height // tile_stride) self.tile_size = tile_size self.tile_stride = tile_stride self._i = 0 self.shuffled = shuffled if self.shuffled: self.I = list(range(len(self))) shuffle(self.I) self.verbose = verbose