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.

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):

  • 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”:

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):

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:

_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:

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:

// 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<event::StwTDCHit>(did, evRef, "STRAW");
// Allocate and put new MC truth hit info into common hit
stwTDCHit.mcInfo = _lmem->create<StwMCInfo>(*_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:

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.