def getCorrectionFunc(order=5,Imat=None,p=None,pc=None,fraclims_dc=[.9,1.1],wrapit=True): """ Getting nonlinear correction factors form a calibration dataset consiting of: i0 array of intensity/parameter values the calibration has been made for Imat 2D array of the corresponding reference patterns, in each row there is one ravelled array of each intensity bin in i0. i0_wp a working point around which a correction polynomial will be developed for each pixel. order the polynomial order up to which will be deveoped. fraclims_dc relative factor for the i0,Imat data limits which are used to determine the working point location. Returns corrFunc(i,D), a function that takes a flat array of intensity/ parameter values as well as a Matrix D of flattened patterns the correction is to be applied on (rows in D are again corresponding to each intensity in i). """ if pc is None: pc = np.mean(p) msk = tools.filtvec(p,pc*np.asarray(fraclims_dc)) p0 = tools.polyFit(p[msk],Imat[msk,...],2) dc = tools.polyVal(p0,pc) comps = tools.polyFit(p-pc,Imat-dc,order,removeOrders=[0]) compsder = tools.polyDer(comps) c = lambda(i): tools.polyVal(comps,i-np.asarray(tools.iterfy(pc)))+dc c_prime = lambda(i): tools.polyVal(compsder,i-np.asarray(tools.iterfy(pc))) t = lambda(i): (c_prime(pc).T * (i-pc)).T + dc cprimeic = c_prime(pc) dcorr_const = -cprimeic*pc + c(pc) - t(0) def corrFunc(D,i): i = i.ravel() return cprimeic * ( i + ((D-c(i))/c_prime(i)).swapaxes(0,-1) ).swapaxes(0,-1) if wrapit: def corrFuncTransposed(D,i=None,normalize=False,fillValue=np.nan): if i is None: i = np.apply_over_axes(np.nansum,D,range(np.ndim(D)-1)).ravel() cr = corrFunc(D.swapaxes(0,-1),i).swapaxes(0,-1) if normalize: cr/=i cr[:,~np.logical_and(i>np.min(i0),i<np.max(i0))] *= fillValue return cr #else: #return corrFunc(D.swapaxes(0,-1),i).swapaxes(0,-1) corrFuncWrapped = wrapFunc(corrFuncTransposed,transposeStack=True) def corrFuncWrap(D,i=None,normalize=False,fillValue=np.nan): if i is not None: Df = D*i.filter([np.min(i0),np.max(i0)]).ones() else: Df = D return corrFuncWrapped(Df,i=i,normalize=normalize,fillValue=fillValue) return corrFuncWrap else: return corrFunc
def __init__(self,Nx=1000,Ny=1000,path_calib='newest'): self._path_calib = path_calib self._path = os.path.abspath(__file__) self._xpx = [] self._ypx = [] self.load_coordinates() xmn = np.min(self.xpx) xmx = np.max(self.xpx) self.xVec = np.linspace(xmn,xmx,Nx) self._binxVec = np.linspace(xmn-(xmx-xmn)/Nx/2, xmx+(xmx-xmn)/Nx/2,Nx+1) ymn = np.min(self.ypx) ymx = np.max(self.ypx) self.yVec = np.linspace(ymn,ymx,Ny) self._binyVec = np.linspace(ymn-(ymx-ymn)/Ny/2, ymx+(ymx-ymn)/Ny/2,Ny+1) self.shp = np.shape(self.xpx) self.shpPattern = (Ny,Nx) xind = np.digitize(self.xpx.ravel(),self._binxVec) yind = np.digitize(self.ypx.ravel(),self._binyVec) self.binning = np.ravel_multi_index((yind-1,xind-1),(Ny,Nx)) self.numperbin = np.bincount(self.binning) self.pixssz = np.array([110.,110])*1e-6 self.bin = wrapFunc(self._bin,isPerEvt=True)
import numpy as np from ixppy import wrapFunc import copy numpyfuncs = ["mean", "std", "sum", "exp", "nansum", "average", "apply_over_axes", "polyval", "isnan", "any"] for funName in numpyfuncs: exec("%s = wrapFunc(np.%s)" % (funName, funName)) def Nansum(data): o = np.squeeze(np.apply_over_axes(np.nansum, data, range(1, np.ndim(data)))) return np.atleast_2d(o).T nansum = wrapFunc(Nansum, transposeStack=False) def MaskNan(data, mask): if len(data) > 0: dat = data.astype(np.float) dat[:, mask] = np.nan return dat else: return data maskNan = wrapFunc(MaskNan)
def getCorrectionFunc(dmat=None,i=None,ic=None,order=5,sc=None,search_dc_limits=None, removeDependence=True): """ Create nonlinear correction function from a calibration dataset consiting of: i array of intensity values (floats) of the calibration dmat ND array of the reference patterns corresponding to values of i, The first dimension corresponds to the calibration intensity values and has the same length as i. ic A working point around which a polynomial correction will be developed for each pixel. order the polynomial order up to which the correction will be deveoped. sc optional: calibration image at ic. default is the image at ic search_dc_limits absolute limits around ic which are used to determine the calibration value of ic as linear approximation of a short interval. optional, can sometimes help to avoid strong deviations of the polynomial approximatiuon from the real measured points. Returns corrFunc(D,i), a function that takes an ND array input for correction (1st dimension corresponds to the different intensity values) as well as the intensity array i. """ if search_dc_limits is not None: search_dc_limits = iterfy(search_dc_limits) if len(search_dc_limits)==1: msk = (i>i-np.abs(search_dc_limits)) & (i<i+np.abs(search_dc_limits)) elif len(search_dc_limits)==2: msk = (i>i-np.min(search_dc_limits)) & (i<i+np.max(search_dc_limits)) p0 = tools.polyFit(i[msk],dmat[msk,...],2) dc = tools.polyVal(p0,i0_wp) pc = tools.polyFit(i-ic,Imat-dc,order,removeOrders=[0]) pcprime = tools.polyDer(pc) c = lambda(i): polyVal(pc,i-ic) + dc else: pc = polyFit(i-ic,dmat,order,removeOrders=[]) pcprime = polyDer(pc) c = lambda(i): polyVal(pc,i-ic) dc = c(ic) c_prime = lambda(i): polyVal(pcprime,i-ic) cprimeic = c_prime(ic) if sc is None: sc = c(ic) def corrFunc(D,i): i = np.asarray(i).ravel() return (sc.swapaxes(0,-1)/ic*i).swapaxes(0,-1) + cprimeic/c_prime(i)* sc/dc * (D-c(i)) def remDepFunc(D,i): i = np.asarray(i).ravel() return D-c(i)+dc if removeDependence: corrFunc = remDepFunc if wrapit: def corrFuncTransposed(D,i,normalize=False,fillValue=np.nan): cr = corrFunc(D.swapaxes(0,-1),i).swapaxes(0,-1) if normalize: cr/=i cr[:,~np.logical_and(i>np.min(i0),i<np.max(i0))] *= fillValue return cr corrFuncWrapped = wrapFunc(corrFuncTransposed,transposeStack=True) def corrFuncWrap(D,i,normalize=False,fillValue=np.nan): Df = D*i.filter([np.min(i0),np.max(i0)]).ones() return corrFuncWrapped(Df,i=i,normalize=normalize,fillValue=fillValue) return corrFuncWrap else: return corrFunc return corrFunc
def getCorrectionFunc(dmat=None,i=None,ic=None,order=5,sc=None,search_dc_limits=None,corrtype='corrNonLin',wrapit=True): """ Create nonlinear correction function from a calibration dataset consiting of: i array of intensity values (floats) of the calibration dmat ND array of the reference patterns corresponding to values of i, The first dimension corresponds to the calibration intensity values and has the same length as i. ic A working point around which a polynomial correction will be developed for each pixel. order the polynomial order up to which the correction will be deveoped. sc optional: calibration image at ic. default is the image at ic search_dc_limits absolute limits around ic which are used to determine the calibration value of ic as linear approximation of a short interval. optional, can sometimes help to avoid strong deviations of the polynomial approximatiuon from the real measured points. Returns corrFunc(D,i), a function that takes an ND array input for correction (1st dimension corresponds to the different intensity values) as well as the intensity array i. """ if ic is None: ic = np.mean(i) if search_dc_limits is not None: search_dc_limits = iterfy(search_dc_limits) if len(search_dc_limits)==1: msk = (i>i-np.abs(search_dc_limits)) & (i<i+np.abs(search_dc_limits)) elif len(search_dc_limits)==2: msk = (i>i-np.min(search_dc_limits)) & (i<i+np.max(search_dc_limits)) p0 = tools.polyFit(i[msk],dmat[msk,...],2) dc = tools.polyVal(p0,i0_wp) pc = tools.polyFit(i-ic,Imat-dc,order,removeOrders=[0]) if corrtype is 'corrNonLin': pcprime = tools.polyDer(pc) #c = lambda(i): polyVal(pc,i-ic) + dc def c(i): #print np.shape(pc) return tools.polyVal(pc,i-ic) + dc else: pc = tools.polyFit(i-ic,dmat,order,removeOrders=[]) #c = lambda(i): tools.polyVal(pc,i-ic) def c(i): #print np.shape(pc) return tools.polyVal(pc,i-ic) dc = c(ic) if corrtype is 'corrNonLin': pcprime = tools.polyDer(pc) if corrtype is 'corrNonLin': pcprime = tools.polyDer(pc) c_prime = lambda(i): tools.polyVal(pcprime,i-ic) cprimeic = c_prime(ic) if sc is None: sc = c(ic) def corrFunc(Dm,im): im = np.asarray(im).ravel() return (sc.T/ic*im).T + cprimeic/c_prime(im)* sc/dc * (Dm-c(im)) #!!! elif corrtype is 'removeDep': def corrFunc(Dm,im): im = np.asarray(im).ravel() return Dm-c(im)+dc #return corrFunc if wrapit: def corrFuncTransposed(Dm,im=None,normalize=False,fillValue=np.nan): if im is None: im = np.apply_over_axes(np.nansum,Dm,range(1,np.ndim(Dm))).ravel() cr = corrFunc(Dm,im) if normalize: im = im.ravel() for dimno in range(cr.ndim-1): im = np.expand_dims(im,-1) cr/=im cr[~np.logical_and(im>np.min(i),im<np.max(i)),...] *= fillValue return cr #else: #return corrFunc(D.swapaxes(0,-1),i).swapaxes(0,-1) corrFuncWrapped = wrapFunc(corrFuncTransposed,transposeStack=False) def corrFuncWrap(Dm,im=None,normalize=False,fillValue=np.nan): if im is not None: Df = Dm*im.filter([np.min(i),np.max(i)]).ones() else: Df = Dm return corrFuncWrapped(Df,im=im,normalize=normalize,fillValue=fillValue) return corrFuncWrap else: return corrFunc
bg = unbV tile -= bg return tile,bg def commonModeCorrectImg(img,mask=None,gainAv=30,nbSwitchFactor=3,unbPx=None): for tNo,tile in enumerate(img): if mask is None: tmask=None else: tmask = mask[tNo] tile,bg = commonModeCorrectTile(tile,mask=tmask,gainAv=gainAv,nbSwitchFactor=nbSwitchFactor,unbPx=unbPx) return img commonModeCorrect = wrapFunc(commonModeCorrectImg,isPerEvt=True) def _nanify(i,mask): if np.shape(mask)[-1] is 1: i[np.squeeze(mask,axis=-1),:] = np.nan else: i[mask,:] = np.nan return i nanify = wrapFunc(_nanify,isPerEvt=False,transposeStack=True) def correct(data,dark=None,mask=None,NpxEdgeMask=1,correctCommonMode=True,gainAv=30,nbSwitchFactor=3,Ntiles=32): if dark is not None: if np.shape(dark)[-1] is not 1: dark=dark[...,np.newaxis] darkcorrect = data.astype(np.float)-dark else: