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"
43#include <fairmq/FwdDecls.h>
69 void Medium(Int_t numed,
const char*
name, Int_t nmat, Int_t isvol, Int_t ifield,
Float_t fieldm,
74 void SpecialCuts(Int_t numed,
const std::initializer_list<std::pair<ECut, Float_t>>& parIDValMap);
78 void SpecialProcesses(Int_t numed,
const std::initializer_list<std::pair<EProc, int>>& parIDValMap);
90 void Matrix(Int_t& nmat, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2, Double_t theta3,
95 mDensityFactor = density;
100 return mDensityFactor;
119 virtual void defineLayer(Int_t nlay, Double_t phi0, Double_t
r, Int_t nladd, Int_t nmod,
120 Double_t lthick = 0., Double_t dthick = 0., UInt_t detType = 0, Int_t buildFlag = 0);
122 virtual void defineLayerTurbo(Int_t nlay, Double_t phi0, Double_t
r, Int_t nladd, Int_t nmod,
123 Double_t
width, Double_t tilt, Double_t lthick = 0., Double_t dthick = 0.,
124 UInt_t detType = 0, Int_t buildFlag = 0);
131 return mgr.getMaterialID(GetName(), imat);
139 return mgr.getMediumID(GetName(), imed);
147 mgr.getMediumIDMappingAsVector(GetName(), mapping);
153 std::string s(GetName());
171 const auto iter = indexmapping.find(trackID);
172 return iter != indexmapping.end() ? iter->second : -1;
178 static int offsetTrackIndex(
int trackID,
int nprimaries,
int primaryOffset,
int secondaryOffset)
183 return trackID + (trackID < nprimaries ? primaryOffset : secondaryOffset);
188 virtual void attachHits(fair::mq::Channel&, fair::mq::Parts&) = 0;
193 std::vector<int>
const& trackoffsets,
194 std::vector<int>
const& nprimaries,
195 std::vector<int>
const& subevtsOrdered) = 0;
200 virtual void mergeHitEntries(TTree&
origin, TTree&
target, std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered) = 0;
214 FairDetector::Initialize();
232 [[deprecated(
"Use getHits API on concrete detectors!")]] TClonesArray*
GetCollection(
int iColl)
const final;
253 std::map<int, int> mMapMaterial;
256 std::map<int, int> mMapMedium;
260 static std::vector<int> sDetId2HitBitIndex;
269 std::unique_ptr<
char,
void (*)(
void*)>
res{abi::__cxa_demangle(
name,
nullptr,
nullptr, &status), std::free};
270 return (status == 0) ?
res.get() :
name;
288template <
typename Container>
289void attachTMessage(Container
const& hits, fair::mq::Channel& channel, fair::mq::Parts& parts)
312 if (
auto br =
tree.GetBranch(brname)) {
313 br->SetAddress(
static_cast<void*
>(&
ptr));
317 return tree.Branch(brname,
ptr);
321template <
typename Det>
323 static constexpr bool value =
false;
330template <
typename Det>
343 return std::string();
353 while (
auto hits =
static_cast<Det*
>(
this)->Det::getHits(probe++)) {
354 for (
auto& hit : *hits) {
360 void attachHits(fair::mq::Channel& channel, fair::mq::Parts& parts)
override
365 if (
static_cast<Det*
>(
this)->Det::getHits(0) ==
nullptr) {
373 while (
auto hits =
static_cast<Det*
>(
this)->Det::getHits(probe++)) {
389 template <
typename T>
391 std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered)
393 auto originbr =
origin.GetBranch(brname.c_str());
395 auto targetdata =
new T;
396 T* incomingdata =
nullptr;
397 originbr->SetAddress(&incomingdata);
399 T* filladdress =
nullptr;
400 if (
origin.GetEntries() == 1) {
401 originbr->GetEntry(0);
402 filladdress = incomingdata;
407 nprimTot += nprimaries[
entry];
412 Int_t idelta1 = nprimTot;
417 Int_t nprim = nprimaries[
index];
419 filladdress = targetdata;
420 originbr->GetEntry(
index);
423 for (
auto& hit : *incomingdata) {
424 hit.SetTrackID(
offsetTrackIndex(hit.GetTrackID(), nprim, idelta0, idelta1));
427 std::copy(incomingdata->begin(), incomingdata->end(), std::back_inserter(*targetdata));
429 incomingdata =
nullptr;
433 idelta1 += trackoffsets[
index];
438 targetbr->SetAddress(&filladdress);
440 targetbr->ResetAddress();
444 incomingdata =
nullptr;
453 template <
typename T,
typename L>
455 std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries,
456 std::vector<int>
const& subevtsOrdered)
458 auto entries = hitbuffervector.size();
461 T* filladdress =
nullptr;
463 filladdress = hitbuffervector[0].get();
470 nprimTot += nprimaries[
entry];
471 nhits += hitbuffervector[
entry] ? hitbuffervector[
entry]->size() : 0;
473 targetdata.reserve(nhits);
477 int idelta1 = nprimTot;
478 filladdress = &targetdata;
483 int nprim = nprimaries[
index];
487 auto incomingdata = hitbuffervector[
index].get();
490 for (
auto& hit : *incomingdata) {
491 hit.SetTrackID(
offsetTrackIndex(hit.GetTrackID(), nprim, idelta0, idelta1));
494 targetdata.insert(targetdata.end(), std::make_move_iterator(incomingdata->begin()), std::make_move_iterator(incomingdata->end()));
498 idelta1 += trackoffsets[
index];
503 targetbr->SetAddress(&filladdress);
505 targetbr->ResetAddress();
506 hitbuffervector = L();
509 void mergeHitEntries(TTree&
origin, TTree&
target, std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered)
final
514 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(probe));
516 while (
name.size() > 0) {
517 mergeAndAdjustHits<typename std::remove_pointer<Hit_t>::type>(
name,
origin,
target, trackoffsets, nprimaries, subevtsOrdered);
526 using Hit_t =
typename std::remove_pointer<decltype(static_cast<Det*>(
this)->Det::getHits(0))>
::type;
527 using Collector_t = tbb::concurrent_unordered_map<int, std::vector<std::vector<std::unique_ptr<Hit_t>>>>;
534 void mergeHitEntriesAndFlush(
int eventID, TTree&
target, std::vector<int>
const& trackoffsets, std::vector<int>
const& nprimaries, std::vector<int>
const& subevtsOrdered)
final
539 using Hit_t =
typename std::remove_pointer<decltype(static_cast<Det*>(
this)->Det::getHits(0))>
::type;
542 auto iter = collector.find(eventID);
543 if (iter == collector.end()) {
544 LOG(error) <<
"No buffered hits available for event " << eventID;
549 while (
name.size() > 0) {
550 auto& vectorofHitBuffers = (*iter).second[probe];
552 mergeAndAdjustHits<Hit_t>(
name, vectorofHitBuffers,
target, trackoffsets, nprimaries, subevtsOrdered);
565 using Hit_t =
typename std::remove_pointer<decltype(static_cast<Det*>(
this)->Det::getHits(0))>
::type;
570 using HitPtr_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(probe));
574 auto store = [eventID, &hitcollector](std::unique_ptr<Hit_t> hits,
int probe) {
575 auto& hitvector = hitcollector[eventID];
576 if (probe >= hitvector.size()) {
577 hitvector.resize(probe + 1);
579 hitvector[probe].emplace_back(std::move(hits));
582 while (
name.size() > 0) {
585 if (
auto hitsptr = decodeTMessage<HitPtr_t>(parts,
index++)) {
586 store(std::unique_ptr<Hit_t>(hitsptr), probe);
590 auto hitsptr = decodeShmMessage<HitPtr_t>(parts,
index++, busy);
591 store(std::make_unique<Hit_t>(*hitsptr), probe);
608 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(probe));
610 while (
name.size() > 0) {
614 auto hitsptr = decodeTMessage<Hit_t>(parts,
index++);
618 br->SetAddress(
static_cast<void*
>(&hitsptr));
625 auto hitsptr = decodeShmMessage<Hit_t>(parts,
index++, busy);
628 br->SetAddress(
static_cast<void*
>(&hitsptr));
646 return new Det(
static_cast<const Det&
>(*
this));
651 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(0));
664 template <
typename Hit_t>
668 static_cast<Det*
>(
this)->Det::mHits =
ptr;
677 using VectorHit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(0));
678 using Hit_t =
typename std::remove_pointer<VectorHit_t>::type::value_type;
683 auto ptr = o2::utils::createSimVector<Hit_t>();
684 more =
static_cast<Det*
>(
this)->Det::setHits(probe,
ptr);
695 static_cast<Det*
>(
this)->Det::createHitBuffers();
712 LOG(info) <<
" BUSY WAITING SIZE ";
716 using Hit_t =
decltype(
static_cast<Det*
>(
this)->Det::getHits(0));
721 auto hits =
static_cast<Hit_t
>(bareptr);
723 static_cast<Det*
>(
this)->Det::setHits(probe, hits);
735 if (instance.hasSegment()) {
header::DataOrigin origin
std::vector< long > entries
void updateHitTrackIndices(std::map< int, int > const &indexmapping) override
std::shared_ptr< void > mHitCollector
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 flag in shared mem indicating of IO busy
std::string getHitBranchNames(int probe) const override
void collectHits(int eventID, fair::mq::Parts &parts, int &index, bool shm) 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)
bool setHits(int i, std::vector< Hit_t > *ptr)
ShmBusyFlag * mShmBusy[NHITBUFFERS]
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)
type-erased hit buffers of this instance in the hit merger (see hitCollector())
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, Double_t theta1, Double_t phi1, Double_t theta2, Double_t phi2, Double_t theta3, Double_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
virtual void collectHits(int eventID, fair::mq::Parts &parts, int &index, bool shm)=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
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 * decodeShmCore(fair::mq::Parts &dataparts, int index, ShmBusyFlag *&busy)
void attachShmMessage(void *hitsptr, fair::mq::Channel &channel, fair::mq::Parts &parts, ShmBusyFlag *busy_ptr)
void * decodeTMessageCore(fair::mq::Parts &dataparts, int index)
std::atomic< bool > ShmBusyFlag
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 attachHitsHeaderMessage(HitsHeader const &header, fair::mq::Channel &channel, fair::mq::Parts &parts)
std::string demangle(const char *name)
utility function to demangle cxx type names
T decodeShmMessage(fair::mq::Parts &dataparts, int index, ShmBusyFlag *&busy)
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()))