/DMLLTDetectorPulseDiscriminator

DMLLTDetectorPulseDiscriminator - A supervised machine learning approach for shape-sensitive detector pulse discrimination in lifetime spectroscopy applications

Primary LanguagePython

badge-OS

Support this project and keep always updated about recent software releases, bug fixes and major improvements by following on researchgate or github.

badge-researchGate

badge-followers badge-stars badge-forks

DMLLTDetectorPulseDiscriminator Framework

Copyright (c) 2019-2021 Danny Petschke (danny.petschke@uni-wuerzburg.de). All rights reserved.

DMLLTDetectorPulseDiscriminator - A supervised machine learning approach for shape-sensitive detector pulse discrimination in lifetime spectroscopy applications.

DMLLTDetectorPulseDiscriminatorAbstract

Content of the Framework

pyDMLLTDetectorPulseDiscriminator

badge-language badge-license

A python-based frameworkproviding the functionalities for TRAINing/EVALuating and TESTing a classifier such as the naive Bayes classifier on a set of CORRECT and FALSE/REJECT detector output pulses. Moreover, it provides the generation of lifetime spectra from shape-discriminated detector pulses applying the TRAINed classifier, i.e. the classifier providing the highest prediction accuracy.

DPulseStreamAPI

badge-language badge-license

A simple exchange protocol written in native C++ providing the functionality for streaming the acquired detector output pulses on a mass storage device according to the data format required from the pyDMLLTDetectorPulseDiscriminator framework for TRAINing/EVALuating and TESTing the classifiers. This protocol is not attached to any type of digitizer enabling an universal application of this approach.

Quickstart Guide

Basic Principle

  • Store a number of CORRECT (OK) and FALSE (!OK) assigned output pulses each in a separate stream for both detectors A and B. In case of you are using the DRS4 evaluation board of the Paul-Scherrer Institute (PSI, Switzerland) the software tool DDRS4PALS does this job for you.

  • TRAIN/EVALuate and TEST the classifiers for A and B on this set of streamed detector pulses.

    For more details see examples.

  • Finally, generate the lifetime spectrum using the pulse stream recorded on the studied sample material by applying the TRAINed classifiers for pulse-shape discrimination.

DMLLTDetectorPulseDiscriminator

How to apply? ... only a few Lines of Code ...

relPath            = 'C:/dpscience/'

"""
 define your TRAINing data set for detector A and B:
"""
filenameTrue_A     = relPath + 'A/true/A.drs4DataStream'
filenameFalse_A    = relPath + 'A/false/A.drs4DataStream'

filenameTrue_B     = relPath + 'B/true/B.drs4DataStream'
filenameFalse_B    = relPath + 'B/false/B.drs4DataStream'  

"""
 pulse stream acquired of the studied sample which is used to generate the lifetime spectrum:
"""
dataStream         = 'E:/Fe/pure_iron.drs4DataStream'

"""
 location and filename where the resulting lifetime spectrum is stored:
"""
spectraOutput      = relPath + 'spectrum/spectrum_Fe'

"""
 configure the machine params of pulse (A):
"""
mlinputA = DMachineParams()

# baseline correction
mlinputA.m_startCell  = 10
mlinputA.m_cellRegion = 150

# median filter
mlinputA.m_medianFilter = True
mlinputA.m_windowSize   = 5

mlinputA.m_classifier = CalibratedClassifierCV(GaussianNB(), cv=2, method='isotonic')

"""
 configure the machine params of pulse (B):
"""
mlinputB = DMachineParams()

# baseline correction
mlinputB.m_startCell  = 10
mlinputB.m_cellRegion = 150

# median filter
mlinputB.m_medianFilter = True
mlinputB.m_windowSize   = 5

mlinputB.m_classifier = CalibratedClassifierCV(GaussianNB(), cv=2, method='isotonic')


"""
 define the number of labelled detector pulses (A/B) which should be used to TRAIN the machine's classifier prior to the lifetime spectrum generation:
"""
numberOfPulsesToBeTrainedCorrect_A = 16
numberOfPulsesToBeTrainedReject_A  = 14

numberOfPulsesToBeTrainedCorrect_B = 14
numberOfPulsesToBeTrainedReject_B  = 18

"""
 train the machine's classifier for detector (A):
"""
mlinputA = trainPulses(fileNameCorrectPulses    = filenameTrue_A, 
                       fileNameRejectPulses     = filenameFalse_A, 
                       outputMachineFileName    = '', 
                       isPositivePolarity       = False,
                       splitAfterNPulsesCorrect = numberOfPulsesToBeTrainedCorrect_A,
                       splitAfterNPulsesReject  = numberOfPulsesToBeTrainedReject_A,
                       machineInput             = mlinputA,
                       debug                    = True)

"""
 train the machine's classifier for detector (B):
"""
mlinputB = trainPulses(fileNameCorrectPulses    = filenameTrue_B, 
                       fileNameRejectPulses     = filenameFalse_B, 
                       outputMachineFileName    = '', 
                       isPositivePolarity       = False,
                       splitAfterNPulsesCorrect = numberOfPulsesToBeTrainedCorrect_B,
                       splitAfterNPulsesReject  = numberOfPulsesToBeTrainedReject_B,
                       machineInput             = mlinputB,
                       debug                    = True)

"""
 generate the lifetime spectrum:
"""
createLifetimeSpectrum(machineInputA           = mlinputA,
                       machineInputB           = mlinputB,
                       pulseStreamFile         = dataStream, 
                       outputName              = spectraOutput,
                       
                       # negative pulse polarity
                       isPositivePolarity      = False,
                       
                       binWidth_in_ps          = 5,
                       numberOfBins            = 28000,   # [ps]
                       offset_in_ps            = 17000.0, # [ps]
                       B_as_start_A_as_stop    = True,
                       
                       # constant fraction (CF) levels
                       cf_level_A              = 25.0,    # [%]
                       cf_level_B              = 25.0,    # [%]
                       
                       # PHS (start)
                       ll_phs_start_in_mV      = 259.0,   # [mV]
                       ul_phs_start_in_mV      = 319.0,   # [mV]
                       
                       # PHS (stop)
                       ll_phs_stop_in_mV       = 67.0,    # [mV]
                       ul_phs_stop_in_mV       = 107.0,   # [mV]
                       
                       # CF determination
                       cubicSpline             = True,
                       cubicSplineRenderPoints = 200,
                       
                       # median filter
                       medianFilterA           = True,
                       windowSizeA             = 9,
                       medianFilterB           = True,
                       windowSizeB             = 5,
                       
                       debug                   = True)

Related Publication/Presentation

Publication in NIM A (Dec. 2019)

A supervised machine learning approach using naive Gaussian Bayes classification for shape-sensitive detector pulse discrimination in positron annihilation lifetime spectroscopy (PALS) (Nuclear Instruments and Methods in Physics Research Section A: Accelerators, Spectrometers, Detectors and Associated Equipment, Elsevier)

Presentation at 15th International Workshop on Slow Positron Beam Techniques & Applications (SLOPOS-15) in Prague (Sept. 2019)

SLOPOS-15 (Prague): A supervised machine learning approach for shape-sensitive detector pulse discrimination in positron spectroscopy applications

How to cite this Framework?

  • You should at least cite the following publication.

DOI

A supervised machine learning approach using naive Gaussian Bayes classification for shape-sensitive detector pulse discrimination in positron annihilation lifetime spectroscopy (PALS) (Nuclear Instruments and Methods in Physics Research Section A: Accelerators, Spectrometers, Detectors and Associated Equipment, Elsevier)

  • Additionally, you must cite the applied version of the framework in your study.

You can cite all released software versions by using the DOI 10.5281/zenodo.2616929. This DOI represents all versions, and will always resolve to the latest one.

DOI

v1.x

DMLLTDetectorPulseDiscriminator v1.0
DOI

License of pyDMLLTDetectorPulseDiscriminator (BSD-3-Clause)

Copyright (c) 2019-2021 Danny Petschke (danny.petschke@uni-wuerzburg.de). All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice
    this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.

  3. Neither the name of the copyright holder "Danny Petschke" nor the names of
    its contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

For more details see BSD-3-Clause License

License of DPulseStreamAPI (GNU General Public License)

Copyright (c) 2019-2021 Danny Petschke (danny.petschke@uni-wuerzburg.de) All rights reserved.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

For more details see GNU General Public License v3