Commit d5bc69e9 authored by Chad Lantz's avatar Chad Lantz
Browse files

Added median filtering of waveforms, and manual setting of waveform plotting functions

parent 5ff0f875
......@@ -15,6 +15,7 @@
#include <string>
#include "Containers.h"
#include "Visualizer.h"
#include "TTree.h"
class Detector{
......@@ -33,20 +34,24 @@ class Detector{
virtual Alignment* GetAlignment( ) { return m_Alignment; }
virtual Alignment2021* GetAlignment2021( ) { return m_Alignment2021; }
virtual void SetNSamples ( int _nSamples ) { m_nSamp = _nSamples; }
virtual void SetElement ( Channel* _entry) { m_Element.push_back(_entry); }
virtual void SetPosition (double x, double y, double z) { m_Position[0] = x; m_Position[1] = y; m_Position[2] = z; }
virtual void SetAngle (double _cosx = 0, double _cosy = 0, double _cosz = 0) { m_Angle[0] = _cosx; m_Angle[1] = _cosy; m_Angle[2] = _cosz; }
virtual void SetBranches ( TTree* _dataTree );
virtual void SetAlignment( Alignment* _alignment ){ m_Alignment = _alignment; }
virtual void SetAlignment2021( Alignment2021* _alignment ){ m_Alignment2021 = _alignment; }
virtual void SetWFAthresholds( double _threshold, int _diffSmoothing ){ m_Threshold = _threshold; m_diffSmoothing = _diffSmoothing; }
virtual void SetFFTlowPass( int _freq ){ m_LPFfreq = _freq; m_doLPF = true; }
virtual void DoDRS4NLcomp( ){ m_doDRS4NLcomp = true; }
virtual void DeclareHistograms ( );
virtual void FillHistograms ( );
virtual void SetNSamples ( int _nSamples ) { m_nSamp = _nSamples; }
virtual void SetElement ( Channel* _entry) { m_Element.push_back(_entry); }
virtual void SetPosition ( double x, double y, double z) { m_Position[0] = x; m_Position[1] = y; m_Position[2] = z; }
virtual void SetAngle ( double _cosx = 0, double _cosy = 0, double _cosz = 0) { m_Angle[0] = _cosx; m_Angle[1] = _cosy; m_Angle[2] = _cosz; }
virtual void SetBranches ( TTree* _dataTree );
virtual void SetAlignment ( Alignment* _alignment ){ m_Alignment = _alignment; }
virtual void SetAlignment2021 ( Alignment2021* _alignment ){ m_Alignment2021 = _alignment; }
virtual void SetWFAthresholds ( double _threshold, int _diffSmoothing ){ m_Threshold = _threshold; m_diffSmoothing = _diffSmoothing; }
virtual void SetFFTlowPass ( int _freq ){ m_LPFfreq = _freq; m_doLPF = true; }
virtual void SetMedianFilter ( int _window ){ m_medHW = _window; m_doMedianFilter = true; }
virtual void DoDRS4NLcomp ( ){ m_doDRS4NLcomp = true; }
virtual void DeclareHistograms( );
virtual void FillHistograms ( );
virtual void PrintMap ( ) = 0;
virtual void PrintMap ( ) = 0;
virtual void PlotWF ( int eventNum );
virtual void PlotWFandDerivative( int eventNum, double _yMin1=0, double _yMax1=0, double _yMin2=0, double _yMax2=0 );
virtual void PlotWFandPWF ( int eventNum, double _yMin1=0, double _yMax1=0, double _yMin2=0, double _yMax2=0 );
void SetName ( std::string _name ) { m_name = _name; }
std::string GetName ( ) { return m_name; }
......@@ -56,6 +61,16 @@ class Detector{
std::string m_name;
/** Vector of channels associated to the dector **/
std::vector< Channel* > m_Element;
/** 1d vector of waveform histograms used with Visualizer for low level analysis */
std::vector < TH1* > hWFvec;
/** 1d vector of processed waveform histograms used with Visualizer for low level analysis */
std::vector < TH1* > hPWFvec;
/** 1d vector of waveform derivative histograms used with Visualizer for low level analysis */
std::vector < TH1* > hDiffvec;
/** 2d vector of TMarkers or TLines to be drawn on the pads. 1st index is channel number, 2nd index is mark to be drawn */
std::vector< std::vector < TObject* >* >* hMarksFront;
/** 2d vector of TMarkers or TLines to be drawn on the pads. 1st index is channel number, 2nd index is mark to be drawn */
std::vector< std::vector < TObject* >* >* hMarksBack;
/** Three element array with x, y, and z of some pre-defined point on the detector **/
double m_Position[3];
/** Three element array of angle about the x, y, and z axis **/
......@@ -66,12 +81,18 @@ class Detector{
int m_diffSmoothing = 25;
/** Frequency cutoff for low pass filtering of waveforms if selected */
int m_LPFfreq = 50;
/** Half window size for median filtering */
int m_medHW = 0;
/** Flag if low pass filtering is to be performed on this detector's waveforms */
bool m_doLPF = false;
/** Perform DRS4 non-linearity compensation on channels of this detector */
bool m_doDRS4NLcomp = false;
/** Perform median filtering on channels of this detector */
bool m_doMedianFilter = false;
/** Number of samples per channel **/
int m_nSamp = 1024;
/** Visualizer for plots **/
Visualizer* m_viz = 0;
/** Alignment of the 2018 Testbeam */
Alignment* m_Alignment = 0;
/** Alignment of the 2021 Testbeam */
......
......@@ -12,6 +12,11 @@
#include "Detector.h"
#include "Containers.h"
#include "TLine.h"
#include "TMarker.h"
#include "TSystem.h"
#include <vector>
......@@ -82,6 +87,8 @@ void Detector::SetBranches( TTree *_dataTree ){
* @brief Declare histograms to be filled with the raw waveform
*/
void Detector::DeclareHistograms(){
hMarksFront = new std::vector< std::vector< TObject* >* >;
hMarksBack = new std::vector< std::vector< TObject* >* >;
for( uint ch = 0; ch < m_Element.size(); ch++ ){
m_Element.at(ch)->WF_histo = new TH1D( m_Element.at(ch)->name.c_str(), (m_Element.at(ch)->name + ", " + m_Element.at(ch)->detector).c_str(), m_nSamp, 0, m_nSamp);
......@@ -97,6 +104,15 @@ void Detector::DeclareHistograms(){
m_Element.at(ch)->doLPF = m_doLPF;
m_Element.at(ch)->LPFfreq = m_LPFfreq;
m_Element.at(ch)->DRS4NLcomp = m_doDRS4NLcomp;
m_Element.at(ch)->doMedianFilter = m_doMedianFilter;
m_Element.at(ch)->medFiltHalfWindow = m_medHW;
hWFvec.push_back(m_Element.at(ch)->WF_histo);
hPWFvec.push_back(m_Element.at(ch)->PWF_histo);
hDiffvec.push_back(m_Element.at(ch)->FirstDerivative);
hMarksFront->push_back( new std::vector< TObject* > );
hMarksBack->push_back( new std::vector< TObject* > );
}
}
......@@ -119,3 +135,172 @@ void Detector::FillHistograms(){
} // End loop over samples in each channel
}
}
/** @brief Generic implementation of PlotWF. Draw the waveforms for all Channels for a given event
* WARNING: This is cpu intensive and intended for low level inspection of a few events at a time
*
* @param - Event number for output file naming
*/
void Detector::PlotWF( int eventNum ){
if(eventNum == 0){//If this is the first event create an output directory
gSystem->Exec( Form("mkdir -p %s/results/plots",std::getenv("JZCaPA") ) );
}
for(int ch = 0; ch < m_Element.size(); ch++){
//Delete and clear old markers
for(int i = 0; i < hMarksFront->at(ch)->size(); i++){
if( !hMarksFront->at(ch)->at(i)->InheritsFrom("TF1") ){
delete hMarksFront->at(ch)->at(i);
}
}
hMarksFront->at(ch)->clear();
//Draw the pedestal no matter what
hMarksFront->at(ch)->push_back( new TLine( 0, m_Element[ch]->PedMean, m_nSamp, m_Element[ch]->PedMean) );
((TLine*)hMarksFront->at(ch)->back())->SetLineColor(kGreen);
//Draw hit window lines, peak marker, and set the range of the fit function to the full hit window
if(m_Element[ch]->is_on){
m_Element[ch]->WF_histo->ResetStats();
if(m_Element[ch]->was_hit){
//Draw vertical red lines around the hit window
hMarksFront->at(ch)->push_back( new TLine( m_Element[ch]->hit_window.first, m_Element[ch]->WF_histo->GetMinimum(), m_Element[ch]->hit_window.first, m_Element[ch]->WF_histo->GetMaximum()) );
((TLine*)hMarksFront->at(ch)->back())->SetLineColor(kRed);
hMarksFront->at(ch)->push_back( new TLine( m_Element[ch]->hit_window.second, m_Element[ch]->WF_histo->GetMinimum(), m_Element[ch]->hit_window.second, m_Element[ch]->WF_histo->GetMaximum()) );
((TLine*)hMarksFront->at(ch)->back())->SetLineColor(kRed);
hMarksFront->at(ch)->push_back( new TMarker( m_Element[ch]->Peak_center, m_Element[ch]->Peak_max + m_Element[ch]->PedMean, 5) );
((TMarker*)hMarksFront->at(ch)->back())->SetMarkerColor(kMagenta+2);
((TMarker*)hMarksFront->at(ch)->back())->SetMarkerSize(3);
}//end if channel was hit
}//end if channel is on
}//end channels loop
if(m_viz == NULL){
m_viz = new Visualizer( "ATLAS" );
m_viz->SetTestBeamLabel(m_Alignment2021->runNumber, m_Alignment2021 );
}
int pads = ceil(sqrt(m_Element.size()));
m_viz->SimplePadsPlot( hWFvec, pads, pads, "Time [bins]", "Amplitude [ADC]", //Background histos, foreground histos, nCol, nRow, Detector label
Form("%swf%d.png", m_name.c_str(), eventNum), m_name.c_str(), "", // Output file name, chule name, plot type
Form("%s/results/plots/", std::getenv("JZCaPA") ), // Output directry
true, hMarksFront ); // Autoscale, Plot markers
}
void Detector::PlotWFandDerivative( int eventNum, double _yMin1, double _yMax1, double _yMin2, double _yMax2 ){
if(eventNum == 0){//If this is the first event create an output directory
gSystem->Exec( Form("mkdir -p %s/results/plots",std::getenv("JZCaPA") ) );
}
for(int ch = 0; ch < m_Element.size(); ch++){
//Delete and clear old markers
for(int i = 0; i < hMarksBack->at(ch)->size(); i++){
delete hMarksBack->at(ch)->at(i);
}
hMarksBack->at(ch)->clear();
for(int i = 0; i < hMarksFront->at(ch)->size(); i++){
if( !hMarksFront->at(ch)->at(i)->InheritsFrom("TF1") ){ // Don't delete the fit functions
delete hMarksFront->at(ch)->at(i);
}
}
hMarksFront->at(ch)->clear();
//Draw the pedestal no matter what
hMarksBack->at(ch)->push_back( new TLine( 0, m_Element[ch]->PedMean, m_nSamp, m_Element[ch]->PedMean) );
((TLine*)hMarksBack->at(ch)->back())->SetLineColor(kGreen);
//Plot the threshold lines on the derivative no matter what
hMarksFront->at(ch)->push_back( new TLine( 0, m_Element[ch]->FirstDerivativeRMS*m_Element[ch]->Threshold, m_nSamp, m_Element[ch]->FirstDerivativeRMS*m_Element[ch]->Threshold) );
((TLine*)hMarksFront->at(ch)->back())->SetLineColor(kMagenta);
hMarksFront->at(ch)->push_back( new TLine( 0, -1*m_Element[ch]->FirstDerivativeRMS*m_Element[ch]->Threshold, m_nSamp, -1*m_Element[ch]->FirstDerivativeRMS*m_Element[ch]->Threshold) );
((TLine*)hMarksFront->at(ch)->back())->SetLineColor(kMagenta);
//Draw hit window lines, peak marker, and set the range of the fit function to the full hit window
if(m_Element[ch]->is_on){
m_Element[ch]->WF_histo->GetYaxis()->SetRange(0,0);
m_Element[ch]->WF_histo->ResetStats();
if(m_Element[ch]->was_hit){
//Draw vertical red lines around the hit window
hMarksBack->at(ch)->push_back( new TLine( m_Element[ch]->hit_window.first, -2950, m_Element[ch]->hit_window.first, -2600) );
((TLine*)hMarksBack->at(ch)->back())->SetLineColor(kRed);
hMarksBack->at(ch)->push_back( new TLine( m_Element[ch]->hit_window.second, -2950, m_Element[ch]->hit_window.second, -2600) );
((TLine*)hMarksBack->at(ch)->back())->SetLineColor(kRed);
//Draw an X on the peak
hMarksBack->at(ch)->push_back( new TMarker( m_Element[ch]->Peak_center, m_Element[ch]->Peak_max + m_Element[ch]->PedMean, 5) );
((TMarker*)hMarksBack->at(ch)->back())->SetMarkerColor(kMagenta+2);
((TMarker*)hMarksBack->at(ch)->back())->SetMarkerSize(3);
}//end if channel was hit
}//end if channel is on
}//end channel loop
if(m_viz == NULL){
m_viz = new Visualizer( "ATLAS" );
m_viz->SetTestBeamLabel(m_Alignment2021->runNumber, m_Alignment2021 );
}
int pads = ceil(sqrt(m_Element.size()));
m_viz->ManyPadsPlot( hWFvec, hDiffvec, pads, pads, m_name.c_str(), //Background histos, foreground histos, nCol, nRow, Detector label
Form("%s/results/plots/%swfDiff_ev%d", std::getenv("JZCaPA"), m_name.c_str(), eventNum ), // Output file name
"Time [bins]", "Amplitude [ADC]", "overlay", //X-axis label, Y-axis label, plot type
hMarksBack, hMarksFront, //Background plot markers, Foreground plot markers
_yMin1, _yMax1, _yMin2, _yMax2); //Y axis ranges
}
void Detector::PlotWFandPWF( int eventNum, double _yMin1, double _yMax1, double _yMin2, double _yMax2 ){
if(eventNum == 0){//If this is the first event create an output directory
gSystem->Exec( Form("mkdir -p %s/results/plots",std::getenv("JZCaPA") ) );
}
for(int ch = 0; ch < m_Element.size(); ch++){
//Delete and clear old markers
for(int i = 0; i < hMarksBack->at(ch)->size(); i++){
delete hMarksBack->at(ch)->at(i);
}
hMarksBack->at(ch)->clear();
for(int i = 0; i < hMarksFront->at(ch)->size(); i++){
if( !hMarksFront->at(ch)->at(i)->InheritsFrom("TF1") ){
delete hMarksFront->at(ch)->at(i);
}
}
hMarksFront->at(ch)->clear();
//Draw the pedestal no matter what
hMarksBack->at(ch)->push_back( new TLine( 0, m_Element[ch]->PedMean, m_nSamp, m_Element[ch]->PedMean) );
((TLine*)hMarksBack->at(ch)->back())->SetLineColor(kGreen);
//Draw hit window lines, peak marker, and set the range of the fit function to the full hit window
if(m_Element[ch]->is_on){
m_Element[ch]->WF_histo->ResetStats();
if(m_Element[ch]->was_hit){
//Draw vertical red lines around the hit window
hMarksBack->at(ch)->push_back( new TLine( m_Element[ch]->hit_window.first, m_Element[ch]->WF_histo->GetMinimum(), m_Element[ch]->hit_window.first, m_Element[ch]->WF_histo->GetMaximum()) );
((TLine*)hMarksBack->at(ch)->back())->SetLineColor(kRed);
hMarksBack->at(ch)->push_back( new TLine( m_Element[ch]->hit_window.second,m_Element[ch]->WF_histo->GetMinimum(), m_Element[ch]->hit_window.second, m_Element[ch]->WF_histo->GetMaximum()) );
((TLine*)hMarksBack->at(ch)->back())->SetLineColor(kRed);
hMarksBack->at(ch)->push_back( new TMarker( m_Element[ch]->Peak_center, m_Element[ch]->Peak_max + m_Element[ch]->PedMean, 5) );
((TMarker*)hMarksBack->at(ch)->back())->SetMarkerColor(kMagenta+2);
((TMarker*)hMarksBack->at(ch)->back())->SetMarkerSize(3);
hMarksFront->at(ch)->push_back( m_Element[ch]->FitFunc );
((TF1*)hMarksFront->at(ch)->back())->SetRange(m_Element[ch]->hit_window.first, m_Element[ch]->hit_window.second);
((TF1*)hMarksFront->at(ch)->back())->SetLineColor(kCyan);
}//end if channel was hit
}//end if channel is on
}//end channel loop
if(m_viz == NULL){
m_viz = new Visualizer( "ATLAS" );
m_viz->SetTestBeamLabel(m_Alignment2021->runNumber, m_Alignment2021 );
}
int pads = ceil(sqrt(m_Element.size()));
m_viz->ManyPadsPlot( hWFvec, hPWFvec, pads, pads, m_name.c_str(), //Background histos, foreground histos, nCol, nRow, Detector label
Form("%s/results/plots/%swfPwfPlot_ev%d",std::getenv("JZCaPA"), m_name.c_str(), eventNum ), // Output file name
"Time [bins]", "Amplitude [ADC]", "overlay", //X-axis label, Y-axis label, plot type
hMarksBack, hMarksFront, //Background plot markers, Foreground plot markers
_yMin1, _yMax1, _yMin2, _yMax2); //Y axis ranges
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment