Пример #1
0
    def fit(self, table ) :
        """TODO: document"""
        log = get_logger()

        #- identify ADC setups
        adc12=(np.array(table['ADC1'])+1000*np.array(table['ADC2']))
        uadc12 = np.unique(adc12)
        nconfig = len(uadc12)
        
        self.adc1     = np.zeros(nconfig,dtype=float)
        self.adc2     = np.zeros(nconfig,dtype=float)
        self.scale    = np.zeros(nconfig,dtype=float)
        self.rotation = np.zeros(nconfig,dtype=float)
        self.offset_x = np.zeros(nconfig,dtype=float)
        self.offset_y = np.zeros(nconfig,dtype=float)
        self.zbpolids = None
        self.zbcoeffs = list()
        
        for config, adc12v in enumerate(uadc12) :
            selection = (adc12==adc12v)
            self.adc1[config]=table['ADC1'][selection][0]
            self.adc2[config]=table['ADC2'][selection][0]
            print("Fitting ADC1={} ADC2={}".format(self.adc1[config],self.adc2[config]))
            
            #- Get reduced coordinates
            rxtan, rytan = _reduce_xytan(table['X_TAN'][selection], table['Y_TAN'][selection])
            rxfp, ryfp = _reduce_xyfp(table['X_FP'][selection], table['Y_FP'][selection])
            
            

            #################################################################
            ## CHOICE OF POLYNOMIALS IS HERE
            ## 
            polids = np.array([2, 5, 6, 9, 20, 27, 28, 29, 30],dtype=int)
            #################################################################
            #- Perform fit
            if 1 : # it's a bit better
                scale, rotation, offset_x, offset_y, zbpolids, zbcoeffs = fit_scale_rotation_offset(rxtan, rytan, rxfp, ryfp, fitzb=True, polids=polids)
                self.scale[config] = scale
                self.rotation[config] = rotation
                self.offset_x[config] = offset_x
                self.offset_y[config] = offset_y
            else :
                zbpolids, zbcoeffs, dx, dy =  fitZhaoBurge(rxtan, rytan, rxfp, ryfp, polids=polids)
            
                self.scale[config] = 1
                self.rotation[config] = 0.
                self.offset_x[config] = 0.
                self.offset_y[config] = 0.
                
            if self.zbpolids is None :
                self.zbpolids = zbpolids
            else :
                assert(np.all(self.zbpolids==zbpolids))
            self.zbcoeffs.append(zbcoeffs)

            #- Goodness of fit
            #xfp_fit, yfp_fit = self.tan2fp(table['X_TAN'][selection], table['Y_TAN'][selection])
            #dx = (table['X_FP'][selection] - xfp_fit)
            #dy = (table['Y_FP'][selection] - yfp_fit)
            #dr = np.sqrt(dx**2 + dy**2)
            #log.info('Mean, median, RMS distance = {:.1f}, {:.1f}, {:.1f} um'.format(
            #    1000*np.mean(dr), 1000*np.median(dr), 1000*np.sqrt(np.mean(dr**2))))

        self.zbcoeffs = np.vstack(self.zbcoeffs)
Пример #2
0
    def fit(self, spots, metrology=None, update_spots=False):
        """TODO: document"""
        log = get_logger()
        if metrology is not None:
            self.metrology = metrology
        else:
            filename = resource_filename('desimeter', "data/fp-metrology.csv")
            if not os.path.isfile(filename):
                log.error("cannot find {}".format(filename))
                raise IOError("cannot find {}".format(filename))
            log.info("reading fiducials metrology in {}".format(filename))
            self.metrology = Table.read(filename, format="csv")

        #- Trim spots to just fiducial spots (not posioners, not unmatchs spots)
        ii = (spots['LOCATION'] > 0) & (spots['PINHOLE_ID'] > 0)
        fidspots = spots[ii]

        #- trim metrology to just the ones that have spots
        fidspots_pinloc = fidspots['LOCATION'] * 10 + fidspots['PINHOLE_ID']
        metro_pinloc = self.metrology['LOCATION'] * 10 + self.metrology[
            'PINHOLE_ID']
        jj = np.in1d(metro_pinloc, fidspots_pinloc)
        metrology = self.metrology[jj]

        #- Sort so that they match each other
        fidspots.sort(keys=('LOCATION', 'PINHOLE_ID'))
        metrology.sort(keys=('LOCATION', 'PINHOLE_ID'))
        assert np.all(fidspots['LOCATION'] == metrology['LOCATION'])
        assert np.all(fidspots['PINHOLE_ID'] == metrology['PINHOLE_ID'])

        #- Get reduced coordinates
        rxpix, rypix = _reduce_xyfvc(fidspots['XPIX'], fidspots['YPIX'])
        rxfp, ryfp = _reduce_xyfp(metrology['X_FP'], metrology['Y_FP'])

        #- Perform fit
        #- Perform fit
        scale, rotation, offset_x, offset_y, zbpolids, zbcoeffs = \
            fit_scale_rotation_offset(rxpix, rypix, rxfp, ryfp, fitzb=True)

        self.scale = scale
        self.rotation = rotation
        self.offset_x = offset_x
        self.offset_y = offset_y
        self.zbpolids = zbpolids
        self.zbcoeffs = zbcoeffs

        #- Goodness of fit
        xfp_fidmeas, yfp_fidmeas = self.fvc2fp(fidspots['XPIX'],
                                               fidspots['YPIX'])
        dx = (metrology['X_FP'] - xfp_fidmeas)
        dy = (metrology['Y_FP'] - yfp_fidmeas)
        dr = np.sqrt(dx**2 + dy**2)
        log.info(
            'Mean, median, RMS distance = {:.1f}, {:.1f}, {:.1f} um'.format(
                1000 * np.mean(dr), 1000 * np.median(dr),
                1000 * np.sqrt(np.mean(dr**2))))

        if update_spots:
            xfp_meas, yfp_meas = self.fvc2fp(spots['XPIX'], spots['YPIX'])
            spots["X_FP"] = xfp_meas
            spots["Y_FP"] = yfp_meas

            #- the metrology table is in a different order than the original
            #- spots table, which is also a superset of the fidicual spots
            #- matched to the metrology, so find the sorting of the metrology
            #- that will match the order that they appear in the spots table
            iifid = (spots['LOCATION'] > 0) & (spots['PINHOLE_ID'] > 0)
            fidspots_pinloc = (spots['LOCATION'] * 10 +
                               spots['PINHOLE_ID'])[iifid]
            metro_pinloc = metrology['LOCATION'] * 10 + metrology['PINHOLE_ID']

            ii = np.argsort(np.argsort(fidspots_pinloc))
            jj = np.argsort(metro_pinloc)
            kk = jj[ii]

            #- Check that we got that dizzying array of argsorts right
            assert np.all(
                spots['LOCATION'][iifid] == metrology['LOCATION'][kk])
            assert np.all(
                spots['PINHOLE_ID'][iifid] == metrology['PINHOLE_ID'][kk])

            #- Update the spots table with metrology columns
            #- TODO: used masked arrays in addition to default=0
            spots["X_FP_METRO"] = np.zeros(len(spots))
            spots["Y_FP_METRO"] = np.zeros(len(spots))
            spots["Z_FP_METRO"] = np.zeros(len(spots))
            spots["X_FP_METRO"][iifid] = metrology['X_FP'][kk]
            spots["Y_FP_METRO"][iifid] = metrology['Y_FP'][kk]
            spots["Z_FP_METRO"][iifid] = metrology['Z_FP'][kk]
Пример #3
0
    def fit(self,
            spots,
            metrology=None,
            update_spots=False,
            zbfit=True,
            fixed_scale=False,
            fixed_rotation=False):
        """
        TODO: document
        """

        log = get_logger()
        if metrology is not None:
            self.metrology = metrology
        else:
            self.metrology = load_metrology()

        #- Trim spots to just fiducial spots (not posioners, not unmatchs spots)
        ii = (spots['LOCATION'] >= 0) & (spots['PINHOLE_ID'] > 0)
        fidspots = spots[ii]

        #- trim metrology to just the ones that have spots
        fidspots_pinloc = fidspots['LOCATION'] * 10 + fidspots['PINHOLE_ID']
        metro_pinloc = self.metrology['LOCATION'] * 10 + self.metrology[
            'PINHOLE_ID']
        jj = np.in1d(metro_pinloc, fidspots_pinloc)
        metrology = self.metrology[jj]

        #- Sort so that they match each other
        fidspots.sort(keys=('LOCATION', 'PINHOLE_ID'))
        metrology.sort(keys=('LOCATION', 'PINHOLE_ID'))
        assert np.all(fidspots['LOCATION'] == metrology['LOCATION'])
        assert np.all(fidspots['PINHOLE_ID'] == metrology['PINHOLE_ID'])

        #- Get reduced coordinates
        rxpix, rypix = self._reduce_xyfvc(fidspots['XPIX'], fidspots['YPIX'])
        rxfp, ryfp = self._reduce_xyfp(metrology['X_FP'], metrology['Y_FP'])

        if fixed_rotation:
            fixed_rotation_value = self.rotation
            log.info(
                "Use fixed rotation = {:5.4f}".format(fixed_rotation_value))
        else:
            fixed_rotation_value = None

        if fixed_scale:
            fixed_scale_value = self.scale
            log.info("Use fixed scale = {:5.4f}".format(fixed_scale_value))
        else:
            fixed_scale_value = None

        res = fit_scale_rotation_offset(rxpix,
                                        rypix,
                                        rxfp,
                                        ryfp,
                                        fitzb=zbfit,
                                        zbpolids=self.zbpolids,
                                        zbcoeffs=self.zbcoeffs,
                                        fixed_scale=fixed_scale_value,
                                        fixed_rotation=fixed_rotation_value)
        self.scale = res[0]
        self.rotation = res[1]
        self.offset_x = res[2]
        self.offset_y = res[3]
        if zbfit:
            self.zbpolids = res[4]
            self.zbcoeffs = res[5]

        #- Goodness of fit
        xfp_fidmeas, yfp_fidmeas = self.fvc2fp(fidspots['XPIX'],
                                               fidspots['YPIX'])
        dx = (metrology['X_FP'] - xfp_fidmeas)
        dy = (metrology['Y_FP'] - yfp_fidmeas)
        dr = np.sqrt(dx**2 + dy**2)
        log.info(
            'Mean, median, RMS distance = {:.1f}, {:.1f}, {:.1f} um'.format(
                1000 * np.mean(dr), 1000 * np.median(dr),
                1000 * np.sqrt(np.mean(dr**2))))

        if update_spots:
            xfp_meas, yfp_meas = self.fvc2fp(spots['XPIX'], spots['YPIX'])
            spots["X_FP"] = xfp_meas
            spots["Y_FP"] = yfp_meas

            #- the metrology table is in a different order than the original
            #- spots table, which is also a superset of the fidicual spots
            #- matched to the metrology, so find the sorting of the metrology
            #- that will match the order that they appear in the spots table
            iifid = (spots['LOCATION'] > 0) & (spots['PINHOLE_ID'] > 0)
            fidspots_pinloc = (spots['LOCATION'] * 10 +
                               spots['PINHOLE_ID'])[iifid]
            metro_pinloc = metrology['LOCATION'] * 10 + metrology['PINHOLE_ID']

            ii = np.argsort(np.argsort(fidspots_pinloc))
            jj = np.argsort(metro_pinloc)
            kk = jj[ii]

            #- Check that we got that dizzying array of argsorts right
            assert np.all(
                spots['LOCATION'][iifid] == metrology['LOCATION'][kk])
            assert np.all(
                spots['PINHOLE_ID'][iifid] == metrology['PINHOLE_ID'][kk])

            #- Update the spots table with metrology columns
            #- TODO: used masked arrays in addition to default=0
            spots["X_FP_METRO"] = np.zeros(len(spots))
            spots["Y_FP_METRO"] = np.zeros(len(spots))
            spots["Z_FP_METRO"] = np.zeros(len(spots))
            spots["X_FP_METRO"][iifid] = metrology['X_FP'][kk]
            spots["Y_FP_METRO"][iifid] = metrology['Y_FP'][kk]
            spots["Z_FP_METRO"][iifid] = metrology['Z_FP'][kk]