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());
170 const auto iter = indexmapping.find(trackID);
171 return iter != indexmapping.end() ? iter->second : -1;
177 static int offsetTrackIndex(
int trackID,
int nprimaries,
int primaryOffset,
int secondaryOffset)
182 return trackID + (trackID < nprimaries ? primaryOffset : secondaryOffset);
187 virtual void attachHits(fair::mq::Channel&, fair::mq::Parts&) = 0;
192 std::vector<int>
const& trackoffsets,
193 std::vector<int>
const& nprimaries,
194 std::vector<int>
const& subevtsOrdered) = 0;
199 virtual void mergeHitEntries(TTree&
origin, TTree&
target, std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered) = 0;
213 FairDetector::Initialize();
231 [[deprecated(
"Use getHits API on concrete detectors!")]] TClonesArray*
GetCollection(
int iColl)
const final;
252 std::map<int, int> mMapMaterial;
255 std::map<int, int> mMapMedium;
259 static std::vector<int> sDetId2HitBitIndex;
268 std::unique_ptr<
char,
void (*)(
void*)>
res{abi::__cxa_demangle(
name,
nullptr,
nullptr, &status), std::free};
269 return (status == 0) ?
res.get() :
name;
272void attachShmMessage(
void* hitsptr, fair::mq::Channel& channel, fair::mq::Parts& parts,
bool* busy_ptr);
284template <
typename Container>
285void attachTMessage(Container
const& hits, fair::mq::Channel& channel, fair::mq::Parts& parts)
302 if (
auto br =
tree.GetBranch(brname)) {
303 br->SetAddress(
static_cast<void*
>(&
ptr));
307 return tree.Branch(brname,
ptr);
311template <
typename Det>
313 static constexpr bool value =
false;
320template <
typename Det>
333 return std::string();
343 while (
auto hits =
static_cast<Det*
>(
this)->Det::getHits(probe++)) {
344 for (
auto& hit : *hits) {
350 void attachHits(fair::mq::Channel& channel, fair::mq::Parts& parts)
override
355 if (
static_cast<Det*
>(
this)->Det::getHits(0) ==
nullptr) {
361 while (
auto hits =
static_cast<Det*
>(
this)->Det::getHits(probe++)) {
377 template <
typename T>
379 std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered)
381 auto originbr =
origin.GetBranch(brname.c_str());
383 auto targetdata =
new T;
384 T* incomingdata =
nullptr;
385 originbr->SetAddress(&incomingdata);
387 T* filladdress =
nullptr;
388 if (
origin.GetEntries() == 1) {
389 originbr->GetEntry(0);
390 filladdress = incomingdata;
392 Int_t entries =
origin.GetEntries();
395 nprimTot += nprimaries[
entry];
400 Int_t idelta1 = nprimTot;
405 Int_t nprim = nprimaries[
index];
407 filladdress = targetdata;
408 originbr->GetEntry(
index);
411 for (
auto& hit : *incomingdata) {
412 hit.SetTrackID(
offsetTrackIndex(hit.GetTrackID(), nprim, idelta0, idelta1));
415 std::copy(incomingdata->begin(), incomingdata->end(), std::back_inserter(*targetdata));
417 incomingdata =
nullptr;
421 idelta1 += trackoffsets[
index];
426 targetbr->SetAddress(&filladdress);
428 targetbr->ResetAddress();
432 incomingdata =
nullptr;
441 template <
typename T,
typename L>
443 std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries,
444 std::vector<int>
const& subevtsOrdered)
446 auto entries = hitbuffervector.size();
448 auto targetdata =
new T;
449 T* filladdress =
nullptr;
451 filladdress = hitbuffervector[0].get();
457 nprimTot += nprimaries[
entry];
462 int idelta1 = nprimTot;
463 filladdress = targetdata;
468 int nprim = nprimaries[
index];
472 auto incomingdata = hitbuffervector[
index].get();
475 for (
auto& hit : *incomingdata) {
476 hit.SetTrackID(
offsetTrackIndex(hit.GetTrackID(), nprim, idelta0, idelta1));
479 std::copy(incomingdata->begin(), incomingdata->end(), std::back_inserter(*targetdata));
483 idelta1 += trackoffsets[
index];
488 targetbr->SetAddress(&filladdress);
490 targetbr->ResetAddress();
492 hitbuffervector.clear();
493 hitbuffervector = L();
497 void mergeHitEntries(TTree&
origin, TTree&
target, std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered)
final
502 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(probe));
504 while (
name.size() > 0) {
505 mergeAndAdjustHits<typename std::remove_pointer<Hit_t>::type>(
name,
origin,
target, trackoffsets, nprimaries, subevtsOrdered);
511 void mergeHitEntriesAndFlush(
int eventID, TTree&
target, std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered)
final
516 using Hit_t =
typename std::remove_pointer<decltype(static_cast<Det*>(
this)->Det::getHits(0))>
::type;
518 using Collector_t = tbb::concurrent_unordered_map<int, std::vector<std::vector<std::unique_ptr<Hit_t>>>>;
520 auto iter = hitbufferPtr->find(eventID);
521 if (iter == hitbufferPtr->end()) {
522 LOG(error) <<
"No buffered hits available for event " << eventID;
527 while (
name.size() > 0) {
528 auto& vectorofHitBuffers = (*iter).second[probe];
530 mergeAndAdjustHits<Hit_t>(
name, vectorofHitBuffers,
target, trackoffsets, nprimaries, subevtsOrdered);
543 using Hit_t =
typename std::remove_pointer<decltype(static_cast<Det*>(
this)->Det::getHits(0))>
::type;
544 using Collector_t = tbb::concurrent_unordered_map<int, std::vector<std::vector<std::unique_ptr<Hit_t>>>>;
551 static tbb::concurrent_unordered_map<void const*, Collector_t> hitcollectors;
552 auto& hitcollector = hitcollectors[
this];
556 bool* busy =
nullptr;
557 using HitPtr_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(probe));
560 auto copyToBuffer = [
this, eventID](HitPtr_t hitdata, Collector_t& collectbuffer,
int probe) {
561 std::vector<std::vector<std::unique_ptr<Hit_t>>>* hitvector =
nullptr;
563 auto eventIter = collectbuffer.find(eventID);
564 if (eventIter == collectbuffer.end()) {
567 collectbuffer[eventID] = std::vector<std::vector<std::unique_ptr<Hit_t>>>();
569 hitvector = &(collectbuffer[eventID]);
571 if (probe >= hitvector->size()) {
572 hitvector->resize(probe + 1);
575 (*hitvector)[probe].emplace_back(
new Hit_t());
577 *((*hitvector)[probe].back()) = *hitdata;
580 while (
name.size() > 0) {
583 auto hitsptr = decodeTMessage<HitPtr_t>(parts,
index++);
586 copyToBuffer(hitsptr, hitcollector, probe);
591 auto hitsptr = decodeShmMessage<HitPtr_t>(parts,
index++, busy);
593 copyToBuffer(hitsptr, hitcollector, probe);
609 bool* busy =
nullptr;
610 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(probe));
612 while (
name.size() > 0) {
616 auto hitsptr = decodeTMessage<Hit_t>(parts,
index++);
620 br->SetAddress(
static_cast<void*
>(&hitsptr));
627 auto hitsptr = decodeShmMessage<Hit_t>(parts,
index++, busy);
630 br->SetAddress(
static_cast<void*
>(&hitsptr));
648 return new Det(
static_cast<const Det&
>(*
this));
653 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(0));
666 template <
typename Hit_t>
670 static_cast<Det*
>(
this)->Det::mHits =
ptr;
679 using VectorHit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(0));
680 using Hit_t =
typename std::remove_pointer<VectorHit_t>::type::value_type;
685 auto ptr = o2::utils::createSimVector<Hit_t>();
686 more =
static_cast<Det*
>(
this)->Det::setHits(probe,
ptr);
697 static_cast<Det*
>(
this)->Det::createHitBuffers();
700 mShmBusy[
b] = instance.hasSegment() ? (
bool*)instance.getmemblock(
sizeof(
bool)) :
new bool;
715 LOG(info) <<
" BUSY WAITING SIZE ";
719 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(0));
724 auto hits =
static_cast<Hit_t
>(bareptr);
726 static_cast<Det*
>(
this)->Det::setHits(probe, hits);
738 if (instance.hasSegment()) {
header::DataOrigin origin
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)
static int updatedTrackIndex(std::map< int, int > const &indexmapping, int trackID)
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
static int offsetTrackIndex(int trackID, int nprimaries, int primaryOffset, int secondaryOffset)
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()))