33#include <FairRootManager.h>
34#include <FairRunAna.h>
35#include <FairRuntimeDb.h>
40#include <TClonesArray.h>
41#include <TDatabasePDG.h>
42#include <TGenericClassInfo.h>
43#include <TGeoManager.h>
47#include <TParameter.h>
48#include <TParticlePDG.h>
85 for (
unsigned int i = 0; i <
fHistList.size(); i++) {
138 FairRunAna* ana = FairRunAna::Instance();
140 LOG(fatal) <<
"No FairRunAna instance";
143 FairRuntimeDb* rtdb = ana->GetRuntimeDb();
145 LOG(fatal) <<
"No FairRuntimeDb instance";
167 TObjArray* topNodes = gGeoManager->GetTopNode()->GetNodes();
168 for (Int_t iTopNode = 0; iTopNode < topNodes->GetEntriesFast(); iTopNode++) {
169 TGeoNode* topNode =
static_cast<TGeoNode*
>(topNodes->At(iTopNode));
170 if (TString(topNode->GetName()).Contains(
"trd")) {
178 LOG(info) <<
"TRD is not in the setup, do nothing";
185 LOG(error) <<
"No CbmTrdParSetDigi container in FairRuntimeDb";
190 LOG(error) <<
"No CbmTrdParSetGeo container in FairRuntimeDb";
194 FairRootManager* manager = FairRootManager::Instance();
200 LOG(error) <<
"No time slice found";
204 fHits =
dynamic_cast<TClonesArray*
>(manager->GetObject(
"TrdHit"));
207 LOG(error) <<
"No TRD hit array found";
211 fClusters =
dynamic_cast<TClonesArray*
>(manager->GetObject(
"TrdCluster"));
214 LOG(error) <<
"No TRD cluster array found";
227 fHitMatches =
dynamic_cast<TClonesArray*
>(manager->GetObject(
"TrdHitMatch"));
233 LOG(error) <<
": No MCEventList data!";
238 LOG(error) <<
"No MC tracks found";
243 LOG(error) <<
"No MC points found";
248 LOG(error) <<
"No TRD hit matches found";
253 LOG(error) <<
"No TRD digi matches found";
263 Int_t layerCounter = 0;
264 TObjArray* topNodes = gGeoManager->GetTopNode()->GetNodes();
265 for (Int_t iTopNode = 0; iTopNode < topNodes->GetEntriesFast(); iTopNode++) {
266 TGeoNode* topNode =
static_cast<TGeoNode*
>(topNodes->At(iTopNode));
267 if (TString(topNode->GetName()).Contains(
"trd")) {
268 TObjArray* layers = topNode->GetNodes();
269 for (Int_t iLayer = 0; iLayer < layers->GetEntriesFast(); iLayer++) {
270 TGeoNode* layer =
static_cast<TGeoNode*
>(layers->At(iLayer));
271 if (TString(layer->GetName()).Contains(
"layer")) {
283 LOG(error) <<
"can not count TRD tracking stations";
288 fHitsMc =
new TClonesArray(
"CbmTrdHitMC", 100);
289 manager->Register(
"TrdHitMC",
"TRD",
fHitsMc, IsOutputBranchPersistent(
"TrdHitMC"));
294 gStyle->SetOptStat(0);
299 for (
unsigned int i = 0; i <
fHistList.size(); i++) {
316 Form(
"MC Points per Hit: Station %i;N mc points / hit", i), 10, -0.5, 9.5);
325 Form(
"Hits per MC Point: Station %i; N hits / mc point", i), 10, -0.5, 9.5);
336 double dr =
sqrt(dx * dx + dy * dy);
338 fhEfficiencyR.emplace_back(Form(
"hEfficiencyR%i", i), Form(
"Efficiency R: Station %i;R [cm]", i), 100, 0, dr);
343 fhEfficiencyXY.emplace_back(Form(
"hEfficiencyXY%i", i), Form(
"Efficiency XY: Station %i;X [cm];Y [cm]", i), 50, -dx,
390 LOG(debug) <<
"Event: " <<
fNevents.GetVal();
398 FairSink* sink = FairRootManager::Instance()->GetSink();
400 sink->WriteObject(&
GetQa(),
nullptr);
420 LOG(fatal) <<
" No Geo params for station " << iStation <<
" module " << ModuleId <<
" found ";
424 double staZ = pGeo->
GetZ();
427 if ((iStation > 0) && (staZ <= lastZ)) {
428 LOG(error) <<
"TRD trackig stations are not properly ordered in Z";
448 Int_t nHits =
fHits->GetEntriesFast();
449 Int_t nClusters =
fClusters->GetEntriesFast();
457 std::vector<std::vector<int>> pointNhits;
458 pointNhits.resize(nMcEvents);
459 for (
int iE = 0; iE < nMcEvents; iE++) {
463 pointNhits[iE].resize(nPoints, 0);
466 for (Int_t iHit = 0; iHit < nHits; iHit++) {
470 LOG(error) <<
"TRD hit N " << iHit <<
" doesn't exist";
478 LOG(error) <<
"Unknown detector class type " << hit->
GetClassType() <<
" for TRD hit N " << iHit;
486 LOG(fatal) <<
"TRD hit layer id " << StationIndex <<
" is out of range";
491 if (clusterId < 0 || clusterId >= nClusters) {
492 LOG(error) <<
"TRD cluster id " << clusterId <<
" is out of range";
498 LOG(error) <<
"TRD cluster N " << clusterId <<
" doesn't exist";
503 LOG(error) <<
"TRD hit address " << address <<
" differs from its cluster address " << cluster->
GetAddress();
509 if (nClusterDigis <= 0) {
510 LOG(error) <<
"hit match for TRD cluster " << clusterId <<
" has no digis ";
521 for (Int_t iDigi = 0; iDigi < nClusterDigis; iDigi++) {
522 Int_t digiIdx = cluster->
GetDigi(iDigi);
523 if (digiIdx < 0 || digiIdx >= nDigis) {
524 LOG(fatal) <<
"TRD cluster: digi index " << digiIdx <<
" out of range ";
529 LOG(fatal) <<
"TRD digi " << iDigi <<
" not found";
534 std::stringstream ss;
535 ss <<
"TRD hit address " << address <<
" differs from its digi address " << digi->
GetAddressModule();
537 LOG(error) << ss.str();
545 if (!tdigi) tdigi = digi->
GetTime();
547 default: LOG(fatal) <<
"TRD digi type neither SPADIC or FASP";
return;
553 LOG(fatal) <<
"TRD digi match " << digiIdx <<
" not found";
568 if (hitMatch ==
nullptr) {
569 std::stringstream ss;
570 ss <<
"hit match for TRD hit " << iHit <<
" doesn't exist";
572 LOG(error) << ss.str();
577 std::stringstream ss;
578 ss <<
"hit match for TRD hit " << iHit <<
" doesn't correspond to digi matches";
580 LOG(error) << ss.str();
588 for (
int i = 0; i < myHitMatch.
GetNofLinks(); i++) {
593 if (iE < 0 || iE >= nMcEvents) {
594 std::stringstream ss;
595 ss <<
"link points to a non-existing MC event";
597 LOG(error) << ss.str();
600 if (link.
GetIndex() >= (
int) pointNhits[iE].size()) {
601 std::stringstream ss;
602 ss <<
"link points to a non-existing MC index";
604 LOG(error) << ss.str();
617 std::stringstream ss;
618 ss <<
"hit from noise [INFO]";
625 std::stringstream ss;
626 ss <<
"link points to a non-existing MC point";
628 LOG(error) << ss.str();
633 std::stringstream ss;
634 ss <<
"mc point module address differs from the hit module address";
636 LOG(error) << ss.str();
648 LOG(fatal) <<
" No Geo params for station " << StationIndex <<
" module " << ModuleId <<
" found ";
652 double staZ = pGeo->
GetZ();
653 if ((staZ < p->GetZIn() - 1.) || (staZ > p->
GetZOut() + 1.)) {
654 std::stringstream ss;
655 ss <<
"TRD station " << StationIndex <<
": active material Z[" << p->
GetZIn() <<
" cm," << p->
GetZOut()
656 <<
" cm] is too far from the nominal station Z " << staZ <<
" cm";
658 LOG(error) << ss.str();
662 if (fabs(hit->
GetZ() - staZ) > 1.) {
663 std::stringstream ss;
664 ss <<
"TRD station " << StationIndex <<
": hit Z " << hit->
GetZ()
665 <<
" cm, is too far from the nominal station Z " << staZ <<
" cm";
667 LOG(error) << ss.str();
674 if (nHitPoints != 1) {
675 std::stringstream ss;
676 ss <<
"hit from mixed hit [INFO] nPoints=" << nHitPoints;
683 std::stringstream ss;
684 ss <<
"MC event time doesn't exist for a TRD link";
686 LOG(error) << ss.str();
690 double x = p->GetX();
691 double y = p->GetY();
692 double z = p->GetZ();
693 double t = t0 + p->GetTime();
694 double px = p->GetPx();
695 double py = p->GetPy();
696 double pz = p->GetPz();
699 if (fabs(p->
GetPzOut()) < 0.01)
continue;
702 double dz = hit->
GetZ() - z;
710 CbmLink mcTrackLink = bestLink;
711 mcTrackLink.
SetIndex(p->GetTrackID());
714 std::stringstream ss;
715 ss <<
"MC track " << p->GetTrackID() <<
" doesn't exist";
717 LOG(error) << ss.str();
721 if (pdg < 9999999 && ((TParticlePDG*) TDatabasePDG::Instance()->GetParticle(pdg))) {
722 mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
727 constexpr double speedOfLight = 29.979246;
730 t += dz / (pz * speedOfLight) *
sqrt(mass * mass + mom3.Mag2());
732 double du = hit->
GetX() -
x;
733 double dv = hit->
GetY() -
y;
734 double dt = hit->
GetTime() - t;
735 double su = hmc->
GetDx();
736 double sv = hit->
GetDy();
741 if (StationIndex % 2) {
756 if ((su < 1.e-5) || (sv < 1.e-5) || (st < 1.e-5)) {
757 std::stringstream ss;
758 ss <<
"TRD hit errors are not properly set: errX " << hit->
GetDx() <<
" errY " << hit->
GetDy() <<
" errT ";
760 LOG(error) << ss.str();
779 for (
int iE = 0; iE < nMcEvents; iE++) {
783 for (
int ip = 0; ip < nPoints; ip++) {
786 LOG(error) <<
"MC point doesn't exist";
792 LOG(fatal) <<
"TRD hit layer id " << StationIndex <<
" for module " << address <<
" is out of range";
796 fhEfficiencyR[StationIndex].Fill(
sqrt(p->GetX() * p->GetX() + p->GetY() * p->GetY()), (pointNhits[iE][ip] > 0));
797 fhEfficiencyXY[StationIndex].Fill(p->GetX(), p->GetY(), (pointNhits[iE][ip] > 0));
806 gStyle->SetPaperSize(20, 20);
821 for (UInt_t i = 0; i <
fHistList.size(); i++) {
825 for (UInt_t i = 0; i < 6; i++) {
@ kTrd
Transition Radiation Detector.
Definition of the CbmQaCanvas class.
Useful utilities for CBM QA tasks.
ClassImp(CbmTrdCalibTracker)
Data Container for TRD clusters.
Class for hits in TRD detector.
friend fvec sqrt(const fvec &a)
int32_t GetAddress() const
int32_t GetDigi(int32_t index) const
Get digi at position index.
int32_t GetNofDigis() const
Number of digis in cluster.
static Int_t GetNofDigis(ECbmModuleId systemId)
static Bool_t IsMatchPresent(ECbmModuleId systemId)
Presence of a digi match branch.
InitStatus Init()
Initialisation.
const Digi * Get(Int_t index) const
Get a digi object.
static CbmDigiManager * Instance()
Static instance.
const CbmMatch * GetMatch(ECbmModuleId systemId, UInt_t index) const
Get a match object.
double GetTimeError() const
int32_t GetAddress() const
void SetIndex(int32_t index)
TObject * Get(const CbmLink *lnk)
Int_t Size(Int_t fileNumber, Int_t eventNumber)
Task class creating and managing CbmMCDataArray objects.
CbmMCDataArray * InitBranch(const char *name)
Container class for MC events with number, file and start time.
int32_t GetFileIdByIndex(uint32_t index)
File number by index @value File number for event at given index in list.
int32_t GetEventIdByIndex(uint32_t index)
Event number by index @value Event number for event at given index in list.
Int_t GetEventIndex(UInt_t event, UInt_t file)
Event index.
std::size_t GetNofEvents() const
Number of events in the list @value Number of events.
double GetEventTime(uint32_t event, uint32_t file)
Event start time.
int32_t GetPdgCode() const
void AddLinks(const CbmMatch &match)
const CbmLink & GetLink(int32_t i) const
int32_t GetNofLinks() const
const CbmLink & GetMatchedLink() const
void Divide2D(int nPads)
Divide canvas into nPads in 2D in a nice way.
Bookkeeping of time-slice content.
static uint32_t GetLayerId(uint32_t address)
Return layer ID from address.
static uint32_t GetModuleAddress(uint32_t address)
Return unique module ID from address.
std::vector< CbmQaHist< TH1D > * > fHistList
List of the above histogramms.
CbmQaHist< TH1D > fh1DpullV
CbmQaHist< TH1D > fh2DresidualY
TClonesArray * fClusters
Data.
CbmQaHist< TH1D > fh2DresidualX
CbmQaCanvas fCanvPointsPerHit
CbmMCDataArray * fMcTracks
std::vector< CbmQaHist< TH1I > > fhHitsPerPoint
hits efficiency
CbmQaHist< TH1D > fh1DpullU
Histogram for PULL Distribution.
CbmTimeSlice * fTimeSlice
CbmQaHist< TH1D > fh1DresidualV
void Finish()
FairTask: Action at end of run. For this task and all of the subtasks.
CbmQaHist< TH1D > fh1DresidualU
number of processed events
TParameter< int > fNevents
subfolder for histograms
std::vector< CbmQaHist< TProfile > > fhEfficiencyR
CbmTrdCalibTracker(const char *name="TrdQaTracker", Int_t verbose=1)
Constructor.
void DeInit()
Free the memory etc.
CbmQaHist< TH1D > fh2DpullY
CbmQaCanvas fCanvResidual
Canvaces: collection of histogramms.
CbmMCDataManager * fMcManager
CbmTrdParSetDigi * fTrdDigiPar
CbmQaHist< TH1D > fh2DresidualT
CbmMCDataArray * fMcPoints
CbmDigiManager * fDigiManager
CbmQaHist< TH1D > fh2DpullT
CbmTrdParSetGeo * fTrdGeoPar
InitStatus ReInit()
FairTask: Reinitialisation.
CbmQaCanvas fCanvEfficiencyXY
void ResolutionQa()
Analysis of hit uncertainty (pull) distributions.
std::vector< CbmQaHist< TProfile2D > > fhEfficiencyXY
hits efficiency
void SetParContainers()
FairTask: Intialise parameter containers.
TClonesArray * fHitMatches
void Exec(Option_t *)
TTask: Process a timeslice.
CbmQaCanvas fCanvEfficiencyR
InitStatus GeometryQa()
Check the geometry.
CbmQaHist< TH1D > fh2DpullX
std::vector< CbmQaHist< TH1I > > fhPointsPerHit
hits purity
TClonesArray * fHitsMc
Output.
CbmQaHist< TH1D > fh1DresidualT
TFolder * fHistFolder
output folder with histos and canvases
CbmQaCanvas fCanvHitsPerPoint
CbmQaHist< TH1D > fh1DpullT
~CbmTrdCalibTracker()
Destructor.
CbmMCEventList * fMcEventList
MC data.
Data Container for TRD clusters.
int32_t GetAddressModule() const
Getter module address in the experiment.
uint64_t GetTimeDAQ() const
Getter for global DAQ time [clk]. Differs for each ASIC. In FASP case DAQ time is already stored in f...
eCbmTrdAsicType GetType() const
Channel FEE SPADIC/FASP according to CbmTrdAsicType.
double GetTime() const
Getter for physical time [ns]. Accounts for clock representation of each ASIC. In SPADIC case physica...
TRD hit to MC point correlation class.
size_t AddPoint(const CbmTrdPoint *p, double t, int id)
Add MC points to the hit. The first time this function is called is for the best matched MC point.
void SetErrorMsg(std::string msg)
Store error message.
void AddCluster(const CbmTrdCluster *c)
Copy cluster details.
size_t PurgeSignals()
Applies to TRD2D and remove 0 charges from the boundaries of the cluster.
size_t AddSignal(const CbmTrdDigi *d, uint64_t t0)
Add signal values in the increasing order of pad index.
double GetDx() const
Calculate residuals in the bending plane.
data class for a reconstructed Energy-4D measurement in the TRD
bool GetClassType() const
Definition of geometry for one TRD module.
virtual Double_t GetZ() const
bool LoadAlignVolumes()
Trigger loading alignment information for all nodes registered.
virtual Int_t GetModuleId(Int_t i) const
virtual const CbmTrdParMod * GetModulePar(Int_t detId) const
int32_t GetModuleAddress() const
std::tuple< double, double > FitKaniadakisGaussian(TH1 *pHist)
Fit a histogram with Kaniadakis Gaussian Distribution.