def mapfile_cc(input_map_filename1, input_map_filename2=None, output_map_filename=None): """ Compute the CC between two maps Args: input_map_filename1 (str): The input map filename input_map_filename2 (str): The input map filename output_map_filename (str): The output cc filename """ # Open the input file infile1 = read(input_map_filename1) # Get the data data1 = infile1.data if input_map_filename2 is not None: infile2 = read(input_map_filename2) data2 = infile2.data data2 = reorder(data2, read_axis_order(infile2), read_axis_order(infile1)) else: data2 = None # Compute the cc cc = array_cc(data1, data2) # Write the output file write(output_map_filename, cc.astype("float32"), infile=infile1)
def edit(input_map_filename, voxel_size=None, origin=None): """ Crop the map Args: input_filename (str): The input map filename voxel_size (list): The voxel size origin (list): The origin """ # Open the input file infile = read(input_map_filename, mode="r+") # Set the voxel size if voxel_size is not None: if len(voxel_size) == 1: voxel_size = voxel_size[0] infile.voxel_size = voxel_size # Set the origin if origin is not None: infile.header.origin["z"] = origin[0] infile.header.origin["y"] = origin[1] infile.header.origin["x"] = origin[2]
def mapfile_threshold(input_filename, output_filename, threshold=0, normalize=False, zero=True): """ Threshold the map Args: input_filename (str): The input map filename output_filename (str): The output map filename threshold (float): The threshold value normalize (bool): Normalize the map before thresholding zero (bool): Shift the data to zero """ # Open the input file infile = read(input_filename) # Get data data = infile.data.copy() # Apply the threshold data = array_threshold(data, threshold=threshold, normalize=normalize, zero=zero) # Write the output file write(output_filename, data, infile=infile)
def mapfile_segment( input_map_filename, output_map_filename=None, output_mask_filename=None, num_objects=1, ): """ Segment the map Args: input_map_filename (str): The input map filename output_map_filename (str): The output map filename output_mask_filename (str): The output mask filename num_objects (int): The number of objects """ # Open the input file infile = read(input_map_filename) # Get data data = infile.data # Segment the data mask = array_segment(data, num_objects=num_objects) # Write the output file if output_mask_filename is not None: write(output_mask_filename, mask, infile=infile) if output_map_filename is not None: write(output_map_filename, maptools.mask(data, mask), infile=infile)
def mapfile_rebin(input_map_filename, output_map_filename, shape=None): """ Rebin the map Args: input_map_filename (str): The input map filename output_map_filename (str): The output map filename shape (tuple): The new shape of the map """ # Open the input file infile = read(input_map_filename) # Get the data data = infile.data # Get the subset of data logger.info("Resampling map from shape %s to %s" % (data.shape, tuple(shape))) data = array_rebin(data, shape) # Write the output file outfile = write(output_map_filename, data, infile=infile) # Update the voxel size outfile.voxel_size = ( outfile.voxel_size["z"] * infile.data.shape[0] // shape[0], outfile.voxel_size["y"] * infile.data.shape[1] // shape[1], outfile.voxel_size["x"] * infile.data.shape[2] // shape[2], )
def mapfile_reorder(input_filename, output_filename, axis_order=None): """ Reorder the data axes Args: input_filename (str): The input map filename output_filename (str): The output map filename axis_order (list): The axis order """ # Open the input file infile = read(input_filename) # Get the axis order original_order = read_axis_order(infile) assert tuple(sorted(axis_order)) == (0, 1, 2) # Reorder the axes data = array_reorder(infile.data, original_order, axis_order) # Write the output file outfile = write(output_filename, data, infile=infile) write_axis_order(outfile, axis_order) outfile.update_header_stats()
def crop( input_filename, output_filename, roi=None, ): """ Crop the map Args: input_filename (str): The input map filename output_filename (str): The output map filename roi (list): The region of interest """ # Open the input file infile = read(input_filename) # Get the roi if roi is not None: z0, y0, x0, z1, y1, x1 = roi else: z0, y0, x0 = 0, 0, 0 z1, y1, x1 = infile.data.shape assert z1 > z0 assert y1 > y0 assert x1 > x0 # Get the subset of data logger.info("Cropping map with roi: %s" % list(roi)) data = infile.data[z0:z1, y0:y1, x0:x1] # Write the output file write(output_filename, data, infile=infile)
def mapfile_fsc3d( input_filename1, input_filename2, output_filename=None, kernel=9, resolution=None ): """ Compute the local FSC of the map Args: input_filename1 (str): The input map filename input_filename2 (str): The input map filename output_filename (str): The output map filename kernel (int): The kernel size resolution (float): The resolution limit """ # Open the input files infile1 = read(input_filename1) infile2 = read(input_filename2) # Get the data data1 = infile1.data data2 = infile2.data # Reorder input arrays data1 = reorder(data1, read_axis_order(infile1), (0, 1, 2)) data2 = reorder(data2, read_axis_order(infile2), (0, 1, 2)) # Compute the local FSC fsc = fsc3d( data1, data2, kernel=kernel, resolution=resolution, voxel_size=infile1.voxel_size, ) # Reorder output array fsc = reorder(fsc, (0, 1, 2), read_axis_order(infile1)) # Write the output file write(output_filename, fsc.astype("float32"), infile=infile1)
def mapfile_mask( input_filename, output_filename, mask_filename=None, fourier_space=False, shift=False, ): """ Mask the map Args: input_filename (str): The input map filename output_filename (str): The output map filename mask_filename (str): The mask filename space (str): Apply in real space or fourier space shift (bool): Shift the mask """ # Open the input file infile = read(input_filename) # Open the mask file maskfile = read(mask_filename) # Apply the mask data = infile.data mask = maskfile.data # Reorder the maskfile axes to match the data mask = reorder(mask, read_axis_order(maskfile), read_axis_order(infile)) # Apply the mask data = array_mask(data, mask, fourier_space=fourier_space, shift=shift) # Write the output file write(output_filename, data.astype("float32"), infile=infile)
def fft(input_map_filename, output_map_filename, mode=None, shift=True, normalize=True): """ Compute the FFT of the map Args: input_map_filename (str): The input map filename output_map_filename (str): The output map filename mode (str): The component to output shift (bool): Shift the fourier components normalize (bool): Normalize before computing FFT """ # Open the input file infile = read(input_map_filename) # Get the subset of data logger.info("Computing FFT (%s)" % mode) # The data data = infile.data # Normalize if necessary if normalize: data = (data - numpy.mean(data)) / numpy.std(data) # Compute FFT data = { "real": lambda x: numpy.real(x), "imaginary": lambda x: numpy.imag(x), "amplitude": lambda x: numpy.abs(x), "phase": lambda x: numpy.angle(x), "power": lambda x: numpy.abs(x)**2, }[mode](numpy.fft.fftn(data).astype("complex64")) # Shift if necessary if shift: data = numpy.fft.fftshift(data) # Write the output file write(output_map_filename, data, infile=infile)
def mapfile_filter( input_filename, output_filename, filter_type="lowpass", filter_shape="gaussian", resolution=None, ): """ Filter the map Args: input_filename (str): The input map filename output_filename (str): The output map filename filter_type (str): The filter type filter_shape (str): The filter shape resolution (list): The resolution """ # Check the input assert filter_type in ["lowpass", "highpass", "bandpass", "bandstop"] assert filter_shape in ["square", "gaussian"] # Open the input file infile = read(input_filename) # Get the voxel size voxel_size = ( infile.voxel_size["z"], infile.voxel_size["y"], infile.voxel_size["x"], ) # Filter the data data = array_filter( infile.data, filter_type=filter_type, filter_shape=filter_shape, resolution=resolution, voxel_size=voxel_size, ) # Write the output file write(output_filename, data, infile=infile)
def mapfile_transform( input_filename, output_filename, offset=None, rotation=(0, 0, 0), translation=(0, 0, 0), deg=False, ): """ Transform the map Args: input_filename (str): The input map filename output_filename (str): The output map filename offset = (array): The offset to rotate about rotation (array): The rotation vector translation (array): The translation vector deg (bool): Is the rotation in degrees """ # Open the input file infile = read(input_filename) # Get the axis order axis_order = read_axis_order(infile) # Get data data = infile.data # Do the transform data = array_transform( data, axis_order=axis_order, offset=offset, rotation=rotation, translation=translation, deg=deg, ) # Write the output file write(output_filename, data, infile=infile)
def mapfile_rescale( input_filename, output_filename, mean=None, sdev=None, vmin=None, vmax=None, scale=None, offset=None, ): """ Rescale the map Args: input_filename (str): The input map filename output_filename (str): The output map filename mean (float): The desired mean value sdev (float): The desired sdev value vmin (float): The desired min value vmax (float): The desired max value scale (float): The scale offset (float): The offset """ # Open the input file infile = read(input_filename) # Get the data data = infile.data # Rescale the map data = array_rescale(data, mean=mean, sdev=sdev, vmin=vmin, vmax=vmax, scale=scale, offset=offset) # Write the output file write(output_filename, data, infile=infile)
def edit( input_filename, voxel_size=None, ): """ Crop the map Args: input_filename (str): The input map filename voxel_size (list): The voxel size """ # Open the input file infile = read(input_filename, mode="r+") # Set the voxel size if voxel_size is not None: if len(voxel_size) == 1: voxel_size = voxel_size[0] infile.voxel_size = voxel_size
def mapfile_segment(input_filename, output_filename, num_objects=1): """ Segment the map Args: input_filename (str): The input map filename output_filename (str): The output map filename num_objects (int): The number of objects """ # Open the input file infile = read(input_filename) # Get data data = infile.data.copy() # Apply the segment data = array_segment(data, num_objects=num_objects) # Write the output file write(output_filename, data, infile=infile)
def rotate(input_filename, output_filename, axes=(0, 1), num=1): """ Rotate the map Args: input_filename (str): The input map filename output_filename (str): The output map filename axes (tuple): The axis to rotate around num (int): The number of times to rotate by 90 degrees """ # Open the input file infile = read(input_filename) # Get data data = infile.data.copy() # Apply the threshold logger.info("Rotating %d times around axes %s" % (num, axes)) data = numpy.rot90(data, k=num, axes=axes) # Write the output file write(output_filename, data, infile=infile)
def mapfile_dilate(input_map_filename, output_map_filename, kernel=3, num_iter=1): """ Dilate the map Args: input_map_filename (str): The input map filename output_map_filename (str): The output map filename kernel (tuple): The kernel size num_iter (int): The number of iterations """ # Open the input file infile = read(input_map_filename) # Get the subset of data logger.info("Dilating map") data = array_dilate(infile.data, kernel=kernel, num_iter=num_iter) # Write the output file write(output_map_filename, data.astype("uint8"), infile=infile)
def mapfile_fsc( input_filename1, input_filename2, output_filename=None, output_data_filename=None, nbins=20, resolution=None, axis=None, method="binned", ): """ Compute the local FSC of the map Args: input_filename1 (str): The input map filename input_filename2 (str): The input map filename output_filename (str): The output map filename nbins (int): The number of bins resolution (float): The resolution limit axis (tuple): The axis of the plane to compute the FSC method (str): Method to use (binned or averaged) """ # Check the axis if type(axis) in [int, float]: axis = (axis, ) # Open the input files infile1 = read(input_filename1) infile2 = read(input_filename2) # Get the data data1 = infile1.data data2 = infile2.data # Reorder data2 to match data1 data1 = reorder(data1, read_axis_order(infile1), (0, 1, 2)) data2 = reorder(data2, read_axis_order(infile2), (0, 1, 2)) # Compute the FSC bins, fsc = array_fsc( data1, data2, voxel_size=tuple(infile1.voxel_size[a] for a in ["z", "y", "x"]), nbins=nbins, resolution=resolution, axis=axis, method=method, ) # Compute the resolution bin_index, bin_value, fsc_value = resolution_from_fsc(bins, fsc) logger.info("Estimated resolution = %f A" % (1 / sqrt(bin_value))) # Write the FSC curve fig, ax = pylab.subplots(figsize=(8, 6)) ax.plot(bins, fsc) ax.set_xlabel("Resolution (A)") ax.set_ylabel("FSC") ax.set_ylim(0, 1) ax.axvline(bin_value, color="black") ax.xaxis.set_major_formatter( ticker.FuncFormatter(lambda x, p: "%.1f" % (1 / sqrt(x)) if x > 0 else None)) fig.savefig(output_filename, dpi=300, bbox_inches="tight") pylab.close(fig) # Write a data file if output_data_filename is not None: with open(output_data_filename, "w") as outfile: yaml.safe_dump( { "table": { "bin": list(map(float, bins)), "fsc": list(map(float, fsc)), }, "resolution": { "bin_index": int(bin_index), "bin_value": float(bin_value), "fsc_value": float(fsc_value), "estimate": float(1 / sqrt(bin_value)), }, }, outfile, )
def fit( input_map_filename, input_pdb_filename, output_pdb_filename=None, resolution=1, ncycle=10, mode="rigid_body", log_filename="fit.log", ): """ Compute the CC between two maps Args: input_map_filename (str): The input map filename input_pdb_filename (str): The input pdb filename output_filename (str): The output pdb filename resolution (float): The resolution ncycle (float): The number of cycles mode (str): The refinement mode log_filename (str): The log filename """ # Read the grid from the map input_map_file = read(input_map_filename) grid = input_map_file.data.shape # Get a working directory wd = tempfile.mkdtemp() # Open log with open(log_filename, "w") as stdout: # Call refmac to convert map to mtz maptools.external.map2mtz( mapin=os.path.abspath(input_map_filename), hklout="input.mtz", resolution=resolution, wd=wd, stdout=stdout, param_file="map2mtz.dat", command_file="map2mtz.sh", ) # Setup the pdb file maptools.external.pdbset( xyzin=os.path.abspath(input_pdb_filename), xyzout="pdbset.pdb", cell=tuple(grid), stdout=stdout, wd=wd, param_file="pdbset.dat", command_file="pdbset.sh", ) # Setup the pdb file maptools.external.refine( xyzin="pdbset.pdb", hklin="input.mtz", xyzout=os.path.abspath(output_pdb_filename), hklout="refined.mtz", mode=mode, ncycle=ncycle, resolution=resolution, stdout=stdout, wd=wd, param_file="refmac.dat", command_file="refmac.sh", )
def mapfile_fsc( input_map_filename1, input_map_filename2, output_plot_filename=None, output_data_filename=None, nbins=20, resolution=None, axis=None, method="binned", ): """ Compute the local FSC of the map Args: input_map_filename1 (str): The input map filename input_map_filename2 (str): The input map filename output_plot_filename (str): The output map filename output_data_filename (str): The output data filename nbins (int): The number of bins resolution (float): The resolution limit axis (tuple): The axis of the plane to compute the FSC method (str): Method to use (binned or averaged) """ # Check the axis if axis is None or type(axis) == int: axis = [axis] elif axis[0] is None or type(axis[0]) == int: axis = [axis] # Open the input files infile1 = read(input_map_filename1) infile2 = read(input_map_filename2) # Get the data data1 = infile1.data data2 = infile2.data # Reorder data2 to match data1 data1 = reorder(data1, read_axis_order(infile1), (0, 1, 2)) data2 = reorder(data2, read_axis_order(infile2), (0, 1, 2)) # Loop through all axes results = [] for current_axis in axis: # Compute the FSC bins, num, fsc = array_fsc( data1, data2, voxel_size=tuple(infile1.voxel_size[a] for a in ["z", "y", "x"]), nbins=nbins, resolution=resolution, axis=current_axis, method=method, ) # Compute the FSC average fsc_average = float(numpy.sum(num * fsc) / numpy.sum(num)) logger.info("FSC average: %g" % fsc_average) # Compute the resolution bin_index, bin_value, fsc_value = resolution_from_fsc(bins, fsc) logger.info("Estimated resolution = %f A" % (1 / sqrt(bin_value))) # Write the results dictionary results.append({ "axis": current_axis, "table": { "bin": list(map(float, bins)), "fsc": list(map(float, fsc)) }, "resolution": { "bin_index": int(bin_index), "bin_value": float(bin_value), "fsc_value": float(fsc_value), "estimate": float(1 / sqrt(bin_value)), }, "fsc_average": fsc_average, }) # Write the FSC curve if output_plot_filename is not None: fig, ax = pylab.subplots(figsize=(8, 6)) for r in results: bins = r["table"]["bin"] fsc = r["table"]["fsc"] axis = r["axis"] resolution = r["resolution"]["bin_value"] if axis == None: axis == (0, 1, 2) ax.plot(r["table"]["bin"], r["table"]["fsc"], label="axis - %s" % str(axis)) ax.set_xlabel("Resolution (A)") ax.set_ylabel("FSC") ax.set_ylim(0, 1) ax.axvline(resolution, color="black") ax.xaxis.set_major_formatter( ticker.FuncFormatter(lambda x, p: "%.1f" % (1 / sqrt(x)) if x > 0 else None)) ax.legend() fig.savefig(output_plot_filename, dpi=300, bbox_inches="tight") pylab.close(fig) # Write a data file if output_data_filename is not None: with open(output_data_filename, "w") as outfile: yaml.safe_dump(results, outfile) # Return the results return results