Exemple #1
0
    def fit_circle_slow(self,
                        beta_i,
                        ring_scan_width,
                        center_scan_width,
                        resolution=1):
        """
        Description
        ===========
        Here we want to find where the forward x-ray beam intersects 
        the detector, (x_center, y_center). 
        
        The radial profile of the diffraction pattern should exhibit
        scattering peaks, and the magnitude of the radial profile will depend
        on the chosen point for the center. Therefore, by calculating many radial profiles
        for a range of centers, and choosing the radial profile with the maximum magnitude
        across a specific radial range( e.g. across a Bragg ring), then we can
        optimize the center.

        Parameters
        ==========

        `beta_i`    tuple of (x_center, y_center, ring_position)
                    all in pixel units
        `ring_scan_width`   how many pixels to scan for ring maxima
        `center_scan_width`  how many pixels to scan in horizontal and vertical 
                            diredtions for ring maxima
        
        Returns
        =======
        tuple of optimized center parameters (x_center, y_center, max_radius)
        """

        self.resolution = resolution

        self.ring_radius_guess = round(beta_i[2])
        self.center_x_guess, self.center_y_guess =  round(beta_i[0]), \
                                        round( beta_i[1] )

        self.RadPro = RadialProfile( center=(self.center_x_guess, \
                                        self.center_y_guess),
                                img_shape=self.img.shape, mask=None,
                                minlength=self.img.shape[0] )

        self._set_radial_scan_range(ring_scan_width)
        self._define_possible_center_coordinates(center_scan_width)
        self._store_profiles_for_each_center()
        self._store_maxima_of_each_profile()
        self._find_center_with_maximum_ring_profile()
        self._set_max_ring_profile()

        return self._get_fit_parameters()
def rad_profiles(img_gen, cent, img_mask, rad_range):
    """
    Makes radial profiles for each image in a generator of images... 

    img_gen, generator of 2D numpy image arrays

    cent, where forward beam hits detector, in pixel units
        (fast_scan coordinate, slow_scan coorinate)
    
    img_mask, 2D boolean numpy array, same shape as the images
        0 is masked, 1 is not masked

    rad_range, tuple of (min radius, max radius) in pixel units,
        (radius range of the radial profile)

    """
    print("Computing radial profiles.. ")
    rp = RadialProfile(cent, mask=img_mask)
    rad_pros = [rp.calculate(i)[rad_range[0]:rad_range[1]] for i in img_gen]
    return rad_pros
def rad_profiles( img_gen, cent, img_mask, rad_range ):
    """
    Makes radial profiles for each image in a generator of images... 

    img_gen, generator of 2D numpy image arrays

    cent, where forward beam hits detector, in pixel units
        (fast_scan coordinate, slow_scan coorinate)
    
    img_mask, 2D boolean numpy array, same shape as the images
        0 is masked, 1 is not masked

    rad_range, tuple of (min radius, max radius) in pixel units,
        (radius range of the radial profile)

    """
    print("Computing radial profiles.. ")
    rp = RadialProfile( cent, mask=img_mask )
    rad_pros = [rp.calculate(i)[rad_range[0]:rad_range[1]] for i in img_gen ]
    return rad_pros
Exemple #4
0
    def fit_circle_slow(self, beta_i, ring_scan_width, center_scan_width, 
                            resolution=1 ):
        """
        Description
        ===========
        Here we want to find where the forward x-ray beam intersects 
        the detector, (x_center, y_center). 
        
        The radial profile of the diffraction pattern should exhibit
        scattering peaks, and the magnitude of the radial profile will depend
        on the chosen point for the center. Therefore, by calculating many radial profiles
        for a range of centers, and choosing the radial profile with the maximum magnitude
        across a specific radial range( e.g. across a Bragg ring), then we can
        optimize the center.

        Parameters
        ==========

        `beta_i`    tuple of (x_center, y_center, ring_position)
                    all in pixel units
        `ring_scan_width`   how many pixels to scan for ring maxima
        `center_scan_width`  how many pixels to scan in horizontal and vertical 
                            diredtions for ring maxima
        
        Returns
        =======
        tuple of optimized center parameters (x_center, y_center, max_radius)
        """

        self.resolution = resolution

        self.ring_radius_guess = round(beta_i[2])
        self.center_x_guess, self.center_y_guess =  round(beta_i[0]), \
                                        round( beta_i[1] )  
        
        self.RadPro = RadialProfile( center=(self.center_x_guess, \
                                        self.center_y_guess), 
                                img_shape=self.img.shape, mask=None, 
                                minlength=self.img.shape[0] )

        self._set_radial_scan_range(ring_scan_width)
        self._define_possible_center_coordinates(center_scan_width)
        self._store_profiles_for_each_center()
        self._store_maxima_of_each_profile()
        self._find_center_with_maximum_ring_profile()
        self._set_max_ring_profile()
       
        return self._get_fit_parameters()
Exemple #5
0
#~~~~~analysis  parameters BEGIN

img_sh = (1734, 1731)

# point where forward beam intersects detector
cent_fname = '/reg/d/psdm/cxi/cxilp6715/results/shared_files/center.npy'
mask_fname = args.mask_file
cent = np.load( cent_fname)
mask = np.load( mask_fname) 

#~~~~~ WAXS parameters
# minimium and maximum radii for calculating radial profile
waxs_rmin = 100 # pixel units
waxs_rmax = 1110
rp = RadialProfile( cent, img_sh, mask=mask  )
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


# ~~ hit findin' parameters... 

beta = 50 # smoothing factor
window_size = 200 # pixel units

# maxima detection
order = 250 # defines minimum neighborhood for local maxima (in radial pixel units)
# paraemters for peak validation
pk_range = (800, 1045) # radial pixel units, relative to the range of the radial profiles
# e.g. will ensure the detected peak lies on rad_pofile[ pk_range[0] : pk_range[1]] 

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Exemple #6
0
def calibrate(img_gen, center, wavescan, detscan, q1_sim=2.48, q2_sim=2.99,
              wavelen_guess=1.41, detdist_guess=0.051, speed='slow',
              mask=None, index_query_fname=None, scan_width=50,
              beta=20, window_size=40, factor=0.007, pixsize=0.00005):
    """Use this function to calibrate the detector distance and the wavelength
    for a particular group of images (e.g. from a run)"""

    rad1_guess = int(
        round(
            np.tan(
                2 *
                np.arcsin(
                    q1_sim *
                    wavelen_guess /
                    4. /
                    np.pi)) *
            detdist_guess /
            pixsize))
    rad2_guess = int(
        round(
            np.tan(
                2 *
                np.arcsin(
                    q2_sim *
                    wavelen_guess /
                    4. /
                    np.pi)) *
            detdist_guess /
            pixsize))
    rad1_scan = np.arange(rad1_guess - scan_width, rad1_guess + scan_width)
    rad2_scan = np.arange(rad2_guess - scan_width, rad2_guess + scan_width)

    radpro = RadialProfile(center, img_shape=mask.shape, mask=mask)
    radpro.set_params(
        wavelen=wavelen_guess,
        detdist=detdist_guess,
        pixsize=pixsize,
        factor=factor)

    detdists, wavelens, scores = [], [], []

    for img in img_gen:
        print ("\nCalibrating a new image...")
        if speed == 'slow':
            rp1 = radpro.calculate_using_fetch(
                img, rad1_scan, index_query_fname=index_query_fname)
            rp2 = radpro.calculate_using_fetch(
                img, rad2_scan, index_query_fname=index_query_fname)
        else:
            rp1 = radpro.calculate(img)[rad1_scan]
            rp2 = radpro.calculate(img)[rad2_scan]

        sm_rp1 = smooth(rp1, beta, window_size)
        sm_rp2 = smooth(rp2, beta, window_size)
        r1 = np.argmax(sm_rp1) + rad1_scan[0]
        r2 = np.argmax(sm_rp2) + rad2_scan[0]

        print("  Found ring1 at %d compared to %d." % (r1, rad1_guess))
        print("  Found ring2 at %d compared to %d." % (r2, rad2_guess))
        print("  Calibrating...")

        detdist, wavelen, score = calibrate_parameters(
            r1,
            r2,
            q1_sim,
            q2_sim,
            detscan,
            wavescan,
            pixsize)

        print(
            "  New detector distance calibrated from %.4f --> %.4f" %
            (detdist_guess, detdist))
        print(
            "  New wavelength calibrated from %.4f --> %.4f" %
            (wavelen_guess, wavelen))

        rad1 = int(
            round(
                np.tan(
                    2 *
                    np.arcsin(
                        q1_sim *
                        wavelen /
                        4. /
                        np.pi)) *
                detdist /
                pixsize))
        rad2 = int(
            round(
                np.tan(
                    2 *
                    np.arcsin(
                        q2_sim *
                        wavelen /
                        4. /
                        np.pi)) *
                detdist /
                pixsize))

        detdists.append(detdist)
        wavelens.append(wavelen)
        scores.append(score)

    return detdists, wavelens, scores
Exemple #7
0
cent = np.load(cent_fname)
# f_mask= h5py.File(mask_fname,'r')
#####
###Also have a common mask for calibration purpose
basic_mask = np.load(
    '/reg/d/psdm/cxi/cxilr6716/results/masks/basic_psana_mask.npy')
# use basic mask for now
mask = np.load('/reg/d/psdm/cxi/cxilr6716/results/masks/basic_psana_mask.npy')
# mask = f_mask['mask'].value
####

#~~~~~ WAXS parameters
# minimium and maximum radii for calculating radial profile
waxs_rmin = 100  # pixel units
waxs_rmax = 1110
rp = RadialProfile(cent, img_sh, mask=mask)
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~ hit findin' parameters...
waterpeak_filter = args.waterpeak_filter > 0
beta = 50  # smoothing factor
window_size = 200  # pixel units

# maxima detection
order = 250  # defines minimum neighborhood for local maxima (in radial pixel units)
# paraemters for peak validation
pk_range = (
    604, 804
)  # radial pixel units, relative to the range of the radial profiles
# e.g. will ensure the detected peak lies on rad_pofile[ pk_range[0] : pk_range[1]]
Exemple #8
0
import sys
sys.append("../.asu_tools/lib/python")
sys.path.append("../.asu_tools/lib/python")
from loki.RingData import RingFit
rf = RingFit(img)
#xi,yi = (
img.shape
xi,yi = (1440,1440)
get_ipython().run_line_magic('pinfo', 'rf.fit_circle_fast')
#rf.fit_circle_fast( (xi,yi, )
xi-1137
ri = 303
rf.fit_circle_fast( (xi,yi,ri ), num_fitting_pts=5000, num_high_pix=100, ring_width=100)
x,y,r = array([ 1450.10619788,  1430.22695615,   316.51128542])
from loki.RingData import RadialProfile
rp = RadialProfile( (xi,yi), img.shape)
figure(2);plot( rp.calculate(img))
rp = RadialProfile( (x,y), img.shape)
figure(2);plot( rp.calculate(img))
#rf.fit_circle_fast( (xi,yi,ri ), num_fitting_pts=5000, num_high_pix=100, ring_width=100)
circ = Circle(xy=(x,y), radius=r, fc='none', ec='r')
figure(1);gca().add_patch(circ);draw()
rf.fit_circle_fast( (xi,yi,ri ), num_fitting_pts=10000, num_high_pix=100, ring_width=150)
xmymr
x,y
rf.fit_circle_slow?#( (xi,yi,ri ),)
get_ipython().run_line_magic('pinfo', 'rf.fit_circle_slow')
get_ipython().run_line_magic('pinfo', 'rf.fit_circle_slow')
rf.fit_circle_slow( (x,y,r ), 50,30,2)
get_ipython().run_line_magic('pinfo', 'rf.fit_circle_slow')
rf.fit_circle_slow( (x,y,r ),  50.,30.,2.)
Exemple #9
0
class RingFit:
    def __init__( self, img ):
        '''
        Initialize a class for fitting shapes to images with shapes on them
        ====================================================================
        img - 2d float np.array
        '''

        self._set_circle_model()
        self._set_circle_model_fast()
        self._set_ellipse_model()
        
        self.img = np.copy(img)
        self._store_1D_image_index_arrays()


    def _set_circle_model_fast( self):
        f_circle  = lambda beta,x : ( x[0] - beta[0] )**2 \
                                  + ( x[1] - beta[1])**2 - beta[2]**2
        self.circle_model_fast = odr.Model(f_circle, 
            implicit=True,
            estimate=self.calc_estimate,
            fjacd=self.circle_jacobian_data, 
            fjacb=self.circle_jacobian_beta)

    def _set_circle_model(self):
#       Equation for a circle        
        f_circle  = lambda beta,x : ( x[0] - beta[0] )**2 \
                                  + ( x[1] - beta[1])**2 - beta[2]**2
        self.circle_model  = odr.Model( f_circle, implicit=True)

    def _set_ellipse_model(self):
#       Equation for an ellipse
        f_ellipse = lambda beta,x : (1/beta[2]/beta[2])*( x[0] -beta[0])**2 \
                                  + (1/beta[3]/beta[3])*( x[1] -beta[1])**2-1
        self.ellipse_model = odr.Model( f_ellipse, implicit=True)

    def _store_1D_image_index_arrays(self):
#       make 2d and 1d index arrays       
        self.y, self.x = np.indices( self.img.shape )
        self.x1D   = self.x.ravel()
        self.y1D   = self.y.ravel()
        

    def fit_circle_fast( self, beta_i, num_fitting_pts=5000, 
                ring_width=20 , num_high_pix=20, 
                return_mean = False):
        '''
        Fit a circle to a ring image
        ============================== 
        beta_i          - float tuple , ( x_center, y_center,radius )
        num_fitting_pts - int, number of pixels to include in fit 
        ring_width      - int, width ring-like region on image that 
                            contains ring of interest (pixels units)
        num_high_pix    - int, remove this many pixels before 
                            running fit (removes artificial high pixels 
                            that might bias the fit)
        '''

        self.ring_width = ring_width
        self._prepare_fitting_framework( beta_i, num_high_pix, num_fitting_pts)
        self._fit_a_model_fast(self.circle_model_fast, param_guess=beta_i)
    
        x,y = self._get_xy()
        a,b,r  = self.beta_fit
        Ri = np.sqrt( (x-a)**2 + (y-b)**2)
        self.residual = np.sum((Ri-r)**2)
        mean_intens = self.img1D[ self.fit_indices].mean()
        return self.beta_fit, self.residual, mean_intens

    def fit_circle( self, beta_i, num_fitting_pts=5000, 
                ring_width=20 , num_high_pix=20, 
                return_mean = False):
        '''
        Fit a circle to a ring image
        ============================== 
        beta_i          - float tuple , ( x_center, y_center,radius )
        num_fitting_pts - int, number of pixels to include in fit 
        ring_width      - int, width ring-like region on image that 
                            contains ring of interest (pixels units)
        num_high_pix    - int, remove this many pixels before 
                            running fit (removes artificial high pixels 
                            that might bias the fit)
        '''

        self.ring_width = ring_width
        self._prepare_fitting_framework( beta_i, num_high_pix, num_fitting_pts)
        self._fit_a_model(self.circle_model, param_guess=beta_i)

        x,y = self._get_xy()
        a,b,r  = self.beta_fit
        Ri = np.sqrt( (x-a)**2 + (y-b)**2)
        self.residual = np.sum((Ri-r)**2)
        
        mean_intens = self.img1D[ self.fit_indices].mean()

        return self.beta_fit, self.residual, mean_intens

    def _get_xy(self):
        """returns the x and y points used in _fit_a_model"""
        return self.pts[0], self.pts[1]

    def fit_ellipse(self, beta_i  ,num_fitting_pts=5000, 
                        ring_width=40,num_high_pix = 20):
        '''
        Fit an ellipse to a ring image
        ============================== 
        beta_i          - float tuple , (x_center, y_center, x_radius,y_radius)

        num_fitting_pts - int, number of pixels to include in fit 
        
        ring_width      - int, width ring-like region on image that contains 
                                ring of interest (pixels units)
        
        num_high_pix    - int, remove this many pixels before running fit 
                                (removes artificial high pixels that might
                                bias the fit)
        '''
        
        self.ring_width = ring_width
        self._prepare_fitting_framework( beta_i, num_high_pix, num_fitting_pts)
        self._fit_a_model( self.ellipse_model, param_guess=beta_i)
        return self.beta_fit


    def _prepare_fitting_framework(self, ring_guess, num_high_pix, 
                                    num_fitting_pts):
#       set the 1D image
        self.img1D = np.copy(self.img.ravel())
        self._mask_1D_image(ring_guess)
        self._remove_highest(num_high_pix)
        num_fitting_pts = self._check_num_fitting_points(num_fitting_pts)
#       find indices of fit pixels in order of decreasing intensity 
        self.fit_indices = np.argsort(self.img1D)[::-1][: num_fitting_pts]

    def _mask_1D_image(self, beta_i):
#       radius of each pixel 
        radius_value = np.sqrt((self.x1D - beta_i[0])**2 + \
                            (self.y1D - beta_i[1])**2 )
        self.img1D[ radius_value > beta_i[2] + self.ring_width/2 ] = 0
        self.img1D[ radius_value < beta_i[2] - self.ring_width/2 ] = 0
        

    def _remove_highest( self, num_high_pix):
#       removes the highest pixels so they don't corrupt the fit 
#           (e.g. bad pixels)
        high_inds = np.argsort( self.img1D )[:num_high_pix]
        self.img1D[ high_inds ] = 0

    def _check_num_fitting_points(self, num_fitting_pts):
        num_pts = np.where( self.img1D > 0 )[0].shape[0]
        if num_fitting_pts >= num_pts :
            num_fitting_pts = num_pts / 2
        return num_fitting_pts

       
    @staticmethod
    def circle_jacobian_beta( beta, x):
        xc,yc,r = beta
        xi,yi = x
        df_db    = np.empty(( len(beta), x.shape[1]))
        df_db[0] =  2*(xc-xi)                     # d_f/dxc
        df_db[1] =  2*(yc-yi)                     # d_f/dyc
        df_db[2] = -2*r                           # d_f/dr
        return df_db

    @staticmethod
    def circle_jacobian_data(beta, x):
        xc,yc,r = beta
        xi,yi = x
        df_dx    = np.empty_like( x )
        df_dx[0] =  2*(xi-xc)                     # d_f/dxi
        df_dx[1] =  2*(yi-yc)                     # d_f/dyi
        return df_dx
   
    @staticmethod
    def calc_estimate(data):
        xc0, yc0 = data.x.mean(axis=1)
        r0 = np.sqrt((data.x[0]-xc0)**2 +(data.x[1] -yc0)**2).mean()
        return xc0, yc0, r0


    def _fit_a_model_fast(self, model, param_guess):
#       use odr module to fit data to model
        self.pts = np.row_stack( [self.x1D[ self.fit_indices], 
                            self.y1D[ self.fit_indices]])
        
        lsc_data = odr.Data( self.pts , y=1)
        lsc_odr   = odr.ODR(lsc_data, model)#  param_guess)
        lsc_odr.set_job(deriv=3) 
        lsc_odr.set_iprint(iter=1, iter_step=1)
        lsc_out = lsc_odr.run()
        self.beta_fit = lsc_out.beta

    def _fit_a_model(self, model, param_guess):
#       use odr module to fit data to model
        self.pts = np.row_stack( [self.x1D[ self.fit_indices], 
                            self.y1D[ self.fit_indices]])
        lsc_data = odr.Data( self.pts , y=1)
        lsc_odr = odr.ODR( lsc_data, model, param_guess)
        lsc_out = lsc_odr.run()
        self.beta_fit = lsc_out.beta


    def fit_circle_slow(self, beta_i, ring_scan_width, center_scan_width, 
                            resolution=1 ):
        """
        Description
        ===========
        Here we want to find where the forward x-ray beam intersects 
        the detector, (x_center, y_center). 
        
        The radial profile of the diffraction pattern should exhibit
        scattering peaks, and the magnitude of the radial profile will depend
        on the chosen point for the center. Therefore, by calculating many radial profiles
        for a range of centers, and choosing the radial profile with the maximum magnitude
        across a specific radial range( e.g. across a Bragg ring), then we can
        optimize the center.

        Parameters
        ==========

        `beta_i`    tuple of (x_center, y_center, ring_position)
                    all in pixel units
        `ring_scan_width`   how many pixels to scan for ring maxima
        `center_scan_width`  how many pixels to scan in horizontal and vertical 
                            diredtions for ring maxima
        
        Returns
        =======
        tuple of optimized center parameters (x_center, y_center, max_radius)
        """

        self.resolution = resolution

        self.ring_radius_guess = round(beta_i[2])
        self.center_x_guess, self.center_y_guess =  round(beta_i[0]), \
                                        round( beta_i[1] )  
        
        self.RadPro = RadialProfile( center=(self.center_x_guess, \
                                        self.center_y_guess), 
                                img_shape=self.img.shape, mask=None, 
                                minlength=self.img.shape[0] )

        self._set_radial_scan_range(ring_scan_width)
        self._define_possible_center_coordinates(center_scan_width)
        self._store_profiles_for_each_center()
        self._store_maxima_of_each_profile()
        self._find_center_with_maximum_ring_profile()
        self._set_max_ring_profile()
       
        return self._get_fit_parameters()
        

    def _set_radial_scan_range(self, ring_scan_width):
        self.ring_scan_start = self.ring_radius_guess - int( ring_scan_width / 2 )
        self.ring_scan_stop = self.ring_radius_guess + int( ring_scan_width / 2 )

        
    def _define_possible_center_coordinates(self, center_scan_width):
        num_center_scan_points = int( center_scan_width / self.resolution) 
        scan_range_x = np.linspace(self.center_x_guess- \
                                        center_scan_width / 2. , 
                                    self.center_x_guess + \
                                        center_scan_width / 2. , 
                                    num_center_scan_points )
        scan_range_y = np.linspace(self.center_y_guess- \
                                        center_scan_width / 2. , 
                                    self.center_y_guess + \
                                        center_scan_width / 2. , 
                                    num_center_scan_points )
        
        self.possible_centers = [ (x,y) for x in scan_range_x
                            for y in scan_range_y]

    def _store_profiles_for_each_center(self):
        self.possible_ring_profiles = []
        for center in self.possible_centers:
            self.RadPro.update_center( center)
            radial_profile = self.RadPro.calculate(self.img) 
            ring_profile = radial_profile[ self.ring_scan_start:\
                                            self.ring_scan_stop]
            self.possible_ring_profiles.append( ring_profile)
    
    def _store_maxima_of_each_profile(self):
        self.ring_profile_maxima = [ max( ring_profile) 
                        for ring_profile in self.possible_ring_profiles ]
        
    def _find_center_with_maximum_ring_profile(self):
        self.fit_center = self.possible_centers[ np.argmax(self.ring_profile_maxima) ]
        
    def _set_max_ring_profile(self):
        self.max_profile = self.possible_ring_profiles[ \
                                np.argmax(self.ring_profile_maxima) ]
    
    def _get_fit_parameters(self):
        fit_radius = np.argmax( self.max_profile ) + self.ring_scan_start
        return ( self.fit_center[0], self.fit_center[1], fit_radius )
Exemple #10
0
def calibrate(img_gen,
              center,
              wavescan,
              detscan,
              q1_sim=2.48,
              q2_sim=2.99,
              wavelen_guess=1.41,
              detdist_guess=0.051,
              speed='slow',
              mask=None,
              index_query_fname=None,
              scan_width=50,
              beta=20,
              window_size=40,
              factor=0.007,
              pixsize=0.00005):
    """Use this function to calibrate the detector distance and the wavelength
    for a particular group of images (e.g. from a run)"""

    rad1_guess = int(
        round(
            np.tan(2 * np.arcsin(q1_sim * wavelen_guess / 4. / np.pi)) *
            detdist_guess / pixsize))
    rad2_guess = int(
        round(
            np.tan(2 * np.arcsin(q2_sim * wavelen_guess / 4. / np.pi)) *
            detdist_guess / pixsize))
    rad1_scan = np.arange(rad1_guess - scan_width, rad1_guess + scan_width)
    rad2_scan = np.arange(rad2_guess - scan_width, rad2_guess + scan_width)

    radpro = RadialProfile(center, img_shape=mask.shape, mask=mask)
    radpro.set_params(wavelen=wavelen_guess,
                      detdist=detdist_guess,
                      pixsize=pixsize,
                      factor=factor)

    detdists, wavelens, scores = [], [], []

    for img in img_gen:
        print("\nCalibrating a new image...")
        if speed == 'slow':
            rp1 = radpro.calculate_using_fetch(
                img, rad1_scan, index_query_fname=index_query_fname)
            rp2 = radpro.calculate_using_fetch(
                img, rad2_scan, index_query_fname=index_query_fname)
        else:
            rp1 = radpro.calculate(img)[rad1_scan]
            rp2 = radpro.calculate(img)[rad2_scan]

        sm_rp1 = smooth(rp1, beta, window_size)
        sm_rp2 = smooth(rp2, beta, window_size)
        r1 = np.argmax(sm_rp1) + rad1_scan[0]
        r2 = np.argmax(sm_rp2) + rad2_scan[0]

        print("  Found ring1 at %d compared to %d." % (r1, rad1_guess))
        print("  Found ring2 at %d compared to %d." % (r2, rad2_guess))
        print("  Calibrating...")

        detdist, wavelen, score = calibrate_parameters(r1, r2, q1_sim, q2_sim,
                                                       detscan, wavescan,
                                                       pixsize)

        print("  New detector distance calibrated from %.4f --> %.4f" %
              (detdist_guess, detdist))
        print("  New wavelength calibrated from %.4f --> %.4f" %
              (wavelen_guess, wavelen))

        rad1 = int(
            round(
                np.tan(2 * np.arcsin(q1_sim * wavelen / 4. / np.pi)) *
                detdist / pixsize))
        rad2 = int(
            round(
                np.tan(2 * np.arcsin(q2_sim * wavelen / 4. / np.pi)) *
                detdist / pixsize))

        detdists.append(detdist)
        wavelens.append(wavelen)
        scores.append(score)

    return detdists, wavelens, scores
data_fname = '/reg/d/psdm/cxi/cxilp6715/scratch/analysis/run%(key)s/small_data-%(key)s.hdf5' % {
    'key': run,
}
cent_fname = '/reg/data/ana14/cxi/cxilp6715/scratch/bin/center.npy'
mask_fname = '/reg/data/ana14/cxi/cxilp6715/scratch/bin/mask_rough.npy'
#   point where forward beam intersects detector
cent = np.load(cent_fname)
mask = np.load(mask_fname)

img_sh = mask.shape

#   minimium and maximum radii for calculating radial profile
rmin = 150  #50 # pixel units
rmax = 800  #1110

rp = RadialProfile(cent, img_sh, mask)

print("Loading data")
f = h5py.File(data_fname, 'r')
dat = f['assembled']

print("Computing the radial profiles")
radprof = np.array([rp.calculate(img)[rmin:rmax] for img in dat])

#plot radial profile
#for i in range( 0,len(radprof),10):
#    plt.plot(radprof[i], 'b')
#plt.show()

print("About to cluster...")
# CLUSTERING NOW #