.. _adding data: Extending hit info with MC data (STRAWs) ======================================== This page is devoted to a practical case of extending event structure with new type of the data. Albeit it is usually done by framework maintainers, users can still be interested in this practical scenario for assesment. Please note that extending an event with new data type is kind of an advanced topic in NA64SW by design. You may find full `commit info by this link`_. .. _`commit info by this link`: https://gitlab.cern.ch/P348/na64sw/-/commit/3f935f674cb67252f81d0ea60679dd956f3dae90#a06c49acd6ef06be4c86ac6b3e81ae06a77f47e7_49_49 Data type --------- A new hit type info has been introduced in the `na64-simulation`_ MC package keeping information about hits in Straw detector. It consists of following data entries (for brevity we restrict with only some): .. _`na64-simulation`: https://gitlab.cern.ch/P348/na64-simulation/ - A triggered wire and station identification - A two 3-dimensional vectors denoting the entry and exit points of the incident particle track triggering a hit - Energy deposition in the tube medium - Energy of initiating track (keV - Particle PDG code, distance from the wire, etc. Most of this information will be kept by a dedicated object representing an "MC truth". Since it is not present in our default event data structure, one has to introduce it. Extedning Event --------------- .. todo:: A documentation of event structure toolchain is not yet written. We will further place a link for corresponding chapter here. Since this data is exclusively related to Straw hits (``stwTDC``), the following configuration object is introduced to ``presets/event-struct/stwTDC.yaml`` to represent this "MC truth": .. code-block:: yaml StwMCInfo: $doc: MC information for a Straw hit $prealloc: 100 entryPoint: float[3] @ global coordinates of entry point exitPoint: float[3] @ global coordinates of exit point eDep: double @ energy deposition of incident particle # ... This type is then introduced as an association to a common Straw hit representation (``StwTDCHit`` type): .. code-block:: yaml StwTDCHit: # ... (existing fields) mcInfo: StwMCInfo @ A "true" MC information By running a special makefile (``utils/evstruct/Makefile``, probably within a dedicated Python virtual environment) we re-generate our C/C++ declarations making event code changes to propagate through the entire framework. That's it for extending event data structure. Extending the MKMC source ------------------------- The MK/MC event source is implemented as a plain C/C++ class in ``extensions/sources/mkmc/`` dir of NA64SW project. The ASCII file parsed by this class is the output of *na64-simulation* package (typically called as ``CaloHits.d`` and consists of data blocks tagged with special tokens. By current update we introduce new token ``STRAW``. Within the ``na64dp::mkmc::Source`` class parsing of the corresponding blocks are dispatched to particular callbacks set in constructor. We create a static method called ``Source::_read_evdat_STRAW()`` to handle this block and append the definitions in constructor with: .. code-block:: cpp _readers["STRAW"] = &Source::_read_evdat_STRAW; Implementation of reader callback is pretty straightforward: it receives the ``std::istream`` instance to read out tokens and builds a hit information accordingly. Firs, the number of anticipated hits goes in the ``STRAW`` section of ``CaloHits.d``, so within this reading callback we settle a loop with: .. code-block:: cpp bool Source::_read_evdat_STRAW(std::istream & is, Event & evRef) { int nHits; is >> nHits; for( int i = 0; i < nHits; ++i ) { // ... } } We create a new *general* Straw hit per MC truth entry and then allocate and add new ``StwMCInfo`` object within *general* hit. Within a ``for``-loop: .. code-block:: cpp // Build up detector a identifier using station#, plane# and wire# info: int stationNo, planeNo; is >> stationNo >> planeNo; DetID did( naming().kStwTDC, naming().kSt, stationNo, 0x0 ); WireID wid; APVPlaneID::Projection prj; switch(planeNo) { case(1): prj = APVPlaneID::kX; break; case(2): prj = APVPlaneID::kU; break; case(3): prj = APVPlaneID::kY; break; case(4): prj = APVPlaneID::kV; break; }; wid.proj(prj); int wireNo; is >> wireNo; wid.wire_no(wireNo); did.payload(wid.id); // Allocate and put new common straw hit instance into an event event::StwTDCHit & stwTDCHit = _add_entry(did, evRef, "STRAW"); // Allocate and put new MC truth hit info into common hit stwTDCHit.mcInfo = _lmem->create(*_lmem); Then one can continue to ``>>`` data from input stream into ``stwTDCHit.mcInfo`` object according to the specification of the input data format and C++ declaration described in YAML in previous section above: .. code-block:: cpp is >> stwTDCHit.mcInfo->entryPoint[0] >> stwTDCHit.mcInfo->entryPoint[1] >> stwTDCHit.mcInfo->entryPoint[2] ; is >> stwTDCHit.mcInfo->particlePDG >> stwTDCHit.mcInfo->geant4TrackID >> stwTDCHit.mcInfo->trackE >> stwTDCHit.mcInfo->eDep // ... ; That's it with extending the source. Added data become available for processing by generic handlers (cuts, histograms, etc) with no cost then.