Ejemplo n.º 1
0
def lambda_values(evt,pulse_energy,sum_over_bkg_frames,fit_bkg,sample_params,outkey=""):
    frame_expected_phc = numpy.dot(sample_params,numpy.array([pulse_energy**3,pulse_energy**2,pulse_energy,1]))
    lambdav = sum_over_bkg_frames*frame_expected_phc/fit_bkg.sum()
    lambdav[lambdav<=0] = 1e-30
    v = evt["analysis"]
    add_record(v, "analysis", outkey+"lambda_values", lambdav)
    add_record(v, "analysis", outkey+"expected_phc", frame_expected_phc)
Ejemplo n.º 2
0
def hitrate(evt, hit, history=100, unit='percent', outkey="hitrate"):
    """Counts hits and adds current hit rate to ``evt["analysis"][outkey]``.

    Args:
        :evt:     The event variable
        :hit:     A boolean (True for hit, False for miss)
    
    Kwargs:
        :history(int):  Buffer length, default = 100
        :outkey(str):   Data key of resulting ``Record``, default is "hitrate" 
        :unit(str):     Unit of hitrate, 'fraction' or 'percent', default is 'fraction'

    :Authors:
        Benedikt J. Daurer ([email protected])
        Tomas Ekeberg
    """
    global hitrate_counters
    if outkey not in hitrate_counters or hitrate_counters[outkey].maxlen != history:
        hitrate_counters[outkey] = collections.deque([], history)
    hitrate_counters[outkey].append(bool(hit))
    hitcount = np.array(hitrate_counters[outkey].count(True))
    ipc.mpi.sum("hitcount - " + outkey, hitcount)
    v = evt["analysis"]
    if (ipc.mpi.is_main_worker()):
        hitrate = hitcount[()] / (ipc.mpi.nr_workers() * float(len(hitrate_counters[outkey])))
        if unit == 'fraction':
            add_record(v, "analysis", outkey, hitrate)
        elif unit == 'percent':
            add_record(v, "analysis", outkey, 100.*hitrate)
Ejemplo n.º 3
0
def cropAndCenter(evt,
                  data_rec,
                  cx=None,
                  cy=None,
                  w=None,
                  h=None,
                  outkey='cropped'):

    data = data_rec.data
    name = data_rec.name
    Ny, Nx = data.shape
    if cx is None:
        cx = (Nx - 1) / 2.
    if cy is None:
        cy = (Ny - 1) / 2.
    # Round to .0 / .5
    cx = np.round(cx * 2) / 2.
    cy = np.round(cy * 2) / 2.
    if w is None:
        w = Nx
    if h is None:
        h = Ny
    data_cropped = data[int(round(cy - h / 2)):int(round(cy + h / 2)),
                        int(round(cx - w / 2)):int(round(cx + w / 2))]
    add_record(evt["analysis"], "analysis", outkey, data_cropped)
Ejemplo n.º 4
0
def radial(evt, type, key, mask=None, cx=None, cy=None):
    """Compute the radial average of a detector image given the center position (and a mask). 
    Adds the records ``evt["analysis"]["radial average - " + key]`` and ``evt["analysis"]["radial distance - " + key]``.

    .. note:: This feature depends on the python package `libspimage <https://github.com/FilipeMaia/libspimage>`_.

    Args:
        :evt:        The event variable
        :type(str):  The event type (e.g. photonPixelDetectors)
        :key(str):   The event key (e.g. CCD)

    Kwargs:
        :mask:    Binary mask, pixels that are masked out are not counted into the radial average.
        :cx(float):  X-coordinate of the center position. If None the center will be in the middle.
        :cy(float):  Y-coordinate of the center position. If None the center will be in the middle.

    :Authors:
        Max F. Hantke ([email protected])
    """
    success, spimage = utils.io.load_spimage()
    if not success:
        print "Skipping analysis.pixel_detector.radial"
        return
    image = evt[type][key].data
    r, img_r = spimage.radialMeanImage(image, msk=mask, cx=cx, cy=cy, output_r=True)
    valid = np.isfinite(img_r)
    if valid.sum() > 0:
        r = r[valid]
        img_r = img_r[valid]
    add_record(evt["analysis"], "analysis", "radial distance - " + key, r)
    add_record(evt["analysis"], "analysis", "radial average - "  + key, img_r)
Ejemplo n.º 5
0
def bin(evt, type, key, binning, mask=None):
    """Bin a detector image given a binning factor (and mask).
    Adds the records ``evt["analysis"]["binned image - " + key]`` and  ``evt["analysis"]["binned mask - " + key]``.

    .. note:: This feature depends on the python package `libspimage <https://github.com/FilipeMaia/libspimage>`_.

    Args:
        :evt:        The event variable
        :type(str):  The event type (e.g. photonPixelDetectors)
        :key(str):   The event key (e.g. CCD)
        :binning(int):   The linear binning factor

    Kwargs:
        :mask:    Binary mask, pixels that are masked out are not counted into the binned value.

    :Authors:
        Max F. Hantke ([email protected])
    """
    success, spimage = utils.io.load_spimage()
    if not success:
        print "Skipping analysis.pixel_detector.bin"
        return
    image = evt[type][key].data
    binned_image, binned_mask = spimage.binImage(image, binning, msk=mask, output_binned_mask=True)
    add_record(evt["analysis"], "analysis", "binned image - "+key, binned_image)
    if binned_mask is not None:
        add_record(evt["analysis"], "analysis", "binned mask - "+key, binned_mask)
Ejemplo n.º 6
0
def photon_error(evt, type_data, key_data, type_fit, key_fit, adu_per_photon):
    import scipy.misc
    data = np.array(evt[type_data][key_data].data / (1. * adu_per_photon),
                    dtype="float")
    fit = np.array(evt[type_fit][key_fit].data / (1. * adu_per_photon),
                   dtype="float")
    data_best = fit.round()
    data = data.copy()
    M = fit != 0
    M *= data > 0
    M *= data_best > 0

    K = data[M]
    W = fit[M]
    Ks = data_best[M]

    # Stirling
    lKf = K * np.log(K) - K
    tmp = K < 5
    if tmp.sum():
        lKf[tmp] = np.log(scipy.misc.factorial(K[tmp], exact=False))

    # Stirling
    lKsf = Ks * np.log(Ks) - Ks
    tmp = Ks < 5
    if tmp.sum():
        lKsf[tmp] = np.log(scipy.misc.factorial(Ks[tmp], exact=False))

    error = (Ks * np.log(W) - lKsf) - (K * np.log(W) - lKf)
    error = error.sum()
    add_record(evt["analysis"], "analysis", "photon error", error, unit='')
Ejemplo n.º 7
0
def commonModeCSPAD2x2(evt, type, key, mask=None):
    """Subtraction of common mode using median value of masked pixels (left and right half of detector are treated separately). 
    Adds a record ``evt["analysis"]["cm_corrected - " + key]``.
    
    Args:
      :evt:        The event variable
      :type(str):  The event type (e.g. photonPixelDetectors)
      :key(str):   The event key (e.g. CCD)

    Kwargs:
      :mask: Binary mask
    
    :Authors:
        Max F. Hantke ([email protected])
        Benedikt J. Daurer ([email protected])
    """
    data = evt[type][key].data
    dataCorrected = np.copy(data)
    lData = data[:,:data.shape[1]/2]
    rData = data[:,data.shape[1]/2:]
    if mask is None:
        lMask = np.ones(shape=lData.shape, dtype="bool")
        rMask = np.ones(shape=rData.shape, dtype="bool")
    else:
        lMask = mask[:,:data.shape[1]/2] == False
        rMask = mask[:,data.shape[1]/2:] == False
    if lMask.sum() > 0:
        dataCorrected[:,:data.shape[1]/2] -= np.median(lData[lMask])
    if rMask.sum() > 0:
        dataCorrected[:,data.shape[1]/2:] -= np.median(rData[rMask])    
    add_record(evt["analysis"], "analysis", "cm_corrected - " + key, dataCorrected)
Ejemplo n.º 8
0
def radial(evt, type, key, mask=None, cx=None, cy=None):
    """Compute the radial average of a detector image given the center position (and a mask) and saves it to ``evt["analysis"]["radial average - " + key]`` and the radial distances are saved to``evt["analysis"]["radial distance - " + key]``

    Args:
        :evt:        The event variable
        :type(str):  The event type (e.g. photonPixelDetectors)
        :key(str):   The event key (e.g. CCD)

    Kwargs:
        :mask:    Binary mask, pixels that are masked out are not counted into the radial average.
        :cx(float):  X-coordinate of the center position. If None the center will be in the middle.
        :cy(float):  Y-coordinate of the center position. If None the center will be in the middle.

    :Authors:
        Max F. Hantke ([email protected])
    """
    import spimage
    image = evt[type][key].data
    r, img_r = spimage.radialMeanImage(image, msk=mask, cx=cx, cy=cy, output_r=True)
    valid = np.isfinite(img_r)
    if valid.sum() > 0:
        r = r[valid]
        img_r = img_r[valid]
    add_record(evt["analysis"], "analysis", "radial distance - "+key, r)
    add_record(evt["analysis"], "analysis", "radial average - "+key, img_r)
Ejemplo n.º 9
0
def hitrate(evt, hit, history=100, unit='percent', outkey="hitrate"):
    """Counts hits and adds current hit rate to ``evt["analysis"][outkey]``.

    Args:
        :evt:     The event variable
        :hit:     A boolean (True for hit, False for miss)
    
    Kwargs:
        :history(int):  Buffer length, default = 100
        :outkey(str):   Data key of resulting :func:`~backend.Record` object, default is "hitrate" 
        :unit(str):     Unit of hitrate, 'fraction' or 'percent', default is 'percent'

    :Authors:
        Benedikt J. Daurer ([email protected]),
        Tomas Ekeberg
    """
    hit = np.atleast_1d(hit)
    global hitrate_counters
    if outkey not in hitrate_counters or hitrate_counters[
            outkey].maxlen != history:
        hitrate_counters[outkey] = collections.deque([], history)
    for h in hit:
        hitrate_counters[outkey].append(bool(h))
    hitcount = np.array(hitrate_counters[outkey].count(True))
    ipc.mpi.sum("hitcount - " + outkey, hitcount)
    v = evt["analysis"]
    if (ipc.mpi.is_main_event_reader()):
        hitrate = hitcount[()] / (ipc.mpi.nr_event_readers() *
                                  float(len(hitrate_counters[outkey])))
        if unit == 'fraction':
            add_record(v, "analysis", outkey, hitrate)
        elif unit == 'percent':
            add_record(v, "analysis", outkey, 100. * hitrate)
Ejemplo n.º 10
0
def pnccdGain(evt, record, gainmode):
    """Returns gain (Number of ADUs per photon) based on photon energy record and gain mode.
    
    Args:
        :evt:    The event variable
        :record: A photon energy ``Record`` given in eV
        :gainmode: The gain mode of PNCCD (3,4,5,6) or 0 for no gain
    """
    maximum_gain = 1250  # at photon energy of 1keV
    if gainmode == 6:   # 1/1
        gain = maximum_gain
    elif gainmode == 5 :# 1/4
        gain = maximum_gain/4
    elif gainmode == 4: # 1/16
        gain = maximum_gain/16
    elif gainmode == 3: # 1/64
        gain = maximum_gain/64
    elif gainmode == 2: # 1/128
        gain = maximum_gain/128
    elif gainmode == 1: # 1/256
        gain = maximum_gain/256
    elif gainmode == 0:
        gain = 1.
    gain = gain * (record.data / 1000.) # Rescale gain given a photon energy in eV
    add_record(evt['analysis'], 'analysis', 'gain', gain)
Ejemplo n.º 11
0
def absolute_error(evt, type_a, key_a, type_b, key_b, out_key=None):
    """Returning the absolute error between two records as a new record."""
    a = evt[type_a][key_a]
    b = evt[type_b][key_b]
    if out_key is None:
        out_key = "abs(%s - %s)" %(a.name, b.name)
    add_record(evt["analysis"], "analysis", out_key, abs(a.data-b.data), unit='')
Ejemplo n.º 12
0
def assemble(evt, type, key, x, y, nx=None, ny=None, subset=None, outkey=None):
    """Asesembles a detector image given some geometry and adds assembled image to ``evt["analysis"]["assembled - " + key]``.

    Args:
        :evt:        The event variable
        :type(str):  The event type (e.g. photonPixelDetectors)
        :key(str):   The event key (e.g. CCD)
        :x(int ndarray): X coordinates
        :y(int ndarray): Y coordinates

    Kwargs:
        :nx(int):    Total width of assembled image (zero padding)
        :ny(int):    Total height of assembled image (zero padding)

    :Authors:
        Benedikt J. Daurer ([email protected])
    """
    if not key in initialized:
        if subset is not None:
            x_ss = []
            y_ss = []
            for i in subset:
                panel = i / 2
                asic = i % 2
                x_ss.append(x[panel,:,(asic*194):((asic+1)*194)])
                y_ss.append(y[panel,:,(asic*194):((asic+1)*194)])
            x_ss = np.hstack(x_ss)
            y_ss = np.hstack(y_ss)
        else:
            x_ss = x
            y_ss = y
        assembled, height, width, shape, y_ss, x_ss = utils.array.assembleImage(x_ss, y_ss ,nx=nx, ny=ny, return_indices=True)
        initialized[key] = {
            'assembled':assembled,
            'height':height,
            'width':width,
            'shape':shape,
            'y':y_ss,
            'x':x_ss
        }
    assembled = initialized[key]['assembled']
    height = initialized[key]['height']
    width = initialized[key]['width']
    shape = initialized[key]['shape']
    y = initialized[key]['y']
    x = initialized[key]['x']
    if subset is not None:
        data = []
        for i in subset:
            panel = i / 2
            asic = i % 2
            data.append(evt[type][key].data[panel,:,(asic*194):((asic+1)*194)])
        data = np.hstack(data)
    else:
        data = evt[type][key].data
    assembled[height-shape[0]:, :shape[1]][y,x] = data
    if outkey is None:
        add_record(evt["analysis"], "analysis", "assembled - "+key, assembled)
    else:
        add_record(evt["analysis"], "analysis", outkey, assembled)
Ejemplo n.º 13
0
def radial(evt, type, key, mask=None, cx=None, cy=None):
    """Compute the radial average of a detector image given the center position (and a mask). 
    Adds the records ``evt["analysis"]["radial average - " + key]`` and ``evt["analysis"]["radial distance - " + key]``.

    .. note:: This feature depends on the python package `libspimage <https://github.com/FilipeMaia/libspimage>`_.

    Args:
        :evt:        The event variable
        :type(str):  The event type (e.g. photonPixelDetectors)
        :key(str):   The event key (e.g. CCD)

    Kwargs:
        :mask:    Binary mask, pixels that are masked out are not counted into the radial average.
        :cx(float):  X-coordinate of the center position. If None the center will be in the middle.
        :cy(float):  Y-coordinate of the center position. If None the center will be in the middle.

    :Authors:
        Max F. Hantke ([email protected])
    """
    success, spimage = utils.io.load_spimage()
    if not success:
        print "Skipping analysis.pixel_detector.radial"
        return
    image = evt[type][key].data
    r, img_r = spimage.radialMeanImage(image,
                                       msk=mask,
                                       cx=cx,
                                       cy=cy,
                                       output_r=True)
    valid = np.isfinite(img_r)
    if valid.sum() > 0:
        r = r[valid]
        img_r = img_r[valid]
    add_record(evt["analysis"], "analysis", "radial distance - " + key, r)
    add_record(evt["analysis"], "analysis", "radial average - " + key, img_r)
Ejemplo n.º 14
0
def lambda_values(evt,pulse_energy,sum_over_bkg_frames,fit_bkg,sample_params,outkey=""):
    frame_expected_phc = np.dot(sample_params,np.array([pulse_energy**3,pulse_energy**2,pulse_energy,1]))
    lambdav = sum_over_bkg_frames*frame_expected_phc/fit_bkg.sum()
    lambdav[lambdav<=0] = 1e-30
    v = evt["analysis"]
    add_record(v, "analysis", outkey+"lambda_values", lambdav)
    add_record(v, "analysis", outkey+"expected_phc", frame_expected_phc)
Ejemplo n.º 15
0
def commonModeCSPAD2x2(evt, type, key, mask=None):
    """Subtraction of common mode using median value of masked pixels (left and right half of detector are treated separately). 
    Adds a record ``evt["analysis"]["cm_corrected - " + key]``.
    
    Args:
      :evt:        The event variable
      :type(str):  The event type (e.g. photonPixelDetectors)
      :key(str):   The event key (e.g. CCD)

    Kwargs:
      :mask: Binary mask
    
    :Authors:
        Max F. Hantke ([email protected])
        Benedikt J. Daurer ([email protected])
    """
    data = evt[type][key].data
    dataCorrected = np.copy(data)
    lData = data[:, :data.shape[1] / 2]
    rData = data[:, data.shape[1] / 2:]
    if mask is None:
        lMask = np.ones(shape=lData.shape, dtype="bool")
        rMask = np.ones(shape=rData.shape, dtype="bool")
    else:
        lMask = mask[:, :data.shape[1] / 2] == False
        rMask = mask[:, data.shape[1] / 2:] == False
    if lMask.sum() > 0:
        dataCorrected[:, :data.shape[1] / 2] -= np.median(lData[lMask])
    if rMask.sum() > 0:
        dataCorrected[:, data.shape[1] / 2:] -= np.median(rData[rMask])
    add_record(evt["analysis"], "analysis", "cm_corrected - " + key,
               dataCorrected)
Ejemplo n.º 16
0
def someAnalysis(evt, type, key, keyword=None):
    """An example for an analysis module. Please document here in the docstring:

    - what the module is doing
    - what arguments need to be passed
    - what the module returns (adds to the event variable)
    - who the authors are

    Args:
        :evt:       The event variable
        :type(str): The event type
        :key(str):  The event key

    Kwargs:
        :keyword(type): Kewyword description (default = None)

    :Authors: 
        Name (email), 
        Name (email)
    """

    # ADD YOUR CODE HERE
    #
    # something = ....

    add_record(evt["analysis"],
               "analysis",
               "somethingNew" + key,
               something,
               unit=some_unit)
Ejemplo n.º 17
0
def bin(evt, type, key, binning, mask=None):
    """Bin a detector image given a binning factor (and mask).
    Adds the records ``evt["analysis"]["binned image - " + key]`` and  ``evt["analysis"]["binned mask - " + key]``.

    .. note:: This feature depends on the python package `libspimage <https://github.com/FilipeMaia/libspimage>`_.

    Args:
        :evt:        The event variable
        :type(str):  The event type (e.g. photonPixelDetectors)
        :key(str):   The event key (e.g. CCD)
        :binning(int):   The linear binning factor

    Kwargs:
        :mask:    Binary mask, pixels that are masked out are not counted into the binned value.

    :Authors:
        Max F. Hantke ([email protected])
    """
    success, spimage = utils.io.load_spimage()
    if not success:
        print "Skipping analysis.pixel_detector.bin"
        return
    image = evt[type][key].data
    binned_image, binned_mask = spimage.binImage(image,
                                                 binning,
                                                 msk=mask,
                                                 output_binned_mask=True)
    add_record(evt["analysis"], "analysis", "binned image - " + key,
               binned_image)
    if binned_mask is not None:
        add_record(evt["analysis"], "analysis", "binned mask - " + key,
                   binned_mask)
Ejemplo n.º 18
0
def photon_error(evt, type_data, key_data, type_fit, key_fit, adu_per_photon):
    import scipy.misc
    data = np.array(evt[type_data][key_data].data / (1.*adu_per_photon), dtype="float")
    fit = np.array(evt[type_fit][key_fit].data / (1.*adu_per_photon), dtype="float")
    data_best = fit.round()
    data = data.copy()
    M = fit != 0
    M *= data > 0
    M *= data_best > 0

    K = data[M]
    W = fit[M]
    Ks = data_best[M]
    
    # Stirling
    lKf = K*np.log(K)-K
    tmp = K < 5
    if tmp.sum():
        lKf[tmp] = np.log( scipy.misc.factorial(K[tmp], exact=False) )

    # Stirling
    lKsf = Ks*np.log(Ks)-Ks
    tmp = Ks < 5
    if tmp.sum():
        lKsf[tmp] = np.log( scipy.misc.factorial(Ks[tmp], exact=False) )
    
    error = ( Ks * np.log(W) - lKsf ) - ( K * np.log(W) - lKf )
    error = error.sum()
    add_record(evt["analysis"], "analysis", "photon error", error, unit='')
Ejemplo n.º 19
0
def someAnalysis(evt, type, key, keyword=None):
    """An example for an analysis module. Please document here in the docstring:

    - what the module is doing
    - what arguments need to be passed
    - what the module returns (adds to the event variable)
    - who the authors are

    Args:
        :evt:       The event variable
        :type(str): The event type
        :key(str):  The event key

    Kwargs:
        :keyword(type): Kewyword description (default = None)

    :Authors: 
        Name (email), 
        Name (email)
    """

    # ADD YOUR CODE HERE
    # 
    # something = ....

    add_record(evt["analysis"], "analysis", "somethingNew"+key, something, unit=some_unit)
Ejemplo n.º 20
0
def countTof(evt,
             record,
             signalThreshold=1,
             minWindow=0,
             maxWindow=-1,
             hitscoreThreshold=2,
             outkey="tof: "):
    """A simple hitfinder that performs a peak counting test on a time-of-flight detector signal, 
    in a specific subwindow and adds the result to ``evt["analysis"][outkey + "isHit"]``, 
    and  the hitscore to ``evt["analysis"][outkey + "hitscore"]``.

    Args:
        :evt:       The event variable
        :record:    A ToF detector :func:`~backend.Record` object

    Kwargs:
        :signalThreshold(str):   The threshold of the signal, anything above this contributes to the score, default=1
        :minWindow(int):         Lower limit of window, default=0
        :maxWindow(int):         Upper limit of window, default=1
        :hitscoreThreshold(int): events with hitscore (Nr. of photons)  above this threshold are hits, default=2
        :outkey(str):            Prefix of data key of resulting :func:`~backend.Record` object, default is "tof: " 

    :Authors:
        Carl Nettelblad ([email protected])
    """
    hitscore = record.data[minWindow:maxWindow] > signalThreshold
    hit = hitscore > hitscoreThreshold
    v = evt["analysis"]
    add_record(v, "analysis", outkey + "isHit", hit)
    add_record(v, "analysis", outkey + "hitscore", hitscore)
Ejemplo n.º 21
0
def bgsub(evt, type, key, bg):
    data = evt[type][key].data
    if bg is not None:
        dataCorrected = data - bg
    else:
        dataCorrected = data
    add_record(evt["analysis"], "analysis", "bgsub - " + key, dataCorrected)
Ejemplo n.º 22
0
def commonModePNCCD(evt,
                    type,
                    key,
                    outkey=None,
                    transpose=False,
                    signal_threshold=None):
    """Common mode correction for PNCCDs.

    For each row its median value is subtracted (left and right half of detector are treated separately).
    Adds a record ``evt["analysis"][outkey]``.
    
    Args:
      :evt:                     The event variable
      :type(str):               The event type (e.g. photonPixelDetectors)
      :key(str):                The event key (e.g. CCD)

    Kwargs:
      :outkey(str):             The event key for the corrected image, default is "corrected - " + key
      :transpose(bool):         Apply procedure on transposed image
      :signal_threshold(float): Apply procedure by using only pixels below given value
    
    :Authors:
        Max F. Hantke ([email protected])
        Benedikt J. Daurer ([email protected])
    """
    if outkey is None:
        outkey = "corrected - " + key
    data = evt[type][key].data

    if transpose:
        data = data.transpose()

    dataCorrected = np.copy(data)

    lData = np.copy(data[:, :data.shape[1] / 2])
    rData = np.copy(data[:, data.shape[1] / 2:])
    if signal_threshold is not None:
        # Set values above singal_threshold to nan
        np.putmask(lData, lData > signal_threshold, np.nan)
        np.putmask(rData, rData > signal_threshold, np.nan)
    # Calculate median from values that are not nan
    lCM = np.nanmedian(lData,
                       axis=1).repeat(lData.shape[1]).reshape(lData.shape)
    rCM = np.nanmedian(rData,
                       axis=1).repeat(rData.shape[1]).reshape(rData.shape)
    # If a whole row is above threshold the CM correction shall not be applied
    np.putmask(lCM, np.isnan(lCM), 0.)
    np.putmask(rCM, np.isnan(rCM), 0.)

    # Subtract common modes
    dataCorrected[:, :data.shape[1] / 2] -= lCM
    dataCorrected[:, data.shape[1] / 2:] -= rCM

    if transpose:
        dataCorrected = dataCorrected.transpose()

    add_record(evt["analysis"], "analysis", outkey, dataCorrected)
Ejemplo n.º 23
0
def getMaskedParticles(evt, type, key, output, thresh = 20, minX = 800, maxX = 1500, minY = 0, maxY = 1700, kw = 5):
    """Black-box method to create a masked version of a camera
    image where individual illuminated particles constitute a mask."""
    outimg = np.zeros(evt[type][key].data.shape, np.dtype(np.uint8))
    kernel = np.ones((kw*2+1,kw*2+1), np.uint8)
    outimg[minY:maxY, minX:maxX] = evt[type][key].data[minY:maxY,minX:maxX] > thresh
    outimg = cv2.dilate(outimg, kernel)
    # cv2.adaptiveThreshold(evt[type][key].data.astype(np.uint8), 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
    add_record(evt["analysis"], "analysis", output, outimg)
Ejemplo n.º 24
0
def photon_count_frame(evt,
                       front_type_s,
                       front_key_s,
                       aduThreshold,
                       outkey=""):
    photon_frame = (evt[front_type_s][front_key_s].data / aduThreshold).round()
    photon_frame[photon_frame <= 0] = 0
    v = evt["analysis"]
    add_record(v, "analysis", outkey + "photon_count", photon_frame)
Ejemplo n.º 25
0
def countContours(evt, type, key, maskedKey, outimage, outvector):
    imageoutput = np.ndarray(evt[type][key].data.shape, np.uint8)
    (contours,_) = cv2.findContours(evt["analysis"][maskedKey].data, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
    
    for i in xrange(len(contours)):
        cv2.drawContours(imageoutput, contours, i, i + 1, -1)
    needed_labels = np.arange(1, len(contours))
    counts = scipy.ndimage.measurements.sum(evt[type][key].data, imageoutput, needed_labels)
    add_record(evt["analysis"], "analysis", outimage, imageoutput)
    add_record(evt["analysis"], "analysis", outvector, counts)
Ejemplo n.º 26
0
def cmc_pnccd(evt, type, key):
    try:
        data = evt[type][key].data
    except:
        print "NO DATA!"
        return
    if data is None:
        return
    dataCorrected = utils.array.cmc_pnccd(data)
    add_record(evt["analysis"], "analysis", "cmc_pnccd - " + key, dataCorrected)
Ejemplo n.º 27
0
def stat_hitfinder(evt,
                   pulse_energy,
                   thr_params,
                   bag_bkg,
                   outkey="bagscore: "):
    thr = thr_params[0] * pulse_energy + thr_params[1] + 2 * bag_bkg.std()
    hit = evt["analysis"]["baglivo_score"].data > thr
    v = evt["analysis"]
    add_record(v, "analysis", outkey + "isHit", hit)
    add_record(v, "analysis", outkey + "threshold", thr)
Ejemplo n.º 28
0
def sphereModel(evt, type, key_centerx, key_centery, key_diameter, key_intensity, 
                shape, wavelength=1., pixelsize=110, distance=1000, adu_per_photon=1,
                quantum_efficiency=1, material='virus', poisson=False):
    """Return sphere model.

    .. note:: For this function, `libspimage <https://github.com/FilipeMaia/libspimage>`_ needs to be installed.

    Args:
        :evt:       The event variable
        :type(str): The event type, e.g. analysis
        :key_centerx(str):    The event key of the estimated off center shift in x
        :key_centery(str):    The event key of the estimated off center shift in y
        :key_diameter(str):   The event key of the estimated diameter
        :key_intensity(str):  The event key of the estimated intensity
        :shape(tuple):        The shape of the fit

    Kwargs:
        :wavelength(float):   Photon wavelength [nm] (default = 1)
        :pixelsize(int):      Side length of a pixel [um] (default=110)
        :distance(int):       Distance from interaction to detector [mm] (default = 1000)
        :adu_per_photon(int): ADUs per photon (default = 1)
        :quantum_efficiency(float):  Quantum efficiency of the detector (default = 1)
        :material(str):       Material of particle, e.g. virus, protein, water, ... (default = virus)
        :poisson(bool):       If True, apply poisson sampling (default = False)

    :Authors: 
        Benedikt J. Daurer ([email protected]), 
        Max Hantke,
        Filipe Maia
    """
    success, spimage = utils.io.load_spimage()
    if not success:
        print "Skipping analysis.sizing.sphereModel"
        return
    
    centerx    = evt[type][key_centerx].data
    centery    = evt[type][key_centery].data    
    diameter   = evt[type][key_diameter].data * 1e-9
    intensity  = evt[type][key_intensity].data * 1e-3 / 1e-12    
    wavelength *= 1e-9
    distance   *= 1e-3
    pixelsize  *= 1e-6

    size    = spimage.sphere_model_convert_diameter_to_size(diameter, wavelength,
                                                            pixelsize, distance) 
    scaling = spimage.sphere_model_convert_intensity_to_scaling(intensity, diameter,
                                                                wavelength, pixelsize,
                                                                distance, quantum_efficiency,
                                                                adu_per_photon, material)
    fit     = spimage.I_sphere_diffraction(scaling,
                                           spimage.rgrid(shape, (centerx, centery)),
                                           size)
    if poisson:
        fit = np.random.poisson(fit)
    add_record(evt["analysis"], "analysis", "fit", fit, unit='ADU')
Ejemplo n.º 29
0
def countContours(evt, type, key, maskedKey, outimage, outvector):
    imageoutput = np.ndarray(evt[type][key].data.shape, np.uint8)
    (contours, _) = cv2.findContours(evt["analysis"][maskedKey].data,
                                     cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
    for i in xrange(len(contours)):
        cv2.drawContours(imageoutput, contours, i, i + 1, -1)
    needed_labels = np.arange(1, len(contours))
    counts = scipy.ndimage.measurements.sum(evt[type][key].data, imageoutput,
                                            needed_labels)
    add_record(evt["analysis"], "analysis", outimage, imageoutput)
    add_record(evt["analysis"], "analysis", outvector, counts)
Ejemplo n.º 30
0
def commonModePNCCD(evt,
                    type,
                    key,
                    outkey=None,
                    transpose=False,
                    signal_threshold=None,
                    mask=None,
                    min_nr_pixels_per_median=1):
    """Common mode correction for PNCCDs.

    For each row its median value is subtracted (left and right half of detector are treated separately).
    Adds a record ``evt["analysis"][outkey]``.
    
    Args:
      :evt:                     The event variable
      :type(str):               The event type (e.g. photonPixelDetectors)
      :key(str):                The event key (e.g. CCD)

    Kwargs:
      :outkey(str):             The event key for the corrected image, default is "corrected - " + key
      :transpose(bool):         Apply procedure on transposed image
      :signal_threshold(float): Apply procedure by using only pixels below given value
      :mask:                    You may provide a boolean mask with values that shall be excluded from common mode correction
      :min_nr_pixels_per_median(int): Common mode correction will be skipped for pixel lines that do not contain as much as this number of values
    
    :Authors:
        Max F. Hantke ([email protected])
        Benedikt J. Daurer ([email protected])
    """
    if outkey is None:
        outkey = "corrected - " + key
    data = evt[type][key].data

    dataCorrected = np.copy(data)
    lData = dataCorrected[:, :data.shape[1] / 2]
    rData = dataCorrected[:, data.shape[1] / 2:]
    if mask is not None:
        lMask = mask[:, :data.shape[1] / 2]
        rMask = mask[:, data.shape[1] / 2:]
    else:
        lMask = None
        rMask = None
    _cmc(lData,
         msk=lMask,
         axis=1 if not transpose else 0,
         signal_threshold=signal_threshold,
         min_nr_pixels_per_median=min_nr_pixels_per_median)
    _cmc(rData,
         msk=rMask,
         axis=1 if not transpose else 0,
         signal_threshold=signal_threshold,
         min_nr_pixels_per_median=min_nr_pixels_per_median)

    add_record(evt["analysis"], "analysis", outkey, dataCorrected)
Ejemplo n.º 31
0
def absolute_error(evt, type_a, key_a, type_b, key_b, out_key=None):
    """Returning the absolute error between two records as a new record."""
    a = evt[type_a][key_a]
    b = evt[type_b][key_b]
    if out_key is None:
        out_key = "abs(%s - %s)" % (a.name, b.name)
    add_record(evt["analysis"],
               "analysis",
               out_key,
               abs(a.data - b.data),
               unit='')
Ejemplo n.º 32
0
def baglivo_score(evt,poisson_mask,outkey=""):
    #poisson_mask = poisson_mask.astype(bool)
    N = evt["analysis"]["expected_phc"].data
    observed_phc = evt["analysis"]["photon_count"].data[poisson_mask]
    lambda_values = evt["analysis"]["lambda_values"].data[poisson_mask]
    normalized_lambdas = lambda_values/lambda_values.sum()

    partial_sum = observed_phc*(numpy.log(observed_phc) - numpy.log(normalized_lambdas) - numpy.log(N))
    partial_sum[observed_phc==0] = 0

    logval = partial_sum.sum()
     
    v = evt["analysis"]
    add_record(v, "analysis", outkey+"baglivo_score", logval)
Ejemplo n.º 33
0
def baglivo_score(evt,poisson_mask,outkey=""):
    #poisson_mask = poisson_mask.astype(bool)
    N = evt["analysis"]["expected_phc"].data
    observed_phc = evt["analysis"]["photon_count"].data[poisson_mask]
    lambda_values = evt["analysis"]["lambda_values"].data[poisson_mask]
    normalized_lambdas = lambda_values/lambda_values.sum()

    partial_sum = observed_phc*(np.log(observed_phc) - np.log(normalized_lambdas) - np.log(N))
    partial_sum[observed_phc==0] = 0

    logval = partial_sum.sum()
     
    v = evt["analysis"]
    add_record(v, "analysis", outkey+"baglivo_score", logval)
Ejemplo n.º 34
0
def commonModePNCCD(evt, type, key, outkey=None, transpose=False, signal_threshold=None):
    """Common mode correction for PNCCDs.

    For each row its median value is subtracted (left and right half of detector are treated separately).
    Adds a record ``evt["analysis"][outkey]``.
    
    Args:
      :evt:                     The event variable
      :type(str):               The event type (e.g. photonPixelDetectors)
      :key(str):                The event key (e.g. CCD)

    Kwargs:
      :outkey(str):             The event key for the corrected image, default is "corrected - " + key
      :transpose(bool):         Apply procedure on transposed image
      :signal_threshold(float): Apply procedure by using only pixels below given value
    
    :Authors:
        Max F. Hantke ([email protected])
        Benedikt J. Daurer ([email protected])
    """
    if outkey is None:
        outkey = "corrected - " + key
    data = evt[type][key].data

    if transpose:
        data = data.transpose()

    dataCorrected = np.copy(data)

    lData = np.copy(data[:,:data.shape[1]/2])
    rData = np.copy(data[:,data.shape[1]/2:])
    if signal_threshold is not None:
        # Set values above singal_threshold to nan
        np.putmask(lData, lData > signal_threshold, np.nan)
        np.putmask(rData, rData > signal_threshold, np.nan)
    # Calculate median from values that are not nan
    lCM = np.nanmedian(lData,axis=1).repeat(lData.shape[1]).reshape(lData.shape)
    rCM = np.nanmedian(rData,axis=1).repeat(rData.shape[1]).reshape(rData.shape)
    # If a whole row is above threshold the CM correction shall not be applied
    np.putmask(lCM, np.isnan(lCM) , 0.)
    np.putmask(rCM, np.isnan(rCM) , 0.)

    # Subtract common modes
    dataCorrected[:,:data.shape[1]/2] -= lCM
    dataCorrected[:,data.shape[1]/2:] -= rCM

    if transpose:
        dataCorrected = dataCorrected.transpose()

    add_record(evt["analysis"], "analysis", outkey, dataCorrected)
Ejemplo n.º 35
0
def averagePulseEnergy(evt, type):
    """Averages pulse energies. Expects an event and an event type and adds the
    average pulse energy to ``evt["analysis"]["averagePulseEnergy"]``.
    
    :Authors:
        Filipe Maia
    """
    pulseEnergies = evt[type]
    pulseEnergy = []
    for pE in pulseEnergies.values():
        if (pE.unit == ureg.mJ):
            pulseEnergy.append(pE.data)
    if pulseEnergy:
        add_record(evt["analysis"], "analysis", "averagePulseEnergy", np.mean(pulseEnergy), ureg.mJ)
Ejemplo n.º 36
0
def moveHalf(evt,
             record,
             vertical=0,
             horizontal=0,
             outkey='half-moved',
             transpose=False):
    data = record.data
    if transpose:
        data = np.transpose(data)
    ny, nx = data.shape
    data_moved = np.zeros((ny + abs(vertical), nx + horizontal),
                          dtype=data.dtype)
    if horizontal < 0: horizontal = 0
    if vertical < 0:
        data_moved[-vertical:, :nx / 2] = data[:, :nx / 2]
        data_moved[:vertical, nx / 2 + horizontal:] = data[:, nx / 2:]
    elif vertical > 0:
        data_moved[:-vertical, :nx / 2] = data[:, :nx / 2]
        data_moved[vertical:, nx / 2 + horizontal:] = data[:, nx / 2:]
    else:
        data_moved[:, :nx / 2] = data[:, :nx / 2]
        data_moved[:, nx / 2 + horizontal:] = data[:, nx / 2:]
    if transpose:
        data_moved = np.transpose(data_moved)
    return add_record(evt["analysis"], "analysis", outkey, data_moved)
Ejemplo n.º 37
0
def cmc(evt, type, key, mask=None):
    """ Common mode subtraction with median value from pixels within given mask. Add record ``evt["analysis"]["cmc - " + key]``

    Args:
      :evt:        The event variable
      :type(str):  The event type (e.g. photonPixelDetectors)
      :key(str):   The event key (e.g. CCD)

    Kwargs:
      :mask: Binary mask
    
    :Authors:
        Max F. Hantke ([email protected])
    """
    data = evt[type][key].data
    dataCorrected = utils.array.cmc(data, mask=mask)
    add_record(evt["analysis"], "analysis", "cmc - " + key, dataCorrected)
Ejemplo n.º 38
0
def onEvent(evt):

    #analysis.event.printKeys(evt)
    analysis.event.printNativeKeys(evt)

    print(evt['photonPixelDetectors']['AGIPD'].data.shape)

    # Timestamp
    T = evt["eventID"]["Timestamp"]

    # Nr. of pulses per train
    npulses = len(T.timestamp)
    analysis.event.printProcessingRate(pulses_per_event=npulses)
    print("%d pulses per train" % (npulses))
    print("Bad cells: ", T.badCells)

    # Read data/gain from AGIPD source
    agipd_data = evt['photonPixelDetectors']['AGIPD'].data[0]
    agipd_gain = evt['photonPixelDetectors']['AGIPD'].data[1]
    agipd_train = add_record(evt['analysis'], 'analysis', 'AGIPD/train',
                             agipd_data)

    # Do hitfinding on a full train
    analysis.hitfinding.countLitPixels(evt,
                                       agipd_train,
                                       aduThreshold=0,
                                       hitscoreThreshold=0,
                                       stack=True)
    hittrain = evt['analysis']['litpixel: isHit'].data

    # Select pulses from the AGIPD train that are hits
    agipd_hits = agipd_train.data[..., hittrain]

    # Hitrate
    analysis.hitfinding.hitrate(evt, hittrain)
    if ipc.mpi.is_main_worker():
        print("The current hit rate is %.2f %%" %
              evt['analysis']['hitrate'].data)

    # Iterate through the hits
    max_hits = 10  # The maximum number of hits to be selected from each train
    for i in range(len(agipd_hits[:max_hits])):
        agipd_pulse = add_record(evt['analysis'], 'analysis', 'AGIPD',
                                 agipd_hits[..., i])
        plotting.image.plotImage(agipd_pulse)
    print("")
Ejemplo n.º 39
0
def getMaskedParticles(evt,
                       type,
                       key,
                       output,
                       thresh=20,
                       minX=800,
                       maxX=1500,
                       minY=0,
                       maxY=1700,
                       kw=5):
    """Black-box method to create a masked version of a camera
    image where individual illuminated particles constitute a mask."""
    outimg = np.zeros(evt[type][key].data.shape, np.dtype(np.uint8))
    kernel = np.ones((kw * 2 + 1, kw * 2 + 1), np.uint8)
    outimg[minY:maxY,
           minX:maxX] = evt[type][key].data[minY:maxY, minX:maxX] > thresh
    outimg = cv2.dilate(outimg, kernel)
    add_record(evt["analysis"], "analysis", output, outimg)
Ejemplo n.º 40
0
 def add_new():
     data_keys = self.sort_data_dict()
     i, u, p, s = entry_item.get(), entry_unit.get(), entry_price.get(), entry_stock.get()
     if len(i) != 0 and len(u) != 0 and len(p) != 0 and len(s) != 0:
         key = f'{i}|{u}'
         if key not in data_keys:
             try:
                 backend.add_record((i, u, float(p), float(s)))
                 self.update_data_list()
             except ValueError:
                 messagebox.showwarning(
                     'Warning', '"Price" and "Stock" should contain numbers not words')
         else:
             messagebox.showwarning(
                 'Warning', 'This item is already in database')
         search()
     else:
         messagebox.showwarning('Warning', "You can't add nothing")
Ejemplo n.º 41
0
def cropAndCenter(evt, data_rec, cx=None, cy=None, w=None, h=None, outkey='cropped'):
    
    data = data_rec.data
    name = data_rec.name
    Ny, Nx = data.shape
    if cx is None:
        cx = (Nx-1)/2.
    if cy is None:
        cy = (Ny-1)/2.
    # Round to .0 / .5    
    cx = np.round(cx * 2)/2.
    cy = np.round(cy * 2)/2.
    if w is None:
        w = Nx
    if h is None:
        h = Ny
    data_cropped = data[cy-h/2:cy+h/2, cx-w/2:cx+w/2]
    add_record(evt["analysis"], "analysis", outkey, data_cropped)
Ejemplo n.º 42
0
def totalNrPhotons(evt, type, key, aduPhoton=1, aduThreshold=0.5):
    """Estimates the total nr. of photons on the detector and adds it to ``evt["analysis"]["nrPhotons - " + key]``.

    Args:
        :evt:       The event variable
        :type(str): The event type (e.g. photonPixelDetectors)
        :key(str):  The event key (e.g. CCD)

    Kwargs:
        :aduPhoton(int):    ADU count per photon, default = 1
        :aduThreshold(int): only pixels above this threshold given in units of ADUs are valid, default = 0.5
    
    :Authors:
        Benedikt J. Daurer ([email protected])
    """
    data  = evt[type][key].data.flat
    valid = data > aduThreshold
    add_record(evt["analysis"], "analysis", "nrPhotons - " + key, sum(data[valid]) / float(aduPhoton))
Ejemplo n.º 43
0
def findCenter(evt,
               type,
               key,
               mask=None,
               x0=0,
               y0=0,
               maxshift=10,
               threshold=0.5,
               blur=4):
    """Estimating the center of diffraction based on pair-wise correlation enforcing friedel-symmetry and adding the estimated off center shifts cx and cy to
    ``evt['analysis']['offCenterX']`` and ``evt['analysis']['offCenterX']``.

    .. note:: For this function, `libspimage <https://github.com/FilipeMaia/libspimage>`_ needs to be installed.

    Args:
        :evt:       The event variable
        :type(str): The event type of detectors, e.g. photonPixelDetectors
        :key(str):  The event key of a detector, e.g. CCD 

    Kwargs:
        :mask(bool or int): Only valid pixels (mask == True or 1) are used (default: all pixels are valid)
        :x0(int):           Initial guess for off center shift in x given in pixels (default = 0)
        :y0(int):           Initial guess for off center shift in y given in pixels (default = 0)
        :maxshift(int):     Maximum shift (in both directions) in pixels that is used for searching optimum (default = 10)
        :threshold(float):  Intensities below this threshold are set to zero (default = 0.5)
        :blur(int):         Radius of the blurring kernel used to find the solution quickly (default = 4)

    :Authors: 
        Benedikt J. Daurer ([email protected]), 
        Filipe Maia,
        Tomas Ekeberg
    """
    success, spimage = utils.io.load_spimage()
    if not success:
        print "Skipping analysis.sizing.findCenter"
        return
    img = evt[type][key].data
    if mask is None:
        mask = np.ones(shape=img.shape, dtype="bool")
    else:
        mask = np.array(mask, dtype="bool")
    cx, cy = spimage.find_center(img,
                                 mask,
                                 method='blurred',
                                 x0=x0,
                                 y0=y0,
                                 dmax=maxshift,
                                 threshold=threshold,
                                 blur_radius=blur)
    v = evt["analysis"]
    add_record(v, "analysis", "offCenterX", cx, unit='px')
    add_record(v, "analysis", "offCenterY", cy, unit='px')
    add_record(v, "analysis", "cx", (img.shape[1] - 1) / 2. + cx, unit='px')
    add_record(v, "analysis", "cy", (img.shape[0] - 1) / 2. + cy, unit='px')
Ejemplo n.º 44
0
def maxPhotonValue(evt, record, aduPhoton=1, outkey=None):
    """Estimates the maximum number of photons on one pixel on the detector and adds it to ``evt["analysis"][outkey]``.

    Args:
        :evt:       The event variable
        :record:    The data record (e.g. evt['photonPixelDetectors']['CCD'])

    Kwargs:
        :aduPhoton(int):  ADU count per photon, default = 1
        :outkey(str):     Data key of resulting data record, default is 'maxPhotons' 
    
    :Authors:
        Tomas Ekeberg ([email protected])
        Benedikt J. Daurer ([email protected])
    """
    if outkey is None:
        outkey = 'maxPhotons'
    data = record.data.flat
    add_record(evt["analysis"], "analysis", outkey, max(data) / float(aduPhoton))
Ejemplo n.º 45
0
def commonModePNCCD2(evt, type, key, outkey=None, signal_threshold=None, mask=None, min_nr_pixels_per_median=1):
    """Common mode correction for PNCCDs.

    For each row its median value is subtracted (left and right half of detector are treated separately).
    Adds a record ``evt["analysis"][outkey]``.
    
    Args:
      :evt:                     The event variable
      :type(str):               The event type (e.g. photonPixelDetectors)
      :key(str):                The event key (e.g. CCD)

    Kwargs:
      :outkey(str):             The event key for the corrected image, default is "corrected - " + key
      :transpose(bool):         Apply procedure on transposed image
      :signal_threshold(float): Apply procedure by using only pixels below given value
      :mask:                    You may provide a boolean mask with values that shall be excluded from common mode correction
      :min_nr_pixels_per_median(int): Common mode correction will be skipped for pixel lines that do not contain as much as this number of values
    
    :Authors:
        Max F. Hantke ([email protected])
        Benedikt J. Daurer ([email protected])
    """
    if outkey is None:
        outkey = "corrected - " + key
    data = evt[type][key].data

    dataCorrected = np.copy(data)
    quads = [dataCorrected[:data.shape[0]/2,:data.shape[1]/2],
             dataCorrected[data.shape[0]/2:,:data.shape[1]/2],
             dataCorrected[:data.shape[0]/2,data.shape[1]/2:],
             dataCorrected[data.shape[0]/2:,data.shape[1]/2:]]
    if mask is not None:
        mquads = [mask[:data.shape[0]/2,:data.shape[1]/2],
                  mask[data.shape[0]/2:,:data.shape[1]/2],
                  mask[:data.shape[0]/2,data.shape[1]/2:],
                  mask[data.shape[0]/2:,data.shape[1]/2:]]
    else:
        mquads = [None, None, None, None]
    for quad,mquad in zip(quads,mquads):
        _cmc(quad, msk=mquad, axis=0, signal_threshold=signal_threshold, min_nr_pixels_per_median=min_nr_pixels_per_median)
        _cmc(quad, msk=mquad, axis=1, signal_threshold=signal_threshold, min_nr_pixels_per_median=min_nr_pixels_per_median)
    
    add_record(evt["analysis"], "analysis", outkey, dataCorrected)
Ejemplo n.º 46
0
def maxPhotonValue(evt, record, aduPhoton=1, outkey=None):
    """Estimates the maximum number of photons on one pixel on the detector and adds it to ``evt["analysis"][outkey]``.

    Args:
        :evt:       The event variable
        :record:    The data record (e.g. evt['photonPixelDetectors']['CCD'])

    Kwargs:
        :aduPhoton(int):  ADU count per photon, default = 1
        :outkey(str):     Data key of resulting data record, default is 'maxPhotons' 
    
    :Authors:
        Tomas Ekeberg ([email protected])
        Benedikt J. Daurer ([email protected])
    """
    if outkey is None:
        outkey = 'maxPhotons'
    data = record.data.flat
    add_record(evt["analysis"], "analysis", outkey, max(data) / float(aduPhoton))
Ejemplo n.º 47
0
def countPhotons(evt, type, key, hitscoreThreshold=200):
    """A simple hitfinder that performs a limit test against an already defined
    photon count for detector key. Adds a boolean to ``evt["analysis"]["isHit" + key]`` and
    the hitscore to ``evt["analysis"]["hitscore - " + key]``.

    Args:
        :evt:       The event variable
        :type(str): The event type (e.g. photonPixelDetectors)
        :key(str):  The event key (e.g. CCD)
    Kwargs:
        :hitscoreThreshold(int): events with hitscore (Nr. of photons)  above this threshold are hits, default=200
    
    :Authors:
        Carl Nettelblad ([email protected])
    """
    v = evt["analysis"]
    hitscore = v["nrPhotons - "+key]    
    v["isHit - "+key] = hitscore > hitscoreThreshold
    add_record(v, "analysis", "hitscore - "+key, hitscore)
Ejemplo n.º 48
0
def averagePhotonEnergy(evt, records, outkey="averagePhotonEnergy"):
    """Averages across given photon energies and adds it to evt["analysis"][outkey].

    Args:
        :evt:      The event variable
        :records:  A dictionary of photon energy ``Records``

    Kwargs:
        :outkey(str):  Data key of resulting ``Record``, default is 'averagePhotonEnergy'

    :Authors:
        Benedikt J. Daurer
    """
    photonEnergy = []
    for pE in records.values():
        if (pE.unit == ureg.eV):
            photonEnergy.append(pE.data)
    if photonEnergy:
        add_record(evt["analysis"], "analysis", outkey, np.mean(photonEnergy), ureg.eV)
Ejemplo n.º 49
0
def stxm(evt, data_rec, pulse_energy=1., mode='bf', cx=None, cy=None, r=20, mask=None, badmask=None):
    data = data_rec.data
    if badmask is None:
        badmask = np.ones_like(data).astype(np.bool8)
    else:
        badmask = np.bool8(badmask)
    Ny, Nx = data.shape
    if cx is None:
        cx = (Nx-1)/2.
    if cy is None:
        cy = (Ny-1)/2.
    # Round to .0 / .5    
    cx = np.round(cx * 2)/2.
    cy = np.round(cy * 2)/2.
    xx, yy = np.meshgrid(np.arange(Nx)-cx, np.arange(Ny)-cy)
    rr = np.sqrt(xx**2 + yy**2)
    if mode == 'bf':
        if mask is None:
            mask = rr < r
        else:
            mask = np.bool8(mask)
        v = data[mask & badmask].sum() / pulse_energy
    elif mode == 'df':
        if mask is None:
            mask = rr > r
        else:
            mask = ~np.bool8(mask)
        v = data[mask & badmask].sum() / pulse_energy
    elif mode == 'sum':
        v = data[badmask].sum() / pulse_energy
    elif mode == 'diff':
        # Calc crop coordinates
        Nx_half = min([cx, Nx-1-cx])
        Ny_half = min([cy, Ny-1-cy])
        x1_min = cx - Nx_half
        y1_min = cy - Ny_half
        x2_max = cx + Nx_half + 1
        y2_max = cy + Ny_half + 1
        Nx_half = int(np.ceil(Nx_half))
        Ny_half = int(np.ceil(Ny_half))
        x1_max = x1_min + Nx_half
        y1_max = y1_min + Ny_half
        x2_min = x2_max - Nx_half
        y2_min = y2_max - Ny_half
        # Calc diff
        # Original type might be unsigned integer
        #
        # Casting is done to doubles for accumulation.
        tmp = data*badmask
        diffx = (tmp[y1_min:y2_max, x1_min:x1_max].sum(dtype=np.float64) - tmp[y1_min:y2_max, x2_min:x2_max].sum(dtype=np.float64)) / pulse_energy
        diffy = (tmp[y1_min:y1_max, x1_min:x2_max].sum(dtype=np.float64) - tmp[y2_min:y2_max, x1_min:x2_max].sum(dtype=np.float64)) / pulse_energy
        # Combine diff
        v = np.sqrt(diffx**2+diffy**2)
    rec = add_record(evt["analysis"], "analysis", "stxm %s" %mode, v)
    return rec
Ejemplo n.º 50
0
def totalNrPhotons(evt, record, aduPhoton=1, aduThreshold=0.5, outkey=None):
    """Estimates the total nr. of photons on the detector and adds it to ``evt["analysis"][outkey]``.

    Args:
        :evt:       The event variable
        :record:    The data record (e.g. evt['photonPixelDetectors']['CCD'])

    Kwargs:
        :aduPhoton(int):    ADU count per photon, default = 1
        :aduThreshold(int): only pixels above this threshold given in units of ADUs are valid, default = 0.5
        :outkey(str):       Data key of resulting data record, default is 'nrPhotons' 
    
    :Authors:
        Benedikt J. Daurer ([email protected])
    """
    if outkey is None:
        outkey = 'nrPhotons'
    data  = record.data.flat
    valid = data > aduThreshold
    add_record(evt["analysis"], "analysis", outkey, sum(data[valid]) / float(aduPhoton))
Ejemplo n.º 51
0
def totalNrPhotons(evt, record, aduPhoton=1, aduThreshold=0.5, outkey=None):
    """Estimates the total nr. of photons on the detector and adds it to ``evt["analysis"][outkey]``.

    Args:
        :evt:       The event variable
        :record:    The data record (e.g. evt['photonPixelDetectors']['CCD'])

    Kwargs:
        :aduPhoton(int):    ADU count per photon, default = 1
        :aduThreshold(int): only pixels above this threshold given in units of ADUs are valid, default = 0.5
        :outkey(str):       Data key of resulting data record, default is 'nrPhotons' 
    
    :Authors:
        Benedikt J. Daurer ([email protected])
    """
    if outkey is None:
        outkey = 'nrPhotons'
    data  = record.data.flat
    valid = data > aduThreshold
    add_record(evt["analysis"], "analysis", outkey, sum(data[valid]) / float(aduPhoton))
Ejemplo n.º 52
0
def countHitscore(evt, hitscore, hitscoreThreshold=200, outkey=""):
    """A simple hitfinder that performs a limit test against an already defined hitscore 
    and adds the result to ``evt["analysis"][outkey + "isHit"]``, and
    the hitscore to ``evt["analysis"][outkey + "hitscore"]``.

    Args:
        :evt:       The event variable
        :hitscore:  A pre-defined hitscore

    Kwargs:
        :hitscoreThreshold(int):   Events with hitscore above this threshold are hits, default=200
    
    :Authors:
        Carl Nettelblad ([email protected])
        Benedikt J. Daurer
    """
    hit = hitscore > hitscoreThreshold
    v = evt["analysis"]
    add_record(v, "analysis", outkey + "isHit", hit)
    add_record(v, "analysis", outley + "hitscore", hitscore)
Ejemplo n.º 53
0
def commonModeLines(evt, record, outkey=None, direction='vertical'):
    """Common mode correction subtracting the median along lines.

    Args:
       :evt:      The event variable
       :record:   A pixel detector ``Record```
       
    Kwargs:
      :outkey:    The event key for the corrected detecor image, default is "corrected"
      :direction: The direction of the lines across which median is taken, default is vertical  
    """
    if outkey is None:
        outkey = "corrected"
    data = record.data
    dataCorrected = np.copy(data)
    if direction is 'vertical':
        dataCorrected -= np.transpose(np.median(data,axis=0).repeat(data.shape[0]).reshape(data.shape))
    elif direction is 'horizontal':
        dataCorrected -= np.median(data,axis=1).repeat(data.shape[1]).reshape(data.shape)
    add_record(evt["analysis"], "analysis", outkey, dataCorrected)
Ejemplo n.º 54
0
def countHitscore(evt, hitscore, hitscoreThreshold=200, outkey=""):
    """A simple hitfinder that performs a limit test against an already defined hitscore 
    and adds the result to ``evt["analysis"][outkey + "isHit"]``, and
    the hitscore to ``evt["analysis"][outkey + "hitscore"]``.

    Args:
        :evt:       The event variable
        :hitscore:  A pre-defined hitscore

    Kwargs:
        :hitscoreThreshold(int):   Events with hitscore above this threshold are hits, default=200
    
    :Authors:
        Carl Nettelblad ([email protected])
        Benedikt J. Daurer
    """
    hit = hitscore > hitscoreThreshold
    v = evt["analysis"]
    add_record(v, "analysis", outkey + "isHit", hit) 
    add_record(v, "analysis", outley + "hitscore", hitscore)
Ejemplo n.º 55
0
def averagePulseEnergy(evt, records, outkey="averagePulseEnergy"):
    """Averages across given pulse energies and adds it to evt["analysis"][outkey].

    Args:
        :evt:      The event variable
        :records:  A dictionary of pulse energy :func:`~Record` objects

    Kwargs:
        :outkey(str):  Data key of resulting :func:`~backend.Record`, default is 'averagePulseEnergy'

    :Authors:
        Filipe Maia,
        Benedikt J. Daurer
    """
    pulseEnergy = []
    for pE in records.values():
        if (pE.unit == ureg.mJ):
            pulseEnergy.append(pE.data)
    if pulseEnergy:
        add_record(evt["analysis"], "analysis", outkey, np.mean(pulseEnergy), ureg.mJ)
Ejemplo n.º 56
0
def commonModeLines(evt, record, outkey=None, direction='vertical'):
    """Common mode correction subtracting the median along lines.

    Args:
       :evt:      The event variable
       :record:   A pixel detector ``Record```
       
    Kwargs:
      :outkey:    The event key for the corrected detecor image, default is "corrected"
      :direction: The direction of the lines across which median is taken, default is vertical  
    """
    if outkey is None:
        outkey = "corrected"
    data = record.data
    dataCorrected = np.copy(data)
    if direction is 'vertical':
        dataCorrected -= np.transpose(np.median(data,axis=0).repeat(data.shape[0]).reshape(data.shape))
    elif direction is 'horizontal':
        dataCorrected -= np.median(data,axis=1).repeat(data.shape[1]).reshape(data.shape)
    add_record(evt["analysis"], "analysis", outkey, dataCorrected)
Ejemplo n.º 57
0
def stxmCenterOfMass(evt, data_rec):
    center_of_mass_y, center_of_mass_x = scipy.ndimage.measurements.center_of_mass(data_rec.data)
    # this assumes that the image is centered already.
    center_of_mass_y -= data_rec.data.shape[0]/2. - 0.5
    center_of_mass_x -= data_rec.data.shape[1]/2. - 0.5
    diff = np.sqrt(center_of_mass_x**2 + center_of_mass_x**2)
    # x_rec = add_record(evt["analysis"], "analysis", "stxm center of mass x", center_of_mass_x)
    # y_rec = add_record(evt["analysis"], "analysis", "stxm center of mass y", center_of_mass_y)
    # return y_rec, x_rec
    rec = add_record(evt["analysis"], "analysis", "stxm center of mass", diff)
    return rec
Ejemplo n.º 58
0
def averagePulseEnergy(evt, records, outkey="averagePulseEnergy"):
    """Averages across given pulse energies and adds it to evt["analysis"][outkey].

    Args:
        :evt:      The event variable
        :records:  A dictionary of pulse energy :func:`~Record` objects

    Kwargs:
        :outkey(str):  Data key of resulting :func:`~backend.Record`, default is 'averagePulseEnergy'

    :Authors:
        Filipe Maia,
        Benedikt J. Daurer
    """
    pulseEnergy = []
    for pE in records.values():
        if (pE.unit == ureg.mJ):
            pulseEnergy.append(pE.data)
    if pulseEnergy:
        add_record(evt["analysis"], "analysis", outkey, np.mean(pulseEnergy), ureg.mJ)
Ejemplo n.º 59
0
def bin(evt, type, key, binning, mask=None):
    """Bin a detector image given a binning factor (and mask) to ``evt["analysis"]["binned image - " + key]`` (``evt["analysis"]["binned mask - " + key]``

    Args:
        :evt:        The event variable
        :type(str):  The event type (e.g. photonPixelDetectors)
        :key(str):   The event key (e.g. CCD)
        :binning(int):   The linear binning factor

    Kwargs:
        :mask:    Binary mask, pixels that are masked out are not counted into the binned value.

    :Authors:
        Max F. Hantke ([email protected])
    """
    import spimage
    image = evt[type][key].data
    binned_image, binned_mask = spimage.binImage(image, binning, msk=mask, output_binned_mask=True)
    add_record(evt["analysis"], "analysis", "binned image - "+key, binned_image)
    if binned_mask is not None:
        add_record(evt["analysis"], "analysis", "binned mask - "+key, binned_mask)