Using MCKinematicsReader for reconstructed tracks

I am trying to access the MC information (in o2sim_Kine.root) of reconstructed tracks (for example in in o2trac_ist.root as I am looking at tracks reconstructed in the ITS) using the outputs of an o2 simulation (o2sim suite).

I have found the o2::steer::MCKinematicsReader class that should, if I understand correctly, allow me to find the MC track (in o2sim_Kine.root) associated with the reconstructed track (in o2trac_its.root) by using labels, and calling the function .getTrack().

I have tried to use the .getTrack(int trackID, int event ID, int sourceID) variation of the function, but I can’t get my code to work: it breaks after iterating over 1 to 5 or 6 tracks, then breaks with a segmentation violation when I use MCKinematicsReader reader.getTrack()

I attached the whole code to this post, but here is a summary of what I am doing in it:

//initialise MCKinematicsReader
o2::steer::MCKinematicsReader reader("/thepathtothecorrectfolder/collisioncontext.root");

//loop over the tracks
for (int itrack = 0; itrack<nTracks; itrack++){
    //get the trackID, eventID and sourceID of the track
    //assuming good declaration of mMCTruthArray and link to the o2trac_its.root file (see full code)
    int trackID = mMCTruthArray.getElement(itrack).getTrackID();
    int eventID = mMCTruthArray.getElement(itrack).getEventID();
    int sourceID = mMCTruthArray.getElement(itrack).getSourceID();

    //get the track associated to those labels
    o2::MCTrack const* mctrack = reader.getTrack(trackID, eventID, sourceID); -->this is where the break happens when it happens

    if (!mctrack){
        Printf("     no track found");
        pdgCode = 0;
    long int pdgCode = mctrack->GetPdgCode();

If I run the built executable several times in a row, the break doesn’t happen always at the same iteration over the tracks: if most of the times it breaks at itrack=0, it sometimes goes up to itrack=6, and returns for the pdgCode 0,1 or 32767 which is apparently the range of the int type: -32768 to 32767. When changing pdgCode from int to long int, I still sometimes get 32767.

The error message I get once it breaks is:

*** Break *** segmentation violation
[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)
[<unknown binary>] (no debug info)
[/Users/stf4795/alice/sw/BUILD/O2-latest/O2/stage/bin/o2-trimITSTrackTree-AIMERIC_files] main /Users/stf4795/alice/sw/SOURCES/O2/v1.2.0/0/AIMERIC_files/src/trim_ITS_track_tree.cxx:152
[/usr/lib/system/libdyld.dylib] start (no debug info)
[<unknown binary>] (no debug info)

Am I using the MCKinematicsReader incorrectly? I’ve found examples in the github but they all show how to use it with the digits files instead of the reconstructed tracks files.

Best wishes,
trim_ITS_track_tree.cxx (6.1 KB)

I’ll take a look. Do you have more instructions how to reproduce (aka a simple sequence of workflows)?

Hi Sandro,

Here is a folder containing:

  • the .sh simulation macro to get the .root files I’m using
  • a folder titled AIMERIC_files that I copy in my ~alice/O2 folder and build using cmake --build . in ~/alice/sw/BUILD/O2-latest/O2 (after adding the line add_subdirectory(AIMERIC_files) to the ~/alice/O2/CMakeLists.txt file)

You will have to change the location of the different files the .cxx file looks at depending on where you run the simulation.

I then type the command ~/alice/sw/BUILD/O2-latest/O2/stage/bin/o2-trimITSTrackTree-AIMERIC_files

I haven’t made an automated workflow out of this, I can look into making one.


Created a JIRA ticket

It seems to work with the attached macro TestITS.C (4.5 KB) .

I took a look into your code and realized 2 things:
a) you read back the labels as MCTruthContainer but for ITS tracks the correct type is std::vector<MCCompLabel>
b) there was a wrong order of source, event, trackID in your call to reader.getTrack() which lead to a segfault.

I am closing the JIRA ticket, but feel free to come back to me in case of problems.

Hi Sandro,

thank you for your help!
Indeed I messed up the order of the inputs in the reader.getTrack() function.
I tried to run your macro in root, unfortunately I get an error message, related to the part a) of your answer:

[O2/latest] ~/alice/MyWorkDir/O2/test_executables %> root
  | Welcome to ROOT 6.20/02               |
  | (c) 1995-2020, The ROOT Team; conception: R. Brun, F. Rademakers |
  | Built for macosx64 on Sep 14 2020, 16:01:00                      |
  | From tags/v6-20-02-alice7@v6-07-06-16911-gdc5d774a41             |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q'       |

root [0] .L TestITS.C 
root [1] TestITS()
Error in <TTree::SetBranchAddress>: The pointer type given (vector<o2::MCCompLabel>) does not correspond to the class needed (o2::dataformats::MCTruthContainer<o2::MCCompLabel>) by the branch: ITSTrackMCTruth
We have 396 tracks We have [/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] cling_runtime_internal_throwIfInvalidPointer (no debug info)
[<unknown binary>] (no debug info)
[<unknown binary>] (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] cling::IncrementalExecutor::executeWrapper(llvm::StringRef, cling::Value*) const (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] cling::Interpreter::EvaluateInternal(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] cling::Interpreter::process(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, cling::Value*, cling::Transaction**, bool) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] HandleInterpreterException(cling::MetaProcessor*, char const*, cling::Interpreter::CompilationResult&, cling::Value*) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] TRint::ProcessLineNr(char const*, char const*, int*) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] TRint::HandleTermInput() (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] TUnixSystem::CheckDescriptors() (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] TMacOSXSystem::DispatchOneEvent(bool) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] TSystem::InnerLoop() (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] TSystem::Run() (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] TApplication::Run(bool) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/lib/] TRint::Run(bool) (no debug info)
[/Users/stf4795/alice/sw/osx_x86-64/ROOT/v6-20-02-alice7-4/bin/root.exe] main (no debug info)
[/usr/lib/system/libdyld.dylib] start (no debug info)
Error in <HandleInterpreterException>: Trying to dereference null pointer or trying to call routine taking non-null arguments.
Execution of your code was aborted.
In file included from input_line_8:1:
/Users/stf4795/alice/MyWorkDir/O2/test_executables/TestITS.C:79:32: warning: null passed to a callee that requires a non-null argument [-Wnonnull]
    std::cerr << "We have " << mcTruthArrayPtr->size() << " labels ";
root [2] 

This is an error message like the first line of this one that led me to use o2::dataformats::MCTruthContainer<o2::MCCompLabel> instead of std::vector<MCCompLabel>

I am using an updated version of O2, what is going differently on my machine if this macro worked on your computer? maybe I’m not supposed to use this macro this way? If that’s the case, I am sorry, I am not used to using macros.


Hi @alandou

Apparently you are using o2trac_its.root reconstructed with at least 3-weeks old code: the message Error in <TTree::SetBranchAddress>: The pointer type given (vector<o2::MCCompLabel>) does not correspond to the class needed (o2::dataformats::MCTruthContainer<o2::MCCompLabel>) by the branch: ITSTrackMCTruth shows that your tree contains o2::dataformats::MCTruthContainer, while all track objects and vertex objects use vector to store MC. You will need to redo at least o2-its-reco-workflow with fresher O2.


P.S. If you want to test with your old data, please just put the serialized class type back to o2::dataformats::MCTruthContainer. I had to use std::vector since tested on newly produced data.

I had not seen that the data format had been changed. Indeed a new simulation solved this issue.
Thanks for the help.

I have still one more issue with an updated version of my code, or with the macro Sandro uploaded abvove: using either version, the algorithm breaks at the following line (I have a printf(“test 0”) before and a printf(test 1) after, only the former appears):

    o2::MCTrack const* mctrack = reader.getTrack(label);

with the following error message:

O2/latest] ~/alice/MyWorkDir/O2/test_executables %> bash
We have 121 tracks We have 121 labels Track number 0
     trackID = 203
     eventID = 0
     sourceID = 0
     test 0
Error in <TFile::TFile>: file o2sim_Kine.root does not exist

 *** Break *** segmentation violation
[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)
[<unknown binary>] (no debug info)
[/Users/stf4795/alice/sw/BUILD/O2-latest/O2/stage/bin/o2-trimITSTrackTree-AIMERIC_files] main /Users/stf4795/alice/sw/SOURCES/O2/v1.2.0/0/AIMERIC_files/src/trim_ITS_track_tree.cxx:158
[/usr/lib/system/libdyld.dylib] start (no debug info)
[<unknown binary>] (no debug info)
[O2/latest] ~/alice/MyWorkDir/O2/test_executables %

even though it had no issue with opening o2sim_Kine.root with the very first line of the macro/function.
Removing the line o2::MCTrack const* mctrack = reader.getTrack(label); and every following line that refers to mctrack has the macro work fine.

EDIT: this looks like an issue with the position of the files in my directory and how the reader works.
Indeed, the macro works fine if I use it inside the folder with the o2sim outputs. Using it in a different folder, even by setting up the input files paths correctly, does not seem to work.