JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwCombinedBCM.cc
Go to the documentation of this file.
1/*!
2 * \file QwCombinedBCM.cc
3 * \brief Combined beam current monitor implementation using weighted averages
4 *
5 * Combined beam current monitor implementation: weighted average of multiple
6 * BCMs with optional beam trip simulation, resolution smearing, and random
7 * event generation. Template class supporting various channel types.
8 * Documentation-only edits; runtime behavior unchanged.
9 */
10
11#include "QwCombinedBCM.h"
12
13// System headersF
14#include <stdexcept>
15
16// Qweak headers
17#ifdef __USE_DATABASE__
18#include "QwDBInterface.h"
19#endif // __USE_DATABASE__
20
21// Qweak types that we want to use in this template
22#include "QwVQWK_Channel.h"
23#include "QwADC18_Channel.h"
24#include "QwScaler_Channel.h"
25#include "QwMollerADC_Channel.h"
26
27
28// Randomness generator: Mersenne twister with period 2^19937 - 1
29//
30// This is defined as static to avoid getting stuck with 100% correlated
31// ADC channels when each channel goes through the same list of pseudo-
32// random numbers...
33
34template<typename T> boost::mt19937 QwCombinedBCM<T>::fRandomnessGenerator;
35template<typename T> boost::random::uniform_real_distribution<double> QwCombinedBCM<T>::fDistribution;
36
37// The boost::variate_generator has operator() overloaded to get a new random
38// value according to the distribution in the second template argument, based
39// on the uniform random value generated by the first template argument.
40// For example: fNormalRandomVariable() will return a random normal variable.
41
42template<typename T> boost::variate_generator < boost::mt19937, boost::random::uniform_real_distribution<double> >
44
45/** Set random number generator seed for beam trip simulation. */
46template<typename T>
48{
49 fRandomVariable.engine().seed(seedval);
50}
51
52/********************************************************/
53
54//this is a combined BCM made out of BCMs that are already calibrated and have pedstals removed.
55//This will be used for projection of charge at the target
56
57/**
58 * Add a constituent BCM to the combination with specified weight.
59 *
60 * @param bcm Pointer to the BCM to include.
61 * @param weight Charge weight for this BCM.
62 * @param sumqw Total sum of absolute weights.
63 */
64template<typename T>
65void QwCombinedBCM<T>::SetBCMForCombo(VQwBCM* bcm, Double_t weight, Double_t sumqw )
66{
67 // Convert back to QWBCM<T>* from generic VQwBCM*
68 fElement.push_back(dynamic_cast<QwBCM<T>* >(bcm));
69 fWeights.push_back(weight);
70 fSumQweights = sumqw;
71}
72
73/********************************************************/
74
75/** Initialize combined BCM with simple name and default settings. */
76template<typename T>
77void QwCombinedBCM<T>::InitializeChannel(TString name, TString datatosave)
78{
79 SetPedestal(0.);
81 fLastTripTime = -99999.9;
82 this->SetElementName(name);
83 this->fBeamCurrent.InitializeChannel(name,"derived");
84}
85
86/** Initialize combined BCM with subsystem scoping. */
87template<typename T>
88void QwCombinedBCM<T>::InitializeChannel(TString subsystem, TString name, TString datatosave)
89{
90 SetPedestal(0.);
92 fLastTripTime = -99999.9;
93 this->SetElementName(name);
94 this->fBeamCurrent.InitializeChannel(subsystem, "QwCombinedBCM", name,"derived");
95}
96
97template<typename T>
98void QwCombinedBCM<T>::InitializeChannel(TString subsystem, TString name,
99 TString type, TString datatosave)
100{
101 SetPedestal(0.);
103 fLastTripTime = -99999.9;
104 this->SetElementName(name);
105 this->SetModuleType(type);
106 this->fBeamCurrent.InitializeChannel(subsystem, "QwCombinedBCM", name,"derived");
107}
108
109
110/********************************************************/
111/**
112 * Compute weighted average of constituent BCM currents and normalize by
113 * total weight sum.
114 */
115template<typename T>
117{
118 static T tmpADC;
119 tmpADC.InitializeChannel("tmp","derived");
120
121 this->ClearEventData();
122
123 for (size_t i = 0; i < fElement.size(); i++) {
124 tmpADC = fElement[i]->fBeamCurrent;
125 tmpADC.Scale(fWeights[i]);
126 this->fBeamCurrent += tmpADC;
127 }
128 this->fBeamCurrent.Scale(1.0/fSumQweights);
129
130 Bool_t ldebug = kFALSE;
131 if (ldebug) {
132 QwMessage << "*****************" << QwLog::endl;
133 QwMessage << "QwCombinedBCM: " << this->GetElementName() << QwLog::endl
134 << "weighted average of hardware sums = " << this->fBeamCurrent.GetValue() << QwLog::endl;
135 if (this->fBeamCurrent.GetNumberOfSubelements() > 1) {
136 for (size_t i = 0; i < 4; i++) {
137 QwMessage << "weighted average of block[" << i << "] = " << this->fBeamCurrent.GetValue(i) << QwLog::endl;
138 }
139 }
140 QwMessage << "*****************" << QwLog::endl;
141 }
142}
143
144//---------------------------------------------------------------------------------------------------------
145
146
147/**
148 * Project the combined current to a device channel, applying resolution
149 * smearing and filling raw event data.
150 */
151template<typename T>
153{
154 (device->GetCharge())->AssignScaledValue(this->fBeamCurrent,1.0);
155 //device->PrintInfo();
156 device->ApplyResolutionSmearing();
157 //device->PrintInfo();
158 device->FillRawEventData();
159}
160
161
162/**
163 * Generate random event data and optionally simulate beam trips with
164 * configurable trip period, length, and ramp duration.
165 */
166template<typename T>
167void QwCombinedBCM<T>::RandomizeEventData(int helicity, double time)
168{
169 this->fBeamCurrent.RandomizeEventData(helicity, time);
170 // do the beam cut routine from MockDataGenerator, but just scale fBeamCurrent instead of re-randomizing
171 // Three time intervals: fmod(time,period) > (period-tripramp): Do the ramp scaling
172 // (period-tripramp) > fmod(time,period) > (period-triplength- tripramp): scale by 0.0
173 // (period-triplength- tripramp) > fmod(time,period) : leave the variable alone
174
175
176 // Determine the probability of having a beam trip
177 if (fLastTripTime<=-99999.9) {
179 }
180// if ( ((time-fLastTripTime) > (fTripPeriod)) ){ // Make some comparison to a probablilty instead of the time
181// Probability of a trip happening in one event: # of trips per hour/3600 * eventtime_in_seconds (which is 0.001s)
182 Double_t tmp = fRandomVariable();
183// std::cout << "random value=="<<tmp << "; fProbabilityOfTrip=="<<fProbabilityOfTrip<<std::endl;
184 if (tmp < fProbabilityOfTrip) {
185 fLastTripTime = time;
186 std::cout << "random value=="<<tmp << "; fProbabilityOfTrip=="<<fProbabilityOfTrip<<"; time=="<<time<<std::endl;
187 }
188
189 Double_t time_since_trip = time - fLastTripTime;
190 if (time_since_trip <= fTripLength) {
191 this->fBeamCurrent.Scale(0.0);
192 //std::cout << "fBeamCurrent.Scale(0.0)" << std::endl;
193 } else if (time_since_trip < (fTripLength + fTripRamp)) {
194 Double_t factor = (time_since_trip-fTripLength)/fTripRamp;
195 //std::cout << "(fTripPeriod - fmod(time, fTripPeriod))=="<<(fTripPeriod - fmod(time, fTripPeriod))<<"; fTripLength=="<<fTripLength
196 // << "; ((fTripPeriod - fmod(time, fTripPeriod)) / fTripLength)=="<<((fTripPeriod - fmod(time, fTripPeriod)) / fTripLength)
197 // << std::endl;
198 this->fBeamCurrent.Scale(factor);
199 //std::cout << "fBeamCurrent.Scale(factor) = " << factor << std::endl;
200 }
201}
202
203
204/**
205 * Load mock data parameters including beam trip settings and resolution.
206 * Recognizes 'beamtrip' and 'resolution' keywords.
207 */
208template<typename T>
210
211 Double_t res=0.0;
212
213 // Test for the word "beamtrip", and get the tripperiod and tripduration if it is found, otherwise, just pass
214 // the line to the fBeamCurrent object.
215 if (paramfile.GetLine().find("beamtrip")!=std::string::npos){
216 // "beamtrip" appears somewhere in the line. Assume it is the next token and move on...
217 paramfile.GetNextToken(); //Throw away this token. Now the next three should be the beamtrip parameters.
218
219 fTripPeriod = paramfile.GetTypedNextToken<Double_t>() * Qw::sec;
220 fTripLength = paramfile.GetTypedNextToken<Double_t>() * Qw::sec;
221 fTripRamp = paramfile.GetTypedNextToken<Double_t>() * Qw::sec;
222
224 } else if (paramfile.GetLine().find("resolution")!=std::string::npos){
225 paramfile.GetNextToken();
226 res = paramfile.GetTypedNextToken<Double_t>();
227 this->SetResolution(res);
228 } else {
229 //std::cout << "In QwCombinedBCM: ChannelName = " << this->GetElementName() << std::endl;
230 this->fBeamCurrent.LoadMockDataParameters(paramfile);
231 }
232}
233
234//---------------------------------------------------------------------------------------------------------
235
236
237/********************************************************/
238/**
239 * Apply single-event cuts: first propagate error codes from constituent
240 * BCMs, then apply cuts using the inherited BCM logic.
241 */
242template<typename T>
244{
245
246 //This is required to update single event cut failures in individual channels
247 // First update the error code based on the codes
248 // of the elements. This requires that the BCMs
249 // have had ApplySingleEventCuts run on them already.
250
251 for (size_t i=0;i<fElement.size();i++){
252 this->fBeamCurrent.UpdateErrorFlag(fElement.at(i)->fBeamCurrent.GetErrorCode());
253 }
254
255
256 // Everything is identical as for a regular BCM
258}
259
260/**
261 * Update error flags by propagating error codes from constituent BCMs.
262 */
263template<typename T>
265 for (size_t i=0;i<fElement.size();i++){
266 this->fBeamCurrent.UpdateErrorFlag(fElement.at(i)->fBeamCurrent.GetErrorCode());
267 }
268 return this->fBeamCurrent.GetEventcutErrorFlag();
269}
270
271
272/********************************************************/
273/*
274template<typename T>
275void QwCombinedBCM<T>::UpdateErrorFlag(const VQwBCM *ev_error){
276
277 try {
278 if(typeid(*ev_error)==typeid(*this)) {
279 // std::cout<<" Here in QwCombinedBCM::UpdateErrorFlag \n";
280 if (this->GetElementName()!="") {
281 QwCombinedBCM<T>* value_bcm = dynamic_cast<QwCombinedBCM<T>* >(ev_error);
282 VQwDataElement *value_data = dynamic_cast<VQwDataElement *>(&(value_bcm->fBeamCurrent));
283 fBeamCurrent.UpdateErrorFlag(value_data->GetErrorCode());//the routine GetErrorCode() return the error flag + configuration flag unconditionally
284 }
285 } else {
286 TString loc="Standard exception from QwCombinedBCM::UpdateErrorFlag :"+
287 ev_error->GetElementName()+" "+this->GetElementName()+" are not of the "
288 +"same type";
289 throw std::invalid_argument(loc.Data());
290 }
291 } catch (std::exception& e) {
292 std::cerr<< e.what()<<std::endl;
293 }
294
295 QwBCM<T>::UpdateErrorFlag(const ev_error);
296};
297*/
298
299/********************************************************/
300/*
301template<typename T>
302void QwCombinedBCM<T>::CalculateRunningAverage(){
303 fBeamCurrent.CalculateRunningAverage();
304=======
305 return eventokay;
306>>>>>>> .merge-right.r3406
307}
308*/
309/********************************************************/
310/*
311template<typename T>
312<<<<<<< .working
313void QwCombinedBCM<T>::AccumulateRunningSum(const VQwBCM &value){
314 fBeamCurrent.AccumulateRunningSum(dynamic_cast<const QwCombinedBCM<T>* >(&value)->fBeamCurrent);
315}
316*/
317/********************************************************/
318/*
319template<typename T>
320void QwCombinedBCM<T>::DeaccumulateRunningSum(VQwBCM &value){
321 fBeamCurrent.DeaccumulateRunningSum(dynamic_cast<QwCombinedBCM<T>* >(&value)->fBeamCurrent);
322}
323*/
324
325
326/********************************************************/
327/** Assignment operator: copy the beam current value. */
328template<typename T>
330{
331 if (this->GetElementName()!="")
332 this->fBeamCurrent=value.fBeamCurrent;
333
334 return *this;
335}
336
337/** Polymorphic assignment operator. */
338template<typename T>
340{
341 if (this->GetElementName()!="")
342 dynamic_cast<QwCombinedBCM<T>* >(this)->fBeamCurrent=
343 dynamic_cast<const QwCombinedBCM<T>* >(&value)->fBeamCurrent;
344
345 return *this;
346}
347
348
349/********************************************************/
350/*
351template<typename T>
352Bool_t QwCombinedBCM<T>::ApplyHWChecks()
353{
354 // For the combined devices there are no physical channels that we can relate to because they are being
355 // derived from combinations of physical channels. Therefore, this is not exactly a "HW Check"
356 // but just a check of the HW checks of the combined channels.
357
358 Bool_t eventokay=kTRUE;
359
360 return eventokay;
361}
362*/
363
364/*
365template<typename T>
366Int_t QwCombinedBCM<T>::SetSingleEventCuts(Double_t LL=0, Double_t UL=0){
367 fBeamCurrent.SetSingleEventCuts(LL,UL);
368 return 1;
369}
370
371
372template<typename T>
373void QwCombinedBCM<T>::SetSingleEventCuts(UInt_t errorflag, Double_t LL=0, Double_t UL=0, Double_t stability=0){
374 //set the unique tag to identify device type (bcm,bpm & etc)
375 errorflag|=kBCMErrorFlag;//currently I use the same flag for bcm & combinedbcm
376 QwMessage<<"QwCombinedBCM Error Code passing to QwVQWK_Ch "<<errorflag<<" "<<stability<<QwLog::endl;
377 fBeamCurrent.SetSingleEventCuts(errorflag,LL,UL,stability);
378
379}
380
381
382template<typename T>
383void QwCombinedBCM<T>::ConstructHistograms(TDirectory *folder, TString &prefix)
384{
385 if (this->GetElementName()=="")
386 {
387 // This channel is not used, so skip filling the histograms.
388 }
389 else
390 {
391 fBeamCurrent.ConstructHistograms(folder, prefix);
392 }
393 return;
394
395}
396
397template<typename T>
398void QwCombinedBCM<T>::FillHistograms()
399{
400 if (this->GetElementName()=="")
401 {
402 // This channel is not used, so skip filling the histograms.
403 }
404 else
405 {
406 fBeamCurrent.FillHistograms();
407 }
408
409
410 return;
411}
412
413template<typename T>
414void QwCombinedBCM<T>::ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values)
415{
416 if (this->GetElementName()==""){
417 // This channel is not used, so skip filling the histograms.
418 } else
419 {
420 fBeamCurrent.ConstructBranchAndVector(tree,prefix,values);
421 }
422 return;
423}
424
425template<typename T>
426void QwCombinedBCM<T>::ConstructBranch(TTree *tree, TString &prefix)
427{
428 if (this->GetElementName()==""){
429 // This channel is not used, so skip filling the histograms.
430 } else
431 {
432 fBeamCurrent.ConstructBranch(tree,prefix);
433 }
434 return;
435}
436
437template<typename T>
438void QwCombinedBCM<T>::ConstructBranch(TTree *tree, TString &prefix, QwParameterFile& modulelist)
439{
440 TString devicename;
441 devicename=this->GetElementName();
442 devicename.ToLower();
443
444 if (this->GetElementName()==""){
445 // This channel is not used, so skip filling the histograms.
446 } else
447 {
448 if (modulelist.HasValue(devicename)){
449 fBeamCurrent.ConstructBranch(tree,prefix);
450 QwMessage <<" Tree leave added to "<<devicename<<QwLog::endl;
451 }
452 }
453 return;
454}
455
456
457template<typename T>
458void QwCombinedBCM<T>::FillTreeVector(QwRootTreeBranchVector &values) const
459{
460 if (this->GetElementName()==""){
461 // This channel is not used, so skip filling the histograms.
462 } else
463 {
464 fBeamCurrent.FillTreeVector(values);
465 }
466 return;
467}
468
469*/
470
471/********************************************************/
472template class QwCombinedBCM<QwVQWK_Channel>;
473template class QwCombinedBCM<QwADC18_Channel>;
Base and derived classes for scaler channel data handling.
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
Decoding and management for Moller ADC channels (6x32-bit datawords)
Decoding and management for VQWK ADC channels (6x32-bit datawords)
Database interface for QwIntegrationPMT and subsystems.
Combined beam current monitor using weighted average of multiple BCMs.
boost::random::uniform_real_distribution< double > QwCombinedBCM< T >::fDistribution
boost::mt19937 QwCombinedBCM< T >::fRandomnessGenerator
static const double sec
Definition QwUnits.h:80
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Configuration file parser with flexible tokenization and search capabilities.
T GetTypedNextToken()
Get next token into specific type.
std::string GetLine()
std::string GetNextToken(const std::string &separatorchars)
Get next token as a string.
virtual const TString & GetElementName() const
Get the name of this element.
void SetElementName(const TString &name)
Set the name of this element.
void SetModuleType(TString ModuleType)
set the type of the beam instrument
Template for a combined beam current monitor using weighted inputs.
Double_t fTripLength
void SetPedestal(Double_t ped) override
Set the pedestal value for the beam current monitor.
Double_t fLastTripTime
void InitializeChannel(TString name, TString datatosave) override
void SetCalibrationFactor(Double_t calib) override
Set the calibration factor for the beam current monitor.
Double_t fTripRamp
static void SetTripSeed(uint seedval)
Double_t fProbabilityOfTrip
void ProcessEvent() override
Double_t fTripPeriod
std::vector< Double_t > fWeights
std::vector< QwBCM< T > * > fElement
void GetProjectedCharge(VQwBCM *device) override
void LoadMockDataParameters(QwParameterFile &paramfile) override
UInt_t UpdateErrorFlag() override
Bool_t ApplySingleEventCuts() override
VQwBCM & operator=(const VQwBCM &value) override
static boost::random::uniform_real_distribution< double > fDistribution
Internal normal probability distribution.
static boost::variate_generator< boost::mt19937, boost::random::uniform_real_distribution< double > > fRandomVariable
Internal normal random variable.
Double_t fSumQweights
void SetBCMForCombo(VQwBCM *bcm, Double_t weight, Double_t sumqw) override
static boost::mt19937 fRandomnessGenerator
Internal randomness generator.
void RandomizeEventData(int helicity=0, double time=0.0) override
void SetResolution(Double_t resolution)
Definition QwBCM.h:79
T fBeamCurrent
Definition QwBCM.h:187
Bool_t ApplySingleEventCuts() override
Apply single-event cuts for this BCM and return pass/fail.
Definition QwBCM.cc:279
void ClearEventData() override
Clear event-scoped data in the underlying channel.
Definition QwBCM.cc:136
QwBCM()
Definition QwBCM.h:40
virtual void FillRawEventData()
Definition VQwBCM.h:119
VQwBCM(VQwDataElement &beamcurrent)
Definition VQwBCM.h:64
virtual const VQwHardwareChannel * GetCharge() const
Definition VQwBCM.h:143
virtual void ApplyResolutionSmearing()
Definition VQwBCM.h:117