JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwBeamMod.cc
Go to the documentation of this file.
1/*!
2 * \file QwBeamMod.cc
3 * \brief Beam modulation subsystem implementation
4 * \author Joshua Hoskins, Ezekiel Wertz, Paul King
5 * \date 2010-05-25
6 */
7
8#include "QwBeamMod.h"
9
10// System headers
11#include <iostream>
12#include <stdexcept>
13
14#ifdef HAS_RNTUPLE_SUPPORT
15// ROOT headers for RNTuple support
16#include <ROOT/RNTupleModel.hxx>
17#include <ROOT/RNTupleWriter.hxx>
18#endif // HAS_RNTUPLE_SUPPORT
19
20// Qweak headers
21#include "QwLog.h"
22#include "QwParameterFile.h"
23#include "QwHistogramHelper.h"
24#include "QwRootFile.h"
25#ifdef __USE_DATABASE__
26#include "QwParitySchema.h"
27#include "QwParityDB.h"
28#endif // __USE_DATABASE__
29
30#include "QwScaler_Channel.h"
31
32// Root plotting headers
33#include "TCanvas.h"
34#include "TF1.h"
35#include "TMath.h"
36
37// Register this subsystem with the factory
39
40
41//*****************************************************************
43 //Handle command line options
44}
45
46Int_t QwBeamMod::LoadChannelMap(TString mapfile){
47 // std::cout <<"Here in LoadChannelMap" << std::endl;
48 Bool_t ldebug=kFALSE;
49
50 Int_t wordsofar=0;
51 Int_t bankindex=-1;
52
53
54 TString varname, varvalue;
55
56 // Open the file
57 QwParameterFile mapstr(mapfile.Data());
59 mapstr.EnableGreediness();
60 mapstr.SetCommentChars("!");
61 while (mapstr.ReadNextLine()) {
63
66 if ((bankindex+1)>0){
67 UInt_t numbanks = UInt_t(bankindex+1);
68 if (fWordsPerSubbank.size()<numbanks){
69 fWordsPerSubbank.resize(numbanks,
70 std::pair<Int_t, Int_t>(fWord.size(),fWord.size()));
71 }
72 }
73 wordsofar=0;
74 }
75 mapstr.TrimWhitespace(); // Get rid of leading and trailing spaces.
76 if (mapstr.LineIsEmpty()) continue;
77
78
79 if (mapstr.HasVariablePair("=",varname,varvalue))
80 {
81 // This is a declaration line. Decode it.
82 varname.ToLower();
83 QwWarning << "QwBeamMod::LoadChannelMap: Unrecognized declaration "
84 << varname << " = " << varvalue << QwLog::endl;
85
86 } else {
87 Bool_t lineok=kTRUE;
88 // QwModChannelID localModChannelID(bankindex, wordsofar,namech, modtype, this);
89 QwModChannelID localModChannelID(bankindex, mapstr);
90 TString namech = localModChannelID.fmodulename;
91 if(localModChannelID.fmoduletype=="VQWK") {
92 wordsofar+=6;
93
94 if (lineok){
95 VQwHardwareChannel* localchan1 = new QwVQWK_Channel();
96
97 localchan1->InitializeChannel(GetName(),"QwBeamMod",localModChannelID.fmodulename,"raw");
98 fModChannel.push_back(localchan1);
99 fModChannel[fModChannel.size()-1]->LoadChannelParameters(mapstr);
100 localModChannelID.fIndex=fModChannel.size()-1;
101 fModChannelID.push_back(localModChannelID);
102 /* localchan1->PrintInfo();
103 localchan1->PrintValue();
104 localchan1->PrintErrorCounters();*/
105 // Store reference to ramp channel
106 if (localModChannelID.fmodulename == "ramp") {
107 fRampChannelIndex = fModChannel.size() - 1;
108 }
109
110 }
111
112 if(ldebug)
113 {
114 localModChannelID.Print();
115 std::cout<<"line ok=";
116 if(lineok) std::cout<<"TRUE"<<std::endl;
117 else std::cout<<"FALSE"<<std::endl;
118 }
119 }
120
121 if(localModChannelID.fmoduletype=="SCALER" || localModChannelID.fmoduletype == "SIS3801D24") {
122 wordsofar+=1;
123
124 if (lineok){
125 VQwHardwareChannel* localchan2 = new QwSIS3801D24_Channel();
126
127 localchan2->InitializeChannel(GetName(),"QwBeamMod",localModChannelID.fmodulename,"raw");
128 fModChannel.push_back(localchan2);
129 fModChannel[fModChannel.size()-1]->LoadChannelParameters(mapstr);
130 localModChannelID.fIndex=fModChannel.size()-1;
131 fModChannelID.push_back(localModChannelID);
132 /* localchan2->PrintInfo();
133 localchan2->PrintValue();
134 localchan2->PrintErrorCounters();*/
135 // Store reference to ramp channel
136 if (localModChannelID.fmodulename == "ramp") {
137 fRampChannelIndex = fModChannel.size() - 1;
138 }
139 }
140
141 if(ldebug)
142 {
143 localModChannelID.Print();
144 std::cout<<"line ok=";
145 if(lineok) std::cout<<"TRUE"<<std::endl;
146 else std::cout<<"FALSE"<<std::endl;
147 }
148
149 }
150
151 if (localModChannelID.fmoduletype == "SIS3801D32") {
152 wordsofar+=1;
153
154 if (lineok){
155 VQwHardwareChannel* localchan3 = new QwSIS3801D32_Channel();
156
157 localchan3->InitializeChannel(GetName(),"QwBeamMod",localModChannelID.fmodulename,"raw");
158 fModChannel.push_back(localchan3);
159 fModChannel[fModChannel.size()-1]->LoadChannelParameters(mapstr);
160 localModChannelID.fIndex=fModChannel.size()-1;
161 fModChannelID.push_back(localModChannelID);
162 /* localchan3->PrintInfo();
163 localchan3->PrintValue();
164 localchan3->PrintErrorCounters();*/
165 // Store reference to ramp channel
166 if (localModChannelID.fmodulename == "ramp") {
167 fRampChannelIndex = fModChannel.size() - 1;
168 }
169 }
170
171 if(ldebug)
172 {
173 localModChannelID.Print();
174 std::cout<<"line ok=";
175 if(lineok) std::cout<<"TRUE"<<std::endl;
176 else std::cout<<"FALSE"<<std::endl;
177 }
178 }
179
180 if(localModChannelID.fmoduletype=="SKIP"){
181 if (localModChannelID.modnum<=0) wordsofar+=1;
182 else wordsofar+= localModChannelID.modnum;
183
184 }
185
186 if(localModChannelID.fmoduletype == "WORD") {
187 // std::cout << "Decoding QwWord :: " << namech << std::endl;
188 QwWord localword;
189 localword.fSubbankIndex=bankindex;
190 localword.fWordInSubbank=wordsofar;
191 wordsofar+=1;
192 // I assume that one data = one word here. But it is not always the case, for
193 // example the triumf adc gives 6 words per channel
194 localword.fModuleType=localModChannelID.fmoduletype;
195 localword.fWordName=namech;
196 //localword.fWordType=dettype; // FIXME dettype is undefined so commented this out
197 fWord.push_back(localword);
198
199 // Store reference to pattern number
200 if (localword.fWordName == "bm_pattern_number") {
201 fPatternWordIndex = fWord.size() - 1;
202 }
203
204 if(namech=="ffb_status")//save the location of this word to access this later
205 fFFB_Index=fWord.size()-1;
206 //store reference to bmwobj
207 if(namech == "bmwobj"){
208 fBmwObj_Index = fWord.size() - 1;
209 }
210
211 fWordsPerSubbank[bankindex].second = fWord.size();
212 QwDebug << "--" << namech << "--" << fWord.size()-1 << QwLog::endl;
213 }
214
215 }
216 }
217
218 if(ldebug)
219 {
220 std::cout<<"Done with Load map channel \n";
221 for(size_t i=0;i<fModChannelID.size();i++)
222 fModChannelID[i].Print();
223
224 for(size_t i=0;i<fWord.size();i++)
225 fWord[i].PrintID();
226 }
227 return 0;
228}
229
230
231
232//QwModChannelID::QwModChannelID(Int_t subbankid, Int_t wordssofar,
233// TString name, TString modtype, QwBeamMod * obj):
234// fSubbankIndex(subbankid),fWordInSubbank(wordssofar),
235// fmoduletype(modtype),fmodulename(name),kUnknownDeviceType(-1)
236//{
237// fTypeID = kQwUnknownDeviceType;
238//}
239
241 QwParameterFile &paramfile):
242 fSubbankIndex(subbankid), fIndex(-1)
243{
244
245 fmoduletype = paramfile.GetTypedNextToken<TString>();
246 modnum = paramfile.GetTypedNextToken<Int_t>(); //slot number
247 channum = paramfile.GetTypedNextToken<Int_t>(); //channel number
248 // fdetectortype = paramfile.GetTypedNextToken<TString>(); //type-purpose of the detector
249 fmodulename = paramfile.GetTypedNextToken<TString>(); //name of the detector
250 fmoduletype.ToUpper();
251 // fdetectortype.ToLower();
252 fmodulename.ToLower();
253
254 Int_t offset;
255 if (fmoduletype == "VQWK") {
257 if (paramfile.ReturnValue("vqwk_buffer_offset",offset)) {
258 fWordInSubbank += offset;
259 }
260 // } else if (fmoduletype == "ADC18") {
261 //fWordInSubbank = QwADC18_Channel::GetBufferOffset(modnum, channum);
262 //if (paramfile.ReturnValue("adc18_buffer_offset",offset)) {
263 // fWordInSubbank += offset;
264 // }
265 } else if (fmoduletype == "SCALER"|| fmoduletype == "SIS3801D24" || fmoduletype == "SIS3801D32" ) {
267 if (paramfile.ReturnValue("scaler_buffer_offset",offset)) {
268 fWordInSubbank += offset;
269 }
270 } else {
271 fWordInSubbank = -1;
272 }
273}
274
275
276
277
278
279//*****************************************************************
280
282 fFFB_holdoff=0;//Default holdoff for the FFB pause
283}
284
285void QwBeamMod::LoadEventCuts_Line(QwParameterFile &mapstr, TString &varvalue, Int_t &eventcut_flag){
286 TString device_type = mapstr.GetTypedNextToken<TString>();
287 device_type.ToUpper();
288 TString device_name = mapstr.GetTypedNextToken<TString>();
289 device_name.ToUpper();
290
291 if (device_type == "VQWK"||device_type=="SCALER" ||device_type=="SIS3801D24" ||device_type=="SIS3801D32"){
292 device_name.ToLower();
293 Double_t LLX = mapstr.GetTypedNextToken<Double_t>(); //lower limit for BCM value
294 Double_t ULX = mapstr.GetTypedNextToken<Double_t>(); //upper limit for BCM value
295 varvalue = mapstr.GetTypedNextToken<TString>();//global/local
296 Double_t burplevel = mapstr.GetTypedNextToken<Double_t>();
297 varvalue.ToLower();
298 Double_t stabilitycut = mapstr.GetTypedNextToken<Double_t>();
299 QwMessage<<"QwBeamMod Error Code "<<GetGlobalErrorFlag(varvalue,eventcut_flag,stabilitycut)<<QwLog::endl;
300 Int_t det_index=GetDetectorIndex(device_name);
301 QwMessage << "*****************************" << QwLog::endl;
302 QwMessage << " Type " << device_type << " Name " << device_name << " Index [" << det_index << "] "
303 << " device flag " << eventcut_flag << QwLog::endl;
304 fModChannel[det_index]->SetSingleEventCuts((GetGlobalErrorFlag(varvalue,eventcut_flag,stabilitycut)|kBModErrorFlag),LLX,ULX,stabilitycut,burplevel);
305 QwMessage << "*****************************" << QwLog::endl;
306
307 } else if (device_type == "WORD" && device_name== "FFB_STATUS"){
308 fFFB_holdoff=mapstr.GetTypedNextToken<UInt_t>();//Read the FFB OFF interval
309 } else if (device_type == "WORD" && device_name== "BMWOBJ"){
310 fBMWObj_LL=mapstr.GetTypedNextToken<Int_t>();
311 fBMWObj_UL=mapstr.GetTypedNextToken<Int_t>();
312 QwMessage << "bmwobj error cuts"
313 << "LowerLimit=" << fBMWObj_LL
314 << "UpperLimit=" << fBMWObj_UL <<QwLog::endl;
315 }
316}
317
318void QwBeamMod::LoadEventCuts_Fin(Int_t &eventcut_flag){
319 //update the event cut ON/OFF for all the devices
320 for (size_t i=0;i<fModChannel.size();i++)
321 fModChannel[i]->SetEventCutMode(eventcut_flag);
322}
323
324//*****************************************************************
326 Bool_t burpstatus = kFALSE;
327 VQwSubsystem* tmp = const_cast<VQwSubsystem *>(subsys);
328 if(Compare(tmp)) {
329 const QwBeamMod* input = dynamic_cast<const QwBeamMod*>(subsys);
330 for(size_t i=0;i<input->fModChannel.size();i++){
331 //QwError << "************* test Clock *****************" << QwLog::endl;
332 burpstatus |= (this->fModChannel[i])->CheckForBurpFail(input->fModChannel[i]);
333 }
334 }
335 return burpstatus;
336}
337
338//*****************************************************************
339Int_t QwBeamMod::LoadInputParameters(TString pedestalfile)
340{
341 Bool_t ldebug=kFALSE;
342 TString varname;
343
344 Int_t lineread=1;
345
346 if(ldebug)std::cout<<"QwBeamMod::LoadInputParameters("<< pedestalfile<<")\n";
347
348 QwParameterFile mapstr(pedestalfile.Data()); //Open the file
349 while (mapstr.ReadNextLine())
350 {
351 lineread+=1;
352 if(ldebug)std::cout<<" line read so far ="<<lineread<<"\n";
353 mapstr.TrimComment('!'); // Remove everything after a '!' character.
354 mapstr.TrimWhitespace(); // Get rid of leading and trailing spaces.
355 if (mapstr.LineIsEmpty()) continue;
356 else
357 {
358 TString varname = mapstr.GetTypedNextToken<TString>(); //name of the channel
359 varname.ToLower();
360 varname.Remove(TString::kBoth,' ');
361 Double_t varped = mapstr.GetTypedNextToken<Double_t>(); // value of the pedestal
362 Double_t varcal = mapstr.GetTypedNextToken<Double_t>(); // value of the calibration factor
363 /* Double_t varweight = */ mapstr.GetTypedNextToken<Double_t>(); // value of the statistical weight
364
365 //if(ldebug) std::cout<<"inputs for channel "<<varname
366 // <<": ped="<<varped<<": cal="<<varcal<<": weight="<<varweight<<"\n";
367 for(size_t i=0;i<fModChannel.size();i++)
368 if(fModChannel[i]->GetElementName()==varname)
369 {
370 fModChannel[i]->SetPedestal(varped);
371 fModChannel[i]->SetCalibrationFactor(varcal);
372 break;
373 }
374 }
375
376 }
377 if(ldebug) std::cout<<" line read in the pedestal + cal file ="<<lineread<<" \n";
378
379 ldebug=kFALSE;
380 return 0;
381}
382
383
384Int_t QwBeamMod::ProcessEvBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t* buffer, UInt_t num_words)
385{
386
387
388 Bool_t lkDEBUG=kFALSE;
389
390 Int_t index = GetSubbankIndex(roc_id,bank_id);
391
392
393 if (index>=0 && num_words>0){
394 // We want to process this ROC. Begin looping through the data.
395 if (lkDEBUG)
396 QwMessage << "QwBeamMod::ProcessEvBuffer: "
397 << "Begin processing ROC" << roc_id
398 << " and subbank "<<bank_id
399 << " number of words="<<num_words<<QwLog::endl;
400 if (buffer[0]==0xf0f0f0f0 && num_words%2==1){
401 buffer++;
402
403 if (lkDEBUG)
404 QwMessage << "QwBeamMod::ProcessEvBuffer: "
405 << "Skipped padding word 0xf0f0f0f0 at beginning of buffer."
406 << QwLog::endl;
407 }
408
409 for(size_t i=0;i<fModChannelID.size();i++) {
410 if(fModChannelID[i].fSubbankIndex==index) {
411 if (lkDEBUG) {
412 std::cout<<"found modulation data for "<<fModChannelID[i].fmodulename<<std::endl;
413 std::cout<<"word left to read in this buffer:"<<num_words-fModChannelID[i].fWordInSubbank<<std::endl;
414 }
415 fModChannel[fModChannelID[i].fIndex]->ProcessEvBuffer(&(buffer[fModChannelID[i].fWordInSubbank]),
416 num_words-fModChannelID[i].fWordInSubbank);
417 //fModChannel[fModChannelID[i].fIndex]->PrintInfo();
418 //fModChannel[fModChannelID[i].fIndex]->PrintValue();
419 //fModChannel[fModChannelID[i].fIndex]->PrintErrorCounters();
420 }
421 }
422
423 for(Int_t i=fWordsPerSubbank[index].first; i<fWordsPerSubbank[index].second; i++) {
424 if(fWord[i].fWordInSubbank+1<= (Int_t) num_words) {
425 fWord[i].fValue=buffer[fWord[i].fWordInSubbank];
426 //fWord[i].Print();
427 } else {
428 QwWarning << "QwBeamMod::ProcessEvBuffer: There is not enough word in the buffer to read data for "
429 << fWord[i].fWordName << QwLog::endl;
430 QwWarning << "QwBeamMod::ProcessEvBuffer: Words in this buffer:" << num_words
431 << " trying to read word number =" << fWord[i].fWordInSubbank << QwLog::endl;
432 }
433 }
434 if(lkDEBUG) {
435 QwDebug << "QwBeamMod::ProcessEvBuffer: Done with Processing this event" << QwLog::endl;
436 for(size_t i=0;i<fWord.size();i++) {
437 std::cout << " word number = " << i << " ";
438 fWord[i].Print();
439 }
440 }
441
442 }
443 lkDEBUG=kFALSE;
444
445 SetDataLoaded(kTRUE);
446
447 return 0;
448}
449
451 //std::cout << "Here in ApplySingleEventCuts() " << std::endl;
452 // std::cout << "ErrorFlag: " << fFFB_ErrorFlag << std::endl;
453 Bool_t test_Mod=kTRUE;
454 Bool_t test_BCM1=kTRUE;
455
456 for(size_t i=0;i<fModChannel.size();i++){
457 //std::cout<<" BCM ["<<i<<"] "<<std::endl;
458 //fModChannel[i]->PrintValue();
459 //if(fModChannel[i]->GetEventcutErrorFlag() >0){
460 // fModChannel[i]->PrintValue();
461 // }
462 test_BCM1 = fModChannel[i]->ApplySingleEventCuts();
463 test_Mod &= test_BCM1;
464
465 // fModChannel[i]->PrintValue();
466 //std::cout << "ErrorFlag: "<< fModChannel[i]->GetEventcutErrorFlag()<< std::endl;
467
468 //if(fModChannel[i]->GetEventcutErrorFlag() >0){
469 // fModChannel[i]->PrintValue();
470 //}
471
472
473 if(!test_BCM1 && bDEBUG) std::cout<<"******* QwBeamMod::SingleEventCuts()->BCM[ "<<i<<" , "<<fModChannel[i]->GetElementName()<<" ] ******" << std::endl;
474 }
475
476
477 /* if (fWord[fFFB_Index].fValue==8 && fFFB_Flag && fFFB_holdoff_Counter==0){
478 fFFB_holdoff_Counter=fFFB_holdoff;
479 fFFB_Flag=kFALSE;
480
481 }
482 */
483 // std::cout << "Upper Limit: " << fBMWObj_UL << " , " << "Lower Limit: " << fBMWObj_LL << std::endl;
484 //copy for fBmwObj
485 if (fBMWObj_LL < fBMWObj_UL) {
486 //std::cout << "Upper Limit: " << fBMWObj_UL << " , " << "Lower Limit: " << fBMWObj_LL << std::endl;
487
488 // Cuts are valid
489 if (fWord[fBmwObj_Index].GetValue()>fBMWObj_UL
490 || fWord[fBmwObj_Index].GetValue()<fBMWObj_LL){
491 // Value is outside of cuts range.
492
493 //std::cout << "bmwobj value: "<< fWord[fBmwObj_Index].GetValue() << " , " << "ErrorFlag: "<< fFFB_ErrorFlag << std::endl;
495 //std::cout << "ErrorFlag: " << fFFB_ErrorFlag << std::endl;
496 }
497 }
498
499 /*if (!fFFB_Flag && (fFFB_holdoff_Counter>0 && fFFB_holdoff_Counter<=fFFB_holdoff) ){
500 fFFB_ErrorFlag = (kGlobalCut+kBModErrorFlag+kBModFFBErrorFlag+kEventCutMode3);
501 fFFB_holdoff_Counter--;
502 if(fFFB_holdoff_Counter==0)
503 fFFB_Flag=kTRUE;
504 }
505 else
506 fFFB_ErrorFlag=0;*/
507
508 //std::cout << "WordValue: " << fWord[fBmwObj_Index].GetValue() << std::endl;
509 //std::cout << "ErrorFlag: " << fFFB_ErrorFlag << std::endl;
510 return test_Mod;
511
512}
513
515{
516 for(size_t i=0;i<fModChannel.size();i++){
517 fModChannel[i]->IncrementErrorCounters();
518 }
519}
520
521void QwBeamMod::PrintErrorCounters() const{//inherited from the VQwSubsystemParity; this will display the error summary
522
523 std::cout<<"*********QwBeamMod Error Summary****************"<<std::endl;
525 for(size_t i=0;i<fModChannel.size();i++){
526 fModChannel[i]->PrintErrorCounters();
527 }
529}
530
532{
533 const QwBeamMod* input = dynamic_cast<const QwBeamMod*> (ev_error);
534
535 for(size_t i=0;i<fModChannel.size();i++){
536 fModChannel[i]->UpdateErrorFlag(input->fModChannel[i]->GetEventcutErrorFlag());
537 }
538 // fFFB_ErrorFlag = input->fFFB_ErrorFlag;
539
540}
541
542UInt_t QwBeamMod::GetEventcutErrorFlag(){//return the error flag
543 UInt_t ErrorFlag;
544 ErrorFlag=0;
545 for(size_t i=0;i<fModChannel.size();i++){
546 ErrorFlag |= fModChannel[i]->GetEventcutErrorFlag();
547 }
548 ErrorFlag |= fFFB_ErrorFlag;
549
550 return ErrorFlag;
551}
552
553
554
555
557 //std::cout << "Here in ProcessEvent() " << std::endl;
558 for (size_t i = 0; i < fModChannel.size(); i++) {
559 // First apply HW checks and update HW error flags.
560 fModChannel[i]->ApplyHWChecks();
561 fModChannel[i]->ProcessEvent();
562 //fModChannel[i]->PrintValue();
563 }
564}
565
567{
568 // Fill histograms here to bypass event cuts
570}
571
572Int_t QwBeamMod::ProcessConfigurationBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t* buffer, UInt_t num_words)
573{
574 return 0;
575}
576
577//*****************************************************************
578
580 // std::cout << "Here in ClearEventData " << std::endl;
581 for(size_t i=0;i<fModChannel.size();i++)
583
584 for (size_t i=0;i<fWord.size();i++)
586 //std::cout << "Error Flag: " << fFFB_ErrorFlag << std::endl;
588}
589
590//*****************************************************************
592{
593 Bool_t ldebug=kFALSE;
594 if(ldebug)
595 {
596 std::cout<<"QwBeamMod::GetDetectorIndex\n";
597 std::cout<<fModChannelID.size()<<" already registered detector\n";
598 }
599
600 Int_t result=-1;
601 for(size_t i=0;i<fModChannelID.size();i++)
602 {
603
604 if(fModChannelID[i].fmodulename==name){
605 result=fModChannelID[i].fIndex;
606 }
607
608 if(ldebug)
609 {
610 std::cout<<"testing against ("<<fModChannelID[i].fTypeID
611 <<","<<fModChannelID[i].fmodulename<<")=>"<<result<<"\n";
612 }
613 }
614 //do it over the words, fWords
615 for(size_t i=0;i<fWord.size();i++) {
616
617 if(fWord[i].fWordName==name){
618 result=i;
619 }
620 }
621
622 return result;
623}
624//*****************************************************************
626{
627
628 if(Compare(value))
629 {
630
631 QwBeamMod* input = dynamic_cast<QwBeamMod*>(value);
632
633 for(size_t i=0;i<input->fModChannel.size();i++){
634 //input->fModChannel[i]->PrintValue();
635 this->fModChannel[i]->AssignValueFrom(input->fModChannel[i]);
636 //fModChannel[i]->PrintValue();
637 }
638 for(size_t i=0;i<input->fWord.size();i++)
639 this->fWord[i].fValue=input->fWord[i].fValue;
640 this->fFFB_ErrorFlag=input->fFFB_ErrorFlag;
641
642 }
643 return *this;
644}
645
647{
648 if(Compare(value)){
649 // std::cout << "Here in operator+= " << std::endl;
650 //QwBeamMod* input= (QwBeamMod*)value ;
651 QwBeamMod* input = dynamic_cast<QwBeamMod*>(value);
652
653 for(size_t i=0;i<input->fModChannel.size();i++)
654 *(this->fModChannel[i]) += *(input->fModChannel[i]);
655// for(size_t i=0;i<input->fWord.size();i++)
656// this->fWord[i]+=input->fWord[i];
657 this->fFFB_ErrorFlag |= input->fFFB_ErrorFlag;
658 // std::cout <<"Error Flag: " << this->fFFB_ErrorFlag <<std::endl;
659 }
660 return *this;
661}
662
664
665 if(Compare(value))
666 {
667 //QwBeamMod* input= (QwBeamMod*)value;
668 QwBeamMod* input = dynamic_cast<QwBeamMod*>(value);
669
670 for(size_t i=0;i<input->fModChannel.size();i++)
671 *(this->fModChannel[i]) -= *(input->fModChannel[i]);
672// for(size_t i=0;i<input->fWord.size();i++)
673// this->fWord[i]-=input->fWord[i];
674 this->fFFB_ErrorFlag |= input->fFFB_ErrorFlag;
675
676 }
677 return *this;
678}
679
681{
682 if(Compare(numer)&&Compare(denom))
683 {
684 //QwBeamMod* innumer= (QwBeamMod*)numer ;
685 QwBeamMod* innumer = dynamic_cast<QwBeamMod*>(numer);
686 //QwBeamMod* indenom= (QwBeamMod*)denom ;
687 QwBeamMod* indenom = dynamic_cast<QwBeamMod*>(denom);
688
689 for(size_t i=0;i<innumer->fModChannel.size();i++)
690 this->fModChannel[i]->Ratio(innumer->fModChannel[i],indenom->fModChannel[i]);
691 for(size_t i=0;i<innumer->fWord.size();i++)
692 this->fWord[i].fValue=innumer->fWord[i].fValue;
693
694 }
695}
696
697
698void QwBeamMod::Scale(Double_t factor)
699{
700 for(size_t i=0;i<fModChannel.size();i++)
701 fModChannel[i]->Scale(factor);
702}
703
705
706void QwBeamMod::AccumulateRunningSum(VQwSubsystem*, Int_t count, Int_t ErrorMask) { }
707
709{
710 Bool_t res = kTRUE;
711 if(typeid(*value)!=typeid(*this))
712 {
713 res=kFALSE;
714 // std::cout<<" types are not ok \n";
715 // std::cout<<" this is bypassed just for now but should be fixed eventually \n";
716 }
717 else
718 {
719 QwBeamMod* input = dynamic_cast<QwBeamMod*>(value);
720
721 if(input->fModChannel.size()!=fModChannel.size())
722 {
723 res=kFALSE;
724 // std::cout<<" not the same number of bcms \n";
725 }
726 }
727 return res;
728}
729
730
731//*****************************************************************
732
733void QwBeamMod::ConstructHistograms(TDirectory *folder, TString &prefix)
734{
735 // Go to the specified folder
736 if (folder != NULL) folder->cd();
737
738 // No histogram creation for asym, yield, diff, etc
739 if (prefix != "") return;
740
741 // Beam modulation channels
742 //for (size_t i = 0; i < fModChannel.size(); i++)
743 // fModChannel[i]->ConstructHistograms(folder,prefix);
744}
745
747{
748 // No data loaded
749 if (! HasDataLoaded()) return;
750
751 // No histograms defined
752 if (fHistograms.size() == 0) return;
753
754 // Beam modulation channels
755 //for (size_t i = 0; i < fModChannel.size(); i++)
756 // fModChannel[i]->FillHistograms();
757
758 // Do we have a ramp channel?
760
761 // Do we have a pattern word?
762 if (fPatternWordIndex < 0 || fPatternWordIndex > Int_t(fWord.size())) return;
763
764 // Determine the ramp/phase
765 Double_t ramp = fModChannel[fRampChannelIndex]->GetValue();
766 if (ramp < 0) return;
767
768 // Determine the pattern number -- the pattern number for single coil is
769 // between [0, 4] so we need to check for this.
770 Int_t pattern = -1;
771
772 if(fWord[fPatternWordIndex].fValue < 11 && fWord[fPatternWordIndex].fValue > 0)
773 pattern = fWord[fPatternWordIndex].fValue;
774 else
775 pattern = fWord[fPatternWordIndex].fValue - 11;
776
777 if (pattern < 0 || pattern > 4) return;
778
779 // Fill histograms for all BPMs and each of the modulation patterns
780 //
781 // Due to the the way the ADC averages the ramp signal we want to filter
782 // out events at the edged of the signal.
783 //
784 // Separated the ramp cut here because it is ridiculously long...
785 //
786
787 [[maybe_unused]]
788 Double_t ramp_block_41 = fModChannel[fRampChannelIndex]->GetValue(4) + fModChannel[fRampChannelIndex]->GetValue(1);
789 [[maybe_unused]]
790 Double_t ramp_block_32 = fModChannel[fRampChannelIndex]->GetValue(3) + fModChannel[fRampChannelIndex]->GetValue(2);
791 [[maybe_unused]]
792 Double_t ramp_block = ramp_block_41 - ramp_block_32;
793
794}
795
796
797void QwBeamMod::ConstructBranchAndVector(TTree *tree, TString & prefix, QwRootTreeBranchVector &values)
798{
799 TString basename;
800
801 for(size_t i = 0; i < fModChannel.size(); i++){
802 fModChannel[i]->ConstructBranchAndVector(tree, prefix, values);
803 }
804 // for (size_t i=0;i<fWord.size();i++)
805 // fWord[i].ConstructBranchAndVector(tree, prefix, values);
806 fTreeArrayIndex = values.size();
807 for (size_t i=0; i<fWord.size(); i++) {
808 // basename = fWord[i].fWordName;
809 basename = prefix(0, (prefix.First("|") >= 0)? prefix.First("|"): prefix.Length());
810 basename += fWord[i].fWordName;
811 values.push_back(basename.Data(), 'D');
812 tree->Branch(basename, &(values[fTreeArrayIndex + i]), values.LeafList(fTreeArrayIndex + i).c_str());
813 }
814}
815
817{
818 //std::cout << "inside FillTreeVector"<< std::endl;
819 //std::cout << "fTreeArrayIndex: " << fTreeArrayIndex << std::endl;
820 size_t index = fTreeArrayIndex;
821
822 for (size_t i = 0; i < fModChannel.size(); i++){
823 fModChannel[i]->FillTreeVector(values);
824 // fModChannel[i]->PrintValue();
825 }
826 for (size_t i = 0; i < fWord.size(); i++){
827 values.SetValue(index++, fWord[i].fValue);
828 }
829 //for (size_t i=0; i<values.size(); i++){
830 // std::cout << values[i] << " ";
831 // if ((i+1)%8==0) std::cout << std::endl;
832 // }
833
834}
835
836#ifdef HAS_RNTUPLE_SUPPORT
837void QwBeamMod::ConstructNTupleAndVector(std::unique_ptr<ROOT::RNTupleModel>& model, TString& prefix, std::vector<Double_t>& values, std::vector<std::shared_ptr<Double_t>>& fieldPtrs)
838{
839 TString basename;
840
841 for(size_t i = 0; i < fModChannel.size(); i++){
842 fModChannel[i]->ConstructNTupleAndVector(model, prefix, values, fieldPtrs);
843 }
844
845 fTreeArrayIndex = values.size();
846 for (size_t i=0; i<fWord.size(); i++) {
847 basename = prefix(0, (prefix.First("|") >= 0)? prefix.First("|"): prefix.Length());
848 basename += fWord[i].fWordName;
849 values.push_back(0.0);
850 fieldPtrs.push_back(model->MakeField<Double_t>(basename.Data()));
851 }
852}
853
854void QwBeamMod::FillNTupleVector(std::vector<Double_t>& values) const
855{
856 size_t index = fTreeArrayIndex;
857
858 for (size_t i = 0; i < fModChannel.size(); i++){
859 fModChannel[i]->FillNTupleVector(values);
860 }
861 for (size_t i = 0; i < fWord.size(); i++){
862 values[index++] = fWord[i].fValue;
863 }
864}
865#endif // HAS_RNTUPLE_SUPPORT
866
867
868//*****************************************************************
870{
871 QwMessage << "Name of the subsystem =" << fSystemName << QwLog::endl;
872
873 QwMessage << "there are " << fModChannel.size() << " mods" << QwLog::endl;
874
875 QwMessage << " Printing Running AVG and other channel info for fModChannel" << QwLog::endl;
876 for(size_t i=0;i<fModChannel.size();i++)
878 for(size_t i=0;i<fWord.size();i++)
879 fWord[i].Print();
880}
881
883{
884 for (size_t i=0;i<fModChannelID.size();i++)
885 {
886 std::cout<<"============================="<<std::endl;
887 std::cout<<" Detector ID="<<i<<std::endl;
888 fModChannelID[i].Print();
889 }
890}
891
892
894{
895 QwMessage <<std::endl<<"Detector name= "<<fmodulename<<QwLog::endl;
896 QwMessage <<"SubbankkIndex= "<<fSubbankIndex<<QwLog::endl;
897 QwMessage <<"word index in subbank= "<<fWordInSubbank<<QwLog::endl;
898 QwMessage <<"module type= "<<fmoduletype<<QwLog::endl;
899// QwMessage <<"detector type= "<<fdetectortype<<" that is index="<<fTypeID<<QwLog::endl;
900 QwMessage <<"Index of this detector in the vector of similar detector= "<<
902//QwMessage <<"Subelement index= "<< fSubelement<<QwLog::endl;
903
904
905 QwMessage << "---------------------------------------------------" << QwLog::endl;
907}
908
909
910#ifdef __USE_DATABASE__
911//*****************************************************************
912void QwBeamMod::FillDB_MPS(QwParityDB *db, TString datatype)
913{
914 Bool_t local_print_flag = false;
915
916 if(local_print_flag) {
917 QwMessage << " --------------------------------------------------------------- " << QwLog::endl;
918 QwMessage << " QwBeamMod::FillDB_MPS " << QwLog::endl;
919 QwMessage << " --------------------------------------------------------------- " << QwLog::endl;
920 }
921
922 std::vector<QwParitySchema::beam_optics_row> entrylist;
923
924 UInt_t analysis_id = db->GetAnalysisID();
925
926 for(size_t bpm = 0; bpm < fModChannel.size(); bpm++) {
927 for(size_t pattern = 0; pattern < 5; pattern++) {
928 // Explicitly zero the beam optics ID to ensure a non-sensical default
929 // is not picked up.
930 QwParitySchema::beam_optics table;
931 QwParitySchema::beam_optics_row row;
932 row[table.analysis_id] = analysis_id;
933 row[table.monitor_id] = 0; // placeholder
934 row[table.modulation_type_id] = pattern;
935 row[table.n] = 0; // placeholder
936 row[table.offset] = 0.0; // placeholder
937 row[table.amplitude] = 0.0; // placeholder
938 row[table.phase] = 0.0; // placeholder
939 row[table.o_error] = 0.0; // placeholder
940 row[table.a_error] = 0.0; // placeholder
941 row[table.p_error] = 0.0; // placeholder
942 row[table.gof_para] = 0.0; // placeholder
943
944 entrylist.push_back(row);
945 }
946 }
947
948 if(local_print_flag) {
949 QwMessage << QwColor(Qw::kGreen) << "Entrylist Size : "
950 << QwColor(Qw::kBoldRed) << entrylist.size()
951 << QwColor(Qw::kNormal) << QwLog::endl;
952 }
953
954 if( entrylist.size() ) {
955 auto c = db->GetScopedConnection();
956 for (const auto& entry : entrylist) {
957 c->QueryExecute(entry.insert_into());
958 }
959 }
960 else {
961 QwMessage << "QwBeamMod::FillDB_MPS :: Nothing to insert in database." << QwLog::endl;
962 }
963}
964
965void QwBeamMod::FillDB(QwParityDB *db, TString datatype)
966{
967 return;
968}
969
970void QwBeamMod::FillErrDB(QwParityDB *db, TString datatype)
971{
972 return;
973}
974#endif // __USE_DATABASE__
975
977{
978 return;
979};
Helper functions and utilities for ROOT histogram management.
Base and derived classes for scaler channel data handling.
class QwScaler_Channel< 0x00ffffff, 0 > QwSIS3801D24_Channel
class QwScaler_Channel< 0xffffffff, 0 > QwSIS3801D32_Channel
A logfile class, based on an identical class in the Hermes analyzer.
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
#define QwDebug
Predefined log drain for debugging output.
Definition QwLog.h:59
ROOT file and tree management wrapper classes.
Parameter file parsing and management.
#define REGISTER_SUBSYSTEM_FACTORY(A)
Definition QwFactory.h:270
static const UInt_t kGlobalCut
Definition QwTypes.h:182
static const UInt_t kBModErrorFlag
Definition QwTypes.h:173
ULong64_t BankID_t
Definition QwTypes.h:21
static const UInt_t kEventCutMode3
Definition QwTypes.h:174
static const UInt_t kBModFFBErrorFlag
Definition QwTypes.h:172
UInt_t GetGlobalErrorFlag(TString evtype, Int_t evMode, Double_t stabilitycut)
Definition QwTypes.cc:132
UInt_t ROCID_t
Definition QwTypes.h:20
Beam modulation subsystem for parity analysis.
@ kBoldRed
Definition QwColor.h:79
@ kGreen
Definition QwColor.h:77
@ kNormal
Definition QwColor.h:81
std::vector< TH1_ptr > fHistograms
Histograms associated with this data element.
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Command-line and configuration file options processor.
Definition QwOptions.h:141
Configuration file parser with flexible tokenization and search capabilities.
T GetTypedNextToken()
Get next token into specific type.
void TrimWhitespace(TString::EStripType head_tail=TString::kBoth)
Bool_t HasVariablePair(const std::string &separatorchars, std::string &varname, std::string &varvalue)
void SetCommentChars(const std::string value)
Set various sets of special characters.
void TrimComment(const char commentchar)
const std::pair< TString, TString > GetParamFileNameContents()
Bool_t ReturnValue(const std::string keyname, T &retvalue)
A helper class to manage a vector of branch entries for ROOT trees.
Definition QwRootFile.h:53
size_type size() const noexcept
Definition QwRootFile.h:81
std::string LeafList(size_type start_index=0) const
Definition QwRootFile.h:228
void push_back(const std::string &name, const char type='D')
Definition QwRootFile.h:195
void SetValue(size_type index, Double_t val)
Definition QwRootFile.h:108
static Int_t GetBufferOffset(Int_t scalerindex, Int_t wordindex, UInt_t header=1)
Concrete hardware channel for VQWK ADC modules (6x32-bit words)
static void PrintErrorCounterTail()
static Int_t GetBufferOffset(Int_t moduleindex, Int_t channelindex)
static void PrintErrorCounterHead()
Word-level data manipulation and bit operations.
Definition QwWord.h:31
Int_t fWordInSubbank
Definition QwWord.h:38
Int_t fSubbankIndex
Definition QwWord.h:37
TString fModuleType
Definition QwWord.h:39
TString fWordName
Definition QwWord.h:40
Abstract base for concrete hardware channels implementing dual-operator pattern.
void InitializeChannel(TString name)
Initialize the fields in this object.
BankID_t fCurrentBank_ID
Bank ID (and Marker word) that is currently being processed;.
TString fSystemName
Name of this subsystem.
Int_t GetSubbankIndex() const
void RegisterRocBankMarker(QwParameterFile &mapstr)
TString GetName() const
std::map< TString, TString > fDetectorMaps
Map of file name to full path or content.
VQwSubsystem(const TString &name)
Constructor with name.
void SetDataLoaded(Bool_t flag)
ROCID_t fCurrentROC_ID
ROC ID that is currently being processed.
Bool_t HasDataLoaded() const
Mapping information for beam modulation channels.
Definition QwBeamMod.h:45
Int_t fWordInSubbank
Definition QwBeamMod.h:60
QwModChannelID(Int_t subbankid, Int_t wordssofar, TString name, TString modtype, QwBeamMod *obj)
TString fmodulename
Definition QwBeamMod.h:67
Int_t fSubbankIndex
Definition QwBeamMod.h:59
TString fmoduletype
Definition QwBeamMod.h:66
Subsystem for beam modulation studies and FFB handling.
Definition QwBeamMod.h:94
void ClearEventData() override
Definition QwBeamMod.cc:579
void LoadEventCuts_Line(QwParameterFile &mapstr, TString &varvalue, Int_t &eventcut_flag) override
Definition QwBeamMod.cc:285
static const Bool_t bDEBUG
Definition QwBeamMod.h:222
void LoadEventCuts_Init() override
Definition QwBeamMod.cc:281
VQwSubsystem & operator-=(VQwSubsystem *value) override
Definition QwBeamMod.cc:663
Bool_t CheckForBurpFail(const VQwSubsystem *subsys) override
Report the number of events failed due to HW and event cut failures.
Definition QwBeamMod.cc:325
void PrintErrorCounters() const override
Definition QwBeamMod.cc:521
Int_t fRampChannelIndex
Definition QwBeamMod.h:224
UInt_t fBmwObj_Index
Definition QwBeamMod.h:226
void PrintModChannelID()
Definition QwBeamMod.cc:882
VQwSubsystem & operator=(VQwSubsystem *value) override
Assignment Note: Must be called at the beginning of all subsystems routine call to operator=(VQwSubsy...
Definition QwBeamMod.cc:625
VQwSubsystem & operator+=(VQwSubsystem *value) override
Definition QwBeamMod.cc:646
Int_t fBMWObj_UL
Definition QwBeamMod.h:228
Int_t ProcessConfigurationBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t *buffer, UInt_t num_words) override
Definition QwBeamMod.cc:572
Int_t fBMWObj_LL
Definition QwBeamMod.h:227
UInt_t fFFB_holdoff
Definition QwBeamMod.h:218
void ProcessOptions(QwOptions &options) override
Process the command line options.
Definition QwBeamMod.cc:42
void AccumulateRunningSum(VQwSubsystem *, Int_t count=0, Int_t ErrorMask=0xFFFFFFF) override
Update the running sums for devices.
Definition QwBeamMod.cc:706
Int_t LoadChannelMap(TString mapfile) override
Mandatory map file definition.
Definition QwBeamMod.cc:46
void FillHistograms() override
Fill the histograms for this subsystem.
Definition QwBeamMod.cc:746
void ProcessEvent_2() override
Process the event data again, including data from other subsystems. Not all derived classes will requ...
Definition QwBeamMod.cc:566
Int_t LoadInputParameters(TString pedestalfile) override
Mandatory parameter file definition.
Definition QwBeamMod.cc:339
virtual void ConstructHistograms()
Construct the histograms for this subsystem.
UInt_t fFFB_ErrorFlag
Definition QwBeamMod.h:220
void CalculateRunningAverage() override
Calculate the average for all good events.
Definition QwBeamMod.cc:704
void WritePromptSummary(QwPromptSummary *ps, TString type) override
Definition QwBeamMod.cc:976
void Ratio(VQwSubsystem *numer, VQwSubsystem *denom) override
Definition QwBeamMod.cc:680
void FillTreeVector(QwRootTreeBranchVector &values) const override
Fill the tree vector.
Definition QwBeamMod.cc:816
Int_t fPatternWordIndex
Definition QwBeamMod.h:225
std::vector< VQwHardwareChannel * > fModChannel
Definition QwBeamMod.h:208
UInt_t GetEventcutErrorFlag() override
Return the error flag to the top level routines related to stability checks and ErrorFlag updates.
Definition QwBeamMod.cc:542
Int_t GetDetectorIndex(TString name)
Definition QwBeamMod.cc:591
void Scale(Double_t factor) override
Definition QwBeamMod.cc:698
Bool_t Compare(VQwSubsystem *source)
Definition QwBeamMod.cc:708
std::vector< QwWord > fWord
Definition QwBeamMod.h:210
Int_t ProcessEvBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t *buffer, UInt_t num_words) override
TODO: The non-event-type-aware ProcessEvBuffer routine should be replaced with the event-type-aware v...
Definition QwBeamMod.cc:384
void ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values) override
Construct the branch and tree vector.
Definition QwBeamMod.cc:797
void ProcessEvent() override
Definition QwBeamMod.cc:556
void Print()
Definition QwBeamMod.cc:869
UInt_t fFFB_Index
Definition QwBeamMod.h:217
void IncrementErrorCounters() override
Increment the error counters.
Definition QwBeamMod.cc:514
std::vector< std::pair< Int_t, Int_t > > fWordsPerSubbank
Definition QwBeamMod.h:211
std::vector< QwModChannelID > fModChannelID
Definition QwBeamMod.h:209
Bool_t ApplySingleEventCuts() override
Apply the single event cuts.
Definition QwBeamMod.cc:450
Int_t fTreeArrayIndex
Definition QwBeamMod.h:206
void LoadEventCuts_Fin(Int_t &eventcut_flag) override
Definition QwBeamMod.cc:318
virtual void PrintValue() const
Print values of all channels.
virtual void FillDB_MPS(QwParityDB *, TString)
Fill the database with MPS-based variables Note that most subsystems don't need to do this.
virtual void FillDB(QwParityDB *, TString)
Fill the database.
virtual UInt_t UpdateErrorFlag()
Uses the error flags of contained data elements to update Returns the error flag to the top level rou...
virtual void FillErrDB(QwParityDB *, TString)