15#ifndef ALICEO2_BASE_DETECTOR_H_
16#define ALICEO2_BASE_DETECTOR_H_
19#include <tbb/concurrent_unordered_map.h>
21#include <initializer_list>
24#include "FairDetector.h"
25#include "FairRootManager.h"
42#include <fairmq/FwdDecls.h>
68 void Medium(Int_t numed,
const char*
name, Int_t nmat, Int_t isvol, Int_t ifield,
Float_t fieldm,
73 void SpecialCuts(Int_t numed,
const std::initializer_list<std::pair<ECut, Float_t>>& parIDValMap);
77 void SpecialProcesses(Int_t numed,
const std::initializer_list<std::pair<EProc, int>>& parIDValMap);
94 mDensityFactor = density;
99 return mDensityFactor;
118 virtual void defineLayer(Int_t nlay, Double_t phi0, Double_t
r, Int_t nladd, Int_t nmod,
119 Double_t lthick = 0., Double_t dthick = 0., UInt_t detType = 0, Int_t buildFlag = 0);
121 virtual void defineLayerTurbo(Int_t nlay, Double_t phi0, Double_t
r, Int_t nladd, Int_t nmod,
122 Double_t
width, Double_t tilt, Double_t lthick = 0., Double_t dthick = 0.,
123 UInt_t detType = 0, Int_t buildFlag = 0);
130 return mgr.getMaterialID(GetName(), imat);
138 return mgr.getMediumID(GetName(), imed);
146 mgr.getMediumIDMappingAsVector(GetName(), mapping);
152 std::string s(GetName());
168 virtual void attachHits(fair::mq::Channel&, fair::mq::Parts&) = 0;
173 std::vector<int>
const& trackoffsets,
174 std::vector<int>
const& nprimaries,
175 std::vector<int>
const& subevtsOrdered) = 0;
180 virtual void mergeHitEntries(TTree& origin, TTree&
target, std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered) = 0;
194 FairDetector::Initialize();
212 [[deprecated(
"Use getHits API on concrete detectors!")]] TClonesArray*
GetCollection(
int iColl)
const final;
233 std::map<int, int> mMapMaterial;
236 std::map<int, int> mMapMedium;
240 static std::vector<int> sDetId2HitBitIndex;
249 std::unique_ptr<
char,
void (*)(
void*)>
res{abi::__cxa_demangle(
name,
nullptr,
nullptr, &status), std::free};
250 return (status == 0) ?
res.get() :
name;
253void attachShmMessage(
void* hitsptr, fair::mq::Channel& channel, fair::mq::Parts& parts,
bool* busy_ptr);
265template <
typename Container>
266void attachTMessage(Container
const& hits, fair::mq::Channel& channel, fair::mq::Parts& parts)
283 if (
auto br =
tree.GetBranch(brname)) {
284 br->SetAddress(
static_cast<void*
>(&
ptr));
288 return tree.Branch(brname,
ptr);
292template <
typename Det>
294 static constexpr bool value =
false;
301template <
typename Det>
314 return std::string();
324 while (
auto hits =
static_cast<Det*
>(
this)->Det::getHits(probe++)) {
325 for (
auto& hit : *hits) {
326 auto iter = indexmapping.find(hit.GetTrackID());
327 hit.SetTrackID(iter->second);
332 void attachHits(fair::mq::Channel& channel, fair::mq::Parts& parts)
override
337 if (
static_cast<Det*
>(
this)->Det::getHits(0) ==
nullptr) {
343 while (
auto hits =
static_cast<Det*
>(
this)->Det::getHits(probe++)) {
359 template <
typename T>
361 std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered)
363 auto originbr = origin.GetBranch(brname.c_str());
365 auto targetdata =
new T;
366 T* incomingdata =
nullptr;
367 originbr->SetAddress(&incomingdata);
369 T* filladdress =
nullptr;
370 if (origin.GetEntries() == 1) {
371 originbr->GetEntry(0);
372 filladdress = incomingdata;
374 Int_t entries = origin.GetEntries();
377 nprimTot += nprimaries[
entry];
382 Int_t idelta1 = nprimTot;
387 Int_t nprim = nprimaries[
index];
389 filladdress = targetdata;
390 originbr->GetEntry(
index);
393 for (
auto& hit : *incomingdata) {
394 const auto oldID = hit.GetTrackID();
396 Int_t
offset = (oldID < nprim) ? idelta0 : idelta1;
397 hit.SetTrackID(oldID +
offset);
400 std::copy(incomingdata->begin(), incomingdata->end(), std::back_inserter(*targetdata));
402 incomingdata =
nullptr;
406 idelta1 += trackoffsets[
index];
411 targetbr->SetAddress(&filladdress);
413 targetbr->ResetAddress();
417 incomingdata =
nullptr;
426 template <
typename T,
typename L>
428 std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries,
429 std::vector<int>
const& subevtsOrdered)
431 auto entries = hitbuffervector.size();
433 auto targetdata =
new T;
434 T* filladdress =
nullptr;
436 filladdress = hitbuffervector[0].get();
442 nprimTot += nprimaries[
entry];
447 int idelta1 = nprimTot;
448 filladdress = targetdata;
453 int nprim = nprimaries[
index];
457 auto incomingdata = hitbuffervector[
index].get();
460 for (
auto& hit : *incomingdata) {
461 const auto oldID = hit.GetTrackID();
463 int offset = (oldID < nprim) ? idelta0 : idelta1;
464 hit.SetTrackID(oldID +
offset);
467 std::copy(incomingdata->begin(), incomingdata->end(), std::back_inserter(*targetdata));
471 idelta1 += trackoffsets[
index];
476 targetbr->SetAddress(&filladdress);
478 targetbr->ResetAddress();
480 hitbuffervector.clear();
481 hitbuffervector = L();
485 void mergeHitEntries(TTree& origin, TTree&
target, std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered)
final
490 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(probe));
492 while (
name.size() > 0) {
493 mergeAndAdjustHits<typename std::remove_pointer<Hit_t>::type>(
name, origin,
target, trackoffsets, nprimaries, subevtsOrdered);
499 void mergeHitEntriesAndFlush(
int eventID, TTree&
target, std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered)
final
504 using Hit_t =
typename std::remove_pointer<decltype(static_cast<Det*>(
this)->Det::getHits(0))>
::type;
506 using Collector_t = tbb::concurrent_unordered_map<int, std::vector<std::vector<std::unique_ptr<Hit_t>>>>;
508 auto iter = hitbufferPtr->find(eventID);
509 if (iter == hitbufferPtr->end()) {
510 LOG(error) <<
"No buffered hits available for event " << eventID;
515 while (
name.size() > 0) {
516 auto& vectorofHitBuffers = (*iter).second[probe];
518 mergeAndAdjustHits<Hit_t>(
name, vectorofHitBuffers,
target, trackoffsets, nprimaries, subevtsOrdered);
531 using Hit_t =
typename std::remove_pointer<decltype(static_cast<Det*>(
this)->Det::getHits(0))>
::type;
532 using Collector_t = tbb::concurrent_unordered_map<int, std::vector<std::vector<std::unique_ptr<Hit_t>>>>;
533 static Collector_t hitcollector;
539 bool* busy =
nullptr;
540 using HitPtr_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(probe));
543 auto copyToBuffer = [
this, eventID](HitPtr_t hitdata, Collector_t& collectbuffer,
int probe) {
544 std::vector<std::vector<std::unique_ptr<Hit_t>>>* hitvector =
nullptr;
546 auto eventIter = collectbuffer.find(eventID);
547 if (eventIter == collectbuffer.end()) {
550 collectbuffer[eventID] = std::vector<std::vector<std::unique_ptr<Hit_t>>>();
552 hitvector = &(collectbuffer[eventID]);
554 if (probe >= hitvector->size()) {
555 hitvector->resize(probe + 1);
558 (*hitvector)[probe].emplace_back(
new Hit_t());
560 *((*hitvector)[probe].back()) = *hitdata;
563 while (
name.size() > 0) {
566 auto hitsptr = decodeTMessage<HitPtr_t>(parts,
index++);
569 copyToBuffer(hitsptr, hitcollector, probe);
574 auto hitsptr = decodeShmMessage<HitPtr_t>(parts,
index++, busy);
576 copyToBuffer(hitsptr, hitcollector, probe);
592 bool* busy =
nullptr;
593 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(probe));
595 while (
name.size() > 0) {
599 auto hitsptr = decodeTMessage<Hit_t>(parts,
index++);
603 br->SetAddress(
static_cast<void*
>(&hitsptr));
610 auto hitsptr = decodeShmMessage<Hit_t>(parts,
index++, busy);
613 br->SetAddress(
static_cast<void*
>(&hitsptr));
631 return new Det(
static_cast<const Det&
>(*
this));
636 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(0));
649 template <
typename Hit_t>
653 static_cast<Det*
>(
this)->Det::mHits =
ptr;
662 using VectorHit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(0));
663 using Hit_t =
typename std::remove_pointer<VectorHit_t>::type::value_type;
668 auto ptr = o2::utils::createSimVector<Hit_t>();
669 more =
static_cast<Det*
>(
this)->Det::setHits(probe,
ptr);
680 static_cast<Det*
>(
this)->Det::createHitBuffers();
683 mShmBusy[
b] = instance.hasSegment() ? (
bool*)instance.getmemblock(
sizeof(
bool)) :
new bool;
698 LOG(info) <<
" BUSY WAITING SIZE ";
702 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(0));
707 auto hits =
static_cast<Hit_t
>(bareptr);
709 static_cast<Det*
>(
this)->Det::setHits(probe, hits);
721 if (instance.hasSegment()) {
void updateHitTrackIndices(std::map< int, int > const &indexmapping) override
void mergeHitEntriesAndFlush(int eventID, TTree &target, std::vector< int > const &trackoffsets, std::vector< int > const &nprimaries, std::vector< int > const &subevtsOrdered) final
std::vector< void * > mCachedPtr[NHITBUFFERS]
pointer to bool in shared mem indicating of IO busy
bool * mShmBusy[NHITBUFFERS]
std::string getHitBranchNames(int probe) const override
static constexpr int NHITBUFFERS
void fillHitBranch(TTree &tr, fair::mq::Parts &parts, int &index) override
void attachHits(fair::mq::Channel &channel, fair::mq::Parts &parts) override
void mergeAndAdjustHits(std::string const &brname, TTree &origin, TTree &target, std::vector< int > const &trackoffsets, std::vector< int > const &nprimaries, std::vector< int > const &subevtsOrdered)
void mergeAndAdjustHits(std::string const &brname, L &hitbuffervector, TTree &target, std::vector< int > const &trackoffsets, std::vector< int > const &nprimaries, std::vector< int > const &subevtsOrdered)
char * mHitCollectorBufferPtr
bool setHits(int i, std::vector< Hit_t > *ptr)
FairModule * CloneModule() const final
void initializeLate() final
void mergeHitEntries(TTree &origin, TTree &target, std::vector< int > const &trackoffsets, std::vector< int > const &nprimaries, std::vector< int > const &subevtsOrdered) final
ClassDefOverride(DetImpl, 0)
pointer to hit (collector) buffer location (strictly internal)
void collectHits(int eventID, fair::mq::Parts &parts, int &index) override
virtual std::string getHitBranchNames(int probe) const =0
void SpecialProcess(Int_t numed, EProc parID, int val)
Set process by name and value.
int registerSensitiveVolumeAndGetVolID(std::string const &name)
~Detector() override
Default Destructor.
static std::vector< int > const & getDetId2HitBitIndex()
virtual void initializeLate()=0
Detector & operator=(const Detector &)
virtual void defineLayerTurbo(Int_t nlay, Double_t phi0, Double_t r, Int_t nladd, Int_t nmod, Double_t width, Double_t tilt, Double_t lthick=0., Double_t dthick=0., UInt_t detType=0, Int_t buildFlag=0)
TClonesArray * GetCollection(int iColl) const final
virtual void attachHits(fair::mq::Channel &, fair::mq::Parts &)=0
virtual void fillParallelWorld() const
fill parallel geometry with sensitive volumes of detector
int getMaterialID(int imat) const
void getMediumIDMappingAsVector(std::vector< int > &mapping)
static void setDensityFactor(Float_t density)
void SpecialCuts(Int_t numed, const std::initializer_list< std::pair< ECut, Float_t > > &parIDValMap)
Custom processes and transport cuts.
void SpecialCut(Int_t numed, ECut parID, Float_t val)
Set cut by name and value.
void SpecialProcesses(Int_t numed, const std::initializer_list< std::pair< EProc, int > > &parIDValMap)
void Matrix(Int_t &nmat, Float_t theta1, Float_t phi1, Float_t theta2, Float_t phi2, Float_t theta3, Float_t phi3) const
Detector()
Default Constructor.
virtual void setNumberOfWrapperVolumes(Int_t n)
Books arrays for wrapper volumes.
virtual void updateHitTrackIndices(std::map< int, int > const &)=0
virtual void mergeHitEntries(TTree &origin, TTree &target, std::vector< int > const &trackoffsets, std::vector< int > const &nprimaries, std::vector< int > const &subevtsOrdered)=0
void Mixture(Int_t imat, const char *name, Float_t *a, Float_t *z, Float_t dens, Int_t nlmat, Float_t *wmat)
virtual void addAlignableVolumes() const
declare alignable volumes of detector
void Medium(Int_t numed, const char *name, Int_t nmat, Int_t isvol, Int_t ifield, Float_t fieldm, Float_t tmaxfd, Float_t stemax, Float_t deemax, Float_t epsil, Float_t stmin, Float_t *ubuf=nullptr, Int_t nbuf=0)
void SetSpecialPhysicsCuts() override
static Float_t getDensityFactor()
int getMediumID(int imed) const
virtual void fillHitBranch(TTree &tr, fair::mq::Parts &parts, int &index)=0
static void setDetId2HitBitIndex(std::vector< int > const &v)
set the DetID to HitBitIndex mapping. Succeeds if not already set.
static void initFieldTrackingParams(int &mode, float &maxfield)
virtual void defineWrapperVolume(Int_t id, Double_t rmin, Double_t rmax, Double_t zspan)
Sets per wrapper volume parameters.
virtual void defineLayer(Int_t nlay, Double_t phi0, Double_t r, Int_t nladd, Int_t nmod, Double_t lthick=0., Double_t dthick=0., UInt_t detType=0, Int_t buildFlag=0)
virtual void mergeHitEntriesAndFlush(int eventID, TTree &target, std::vector< int > const &trackoffsets, std::vector< int > const &nprimaries, std::vector< int > const &subevtsOrdered)=0
void Material(Int_t imat, const char *name, Float_t a, Float_t z, Float_t dens, Float_t radl, Float_t absl, Float_t *buf=nullptr, Int_t nwbuf=0)
std::string addNameTo(const char *ext) const
virtual void InitializeO2Detector()=0
virtual void collectHits(int eventID, fair::mq::Parts &parts, int &index)=0
static MaterialManager & Instance()
static ShmManager & Instance()
bool isOperational() const
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLint GLint GLsizei GLint GLenum GLenum type
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean GLboolean GLboolean GLboolean a
GLenum GLuint GLenum GLsizei const GLchar * buf
GLdouble GLdouble GLdouble z
void attachShmMessage(void *hitsptr, fair::mq::Channel &channel, fair::mq::Parts &parts, bool *busy_ptr)
void * decodeTMessageCore(fair::mq::Parts &dataparts, int index)
T decodeShmMessage(fair::mq::Parts &dataparts, int index, bool *&busy)
TBranch * getOrMakeBranch(TTree &tree, const char *brname, T *ptr)
void attachMessageBufferToParts(fair::mq::Parts &parts, fair::mq::Channel &channel, void *data, TClass *cl)
void attachTMessage(Container const &hits, fair::mq::Channel &channel, fair::mq::Parts &parts)
void * decodeShmCore(fair::mq::Parts &dataparts, int index, bool *&busy)
std::string demangle(const char *name)
utility function to demangle cxx type names
void attachDetIDHeaderMessage(int id, fair::mq::Channel &channel, fair::mq::Parts &parts)
T decodeTMessage(fair::mq::Parts &dataparts, int index)
void freeSimVector(std::vector< T > *ptr)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::unique_ptr< TTree > tree((TTree *) flIn.Get(std::string(o2::base::NameConf::CTFTREENAME).c_str()))