14#ifdef HAS_RNTUPLE_SUPPORT
15#include "ROOT/RNTupleModel.hxx"
16#include "ROOT/RField.hxx"
37 (
"enable-burstsum", po::value<bool>()->default_bool_value(
false),
38 "enable burst sum calculation");
40 (
"enable-runningsum", po::value<bool>()->default_bool_value(
true),
41 "enable running sum calculation");
43 (
"enable-differences", po::value<bool>()->default_bool_value(
false),
44 "store pattern differences in tree");
46 (
"enable-alternateasym", po::value<bool>()->default_bool_value(
false),
47 "enable alternate asymmetries");
50 (
"print-burstsum", po::value<bool>()->default_bool_value(
false),
51 "print burst sum of subsystems");
53 (
"print-patternsum", po::value<bool>()->default_bool_value(
false),
54 "print pattern sum of subsystems");
56 (
"print-runningsum", po::value<bool>()->default_bool_value(
false),
57 "print running sum of subsystems");
60 (
"burstlength", po::value<int>()->default_value(9000),
61 "number of patterns per burst");
64 (
"max-burst-index", po::value<int>()->default_value(0x7fffffff),
65 "max number of bursts for a run");
68 (
"print-burst-index-map", po::value<bool>()->default_value(kFALSE),
69 "whether to print the shorter max burst index if the final is shorter than min-burstlength");
72 (
"min-burstlength", po::value<int>()->default_value(2333),
73 "minimum acceptable burst length");
97 QwWarning <<
"QwHelicityPattern::ProcessOptions: "
98 <<
"The 'enable-alternateasym' flag is disabled for pair analysis."
144 std::vector<VQwSubsystem*> subsys_helicity =
event.GetSubsystemByType(
"QwHelicity");
145 if (subsys_helicity.size()==0) {
146 subsys_helicity = event.GetSubsystemByType(
"QwHelicityDecoder");
148 if (subsys_helicity.size() > 0) {
151 QwHelicityBase* helicity = dynamic_cast<QwHelicityBase*>(subsys_helicity.at(0));
154 fPatternSize = helicity->GetMaxPatternPhase();
157 if (subsys_helicity.size() > 1)
158 QwWarning <<
"Multiple helicity subsystems defined! "
159 <<
"Using " << helicity->GetName() <<
"."
164 QwError <<
"No helicity subsystem defined! "
165 <<
"Calculate asymmetries based on (+--+) quartets!"
167 fHelicityIsMissing = kTRUE;
174 if(fPatternSize%2 == 0)
176 fEvents.resize(fPatternSize,event);
177 fHelicity.resize(fPatternSize,-9999);
178 fEventNumber.resize(fPatternSize,-1);
179 fEventLoaded.resize(fPatternSize,kFALSE);
183 fCurrentPatternNumber = -1;
188 "Standard exception from QwHelicityPattern : the pattern size has to be even; right now pattern_size=";
189 loc+=Form(
"%zu",fPatternSize);
190 throw std::invalid_argument(loc.Data());
193 catch (std::exception& e)
195 std::cerr << e.what() << std::endl;
246 Bool_t localdebug = kFALSE;
249 Long_t localEventNumber = -1;
250 Long_t localPatternNumber = -1;
251 Int_t localPhaseNumber = -1;
252 Int_t localHelicityActual = -1;
253 Bool_t localIgnoreHelicity = kFALSE;
258 std::vector<VQwSubsystem*> subsys_helicity =
event.GetSubsystemByType(
"QwHelicity");
259 if (subsys_helicity.size()==0) {
260 subsys_helicity =
event.GetSubsystemByType(
"QwHelicityDecoder");
265 if (subsys_helicity.size() > 0) {
279 QwError <<
"QwHelicityPattern::LoadEventData: The helicity subsystem does not have valid data!"
284 static Bool_t user_has_been_warned = kFALSE;
285 if (! user_has_been_warned) {
286 QwError <<
"No helicity subsystem found! Dropping to \"Missing Helicity\" mode!" <<
QwLog::endl;
287 user_has_been_warned = kTRUE;
293 localIgnoreHelicity = kTRUE;
297 if(localPhaseNumber >=
static_cast<Int_t
>(
fPatternSize)){
298 localPatternNumber++;
299 localPhaseNumber = 0;
306 std::cout<<
"\n ###################################\n";
307 std::cout<<
"QwHelicityPattern::LoadEventData :: ";
308 std::cout<<
" event, pattern, phase # "<<localEventNumber<<
" "<<localPatternNumber<<
" "<<localPhaseNumber<<
"\n";
309 std::cout<<
" helicity ="<< localHelicityActual<<
"\n";
310 for(
size_t i=0; i<
fEvents.size(); i++)
319 if(localPhaseNumber<0){
320std::cout <<
"local phase no: " << localPhaseNumber <<
" current pattern no: " <<
fCurrentPatternNumber << std::endl;
321 QwWarning <<
"QwHelicityPattern::LoadEventData: "
322 <<
"Reduced event phase number is less than zero; ignore this event."
325 }
else if(localPhaseNumber >=
static_cast<Int_t
>(
fPatternSize)){
326 QwWarning<<
" In QwHelicityPattern::LoadEventData trying upload an event with a phase larger than expected \n"
327 <<
" phase ="<<localPhaseNumber+1<<
" maximum expected phase="<<
fPatternSize<<
"\n"
328 <<
" operation impossible, pattern reset to 0: no asymmetries will be computed "<<
QwLog::endl;
332 std::cout<<
"QwHelicityPattern::LoadEventData local i="
333 <<localPhaseNumber<<
"\n";
335 fEvents[localPhaseNumber] = event;
337 fHelicity[localPhaseNumber] = localHelicityActual;
352 Bool_t complete_and_good = kFALSE;
357 return complete_and_good;
362 Bool_t filled=kFALSE;
368 size_t secondevt = firstevt + 1;
377 Bool_t localdebug=kFALSE;
379 if(localdebug) std::cout<<
"Entering QwHelicityPattern::CalculateAsymmetry \n";
388 size_t secondevt = firstevt + 1;
408 QwDebug<<
" QwHelicityPattern::CalculatePairAsymmetry == \n"
409 <<
" undefined local helicity (-9999) \n"
410 <<
" impossible to compute asymmetry \n"
415 QwDebug <<
"QwHelicityPattern::CalculatePairAsymmetry: "
416 <<
"Helicity should be "<<plushel<<
" or "<<minushel
418 <<
"; Asymmetry computation aborted!"<<
QwLog::endl;
421 QwError<<
" QwHelicityPattern::CalculatePairAsymmetry == \n"
422 <<
" you do not have the same number of positive and negative \n"
423 <<
" impossible to compute asymmetry \n"
454 Bool_t complete_and_good = kFALSE;
459 return complete_and_good;
468 Bool_t localdebug=kFALSE;
471 while(filled && i>-1)
474 std::cout<<
" i="<<i<<
" is loaded ?"
495 Bool_t localdebug=kFALSE;
497 if(localdebug) std::cout<<
"Entering QwHelicityPattern::CalculateAsymmetry \n";
502 Bool_t firstplushel=kTRUE;
503 Bool_t firstminushel=kTRUE;
514 localhel ^= ((i >> j)&0x1);
516 if (localhel == plushel) {
519 firstplushel = kFALSE;
523 }
else if (localhel == minushel) {
526 firstminushel = kFALSE;
536 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: here filling fPositiveHelicitySum \n";
538 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: with = \n";
540 firstplushel = kFALSE;
542 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: with += \n";
547 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: here filling fNegativeHelicitySum \n";
549 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: with = \n";
551 firstminushel = kFALSE;
553 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: with += \n";
558 QwDebug <<
"QwHelicityPattern::CalculateAsymmetry: "
559 <<
"Helicity should be "<<plushel<<
" or "<<minushel
561 <<
"; Asymmetry computation aborted!"<<
QwLog::endl;
570 if (checkhel == -9999) {
573 }
else if (checkhel!=0) {
576 QwError<<
" QwHelicityPattern::CalculateAsymmetry == \n"
577 <<
" you do not have the same number of positive and negative \n"
578 <<
" impossible to compute asymmetry \n"
672 for(
size_t i=0; i<
fEvents.size(); i++)
717 fYield.AccumulateRunningSum(entry.
fYield, count, ErrorMask);
758 fYield.CalculateRunningAverage();
815 TString prefix =
"blinder_";
816 fBlinder.ConstructObjects(folder,prefix);
819 fYield.ConstructObjects(folder,prefix);
838 TString prefix =
"yield_";
839 fYield.ConstructHistograms(folder,prefix);
841 fAsymmetry.ConstructHistograms(folder,prefix);
873TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length())+
"BurstCounter";
875 TString newprefix =
"yield_" + prefix;
876 fYield.ConstructBranchAndVector(tree, newprefix, values);
877 newprefix =
"asym_" + prefix;
878 fAsymmetry.ConstructBranchAndVector(tree, newprefix, values);
881 newprefix =
"diff_" + prefix;
882 fDifference.ConstructBranchAndVector(tree, newprefix, values);
885 newprefix =
"asym1_" + prefix;
886 fAsymmetry1.ConstructBranchAndVector(tree, newprefix, values);
887 newprefix =
"asym2_" + prefix;
888 fAsymmetry2.ConstructBranchAndVector(tree, newprefix, values);
894 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length())+
"BurstCounter";
897 TString newprefix =
"yield_" + prefix;
898 fYield.ConstructBranch(tree, newprefix);
899 newprefix =
"asym_" + prefix;
903 newprefix =
"diff_" + prefix;
907 newprefix =
"asym1_" + prefix;
909 newprefix =
"asym2_" + prefix;
916 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length())+
"BurstCounter";
918 TString newprefix =
"yield_" + prefix;
919 fYield.ConstructBranch(tree, newprefix, trim_tree);
920 newprefix =
"asym_" + prefix;
921 fAsymmetry.ConstructBranch(tree, newprefix, trim_tree);
924 newprefix =
"diff_" + prefix;
928 newprefix =
"asym1_" + prefix;
929 fAsymmetry1.ConstructBranch(tree, newprefix, trim_tree);
930 newprefix =
"asym2_" + prefix;
931 fAsymmetry2.ConstructBranch(tree, newprefix, trim_tree);
938 fYield.FillTreeVector(values);
950#ifdef HAS_RNTUPLE_SUPPORT
951void QwHelicityPattern::ConstructNTupleAndVector(std::unique_ptr<ROOT::RNTupleModel>& model, TString& prefix, std::vector<Double_t>& values, std::vector<std::shared_ptr<Double_t>>& fieldPtrs)
953 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length())+
"BurstCounter";
957 TString newprefix =
"yield_" + prefix;
958 fYield.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
959 newprefix =
"asym_" + prefix;
960 fAsymmetry.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
963 newprefix =
"diff_" + prefix;
964 fDifference.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
967 newprefix =
"asym1_" + prefix;
968 fAsymmetry1.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
969 newprefix =
"asym2_" + prefix;
970 fAsymmetry2.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
974void QwHelicityPattern::FillNTupleVector(std::vector<Double_t>& values)
const
977 fYield.FillNTupleVector(values);
990#ifdef __USE_DATABASE__
991void QwHelicityPattern::FillDB(QwParityDB *db)
995 fYield.FillDB(db,
"yield");
1006void QwHelicityPattern::FillErrDB(QwParityDB *db)
1016 fYield.WritePromptSummary(ps,
"yield");
1017 fAsymmetry.WritePromptSummary(ps,
"asymmetry");
Helper functions and utilities for ROOT histogram management.
A logfile class, based on an identical class in the Hermes analyzer.
#define QwOut
Predefined log drain for explicit output.
#define QwError
Predefined log drain for errors.
#define QwWarning
Predefined log drain for warnings.
#define QwMessage
Predefined log drain for regular messages.
#define QwDebug
Predefined log drain for debugging output.
Definition of the pure virtual base class of all data elements.
Prompt summary data management.
Helicity state management and pattern recognition.
A class for blinding data, adapted from G0 blinder class.
Helicity data decoder from the data file.
Helicity pattern analysis and management.
static std::ostream & endl(std::ostream &)
End of the line.
Command-line and configuration file options processor.
T GetValue(const std::string &key)
Get a templated value.
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.
Configuration file parser with flexible tokenization and search capabilities.
void SetPatternSize(const Int_t in)
A helper class to manage a vector of branch entries for ROOT trees.
Bool_t HasDataLoaded() const
static void DefineOptions(QwOptions &options)
static const UInt_t kErrorFlag_BlinderFail
Error flag value.
Base subsystem for helicity state management and pattern recognition.
Int_t GetMinPatternPhase()
Bool_t IsHelicityIgnored()
Int_t GetHelicityActual()
Long_t GetPatternNumber()
QwSubsystemArrayParity fAlternateDiff
Bool_t NextPairIsComplete()
Bool_t fEnableAlternateAsym
void ConstructBranchAndVector(TTree *tree, TString &prefix, QwRootTreeBranchVector &values)
Bool_t fHelicityIsMissing
void ConstructBranch(TTree *tree, TString &prefix)
QwSubsystemArrayParity fNegativeHelicitySum
QwSubsystemArrayParity fPairDifference
Int_t fBurstMinGoodPatterns
std::vector< Bool_t > fEventLoaded
QwHelicityPattern()
Private default constructor (not implemented, will throw linker error on use)
ULong_t fLastWindowNumber
static void DefineOptions(QwOptions &options)
Define the configuration options.
QwSubsystemArrayParity fDifference
QwSubsystemArrayParity fPairYield
void UpdateBlinder()
Update the blinder status using a random number generator.
Int_t fCurrentPatternNumber
std::vector< QwSubsystemArrayParity > fEvents
void ProcessOptions(QwOptions &options)
Process the configuration options.
void CalculatePairAsymmetry()
Bool_t IsCompletePattern() const
void DisableBurstSum()
Disable burst sum calculation.
std::vector< Int_t > fHelicity
void AccumulatePairRunningSum(QwHelicityPattern &entry)
std::vector< Int_t > fEventNumber
void CalculateAsymmetry()
void SetDataLoaded(Bool_t flag)
void WritePromptSummary(QwPromptSummary *ps)
QwSubsystemArrayParity fAsymmetry1
void FillTreeVector(QwRootTreeBranchVector &values) const
void ConstructHistograms()
QwSubsystemArrayParity fPositiveHelicitySum
void LoadEventData(QwSubsystemArrayParity &event)
void AccumulateRunningSum(QwHelicityPattern &entry, Int_t count=0, Int_t ErrorMask=0xFFFFFFF)
QwSubsystemArrayParity fYield
QwSubsystemArrayParity fAsymmetry
ULong_t fLastPatternNumber
QwSubsystemArrayParity fPairAsymmetry
Bool_t PairAsymmetryIsGood()
QwSubsystemArrayParity fAsymmetry2
void CalculateRunningAverage()
Subsystem array container specialized for parity analysis with asymmetry calculations.
UInt_t GetEventcutErrorFlag() const
Return the error flag to the main routine.