14#ifdef HAS_RNTUPLE_SUPPORT
15#include "ROOT/RNTupleModel.hxx"
16#include "ROOT/RField.hxx"
36 (
"enable-burstsum", po::value<bool>()->default_bool_value(
false),
37 "enable burst sum calculation");
39 (
"enable-runningsum", po::value<bool>()->default_bool_value(
true),
40 "enable running sum calculation");
42 (
"enable-differences", po::value<bool>()->default_bool_value(
false),
43 "store pattern differences in tree");
45 (
"enable-alternateasym", po::value<bool>()->default_bool_value(
false),
46 "enable alternate asymmetries");
49 (
"print-burstsum", po::value<bool>()->default_bool_value(
false),
50 "print burst sum of subsystems");
52 (
"print-patternsum", po::value<bool>()->default_bool_value(
false),
53 "print pattern sum of subsystems");
55 (
"print-runningsum", po::value<bool>()->default_bool_value(
false),
56 "print running sum of subsystems");
59 (
"burstlength", po::value<int>()->default_value(9000),
60 "number of patterns per burst");
63 (
"max-burst-index", po::value<int>()->default_value(0x7fffffff),
64 "max number of bursts for a run");
67 (
"print-burst-index-map", po::value<bool>()->default_value(kFALSE),
68 "whether to print the shorter max burst index if the final is shorter than min-burstlength");
71 (
"min-burstlength", po::value<int>()->default_value(2333),
72 "minimum acceptable burst length");
96 QwWarning <<
"QwHelicityPattern::ProcessOptions: "
97 <<
"The 'enable-alternateasym' flag is disabled for pair analysis."
143 std::vector<VQwSubsystem*> subsys_helicity =
event.GetSubsystemByType(
"QwHelicity");
144 if (subsys_helicity.size() > 0) {
148 QwHelicity* helicity = dynamic_cast<QwHelicity*>(subsys_helicity.at(0));
151 fPatternSize = helicity->GetMaxPatternPhase();
154 if (subsys_helicity.size() > 1)
155 QwWarning <<
"Multiple helicity subsystems defined! "
156 <<
"Using " << helicity->GetName() <<
"."
161 QwError <<
"No helicity subsystem defined! "
162 <<
"Calculate asymmetries based on (+--+) quartets!"
164 fHelicityIsMissing = kTRUE;
171 if(fPatternSize%2 == 0)
173 fEvents.resize(fPatternSize,event);
174 fHelicity.resize(fPatternSize,-9999);
175 fEventNumber.resize(fPatternSize,-1);
176 fEventLoaded.resize(fPatternSize,kFALSE);
180 fCurrentPatternNumber = -1;
185 "Standard exception from QwHelicityPattern : the pattern size has to be even; right now pattern_size=";
186 loc+=Form(
"%zu",fPatternSize);
187 throw std::invalid_argument(loc.Data());
190 catch (std::exception& e)
192 std::cerr << e.what() << std::endl;
243 Bool_t localdebug = kFALSE;
246 Long_t localEventNumber = -1;
247 Long_t localPatternNumber = -1;
248 Int_t localPhaseNumber = -1;
249 Int_t localHelicityActual = -1;
250 Bool_t localIgnoreHelicity = kFALSE;
255 std::vector<VQwSubsystem*> subsys_helicity =
event.GetSubsystemByType(
"QwHelicity");
258 if (subsys_helicity.size() > 0) {
260 helicity =
dynamic_cast<QwHelicity*
>(subsys_helicity.at(0));
269 QwError <<
"QwHelicityPattern::LoadEventData: The helicity subsystem does not have valid data!"
274 static Bool_t user_has_been_warned = kFALSE;
275 if (! user_has_been_warned) {
276 QwError <<
"No helicity subsystem found! Dropping to \"Missing Helicity\" mode!" <<
QwLog::endl;
277 user_has_been_warned = kTRUE;
283 localIgnoreHelicity = kTRUE;
288 localPatternNumber++;
289 localPhaseNumber = 0;
296 std::cout<<
"\n ###################################\n";
297 std::cout<<
"QwHelicityPattern::LoadEventData :: ";
298 std::cout<<
" event, pattern, phase # "<<localEventNumber<<
" "<<localPatternNumber<<
" "<<localPhaseNumber<<
"\n";
299 std::cout<<
" helicity ="<< localHelicityActual<<
"\n";
300 for(
size_t i=0; i<
fEvents.size(); i++)
309 if(localPhaseNumber<0){
310 QwWarning <<
"QwHelicityPattern::LoadEventData: "
311 <<
"Reduced event phase number is less than zero; ignore this event."
315 QwWarning<<
" In QwHelicityPattern::LoadEventData trying upload an event with a phase larger than expected \n"
316 <<
" phase ="<<localPhaseNumber+1<<
" maximum expected phase="<<
fPatternSize<<
"\n"
317 <<
" operation impossible, pattern reset to 0: no asymmetries will be computed "<<
QwLog::endl;
321 std::cout<<
"QwHelicityPattern::LoadEventData local i="
322 <<localPhaseNumber<<
"\n";
324 fEvents[localPhaseNumber] = event;
326 fHelicity[localPhaseNumber] = localHelicityActual;
341 Bool_t complete_and_good = kFALSE;
346 return complete_and_good;
351 Bool_t filled=kFALSE;
357 size_t secondevt = firstevt + 1;
366 Bool_t localdebug=kFALSE;
368 if(localdebug) std::cout<<
"Entering QwHelicityPattern::CalculateAsymmetry \n";
377 size_t secondevt = firstevt + 1;
397 QwDebug<<
" QwHelicityPattern::CalculatePairAsymmetry == \n"
398 <<
" undefined local helicity (-9999) \n"
399 <<
" impossible to compute asymmetry \n"
404 QwDebug <<
"QwHelicityPattern::CalculatePairAsymmetry: "
405 <<
"Helicity should be "<<plushel<<
" or "<<minushel
407 <<
"; Asymmetry computation aborted!"<<
QwLog::endl;
410 QwError<<
" QwHelicityPattern::CalculatePairAsymmetry == \n"
411 <<
" you do not have the same number of positive and negative \n"
412 <<
" impossible to compute asymmetry \n"
443 Bool_t complete_and_good = kFALSE;
448 return complete_and_good;
457 Bool_t localdebug=kFALSE;
460 while(filled && i>-1)
463 std::cout<<
" i="<<i<<
" is loaded ?"
484 Bool_t localdebug=kFALSE;
486 if(localdebug) std::cout<<
"Entering QwHelicityPattern::CalculateAsymmetry \n";
491 Bool_t firstplushel=kTRUE;
492 Bool_t firstminushel=kTRUE;
503 localhel ^= ((i >> j)&0x1);
505 if (localhel == plushel) {
508 firstplushel = kFALSE;
512 }
else if (localhel == minushel) {
515 firstminushel = kFALSE;
525 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: here filling fPositiveHelicitySum \n";
527 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: with = \n";
529 firstplushel = kFALSE;
531 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: with += \n";
536 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: here filling fNegativeHelicitySum \n";
538 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: with = \n";
540 firstminushel = kFALSE;
542 if (localdebug) std::cout<<
"QwHelicityPattern::CalculateAsymmetry: with += \n";
547 QwDebug <<
"QwHelicityPattern::CalculateAsymmetry: "
548 <<
"Helicity should be "<<plushel<<
" or "<<minushel
550 <<
"; Asymmetry computation aborted!"<<
QwLog::endl;
559 if (checkhel == -9999) {
562 }
else if (checkhel!=0) {
565 QwError<<
" QwHelicityPattern::CalculateAsymmetry == \n"
566 <<
" you do not have the same number of positive and negative \n"
567 <<
" impossible to compute asymmetry \n"
661 for(
size_t i=0; i<
fEvents.size(); i++)
706 fYield.AccumulateRunningSum(entry.
fYield, count, ErrorMask);
747 fYield.CalculateRunningAverage();
804 TString prefix =
"blinder_";
805 fBlinder.ConstructObjects(folder,prefix);
808 fYield.ConstructObjects(folder,prefix);
827 TString prefix =
"yield_";
828 fYield.ConstructHistograms(folder,prefix);
830 fAsymmetry.ConstructHistograms(folder,prefix);
862TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length())+
"BurstCounter";
864 TString newprefix =
"yield_" + prefix;
865 fYield.ConstructBranchAndVector(tree, newprefix, values);
866 newprefix =
"asym_" + prefix;
867 fAsymmetry.ConstructBranchAndVector(tree, newprefix, values);
870 newprefix =
"diff_" + prefix;
871 fDifference.ConstructBranchAndVector(tree, newprefix, values);
874 newprefix =
"asym1_" + prefix;
875 fAsymmetry1.ConstructBranchAndVector(tree, newprefix, values);
876 newprefix =
"asym2_" + prefix;
877 fAsymmetry2.ConstructBranchAndVector(tree, newprefix, values);
883 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length())+
"BurstCounter";
886 TString newprefix =
"yield_" + prefix;
887 fYield.ConstructBranch(tree, newprefix);
888 newprefix =
"asym_" + prefix;
892 newprefix =
"diff_" + prefix;
896 newprefix =
"asym1_" + prefix;
898 newprefix =
"asym2_" + prefix;
905 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length())+
"BurstCounter";
907 TString newprefix =
"yield_" + prefix;
908 fYield.ConstructBranch(tree, newprefix, trim_tree);
909 newprefix =
"asym_" + prefix;
910 fAsymmetry.ConstructBranch(tree, newprefix, trim_tree);
913 newprefix =
"diff_" + prefix;
917 newprefix =
"asym1_" + prefix;
918 fAsymmetry1.ConstructBranch(tree, newprefix, trim_tree);
919 newprefix =
"asym2_" + prefix;
920 fAsymmetry2.ConstructBranch(tree, newprefix, trim_tree);
927 fYield.FillTreeVector(values);
939#ifdef HAS_RNTUPLE_SUPPORT
940void QwHelicityPattern::ConstructNTupleAndVector(std::unique_ptr<ROOT::RNTupleModel>& model, TString& prefix, std::vector<Double_t>& values, std::vector<std::shared_ptr<Double_t>>& fieldPtrs)
942 TString basename = prefix(0, (prefix.First(
"|") >= 0)? prefix.First(
"|"): prefix.Length())+
"BurstCounter";
946 TString newprefix =
"yield_" + prefix;
947 fYield.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
948 newprefix =
"asym_" + prefix;
949 fAsymmetry.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
952 newprefix =
"diff_" + prefix;
953 fDifference.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
956 newprefix =
"asym1_" + prefix;
957 fAsymmetry1.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
958 newprefix =
"asym2_" + prefix;
959 fAsymmetry2.ConstructNTupleAndVector(model, newprefix, values, fieldPtrs);
963void QwHelicityPattern::FillNTupleVector(std::vector<Double_t>& values)
const
966 fYield.FillNTupleVector(values);
979#ifdef __USE_DATABASE__
980void QwHelicityPattern::FillDB(QwParityDB *db)
984 fYield.FillDB(db,
"yield");
995void QwHelicityPattern::FillErrDB(QwParityDB *db)
1005 fYield.WritePromptSummary(ps,
"yield");
1006 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 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.
Subsystem for helicity state management and pattern recognition.
Int_t GetMinPatternPhase()
Bool_t IsHelicityIgnored()
Long_t GetPatternNumber()
Int_t GetHelicityActual()
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
Long_t fLastPatternNumber
QwSubsystemArrayParity fPairDifference
Int_t fBurstMinGoodPatterns
std::vector< Bool_t > fEventLoaded
QwHelicityPattern()
Private default constructor (not implemented, will throw linker error on use)
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
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.