Difference between revisions of "Analysis TTreeFormat"

From GlueXWiki
Jump to: navigation, search
(Adding/Filling Custom Branches)
(Example Usage)
Line 46: Line 46:
 
locEventLoop->Get(locEventWriterROOTVector); //creates the TTrees for all DReactions upon first call
 
locEventLoop->Get(locEventWriterROOTVector); //creates the TTrees for all DReactions upon first call
 
locEventWriterROOTVector[0]->Fill_Tree(locEventLoop, locReaction, locParticleCombos);
 
locEventWriterROOTVector[0]->Fill_Tree(locEventLoop, locReaction, locParticleCombos);
 +
</syntaxhighlight>
 +
 +
=== Accessing TClonesArray Data Examples ===
 +
* TSelector:
 +
<syntaxhighlight>
 +
GetEntry(entry);
 +
cout << ((TLorentzVector*)PiPlus2__P4_KinFit->At(0))->Px() << endl; //At(): particle combination 0, 1, 2, ...
 +
</syntaxhighlight>
 +
 +
* TTree:
 +
<syntaxhighlight>
 +
MyTree->Draw("PiPlus2__P4_KinFit->Px()"); //draws all particle combinations
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Line 71: Line 83:
 
*locMyVariable = 3.0; //or whatever you want to save
 
*locMyVariable = 3.0; //or whatever you want to save
 
locEventWriterROOTVector[0]->Fill_Trees(locEventLoop);
 
locEventWriterROOTVector[0]->Fill_Trees(locEventLoop);
</syntaxhighlight>
 
 
=== Accessing TClonesArray Data Examples ===
 
* TSelector:
 
<syntaxhighlight>
 
GetEntry(entry);
 
cout << ((TLorentzVector*)PiPlus2__P4_KinFit->At(0))->Px() << endl; //At(): particle combination 0, 1, 2, ...
 
</syntaxhighlight>
 
 
* TTree:
 
<syntaxhighlight>
 
MyTree->Draw("PiPlus2__P4_KinFit->Px()"); //draws all particle combinations
 
 
</syntaxhighlight>
 
</syntaxhighlight>
  

Revision as of 16:07, 26 April 2013

Why a standard TTree format?

  • For any reaction can streamline (and provide a best-practices implementation/examples of): analysis utilities, BDT setup/input, amplitude analysis setup/input(?)
  • Makes it easy for users to keep everything organized, especially handling of the combinatoric background.
  • Format is designed to be one-size-fits-all, but is still extensible (customizable).

TTree Format - General

ROOT Version

  • ROOT >= v5.32 will be required for building DANA
    • Much easier to code TTree creation: TClonesArray::ConstructedAt() can be used instead of calls to placement-new
    • Just about any version of ROOT is fine for reading the data

Data Hierarchy

  • One TTree per DReaction
    • e.g., will have different trees for missing/detected recoil proton for the same final state
  • One TTree entry per recorded physics event.
  • One TBranch per variable. (e.g. "RunNumber", "PiMinus__PathLength", etc.)
  • Variables that change with DParticleCombo will be stored in arrays/TClonesArray's: one array index per DParticleCombo
    • e.g.: "PiPlus2__ChiSq_Tracking" (double[]), "Proton__P4_Measured" (TClonesArray(TLorentzVector))
  • Thrown particle data will be stored in arrays: one array index per DMCThrown.
  • Particle hypothesis data that is not used in any DParticleCombo written to the TTree will be stored in arrays: one array index per unused particle hypothesis (DChargedTrack and DNeutralParticleHypothesis).
    • Unused beam particles are NOT saved.
  • Event-independent information (e.g. the DReaction decay chain) is stored in TTree::fUserInfo (a TList*)

Object-Oriented Programming

  • Will provide tool to convert tree branch data into the C++ objects for a given event (callable from TSelector::Process())
    • C++ classes (similar to DANA classes): DTreeEvent, DTreeCombo, DTreeStep, DTreeParticle (compiled into ROOT dictionary & loadable shared library)
    • Can be used to write/execute reusable software that will work for any reaction (e.g. handling double-counting when filling histograms)

Example Usage

Save All DParticleCombo's for All DReaction's

  • This saves all of the particle combinations (for every DReaction) that survived all of the DAnalysisAction cuts.
//In plugin evnt()
vector<const DEventWriterROOT*> locEventWriterROOTVector;
locEventLoop->Get(locEventWriterROOTVector); //creates the TTrees for all DReactions upon first call
locEventWriterROOTVector[0]->Fill_Trees(locEventLoop);
  • This allows you to choose which DParticleCombo's (locParticleCombos) of which DReaction's (locReaction) to save.
    • Beware: the locParticleCombos MUST have originated from the locReaction or else this will probably crash (can check DParticleCombo::Get_Reaction()).
//In plugin evnt()
vector<const DEventWriterROOT*> locEventWriterROOTVector;
locEventLoop->Get(locEventWriterROOTVector); //creates the TTrees for all DReactions upon first call
locEventWriterROOTVector[0]->Fill_Tree(locEventLoop, locReaction, locParticleCombos);

Accessing TClonesArray Data Examples

  • TSelector:
GetEntry(entry);
cout << ((TLorentzVector*)PiPlus2__P4_KinFit->At(0))->Px() << endl; //At(): particle combination 0, 1, 2, ...
  • TTree:
MyTree->Draw("PiPlus2__P4_KinFit->Px()"); //draws all particle combinations

Adding/Filling Custom Branches

//Create the trees
vector<const DEventWriterROOT*> locEventWriterROOTVector;
locEventLoop->Get(locEventWriterROOTVector); //creates the TTrees for all DReactions upon first call
 
//Create the branch
double* locMyVariable = new double;
string locReactionName = locReaction->Get_ReactionName();
string locTreeName = locReactionName + string("_Tree");
japp->RootWriteLock(); //always acquire a lock before accessing the global ROOT file
{
  //get the tree
  gDirectory->cd("/");
  gDirectory->cd(locReactionName.c_str());
  TTree* locTree = (TTree*)gDirectory->Get(locTreeName.c_str());
  locTree->Branch("MyBranchName", locMyVariable, "D");
}
 
//Set the data in the branch and fill
*locMyVariable = 3.0; //or whatever you want to save
locEventWriterROOTVector[0]->Fill_Trees(locEventLoop);

TTree Format - Detail

Particle Names

  • Example Reaction (b1pi):
    • γ p → X(2000), (p)
      • X(2000) → b1(1235)+, π-
        • b1(1235)+ → ω, π+
          • ω → π+, π-, π0
            • π0 → γ γ
  • Reaction Particle Names, Beam: "Beam"
  • Reaction Particle Names, Detected: "PiMinus1," "PiPlus1," "PiPlus2," "PiMinus2," "Gamma1," "Gamma2"
  • Reaction Particle Names, Decaying: "X," "b1_1235_Plus," "omega," "Pi0"
    • No branches are created for these particles. All of their properties are derivable from the other data in the tree
  • Reaction Particle Names, Missing: "Proton"
    • No branches are created for these particles. All of their properties are derivable from the other data in the tree
  • Thrown MC Particle Name: "Thrown"
    • Array entries do NOT correspond to particle combos: just a different particle in each array index
  • Unused Particle Hypothesis Name: "Unused"
    • Array entries do NOT correspond to particle combos: just a different particle in each array index

Particle Data : Thrown

//IDENTIFIERS
"ID": (unsigned int)[] //each particle has it's own #
"ParentID": (unsigned int)[] //the "Identifier" of the particle this particle decayed from (0 if none (e.g. photoproduced))
"PID_PDG": int[]
 
//KINEMATICS: THROWN  //At the production vertex 
"X4_Thrown": TClonesArray(TLorentzVector)
"P4_Thrown": TClonesArray(TLorentzVector)

Particle Data : Beam Reaction Particles

//KINEMATICS: MEASURED //At the target center
"X4_Measured": TClonesArray(TLorentzVector)
"P4_Measured": TClonesArray(TLorentzVector)
 
//KINEMATICS: KINFIT //At the interaction vertex //only present if kinfit performed
"X4_KinFit": TClonesArray(TLorentzVector)
"P4_KinFit": TClonesArray(TLorentzVector)

Particle Data : Detected Reaction Particles

//IDENTIFIERS
"ID": (unsigned int)[] //each physical particle has it's own # (to keep track of different pid hypotheses for the same particle)
 
//KINEMATICS: MEASURED //At the production vertex
"X4_Measured": TClonesArray(TLorentzVector) //t is the measured value in TOF/BCAL/FCAL projected back to Position_Measured
"P4_Measured": TClonesArray(TLorentzVector)
 
// KINEMATICS: END //at the reconstructed position of the BCAL/FCAL/TOF hit
"X4_End": TClonesArray(TLorentzVector)
"P4_End": TClonesArray(TLorentzVector)
 
//KINEMATICS: KINFIT //At the production vertex //only present if kinfit performed
"X4_KinFit": TClonesArray(TLorentzVector)
"P4_KinFit": TClonesArray(TLorentzVector)
 
// KINEMATICS: Other
"PathLength": double[] //from dPosition_KinFit/Measured (KinFit if performed) to dPosition_End
 
// PID QUALITY:
"NDF_Tracking": (unsigned int)[] //for charged only
"ChiSq_Tracking": double[] //for charged only
"NDF_Timing": (unsigned int)[]
"ChiSq_Timing": double[] //using kinematic fit data
"ChiSq_Timing_Measured": double[] //using measured data
"NDF_DCdEdx": (unsigned int)[] //for charged only
"ChiSq_DCdEdx": double[] //for charged only
 
// DEPOSITED ENERGY:
"dEdx_CDC": double[] //for charged only
"dEdx_FDC": double[] //for charged only
"dEdx_TOF": double[] //for charged only
"dEdx_ST": double[] //for charged only
"Energy_BCAL": double[]
"Energy_FCAL": double[]

Particle Data : Unused Hypotheses

//IDENTIFIERS
"ID": (unsigned int)[] //each physical particle has it's own # (to keep track of different pid hypotheses for the same particle)
"PID": (unsigned int)[] //Particle_t value
 
//KINEMATICS: MEASURED  //At the production vertex 
"P4_Measured": TClonesArray(TLorentzVector)
"X4_Measured": TClonesArray(TLorentzVector) //t is the measured value in TOF/BCAL/FCAL projected back to Position_Measured
 
// KINEMATICS: END //at the reconstructed position of the BCAL/FCAL/TOF hit
"P4_End": TClonesArray(TLorentzVector)
"X4_End": TClonesArray(TLorentzVector)
 
// KINEMATICS: Other
"PathLength": double[] //from Position_Measured to Position_End
 
// PID QUALITY:
"NDF_Tracking": (unsigned int)[] //for charged only
"ChiSq_Tracking": double[] //for charged only
"NDF_Timing": (unsigned int)[]
"ChiSq_Timing": double[] //using kinematic fit data
"ChiSq_Timing_Measured": double[] //using measured data
"NDF_DCdEdx": (unsigned int)[] //for charged only
"ChiSq_DCdEdx": double[] //for charged only
 
// DEPOSITED ENERGY:
"dEdx_CDC": double[] //for charged only
"dEdx_FDC": double[] //for charged only
"dEdx_TOF": double[] //for charged only
"dEdx_ST": double[] //for charged only
"Energy_BCAL": double[]
"Energy_FCAL": double[]

Event-Independent Information

  • Stored in TTree::fUserInfo (a TList*)
  • "MiscInfoMap": TMap of TObjString -> TObjString
    • e.g.: "KinFitType" -> DKinFitType (converted to TObjString)
  • "NameToPIDMap": TMap of "UniqueParticleName" (TObjString) -> Particle_t (converted to TObjString)
  • "NameToPositionMap": TMap of "UniqueParticleName" (TObjString) -> "StepIndex_ParticleIndex" (stored in TObjString) (ParticleIndex = -1 for initial, -2 for target, 0+ for final state)
  • "PositionToNameMap": TMap of "StepIndex_ParticleIndex" (stored in TObjString) (ParticleIndex = -1 for initial, -2 for target, 0+ for final state) -> "UniqueParticleName" (TObjString)
  • "PositionToPIDMap": TMap of "StepIndex_ParticleIndex" (stored in TObjString) (ParticleIndex = -1 for initial, -2 for target, 0+ for final state) -> Particle_t (converted to TObjString)

C++ Classes

  • Data Structures:
    • DTreeParticle: roughly mirrors DKinematicData: kinematics + PID info of track
    • DTreeStep: roughly mirrors DParticleComboStep: collection of DTreeParticle's for a given step of a reaction (e.g. photoproduction, Λ decay, π0 decay, etc.)
    • DTreeCombo: roughly mirrors DParticleCombo (collection of DTreeStep's for a given reaction), + detected particles not used in the combo
    • DTreeEvent: contains DTreeCombo's for each output DReaction, + thrown tracks
  • Extensible:
    • Each class has maps to contain additional data (TObject* and double, map keys are string): custom branches in the TTree will be added here.
  • Usage:
    • Process with a TSelector.
    • TTree::Draw() and TTree::Project() will not work due to nested classes/containers.

DTreeParticle

  • Roughly mirrors DKinematicData: kinematics + PID info of track
  • p3, v3, and t are stored at both the start (production) and end points (decay, TOF/BCAL/FCAL hit) of the track.
    • This is primarily motivated by the Ξ-, which is long-lived and whose trajectory is bent by the magnetic field before it decays.
  • Extensible: maps can be used by users to add their own custom information.
class DTreeParticle : public TObject
{
  public:
    // PID:
    Particle_t dPID;
 
    // KINEMATICS: Measured
    TVector3 dPosition_Measured; //the position where the particle is produced
    double dTime_Measured; //time of the track at dPosition_Measured, projected from the TOF/BCAL/FCAL hit
    TVector3 dMomentum_Measured; //momentum of the track at dPosition_Start
 
    // KINEMATICS: KinFit 
    TVector3 dPosition_KinFit; //the position where the particle is produced
    double dTime_KinFit; //time of the track at dPosition_KinFit
    TVector3 dMomentum_KinFit; //momentum of the track at dPosition_KinFit
 
    // KINEMATICS: End
    TVector3 dPosition_End; //detected particles: the reconstructed position of the BCAL/FCAL/TOF hit; decaying particles: the point where it decays
    double dTime_End; //time of the track at dPosition_End
    TVector3 dMomentum_End; //momentum of the track at dPosition_End
 
    // KINEMATICS: Other
    double dPathLength; //from dPosition_KinFit/Measured (if kinfit performed/not-performed) to dPosition_End
 
    // PID QUALITY:
    unsigned int dNDF_Tracking;
    double dChiSq_Tracking;
    unsigned int dNDF_Timing;
    double dChiSq_Timing;
    unsigned int dNDF_DCdEdx;
    double dChiSq_DCdEdx;
 
    // DEPOSITED ENERGY:
    map<DetectorSystem_t, double> dDepositedEnergies; //Is dE/dx for all but BCAL/FCAL (shower energies)
 
    // DTREESTEP POINTERS:
    const DTreeStep* dProductionStep; //the step object in which this DTreeParticle is produced (is a final-state particle)
    const DTreeStep* dDecayStep; //the step object in which this DTreeParticle decays (is an initial-state particle) (will be null if not a decaying particle!)
 
    // CUSTOM VARIABLES:
    map<string, double> dCustomVariables; //key is unique string, double is value
    map<string, const TObject*> dCustomObjects; //key is unique string, TObject* is object
 
  ClassDef(DTreeParticle, 1)
};

DTreeStep

  • Roughly mirrors DParticleComboStep: collection of DTreeParticle's for a given step of a reaction (e.g. photoproduction, Λ decay, π0 decay, etc.)
  • Extensible: maps can be used by users to add their own custom information.
class DTreeStep : public TObject
{
  public:
    // INITIAL PARTICLES:
    const DTreeParticle* dInitialParticle; //if is null: decaying or beam particle not yet set!
    const DTreeParticle* dTargetParticle; //NULL for no target
 
    // FINAL PARTICLES:
    deque<DParticle_t> dFinalParticleIDs; //separate in case particle is NULL (e.g. decaying resonance)
    deque<const DTreeParticle*> dFinalParticles; //particle may be NULL if it is decaying or missing (especially if no kinematic fit was performed!!)
 
    // CUSTOM VARIABLES:
    map<string, double> dCustomVariables; //key is unique string, double is value
    map<string, const TObject*> dCustomObjects; //key is unique string, TObject* is object
 
  ClassDef(DTreeStep, 1)
};

DTreeCombo

  • Roughly mirrors DParticleCombo (collection of DTreeStep's for a given reaction), + detected particles not used in the combo
  • Extensible: maps can be used by users to add their own custom information.
class DTreeCombo : public TObject
{
  public:
    // STEPS:
    deque<const DTreeStep*> dTreeSteps;
 
    // RF:
    double dRFTime;
 
    // UNUSED PARTICLES:
    vector<const DTreeParticle*> dUnusedDetectedParticles;
    vector<const DTreeShower*> dUnusedDetectedShowers;
 
    // KINEMATIC FIT:
    DKinFitType dKinematicFitType; //Defined in DKinFitResults.h //d_NoFit if not performed
    double dChiSq_KinematicFit; //NaN if not performed
    unsigned int dNDF_KinematicFit; //0 if not performed
 
    // CUSTOM VARIABLES:
    map<string, double> dCustomVariables; //key is unique string, double is value
    map<string, const TObject*> dCustomObjects; //key is unique string, TObject* is object
 
  ClassDef(DTreeCombo, 1)
};

DTreeEvent

  • Contains DTreeCombo's for each output DReaction, + thrown tracks
  • Extensible: maps can be used by users to add their own custom information.
class DTreeEvent : public TObject
{
  public:
    // RUN, EVENT #'s:
    unsigned int dRunNumber;
    unsigned int dEventNumber;
 
    // DATA:
    map<string, deque<const DTreeCombo*> > dTreeCombos; //string key is (D)Reaction name, deque is the particle combos
    deque<const DTreeParticle*> dThrownParticles;
 
    // CUSTOM VARIABLES:
    map<string, double> dCustomVariables; //key is unique string, double is value
    map<string, const TObject*> dCustomObjects; //key is unique string, TObject* is object
 
  ClassDef(DTreeEvent, 1)
};