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.
# Defined variables
For ADC channels it defines:
- ADC value: `var_adc`
- pedestal: `var_adcPed`
- multiplicity: `var_adcMult`
For TDC channels it defines:
- TDC value: `var_tdc`
- 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.
43
44
45
46
47
48
49
50
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
*/
/**
\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 "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(),
fAdcVal(), fAdcPedestal(), fAdcMultiplicity(),
fTdcVal(), fTdcMultiplicity()
{}
THcTrigDet::~THcTrigDet() {}
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) fAdcVal[i] = -1.0;
for (int i=0; i<fMaxTdcChannels; ++i) fTdcVal[i] = -1.0;
// Call initializer for base class.
// This also calls `ReadDatabase` and `DefineVariables`.
EStatus status = THaDetector::Init(date);
if (status) {
fStatus = status;
return fStatus;
}
// Initialize hitlist part of the class.
InitHitList(fDetMap, "THcTrigRawHit", 100);
// 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;
}
fStatus = kOK;
return fStatus;
}
void THcTrigDet::Clear(Option_t* opt) {
THaAnalysisObject::Clear(opt);
for (int i=0; i<fNumAdc; ++i) fAdcVal[i] = 0.0;
for (int i=0; i<fNumTdc; ++i) fTdcVal[i] = 0.0;
}
Int_t THcTrigDet::Decode(const THaEvData& evData) {
// Decode raw data for this event.
Int_t numHits = DecodeToHitList(evData);
// Process each hit and fill variables.
Int_t iHit = 0;
while (iHit < numHits) {
THcTrigRawHit* hit = dynamic_cast<THcTrigRawHit*>(fRawHitList->At(iHit));
if (hit->fPlane == 1) {
fAdcVal[hit->fCounter-1] = hit->GetData(0, 0);
fAdcPedestal[hit->fCounter-1] = hit->GetAdcPedestal(0);
fAdcMultiplicity[hit->fCounter-1] = hit->GetMultiplicity(0);
}
else if (hit->fPlane == 2) {
fTdcVal[hit->fCounter-1] = hit->GetData(1, 0);
fTdcMultiplicity[hit->fCounter-1] = hit->GetMultiplicity(1);
}
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);
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
fKwPrefix = kwPrefix;
}
Int_t THcTrigDet::ReadDatabase(const TDatime& date) {
std::string adcNames, tdcNames;
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.
{0}
};
gHcParms->LoadParmValues(list, fKwPrefix.c_str());
// Split the names to std::vector<std::string>.
fAdcNames = vsplit(adcNames);
fTdcNames = vsplit(tdcNames);
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> adcValTitle(fNumAdc), adcValVar(fNumAdc);
std::vector<TString> adcPedestalTitle(fNumAdc), adcPedestalVar(fNumAdc);
std::vector<TString> adcMultiplicityTitle(fNumAdc), adcMultiplicityVar(fNumAdc);
adcValTitle.at(i) = fAdcNames.at(i) + "_adc";
adcValVar.at(i) = TString::Format("fAdcVal[%d]", i);
vars.push_back({
adcValTitle.at(i).Data(),
adcValTitle.at(i).Data(),
adcValVar.at(i).Data()
});
adcPedestalTitle.at(i) = fAdcNames.at(i) + "_adcPed";
adcPedestalVar.at(i) = TString::Format("fAdcPedestal[%d]", i);
vars.push_back({
adcPedestalTitle.at(i).Data(),
adcPedestalTitle.at(i).Data(),
adcPedestalVar.at(i).Data()
});
adcMultiplicityTitle.at(i) = fAdcNames.at(i) + "_adcMult";
adcMultiplicityVar.at(i) = TString::Format("fAdcMultiplicity[%d]", i);
adcMultiplicityTitle.at(i).Data(),
adcMultiplicityTitle.at(i).Data(),
adcMultiplicityVar.at(i).Data()
// Push the variable names for TDC channels.
std::vector<TString> tdcValTitle(fNumTdc), tdcValVar(fNumTdc);
std::vector<TString> tdcMultiplicityTitle(fNumTdc), tdcMultiplicityVar(fNumTdc);
tdcValTitle.at(i) = fTdcNames.at(i) + "_tdc";
tdcValVar.at(i) = TString::Format("fTdcVal[%d]", i);
vars.push_back({
tdcValTitle.at(i).Data(),
tdcValTitle.at(i).Data(),
tdcValVar.at(i).Data()
});
tdcMultiplicityTitle.at(i) = fTdcNames.at(i) + "_tdcMult";
tdcMultiplicityVar.at(i) = TString::Format("fTdcMultiplicity[%d]", i);
tdcMultiplicityTitle.at(i).Data(),
tdcMultiplicityTitle.at(i).Data(),
tdcMultiplicityVar.at(i).Data()