def __init__(self, name, wavelength, sample, directory = None, image = None, beam = None, reversephi = False, distance = None, gain = 0.0, dmin = 0.0, dmax = 0.0, polarization = 0.0, frames_to_process = None, user_lattice = None, user_cell = None, epoch = 0, ice = False, excluded_regions = []): '''Create a new sweep named name, belonging to XWavelength object wavelength, representing the images in directory starting with image, with beam centre optionally defined.''' # + check the wavelength is an XWavelength object # raise an exception if not... or not... if not wavelength.__class__.__name__ == 'XWavelength': pass # FIXME bug 2221 if DIRECTORY starts with ~/ or ~graeme (say) need to # interpret this properly - e.g. map it to a full PATH. directory = expand_path(directory) # bug # 2274 - maybe migrate the data to a local disk (this # will depend if the user has added -migrate_data to the cl) directory = FileHandler.migrate(directory) self._name = name self._wavelength = wavelength self._sample = sample self._directory = directory self._image = image self._reversephi = reversephi self._epoch = epoch self._user_lattice = user_lattice self._user_cell = user_cell self._header = { } self._resolution_high = dmin self._resolution_low = dmax self._ice = ice self._excluded_regions = excluded_regions self._imageset = None # FIXME in here also need to be able to accumulate the total # dose from all experimental measurements (complex) and provide # a _epoch_to_dose dictionary or some such... may be fiddly as # this will need to parse across multiple templates. c/f Bug # 2798 self._epoch_to_image = { } self._image_to_epoch = { } # to allow first, last image for processing to be # set... c/f integrater interface self._frames_to_process = frames_to_process # + derive template, list of images if directory and image: self._template, self._directory = \ image2template_directory(os.path.join(directory, image)) from xia2.Schema import load_imagesets imagesets = load_imagesets( self._template, self._directory, image_range=self._frames_to_process, reversephi=(Flags.get_reversephi() or self._reversephi)) assert len(imagesets) == 1, "one imageset expected, %d found" % \ len(imagesets) self._imageset = copy.deepcopy(imagesets[0]) start, end = self._imageset.get_array_range() self._images = list(range(start+1, end+1)) # FIXME in here check that (1) the list of images is continuous # and (2) that all of the images are readable. This should also # take into account frames_to_process if set. if self._frames_to_process is None: self._frames_to_process = min(self._images), max(self._images) start, end = self._frames_to_process error = False from xia2.Handlers.Phil import PhilIndex params = PhilIndex.get_python_object() if params.general.check_image_files_readable: for j in range(start, end + 1): if not j in self._images: Debug.write('image %s missing' % \ self.get_image_name(j)) error = True continue if not os.access(self.get_image_name(j), os.R_OK): Debug.write('image %s unreadable' % \ self.get_image_name(j)) error = True continue if error: raise RuntimeError, 'problem with sweep %s' % self._name # + read the image header information into here? # or don't I need it? it would be useful for checking # against wavelength.getWavelength() I guess to make # sure that the plumbing is all sound. # check that they match by closer than 0.0001A, if wavelength # is not None beam_ = self._imageset.get_beam() scan = self._imageset.get_scan() if not wavelength == None: # FIXME 29/NOV/06 if the wavelength wavelength value # is 0.0 then first set it to the header value - note # that this assumes that the header value is correct # (a reasonable assumption) if wavelength.get_wavelength() == 0.0: wavelength.set_wavelength(beam_.get_wavelength()) # FIXME 08/DEC/06 in here need to allow for the fact # that the wavelength in the image header could be wrong and # in fact it should be replaced with the input value - # through the user will need to be warned of this and # also everything using the FrameProcessor interface # will also have to respect this! if math.fabs(beam_.get_wavelength() - wavelength.get_wavelength()) > 0.0001: # format = 'wavelength for sweep %s does not ' + \ # 'match wavelength %s' # raise RuntimeError, format % \ # (name, wavelength.get_name()) format = 'Header wavelength for sweep %s different' + \ ' to assigned value (%4.2f vs. %4.2f)' Chatter.write(format % (name, beam_.get_wavelength(), wavelength.get_wavelength())) # also in here look at the image headers to see if we can # construct a mapping between exposure epoch and image ... images = [] if self._frames_to_process: start, end = self._frames_to_process for j in self._images: if j >= start and j <= end: images.append(j) else: images = self._images for j in images: epoch = scan.get_image_epoch(j) if epoch == 0.0: epoch = float(os.stat(self._imageset.get_path(j-images[0])).st_mtime) self._epoch_to_image[epoch] = j self._image_to_epoch[j] = epoch epochs = self._epoch_to_image.keys() Debug.write('Exposure epoch for sweep %s: %d %d' % \ (self._template, min(epochs), max(epochs))) self._input_imageset = copy.deepcopy(self._imageset) # + get the lattice - can this be a pointer, so that when # this object updates lattice it is globally-for-this-crystal # updated? The lattice included directly in here includes an # exact unit cell for data reduction, the crystal lattice # contains an approximate unit cell which should be # from the unit cells from all sweeps contained in the # XCrystal. FIXME should I be using a LatticeInfo object # in here? See what the Indexer interface produces. ALT: # just provide an Indexer implementation "hook". # See Headnote 001 above. See also _get_indexer, # _get_integrater below. self._indexer = None self._refiner = None self._integrater = None # I don't need this - it is equivalent to self.getWavelength( # ).getCrystal().getLattice() # self._crystal_lattice = None # this means that this module will have to present largely the # same interface as Indexer and Integrater so that the calls # can be appropriately forwarded. # finally configure the beam if set if beam is not None: from dxtbx.model.detector_helpers import set_mosflm_beam_centre try: set_mosflm_beam_centre(self.get_imageset().get_detector(), self.get_imageset().get_beam(), beam) except AssertionError, e: Debug.write('Error setting mosflm beam centre: %s' % e)