示例#1
0
 def background(self, spotfinder):
     self.addColumn(
         'PxlBkgrd'
     )  # mean pixel background at center of windows in the shell
     self.PxlBkgrd.format = "%.1f"
     self.addColumn(
         'MnWndwSz'
     )  # mean size (in pixels) of the scanbox windows in the shell
     self.MnWndwSz.format = "%.0f"
     for irow in xrange(self.S_table_rows):
         self.PxlBkgrd[irow] = flex.double()
         self.MnWndwSz[irow] = flex.double()
     sortedidx = flex.sort_permutation(spotfinder.background_resolutions(),
                                       reverse=True)
     reverse_resolutions = spotfinder.background_resolutions().select(
         sortedidx)
     reverse_backgrounds = spotfinder.background_means().select(sortedidx)
     reverse_wndw_sz = spotfinder.background_wndw_sz().select(sortedidx)
     row = 0
     for x in xrange(len(reverse_resolutions)):
         while reverse_resolutions[x] < self.Limit[row]:
             row += 1
             if row >= self.S_table_rows: break
         if row >= self.S_table_rows: break
         self.PxlBkgrd[row].append(reverse_backgrounds[x])
         self.MnWndwSz[row].append(reverse_wndw_sz[x])
     for irow in xrange(self.S_table_rows):
         #print irow, len(self.PxlBkgrd[irow])
         #print list(self.PxlBkgrd[irow])
         #print list(self.PxlSigma[irow])
         if len(self.PxlBkgrd[irow]) == 0:
             self.PxlBkgrd[irow] = None
             continue  #No analysis without mean background
         self.PxlBkgrd[irow] = flex.mean(self.PxlBkgrd[irow])
         self.MnWndwSz[irow] = flex.mean(self.MnWndwSz[irow])
示例#2
0
 def background(self,spotfinder):
   self.addColumn('PxlBkgrd') # mean pixel background at center of windows in the shell
   self.PxlBkgrd.format = "%.1f"
   self.addColumn('MnWndwSz') # mean size (in pixels) of the scanbox windows in the shell
   self.MnWndwSz.format = "%.0f"
   for irow in xrange(self.S_table_rows):
     self.PxlBkgrd[irow] = flex.double()
     self.MnWndwSz[irow] = flex.double()
   sortedidx = flex.sort_permutation(spotfinder.background_resolutions(),reverse=True)
   reverse_resolutions = spotfinder.background_resolutions().select(sortedidx)
   reverse_backgrounds = spotfinder.background_means().select(sortedidx)
   reverse_wndw_sz = spotfinder.background_wndw_sz().select(sortedidx)
   row = 0
   for x in xrange(len(reverse_resolutions)):
     while reverse_resolutions[x] < self.Limit[row]:
       row += 1
       if row >= self.S_table_rows: break
     if row >= self.S_table_rows: break
     self.PxlBkgrd[row].append(reverse_backgrounds[x])
     self.MnWndwSz[row].append(reverse_wndw_sz[x])
   for irow in xrange(self.S_table_rows):
     #print irow, len(self.PxlBkgrd[irow])
     #print list(self.PxlBkgrd[irow])
     #print list(self.PxlSigma[irow])
     if len(self.PxlBkgrd[irow])==0: self.PxlBkgrd[irow]=None; continue #No analysis without mean background
     self.PxlBkgrd[irow] = flex.mean(self.PxlBkgrd[irow])
     self.MnWndwSz[irow] = flex.mean(self.MnWndwSz[irow])
示例#3
0
    def sigma_analysis(self):
        #assumes that self.total_signal() and self.background() have already been called.
        self.addColumn('MeanIsigI',
                       0)  #mean I over sig(I) for spots within the shell
        self.MeanIsigI.format = "%.3f"
        index = 0
        for row in xrange(self.S_table_rows):
            if self.PxlBkgrd[row] == None: continue
            IsigI_values = flex.double()
            for idx in xrange(self.Population[row]):
                # Use International Tables Vol F (2001) equation 11.2.5.9 (p. 214)
                I_s = flex.sum(self.persist_fstats.master[
                    self.persist_indices[index]].wts)
                I_bg = flex.sum(self.persist_fstats.master[
                    self.persist_indices[index]].bkg)
                m_sz = len(self.persist_fstats.master[
                    self.persist_indices[index]].wts)
                n_sz = self.MnWndwSz[row]
                gain = 1.00

                spot_variance = gain * (I_s + I_bg + (m_sz * m_sz) *
                                        (1. / n_sz) * self.PxlBkgrd[row])

                IsigI_values.append(I_s / math.sqrt(spot_variance))

                index += 1
            if len(IsigI_values) > 0:
                self.MeanIsigI[row] = flex.mean(IsigI_values)
示例#4
0
 def get_resolution_inspection(self):
     all_frames = self.images.keys()
     all_resolutions = flex.double(
         [self.images[f]['resolution'] for f in all_frames])
     ave_resolution = flex.mean(all_resolutions)
     self.pd['resolution_inspection'] = '%f' % (ave_resolution)
     return self.pd['resolution_inspection']
示例#5
0
 def total_signal(self, fstats, indices):
     #for index in indices:
     #  print index,fstats.master[index].intensity(),flex.sum(fstats.master[index].wts)
     self.addColumn('Integrated',
                    0)  #total integrated signal within the shell
     self.Integrated.format = "%.0f"
     self.addColumn('MeanI', 0)  #mean integrated signal within the shell
     self.MeanI.format = "%.0f"
     self.addColumn('MeanBkg',
                    0)  #mean integrated background within the shell
     self.MeanBkg.format = "%.1f"
     self.addColumn('MeanSz',
                    0)  #mean pixel count for spots within the shell
     self.MeanSz.format = "%.0f"
     self.addColumn('MnEccen', 0)  #mean eccentricity spots within the shell
     self.MnEccen.format = "%.3f"
     self.addColumn('MnSkew', 0)  #mean eccentricity spots within the shell
     self.MnSkew.format = "%.3f"
     index = 0
     for row in xrange(self.S_table_rows):
         row_values = flex.double()
         bkg_values = flex.double()
         sz_values = flex.double()
         eccen_values = flex.double()
         skew_values = flex.double()
         for idx in xrange(self.Population[row]):
             spot_signal = flex.sum(fstats.master[indices[index]].wts)
             bkg_signal = flex.sum(fstats.master[indices[index]].bkg)
             spot_sz = len(fstats.master[indices[index]].wts)
             spot_eccen = fstats.master[indices[index]].model_eccentricity()
             spot_skew = fstats.master[indices[index]].skewness()
             self.Integrated[row] += spot_signal
             row_values.append(spot_signal)
             bkg_values.append(bkg_signal)
             sz_values.append(spot_sz)
             eccen_values.append(spot_eccen)
             skew_values.append(spot_skew)
             index += 1
         if len(row_values) > 0:
             self.MeanI[row] = flex.mean(row_values)
             self.MeanBkg[row] = flex.mean(bkg_values)
             self.MeanSz[row] = flex.mean(sz_values)
             self.MnEccen[row] = flex.mean(eccen_values)
             self.MnSkew[row] = flex.mean(skew_values)
     self.persist_fstats = fstats
     self.persist_indices = indices
示例#6
0
 def total_signal(self,fstats,indices):
   #for index in indices:
   #  print index,fstats.master[index].intensity(),flex.sum(fstats.master[index].wts)
   self.addColumn('Integrated',0) #total integrated signal within the shell
   self.Integrated.format = "%.0f"
   self.addColumn('MeanI',0) #mean integrated signal within the shell
   self.MeanI.format = "%.0f"
   self.addColumn('MeanBkg',0) #mean integrated background within the shell
   self.MeanBkg.format = "%.1f"
   self.addColumn('MeanSz',0) #mean pixel count for spots within the shell
   self.MeanSz.format = "%.0f"
   self.addColumn('MnEccen',0) #mean eccentricity spots within the shell
   self.MnEccen.format = "%.3f"
   self.addColumn('MnSkew',0) #mean eccentricity spots within the shell
   self.MnSkew.format = "%.3f"
   index=0
   for row in xrange(self.S_table_rows):
     row_values = flex.double()
     bkg_values = flex.double()
     sz_values = flex.double()
     eccen_values = flex.double()
     skew_values = flex.double()
     for idx in xrange(self.Population[row]):
       spot_signal = flex.sum(fstats.master[indices[index]].wts)
       bkg_signal = flex.sum(fstats.master[indices[index]].bkg)
       spot_sz = len(fstats.master[indices[index]].wts)
       spot_eccen = fstats.master[indices[index]].model_eccentricity()
       spot_skew = fstats.master[indices[index]].skewness()
       self.Integrated[row]+=spot_signal
       row_values.append(spot_signal)
       bkg_values.append(bkg_signal)
       sz_values.append(spot_sz)
       eccen_values.append(spot_eccen)
       skew_values.append(spot_skew)
       index+=1
     if len(row_values)>0:
       self.MeanI[row]=flex.mean(row_values)
       self.MeanBkg[row]=flex.mean(bkg_values)
       self.MeanSz[row]=flex.mean(sz_values)
       self.MnEccen[row]=flex.mean(eccen_values)
       self.MnSkew[row]=flex.mean(skew_values)
   self.persist_fstats = fstats
   self.persist_indices = indices
示例#7
0
 def c_spot_filter(self,oldkey,newkey,apfunction,arguments=[]):
   parent = self.key[oldkey]
   if parent == 1:
     parentselection = xrange(self.master.size())
   else:
     parentselection = self.nodes[parent].data
   nextkey = max(self.nodes.keys())+1
   self.spotfilter.set_arguments(flex.double(arguments))
   childselection = self.spotfilter.filter(
     self.master,parentselection,apfunction)
   self.nodes[nextkey]=ListNode(childselection,newkey,parent)
   self.key[newkey]=nextkey
  def oneImage(self,framenumber):
    self.reporters[framenumber] = []

    from dxtbx.format.Registry import Registry
    filename = self.phil_params.distl.image[framenumber]
    reader = Registry.find(filename)
    img = reader(filename)

    detector = img.get_detector()
    beam = img.get_beam()
    S0 = beam.get_s0()
    data = img.get_raw_data()
    scan = img.get_scan()
    print scan
    if scan is None:
      print "No scan"
      RR = (0,1)
    else:
      print scan.get_oscillation()
      RR = scan.get_oscillation_range()

    from spotfinder.dxtbx_toolbox import Distl

    sfall = Distl(params = self.phil_params, detector = detector, beam = beam, data = data)

    resolutions = flex.double()
    spotlist = []
    from dials.model.data import ReflectionList,Reflection
    reflections = ReflectionList()


    for ip,panel in enumerate(detector):
      for spot in sfall.finderlist[ip].spots:
        resolutions.append( panel.get_resolution_at_pixel(S0, (spot.ctr_mass_x(), spot.ctr_mass_y())) )
        spotlist.append(spot)
        refl = Reflection()
        refl.panel_number = ip
        refl.centroid_position = (spot.ctr_mass_x(), spot.ctr_mass_y(),0.0)
        refl.centroid_variance = (0.5,0.5,0.0)
        reflections.append(refl)


    selection = (resolutions>0.0)
    if self.phil_params.distl.res.outer is not None:
      selection = (selection and (resolutions>self.phil_params.distl.res.outer))
    if self.phil_params.distl.res.inner is not None:
      selection = (selection and (resolutions<self.phil_params.distl.res.inner))

    reflections = reflections.select(selection)

    return dict(detector=detector, beam=beam, reflections=reflections, scan = scan,
                gonio = img.get_goniometer())
示例#9
0
    def filtered(self, sorted_order):
        # recoded in C++
        from spotfinder.core_toolbox import bin_exclusion_and_impact
        assert len(sorted_order) == len(self.ref_spots)

        limits_low_hi_res = flex.double()
        for x in xrange(len(self.intervals)):
            limits_low_hi_res.append(self.intervals[x][0])
            limits_low_hi_res.append(self.intervals[x][1])

        N = bin_exclusion_and_impact(self.ref_spots, sorted_order,
                                     limits_low_hi_res, self.impact)
        return N
示例#10
0
  def filtered(self,sorted_order):
    # recoded in C++
    from spotfinder.core_toolbox import bin_exclusion_and_impact
    assert len(sorted_order)==len(self.ref_spots)

    limits_low_hi_res = flex.double();
    for x in xrange(len(self.intervals)):
      limits_low_hi_res.append(self.intervals[x][0]);
      limits_low_hi_res.append(self.intervals[x][1]);

    N = bin_exclusion_and_impact(self.ref_spots,
                                    sorted_order,
                                    limits_low_hi_res,
                                    self.impact)
    return N
示例#11
0
  def sigma_analysis(self):
    #assumes that self.total_signal() and self.background() have already been called.
    self.addColumn('MeanIsigI',0) #mean I over sig(I) for spots within the shell
    self.MeanIsigI.format = "%.3f"
    index=0
    for row in xrange(self.S_table_rows):
      if self.PxlBkgrd[row] == None: continue
      IsigI_values = flex.double()
      for idx in xrange(self.Population[row]):
        # Use International Tables Vol F (2001) equation 11.2.5.9 (p. 214)
        I_s = flex.sum(self.persist_fstats.master[self.persist_indices[index]].wts)
        I_bg = flex.sum(self.persist_fstats.master[self.persist_indices[index]].bkg)
        m_sz = len(self.persist_fstats.master[self.persist_indices[index]].wts)
        n_sz = self.MnWndwSz[row]
        gain = 1.00

        spot_variance = gain * (I_s + I_bg + (m_sz*m_sz) * (1./n_sz) * self.PxlBkgrd[row])

        IsigI_values.append( I_s / math.sqrt(spot_variance))

        index+=1
      if len(IsigI_values)>0: self.MeanIsigI[row]=flex.mean(IsigI_values)
示例#12
0
    def oneImage(self, framenumber):
        self.reporters[framenumber] = []

        import dxtbx.format.Registry
        filename = self.phil_params.distl.image[framenumber]
        reader = dxtbx.format.Registry.get_format_class_for_file(filename)
        img = reader(filename)

        detector = img.get_detector()
        beam = img.get_beam()
        S0 = beam.get_s0()
        data = img.get_raw_data()
        scan = img.get_scan()
        print(scan)
        if scan is None:
            print("No scan")
            RR = (0, 1)
        else:
            print(scan.get_oscillation())
            RR = scan.get_oscillation_range()

        from spotfinder.dxtbx_toolbox import Distl

        sfall = Distl(params=self.phil_params,
                      detector=detector,
                      beam=beam,
                      data=data)

        resolutions = flex.double()
        spotlist = []
        from dials.model.data import ReflectionList, Reflection
        reflections = ReflectionList()

        for ip, panel in enumerate(detector):
            for spot in sfall.finderlist[ip].spots:
                resolutions.append(
                    panel.get_resolution_at_pixel(
                        S0, (spot.ctr_mass_x(), spot.ctr_mass_y())))
                spotlist.append(spot)
                refl = Reflection()
                refl.panel_number = ip
                refl.centroid_position = (spot.ctr_mass_x(), spot.ctr_mass_y(),
                                          0.0)
                refl.centroid_variance = (0.5, 0.5, 0.0)
                reflections.append(refl)

        selection = (resolutions > 0.0)
        if self.phil_params.distl.res.outer is not None:
            selection = (selection
                         and (resolutions > self.phil_params.distl.res.outer))
        if self.phil_params.distl.res.inner is not None:
            selection = (selection
                         and (resolutions < self.phil_params.distl.res.inner))

        reflections = reflections.select(selection)

        return dict(detector=detector,
                    beam=beam,
                    reflections=reflections,
                    scan=scan,
                    gonio=img.get_goniometer())
示例#13
0
def run_signal_strength_core(params,E):
  verbose = params.distl.verbose
  if params.distl.res.inner!=None:
    params.distl_lowres_limit = params.distl.res.inner
  if params.distl.res.outer!=None:
    params.force_method2_resolution_limit = params.distl.res.outer
    params.distl_highres_limit = params.distl.res.outer

  params.distl_force_binning = False
  params.distl_permit_binning = False
  params.wedgelimit = len(E.argv)
  params.spotfinder_header_tests = False
  Org = DistlOrganizer(verbose = True, argument_module=E,
                       phil_params=params)
  Org.printSpots()

  #Image analysis requested by NE-CAT (Point of contact: Craig Ogata)
  for key in Org.S.images.keys():
    # List of spots between specified high- and low-resolution limits
    if Org.S.images[key].has_key('lo_pass_resolution_spots'):
      spots = Org.S.images[key]['lo_pass_resolution_spots']
    elif Org.S.images[key].has_key('inlier_spots'):
      spots = Org.S.images[key]['inlier_spots']
    else:
      spots = []

    saturation = Org.Files.imageindex(key).saturation

    #Total number of spots in this range
    print
    print "Number of focus spots on image #%d within the input resolution range: %d"%(
      key,len(spots))

    signals=flex.double()
    saturations=flex.double()

    #Each spot
    for i,spot in enumerate(spots):
     signals.append(flex.sum(spot.wts))
     saturations.append(flex.max(spot.wts)/saturation)
     if verbose:
      #peak height given in ADC units above local background
      #integrated signal strength given in pixel-ADC units above local background
      print "%2d: Area in pixels=%d Peak=%.1f, Total integrated signal=%.1f (in pixel-ADC units above background)"%(
        i, spot.area(), flex.max(spot.wts), flex.sum(spot.wts))

      #peak signal-to-noise expressed in standard deviations above local background
      print "    Peak signal-to-noise=%.1f"%(spot.intensity())

      #peak height expressed in ADC units, without background subtraction
      image = Org.Files.imageindex(key)
      print "    Peak position x=%4d y=%4d (pixels); pixel value=%5d"%(
        spot.max_pxl_x(), spot.max_pxl_y(),
        image.linearintdata[(spot.max_pxl_x(),spot.max_pxl_y())])

      #Gory detail, looping through each pixel on each spot
      for j,pixel in enumerate(spot.bodypixels):
        print "       body pixel x=%4d y=%4d; pixel value=%5d; ADC height above background=%.1f"%(
          pixel.x,pixel.y,image.linearintdata[(pixel.x,pixel.y)],spot.wts[j])
    if signals.size()>0:
      print "Total integrated signal, pixel-ADC units above local background (just the good Bragg candidates) %d"%(
            flex.sum(flex.double([flex.sum(spot.wts) for spot in Org.S.images[key]['inlier_spots']]))
      )
      print "Signals range from %.1f to %.1f with mean integrated signal %.1f"%(
      flex.min(signals), flex.max(signals), flex.mean(signals) )
      print "Saturations range from %.1f%% to %.1f%% with mean saturation %.1f%%"%(
      100.*flex.min(saturations), 100.*flex.max(saturations), 100.*flex.mean(saturations) )

  if params.distl.pdf_output != None:
    #later, put this in a separate module so reportlab is not imported unless requested
    from labelit.publications.sublattice.sublattice_pdf import SublatticePDF,graphic
    from labelit.publications.sublattice.sublattice_pdf import PointTransform
    class genPDF(SublatticePDF):
      def make_image_plots_detail(self):
         params.pdf_output.window_fraction=1.0
         params.pdf_output.window_offset_x=0.0
         params.pdf_output.window_offset_y=0.0
         params.pdf_output.markup_inliers=True
         couple=(params.pdf_output.window_offset_x,
                 params.pdf_output.window_offset_y)
         #instead of self.R.setTransform, which requires pickled spotfinder:
         self.R.T = PointTransform()
         self.R.S = self.R.spotfinder
         self.R.T.setImage(spotfinder=self.R.S,subwindow_origin=couple,commands=params)
         self.R.title(self.image_name)
         #try:
         pil_image = graphic(filein = self.image_name,
                             couple = couple,
                             commands = params)
         self.R.image(pil_image)
         #except:
         #  print "failure, file %s"%self.filename
         if params.pdf_output.markup_inliers:
           self.R.show_ellipse(
           image_number=self.R.spotfinder.images.keys()[0],
           tags = ['goodspots','spots_non-ice','hi_pass_resolution_spots',
                    'spots_unimodal'],
           detail=True)
         self.R.c.showPage()
         return self
    pdf = genPDF(params.distl.pdf_output)
    pdf.filename = params.distl.pdf_output
    pdf.image_name = params.distl.image
    pdf.set_spotfinder(Org.S)
    pdf.make_image_plots_detail()

  if params.distl.image_viewer == True:
    try:
      from rstbx.viewer.spotfinder_wrap import spot_wrapper
      spot_wrapper(params).display(path = params.distl.image,
                                   organizer = Org)
    except ImportError,e:
      from libtbx.utils import Sorry
      # must use phenix.wxpython for wx display
      raise Sorry(str(e)+" Try setting env variable PHENIX_GUI_ENVIRONMENT=1")
示例#14
0
    def oneImage(self, framenumber, pd, image):
        self.reporters[framenumber] = []
        # The only way to get pixel size & pixel dimensions (currently) is from header
        pimage = image
        pimage.read()
        #print "Detector type",type(pimage)
        if 'endstation' not in pd:
            from iotbx.detectors.context import endstation
            pd['endstation'] = endstation.EndStation_from_ImageObject(
                pimage, self.phil_params)
            for key in pd['endstation'].mosflm():
                pd[key] = pd['endstation'].mosflm()[key]
        pd['vendortype'] = pimage.vendortype
        pd['binning'] = "%d" % pimage.bin
        pd['pixel_size'] = "%f" % pimage.pixel_size
        self.pixel_size = float(pd['pixel_size'])

        pd['size1'] = "%d" % pimage.size1
        self.size1 = float(pd['size1'])
        pd['size2'] = "%d" % pimage.size2
        self.size2 = float(pd['size2'])
        if 'osc_start' not in pd: pd['osc_start'] = {}
        pd['osc_start'][framenumber] = "%f" % pimage.osc_start
        if 'file' not in pd: pd['file'] = {}
        pd['file'][framenumber] = pimage.filename
        self.two_theta_degrees = float(pd['twotheta'])

        if 'xbeam' not in pd or 'ybeam' not in pd:
            raise SpotfinderError(
                "Deprecation warning: inputs had no beam position", pd)
        self.complex_nominal_center = complex(float(pd["xbeam"]),
                                              float(pd["ybeam"]))

        arguments = ""  # distl_aggressive no longer supported, eg "-s2 5 -s3 8"

        #allow for self.phil_params.distl_highres_limit
        if self.phil_params.distl_highres_limit != None:
            arguments = arguments + " -ro %.3f" % self.phil_params.distl_highres_limit

        #  test implementation of parallel processing for spotfinder
        #from labelit.webice_support import parallel_distl
        #pimage,pd = parallel_distl.split_image(pimage,pd)

        try:
            sf = Distl(
                arguments,
                pimage,
                pd,
                report_overloads=self.phil_params.distl_report_overloads,
                params=self.phil_params)
        except Sorry as e:
            raise e
        except Exception as e:
            raise SpotfinderError("Spotfinder cannot analyze image %s :" %
                                  pimage.filename + e.message)

        #To support sublattice detection, make pixel-wise Z-scores persistent
        if self.phil_params.distl_keep_Zdata:
            pimage.linear_Z_data = sf.Z_data(
            )  #potentially uses a lot of memory

        #************************************************************
        #
        #  Very important.  For the mar image plate (and allother circular detectors,
        #  must specify that these are embedded circular detectors and so adjust the
        #  percentage underloads.  Or else libdistl must be changed so as not to
        # search in these regions:  yes, this would be better because I propose to
        # change the search loop anyway.  However, the getUnderload function must
        # also be modified!!!
        #
        #  ice ring search must also be modified to take this into account, but this
        #  part must be more precise than the above.
        #
        #************************************************************

        if self.two_theta_degrees == 0.0:
            mm_minimum_radius = resol_to_radius(
                self.phil_params.distl_lowres_limit, pd)

        sfa = SpotFilterAgent(
            pixel_size=pimage.pixel_size,
            xbeam=float(pd["xbeam"]),
            ybeam=float(pd["ybeam"]),
            distance=float(pd['distance']),
            wavelength=float(pd['wavelength']),
            icerings=sf.icerings,
        )
        #from libtbx import easy_pickle
        #easy_pickle.dump("file.dmp",sfa)
        #easy_pickle.load("file.dmp")

        fstats = ListManager(masterlist=sf.spots,
                             masterkey='spots_total',
                             spotfilter=sfa)

        fstats['distl_resolution'] = sf.imgresol()

        # 1. Get all spots

        fstats.alias(oldkey='spots_total', newkey='goodspots')
        if VERBOSE_COUNT: print "total DISTL spots", fstats['N_spots_total']

        fstats.c_spot_filter('goodspots', 'spots_non-ice', 'ice_ring_test')
        fstats['ice-ring_impact'] = sf.nicerings()
        fstats['ice-ring_bounds'] = [
            (sf.icerings[i].lowerresol, sf.icerings[i].upperresol)
            for i in xrange(fstats['ice-ring_impact'])
        ]

        #**********************************************************************
        #  Known parts of code that are inefficient: use 35000-spot HK97 example
        #  1. 3.8 seconds: sorting the resolution spots (item #4 in tnear2) (Corrected)
        #  2. 9.7 seconds: spreadsheet bookkeeping; method2_resolution.py, xrow loop (Partly corrected 5/09)
        #  3. 4.4 seconds: ice2::RingFinder::filtered()  (Corrected)

        # 3. omit spots too close to the beamstop
        if self.two_theta_degrees == 0.0:
            fstats.c_spot_filter('spots_non-ice',
                                 'hi_pass_resolution_spots',
                                 'resolution_test',
                                 arguments=[
                                     mm_minimum_radius,
                                 ])
        else:
            fstats.precompute_resolution(
                self.two_theta_degrees * math.pi / 180.,  #two theta radians
                pd['endstation'].rotation_axis(),
                pd['endstation'].camera_convention())

            fstats.c_spot_filter(
                'spots_non-ice',
                'hi_pass_resolution_spots',
                'resolution_test_nztt',
                arguments=[self.phil_params.distl_lowres_limit])

        if VERBOSE_COUNT:
            print "after lowres filter", fstats["N_hi_pass_resolution_spots"]


#start here.
#In the end, make sure these work:
#interface with mosflm: "TWOTHETA" keyword fails; "TILT" fix works with fudge factor
#James Holton's spots index (make unit test); anything with resolution_mm
#diffimage display!:  ring_markup() method of webice_support/__init__
#report the two theta value in stats index
# 4. Calculate resolution cutoff
        if self.two_theta_degrees == 0.0:
            sorted_order, sorted_resolutions = fstats.resolution_sort(
                "hi_pass_resolution_spots")
        else:
            sorted_order, sorted_resolutions = fstats.resolution_sort_nztt(
                "hi_pass_resolution_spots")
        # targetBinNumber: first try number of candidate Bragg spots per bin
        targetBinNumber = max(self.BinMin, len(sorted_order) // 20)

        # cutoff threshhold: expected number spots in highest resolution bin
        cutoff_ratio = 100. / self.phil_params.distl.method2_cutoff_percentage
        fstats['resolution_divisor'] = cutoff_ratio
        lowerCutoffBinNumber = targetBinNumber / cutoff_ratio

        if len(sorted_order) < targetBinNumber:
            # So few spots that there is only one bin
            # no resolution determination possible
            fstats['resolution'] = None
            fstats['resolution_detail'] = len(sorted_order)

        elif False and sorted_resolutions[self.BinMin - 1] < 4.0:
            '''This filter (that essentially says you must have low
      resolution spots) hindered the ability to index the case
      ana/procrun0000084148/sphN1_*.mar2300.  Further investigation
      showed that not a single one of the 94 reference cases in the
      regression database was affected by this test, so the test is
      being provisionally removed.  It is not known if the test has a
      beneficial effect on cases with no protein diffraction, i.e., just
      ice rings.'''
            # This test indicates that there are so few spots at low
            #  resolution that the first bin extends past 4.0 Angstroms,
            #  into the region where ice rings might be found
            #  since there are too few low resolution data
            #  conclude that these are false Bragg spots
            fstats['resolution'] = None
            sorted_resolutions = []
            # deprecated; would need to be recoded:
            fstats['N_spots_resolution'] = 0

        else:
            from spotfinder.diffraction.geometry import Geom2d
            frac_calc = Geom2d(pd)
            #spot-based ice-ring filtering, added Aug 2004
            '''The case ana/procrun0000084148/sphN1_*.mar2300 (image 090) shows the
      limits of this filter as presently implemented.  In that particular
      case, this ice-ring filter eliminates spots from a large area in the
      2-3 Angstrom resolution range.  However, to be believed, the purported
      ice-spots should define a circle or ellipse centered at the beam position
      with a resolution spread that is very narrow.  Code could be
      written much more effectively to search and elimate these rings'''
            from spotfinder.applications.heuristic_tbx.ice2 import RingFinder
            from spotfinder.applications.heuristic_tbx.ice_nztt import RingFinder_nztt

            if (abs(float(pd['twotheta'])) > 0.0):
                # Very inefficient--8 seconds per call; will need to be optimized
                #PP = Profiler("nztt")
                Ring = RingFinder_nztt(sorted_resolutions, targetBinNumber,
                                       frac_calc, image)
                #del PP
            else:
                Ring = RingFinder(sorted_resolutions, targetBinNumber,
                                  frac_calc)

            fstats.add_child("hi_pass_resolution_spots",
                             "ice_free_resolution_spots",
                             Ring.filtered(sorted_order))
            fstats['ice-ring_impact'] += Ring.ice_ring_impact()
            fstats['ice-ring_bounds'] += Ring.ice_ring_bounds()

            #*************************the filtering of existing spots

            if VERBOSE_COUNT:
                print "after spot_based ice-ring filter", fstats[
                    'N_ice_free_resolution_spots']

            if fstats['N_ice_free_resolution_spots'] < targetBinNumber:
                # So few spots that there is only one bin
                # no resolution determination possible
                fstats['resolution'] = None
                fstats['resolution_detail'] = fstats[
                    'N_ice_free_resolution_spots']
            else:
                from spotfinder.applications.heuristic_tbx.method2_resolution\
                  import ResolutionShells
                sorted_resolutions = fstats.spotfilter.get_resolution(
                    fstats.master,
                    fstats.get_indices('ice_free_resolution_spots'))

                Shell = ResolutionShells(
                    sorted_resolutions,
                    sorted_resolutions[targetBinNumber - 1], frac_calc)
                #Shell.show()

                if self.phil_params.distl.bins.verbose:
                    ShellR = spotreporter(
                        sorted_resolutions,
                        self.phil_params,
                        sorted_resolutions[targetBinNumber - 1],
                        wavelength=float(pd['wavelength']),
                        max_total_rows=self.phil_params.distl.bins.N,
                        fractionCalculator=frac_calc,
                        use_binning_of=self)
                    ShellR.total_signal(
                        fstats,
                        fstats.get_indices('ice_free_resolution_spots'))
                    ShellR.background(sf)
                    ShellR.sigma_analysis()
                    print
                    ShellR.show(
                        message=
                        "Analysis of spots after ice removal, but prior to resolution cutoff, for image \n%s"
                        % pimage.filename)
                    self.reporters[framenumber].append(ShellR)

                # slight adjustment so that we don't focus on the lowest
                #  resolution data shell (spends too much time in Ewald sphere)
                #  But don't make this adjustment if we are limited by low spot count
                if Shell.rows() > 2 and \
                    Shell.Population[1] > 2*lowerCutoffBinNumber and \
                    Shell.Population[1] > self.BinMin:
                    lowerCutoffBinNumber = Shell.Population[1] / cutoff_ratio

                # first determination of cutoff ignoring corner effect
                for x in xrange(Shell.rows()):
                    idx = Shell.rows() - x - 1
                    if Shell.Population[idx] > lowerCutoffBinNumber:
                        lastshell = idx
                        break

                # eliminate pathological case where there are a lot of low resolution
                # spots and then some ice rings at high resolution.  If there are ten
                # empty shells in a row (empty defined as having fewer than
                # VetterCut spots), redetermine lastshell.
                #
                # Originally, VetterCut := lowerCutoffBinNumber
                # Modify the heuristic to cover two extremes:
                # Case 1.  Based on the HK97 virus work; there is a class of diffraction
                #    cases showing a distinct dip in diffraction intensity in the
                #    5-Angstrom regime.  If lowerCutoffBinNumber is used (usually
                #    20% of the spot count in the 2nd bin), the algorithm can
                #    misbehave and reject all the high-resolution Bragg spots.
                #    For one case in particular a tiny change in beam position
                #    flips the resolution cutoff from a 6.5- to 4.4-Angstrom.
                # Case 2.  There are many cases where the diffraction clearly
                #    drops off, and at higher resolutions there are random-signal
                #    spots plus ice rings.  The spot count in these high-res bins
                #    is typically small, <20.  Use "20" as a heuristic cutoff
                #    between Case 1 & Case 2.
                # In future, it may be productive to focus on smarter algorithms to
                # execute ellipse recognition in the "Ringfinder" section above

                if lowerCutoffBinNumber <= 20:
                    VetterCut = lowerCutoffBinNumber
                else:
                    VetterCut = 20 + lowerCutoffBinNumber // 5
                lastshell = Shell.vetter(VetterCut, lastshell)

                #option for overriding the resolution analysis based on falloff
                # of spot count.  Force spots at least this far out
                if self.phil_params.force_method2_resolution_limit is not None:
                    for x in xrange(Shell.rows()):
                        if Shell.Limit[
                                x] < self.phil_params.force_method2_resolution_limit and lastshell < x:
                            lastshell = x
                            break

                # extend resolution cutoff taking into account corner cutoff
                while Shell.Fract[
                        lastshell] < 1.0 and lastshell + 1 < Shell.rows():
                    nextshell = lastshell + 1
                    if Shell.adjustPop[nextshell] > lowerCutoffBinNumber:
                        lastshell += 1
                    else:
                        break

                fstats['resolution'] = Shell.Limit[lastshell]
                if self.phil_params.distl_highres_limit != None:
                    fstats['resolution'] = max(
                        fstats['resolution'],
                        self.phil_params.distl_highres_limit)

                for x in xrange(lastshell + 1):
                    if self.phil_params.spotfinder_verbose:
                        print "(%.2f,%d)" % (Shell.Limit[x],
                                             Shell.Population[x])

                if self.two_theta_degrees == 0.0:
                    fstats.c_spot_filter(  #hi-resolution radius
                        'ice_free_resolution_spots',
                        'lo_pass_resolution_spots',
                        'lo_pass_resolution_test',
                        arguments=[
                            resol_to_radius(fstats['resolution'], self.pd),
                        ])
                else:
                    fstats.c_spot_filter(  #hi-resolution radius
                        'ice_free_resolution_spots',
                        'lo_pass_resolution_spots',
                        'lo_pass_resolution_test_nztt',
                        arguments=[
                            fstats['resolution'],
                        ])

                if VERBOSE_COUNT:
                    print "ice_free_resolution_spots ", fstats[
                        'N_ice_free_resolution_spots']

                fstats['shells'] = Shell

                if VERBOSE_COUNT:
                    print "after resolution-shell cutoff", fstats[
                        'N_lo_pass_resolution_spots']
                fstats['resolution_mm'] = resol_to_radius(
                    fstats['resolution'], pd)

        fstats['saturation'] = self.calculate_saturation(fstats, image)

        if self.phil_params.distl.bins.verbose:
            try:
                subset = fstats.spotfilter.get_resolution(
                    fstats.master,
                    fstats.get_indices('lo_pass_resolution_spots'))
                ShellR = spotreporter(subset,
                                      self.phil_params,
                                      use_binning_of=self)
                ShellR.total_signal(
                    fstats, fstats.get_indices('lo_pass_resolution_spots'))
                ShellR.background(sf)
                ShellR.sigma_analysis()
                print
                ShellR.show(
                    message=
                    "Analysis of spots after resolution filtering, but prior to spot quality heuristics, for image \n%s"
                    % pimage.filename)
                self.reporters[framenumber].append(ShellR)

            except Exception:  # in case the low-pass filter step was skipped; e.g., blank image.
                pass

        # 5. eliminate multi-modal spots & punctate spots
        fstats.c_spot_filter(fstats.most_recent_child(),
                             'spots_unimodal',
                             'modal_test',
                             arguments=[
                                 self.phil_params.distl_profile_bumpiness,
                                 self.phil_params.distl.minimum_spot_area
                                 or sf.spotbasesize()
                             ])
        # parameters are bumpiness(max number of local maxima in peak),minimum pixels

        if VERBOSE_COUNT:
            print "not bumpy & not punctate", fstats['N_spots_unimodal']

        # 6. Compute distributions for outlier rejection
        #Y = Timer("Inliers")#try to get this down from 232 seconds to 8 seconds
        #(For HK97 sz=4)

        inlier_idx_raw = flex.int()
        inlier_neigh = []
        unimodal_spots = fstats['spots_unimodal']

        if fstats[
                'N_spots_unimodal'] > 2:  # avoids divide-by-zero error in stats calls, below
            intensities = flex.double([s.intensity() for s in unimodal_spots])
            areas = flex.double([s.bodypixels.size() for s in unimodal_spots])
            # Deprecate shapes because code is unstable; in rare cases spots can have
            # body pixels but no border pixels ( RAW/APS_07_2005/pEI4/pEI4_8_1.0001 )
            #shapes      = flex.double([s.shape() for s in unimodal_spots])
            eccentricity = flex.double(
                [s.model_eccentricity() for s in unimodal_spots])
            skewness = fstats.get_property(fstats.most_recent_child(),
                                           'skewness')

            fstats['intensity'] = (i_ave, i_std) = scitbx_stats(intensities)
            fstats['area'] = (a_ave, a_std) = scitbx_stats(areas)
            #fstats['shape']     = (s_ave,s_std) = scitbx_stats(shapes)
            fstats['eccen'] = (e_ave, e_std) = scitbx_stats(eccentricity)
            fstats['skewness'] = (k_ave, k_std) = scitbx_stats(skewness)

            #Filtering on skewness is important when using center-of-mass positions
            # for autoindexing.  The goal is to eliminate pairs of unresolved Bragg
            # spots.  Condition is flagged when the max_pixel to center-of-mass
            # vector is more than 45% of the semi-major axis
            fstats.c_spot_filter(fstats.most_recent_child(),
                                 'spots_low_skew',
                                 'low_skew',
                                 arguments=[
                                     min(0.45, 2.0 * k_std + k_ave),
                                 ])

            #Filter on the intensity distribution.
            fstats.c_spot_filter(fstats.most_recent_child(),
                                 'spots_good_intensity',
                                 'intensity_inlier',
                                 arguments=[
                                     i_ave - 5.0 * i_std,
                                     i_ave + 5.0 * i_std,
                                     image.saturation,
                                 ])

            #special code for expecting a high MOSFLM RESID based on the
            # presence of very high signal/noise ratio (essentially lysozyme strength).
            # This is all just a supposition based on one dataset, offset_1 from Ana.
            # The assumption may be wrong; e.g. the high resid may be due to very low
            # background instead of high s/n; or due to some geometrical distortion.
            #This breaks encapsulation and will have to be re-organized in the future.
            if 'special_resid' not in pd: pd['special_resid'] = ''
            if fstats['intensity'][0] > 160.:
                pd['special_resid'] = 'RESID 10.0 #High s/n'
            #The most unusual thing about the procrun0000077831/TMC114_WT2_run77831_1_001
            #dataset is its large differential between spot areas of the largest spots
            # and the smallest spots.  Hypothesize that this also leads to high
            # weighted residuals.
            if stats_profile(areas) > 10.:
                pd['special_resid'] = 'RESID 10.0 #High s/n'

            from annlib_ext import AnnAdaptor
            data = fstats.get_property(
                'goodspots', self.phil_params.distl_spotcenter_algorithm)
            query = fstats.get_property(
                fstats.most_recent_child(),
                self.phil_params.distl_spotcenter_algorithm)

            A = AnnAdaptor(data, 2)  # construct k-d tree for reference set
            A.query(query)  # find nearest neighbors of query points

            neighbors = (self.pixel_size) * flex.sqrt(A.distances)
            """Explanation: Distance to the nearest neighbor is math.sqrt(A.distances[i]), in
         units of pixels.  The vector to the nearest neighbor, in units of pixels, is
         ( fstats.master[A.nn[i]].x()-query[2*i], fstats.master[A.nn[i]].y()-query[2*i+1])
      """

            fstats['neighbor'] = (n_ave, n_std) = scitbx_stats(neighbors)

            sep_input_spots = fstats[fstats.most_recent_child()]
            sep_input_indices = fstats.get_indices(fstats.most_recent_child())

            overlapping_count = 0
            for idx in xrange(len(sep_input_spots)):
                try:
                    if float(pd['pixel_size'])*sep_input_spots[idx].majoraxis() * \
                       self.phil_params.overlapping_spot_criterion > neighbors[idx]:
                        overlapping_count += 1
                except Exception:
                    pass
            if len(sep_input_spots) == 0: percent_overlap = 0
            else:
                percent_overlap = 100 * overlapping_count / len(
                    sep_input_spots)
            #print "overlap %2.0f%% vs. cutoff %2.0f%%"%(percent_overlap,self.phil_params.percent_overlap_forcing_detail)

            from spotfinder.core_toolbox.close_spots_detail import NearNeighborVectors
            Afull = AnnAdaptor(data, 2)
            Afull.query(data)
            NV = NearNeighborVectors(ave_area=a_ave,
                                     query_centers=data,
                                     fstats=fstats,
                                     ann_adaptor=Afull)
            #NV.show_vector_map()
            #NV.show_maxima()

            DEVELOP_ASSERT = True
            self.force_detail = percent_overlap > self.phil_params.percent_overlap_forcing_detail
            if DEVELOP_ASSERT or self.force_detail:
                self.overlapping = True
                #extraordinary procedure, when many spots are close.  Include closely
                #  spaced spots in autoindexing, if it appears that they truly
                #  reflect lattice spacing.
                if self.phil_params.spotfinder_verbose:
                    print len(sep_input_spots
                              ), "spot count before close neighbor analysis;",
                    print overlapping_count, "(%2.0f%%) rejected on neighbors;" % (
                        percent_overlap)

                pmax = NV.vectors()
                #filter out spots that are potentially large enough to contain
                #two spots, now that we know a candidate projected unit-cell vector
                # expect big time savings if this section is pushed down to C++
                compact_idx = []

                if 0 < len(pmax) <= 3:
                    sq_vectors = [v[0] * v[0] + v[1] * v[1] for v in pmax]
                    for idx in xrange(len(sep_input_spots)):
                        spot_compact = True
                        for iv, vector in enumerate(pmax):
                            thisspot = sep_input_spots[idx]
                            #more efficient code--disallowed spots (based on nearest neighbor
                            # vector) are now flagged based on the width of the ellipse model
                            # rather than a more time-consuming body-pixel match:

                            #calculate angle theta between major axis and neighbor vector
                            dot = thisspot.eigenvector(1)[0] * vector[
                                0] + thisspot.eigenvector(1)[1] * vector[1]
                            costheta = dot / math.sqrt(sq_vectors[iv])
                            costhetasq = min(costheta * costheta, 1.0)
                            sintheta = math.sqrt(1 - costhetasq)
                            spota = thisspot.a()
                            spotb = thisspot.b()
                            a_sin_theta = spota * sintheta
                            b_cos_theta = spotb * costheta
                            #evaluate the ellipse full width along neighbor vector direction
                            width_sq = 4. * (spota * spota * spotb * spotb /
                                             (a_sin_theta * a_sin_theta +
                                              b_cos_theta * b_cos_theta))
                            if width_sq >= sq_vectors[iv]:
                                spot_compact = False
                                break

                        if spot_compact: compact_idx.append(idx)
                        else:
                            pass  #print "eliminate the spot at",thisspot.x(),thisspot.y()
                else:
                    compact_idx = xrange(len(sep_input_spots))
                if self.phil_params.spotfinder_verbose:
                    print len(sep_input_spots) - len(
                        compact_idx), "large spots rejected"

                # finally, allow certain close spots (but not all of them) to be included
                for idx in compact_idx:
                    try:
                        S = (int(fstats.master[A.nn[idx]].max_pxl_x() -
                                 query[2 * idx]),
                             int(fstats.master[A.nn[idx]].max_pxl_y() -
                                 query[2 * idx + 1]))
                        #accept spot by default
                        reject_spot = False
                        #if close to nearest neighbor reject
                        if sep_input_spots[idx].majoraxis() * \
                           self.phil_params.overlapping_spot_criterion > math.sqrt(S[0]*S[0]+S[1]*S[1]):
                            # with normal procedure, spot would be rejected at this point
                            reject_spot = True
                            if len(pmax) <= 3:
                                for vector in pmax:
                                    if abs(vector[0] - S[0]) <= 1 and abs(
                                            vector[1] - S[1]) <= 1:
                                        #but allow if the proximity is to a candidate cell near neighbor
                                        reject_spot = False
                                        break
                        if reject_spot: continue

                        inlier_idx_raw.append(sep_input_indices[idx])
                        inlier_neigh.append(neighbors[idx])
                    except Exception:
                        pass

                if self.phil_params.spotfinder_verbose:
                    print len(compact_idx) - len(
                        inlier_idx_raw), "close spots rejected"
                    print len(sep_input_spots
                              ), "input for spot separation analysis;",
                    jj = len(sep_input_spots) - len(inlier_idx_raw)
                    print jj, "(%2.0f%%) rejected on special criteria;" % (
                        100. * jj / len(sep_input_spots))

            else:  #normal procedure, assuming not too many close spots
                for idx in xrange(len(sep_input_spots)):
                    try:
                        if math.fabs(intensities[idx]-i_ave) <= 5.0*i_std and \
                           intensities[idx]<image.saturation and \
                           float(pd['pixel_size'])*sep_input_spots[idx].majoraxis() * \
                           self.phil_params.overlapping_spot_criterion<=neighbors[idx]:
                            inlier_idx_raw.append(sep_input_indices[idx])
                            inlier_neigh.append(neighbors[idx])
                    except Exception:
                        #print "REJECT spot on exception"
                        pass  #sometimes throw an error when majoraxis is requested (edge spots)

                if len(inlier_idx_raw) < self.NspotMin:
                    for idx in xrange(len(sep_input_spots)):
                        try:
                            proximal_radius = 2.0 * self.phil_params.overlapping_spot_criterion * float(
                                pd['pixel_size']
                            ) * sep_input_spots[idx].majoraxis()
                            if math.fabs(intensities[idx]-i_ave) <= 5.0*i_std and \
                               intensities[idx]<image.saturation and \
                               float(pd['pixel_size'])*sep_input_spots[idx].majoraxis() *self.phil_params.overlapping_spot_criterion > neighbors[idx] and \
                               sf.isIsolated(sep_input_spots[idx],proximal_radius):
                                #print "Very few Bragg spots; forced to accept spot with neighbor distance",neighbors[idx]/(float(pd['pixel_size'])*sep_input_spots[idx].majoraxis())
                                inlier_idx_raw.append(sep_input_indices[idx])
                                inlier_neigh.append(neighbors[idx])
                        except Exception:
                            print "REJECT spot on exception"
                            pass  #sometimes throw an error when majoraxis is requested (edge spots)

        if fstats.has_extended_key('lo_pass_resolution_spots'):
            fstats.alias('lo_pass_resolution_spots', 'spots_resolution')
        elif fstats.has_extended_key('ice_free_resolution_spots'):
            fstats.alias('ice_free_resolution_spots', 'spots_resolution')
        else:
            fstats.alias('hi_pass_resolution_spots', 'spots_resolution')

        fstats.add_child('spots_unimodal', 'spots_separated', inlier_idx_raw)

        fstats.alias(fstats.most_recent_child(), 'spots_inlier')
        fstats.alias('spots_inlier',
                     'inlier_spots')  #for backward compatibility

        if self.phil_params.distl.bins.verbose:
            try:
                subset = fstats.spotfilter.get_resolution(
                    fstats.master, fstats.get_indices('inlier_spots'))
                ShellR = spotreporter(subset,
                                      self.phil_params,
                                      use_binning_of=self)
                ShellR.total_signal(fstats, fstats.get_indices('inlier_spots'))
                ShellR.background(sf)
                ShellR.sigma_analysis()
                print
                ShellR.show(
                    message=
                    "Analysis of good Bragg spots after quality heuristics, for image \n%s"
                    % pimage.filename)
                self.reporters[framenumber].append(ShellR)

            except Exception:
                pass  #if there aren't enough spots, just skip the tabular printout

        if 'masks' not in pd: pd['masks'] = {}
        pd['masks'][framenumber] = None
        if fstats['N_spots_inlier'] > (  #guard against C++ hard-coded minimum
                self.phil_params.codecamp.minimum_spot_count or 25):
            Msk = fstats.single_mask('inlier_spots', self.phil_params)
            pd['masks'][framenumber] = [Msk.x, Msk.y]

        if VERBOSE_COUNT: print "inlier spots", fstats["N_inlier_spots"]

        #need this for later calculation of maxcell
        fstats['neighbors'] = flex.double(inlier_neigh)

        return fstats
 def get_resolution_inspection(self):
   all_frames = self.images.keys()
   all_resolutions=flex.double([self.images[f]['resolution'] for f in all_frames])
   ave_resolution=flex.mean(all_resolutions)
   self.pd['resolution_inspection']='%f'%(ave_resolution)
   return self.pd['resolution_inspection']
示例#16
0
 def precompute_resolution(self,twotheta,rotation_axis,camera_convention):
   self.spotfilter.precompute_resolution(self.master,twotheta,
     flex.double(rotation_axis),camera_convention)
示例#17
0
      arguments=[self.phil_params.distl_profile_bumpiness,
                 self.phil_params.distl.minimum_spot_area or sf.spotbasesize()])
      # parameters are bumpiness(max number of local maxima in peak),minimum pixels

    if VERBOSE_COUNT: print "not bumpy & not punctate",fstats['N_spots_unimodal']

    # 6. Compute distributions for outlier rejection
    #Y = Timer("Inliers")#try to get this down from 232 seconds to 8 seconds
                         #(For HK97 sz=4)

    inlier_idx_raw = flex.int()
    inlier_neigh=[]
    unimodal_spots = fstats['spots_unimodal']

    if fstats['N_spots_unimodal']>2: # avoids divide-by-zero error in stats calls, below
      intensities = flex.double([s.intensity() for s in unimodal_spots])
      areas       = flex.double([s.bodypixels.size() for s in unimodal_spots])
      # Deprecate shapes because code is unstable; in rare cases spots can have
      # body pixels but no border pixels ( RAW/APS_07_2005/pEI4/pEI4_8_1.0001 )
      #shapes      = flex.double([s.shape() for s in unimodal_spots])
      eccentricity= flex.double([s.model_eccentricity() for s in unimodal_spots])
      skewness    = fstats.get_property(fstats.most_recent_child(),'skewness')

      fstats['intensity'] = (i_ave,i_std) = scitbx_stats(intensities)
      fstats['area']      = (a_ave,a_std) = scitbx_stats(areas)
      #fstats['shape']     = (s_ave,s_std) = scitbx_stats(shapes)
      fstats['eccen']     = (e_ave,e_std) = scitbx_stats(eccentricity)
      fstats['skewness']  = (k_ave,k_std) = scitbx_stats(skewness)

      #Filtering on skewness is important when using center-of-mass positions
      # for autoindexing.  The goal is to eliminate pairs of unresolved Bragg
示例#18
0
    def triage_image(self):
        """ Performs a quick DISTL spotfinding without grid search.
    """
        from spotfinder.command_line.signal_strength import master_params as sf_params

        sf_params = sf_params.extract()
        sf_params.distl.image = self.img

        E = Empty()
        E.argv = ['Empty']
        E.argv.append(sf_params.distl.image)

        log_info = ['{}\n'.format(self.img)]
        img_filename = os.path.basename(self.img)

        # Perform spotfinding
        # ... using spotfinding grid search
        if self.params.image_triage.type == 'grid_search':
            log_info.append('\n CCTBX TRIAGE grid search:')
            # Determine grid search extent
            a_min = self.params.image_triage.grid_search.area_min
            a_max = self.params.image_triage.grid_search.area_max
            a_step = (a_max -
                      a_min) // self.params.image_triage.grid_search.step_size
            h_min = self.params.image_triage.grid_search.height_min
            h_max = self.params.image_triage.grid_search.height_max
            h_step = (h_max -
                      h_min) // self.params.image_triage.grid_search.step_size

            # Cycle through grid points
            spotlist = []
            for spa in range(a_min, a_max + 1, a_step):
                for sph in range(h_min, h_max + 1, h_step):
                    sf_params.distl.minimum_spot_area = spa
                    sf_params.distl.minimum_spot_height = sph
                    sf_params.distl.minimum_signal_height = sph

                    # Perform spotfinding
                    Bragg_spots = self.run_distl(sf_params)
                    N_Bragg_spots = len(Bragg_spots)

                    if N_Bragg_spots > 0:
                        total_intensity = flex.sum(flex.double(Bragg_spots))
                    else:
                        total_intensity = 0

                    spotlist.append({
                        'bragg': N_Bragg_spots,
                        'ti': total_intensity,
                        'spa': spa,
                        'sph': sph
                    })
                    log_info.append('{:<{w}}: H = {:<2}, A = {:<2}, Bragg = {:<6.0f}  '\
                                    'total intensity = {:<12.4f}'.format(img_filename, sph, spa,
                                    N_Bragg_spots, total_intensity, w = len(img_filename)))

            # Pick best spotfinding result (highest total intensity seems to work for now
            pick = sorted(spotlist, key=lambda j: j['ti'])[-1]
            N_Bragg_spots = pick['bragg']
            start_sph = pick['sph']
            start_sih = pick['sph']
            start_spa = pick['spa']

        # ... using spotfinding without grid search
        else:
            # Set spotfinding params
            sf_params.distl.minimum_spot_area = self.params.cctbx.grid_search.area_median
            sf_params.distl.minimum_spot_height = self.params.cctbx.grid_search.height_median
            sf_params.distl.minimum_signal_height = self.params.cctbx.grid_search.height_median

            # Perform spotfinding
            Bragg_spots = self.run_distl(sf_params)

            # Extract spotfinding results
            N_Bragg_spots = len(Bragg_spots)
            start_sph = self.params.cctbx.grid_search.height_median
            start_sih = self.params.cctbx.grid_search.height_median
            start_spa = self.params.cctbx.grid_search.area_median

        # Determine triage success
        if N_Bragg_spots >= self.params.image_triage.min_Bragg_peaks:
            log_info.append('ACCEPTED! Selected starting point:')
            log_info.append('{:<{w}}: S = {:<2}, H = {:<2}, A = {:<2}, Bragg = {:<6.0f}'\
                            ''.format(img_filename, start_sih, start_sph, start_spa,
                                      N_Bragg_spots, w = len(img_filename)))
            status = None
        else:
            log_info.append(
                'REJECTED! ({} Bragg peaks found)'.format(N_Bragg_spots))
            status = 'failed triage'

        log_entry = "\n".join(log_info)

        return status, log_entry, start_sph, start_spa
示例#19
0
  def triage_image(self):
    """ Performs a quick DISTL spotfinding without grid search.
    """
    from spotfinder.command_line.signal_strength import master_params as sf_params

    sf_params = sf_params.extract()
    sf_params.distl.image = self.img

    E = Empty()
    E.argv=['Empty']
    E.argv.append(sf_params.distl.image)

    log_info = ['{}\n'.format(self.img)]
    img_filename = os.path.basename(self.img)

    # Perform spotfinding
    # ... using spotfinding grid search
    if self.params.image_triage.type == 'grid_search':
      log_info.append('\n CCTBX TRIAGE grid search:')
      # Determine grid search extent
      a_min = self.params.image_triage.grid_search.area_min
      a_max = self.params.image_triage.grid_search.area_max
      a_step = (a_max - a_min) // self.params.image_triage.grid_search.step_size
      h_min = self.params.image_triage.grid_search.height_min
      h_max = self.params.image_triage.grid_search.height_max
      h_step = (h_max - h_min) // self.params.image_triage.grid_search.step_size

      # Cycle through grid points
      spotlist = []
      for spa in range(a_min, a_max + 1, a_step):
        for sph in range(h_min, h_max + 1, h_step):
          sf_params.distl.minimum_spot_area = spa
          sf_params.distl.minimum_spot_height = sph
          sf_params.distl.minimum_signal_height = sph

          # Perform spotfinding
          Bragg_spots = self.run_distl(sf_params)
          N_Bragg_spots = len(Bragg_spots)

          if N_Bragg_spots > 0:
            total_intensity = flex.sum(flex.double(Bragg_spots))
          else:
            total_intensity = 0

          spotlist.append({'bragg':N_Bragg_spots, 'ti':total_intensity,
                           'spa':spa, 'sph':sph})
          log_info.append('{:<{w}}: H = {:<2}, A = {:<2}, Bragg = {:<6.0f}  '\
                          'total intensity = {:<12.4f}'.format(img_filename, sph, spa,
                          N_Bragg_spots, total_intensity, w = len(img_filename)))

      # Pick best spotfinding result (highest total intensity seems to work for now
      pick = sorted(spotlist, key = lambda j: j['ti'])[-1]
      N_Bragg_spots = pick['bragg']
      start_sph = pick['sph']
      start_sih = pick['sph']
      start_spa = pick['spa']

    # ... using spotfinding without grid search
    else:
      # Set spotfinding params
      sf_params.distl.minimum_spot_area = self.params.cctbx.grid_search.area_median
      sf_params.distl.minimum_spot_height = self.params.cctbx.grid_search.height_median
      sf_params.distl.minimum_signal_height = self.params.cctbx.grid_search.height_median

      # Perform spotfinding
      Bragg_spots = self.run_distl(sf_params)

      # Extract spotfinding results
      N_Bragg_spots = len(Bragg_spots)
      start_sph = self.params.cctbx.grid_search.height_median
      start_sih = self.params.cctbx.grid_search.height_median
      start_spa = self.params.cctbx.grid_search.area_median

    # Determine triage success
    if N_Bragg_spots >= self.params.image_triage.min_Bragg_peaks:
      log_info.append('ACCEPTED! Selected starting point:')
      log_info.append('{:<{w}}: S = {:<2}, H = {:<2}, A = {:<2}, Bragg = {:<6.0f}'\
                      ''.format(img_filename, start_sih, start_sph, start_spa,
                                N_Bragg_spots, w = len(img_filename)))
      status = None
    else:
      log_info.append('REJECTED!')
      status = 'failed triage'

    log_entry = "\n".join(log_info)

    return status, log_entry, start_sph, start_spa
示例#20
0
def run_signal_strength_core(params, E):
    verbose = params.distl.verbose
    if params.distl.res.inner != None:
        params.distl_lowres_limit = params.distl.res.inner
    if params.distl.res.outer != None:
        params.force_method2_resolution_limit = params.distl.res.outer
        params.distl_highres_limit = params.distl.res.outer

    params.distl_force_binning = False
    params.distl_permit_binning = False
    params.wedgelimit = len(E.argv)
    params.spotfinder_header_tests = False
    Org = DistlOrganizer(verbose=True, argument_module=E, phil_params=params)
    Org.printSpots()

    #Image analysis requested by NE-CAT (Point of contact: Craig Ogata)
    for key in Org.S.images.keys():
        # List of spots between specified high- and low-resolution limits
        if Org.S.images[key].has_key('lo_pass_resolution_spots'):
            spots = Org.S.images[key]['lo_pass_resolution_spots']
        elif Org.S.images[key].has_key('inlier_spots'):
            spots = Org.S.images[key]['inlier_spots']
        else:
            spots = []

        saturation = Org.Files.imageindex(key).saturation

        #Total number of spots in this range
        print
        print "Number of focus spots on image #%d within the input resolution range: %d" % (
            key, len(spots))

        signals = flex.double()
        saturations = flex.double()

        #Each spot
        for i, spot in enumerate(spots):
            signals.append(flex.sum(spot.wts))
            saturations.append(flex.max(spot.wts) / saturation)
            if verbose:
                #peak height given in ADC units above local background
                #integrated signal strength given in pixel-ADC units above local background
                print "%2d: Area in pixels=%d Peak=%.1f, Total integrated signal=%.1f (in pixel-ADC units above background)" % (
                    i, spot.area(), flex.max(spot.wts), flex.sum(spot.wts))

                #peak signal-to-noise expressed in standard deviations above local background
                print "    Peak signal-to-noise=%.1f" % (spot.intensity())

                #peak height expressed in ADC units, without background subtraction
                image = Org.Files.imageindex(key)
                print "    Peak position x=%4d y=%4d (pixels); pixel value=%5d" % (
                    spot.max_pxl_x(), spot.max_pxl_y(),
                    image.linearintdata[(spot.max_pxl_x(), spot.max_pxl_y())])

                #Gory detail, looping through each pixel on each spot
                for j, pixel in enumerate(spot.bodypixels):
                    print "       body pixel x=%4d y=%4d; pixel value=%5d; ADC height above background=%.1f" % (
                        pixel.x, pixel.y,
                        image.linearintdata[(pixel.x, pixel.y)], spot.wts[j])
        if signals.size() > 0:
            print "Total integrated signal, pixel-ADC units above local background (just the good Bragg candidates) %d" % (
                flex.sum(
                    flex.double([
                        flex.sum(spot.wts)
                        for spot in Org.S.images[key]['inlier_spots']
                    ])))
            print "Signals range from %.1f to %.1f with mean integrated signal %.1f" % (
                flex.min(signals), flex.max(signals), flex.mean(signals))
            print "Saturations range from %.1f%% to %.1f%% with mean saturation %.1f%%" % (
                100. * flex.min(saturations), 100. * flex.max(saturations),
                100. * flex.mean(saturations))

    if params.distl.pdf_output != None:
        #later, put this in a separate module so reportlab is not imported unless requested
        from labelit.publications.sublattice.sublattice_pdf import SublatticePDF, graphic
        from labelit.publications.sublattice.sublattice_pdf import PointTransform

        class genPDF(SublatticePDF):
            def make_image_plots_detail(self):
                params.pdf_output.window_fraction = 1.0
                params.pdf_output.window_offset_x = 0.0
                params.pdf_output.window_offset_y = 0.0
                params.pdf_output.markup_inliers = True
                couple = (params.pdf_output.window_offset_x,
                          params.pdf_output.window_offset_y)
                #instead of self.R.setTransform, which requires pickled spotfinder:
                self.R.T = PointTransform()
                self.R.S = self.R.spotfinder
                self.R.T.setImage(spotfinder=self.R.S,
                                  subwindow_origin=couple,
                                  commands=params)
                self.R.title(self.image_name)
                #try:
                pil_image = graphic(filein=self.image_name,
                                    couple=couple,
                                    commands=params)
                self.R.image(pil_image)
                #except:
                #  print "failure, file %s"%self.filename
                if params.pdf_output.markup_inliers:
                    self.R.show_ellipse(
                        image_number=self.R.spotfinder.images.keys()[0],
                        tags=[
                            'goodspots', 'spots_non-ice',
                            'hi_pass_resolution_spots', 'spots_unimodal'
                        ],
                        detail=True)
                self.R.c.showPage()
                return self

        pdf = genPDF(params.distl.pdf_output)
        pdf.filename = params.distl.pdf_output
        pdf.image_name = params.distl.image
        pdf.set_spotfinder(Org.S)
        pdf.make_image_plots_detail()

    if params.distl.image_viewer == True:
        try:
            from rstbx.viewer.spotfinder_wrap import spot_wrapper
            spot_wrapper(params).display(path=params.distl.image,
                                         organizer=Org)
        except ImportError, e:
            from libtbx.utils import Sorry
            # must use phenix.wxpython for wx display
            raise Sorry(
                str(e) + " Try setting env variable PHENIX_GUI_ENVIRONMENT=1")