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");
Definition of the pure virtual base class of all data elements.
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.
Helper functions and utilities for ROOT histogram management.
Prompt summary data management.
Helicity data decoder from the data file.
Helicity state management and pattern recognition.
A class for blinding data, adapted from G0 blinder class.
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.