Back to home page

EIC code displayed by LXR

 
 

    


Warning, /tutorial-reconstruction-algorithms/episodes/06-working-with-podio.md is written in an unsupported language. File is not indexed.

0001 ---
0002 title: "Working with PODIO"
0003 teaching: 5
0004 exercises: 1
0005 ---
0006 
0007 ::::::::::::::::::::::::::::::::::::::::::::: questions
0008 
0009 - What is PODIO and why does the EIC data model use it?
0010 - How do I create and fill PODIO collections, and what is a subset collection?
0011 
0012 :::::::::::::::::::::::::::::::::::::::::::::
0013 
0014 ::::::::::::::::::::::::::::::::::::::::::::: objectives
0015 
0016 - Gain familiarity working with PODIO collections.
0017 - Understand PODIO subset collections.
0018 
0019 :::::::::::::::::::::::::::::::::::::::::::::
0020 
0021 ## Introduction to PODIO
0022 
0023 Our data model is in a library/namespace/repository called `edm4eic`, and it is built on top of `edm4hep`, a data model designed to capture commonalities across HEP experiments. `edm4eic` is implemented using PODIO, which is a toolkit for generating the data model classes from a specification written in YAML. Here is a very simple example of a PODIO specification:
0024 
0025 ```yaml
0026 options :
0027   # should getters / setters be prefixed with get / set?
0028   getSyntax: False
0029   # should POD members be exposed with getters/setters in classes that have them as members?
0030   exposePODMembers: True
0031   includeSubfolder: True
0032 
0033 datatypes :
0034   ExampleHit :
0035     Description : "Hit"
0036     Author : "B. Hegner"
0037     Members:
0038       - unsigned long long cellID      // cellID
0039       - double x      // x-coordinate
0040       - double y      // y-coordinate
0041       - double z      // z-coordinate
0042       - double energy // measured energy deposit
0043 
0044   ExampleCluster :
0045     Description : "Cluster"
0046     Author : "N. Brei"
0047     Members:
0048       - double energy // cluster energy
0049     OneToManyRelations:
0050       - ExampleHit Hits // hits contained in the cluster
0051       - ExampleCluster Clusters // sub clusters used to create this cluster
0052 ```
0053 
0054 PODIO will then generate for us the following classes:
0055 ```
0056 DatamodelDefinition.h ExampleCluster.h ExampleClusterCollection.h ExampleClusterCollectionData.h ExampleClusterData.h ExampleClusterObj.h ExampleHit.h ExampleHitCollection.h ExampleHitCollectionData.h ExampleHitData.h ExampleHitObj.h MutableExampleHit.h MutableExampleCluster.h
0057 ```
0058 
0059 As you can see, PODIO has a lot of moving pieces. Why? 
0060 
0061 1. PODIO adds a separate layer for managing memory in a way which is more consistent with Python and other garbage-collected languages. The user only has to work with values, no explicit allocations or deletions.
0062 2. PODIO separates the data's memory layout from its accessors
0063 3. PODIO enforces immutability directly in the object model
0064 4. PODIO has sophisticated (though fragile!) mechanisms for tracking object references
0065 
0066 These design principles in principle should eliminate entire classes of bugs. However, there are still subtleties when using PODIO that can lead to leaks, crashes, or corrupted references. Luckily, the correct usage pattern is quite simple, as we will discuss next.
0067 
0068 
0069 ## Working with PODIO objects, collections, and subset collections:
0070 
0071 
0072 ```c++
0073 auto hits = std::make_unique<ExampleHitCollection>();
0074 
0075 hits->push_back(ExampleHit(22, 0.0, 0.0, 0.0, 0.001));
0076 
0077 MutableExampleHit hit;
0078 hit.x(0.0);
0079 hit.energy(0.001);
0080 // ...
0081 hits->push_back(hit);
0082 
0083 MutableExampleCluster cluster;
0084 cluster.addHits(hit);
0085 
0086 // Safety tip: Add object to a collection BEFORE creating an association to it
0087 
0088 auto clusters = std::make_unique<ExampleClusterCollection>();
0089 clusters->push_back(cluster);
0090 
0091 auto subset_clusters = std::make_unique<ExampleClusterCollection>();
0092 subset_clusters->setSubsetCollection(true);
0093 subset_clusters->push_back(cluster);
0094 
0095 // Safety tip: Every PODIO object is owned by exactly one collection.
0096 // If you want to put the object in other collections, those collections need to 
0097 // be designated as "subset collections", which means that they don't own their contents. 
0098 ```
0099 
0100 
0101 Note that when you write a factory, its inputs will be `const ExampleHitCollection*`, which are *immutable*.
0102 Its output is held by a `PodioOutput<ExampleHit>` member; calling `m_output()` returns a `std::unique_ptr<ExampleHitCollection>&` that the factory can mutate, and `m_output().get()` gives a raw mutable pointer that you can hand to your algorithm's `process()` method. After `Process()` returns, JOmniFactory transfers ownership of that collection to JANA2, which adds it to a podio `Frame`. From that point on, the collection is immutable and owned by the `Frame`.
0103 
0104 JANA2 will create and destroy `Frame`s internally. 
0105 
0106 
0107 ::::::::::::::::::::::::::::::::::::::::::::: challenge
0108 
0109 ## Exercise
0110 
0111 - Have your algorithm produce some (fake) output data!
0112 
0113 ::::::::::::::: solution
0114 
0115 In your algorithm's `process()`, create mutable objects, set some field values, and `push_back`
0116 them onto the output collection (or, for an electron finder, mark the output as a subset collection
0117 with `setSubsetCollection()` and push existing input objects onto it). Running EICrecon and
0118 inspecting the output collection should now show your fabricated entries.
0119 
0120 :::::::::::::::
0121 
0122 :::::::::::::::::::::::::::::::::::::::::::::
0123 
0124 ::::::::::::::::::::::::::::::::::::::::::::: keypoints
0125 
0126 - `edm4eic` (on top of `edm4hep`) is generated by PODIO from a YAML specification.
0127 - PODIO manages memory, separates layout from accessors, and enforces immutability, but object references are fragile.
0128 - Every PODIO object is owned by exactly one collection; use a *subset collection* (`setSubsetCollection()`) to reference objects owned elsewhere.
0129 - Factory inputs are immutable `const *`; the output collection becomes immutable once JANA2 moves it into a `Frame`.
0130 
0131 :::::::::::::::::::::::::::::::::::::::::::::