How can I execute a metadata class from a rml file?

REST version : v2.3.7
REST commit : a556b20

I wrote a Metadata class which I want to use to add a std::map to a root file. The map contains for example the calibration factors for each veto, or assigns a name to a particular signalID.
The class you can find on github:

How do I have to format the .rml file to execute this class and to save the map to the root file? I want to execute something like restManager --c MapGroup.rml --f data/R01221_0-91_merged.root.

In the example below, I tried to use addProcess, but this obviously doesnā€™t work (because the class is not a processā€¦). I also tried to use addMetadata, but then just nothing happens when launching the rml. What do I have to do differently?

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>

<TRestManager>

<globals>
    <parameter name="mainDataPath" value="/home/konrad/iaxo-quickana/data" />
</globals>

<TRestRun name="vetoMapGroups" title="vetoMapGroups" verboseLevel="info">
    <parameter name="outputFileName" value="test.root" />
</TRestRun>


// Veto Group Names

<addProcess type="TRestMapGroup" name="vetoNames" value="ON" verboseLevel="info">
       <MapGroup key="top_1"    value="4692,4709,4723,4740"/>
       <MapGroup key="top_2"    value="4688,4705,4728,4744"/>
       <MapGroup key="top_3"    value="4713,4719,4735"/>
</addProcess>

// Calibration Factors

<addProcess type="TRestMapGroup" name="vetoCalibration" value="ON" verboseLevel="info">
        <MapGroup key="4612"  value="1"/>
        <MapGroup key="4616"  value="1"/>
</addProcess>

</TRestManager>

Hi Konrad,

you cannot execute a metadata class from a processing chain. A process is able to access the information of your metadata class, defined at TRestRun.

So, if in your RML you define inside TRestRun a TRestMapGroup metadata class. Then you would be able to code inside your process the following, and retrieve the metadata class information. Of course, if you didnt define, inside the process you will get a nullptr.

TRestMapGroup *myGroup = GetMetadata<TRestMapGroup>();

Your process now will use any information you defined at TRestMapGroup metadata class.

In other words, you cannot do

<addProcess type="TRestMapGroup"

because TRestMapGroup is not a process ā€¦

Still, inside restManager you will be able to define inside the RML to execute anything you wish.

If you defined

<TRestMapGroup name="vetoDefinitions" />

You will be able to execute any method inside the RML.

<addTask command="vetoDefinitions->MyCoolFunction()" value="ON"/>

Of course, you could do that also from a macro, create an instance of TRestMapGroup and call MyCoolFunction().

I am not sure if I understoodā€¦
So to add the metadata to the root file, I have to write a process which uses my metadata class? But how can I for example make use of the TRestMapGroup::InitFromConfigFile() method?

What I want in the end is to give the parameters to the class with a rml (like in the example above, to specify key and value pairs), run the rml on a root file with processed data, and then obtain a new root file which in addition contains fMapGroup objects.

Or is it better to do all of this with a Macro?

This method is called on class initialization. If you do TRestMapGroup *gr = new TRestMapGroup("config.rml"); the InitFromConfigFile method will be called. When you add your metadata object description inside TRestRun to be used in a processing chain this is done internally.

Both, using a macro, or implementing a process are two good options.

  • Option 1. Implementing a process. The output file generated will contain all metadata structures used previously, the ones defined at TRestRun, an eventTree, an analysisTree. The output file can be further processed in the future, and traceability is assured.

  • Option 2. Implementing a macro. You do basically what you want, but you will not be able, or you should not use it to write ROOT files in an incremental way. Just instantiate any metadata classes you need (through RML or ROOT), open any ROOT/REST files you need, and produce any non-REST output you want, being it a ROOT file, TXT file, a canvas with a plot, or anything else your macro is supossed to do.

Anyhow, we will be able to use the metadata class on both cases. Any process will be able to make use of it, any macro will be able to use it.

If it is not clear yet, then the best is to build a macro or just methods inside a class. If we build a process is because we want it to be permanently executed at the processing of the event data. We must distinguish between both, processing and analysing data. Building a process will make it possible to place those routines at a data production stage, building a macro will make it possible to use it for doing any kind of analysis.

Still, a metadata class is a c++ class that could do many things, so one could think of a c++ metadata class that is initialized through RML, but then we call methods in that class to do things.

For example, I could imagine to have a TRestMapGroupIds class, I initialize it through RML then I am able to call a method that draws an histogram with the average of each group from the analysisTree or RDataFrame.

So, one could imagine to do things like:

RDataFrame dataFrame( "AnalysisTree", "BunchOfRoot*Files.root");
TRetMapGroupIds *groups = new TRestMapGroupIds( "config.rml");
groups->PrintGroupAverages(dataFrame, "map_variable");

As an example, PrintGroupAverages would be a method you implement inside TRestMapGroupIds and iterates over the entries at the RDataFrame passed as argument, averages the entries matching the .first element of the map that belongs to each group and prints on screen.

Of course, you could do that at a ROOT session, or at a macro.

1 Like

Thank you for the answer! Now I managed to get the class finally running, so it now creates a map with the input from the RML.

I think currently we donā€™t need a process to add the map to a root file, it is enough to call the class from a macro or another process for analysis and plotting purposes.

For me the most important thing was that it allows me to define the veto calibration factors and names in a RML, so that they are easily accessible and can be shared, and this is now possible.

1 Like