Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
TwoarmVDCTimeCorrection.cxx
Go to the documentation of this file.
1//*-- Author : Ole Hansen 18-Oct-19
2
4//
5// HallA::TwoarmVDCTimeCorrection
6//
7// Calculates a trigger time correction for the VDC from the TDC
8// difference between two scintillators.
9// Runs after Decode.
10//
12
14#include "THaDetector.h"
15#include "THaAnalyzer.h"
16#include "THaVarList.h"
17#include "THaCut.h"
18#include "THaGlobals.h"
19#include "TError.h"
20#include <vector>
21
22using namespace std;
24
25namespace HallA {
26
27//_____________________________________________________________________________
29 const char* description, const char* scint1, const char* scint2,
30 const char* cond )
31 : TimeCorrectionModule(name, description, THaAnalyzer::kDecode),
32 fDet{DetDef(scint1), DetDef(scint2)}, fCondExpr(cond), fCond(nullptr),
33 fDidInitDefs(false)
34{
35 // Constructor
36}
37
38//_____________________________________________________________________________
40{
41 // Destructor
42
43 delete fCond;
44}
45
46//_____________________________________________________________________________
49{
50 // Initialize the module.
51 // Locate the relevant variables of the two scintillator detectors specified
52 // in the constructor and store pointers to them
53
54 const char* const here = "Init";
55
56 // Standard initialization. Calls this object's ReadDatabase()
57 // and DefineVariables().
58 if( InterStageModule::Init( run_time ) != kOK )
59 return fStatus;
60
61 // Make the name of our block of tests. We need fPrefix to be set
63
64 // Find reference detectors
65 // In principle we should check that these are THaScintillators, but Tritium/nnL
66 // use their own TriFadcScin class, which inherits from THaNonTrackingDetector.
67 // In fact, generic THaDetectors are fine for this purpose. As long as they
68 // export the required variables which have the expected contents (see below),
69 // there's no need to be more restrictive.
70 fStatus = kOK;
71 for( auto& detdef : fDet ) {
72 auto* obj = dynamic_cast<THaDetector*>
73 ( FindModule(detdef.fName.Data(), "THaDetector"));
74 if( !obj ) {
76 // Keep going to get reports on all failures
77 continue;
78 }
79 detdef.fObj = obj;
80 detdef.fNelem = obj->GetNelem();
81 // Retrieve pointers to the global variables we need
82 class VarDef {
83 public:
85 THaVar*& pvar;
86 };
87 vector<VarDef> vardefs {
88 { detdef.fName + ".nthit", detdef.fNthit },
89 { detdef.fName + ".t_pads", detdef.fTpad },
90 { detdef.fName + ".rt_c", detdef.fRT },
91 { detdef.fName + ".lt_c", detdef.fLT }
92 };
93 for( const auto& vardef : vardefs ) {
94 vardef.pvar = gHaVars->Find(vardef.name); // sets the relevant THaVar
95 // pointer in the current detdef
96 if( !vardef.pvar ) {
97 Error(Here(here), "Global variable %s not found. "
98 "Module not initialized.", vardef.name.Data() );
100 // Keep going to get reports on all failures
101 }
102 }
103 }
104 fIsInit = (fStatus == kOK);
105
106 return fStatus;
107}
108
109//_____________________________________________________________________________
111{
112 // Calculate per-event time correction
113
114 const char* const here = "Process";
115
116 if( !fIsInit )
117 return -1;
118
119 if( !fDidInitDefs ) {
120 InitDefs();
121 fDidInitDefs = true;
122 }
123
125 if( fCond && !fCond->EvalCut() )
126 return 0;
127
128 const DetDef& det1 = fDet[0], det2 = fDet[1];
129 if( det1.fNthit->GetValueInt() > 0 && det2.fNthit->GetValueInt() > 0 ) {
130 // Both scintillators have at least one complete hit, i.e. the TDCs on both
131 // sides of a paddle fired
132 //FIXME: taking index = 0 when fNthit > 1 not necessarily correct!
133 auto thePad1 = static_cast<Int_t>( det1.fTpad->GetValueInt(0) );
134 auto thePad2 = static_cast<Int_t>( det2.fTpad->GetValueInt(0) );
135 if( thePad1 >= 0 && thePad1 < det1.fNelem &&
136 thePad2 >= 0 && thePad2 < det2.fNelem ) {
137 //TODO: use fLT too
138 fEvtTime += det1.fRT->GetValue(thePad1) - det2.fRT->GetValue(thePad2);
139 fDataValid = true;
140 } else {
141 // If we get here, the detector lied to us: if fNthit > 0, then all
142 // fTpad[i] should always be valid pad numbers
143 Warning(Here(here), "Bad pad number %s = %d, %s = %d. "
144 "Should never happen. Call expert.",
145 det1.fTpad->GetName(), thePad1, det2.fTpad->GetName(), thePad2);
146 return -2;
147 }
148 }
149
150 return 0;
151}
152
153//_____________________________________________________________________________
155{
156 // Read this detector's parameters from the database.
157 // 'date' contains the date/time of the run being analyzed.
158
159 Int_t ret = TimeCorrectionModule::ReadDatabase(date);
160 if( ret != kOK )
161 return ret;
162
163 FILE* file = OpenFile(date);
164 if( !file ) {
165 // Missing file OK -- all keys are optional
166 fIsInit = true;
167 return kOK;
168 }
169
170 // Read configuration parameters
171 fIsInit = false;
172 DBRequest config_request[] = {
173 { "condition", &fCondExpr, kTString, 0, true },
174 { nullptr }
175 };
176 Int_t err = LoadDB( file, date, config_request );
177 fclose(file);
178 if( err )
179 return err;
180
181 fIsInit = true;
182 return kOK;
183}
184
185//_____________________________________________________________________________
187{
188 // Initialize tests based on the string expressions read from the database.
189 // Return number of successful definitions.
190
191 Int_t ndef = 0;
192
193 // Delete existing test, if any, to allow reinitialization
194 delete fCond;
195 fCond = nullptr;
196
197 // Parse test expression, if any
198 if( !fCondExpr.IsNull() ) {
199 fCond = new THaCut( "cond", fCondExpr, fTestBlockName );
200 if( fCond->IsZombie() or fCond->IsError() ) {
201 delete fCond;
202 fCond = nullptr;
203 }
204 ++ndef;
205 }
206
207 return ndef;
208}
209
210//____________________________________________________________________________
212{
213 // Create the test block name
214
215 if( fPrefix && *fPrefix ) {
217 fTestBlockName.Chop(); // remove trailing "."
218 } else
220 fTestBlockName.Append("_Tests");
221}
222
223//_____________________________________________________________________________
224
225} // namespace HallA
226
228
int Int_t
char name[80]
R__EXTERN class THaVarList * gHaVars
Definition THaGlobals.h:11
static const char *const here
Definition THaVar.cxx:64
virtual Int_t Process(const THaEvData &)
TwoarmVDCTimeCorrection(const char *name, const char *description, const char *scint1, const char *scint2, const char *cond="")
virtual Int_t ReadDatabase(const TDatime &date)
static Int_t LoadDB(FILE *file, const TDatime &date, const DBRequest *request, const char *prefix, Int_t search=0, const char *here="THaAnalysisObject::LoadDB")
virtual const char * Here(const char *) const
THaAnalysisObject * FindModule(const char *name, const char *classname, bool do_error=true)
virtual FILE * OpenFile(const TDatime &date)
Bool_t EvalCut()
Definition THaCut.h:31
Bool_t IsError() const
Definition THaFormula.h:53
virtual THaVar * Find(const char *name) const
Double_t GetValue(Int_t i=0) const
Definition THaVar.h:48
Long64_t GetValueInt(Int_t i=0) const
Definition THaVar.h:49
const char * GetName() const override
TString fName
virtual void Warning(const char *method, const char *msgfmt,...) const
R__ALWAYS_INLINE Bool_t IsZombie() const
virtual void Error(const char *method, const char *msgfmt,...) const
TString & Chop()
TString & Append(char c, Ssiz_t rep=1)
Bool_t IsNull() const
STL namespace.
ClassImp(TPyArg)