def get_image_volume(cbf_paths): """Load the image volume from the list of cbf_paths. The list of paths is assumed to be is order from 1->n. :param cbf_paths: The list of cbf files :param width The width (xsize) of the volume :param height The height (ysize) of the volume :returns: The 3D volume array """ # Read the first image and get the size cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cbf_paths[0], pycbf.MSG_DIGEST) image = get_image(cbf_handle) height, width = image.shape # Initialise the image volume num_slices = len(cbf_paths) volume = numpy.zeros(shape=(num_slices, height, width), dtype=numpy.int32) volume[0,:,:] = image # For each CBF file, read the image and put into the image volume for i, filename in enumerate(cbf_paths[1:]): cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(filename, pycbf.MSG_DIGEST) volume[i+1,:,:] = get_image(cbf_handle) # Return the image volume return volume
def get_image_volume(cbf_paths): """Load the image volume from the list of cbf_paths. The list of paths is assumed to be is order from 1->n. :param cbf_paths: The list of cbf files :param width The width (xsize) of the volume :param height The height (ysize) of the volume :returns: The 3D volume array """ # Read the first image and get the size cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cbf_paths[0], pycbf.MSG_DIGEST) image = get_image(cbf_handle) height, width = image.shape # Initialise the image volume num_slices = len(cbf_paths) volume = np.zeros(shape=(num_slices, height, width), dtype=np.int32) volume[0, :, :] = image # For each CBF file, read the image and put into the image volume for i, filename in enumerate(cbf_paths[1:]): cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(filename, pycbf.MSG_DIGEST) volume[i + 1, :, :] = get_image(cbf_handle) # Return the image volume return volume
def open_file_return_array(filename): import pycbf import numpy # open file cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(filename, pycbf.MSG_DIGEST) cbf_handle.rewind_datablock() # find right datablock cbf_handle.select_datablock(0) cbf_handle.select_category(0) cbf_handle.select_column(2) cbf_handle.select_row(0) type = cbf_handle.get_typeofvalue() assert (type.find('bnry') > -1) # read and reshape image = numpy.fromstring(cbf_handle.get_integerarray_as_string(), numpy.int32) parameters = cbf_handle.get_integerarrayparameters_wdims() image.shape = (parameters[10], parameters[9]) return image
def _get_cbf_handle(self): try: return self._cbf_handle except AttributeError: self._cbf_handle = pycbf.cbf_handle_struct() self._cbf_handle.read_widefile(self._image_file, pycbf.MSG_DIGEST) return self._cbf_handle
def open_file_return_array(filename): import pycbf import numpy # open file cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(filename, pycbf.MSG_DIGEST) cbf_handle.rewind_datablock() # find right datablock cbf_handle.select_datablock(0) cbf_handle.select_category(0) cbf_handle.select_column(2) cbf_handle.select_row(0) type = cbf_handle.get_typeofvalue() assert type.find("bnry") > -1 # read and reshape image = numpy.fromstring(cbf_handle.get_integerarray_as_string(), numpy.int32) parameters = cbf_handle.get_integerarrayparameters_wdims() image.shape = (parameters[10], parameters[9]) return image
def save_numpy_data_as_cbf(data, size1, size2, title, cbfout, pilatus_header=None): h = pycbf.cbf_handle_struct() h.new_datablock(title) h.require_category('array_data') if pilatus_header is not None: h.require_column('header_convention') h.set_value('"PILATUS_1.2"') h.require_column('header_contents') h.set_value(pilatus_header) h.require_category('array_data') h.require_column('data') elsigned = 1 if data.dtype in (numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64): elsigned = 0 h.set_integerarray_wdims_fs(pycbf.CBF_BYTE_OFFSET, 1, data.tostring(), data.dtype.itemsize, elsigned, len(data), "little_endian", size1, size2, 1, 0) h.write_file(cbfout, pycbf.CBF, pycbf.MIME_HEADERS | pycbf.MSG_DIGEST | pycbf.PAD_4K, pycbf.ENC_NONE)
def read_metadata(filename): if filename.endswith('bz2'): fname = os.path.splitext(filename)[0] else: fname = filename if os.path.splitext(fname)[1] == '.cbf': try: import pycbf except ImportError: raise NeXusError('Reading CBF files requires the pycbf module') cbf = pycbf.cbf_handle_struct() cbf.read_file(fname, pycbf.MSG_DIGEST) cbf.select_datablock(0) cbf.select_category(0) cbf.select_column(1) meta_text = cbf.get_value().splitlines() date_string = meta_text[2][2:] time_stamp = epoch(date_string) exposure = float(meta_text[5].split()[2]) summed_exposures = 1 return time_stamp, exposure, summed_exposures elif os.path.exists(fname + '.metadata'): parser = ConfigParser() parser.read(fname + '.metadata') return (parser.getfloat('metadata', 'timeStamp'), parser.getfloat('metadata', 'exposureTime'), parser.getint('metadata', 'summedExposures')) else: return time.time(), 1.0, 1
def read_image(filename): if os.path.splitext(filename)[1] == '.cbf': try: import pycbf except ImportError: raise NeXusError("Please install the 'pycbf' module") cbf = pycbf.cbf_handle_struct() cbf.read_file(filename, pycbf.MSG_DIGEST) cbf.select_datablock(0) cbf.select_category(0) cbf.select_column(2) imsize = cbf.get_image_size(0) return np.fromstring(cbf.get_integerarray_as_string(), np.int32).reshape(imsize) else: try: import tifffile as TIFF except ImportError: raise NeXusError("Please install the 'tifffile' module") if filename.endswith('.bz2'): import bz2 tiff_file = TIFF.TiffFile(bz2.BZ2File(filename)) else: tiff_file = TIFF.TiffFile(filename) return tiff_file.asarray()
def _get_cbf_handle(self): try: return self._cbf_handle except AttributeError: self._cbf_handle = pycbf.cbf_handle_struct() self._cbf_handle.read_widefile(self._image_file.encode(), pycbf.MSG_DIGEST) return self._cbf_handle
def understand(image_file): """Check to see if this looks like an CBF format image, i.e. we can make sense of it.""" header = FormatCBF.get_cbf_header(image_file) if "_diffrn.id" not in header and "_diffrn_source" not in header: return False # According to ImageCIF, "Data items in the DIFFRN_MEASUREMENT_AXIS # category associate axes with goniometers." # http://www.iucr.org/__data/iucr/cifdic_html/2/cif_img.dic/Cdiffrn_measurement_axis.html if "diffrn_measurement_axis" in header: return False # This implementation only supports single panel. try: cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file.encode(), pycbf.MSG_DIGEST) except Exception as e: if "CBFlib Error" in str(e): return False # check if multiple arrays try: return cbf_handle.count_elements() == 1 except Exception as e: if "CBFlib Error" in str(e): return False return True
def read_image(filename): if os.path.splitext(filename)[1] == '.cbf': try: import pycbf except ImportError: raise NeXusError('Reading CBF files requires the pycbf module') cbf = pycbf.cbf_handle_struct() cbf.read_file(filename, pycbf.MSG_DIGEST) cbf.select_datablock(0) cbf.select_category(0) cbf.select_column(2) imsize = cbf.get_image_size(0) return np.fromstring(cbf.get_integerarray_as_string(), np.int32).reshape(imsize) else: try: from nexpy.readers.tifffile import tifffile as TIFF except ImportError: raise NeXusError('Reading TIFF files requires the TIFF reader installed with NeXpy') if filename.endswith('.bz2'): import bz2 tiff_file = TIFF.TiffFile(bz2.BZ2File(filename)) else: tiff_file = TIFF.TiffFile(filename) return tiff_file.asarray()
def read_file(self, filename): """Read the CBF file""" import pycbf self.cbf_handle = pycbf.cbf_handle_struct() self.cbf_handle.read_file(filename, pycbf.MSG_DIGEST) self.cbf_handle.rewind_datablock()
def imgCIF(cif_file, sensor): '''Initialize a detector model from an imgCIF file.''' cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) return DetectorFactory.imgCIF_H(cbf_handle, sensor)
def save_numpy_data_as_cbf(data, size1, size2, title, cbfout, pilatus_header=None): h = pycbf.cbf_handle_struct() h.new_datablock(title) h.require_category('array_data') if pilatus_header is not None: h.require_column('header_convention') h.set_value('"PILATUS_1.2"') h.require_column('header_contents') h.set_value(pilatus_header) h.require_category('array_data') h.require_column('data') elsigned = 1 if data.dtype in (numpy.uint8, numpy.uint16, numpy.uint32, numpy.uint64): elsigned = 0 h.set_integerarray_wdims_fs(pycbf.CBF_BYTE_OFFSET, 1, data.tostring(), data.dtype.itemsize, elsigned, len(data), "little_endian", size1, size2, 1, 0) h.write_file(cbfout, pycbf.CBF, pycbf.MIME_HEADERS|pycbf.MSG_DIGEST|pycbf.PAD_4K, pycbf.ENC_NONE)
def imgCIF(cif_file): """Initialize a scan model from an imgCIF file.""" cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) return ScanFactory.imgCIF_H(cif_file, cbf_handle)
def imgCIF(cif_file): '''Initialize a scan model from an imgCIF file.''' cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) return scan_factory.imgCIF_H(cif_file, cbf_handle)
def read_metadata(filename): if filename.endswith('bz2'): fname = os.path.splitext(filename)[0] else: fname = filename if os.path.splitext(fname)[1] == '.cbf': try: import pycbf except ImportError: raise NeXusError('Reading CBF files requires the pycbf module') cbf = pycbf.cbf_handle_struct() cbf.read_file(fname, pycbf.MSG_DIGEST) cbf.select_datablock(0) cbf.select_category(0) cbf.select_column(1) meta_text = cbf.get_value().splitlines() date_string = meta_text[2][2:] time_stamp = epoch(date_string) exposure = float(meta_text[5].split()[2]) summed_exposures = 1 return time_stamp, exposure, summed_exposures elif os.path.exists(fname+'.metadata'): parser = ConfigParser() parser.read(fname+'.metadata') return (parser.getfloat('metadata', 'timeStamp'), parser.getfloat('metadata', 'exposureTime'), parser.getint('metadata', 'summedExposures')) else: return time.time(), 1.0, 1
def imgCIF(cif_file): """Initialize a goniometer model from an imgCIF file.""" # FIXME in here work out how to get the proper setting matrix if != 1 cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file.encode(), pycbf.MSG_DIGEST) return GoniometerFactory.imgCIF_H(cbf_handle)
def understand(image_file): '''Check to see if this looks like an CBF format image, i.e. we can make sense of it.''' cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file, pycbf.MSG_DIGEST) #check if multiple arrays return cbf_handle.count_elements() > 1
def load_cbf_as_numpy(filein, quiet=True): assert os.path.isfile(filein) if not quiet: print "reading", filein, "as cbf" h = pycbf.cbf_handle_struct() h.read_file(filein, pycbf.MSG_DIGEST) ndimfast, ndimslow = h.get_image_size_fs(0) arr = numpy.fromstring(h.get_image_fs_as_string(0, 4, 1, ndimfast, ndimslow), dtype=numpy.int32) return arr, ndimfast, ndimslow
def load_cbf_as_numpy(filein, quiet=True): assert os.path.isfile(filein) if not quiet: print "reading", filein, "as cbf" h = pycbf.cbf_handle_struct() h.read_file(filein, pycbf.MSG_DIGEST) ndimfast, ndimslow = h.get_image_size_fs(0) arr = numpy.fromstring(h.get_image_fs_as_string(0, 4, 1, ndimfast, ndimslow), dtype=numpy.int32) return arr, ndimfast, ndimslow
def imgCIF(cif_file): '''Initialize a goniometer model from an imgCIF file.''' # FIXME in here work out how to get the proper setting matrix if != 1 cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) return goniometer_factory.imgCIF_H(cbf_handle)
def understand(image_file): '''Check to see if this looks like an CBF format image, i.e. we can make sense of it.''' try: cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file, pycbf.MSG_DIGEST) except Exception, e: if 'CBFlib Error' in str(e): return False
def test_cbf_buffer(dials_regression): filename = os.path.join(dials_regression, "image_examples", "dials-190", "whatev1_01_00001.cbf") with open(filename, "rb") as f: contents = f.read() handle = pycbf.cbf_handle_struct() cbf_read_buffer(handle, contents, pycbf.MSG_DIGEST) det = DetectorFactory.imgCIF_H(handle, "unknown") assert det
def understand(image_file): '''Check to see if this looks like an CBF format image, i.e. we can make sense of it.''' try: cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file, pycbf.MSG_DIGEST) except Exception, e: if 'CBFlib Error' in str(e): return False
def load_xds_special(cbfin): h = pycbf.cbf_handle_struct() h.read_file(cbfin, pycbf.MSG_DIGEST) h.require_category("array_data") h.find_column("header_contents") header = h.get_value() M = cbf_binary_adaptor(cbfin) data = M.uncompress_implementation("buffer_based").uncompress_data() #print "slow, fast=", M.dim_slow(), M.dim_fast() # can be obtained after getting data return header, data, M.dim_slow(), M.dim_fast()
def load_xds_special(cbfin): h = pycbf.cbf_handle_struct() h.read_file(cbfin, pycbf.MSG_DIGEST) h.require_category("array_data") h.find_column("header_contents") header = h.get_value() M = cbf_binary_adaptor(cbfin) data = M.uncompress_implementation("buffer_based").uncompress_data() #print "slow, fast=", M.dim_slow(), M.dim_fast() # can be obtained after getting data return header, data, M.dim_slow(), M.dim_fast()
def imgCIF(cif_file, sensor): '''Initialize a detector model from an imgCIF file.''' cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) cbf_detector = cbf_handle.construct_detector(0) pixel = (cbf_detector.get_inferred_pixel_size(1), cbf_detector.get_inferred_pixel_size(2)) # FIXME can probably simplify the code which follows below by # making proper use of cctbx vector calls - should not be as # complex as it appears to be... origin = tuple(cbf_detector.get_pixel_coordinates(0, 0)) fast = cbf_detector.get_pixel_coordinates(0, 1) slow = cbf_detector.get_pixel_coordinates(1, 0) dfast = [fast[j] - origin[j] for j in range(3)] dslow = [slow[j] - origin[j] for j in range(3)] lfast = math.sqrt(sum([dfast[j] * dfast[j] for j in range(3)])) lslow = math.sqrt(sum([dslow[j] * dslow[j] for j in range(3)])) fast = tuple([dfast[j] / lfast for j in range(3)]) slow = tuple([dslow[j] / lslow for j in range(3)]) size = tuple(reversed(cbf_handle.get_image_size(0))) try: underload = find_undefined_value(cbf_handle) overload = cbf_handle.get_overload(0) * dxtbx_overload_scale trusted_range = (underload, overload) except: # intentional trusted_range = (0.0, 0.0) cbf_detector.__swig_destroy__(cbf_detector) del(cbf_detector) # Get the sensor type dtype = detector_factory.sensor(sensor) # If the sensor type is PAD then create the detector with a # parallax corrected pixel to millimeter function #if dtype == detector_helper_sensors.SENSOR_PAD: #px_mm = ParallaxCorrectedPxMmStrategy(0.252500934883) #else: px_mm = SimplePxMmStrategy() return detector_factory.make_detector( dtype, fast, slow, origin, pixel, size, trusted_range, px_mm)
def read_image(self, filename): if self.get_image_type() == 'CBF': import pycbf cbf = pycbf.cbf_handle_struct() cbf.read_file(str(filename), pycbf.MSG_DIGEST) cbf.select_datablock(0) cbf.select_category(0) cbf.select_column(2) imsize = cbf.get_image_size(0) return np.fromstring(cbf.get_integerarray_as_string(),np.int32).reshape(imsize) else: return TIFF.imread(filename)
def imgCIF(cif_file): """Initialize a detector model from an imgCIF file. N.B. the definition of the polarization plane is not completely helpful in this - it is the angle between the polarization plane and the +Y laboratory frame vector.""" cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(cif_file.encode(), pycbf.MSG_DIGEST) result = BeamFactory.imgCIF_H(cbf_handle) return result
def imgCIF(cif_file, sensor): '''Initialize a detector model from an imgCIF file.''' cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) cbf_detector = cbf_handle.construct_detector(0) pixel = (cbf_detector.get_inferred_pixel_size(1), cbf_detector.get_inferred_pixel_size(2)) # FIXME can probably simplify the code which follows below by # making proper use of cctbx vector calls - should not be as # complex as it appears to be... origin = tuple(cbf_detector.get_pixel_coordinates(0, 0)) fast = cbf_detector.get_pixel_coordinates(0, 1) slow = cbf_detector.get_pixel_coordinates(1, 0) dfast = [fast[j] - origin[j] for j in range(3)] dslow = [slow[j] - origin[j] for j in range(3)] lfast = math.sqrt(sum([dfast[j] * dfast[j] for j in range(3)])) lslow = math.sqrt(sum([dslow[j] * dslow[j] for j in range(3)])) fast = tuple([dfast[j] / lfast for j in range(3)]) slow = tuple([dslow[j] / lslow for j in range(3)]) size = tuple(reversed(cbf_handle.get_image_size(0))) try: underload = find_undefined_value(cbf_handle) overload = cbf_handle.get_overload(0) * dxtbx_overload_scale trusted_range = (underload, overload) except: # intentional trusted_range = (0.0, 0.0) cbf_detector.__swig_destroy__(cbf_detector) del (cbf_detector) # Get the sensor type dtype = detector_factory.sensor(sensor) # If the sensor type is PAD then create the detector with a # parallax corrected pixel to millimeter function #if dtype == detector_helper_sensors.SENSOR_PAD: #px_mm = ParallaxCorrectedPxMmStrategy(0.252500934883) #else: px_mm = SimplePxMmStrategy() return detector_factory.make_detector(dtype, fast, slow, origin, pixel, size, trusted_range, px_mm)
def load_minicbf_as_numpy(filein, quiet=True): # This can also read XDS special cbf assert os.path.isfile(filein) if not quiet: print "reading", filein, "as minicbf" h = pycbf.cbf_handle_struct() h.read_file(filein, pycbf.MSG_DIGEST) h.require_category("array_data") h.find_column("data") compression, binary_id, elsize, elsigned, elunsigned, elements, minelement, maxelement, bo, ndimfast, ndimmid, ndimslow, padding = h.get_integerarrayparameters_wdims() assert elsize == 4 or elsize == 8 assert elsigned == 1 assert ndimslow <= 1 arr = numpy.fromstring(h.get_integerarray_as_string(), dtype=numpy.int32 if elsize==4 else numpy.int64) return arr, ndimfast, ndimmid
def imgCIF(cif_file): '''Initialize a goniometer model from an imgCIF file.''' cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) cbf_gonio = cbf_handle.construct_goniometer() axis, fixed = cbf_gonio_to_effective_axis_fixed(cbf_gonio) cbf_gonio.__swig_destroy__(cbf_gonio) del(cbf_gonio) return goniometer_factory.make_goniometer(axis, fixed)
def load_minicbf_as_numpy(filein, quiet=True): # This can also read XDS special cbf assert os.path.isfile(filein) if not quiet: print "reading", filein, "as minicbf" h = pycbf.cbf_handle_struct() h.read_file(filein, pycbf.MSG_DIGEST) h.require_category("array_data") h.find_column("data") compression, binary_id, elsize, elsigned, elunsigned, elements, minelement, maxelement, bo, ndimfast, ndimmid, ndimslow, padding = h.get_integerarrayparameters_wdims() assert elsize == 4 or elsize == 8 assert elsigned == 1 assert ndimslow <= 1 arr = numpy.fromstring(h.get_integerarray_as_string(), dtype=numpy.int32 if elsize==4 else numpy.int64) return arr, ndimfast, ndimmid
def understand(image_file): """Check to see if this looks like an CSPD CBF format image, i.e. we can make sense of it.""" cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file.encode(), pycbf.MSG_DIGEST) cbf_handle.find_category(b"diffrn_detector") if cbf_handle.count_rows() > 1: return False # support 1 detector per file for now cbf_handle.find_column(b"type") return cbf_handle.get_value() == b"CS PAD"
def understand(image_file): '''Check to see if this looks like an CSPD CBF format image, i.e. we can make sense of it.''' cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file, pycbf.MSG_DIGEST) cbf_handle.find_category("diffrn_detector") if cbf_handle.count_rows() > 1: return False # support 1 detector per file for now cbf_handle.find_column("type") return cbf_handle.get_value() == "CS PAD"
def get_pilatus_header(cbfin): h = pycbf.cbf_handle_struct() if cbfin.endswith(".bz2"): # TODO to speed up, better only bunzip2 the first part of file.. import tempfile import bz2 junk, tmpf = tempfile.mkstemp() open(tmpf, "wb").write(bz2.BZ2File(cbfin).read()) h.read_file(tmpf, pycbf.MSG_DIGEST) os.remove(tmpf) else: h.read_file(cbfin, pycbf.MSG_DIGEST) h.require_category("array_data") h.find_column("header_contents") header = h.get_value() return header
def imgCIF(cif_file): '''Initialize a goniometer model from an imgCIF file.''' # FIXME in here work out how to get the proper setting matrix if != 1 cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) cbf_gonio = cbf_handle.construct_goniometer() axis, fixed = cbf_gonio_to_effective_axis_fixed(cbf_gonio) cbf_gonio.__swig_destroy__(cbf_gonio) del(cbf_gonio) return goniometer_factory.make_goniometer(axis, fixed)
def get_pilatus_header(cbfin): h = pycbf.cbf_handle_struct() if cbfin.endswith(".bz2"): # TODO to speed up, better only bunzip2 the first part of file.. import tempfile import bz2 junk, tmpf = tempfile.mkstemp() open(tmpf, "wb").write(bz2.BZ2File(cbfin).read()) h.read_file(tmpf, pycbf.MSG_DIGEST) os.remove(tmpf) else: h.read_file(cbfin, pycbf.MSG_DIGEST) h.require_category("array_data") h.find_column("header_contents") header = h.get_value() return header
def get_data(self): self.import_file = self.get_filename() cbf = pycbf.cbf_handle_struct() cbf.read_file(str(self.import_file), pycbf.MSG_DIGEST) cbf.select_datablock(0) cbf.select_category(0) cbf.select_column(2) imsize = cbf.get_image_size(0) z = NXfield(np.fromstring(cbf.get_integerarray_as_string(),np.int32).reshape(imsize), name='z') y = NXfield(range(z.shape[0]), name='y') x = NXfield(range(z.shape[1]), name='x') cbf.select_column(1) notes = NXnote(type='text/plain', description='CBF Header', data=cbf.get_value().replace('\n','\r\n')) return NXentry(NXdata(z,(y,x)), CBF_header=notes)
def understand(image_file): """Check to see if this looks like an CBF format image, i.e. we can make sense of it.""" try: cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file, pycbf.MSG_DIGEST) except Exception as e: if "CBFlib Error" in str(e): return False # check if multiple arrays try: return cbf_handle.count_elements() > 1 except Exception as e: if "CBFlib Error" in str(e): return False
def imgCIF(cif_file): '''Initialize a detector model from an imgCIF file. N.B. the definition of the polarization plane is not completely helpful in this - it is the angle between the polarization plane and the +Y laboratory frame vector.''' d2r = math.pi / 180.0 cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) cbf_handle.find_category('axis') # find record with equipment = source cbf_handle.find_column('equipment') cbf_handle.find_row('source') # then get the vector and offset from this direction = [] for j in range(3): cbf_handle.find_column('vector[%d]' % (j + 1)) direction.append(cbf_handle.get_doublevalue()) # and the wavelength wavelength = cbf_handle.get_wavelength() # and information about the polarization - FIXME this should probably # be a rotation about the beam not about the Z axis. try: polar_fraction, polar_angle = cbf_handle.get_polarization() except Exception: polar_fraction = 0.999 polar_angle = 0.0 polar_plane_normal = (math.sin(polar_angle * d2r), math.cos(polar_angle * d2r), 0.0) return BeamFactory.make_polarized_beam( sample_to_source=direction, wavelength=wavelength, polarization=polar_plane_normal, polarization_fraction=polar_fraction)
def imgCIF(cif_file): '''Initialize a detector model from an imgCIF file. N.B. the definition of the polarization plane is not completely helpful in this - it is the angle between the polarization plane and the +Y laboratory frame vector.''' d2r = math.pi / 180.0 cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cif_file, pycbf.MSG_DIGEST) cbf_handle.find_category('axis') # find record with equipment = source cbf_handle.find_column('equipment') cbf_handle.find_row('source') # then get the vector and offset from this direction = [] for j in range(3): cbf_handle.find_column('vector[%d]' % (j + 1)) direction.append(cbf_handle.get_doublevalue()) # and the wavelength wavelength = cbf_handle.get_wavelength() # and information about the polarization - FIXME this should probably # be a rotation about the beam not about the Z axis. try: polar_fraction, polar_angle = cbf_handle.get_polarization() except: # intentional polar_fraction = 0.999 polar_angle = 0.0 polar_plane_normal = ( math.sin(polar_angle * d2r), math.cos(polar_angle * d2r), 0.0) return beam_factory.make_polarized_beam( sample_to_source=direction, wavelength=wavelength, polarization=polar_plane_normal, polarization_fraction=polar_fraction)
def process(file_name, out=None): if (out is None): out = sys.stdout import pycbf print >> out, "File name:", file_name object = pycbf.cbf_handle_struct() # FIXME object.read_file(file_name, pycbf.MSG_DIGEST) object.rewind_datablock() n_blocks = object.count_datablocks() print >> out, "Number of blocks:", n_blocks for i_block in xrange(n_blocks): object.select_datablock(i_block) print >> out, " Block name:", object.datablock_name() object.rewind_category() n_categories = object.count_categories() print >> out, " Number of categories:", n_categories for i_category in xrange(n_categories): object.select_category(i_category) print >> out, " Category name:", object.category_name() print >> out
def get_data(self): self.import_file = self.get_filename() cbf = pycbf.cbf_handle_struct() cbf.read_file(str(self.import_file), pycbf.MSG_DIGEST) cbf.select_datablock(0) cbf.select_category(0) cbf.select_column(2) imsize = cbf.get_image_size(0) z = NXfield(np.fromstring(cbf.get_integerarray_as_string(), np.int32).reshape(imsize), name='z') y = NXfield(range(z.shape[0]), name='y') x = NXfield(range(z.shape[1]), name='x') cbf.select_column(1) notes = NXnote(type='text/plain', description='CBF Header', data=cbf.get_value().replace('\n', '\r\n')) return NXentry(NXdata(z, (y, x)), CBF_header=notes)
def understand(image_file): """Check to see if this looks like an CBF format image, i.e. we can make sense of it.""" cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file.encode(), pycbf.MSG_DIGEST) # check if multiple arrays if cbf_handle.count_elements() <= 1: return False # we need the optional column equipment_component to build a hierarchy try: cbf_handle.find_category(b"axis") cbf_handle.find_column(b"equipment_component") except Exception as e: if "CBF_NOTFOUND" in str(e): return False raise e return True
def understand(image_file): '''Check to see if this looks like an CBF format image, i.e. we can make sense of it.''' cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file, pycbf.MSG_DIGEST) #check if multiple arrays if cbf_handle.count_elements() <= 1: return False # we need the optional column equipment_component to build a hierarchy try: cbf_handle.find_category("axis") cbf_handle.find_column("equipment_component") except Exception, e: if "CBF_NOTFOUND" in str(e): return False else: raise e
def process(file_name, out=None): if out is None: out = sys.stdout import pycbf print >> out, "File name:", file_name object = pycbf.cbf_handle_struct() # FIXME object.read_file(file_name, pycbf.MSG_DIGEST) object.rewind_datablock() n_blocks = object.count_datablocks() print >> out, "Number of blocks:", n_blocks for i_block in xrange(n_blocks): object.select_datablock(i_block) print >> out, " Block name:", object.datablock_name() object.rewind_category() n_categories = object.count_categories() print >> out, " Number of categories:", n_categories for i_category in xrange(n_categories): object.select_category(i_category) print >> out, " Category name:", object.category_name() print >> out
def load(self, warn=True): data = [] metadata = [] try: h = _cbf.cbf_handle_struct() h.read_widefile(self.name, _cbf.MSG_DIGEST) h.rewind_datablock() for nd in range(h.count_datablocks()): h.select_datablock(nd) # db_name = h.datablock_name() # print "DBl: %d, %s" % (nd, db_name) h.rewind_category() for nc in range(h.count_categories()): h.select_category(nc) # ct_name = h.category_name() # print " Cat: %d, %s" % (nc, ct_name) h.rewind_column() colnames = [] for nv in range(h.count_columns()): h.select_column(nv) cl_name = h.column_name() colnames.append(cl_name) # print " Col: %d, %s" % (nv, cl_name) h.rewind_row() for nh in range(h.count_rows()): h.select_row(nh) h.rewind_column() for nv in range(h.count_columns()): h.select_column(nv) v = self.getvalue(h) # print " %d %d: " % (nh, nv), v item = "%s-%d" % (colnames[nv], nh), v if isinstance(v, numpy.ndarray): data.append(item) else: metadata.append(item) finally: del(h) return DataHolder(data, metadata, warn)
def _get_cbf_handle(self): try: return self._cbf_handle except AttributeError: self._cbf_handle = pycbf.cbf_handle_struct() buffer = None # Reopen to tell if it's a gzip - this should be cached, so fast with FormatCBF.open_file(self._image_file, "rb") as fin: # If this was a gzip or bzip file, read as a buffer if (gzip and isinstance(fin._cache_object._file, gzip.GzipFile) ) or (bz2 and isinstance(fin._cache_object._file, bz2.BZ2File)): buffer = fin.read() if buffer: cbf_read_buffer(self._cbf_handle, buffer, pycbf.MSG_DIGEST) else: self._cbf_handle.read_widefile(self._image_file.encode(), pycbf.MSG_DIGEST) return self._cbf_handle
def understand(image_file): '''Check to see if this looks like an CBF format image, i.e. we can make sense of it.''' header = FormatCBF.get_cbf_header(image_file) if not '_diffrn.id' in header and not '_diffrn_source': return False # According to ImageCIF, "Data items in the DIFFRN_MEASUREMENT_AXIS # category associate axes with goniometers." # http://www.iucr.org/__data/iucr/cifdic_html/2/cif_img.dic/Cdiffrn_measurement_axis.html if 'diffrn_measurement_axis' in header: return False # This implementation only supports single panel. try: cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(image_file, pycbf.MSG_DIGEST) except Exception, e: if 'CBFlib Error' in str(e): return False
def load(self, warn=True): data = [] metadata = [] try: h = _cbf.cbf_handle_struct() h.read_widefile(self.name, _cbf.MSG_DIGEST) h.rewind_datablock() for nd in range(h.count_datablocks()): h.select_datablock(nd) # db_name = h.datablock_name() # print "DBl: %d, %s" % (nd, db_name) h.rewind_category() for nc in range(h.count_categories()): h.select_category(nc) # ct_name = h.category_name() # print " Cat: %d, %s" % (nc, ct_name) h.rewind_column() colnames = [] for nv in range(h.count_columns()): h.select_column(nv) cl_name = h.column_name() colnames.append(cl_name) # print " Col: %d, %s" % (nv, cl_name) h.rewind_row() for nh in range(h.count_rows()): h.select_row(nh) h.rewind_column() for nv in range(h.count_columns()): h.select_column(nv) v = self.getvalue(h) # print " %d %d: " % (nh, nv), v item = "%s-%d" % (colnames[nv], nh), v if isinstance(v, numpy.ndarray): data.append(item) else: metadata.append(item) finally: del(h) return DataHolder(data, metadata, warn)
def find_HKL(cbf_image): # construct and link a cbf_handle to the image itself. cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cbf_image, pycbf.MSG_DIGEST) # get the beam direction cbf_handle.find_category('axis') cbf_handle.find_column('equipment') cbf_handle.find_row('source') beam_direction = [] for j in range(3): cbf_handle.find_column('vector[%d]' % (j + 1)) beam_direction.append(cbf_handle.get_doublevalue()) B = - matrix.col(beam_direction).normalize() detector = cbf_handle.construct_detector(0) # this returns slow fast slow fast pixels pixels mm mm detector_normal = tuple(detector.get_detector_normal()) distance = detector.get_detector_distance() pixel = (detector.get_inferred_pixel_size(1), detector.get_inferred_pixel_size(2)) gonio = cbf_handle.construct_goniometer() real_axis, real_angle = determine_effective_scan_axis(gonio) axis = tuple(gonio.get_rotation_axis()) angles = tuple(gonio.get_rotation_range()) # this method returns slow then fast dimensions i.e. (y, x) size = tuple(reversed(cbf_handle.get_image_size(0))) wavelength = cbf_handle.get_wavelength() O = matrix.col(detector.get_pixel_coordinates(0, 0)) fast = matrix.col(detector.get_pixel_coordinates(0, 1)) slow = matrix.col(detector.get_pixel_coordinates(1, 0)) X = fast - O Y = slow - O X = X.normalize() Y = Y.normalize() N = X.cross(Y) S0 = (1.0 / wavelength) * B # Need to rotate into Rossmann reference frame for phi calculation, as # that's code from Labelit :o( RB = matrix.col([0, 0, 1]) if B.angle(RB) % math.pi: RtoR = RB.cross(R).axis_and_angle_as_r3_rotation_matrix( RB.angle(R)) elif B.angle(RB): RtoR = matrix.sqr((1, 0, 0, 0, -1, 0, 0, 0, -1)) else: RtoR = matrix.sqr((1, 0, 0, 0, 1, 0, 0, 0, 1)) Raxis = RtoR * axis RUB = RtoR * UB RA = rotation_angles(wavelength, RUB, wavelength, Raxis) assert(RA(hkl)) omegas = [180.0 / math.pi * a for a in RA.get_intersection_angles()] print '%.2f %.2f' % tuple(omegas) for omega in omegas: R = matrix.col(axis).axis_and_angle_as_r3_rotation_matrix( math.pi * omega / 180.0) q = R * UB * hkl p = S0 + q p_ = p * (1.0 / math.sqrt(p.dot())) P = p_ * (O.dot(N) / (p_.dot(N))) R = P - O i = R.dot(X) j = R.dot(Y) k = R.dot(N) print '%d %d %d %.3f %.3f %.3f %.3f %.3f' % \ (hkl[0], hkl[1], hkl[2], i, j, omega, i / pixel[0], j / pixel[1]) # finally, the inverse calculation - given a position on the detector, # and omega setting, give the Miller index of the reflection i = 193 j = 267 w = 42 # RUBI is (R * UB).inverse() RUBI = (matrix.col(axis).axis_and_angle_as_r3_rotation_matrix( math.pi * w / 180.0) * UB).inverse() p = matrix.col(detector.get_pixel_coordinates(j, i)).normalize() q = (1.0 / wavelength) * p - S0 h, k, l = map(nint, (RUBI * q).elems) assert(h == -17) assert(k == -10) assert(l == 9) print h, k, l detector.__swig_destroy__(detector) del(detector) gonio.__swig_destroy__(gonio) del(gonio)
def cbfdump(cbf_image, do_print = False): cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cbf_image, pycbf.MSG_DIGEST) detector_id = find_detector_id(cbf_handle) # find the direct beam vector - takes a few steps cbf_handle.find_category('axis') # find record with equipment = source cbf_handle.find_column('equipment') cbf_handle.find_row('source') # then get the vector and offset from this beam_direction = [] for j in range(3): cbf_handle.find_column('vector[%d]' % (j + 1)) beam_direction.append(cbf_handle.get_doublevalue()) # and calculate the polarization plane normal vector, which is # presumed to be in the x / y plane? it is certainly given as an angle # from +y polarization_ratio, polarization_norm = cbf_handle.get_polarization() polarization_plane_normal = (math.sin(polarization_norm * math.pi / 180.0), math.cos(polarization_norm * math.pi / 180.0), 0.0) detector = cbf_handle.construct_detector(0) # this returns slow fast slow fast pixels pixels mm mm beam = detector.get_beam_center() beam_pixel = tuple(reversed(beam[:2])) beam_mm = tuple(reversed(beam[2:])) detector_normal = tuple(detector.get_detector_normal()) distance = detector.get_detector_distance() pixel = (detector.get_inferred_pixel_size(1), detector.get_inferred_pixel_size(2)) gonio = cbf_handle.construct_goniometer() real_axis, real_angle = determine_effective_scan_axis(gonio) axis = tuple(gonio.get_rotation_axis()) angles = tuple(gonio.get_rotation_range()) date = cbf_handle.get_datestamp() time = cbf_handle.get_timestamp() # this method returns slow then fast dimensions i.e. (y, x) size = tuple(reversed(cbf_handle.get_image_size(0))) exposure = cbf_handle.get_integration_time() overload = cbf_handle.get_overload(0) underload = find_undefined_value(cbf_handle) wavelength = cbf_handle.get_wavelength() if do_print: print 'Detector information:' if do_print: print 'Dimensions: %d %d' % size if do_print: print 'Pixel size: %.3f %.3f' % pixel if do_print: print 'Distance: %.1f' % distance if do_print: print 'Normal: %.2f %.2f %.2f' % detector_normal if do_print: print 'Exposure: %.2f' % exposure if do_print: print 'Overload: %d' % int(overload) if do_print: print 'Underload: %d' % int(underload) if do_print: print 'Beam: %.2f %.2f' % beam_mm if do_print: print 'Beam: %.2f %.2f %.2f' % tuple(beam_direction) if do_print: print 'Polariz.: %.2f %.2f %.2f' % \ tuple(polarization_plane_normal) if do_print: print 'Goniometer:' if do_print: print 'Axis: %.2f %.2f %.2f' % axis if do_print: print 'Real axis: %.2f %.2f %.2f' % real_axis if do_print: print 'Angles: %.2f %.2f' % angles if do_print: print 'Real angle: %.2f' % real_angle if do_print: print 'Experiment:' if do_print: print 'Wavelength: %.5f' % wavelength # now need to dig out the detector axes # perhaps bodge this by looking at the displacements of pixels in the # fast and slow directions? origin = matrix.col(detector.get_pixel_coordinates(0, 0)) pfast = matrix.col(detector.get_pixel_coordinates(0, 1)) pslow = matrix.col(detector.get_pixel_coordinates(1, 0)) if do_print: print 'Origin: %.2f %.2f %.2f' % origin.elems dfast = pfast - origin dslow = pslow - origin fast = dfast.normalize() slow = dslow.normalize() if do_print: print 'Fast direction: %.2f %.2f %.2f' % fast.elems if do_print: print 'Slow direction: %.2f %.2f %.2f' % slow.elems if hasattr(detector, 'get_detector_axis_fast'): if do_print: print 'CBF fast: %.2f %.2f %.2f' % \ tuple(detector.get_detector_axis_fast()) if do_print: print 'CBF slow: %.2f %.2f %.2f' % \ tuple(detector.get_detector_axis_slow()) # now also compute the position on the detector where the beam will # actually strike the detector - this will be the intersection of the # source vector with the plane defined by fast and slow passing through # the detector origin. Then return this position on the detector in mm. # # unit vectors - # _b - beam # _n - detector normal # _f, _s - fast and slow directions on the detector # # full vectors - # _O - displacement of origin # _D - displacement to intersection of beam with detector plane # _B - displacement from origin to said intersection _b = matrix.col(beam_direction) / math.sqrt( matrix.col(beam_direction).dot()) _n = matrix.col(detector_normal) / math.sqrt( matrix.col(detector_normal).dot()) _f = fast _s = slow _O = origin _D = _b * (_O.dot(_n) / _b.dot(_n)) _B = _D - _O x = _B.dot(_f) y = _B.dot(_s) if do_print: print 'Computed: %.2f %.2f' % (x, y) if do_print: print 'Pixels: %.2f %.2f' % (x / pixel[0], y / pixel[1]) if do_print: print 'Size: %.2f %.2f' % (size[0] * pixel[0], size[1] * pixel[1]) detector.__swig_destroy__(detector) del(detector) gonio.__swig_destroy__(gonio) del(gonio) return
def get_table_entry(xcbf,xcol): """ get_table_entry xcbf is a cbf_handle_struct (a CBF) xcol is the column for which a value is desired """ try: xcbf.find_column(xcol) xtemp = xcbf.get_value() return xtemp except: return "." object = pycbf.cbf_handle_struct() try: cbf = sys.argv[1] object.read_file(cbf,pycbf.MSG_DIGEST) foundfile = 1 except: foundfile = 0 # # Minimal file open logic depending on the user # to know the exact path # # Exit on an empty string # while foundfile == 0: cbf = raw_input("path to cbf: ") if cbf == "":
def compute_reciprocal_space_distance_map(cbf_image): '''Compute a map of distance from the transformed centre of each pixel to the nearest reciprocal space node, measured in h, k, l space.''' # construct and link a cbf_handle to the image itself. cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_file(cbf_image, pycbf.MSG_DIGEST) # find the direction if the S0 beam vector (i.e. source -> sample) B = find_beam_direction(cbf_handle) # find out about the detector detector = cbf_handle.construct_detector(0) # this returns slow fast slow fast pixels pixels mm mm detector_normal = tuple(detector.get_detector_normal()) distance = detector.get_detector_distance() pixel = (detector.get_inferred_pixel_size(1), detector.get_inferred_pixel_size(2)) # find out about the goniometer gonio = cbf_handle.construct_goniometer() R = compute_central_rotation_matrix(gonio) # this method returns slow then fast dimensions i.e. (y, x) size = tuple(reversed(cbf_handle.get_image_size(0))) wavelength = cbf_handle.get_wavelength() O = matrix.col(detector.get_pixel_coordinates(0, 0)) fast = matrix.col(detector.get_pixel_coordinates(0, 1)) slow = matrix.col(detector.get_pixel_coordinates(1, 0)) X = fast - O Y = slow - O X = X.normalize() Y = Y.normalize() N = X.cross(Y) S0 = (1.0 / wavelength) * B # RUBI is (R * UB).inverse() RUBI = (R * UB).inverse() square_distances = [] for i in range(size[1]): for j in range(size[0]): p = matrix.col(detector.get_pixel_coordinates_fs(j, i)).normalize() q = (1.0 / wavelength) * p - S0 _hkl = (RUBI * q).elems hkl = map(nint, _hkl) d2 = sum([(_hkl[k] - hkl[k]) * (_hkl[k] - hkl[k]) for k in range(3)]) square_distances.append(d2) # plot - this needs the full fat cctbx with extra bits try: plot_image(size[0], size[1], square_distances, 'cctbx_introduction_1.png') except exceptions.Exception, e: print 'Plotting image failed: %s' % str(e)
("diffrn_detector" , "id"), ("diffrn_detector_axis" , "axis_id"), ("diffrn_detector_element" , "id"), ("diffrn_data_frame" , "detector_element_id"), ("array_structure_list" , None), ("array_structure_list_axis" , "axis_set_id"), ("array_structure_list_section", None)] # categories whose data to copy from one cbf to another copy_categories = [("axis" , "id"), ("diffrn_scan_axis" , "axis_id"), ("diffrn_scan_frame_axis" , "axis_id")] names = [n[0] for n in required_categories]; names.extend([c[0] for c in copy_categories]) keys = [n[1] for n in required_categories]; keys .extend([c[1] for c in copy_categories]) src_cbf = pycbf.cbf_handle_struct() src_cbf.read_widefile(params.source_cbf, pycbf.MSG_DIGEST) # verify all the categories are present in the source cbf print "Testing for required categories in source:" src_cbf.select_category(0) n_found = 0 while True: if not src_cbf.category_name() in names: raise Sorry("%s not a recognized category"%src_cbf.category_name()) print "Found", src_cbf.category_name() n_found += 1 try: src_cbf.next_category() except Exception, e: assert "CBF_NOTFOUND" in e.message
import pycbf obj = pycbf.cbf_handle_struct() obj.read_file("../adscconverted.cbf", 0) obj.select_datablock(0) g = obj.construct_goniometer() print "Rotation axis is", g.get_rotation_axis() d = obj.construct_detector(0) print "Beam center is", d.get_beam_center()
def failover_full_cbf(cbf_file): '''Use pycbf library to read full cbf file description.''' header = { } cbf_handle = pycbf.cbf_handle_struct() cbf_handle.read_widefile(cbf_file, pycbf.MSG_DIGEST) detector_id_map = {'Pilatus2M':'pilatus 2M', 'Pilatus6M':'pilatus 6M', 'i19-p300k':'pilatus 300K', 'ADSCQ315-SN920':'adsc q315 2x2 binned'} header['detector_class'] = detector_id_map[find_detector_id(cbf_handle)] if 'pilatus' in header['detector_class']: header['detector'] = 'dectris' elif 'adsc' in header['detector_class']: header['detector'] = 'adsc' else: raise RuntimeError, 'unknown detector %s' % header['detector_class'] cbf_handle.rewind_datablock() detector = cbf_handle.construct_detector(0) # FIXME need to check that this is doing something sensible...! header['beam'] = tuple(map(math.fabs, detector.get_beam_center()[2:])) detector_normal = tuple(detector.get_detector_normal()) gonio = cbf_handle.construct_goniometer() axis = tuple(gonio.get_rotation_axis()) angles = tuple(gonio.get_rotation_range()) header['distance'] = detector.get_detector_distance() header['pixel'] = (detector.get_inferred_pixel_size(1), detector.get_inferred_pixel_size(2)) header['phi_start'], header['phi_width'] = angles header['phi_end'] = header['phi_start'] + header['phi_width'] year, month, day, hour, minute, second, x = cbf_handle.get_datestamp() struct_time = datetime.datetime(year, month, day, hour, minute, second).timetuple() header['date'] = time.asctime(struct_time) header['epoch'] = cbf_handle.get_timestamp()[0] header['size'] = tuple(cbf_handle.get_image_size(0)) header['exposure_time'] = cbf_handle.get_integration_time() header['wavelength'] = cbf_handle.get_wavelength() # compute the true two-theta offset... which is kind-of going around # the houses. oh and the real rotation axis. origin = detector.get_pixel_coordinates(0, 0) fast = detector.get_pixel_coordinates(0, 1) slow = detector.get_pixel_coordinates(1, 0) dfast = matrix.col([fast[j] - origin[j] for j in range(3)]).normalize() dslow = matrix.col([slow[j] - origin[j] for j in range(3)]).normalize() dorigin = matrix.col(origin) dnormal = dfast.cross(dslow) centre = - (dorigin - dorigin.dot(dnormal) * dnormal) f = centre.dot(dfast) s = centre.dot(dslow) header['fast_direction'] = dfast.elems header['slow_direction'] = dslow.elems header['detector_origin_mm'] = f, s header['rotation_axis'] = cbf_gonio_to_effective_axis(gonio) two_theta = dfast.angle(matrix.col((0.0, 1.0, 0.0)), deg = True) if math.fabs(two_theta - 180.0) < 1.0: header['two_theta'] = 0 else: header['two_theta'] = two_theta # find the direct beam vector - takes a few steps cbf_handle.find_category('axis') # find record with equipment = source cbf_handle.find_column('equipment') cbf_handle.find_row('source') # then get the vector and offset from this beam_direction = [] for j in range(3): cbf_handle.find_column('vector[%d]' % (j + 1)) beam_direction.append(cbf_handle.get_doublevalue()) # FIXME in here add in code to compute from first principles the beam # centre etc. detector.__swig_destroy__(detector) del(detector) gonio.__swig_destroy__(gonio) del(gonio) return header