NAIA
Ntuples for AMS-Italy Analysis
Status of the framework and tools
Status
# STATUS
- Last relased version: v1.0.2
- Several bugfixes and infrastructural improvements on the library side
- Next planned version: v1.1.0
- Some bugs spotted on the production side and new variables are needed, will need a new production.
- Work will begin after this meeting, and production start is planned for ~July
- Currently considering yearly production runs, depending on the need for reprocessing due to bugs / new variables.
- Currently available datasets:
- ISS.B1236/pass8 (11.5 years of data)
- Ar.B1236 Be.B1236 C.B1236 Fe.B1236 Li.B1236 N.B1236 O.B1236 Pr.B1236 Si.B1236 B.B1236 Ca.B1236 el.B1236 He.B1236 Mg.B1236 Ne.B1236 pos.B1236 S.B1236 Ti.B1236
Tools: Were we left off
# TOOLS
NAIA is just a data model and framework for AMS analysis. We can think of it as the foundational layer, but there is room for creating useful tools to further the data analysis experience.
We currently have in the works:
- A NAIA adapter for ROOT's TSelector framework (NaiaTSelector)
- A common selection library (NSL)
- A ROOT-based spline fitting library (RSpline)
- A rewrite of the plugin system initially proposed for the dbar analysis
Tools: NSL
# TOOLS
NSL: A common selection library
This project aims at providing a set of commonly used selections that:
- can be easily and arbitrarily combined (and/or parametrized)
- allow to quickly build an analysis
- are easy to read and understand (on a concept level, at least)
- can be used to share the logic of a set of selections without having to worry too much about implementation details
Manual available at: https://nsl-readthedocs.readthedocs.io/en/latest/index.html
NSL: basics
# TOOLS
A story as old as time
//Trigger selection
if( (PhysBPatt & triggerPatt) == 0 ) continue; //Any non-prescaled trigger
//Inner Tracker selection
if( trtrackc->InnerCharge[chargeRecoType] < ITrTrackCharge_low || trtrackc->InnerCharge[chargeRecoType] > ITrTrackCharge_high ) continue;
if( trtrackc->TrChiSqY[TrTrackCont::Span::InnerOnly] > 10 ) continue;
if( trtrackc->InnerChargeRMS[chargeRecoType]/trtrackc->InnerCharge[chargeRecoType] > TrackChargeRMS ) continue;
if( !trtrackc->CheckInnerPattern() ) continue;
if( !option.CompareTo("") || option.Contains("PG") ){
if( trtrackc->NGoodCluster < 3 ) continue;
}
if( !option.CompareTo("qi") ){
if( trtrackc->GetNHitsInnerY() < 5 ) continue;
}
//Upper ToF selection
if( betahc->Beta < Beta_thr ) continue;
if(Charge < 9){
if( !betahc->TofGoodPathL[0] && !betahc->TofGoodPathL[1] ) continue;
}
if( betahc->UTofCharge < UTofCharge_lthr || betahc->UTofCharge > UTofCharge_hthr ) continue;
//L1 selection
if( !trtrackc->SpanType[TrTrackCont::Span::InnerL1] ) continue;
if (trtrackc->TrChiSqY[TrTrackCont::Span::InnerL1] > 10) continue;
if( trtrackc->GetL1NormRes() > 10 ) continue;
NSL: basics
# TOOLS
A story as old as time:
- A long sequence of ifs inside the main event loop
- At the end of the loop (or interleaved among the selections) fill histograms / trees
- After looping, save results
The first item can be summarized as:
We are only interested in a precise subset of events, and we filter out events we don’t care about by asking simple yes/no questions about the value of some variables.
The whole library is designed around this concept
NSL: The Selection
# TOOLS
In short, a selection is just a yes/no question about variables in an event.
Whenever you instantiate a NSL::Selection
object you can always query wether a NAIA::Event
passes that selection
NSL::Selection my_selection = get_some_selection();
// ...
for (NAIA::Event &ev : chain) {
if (my_selection(event)){
// do stuff...
}
}
things can still get out of hands pretty soon
if (my_selection_1(event) && my_selection_2(event) && /* ... */ my_selection_N(event)) {
NSL: The Selection
# TOOLS
Another main point of this library is allowing to define the whole selection logic ahead of time before the event loop, so that in the event loop you can focus on what you actually do with the events you select, rather than how you select them.
namespace ns = NSL::Selections;
auto triggerSel = ns::Trigger::HasPhysicsTrigger();
auto innerTrackerSel =
ns::InnerTracker::HitPattern() &&
ns::Track::ChiSquareLessThan(10.0f, NAIA::TrTrack::Side::Y, NAIA::TrTrack::Fit::GBL, NAIA::TrTrack::Span::InnerOnly);
for (NAIA::Event &ev : chain) {
if (!triggerSel(event))
continue;
if (!innerTrackerSel(event))
continue;
// fill histos or whatever :)
}
A full list of already defined selections is available here
NSL: Hooks
# TOOLS
In some cases it might be useful to perform some check between the evaluation of two or more selections, maybe you want to print some value to the screen, fill some histogram, check if some precondition is satisfied, etc…
NSL: Hooks
# TOOLS
In some cases it might be useful to perform some check between the evaluation of two or more selections, maybe you want to print some value to the screen, fill some histogram, check if some precondition is satisfied, etc…
But if you defined you entire Selection sequence in one go there is no way of inserting code between one check and the next one. On the other hand, keeping all selections separated only to be able to fill a histogram in between kinda defeats the purpose of the whole design of this library.
NSL: Hooks
# TOOLS
In some cases it might be useful to perform some check between the evaluation of two or more selections, maybe you want to print some value to the screen, fill some histogram, check if some precondition is satisfied, etc…
But if you defined you entire Selection sequence in one go there is no way of inserting code between one check and the next one. On the other hand, keeping all selections separated only to be able to fill a histogram in between kinda defeats the purpose of the whole design of this library.
For this exact application NSL allows to define for each selection a “hook”, which is a snippet of code that can be run before or after the evaluation of the selection. The former case is named a “pre-hook”, while the latter is called a “post-hook” and can be selectively run when the check succeeds, fails or in both cases.
NSL: Hooks
# TOOLS
The way you attach a hook to a Selection is by calling AddPreHook
or AddPostHook
// NSL namespace omitted for clarity
auto my_selection_chain = MySelection1(...).AddPreHook([](NAIA::Event &ev){ /* your hook code here */ }) &&
MySelection2(...).AddPostHook([](NAIA::Event &ev){ /* ... */ }, PostHookCondition::OnSuccess) &&
/* All your selections ... */;
NSL: Hooks
# TOOLS
The way you attach a hook to a Selection is by calling AddPreHook
or AddPostHook
// NSL namespace omitted for clarity
auto my_selection_chain = MySelection1(...).AddPreHook([](NAIA::Event &ev){ /* your hook code here */ }) &&
MySelection2(...).AddPostHook([](NAIA::Event &ev){ /* ... */ }, PostHookCondition::OnSuccess) &&
/* All your selections ... */;
A hook is represented in code by any kind of function that takes a NAIA::Event &
and returns void
. Also, for post-hooks the PostHookCondition
enum controls when the hook is actually executed. In the last example we added a “pre-hook” to MySelection1
which will always be executed before the selection is checked, and a “post-hook” to MySelection2
which will only be executed when the selection is passed.
NSL: Hooks (example)
# TOOLS
// create a chain and add a rootfile to it
NAIA::NAIAChain chain;
chain.Add("some_root_file.root");
// define your selections
auto my_selections = NSL::Trigger::HasPhysicsTrigger() &&
NSL::Tof::BetaInRange(0.3, 1.5, NAIA::Tof::BetaType::BetaH);
// create a histogram for the charge distribution plot
TH1D charge_distribution{"charge", ";Q;Counts", 100, 0, 15};
// create the action that fills the charge histogram
// NOTE: since NSL requires that hooks take an event and return void, we need to use lambda capture-by-reference to
// have the histogram available inside our hook function
auto fill_charge_distribution = [&charge_distribution](NAIA::Event &ev){
charge_distribution.Fill(ev.trTrackBase->InnerCharge[NAIA::TrTrack::ChargeRecoType::YJ]);
};
// add our function to our selectinos as a post-hook, to be run when the selections pass
my_selections.AddPostHook(fill_charge_distribution, NSL::PostHookCondition::OnSuccess);
// loop over the events and evaluate the selection(s).
for (NAIA::Event &event : chain){
if (!my_selections(event)){
continue;
}
}
charge_distribution.Draw();
Happy coding :)
#
230421 - NAIA Status and tools
By Valerio Formato
230421 - NAIA Status and tools
- 127