Пример #1
0
  def onRun(self, e):
    # Run full processing

    self.init_settings()
    if self.sanity_check():
      prime_phil = master_phil.format(python_object=self.pparams)

      with misc.Capturing() as output:
        prime_phil.show()

      txt_out = ''
      for one_output in output:
        txt_out += one_output + '\n'

      source_dir = os.path.dirname(self.out_dir)
      prime_file = os.path.join(source_dir, self.prime_filename)
      out_file = os.path.join(self.out_dir, 'stdout.log')
      with open(prime_file, 'w') as pf:
        pf.write(txt_out)

      self.prime_run_window = frm.PRIMERunWindow(self, -1,
                                                 title='PRIME Output',
                                                 params=self.pparams,
                                                 prime_file=prime_file)
      self.prime_run_window.prev_pids = easy_run.fully_buffered('pgrep -u {} {}'
                                        ''.format(user, python)).stdout_lines
      self.prime_run_window.Show(True)
Пример #2
0
    def load_image(self):
        """ Reads raw image file and extracts data for conversion into pickle
        format. Also estimates gain if turned on."""
        # Load raw image or image pickle

        try:
            with misc.Capturing() as junk_output:
                loaded_img = dxtbx.load(self.raw_img)
        except IOError, e:
            loaded_img = None
            pass
Пример #3
0
    def __init__(self,
                 source_image,
                 object_folder,
                 final_folder,
                 final_filename,
                 final,
                 logfile,
                 gain=0.32,
                 params=None):
        '''Initialise the script.'''
        from dxtbx.datablock import DataBlockFactory

        self.params = params

        # Read settings from the DIALS target (.phil) file
        # If none is provided, use default settings (and may God have mercy)
        if self.params.dials.target != None:
            with open(self.params.dials.target, 'r') as settings_file:
                settings_file_contents = settings_file.read()
            settings = parse(settings_file_contents)
            current_phil = phil_scope.fetch(sources=[settings])
            self.phil = current_phil.extract()
        else:
            self.phil = phil_scope.extract()

    # Set general file-handling settings
        file_basename = os.path.basename(source_image).split('.')[0]
        self.phil.output.datablock_filename = "{}/{}.json".format(
            object_folder, file_basename)
        self.phil.output.indexed_filename = "{}/{}_indexed.pickle".format(
            object_folder, file_basename)
        self.phil.output.strong_filename = "{}/{}_strong.pickle".format(
            object_folder, file_basename)
        self.phil.output.refined_experiments_filename = "{}/{}_refined_experiments.json".format(
            object_folder, file_basename)
        self.phil.output.integrated_filename = "{}/{}_integrated.pickle".format(
            object_folder, file_basename)
        self.phil.output.profile_filename = "{}/{}_profile.phil".format(
            object_folder, file_basename)
        self.phil.output.integration_pickle = final_filename
        self.int_log = logfile  #"{}/int_{}.log".format(final_folder, file_basename)

        self.img = [source_image]
        self.obj_base = object_folder
        self.gain = gain
        self.fail = None
        self.frame = None
        self.final = final
        self.final['final'] = final_filename
        with misc.Capturing() as junk_output:
            self.datablock = DataBlockFactory.from_filenames(self.img)[0]
        self.obj_filename = "int_{}".format(os.path.basename(self.img[0]))
Пример #4
0
    def regenerate_params(self, phil=None):

        if phil is not None:
            current_phil = master_phil.format(python_object=phil)
        else:
            current_phil = master_phil

        # Generate Python object and text of parameters
        self.pparams = current_phil.extract()
        with misc.Capturing() as txt_output:
            current_phil.show()
        self.phil_string = ''
        for one_output in txt_output:
            self.phil_string += one_output + '\n'
Пример #5
0
  def reset_settings(self):
    self.pparams = master_phil.extract()
    self.input_window.inp_box.delete_all()
    self.input_window.out_box.reset_default()
    self.input_window.project_title.reset_default()
    self.input_window.opt_chk_useref.SetValue(False)
    self.input_window.opt_spc_nproc.reset_default()
    self.input_window.opt_spc_nres.reset_default()

    # Generate Python object and text of parameters
    with misc.Capturing() as txt_output:
      master_phil.show()
    self.phil_string = ''
    for one_output in txt_output:
      self.phil_string += one_output + '\n'
Пример #6
0
    def onOutputScript(self, e):

        # Determine param filepath
        save_dlg = wx.FileDialog(self,
                                 message="Save IOTA Script",
                                 defaultDir=os.curdir,
                                 defaultFile="*.param",
                                 wildcard="*",
                                 style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if save_dlg.ShowModal() == wx.ID_OK:
            script_filepath = save_dlg.GetPath()

            # Finalize settings
            self.init_settings()
            self.gparams = self.iota_phil.extract()

            # Save target PHIL file, if a PHIL script exists
            if self.target_phil is not None:
                if self.gparams.advanced.integrate_with == 'cctbx':
                    phil_filepath = os.path.join(
                        os.path.dirname(script_filepath), 'cctbx.phil')
                    self.gparams.cctbx.target = phil_filepath
                if self.gparams.advanced.integrate_with == 'dials':
                    phil_filepath = os.path.join(
                        os.path.dirname(script_filepath), 'dials.phil')
                    self.gparams.dials.target = phil_filepath

            # Generate text of params
            final_phil = self.iota_phil.format(python_object=self.gparams)

            test_params = final_phil.extract()

            with misc.Capturing() as txt_output:
                final_phil.show()
            txt_out = ''
            for one_output in txt_output:
                txt_out += one_output + '\n'

            # Save files
            with open(script_filepath, 'w') as param_file:
                param_file.write(txt_out)

            if self.target_phil is not None:
                with open(phil_filepath, 'w') as phil_file:
                    phil_file.write(self.target_phil)
Пример #7
0
    def run_distl(self, params):
        """ Performs a quick DISTL spotfinding and returns Bragg spots information.
    """
        from spotfinder.applications import signal_strength

        # run DISTL spotfinder
        with misc.Capturing() as distl_output:
            Org = signal_strength.run_signal_strength(params)

        # Extract relevant spotfinding info
        for frame in Org.S.images.keys():
            saturation = Org.Files.imageindex(frame).saturation
            Bragg_spots = [
                flex.sum(spot.wts)
                for spot in Org.S.images[frame]['inlier_spots']
            ]

        return Bragg_spots
Пример #8
0
    def __init__(self, img, gain, params, center_intensity=0):
        """ Initialization and data read-in
    """
        self.gain = gain
        self.params = params

        # Read settings from the DIALS target (.phil) file
        # If none is provided, use default settings (and may God have mercy)
        if self.params.dials.target != None:
            with open(self.params.dials.target, 'r') as settings_file:
                settings_file_contents = settings_file.read()
            settings = parse(settings_file_contents)
            current_phil = phil_scope.fetch(sources=[settings])
            self.phil = current_phil.extract()
        else:
            self.phil = phil_scope.extract()

        # Modify settings
        self.phil.output.strong_filename = None
        self.processor = IOTADialsProcessor(params=self.phil)

        # Set customized parameters
        beamX = self.params.image_conversion.beam_center.x
        beamY = self.params.image_conversion.beam_center.y
        if beamX != 0 or beamY != 0:
            self.phil.geometry.detector.slow_fast_beam_centre = '{} {}'.format(
                beamY, beamX)
        if self.params.image_conversion.distance != 0:
            self.phil.geometry.detector.distance = self.params.image_conversion.distance
        if self.params.advanced.estimate_gain:
            self.phil.spotfinder.threshold.dispersion.gain = gain
        if self.params.image_conversion.mask is not None:
            self.phil.spotfinder.lookup.mask = self.params.image_conversion.mask
            self.phil.integration.lookup.mask = self.params.image_conversion.mask

        if self.params.dials.auto_threshold:
            threshold = int(center_intensity)
            self.phil.spotfinder.threshold.dispersion.global_threshold = threshold

        # Convert raw image into single-image datablock
        with misc.Capturing() as junk_output:
            self.datablock = DataBlockFactory.from_filenames([img])[0]
Пример #9
0
    def cluster_unit_cells(self):
        input = []
        for item in self.spotfinding_info:
            if item[4] is not None:
                try:
                    info_line = [float(i) for i in item[4]]
                    info_line.append(item[3])
                    input.append(info_line)
                except ValueError:
                    pass

        with misc.Capturing() as junk_output:
            try:
                ucs = Cluster.from_iterable(iterable=input)
                clusters, _ = ucs.ab_cluster(5000,
                                             log=False,
                                             write_file_lists=False,
                                             schnell=True,
                                             doplot=False)
            except Exception, e:
                clusters = []
Пример #10
0
    def run(self):

        log_entry = ['\n']
        with misc.Capturing() as output:
            e = None
            try:
                print "{:-^100}\n".format(" SPOTFINDING: ")
                self.find_spots()
                print "{:-^100}\n\n".format(" FOUND {} SPOTS: ".format(
                    len(self.observed)))
            except Exception, e:
                if hasattr(e, "classname"):
                    print e.classname, "for %s:" % self.img[0],
                    error_message = "{}: {}".format(
                        e.classname, e[0].replace('\n', ' ')[:50])
                else:
                    print "Spotfinding error for %s:" % self.img[0],
                    error_message = "{}".format(str(e).replace('\n', ' ')[:50])
                print e
                self.fail = 'failed spotfinding'

            if self.fail == None:
                try:
                    print "{:-^100}\n".format(" INDEXING: ")
                    self.index()
                    print "{:-^100}\n\n".format(
                        " USED {} INDEXED REFLECTIONS: ".format(
                            len(self.indexed)))
                except Exception, e:
                    if hasattr(e, "classname"):
                        print e.classname, "for %s:" % self.img[0],
                        error_message = "{}: {}".format(
                            e.classname, e[0].replace('\n', ' ')[:50])
                    else:
                        print "Indexing error for %s:" % self.img[0],
                        error_message = "{}".format(
                            str(e).replace('\n', ' ')[:50])
                    print e
                    self.fail = 'failed indexing'
Пример #11
0
    def __init__(self, img, gain, params):
        """ Initialization and data read-in
    """
        from dxtbx.datablock import DataBlockFactory

        self.gain = gain
        self.params = params

        # Read settings from the DIALS target (.phil) file
        # If none is provided, use default settings (and may God have mercy)
        if self.params.dials.target != None:
            with open(self.params.dials.target, 'r') as settings_file:
                settings_file_contents = settings_file.read()
            settings = parse(settings_file_contents)
            current_phil = phil_scope.fetch(sources=[settings])
            self.phil = current_phil.extract()
        else:
            self.phil = phil_scope.extract()

        # Convert raw image into single-image datablock
        with misc.Capturing() as junk_output:
            self.datablock = DataBlockFactory.from_filenames([img])[0]
Пример #12
0
    def onSaveScript(self, e):
        self.init_settings()

        # Generate text of params
        final_phil = master_phil.format(python_object=self.pparams)
        with misc.Capturing() as txt_output:
            final_phil.show()
        txt_out = ''
        for one_output in txt_output:
            txt_out += one_output + '\n'

        # Save param file
        save_dlg = wx.FileDialog(self,
                                 message="Save PRIME Script",
                                 defaultDir=os.curdir,
                                 defaultFile="*.phil",
                                 wildcard="*.phil",
                                 style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if save_dlg.ShowModal() == wx.ID_OK:
            with open(save_dlg.GetPath(), 'w') as savefile:
                savefile.write(txt_out)

        save_dlg.Destroy()
Пример #13
0
class SingleImage(object):
    def __init__(self, img, init, verbose=True, imported_grid=None):
        """ Constructor for the SingleImage object using a raw image file or pickle
    """

        # Initialize parameters
        self.params = init.params
        self.args = init.args
        self.user_id = init.user_id
        self.raw_img = img[2]
        self.conv_img = img[2]
        self.img_index = img[0]
        self.center_int = 0
        self.status = None
        self.fail = None
        self.final = None
        self.log_info = []
        self.gs_results = []
        self.main_log = init.logfile
        self.verbose = verbose
        self.hmed = self.params.cctbx.grid_search.height_median
        self.amed = self.params.cctbx.grid_search.area_median

        self.input_base = init.input_base
        self.conv_base = init.conv_base
        self.int_base = init.int_base
        self.obj_base = init.obj_base
        self.fin_base = init.fin_base
        self.viz_base = init.viz_base
        self.log_base = init.log_base
        self.tmp_base = init.tmp_base
        self.abort_file = os.path.join(self.int_base, '.abort.tmp')

        self.obj_path = None
        self.obj_file = None
        self.fin_path = None
        self.fin_file = None
        self.viz_path = None

# ============================== SELECTION-ONLY FUNCTIONS ============================== #

    def import_int_file(self, init):
        """ Replaces path settings in imported image object with new settings
        NEED TO RE-DO LATER """

        if os.path.isfile(self.abort_file):
            self.fail = 'aborted'
            return self

        # Generate paths to output files
        self.params = init.params
        self.main_log = init.logfile
        self.input_base = init.input_base
        self.conv_base = init.conv_base
        self.int_base = init.int_base
        self.obj_base = init.obj_base
        self.fin_base = init.fin_base
        self.log_base = init.log_base
        self.viz_base = init.viz_base
        self.obj_path = misc.make_image_path(self.conv_img, self.input_base,
                                             self.obj_base)
        self.obj_file = os.path.abspath(
            os.path.join(
                self.obj_path,
                os.path.basename(self.conv_img).split('.')[0] + ".int"))
        self.fin_path = misc.make_image_path(self.conv_img, self.input_base,
                                             self.fin_base)
        self.log_path = misc.make_image_path(self.conv_img, self.input_base,
                                             self.log_base)
        self.fin_file = os.path.abspath(
            os.path.join(
                self.fin_path,
                os.path.basename(self.conv_img).split('.')[0] + "_int.pickle"))
        self.final['final'] = self.fin_file
        self.final['img'] = self.conv_img
        self.viz_path = misc.make_image_path(self.conv_img, self.input_base,
                                             self.viz_base)
        self.viz_file = os.path.join(
            self.viz_path,
            os.path.basename(self.conv_img).split('.')[0] + "_int.png")

        # Create actual folders (if necessary)
        try:
            if not os.path.isdir(self.obj_path):
                os.makedirs(self.obj_path)
            if not os.path.isdir(self.fin_path):
                os.makedirs(self.fin_path)
            if not os.path.isdir(self.viz_path):
                os.makedirs(self.viz_path)
        except OSError:
            pass

        # Grid search / integration log file
        self.int_log = os.path.join(
            self.log_path,
            os.path.basename(self.conv_img).split('.')[0] + '.tmp')

        # Reset status to 'grid search' to pick up at selection (if no fail)
        if self.fail == None:
            self.status = 'bypass grid search'

        return self

    def determine_gs_result_file(self):
        """ For 'selection-only' cctbx.xfel runs, determine where the image objects are """
        if self.params.cctbx.selection.select_only.grid_search_path != None:
            obj_path = os.path.abspath(
                self.params.cctbx.selection.select_only.grid_search_path)
        else:
            run_number = int(os.path.basename(self.int_base)) - 1
            obj_path = "{}/integration/{:03d}/image_objects"\
                      "".format(os.path.abspath(os.curdir), run_number)
        gs_result_file = os.path.join(obj_path,
                                      os.path.basename(self.obj_file))
        return gs_result_file

# =============================== IMAGE IMPORT FUNCTIONS =============================== #

    def load_image(self):
        """ Reads raw image file and extracts data for conversion into pickle
        format. Also estimates gain if turned on."""
        # Load raw image or image pickle

        try:
            with misc.Capturing() as junk_output:
                loaded_img = dxtbx.load(self.raw_img)
        except Exception, e:
            print 'IOTA IMPORT ERROR:', e
            loaded_img = None
            pass

        # Extract image information
        if loaded_img is not None:
            raw_data = loaded_img.get_raw_data()
            detector = loaded_img.get_detector()[0]
            beam = loaded_img.get_beam()
            scan = loaded_img.get_scan()
            distance = detector.get_distance()
            pixel_size = detector.get_pixel_size()[0]
            overload = detector.get_trusted_range()[1]
            wavelength = beam.get_wavelength()
            beam_x = detector.get_beam_centre(beam.get_s0())[0]
            beam_y = detector.get_beam_centre(beam.get_s0())[1]

            if scan is None:
                timestamp = None
                img_type = 'pickle'
            else:
                img_type = 'raw'
                msec, sec = math.modf(scan.get_epochs()[0])
                timestamp = evt_timestamp((sec, msec))

            # Assemble datapack
            data = dpack(data=raw_data,
                         distance=distance,
                         pixel_size=pixel_size,
                         wavelength=wavelength,
                         beam_center_x=beam_x,
                         beam_center_y=beam_y,
                         ccd_image_saturation=overload,
                         saturated_value=overload,
                         timestamp=timestamp)

            if scan is not None:
                osc_start, osc_range = scan.get_oscillation()
                if osc_start != osc_range:
                    data['OSC_START'] = 0  #osc_start
                    data['OSC_RANGE'] = 0  #osc_start
                    data['TIME'] = scan.get_exposure_times()[0]
        else:
            data = None
            img_type = 'not imported'

        # Estimate gain (or set gain to 1.00 if cannot calculate)
        # Cribbed from estimate_gain.py by Richard Gildea
        if self.params.advanced.estimate_gain:
            from dxtbx.datablock import DataBlockFactory
            from dials.command_line.estimate_gain import estimate_gain
            with misc.Capturing() as junk_output:
                try:
                    datablock = DataBlockFactory.from_filenames([self.raw_img
                                                                 ])[0]
                    imageset = datablock.extract_imagesets()[0]
                    self.gain = estimate_gain(imageset)
                except Exception, e:
                    self.gain = 1.0
 def generate_phil_string(self, current_phil):
     with misc.Capturing() as txt_output:
         current_phil.show()
     self.phil_string = ''
     for one_output in txt_output:
         self.phil_string += one_output + '\n'
Пример #15
0
    def run(self, gparams, target_phil=None, list_file=None):
        ''' Run initialization for IOTA GUI

        gparams = IOTA parameters from the GUI elements in PHIL format
        gtxt = text version of gparams
        list_file = if "Write Input List" button pressed, specifies name
                    of list file
    '''

        self.params = gparams
        self.target_phil = target_phil

        # If input list for some reason isn't transmitted from main window, make it
        if self.input_list is None:
            self.input_list = self.make_input_list()

        # Select range of images if turned on
        if self.params.advanced.image_range.flag_on:
            self.input_list = self.select_image_range(self.input_list)

        # Select a random subset of images if turned on
        if self.params.advanced.random_sample.flag_on and \
          self.params.advanced.random_sample.number < len(self.input_list):
            self.input_list = self.select_random_subset(self.input_list)

        # Check for data not found
        if len(self.input_list) == 0:
            wx.MessageBox('ERROR: Data Not Found!', 'ERROR',
                          wx.OK | wx.ICON_ERROR)
            return False

        # If list-only option selected, output list only
        if list_file != None:
            with open(list_file, "w") as lf:
                for i, input_file in enumerate(self.input_list, 1):
                    lf.write('{}\n'.format(input_file))
            return True

        # Run the sanity check procedure
        if not self.sanity_check():
            return False

        # If fewer images than requested processors are supplied, set the number of
        # processors to the number of images
        if self.params.mp_method == 'multiprocessing':
            if self.params.n_processors > len(self.input_list):
                self.params.n_processors = len(self.input_list)

        # Generate base folder paths
        self.conv_base = misc.set_base_dir('converted_pickles',
                                           out_dir=self.params.output)
        self.int_base = misc.set_base_dir('integration',
                                          out_dir=self.params.output)
        self.obj_base = os.path.join(self.int_base, 'image_objects')
        self.fin_base = os.path.join(self.int_base, 'final')
        self.log_base = os.path.join(self.int_base, 'logs')
        self.viz_base = os.path.join(self.int_base, 'visualization')
        if str(self.params.advanced.temporary_output_folder).lower() in (
                'none', ''):
            self.tmp_base = os.path.join(self.int_base, 'tmp')
        else:
            self.tmp_base = os.path.join(
                self.params.advanced.temporary_output_folder)

        # Generate base folders
        os.makedirs(self.int_base)
        os.makedirs(self.obj_base)
        os.makedirs(self.fin_base)
        os.makedirs(self.log_base)
        try:
            if not os.path.isdir(self.tmp_base):
                os.makedirs(self.tmp_base)
        except OSError:
            pass

        # Determine input base
        common_pfx = os.path.abspath(
            os.path.dirname(os.path.commonprefix(self.input_list)))
        if len(self.params.input) == 1:
            self.input_base = os.path.commonprefix(
                [self.params.input[0], common_pfx])
        else:
            self.input_base = common_pfx

        # Initialize main log
        self.logfile = os.path.abspath(os.path.join(self.int_base, 'iota.log'))

        # Write target file and record its location in params
        local_target_file = os.path.join(self.int_base, 'target.phil')
        if type(self.target_phil) == list:
            self.target_phil = '\n'.join(self.target_phil)
        with open(local_target_file, 'w') as tf:
            tf.write(self.target_phil)

        if self.params.advanced.integrate_with == 'cctbx':
            self.params.cctbx.target = local_target_file
        elif self.params.advanced.integrate_with == 'dials':
            self.params.dials.target = local_target_file

        # Collect final params and convert to PHIL object
        final_phil = inp.master_phil.format(python_object=self.params)

        # Generate text of params
        with misc.Capturing() as txt_output:
            final_phil.show()
        self.txt_out = ''
        for one_output in txt_output:
            self.txt_out += one_output + '\n'

        # Log starting info
        misc.main_log(self.logfile, '{:=^80} \n'.format(' IOTA MAIN LOG '))
        misc.main_log(self.logfile,
                      '{:-^80} \n'.format(' SETTINGS FOR THIS RUN '))
        misc.main_log(self.logfile, self.txt_out)

        # Log cctbx.xfel / DIALS settings
        misc.main_log(
            self.logfile, '{:-^80} \n\n'
            ''.format(' TARGET FILE ({}) CONTENTS '
                      ''.format(local_target_file)))
        misc.main_log(self.logfile, self.target_phil)

        return True
Пример #16
0
    def integrate(self, grid_point):
        """ Runs the integration module in cctbx.xfel; used by either grid-search or
        final integration function. """

        self.s = grid_point['sih']
        self.h = grid_point['sph']
        self.a = grid_point['spa']

        args = self.args

        # Generate advanced arguments (and PDF subfolder)
        if self.charts and self.tag == 'grid search':
            filename = os.path.basename(self.img).split('.')[0]
            pdf_folder = os.path.join(self.viz, 'pdf_{}/s{}_h{}_a{}'\
                         ''.format(filename, self.s, self.h, self.a))
            if not os.path.exists(pdf_folder):
                os.makedirs(pdf_folder)
            self.args.extend([
                "integration.enable_residual_map=True",
                "integration.enable_residual_scatter=True",
                "integration.mosaic.enable_AD14F7B=True",
                "integration.graphics_backend=pdf",
                "integration.pdf_output_dir={}".format(pdf_folder)
            ])
        if self.tag == 'integrate':
            args.append("indexing.completeness_pickle={}".format(self.out_img))

        #Actually run integration using iota.bulletproof
        error_message = ''
        with misc.Capturing() as index_log:
            arguments = [
                "distl.minimum_signal_height={}".format(
                    str(self.s)), "distl.minimum_spot_height={}".format(
                        str(self.h)), "distl.minimum_spot_area={}".format(
                            str(self.a)), "indexing.open_wx_viewer=False"
            ] + list(args[1:])

            tmppath = os.path.join(self.tmp_base,
                                   str(uuid.uuid4()) + ".pickle")
            assert not os.path.exists(tmppath)

            # invoke the indexer in a way that will protect iota from any crashes
            command = "iota.bulletproof {} {} {}" \
                      "".format(tmppath, self.target, " ".join(arguments))
            try:
                easy_run.fully_buffered(command,
                                        join_stdout_stderr=True).show_stdout()
                if not os.path.exists(tmppath):
                    print tmppath
                    print command
                    raise Exception("Indexing failed for an unknown reason")

                # iota.bulletproof saves the needed results from indexing in a tmp file
                result = easy_pickle.load(tmppath)
                os.remove(tmppath)
                if isinstance(result, str):
                    raise Exception(result)
                else:
                    int_final = result

            except Exception, e:
                int_final = None
                if hasattr(e, "classname"):
                    print e.classname, "for %s:" % self.img,
                    error_message = "{}: {}".format(
                        e.classname, e[0].replace('\n', ' ')[:50])
                else:
                    print "Integration error for %s:" % self.img,
                    error_message = "{}".format(str(e).replace('\n', ' ')[:50])
                print e
Пример #17
0
    def run(self):

        self.processor = IOTADialsProcessor(params=self.phil)

        log_entry = ['\n']
        with misc.Capturing() as output:
            e = None
            try:
                print "{:-^100}\n".format(" SPOTFINDING: ")
                self.find_spots()
                print "{:-^100}\n\n".format(" FOUND {} SPOTS: ".format(
                    len(self.observed)))
            except Exception as e:
                if hasattr(e, "classname"):
                    print e.classname, "for %s:" % self.img[0],
                    error_message = "{}: {}".format(
                        e.classname, e[0].replace('\n', ' ')[:50])
                else:
                    print "Spotfinding error for %s:" % self.img[0],
                    error_message = "{}".format(str(e).replace('\n', ' ')[:50])
                print error_message
                self.fail = 'failed spotfinding'

            if self.fail == None:
                try:
                    print "{:-^100}\n".format(" INDEXING: ")
                    self.index()
                    if self.indexed is not None:
                        print "{:-^100}\n\n".format(
                            " USED {} INDEXED REFLECTIONS: "
                            "".format(len(self.indexed)))
                except Exception as e:
                    if hasattr(e, "classname"):
                        error_message = "{}: {}".format(
                            e.classname, e[0].replace('\n', ' ')[:50])
                    else:
                        print "Indexing error for %s:" % self.img[0],
                        error_message = "{}".format(
                            str(e).replace('\n', ' ')[:50])
                    print error_message
                    self.fail = 'failed indexing'

            if (self.fail is None
                    and self.phil.indexing.known_symmetry.space_group is None
                    and self.params.dials.determine_sg_and_reindex):
                try:
                    print "{:-^100}\n".format(" DETERMINING SPACE GROUP : ")
                    self.refine_bravais_settings_and_reindex()
                    lat = self.experiments[0].crystal.get_space_group().info()
                    sg = str(lat).replace(' ', '')
                    if sg != 'P1':
                        print "{:-^100}\n".format(
                            " REINDEXED TO SPACE GROUP {} ".format(sg))
                    else:
                        print "{:-^100}\n".format(
                            " RETAINED TRICLINIC (P1) SYMMETRY ")
                except Exception as e:
                    print "Bravais / Reindexing Error: ", e

            if self.fail == None:
                try:
                    self.refine()
                    print "{:-^100}\n".format(" INTEGRATING: ")
                    self.integrate()
                    print "{:-^100}\n\n".format(
                        " FINAL {} INTEGRATED REFLECTIONS "
                        "".format(len(self.integrated)))
                except Exception as e:
                    if hasattr(e, "classname"):
                        print e.classname, "for %s:" % self.img[0],
                        error_message = "{}: {}".format(
                            e.classname, e[0].replace('\n', ' ')[:50])
                    else:
                        print "Integration error for %s:" % self.img[0],
                        error_message = "{}".format(
                            str(e).replace('\n', ' ')[:50])
                    print error_message
                    self.fail = 'failed integration'

        if self.fail == None and self.params.dials.filter.flag_on:
            selector = Selector(
                frame=self.frame,
                uc_tol=self.params.dials.filter.target_uc_tolerance,
                pg=self.params.dials.filter.target_pointgroup,
                uc=self.params.dials.filter.target_unit_cell,
                min_ref=self.params.dials.filter.min_reflections,
                min_res=self.params.dials.filter.min_resolution)
            self.fail = selector.filter()

        with open(self.int_log, 'w') as tf:
            for i in output:
                if 'cxi_version' not in i:
                    tf.write('\n{}'.format(i))

        if self.fail == None:
            # Collect information
            obs = self.frame['observations'][0]
            Bravais_lattice = self.frame['pointgroup']
            cell = obs.unit_cell().parameters()
            lres, hres = obs.d_max_min()

            # Calculate number of spots w/ high I / sigmaI
            Is = obs.data()
            sigmas = obs.sigmas()
            I_over_sigI = Is / sigmas
            spots = len(Is)
            strong_spots = len([
                i for i in I_over_sigI
                if i >= self.params.cctbx.selection.min_sigma
            ])

            # Mosaicity parameters
            mosaicity = round(
                (self.frame.get('ML_half_mosaicity_deg', [0])[0]), 6)
            dom_size = self.frame.get('ML_domain_size_ang', [0])[0]
            ewald_proximal_volume = self.frame.get('ewald_proximal_volume',
                                                   [0])[0]

            # Assemble output for log file and/or integration result file
            p_cell = "{:>6.2f}, {:>6.2f}, {:>6.2f}, {:>6.2f}, {:>6.2f}, {:>6.2f}"\
                   "".format(cell[0], cell[1], cell[2], cell[3], cell[4], cell[5])

            int_status = 'RES: {:<4.2f}  NSREF: {:<4}  SG: {:<5}  CELL: {}'\
                         ''.format(hres, strong_spots, Bravais_lattice, p_cell)

            int_results = {
                'sg': Bravais_lattice,
                'a': cell[0],
                'b': cell[1],
                'c': cell[2],
                'alpha': cell[3],
                'beta': cell[4],
                'gamma': cell[5],
                'wavelength': self.frame['wavelength'],
                'distance': self.frame['distance'],
                'beamX': self.frame['xbeam'],
                'beamY': self.frame['ybeam'],
                'strong': strong_spots,
                'res': hres,
                'lres': lres,
                'mos': mosaicity,
                'epv': ewald_proximal_volume,
                'info': int_status,
                'ok': True
            }

            # Update final entry with integration results
            self.final.update(int_results)

            # Generate log summary of integration results
            img_filename = os.path.basename(self.img[0])
            log_entry.append('DIALS integration:')
            log_entry.append('{:<{width}} --->  {}'.format(
                img_filename, int_status, width=len(img_filename) + 2))

        else:
            # Generate log summary of integration results
            if 'spotfinding' in self.fail:
                step_id = 'SPOTFINDING'
            elif 'indexing' in self.fail:
                step_id = 'INDEXING'
            elif 'integration' in self.fail:
                step_id = 'INTEGRATION'
            elif 'filter' in self.fail:
                step_id = 'FILTER'
            log_entry.append('\n {} FAILED - {}'.format(step_id, e))
            int_status = 'not integrated -- {}'.format(e)
            int_results = {'info': int_status}
            self.final['final'] = None

        log_entry = "\n".join(log_entry)

        return self.fail, self.final, log_entry
Пример #18
0
  def load_image(self):
    """ Reads raw image file and extracts data for conversion into pickle
        format. Also estimates gain if turned on."""
    # Load raw image or image pickle

    try:
      with misc.Capturing() as junk_output:
        loaded_img = dxtbx.load(self.raw_img)
    except Exception as e:
      print 'IOTA IMPORT ERROR:', e
      loaded_img = None
      pass

    # Extract image information
    if loaded_img is not None:
      raw_data   = loaded_img.get_raw_data()
      detector   = loaded_img.get_detector()[0]
      beam       = loaded_img.get_beam()
      scan       = loaded_img.get_scan()
      distance   = detector.get_distance()
      pixel_size = detector.get_pixel_size()[0]
      overload   = detector.get_trusted_range()[1]
      wavelength = beam.get_wavelength()
      beam_x     = detector.get_beam_centre(beam.get_s0())[0]
      beam_y     = detector.get_beam_centre(beam.get_s0())[1]

      if scan is None:
        timestamp = None
        img_type = 'pickle'
      else:
        img_type = 'raw'
        msec, sec = math.modf(scan.get_epochs()[0])
        timestamp = evt_timestamp((sec,msec))

      # Assemble datapack
      data = dpack(data=raw_data,
                   distance=distance,
                   pixel_size=pixel_size,
                   wavelength=wavelength,
                   beam_center_x=beam_x,
                   beam_center_y=beam_y,
                   ccd_image_saturation=overload,
                   saturated_value=overload,
                   timestamp=timestamp
                   )

      if scan is not None:
        osc_start, osc_range = scan.get_oscillation()
        if osc_start != osc_range:
          data['OSC_START'] = 0 #osc_start
          data['OSC_RANGE'] = 0 #osc_start
          data['TIME'] = scan.get_exposure_times()[0]
    else:
      data = None
      img_type = 'not imported'

    # Estimate gain (or set gain to 1.00 if cannot calculate)
    # Cribbed from estimate_gain.py by Richard Gildea
    if self.params.advanced.estimate_gain:
      from dxtbx.datablock import DataBlockFactory
      from dials.command_line.estimate_gain import estimate_gain
      with misc.Capturing() as junk_output:
        try:
          datablock = DataBlockFactory.from_filenames([self.raw_img])[0]
          imageset = datablock.extract_imagesets()[0]
          self.gain = estimate_gain(imageset)
        except Exception as e:
          self.gain = 1.0
    else:
      self.gain = 1.0

    return data, img_type