Newer
Older
/**
\class THcTrigDet
\ingroup Detectors
\brief A mock detector to hold trigger related data.
This class behaves as a detector, but it does not correspond to any physical
detector in the hall. Its purpose is to gather all the trigger related data
comming from a specific source, like HMS.
Can hold up to 100 ADC and TDC channels, though the limit can be changed if
needed. It just seemed like a reasonable starting value.
Only outputs the first hit for each channel to the Root tree leaf.
# Defined variables
For ADC channels it defines:
- raw pedestal: `var_adcPedRaw`
- raw pulse integral: `var_adcPulseIntRaw`
- raw pulse amplitude: `var_adcPulseAmpRaw`
- raw pulse time: `var_adcPulseTimeRaw`
- single sample pedestal value: `var_adcPed`
- pedestal subtracted pulse integral: `var_adcPulseInt`
- pedestal subtracted pulse amplitude: `var_adcPulseAmp`
- multiplicity: `var_adcMult`
For TDC channels it defines:
- raw TDC time: `var_tdcTimeRaw`
- refence time subtracted TDC time: `var_tdcTime`
- multiplicity: `var_tdcMult`
# Parameter file variables
The names and number of channels is defined in a parameter file. The detector
looks for next variables:
- `prefix_numAdc = number_of_ADC_channels`
- `prefix_numTdc = number_of_TDC_channels`
- `prefix_adcNames = "varName1 varName2 ... varNameNumAdc"`
- `prefix_tdcNames = "varName1 varName2 ... varNameNumTdc"`
# Map file information
ADC channels must be assigned plane `1` and signal `0` while TDC channels must
be assigned plane `2` and signal `1`.
Each channel within a plane must be assigned a consecutive "bar" number, which
is then used to get the correct variable name from parameter file.
Use only with THcTrigApp class.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
*/
/**
\fn THcTrigDet::THcTrigDet(
const char* name, const char* description="",
THaApparatus* app=NULL)
\brief A constructor.
\param[in] name Name of the apparatus. Is typically named after spectrometer
whose trigger data is collecting; like "HMS".
\param[in] description Description of the apparatus.
\param[in] app The parent apparatus pointer.
*/
/**
\fn virtual THcTrigDet::~THcTrigDet()
\brief A destructor.
*/
/**
\fn virtual THaAnalysisObject::EStatus THcTrigDet::Init(const TDatime& date)
\brief Initializes the detector variables.
\param[in] date Time of the current run.
*/
/**
\fn virtual void THcTrigDet::Clear(Option_t* opt="")
\brief Clears variables before next event.
\param[in] opt Maybe used in base clas... Not sure.
*/
/**
\fn Int_t THcTrigDet::Decode(const THaEvData& evData)
\brief Decodes and processes events.
\param[in] evData Raw data to decode.
*/
//TODO: Check if fNumAdc < fMaxAdcChannels && fNumTdc < fMaxTdcChannels.
#include <algorithm>
#include <iostream>
#include <stdexcept>
#include "TString.h"
#include "THaApparatus.h"
#include "THaEvData.h"
#include "THcDetectorMap.h"
#include "THcGlobals.h"
#include "THcParmList.h"
#include "THcRawAdcHit.h"
#include "THcRawTdcHit.h"
#include "THcTrigApp.h"
#include "THcTrigRawHit.h"
THcTrigDet::THcTrigDet() {}
THcTrigDet::THcTrigDet(
const char* name, const char* description, THaApparatus* app
) :
THaDetector(name, description, app), THcHitList(),
fKwPrefix(""),
fNumAdc(0), fNumTdc(0), fAdcNames(), fTdcNames(),
fTdcTimeRaw(), fTdcTime(),
fAdcPedRaw(), fAdcPulseIntRaw(), fAdcPulseAmpRaw(), fAdcPulseTimeRaw(),
Mark Jones
committed
fAdcPed(), fAdcPulseInt(), fAdcPulseAmp(), fAdcPulseTime(),
{
// Guess at spectrometer name that this trigger detector is associated with
// Can override with SetSpectName
fSpectName = name[0];
}
THcTrigDet::~THcTrigDet() {
delete [] fAdcTimeWindowMin; fAdcTimeWindowMin = NULL;
delete [] fAdcTimeWindowMax; fAdcTimeWindowMax = NULL;
delete [] fTdcTimeWindowMin; fTdcTimeWindowMin = NULL;
delete [] fTdcTimeWindowMax; fTdcTimeWindowMax = NULL;
}
THaAnalysisObject::EStatus THcTrigDet::Init(const TDatime& date) {
// Call `Setup` before everything else.
Setup(GetName(), GetTitle());
// Initialize all variables.
for (int i=0; i<fMaxAdcChannels; ++i) {
fAdcPedRaw[i] = 0;
fAdcPulseIntRaw[i] = 0;
fAdcPulseAmpRaw[i] = 0;
fAdcPulseTimeRaw[i] = 0;
Mark Jones
committed
fAdcPulseTime[i] = kBig;
fAdcPed[i] = 0.0;
fAdcPulseInt[i] = 0.0;
fAdcPulseAmp[i] = 0.0;
fAdcMultiplicity[i] = 0;
};
for (int i=0; i<fMaxTdcChannels; ++i) {
fTdcTimeRaw[i] = 0;
fTdcTime[i] = 0.0;
fTdcMultiplicity[i] = 0;
};
// Call initializer for base class.
// This also calls `ReadDatabase` and `DefineVariables`.
EStatus status = THaDetector::Init(date);
if (status) {
fStatus = status;
return fStatus;
// Fill in detector map.
string EngineDID = string(GetApparatus()->GetName()).substr(0, 1) + GetName();
std::transform(EngineDID.begin(), EngineDID.end(), EngineDID.begin(), ::toupper);
if (gHcDetectorMap->FillMap(fDetMap, EngineDID.c_str()) < 0) {
static const char* const here = "Init()";
Error(Here(here), "Error filling detectormap for %s.", EngineDID.c_str());
return kInitError;
}
DBRequest listextra[]={
{"_trig_tdcrefcut", &fTDC_RefTimeCut, kInt, 0, 1},
{"_trig_adcrefcut", &fADC_RefTimeCut, kInt, 0, 1},
{0}
};
fTDC_RefTimeCut = -1000; // Minimum allowed reference times
fADC_RefTimeCut = -1000;
gHcParms->LoadParmValues((DBRequest*)&listextra,fKwPrefix.c_str());
// Initialize hitlist part of the class.
InitHitList(fDetMap, "THcTrigRawHit", 200,fTDC_RefTimeCut,fADC_RefTimeCut);
CreateMissReportParms(fKwPrefix.c_str());
fPresentP = 0;
THaVar* vpresent = gHaVars->Find(Form("%s.present",fSpectName.Data()));
if(vpresent) {
fPresentP = (Bool_t *) vpresent->GetValuePointer();
}
fStatus = kOK;
return fStatus;
}
void THcTrigDet::Clear(Option_t* opt) {
THaAnalysisObject::Clear(opt);
for (int i=0; i<fNumAdc; ++i) {
fAdcPedRaw[i] = 0;
fAdcPulseIntRaw[i] = 0;
fAdcPulseAmpRaw[i] = 0;
fAdcPulseTimeRaw[i] = 0;
Mark Jones
committed
fAdcPulseTime[i] = kBig;
fAdcPed[i] = 0.0;
fAdcPulseInt[i] = 0.0;
fAdcPulseAmp[i] = 0.0;
fAdcMultiplicity[i] = 0;
};
for (int i=0; i<fNumTdc; ++i) {
fTdcTimeRaw[i] = 0;
fTdcTime[i] = 0.0;
fTdcMultiplicity[i] = 0;
};
}
Int_t THcTrigDet::Decode(const THaEvData& evData) {
Bool_t present = kTRUE; // Don't suppress reference time warnings
if(HaveIgnoreList()) {
if(IsIgnoreType(evData.GetEvType())) {
present = kFALSE;
}
} else if(fPresentP) { // if this spectrometer not part of trigger
present = *fPresentP;
}
Int_t numHits = DecodeToHitList(evData, !present);
// Process each hit and fill variables.
Int_t iHit = 0;
while (iHit < numHits) {
THcTrigRawHit* hit = dynamic_cast<THcTrigRawHit*>(fRawHitList->At(iHit));
THcRawAdcHit rawAdcHit = hit->GetRawAdcHit();
fAdcMultiplicity[cnt] = rawAdcHit.GetNPulses();
UInt_t good_hit=999;
for (UInt_t thit=0; thit<rawAdcHit.GetNPulses(); ++thit) {
Int_t TestTime=rawAdcHit.GetPulseTimeRaw(thit);
if (TestTime>fAdcTimeWindowMin[cnt]&&TestTime<fAdcTimeWindowMax[cnt]&&good_hit==999) {
good_hit=thit;
}
}
fAdcPedRaw[cnt] = rawAdcHit.GetPedRaw();
fAdcPulseIntRaw[cnt] = rawAdcHit.GetPulseIntRaw(good_hit);
fAdcPulseAmpRaw[cnt] = rawAdcHit.GetPulseAmpRaw(good_hit);
fAdcPulseTimeRaw[cnt] = rawAdcHit.GetPulseTimeRaw(good_hit);
fAdcPulseTime[cnt] = rawAdcHit.GetPulseTime(good_hit)+fAdcTdcOffset;
fAdcPed[cnt] = rawAdcHit.GetPed();
fAdcPulseInt[cnt] = rawAdcHit.GetPulseInt(good_hit);
fAdcPulseAmp[cnt] = rawAdcHit.GetPulseAmp(good_hit);
}
else if (hit->fPlane == 2) {
THcRawTdcHit rawTdcHit = hit->GetRawTdcHit();
for (UInt_t thit=0; thit<rawTdcHit.GetNHits(); ++thit) {
Int_t TestTime= rawTdcHit.GetTimeRaw(thit);
if (TestTime>fTdcTimeWindowMin[cnt]&&TestTime<fTdcTimeWindowMax[cnt]&&good_hit==999) {
good_hit=thit;
}
fTdcTimeRaw[cnt] = rawTdcHit.GetTimeRaw(good_hit);
fTdcTime[cnt] = rawTdcHit.GetTime(good_hit)*fTdcChanperNS+fTdcOffset;
fTdcMultiplicity[cnt] = rawTdcHit.GetNHits();
else {
throw std::out_of_range(
"`THcTrigDet::Decode`: only planes `1` and `2` available!"
);
}
++iHit;
}
return 0;
}
void THcTrigDet::Setup(const char* name, const char* description) {
// Prefix for parameters in `param` file.
string kwPrefix = string(GetApparatus()->GetName()) + "_" + name;
std::transform(kwPrefix.begin(), kwPrefix.end(), kwPrefix.begin(), ::tolower);
fKwPrefix = kwPrefix;
}
Int_t THcTrigDet::ReadDatabase(const TDatime& date) {
std::string adcNames, tdcNames;
std::string trigNames="pTRIG1_ROC1 pTRIG4_ROC1 pTRIG1_ROC2 pTRIG4_ROC2";
DBRequest list[] = {
{"_numAdc", &fNumAdc, kInt}, // Number of ADC channels.
{"_numTdc", &fNumTdc, kInt}, // Number of TDC channels.
{"_adcNames", &adcNames, kString}, // Names of ADC channels.
{"_tdcNames", &tdcNames, kString}, // Names of TDC channels.
{"_trigNames", &trigNames, kString,0,1}, // Names of Triggers for coincidence time.
{"_tdcoffset", &fTdcOffset, kDouble,0,1}, // Offset of tdc channels
{"_adc_tdc_offset", &fAdcTdcOffset, kDouble,0,1}, // Offset of Adc Pulse time (ns)
{"_tdcchanperns", &fTdcChanperNS, kDouble,0,1}, // Convert channesl to ns
gHcParms->LoadParmValues(list, fKwPrefix.c_str());
//
fAdcTimeWindowMin = new Double_t [fNumAdc];
fAdcTimeWindowMax = new Double_t [fNumAdc];
fTdcTimeWindowMin = new Double_t [fNumTdc];
fTdcTimeWindowMax = new Double_t [fNumTdc];
for(Int_t ip=0;ip<fNumAdc;ip++) { // Set a large default window
fAdcTimeWindowMin[ip]=0;
fAdcTimeWindowMax[ip]=10000;
}
for(Int_t ip=0;ip<fNumTdc;ip++) { // Set a large default window
fTdcTimeWindowMin[ip]=0;
fTdcTimeWindowMax[ip]=10000;
}
DBRequest list2[]={
{"_AdcTimeWindowMin", fAdcTimeWindowMin, kDouble, (UInt_t) fNumAdc, 1},
{"_AdcTimeWindowMax", fAdcTimeWindowMax, kDouble, (UInt_t) fNumAdc, 1},
{"_TdcTimeWindowMin", fTdcTimeWindowMin, kDouble, (UInt_t) fNumTdc, 1},
{"_TdcTimeWindowMax", fTdcTimeWindowMax, kDouble, (UInt_t) fNumTdc, 1},
{0}
};
gHcParms->LoadParmValues(list2, fKwPrefix.c_str());
for(Int_t ip=0;ip<fNumTdc;ip++) {
// cout << ip << " " << fTdcNames.at(ip) << " " << fTdcTimeWindowMin[ip] << " " << fTdcTimeWindowMax[ip] << endl;
}
// Split the names to std::vector<std::string>.
fAdcNames = vsplit(adcNames);
fTdcNames = vsplit(tdcNames);
//Assign an index to coincidence trigger times strings
for (UInt_t j = 0; j <fTrigNames.size(); j++) {
fTrigId[j]=-1;
}
for (int i = 0; i <fNumTdc; i++) {
for (UInt_t j = 0; j <fTrigNames.size(); j++) {
if(fTdcNames.at(i)==fTrigNames[j]) fTrigId[j]=i;
}
}
cout << " Trig = " << fTrigNames.size() << endl;
for (UInt_t j = 0; j <fTrigNames.size(); j++) {
cout << fTrigNames[j] << " " << fTrigId[j] << endl;
}
return kOK;
}
Int_t THcTrigDet::DefineVariables(THaAnalysisObject::EMode mode) {
if (mode == kDefine && fIsSetup) return kOK;
fIsSetup = (mode == kDefine);
std::vector<RVarDef> vars;
//Push the variable names for ADC channels.
std::vector<TString> adcPedRawTitle(fNumAdc), adcPedRawVar(fNumAdc);
std::vector<TString> adcPulseIntRawTitle(fNumAdc), adcPulseIntRawVar(fNumAdc);
std::vector<TString> adcPulseAmpRawTitle(fNumAdc), adcPulseAmpRawVar(fNumAdc);
std::vector<TString> adcPulseTimeRawTitle(fNumAdc), adcPulseTimeRawVar(fNumAdc);
Mark Jones
committed
std::vector<TString> adcPulseTimeTitle(fNumAdc), adcPulseTimeVar(fNumAdc);
std::vector<TString> adcPedTitle(fNumAdc), adcPedVar(fNumAdc);
std::vector<TString> adcPulseIntTitle(fNumAdc), adcPulseIntVar(fNumAdc);
std::vector<TString> adcPulseAmpTitle(fNumAdc), adcPulseAmpVar(fNumAdc);
std::vector<TString> adcMultiplicityTitle(fNumAdc), adcMultiplicityVar(fNumAdc);
adcPedRawTitle.at(i) = fAdcNames.at(i) + "_adcPedRaw";
adcPedRawVar.at(i) = TString::Format("fAdcPedRaw[%d]", i);
adcPedRawTitle.at(i).Data(),
adcPedRawTitle.at(i).Data(),
adcPedRawVar.at(i).Data()
};
vars.push_back(entry1);
adcPulseIntRawTitle.at(i) = fAdcNames.at(i) + "_adcPulseIntRaw";
adcPulseIntRawVar.at(i) = TString::Format("fAdcPulseIntRaw[%d]", i);
adcPulseIntRawTitle.at(i).Data(),
adcPulseIntRawTitle.at(i).Data(),
adcPulseIntRawVar.at(i).Data()
};
vars.push_back(entry2);
adcPulseAmpRawTitle.at(i) = fAdcNames.at(i) + "_adcPulseAmpRaw";
adcPulseAmpRawVar.at(i) = TString::Format("fAdcPulseAmpRaw[%d]", i);
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
adcPulseAmpRawTitle.at(i).Data(),
adcPulseAmpRawTitle.at(i).Data(),
adcPulseAmpRawVar.at(i).Data()
};
vars.push_back(entry3);
adcPulseTimeRawTitle.at(i) = fAdcNames.at(i) + "_adcPulseTimeRaw";
adcPulseTimeRawVar.at(i) = TString::Format("fAdcPulseTimeRaw[%d]", i);
RVarDef entry4 {
adcPulseTimeRawTitle.at(i).Data(),
adcPulseTimeRawTitle.at(i).Data(),
adcPulseTimeRawVar.at(i).Data()
};
vars.push_back(entry4);
adcPedTitle.at(i) = fAdcNames.at(i) + "_adcPed";
adcPedVar.at(i) = TString::Format("fAdcPed[%d]", i);
RVarDef entry5 {
adcPedTitle.at(i).Data(),
adcPedTitle.at(i).Data(),
adcPedVar.at(i).Data()
};
vars.push_back(entry5);
adcPulseIntTitle.at(i) = fAdcNames.at(i) + "_adcPulseInt";
adcPulseIntVar.at(i) = TString::Format("fAdcPulseInt[%d]", i);
RVarDef entry6 {
adcPulseIntTitle.at(i).Data(),
adcPulseIntTitle.at(i).Data(),
adcPulseIntVar.at(i).Data()
};
vars.push_back(entry6);
adcPulseAmpTitle.at(i) = fAdcNames.at(i) + "_adcPulseAmp";
adcPulseAmpVar.at(i) = TString::Format("fAdcPulseAmp[%d]", i);
RVarDef entry7 {
adcPulseAmpTitle.at(i).Data(),
adcPulseAmpTitle.at(i).Data(),
adcPulseAmpVar.at(i).Data()
};
vars.push_back(entry7);
adcMultiplicityTitle.at(i) = fAdcNames.at(i) + "_adcMultiplicity";
adcMultiplicityVar.at(i) = TString::Format("fAdcMultiplicity[%d]", i);
RVarDef entry8 {
adcMultiplicityTitle.at(i).Data(),
adcMultiplicityTitle.at(i).Data(),
adcMultiplicityVar.at(i).Data()
Mark Jones
committed
adcPulseTimeTitle.at(i) = fAdcNames.at(i) + "_adcPulseTime";
adcPulseTimeVar.at(i) = TString::Format("fAdcPulseTime[%d]", i);
RVarDef entry9 {
adcPulseTimeTitle.at(i).Data(),
adcPulseTimeTitle.at(i).Data(),
adcPulseTimeVar.at(i).Data()
};
vars.push_back(entry9);
} // loop over fNumAdc
// Push the variable names for TDC channels.
std::vector<TString> tdcTimeRawTitle(fNumTdc), tdcTimeRawVar(fNumTdc);
std::vector<TString> tdcTimeTitle(fNumTdc), tdcTimeVar(fNumTdc);
std::vector<TString> tdcMultiplicityTitle(fNumTdc), tdcMultiplicityVar(fNumTdc);
tdcTimeRawTitle.at(i) = fTdcNames.at(i) + "_tdcTimeRaw";
tdcTimeRawVar.at(i) = TString::Format("fTdcTimeRaw[%d]", i);
tdcTimeRawTitle.at(i).Data(),
tdcTimeRawTitle.at(i).Data(),
tdcTimeRawVar.at(i).Data()
};
vars.push_back(entry1);
tdcTimeTitle.at(i) = fTdcNames.at(i) + "_tdcTime";
tdcTimeVar.at(i) = TString::Format("fTdcTime[%d]", i);
tdcTimeTitle.at(i).Data(),
tdcTimeTitle.at(i).Data(),
tdcTimeVar.at(i).Data()
};
vars.push_back(entry2);
tdcMultiplicityTitle.at(i) = fTdcNames.at(i) + "_tdcMultiplicity";
tdcMultiplicityVar.at(i) = TString::Format("fTdcMultiplicity[%d]", i);
RVarDef entry3 {
tdcMultiplicityTitle.at(i).Data(),
tdcMultiplicityTitle.at(i).Data(),
tdcMultiplicityVar.at(i).Data()
RVarDef end {0};
vars.push_back(end);
return DefineVarsFromList(vars.data(), mode);
}
void THcTrigDet::SetSpectName( const char* name)
{
fSpectName = name;
}
void THcTrigDet::AddEvtType(int evtype) {
eventtypes.push_back(evtype);
}
void THcTrigDet::SetEvtType(int evtype) {
eventtypes.clear();
AddEvtType(evtype);
}
Bool_t THcTrigDet::IsIgnoreType(Int_t evtype) const
{
for (UInt_t i=0; i < eventtypes.size(); i++) {
if (evtype == eventtypes[i]) return kTRUE;
}
return kFALSE;
}
Bool_t THcTrigDet::HaveIgnoreList() const
{
return( (eventtypes.size()>0) ? kTRUE : kFALSE);
}
//_____________________________________________________________________________
Int_t THcTrigDet::End(THaRunBase* run)
{
MissReport(Form("%s.%s", GetApparatus()->GetName(), GetName()));
return 0;
}