Esempio n. 1
0
def desmearflat(x,Intensity,Error,beamprofile_or_mat,smoothing,L,pixelsize,title='',NMC=10,MCcallback=None,method='direct'):
    """De-smear scattering curves (flat detector)
    
    Inputs:
        x: pixel coordinates (0 is the beam position)
        Intensity: intensity
        Error: error
        beamprofile_or_mat: a valid input for directdesmearflat()
        smoothing: smoothing parameter
        L: sample-detector distance
        pixelsize: pixel size
        title: title to write over the smoothing diagram
        NMC: Number of Monte Carlo steps for the error propagation.
        MCcallback: callback function, which will be called in each MC step
            (thus NMC times in total).
        method: 'direct' or 'indirect' (Singh, Ghosh, Shannon or Glatter)
        
    Outputs:
        Idesm: de-smeared intensity
        Edesm: error of de-smeared intensity (estimated by a Monte Carlo
            simulation)
        mat: smearing matrix
    """
    #set up smoothing
    if type(beamprofile_or_mat)==type({}):
        beamprofile_or_mat=smearingmatrixflat(x.min(),x.max(),pixelsize,
                                              beamprofile_or_mat['p'],
                                              beamprofile_or_mat['x'],
                                              beamprofile_or_mat['y'],L)
    def cbfunc(sm,ysm,axes,matrix=beamprofile_or_mat):
        Idesm,mat=directdesmearflat(x,ysm,Error,matrix,L,pixelsize,NMC=0)
        if type(matrix)==type({}):
            matrix['mat']=mat # the smearing matrix won't change during the iterations, better fix it to avoid re-calculation
        axes.plot(x,Idesm,'r-')
        axes.set_title(title)
    if method.lower()=='direct':
        try:
            sm,ysm=guitools.testsmoothing(x,Intensity,smoothing,
                                          slidermin=np.power(10,np.log10(smoothing)-2),
                                          slidermax=np.power(10,np.log10(smoothing)+2),
                                          returnsmoothed=True,callback=cbfunc,tkgui=True)
        except RuntimeError:
            raise RuntimeError('Smoothing was interrupted, cannot do desmearing.')
        Idesm,Edesm,mat=directdesmearflat(x,ysm,Error,beamprofile_or_mat,L,
                                          pixelsize,NMC=NMC,MCcallback=MCcallback)
    else:
        Idesm,Edesm,mat=indirectdesmearflat(x,Intensity,Error,len(Intensity)/2,1,beamprofile_or_mat)
    return Idesm,Edesm,mat
Esempio n. 2
0
def directdesmearflat(pix,Intensity,Error,beamprofile_or_mat,L,pixelsize,NMC=0,MCcallback=None):
    """Do a direct desmear (Singh, Ghosh, Shannon) on a scattering curve recorded
    with a flat detector.
    
    Inputs:
        pix: pixel coordinates of the intensity. Should be equally spaced. Pixel
            zero corresponds to the primary beam position.
        Intensity: intensity curve corresponding to pix
        Error: error curve
        beamprofile_or_mat: beam profile dict, as returned by the function
            generate_beamprofile() or a smearing matrix.
        L: sample-detector distance
        pixelsize: pixel size (in mm)
        NMC: number of Monte-Carlo iterations for error propagation.
        MCcallback: call-back routine for the Monte Carlo procedure
        
    Outputs: Idesm, [Edesm], mat
        Idesm: desmeared intensity
        Edesm: error of the desmeared intensity (only if NMC>=2)
        mat: smearing matrix
    """
    if type(beamprofile_or_mat)==type({}):
        beamprofile_or_mat=smearingmatrixflat(pix.min(),pix.max(),pixelsize,
                                               beamprofile_or_mat['p'],
                                               beamprofile_or_mat['x'],
                                               beamprofile_or_mat['y'],L)
    idesm=np.linalg.linalg.solve(beamprofile_or_mat,(Intensity).flatten())
    if NMC<2:
        return idesm,beamprofile_or_mat
    edesm=np.zeros(idesm.shape,np.double)
    for i in range(NMC):
        if hasattr(MCcallback,'__call__'):
            MCcallback.__call__()
        id1=np.linalg.linalg.solve(beamprofile_or_mat,(Intensity+Error*np.random.randn(len(Error))).flatten())
        edesm+=(idesm-id1)**2
    return idesm,np.sqrt(edesm)/(NMC-1),beamprofile_or_mat