9 #include "AliAnalysisManager.h"
10 #include "AliESDEvent.h"
11 #include "AliAODEvent.h"
12 #include "AliMCEvent.h"
13 #include "AliESDInputHandler.h"
14 #include "AliAODHandler.h"
15 #include "AliMCEventHandler.h"
17 #include "AliESDTrdTrack.h"
19 #include "AliTRDtrackletMCM.h"
20 #include "AliVParticle.h"
21 #include "AliMCParticle.h"
22 #include "AliTrackReference.h"
24 #include "TGeoGlobalMagField.h"
25 #include "AliTRDtrackletWord.h"
27 #include "AliTRDonlineTrackletQA.h"
29 ClassImp(AliTRDonlineTrackletQA)
31 AliTRDonlineTrackletQA::AliTRDonlineTrackletQA(const char *name) :
32 AliAnalysisTask(name, ""),
71 fGeo(new AliTRDgeometry),
78 DefineInput(0, TChain::Class());
79 DefineInput(1, TTree::Class());
81 DefineOutput(0, TTree::Class());
82 DefineOutput(1, TList::Class());
85 AliTRDonlineTrackletQA::~AliTRDonlineTrackletQA()
92 void AliTRDonlineTrackletQA::ConnectInputData(const Option_t * /* option */)
96 fInputHandler = (AliInputEventHandler*) AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler();
98 fInputEvent = fInputHandler->GetEvent();
100 AliMCEventHandler *mcH = (AliMCEventHandler*) AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler();
102 fMCEvent = mcH->MCEvent();
105 void AliTRDonlineTrackletQA::CreateOutputObjects()
107 // create output objects
111 fOutputList = new TList();
113 fHistYpos = new TH1F("ypos",
114 "Tracklet (sim) y-position;y (cm);count",
115 8192/32, -4096*160e-4, 4095*160e-4);
116 fHistYposRaw = new TH1F("ypos-raw",
117 "Tracklet (raw) y-position;y (cm);count",
119 fHistYres = new TH1F("yres",
120 "Tracklet (sim) #Deltay;y_{tracklet}-y_{MC} (cm);count",
121 8192/32, -4096/32*160e-4, 4095/32*160e-4);
122 fHistYresDy = new TH2F("yresdy",
123 "Tracklet (sim) #Deltay;y_{tracklet}-y_{MC} (cm);deflection (bin)",
124 8192/32, -4096/32*160e-4, 4095/32*160e-4,
126 fHistYresESD = new TH1F("yresesd",
127 "Tracklet #Deltay;y (cm);count",
129 fHistYdiff = new TH1F("ydiff",
130 "Tracklet #Deltay (sim - raw);y_{sim}-y_{raw} (cm);count",
131 8192/32, -4096/32*160e-4, 4095/32*160e-4);
132 for (Int_t iLayer = 0; iLayer < 6; iLayer++) {
133 fHistYlocal[iLayer] = new TH2F(Form("ylocal_%i", iLayer),
134 Form("Tracklet local y, layer %i;y_{MC} (pad width);y_{trkl} (pad width)", iLayer),
135 100, -1, 1, 100, -1, 1);
138 fHistdY = new TH1F("dy",
139 "deflection (sim);dy (140 #mum)",
141 fHistdYRaw = new TH1F("dy-raw",
142 "deflection (sim);dy (140 #mum)",
144 fHistdYres = new TH1F("dyres",
145 "deflection residual;dy (cm)",
147 fHistdYresESD = new TH1F("dyresesd",
148 "deflection residual;dy (cm)",
150 fHistCanddY = new TH1F("dycand",
151 "deflection;dy (140 #mum)",
153 fHistFounddY = new TH1F("dyfound",
154 "deflection;dy (140 #mum)",
156 fHistdYdiff = new TH1F("dydiff",
157 "deflection #Deltady;dy_{sim}-dy_{raw} (140 #mum)",
159 fHistdYdYraw = new TH2F("dydyraw",
160 "deflection from sim. vs raw;dy_{sim} (140 #mum);dy_{raw} (140 #mum)",
161 128, -64.5, 63.5, 128, -64.5, 63.5);
163 fHistTrklPerRef = new TH1F("trklperref",
164 "No. of tracklets per track reference;no. of tracklets",
167 fHistdYdYref = new TH2F("dydyref",
168 "deflection vs. deflection from track reference;dy_{ref} (140 #mum);dy (140 #mum)",
169 128, -64.5, 63.5, 128, -64.5, 63.5);
171 fHistZrow = new TH1F("zrow",
172 "z-position;pad row",
174 fHistZrowRaw = new TH1F("zrow-raw",
175 "z-position;pad row",
178 fHistPid = new TH1F("pid",
181 fHistPidRaw = new TH1F("pid-raw",
185 fHistYdYRaw = new TH2F("ydyraw",
186 "y vs dy (raw tracklets);y (cm);dy (140 #mum)",
187 8192/32, -4096*160e-4, 4095*160e-4,
190 fTreeTracklets = new TTree("trkl", "trkl");
191 fTreeTracklets->Branch("y", &fY);
192 fTreeTracklets->Branch("dy", &fDY);
193 fTreeTracklets->Branch("ydiff", &fYdiff);
194 fTreeTracklets->Branch("dydiff", &fDYdiff);
195 fTreeTracklets->Branch("q0", &fQ0);
196 fTreeTracklets->Branch("q1", &fQ1);
197 fTreeTracklets->Branch("nhits", &fNHits);
199 fOutputList->Add(fHistYpos);
200 fOutputList->Add(fHistdY);
201 fOutputList->Add(fHistZrow);
202 fOutputList->Add(fHistPid);
204 fOutputList->Add(fHistYres);
205 fOutputList->Add(fHistYresDy);
206 fOutputList->Add(fHistCanddY);
207 fOutputList->Add(fHistFounddY);
208 fOutputList->Add(fHistTrklPerRef);
209 fOutputList->Add(fHistdYres);
210 fOutputList->Add(fHistYresESD);
211 fOutputList->Add(fHistdYresESD);
212 fOutputList->Add(fHistdYdYref);
214 for (Int_t iLayer = 0; iLayer < 6; iLayer++)
215 fOutputList->Add(fHistYlocal[iLayer]);
217 fOutputList->Add(fHistYposRaw);
218 fOutputList->Add(fHistdYRaw);
219 fOutputList->Add(fHistZrowRaw);
220 fOutputList->Add(fHistPidRaw);
221 fOutputList->Add(fHistYdYRaw);
223 fOutputList->Add(fHistYdiff);
224 fOutputList->Add(fHistdYdiff);
225 fOutputList->Add(fHistdYdYraw);
227 fOutputList->Add(fTreeTracklets);
230 void AliTRDonlineTrackletQA::Exec(const Option_t * /* option */)
232 // execute this for each event
234 // connect input data
235 fTrackletTree = (TTree*) GetInputData(1);
239 fTrackletTree->SetBranchAddress("tracklets_sim", &fTrackletsSim);
240 fTrackletTree->SetBranchAddress("tracklets_raw", &fTrackletsRaw);
241 fTrackletTree->GetEntry(fTrackletTree->GetEntriesFast()-1);
243 // prepare raw tracklets for comparison
249 TTree trklRaw("raw tracklets", "raw tracklets");
250 trklRaw.Branch("det", &detRaw);
251 trklRaw.Branch("rob", &robRaw);
252 trklRaw.Branch("mcm", &mcmRaw);
253 trklRaw.Branch("y", &yRaw);
254 trklRaw.Branch("dy", &dyRaw);
255 trklRaw.SetDirectory(0x0);
256 // prepare simulated tracklets for comparison
262 TTree trklSim("sim tracklets", "sim tracklets");
263 trklSim.Branch("det", &detSim);
264 trklSim.Branch("rob", &robSim);
265 trklSim.Branch("mcm", &mcmSim);
266 trklSim.Branch("y", &ySim);
267 trklSim.Branch("dy", &dySim);
268 trklSim.SetDirectory(0x0);
270 // ----- simulated tracklets -----
271 AliTRDtrackletMCM *trkl = 0x0;
273 for (Int_t iTracklet = 0; iTracklet < fTrackletsSim->GetEntries(); iTracklet++) {
274 trkl = (AliTRDtrackletMCM*) (*fTrackletsSim)[iTracklet];
275 // Int_t label = trkl->GetLabel();
276 // if (label > -1 && label < maxTracks)
277 // mcTrackToTrackletMCM[label].idx[mcTrackToTrackletMCM[label].size < 10 ? mcTrackToTrackletMCM[label].size++ : 0] = iTracklet;
278 fHistYpos->Fill(trkl->GetY());
279 fHistdY->Fill(trkl->GetdY());
280 fHistZrow->Fill(trkl->GetZbin());
281 fHistPid->Fill(trkl->GetPID());
283 detSim = trkl->GetDetector();
284 robSim = trkl->GetROB();
285 mcmSim = trkl->GetMCM();
286 ySim = trkl->GetYbin();
287 dySim = trkl->GetdY();
295 // ----- raw tracklets -----
297 for (Int_t iTracklet = 0; iTracklet < fTrackletsRaw->GetEntries(); iTracklet++) {
298 AliTRDtrackletWord *trklWord = (AliTRDtrackletWord*) (*fTrackletsRaw)[iTracklet];
299 // remove unwanted chambers
300 if (trklWord->GetDetector() == 57 ||
301 trklWord->GetDetector() == 47 ||
302 trklWord->GetDetector() == 32)
305 fHistYposRaw->Fill(trklWord->GetY());
306 fHistdYRaw->Fill(trklWord->GetdY());
307 fHistZrowRaw->Fill(trklWord->GetZbin());
308 fHistPidRaw->Fill(trklWord->GetPID());
309 fHistYdYRaw->Fill(trklWord->GetY(), trklWord->GetdY());
311 detRaw = trklWord->GetDetector();
312 robRaw = trklWord->GetROB();
313 mcmRaw = trklWord->GetMCM();
314 yRaw = trklWord->GetYbin();
315 dyRaw = trklWord->GetdY();
320 // ----- tracklet comparison raw to simulated -----
321 trklRaw.BuildIndex("(det+rob*540)*16+mcm", "det");
322 trklSim.BuildIndex("(det+rob*540)*16+mcm", "det");
323 trklRaw.AddFriend(&trklSim, (const char*) "sim");
324 gDirectory->Add(fHistYdiff, kFALSE);
325 Int_t ncomp = trklRaw.Draw("(sim.y-y)*160e-4>>+ydiff", "", "goff");
326 printf("----- Compared %i tracklets -----\n", ncomp);
327 gDirectory->Remove(fHistYdiff);
328 gDirectory->Add(fHistdYdiff, kFALSE);
329 trklRaw.Draw("(sim.dy-dy)>>+dydiff", "", "goff");
330 gDirectory->Remove(fHistdYdiff);
331 gDirectory->Add(fHistdYdYraw, kFALSE);
332 trklRaw.Draw("dy:sim.dy>>+dydyraw", "", "goff");
333 // trklRaw.Scan("det:rob:mcm:y:dy:sim.dy", "sim.dy < 30 && dy > 30");
334 gDirectory->Remove(fHistdYdYraw);
336 // ----- MC tracks and track references -----
337 // determine tracklet efficiency
339 Int_t nTracksMC = fMCEvent->GetNumberOfTracks();
340 AliInfo(Form("no. of MC tracks: %i", nTracksMC));
341 for (Int_t iTrack = 0; iTrack < nTracksMC; iTrack++) {
343 if (!fMCEvent->IsPhysicalPrimary(iTrack))
346 AliMCParticle *mcpart = (AliMCParticle*) fMCEvent->GetTrack(iTrack);
348 // don't look at tracks with too low pt
349 if (TMath::Abs(mcpart->Pt()) < fMinPt)
352 // look for two track references in a chamber
353 Int_t nTrackRefs = mcpart->GetNumberOfTrackReferences();
354 AliTrackReference *tr[2] = { 0x0 };
357 for (Int_t iTrackRef = 0; iTrackRef < nTrackRefs; iTrackRef++) {
358 AliTrackReference *trackRef = mcpart->GetTrackReference(iTrackRef);
359 if (trackRef->DetectorId() != AliTrackReference::kTRD)
361 if (trackRef->Pt() < fMinPt)
363 Int_t label = trackRef->Label();
367 // first track reference, remember it
374 // next one is too far away, remember it but forget the previous one
375 if (TMath::Abs(trackRef->LocalX() - tr[0]->LocalX()) > 5.) {
380 // too close to previous track reference
382 else if (TMath::Abs(trackRef->LocalX() - tr[0]->LocalX()) < .5) {
385 // then it must be ok, so we take it
392 // calculation deflection from track references
393 Float_t deflLength = 3. * (tr[1]->LocalY() - tr[0]->LocalY()) / (tr[1]->LocalX() - tr[0]->LocalX());
394 // if it is too large we reject it
395 if (deflLength < 1.) {
396 fHistCanddY->Fill(deflLength/140e-4);
403 // now search for tracklets belonging to this track reference
404 Int_t nTrackletsPerRef(0);
406 for (Int_t iTracklet = 0; iTracklet < fTrackletsSim->GetEntries(); iTracklet++) {
407 trkl = (AliTRDtrackletMCM*) (*fTrackletsSim)[iTracklet];
408 // they must have the same label
409 if (!trkl->HasLabel(label))
411 // and be close enough in radial position
412 if (TMath::Abs(trackRef->LocalX() - trkl->GetX()) > 5.)
414 // if they are close in position we accept it
415 if ((TMath::Abs(trackRef->LocalY() - trkl->GetY()) < 5.) &&
416 (TMath::Abs(trackRef->Z() - trkl->GetZ()) < 5.)) {
417 defl = trkl->GetdY();
421 fHistTrklPerRef->Fill(nTrackletsPerRef);
422 if (nTrackletsPerRef == 0) {
423 AliInfo(Form("Track ref without assigned tracklet: x=%4.2f, y=%4.2f, z=%4.2f, pt=%4.2f (%i)",
424 trackRef->X(), trackRef->Y(), trackRef->Z(), trackRef->Pt(), trackRef->Label()));
426 if (nTrackletsPerRef == 1) {
427 fHistdYdYref->Fill(deflLength/140.e-4, defl);
428 fHistFounddY->Fill(deflLength/140.e-4);
435 // ----- ESD tracks -----
437 for (Int_t iTrack = 0; iTrack < fESD->GetNumberOfTracks(); iTrack++) {
438 AliESDtrack *esdTrack = fESD->GetTrack(iTrack);
439 AliDebug(1, Form("ESD track pt: %7.2f", esdTrack->Pt()));
443 PostData(1, fOutputList);
446 void AliTRDonlineTrackletQA::LocalInit()
451 void AliTRDonlineTrackletQA::Terminate(const Option_t * /* option */)
455 fOutputList = dynamic_cast<TList*> (GetOutputData(1));
458 AliError("No output objects found!");
462 // fHistYpos = dynamic_cast<TH1F*> (fOutputList->FindObject("ypos"));
464 // TCanvas *c = new TCanvas;
468 // fHistYpos->DrawCopy();
472 void AliTRDonlineTrackletQA::PlotMC(AliTRDtrackletMCM *trkl)
474 // compare the given tracklet to the MC information,
475 // i.e. track references
477 Int_t label = trkl->GetLabel();
479 // check for valid label
481 AliWarning("MC tracklet has no label");
484 if (label >= fMCEvent->GetNumberOfTracks()) {
485 AliWarning("MC tracklet has invalid label");
489 // some cuts on the tracklet
490 // if (!fMCEvent->IsPhysicalPrimary(label))
492 // if (TMath::Abs(trkl->GetdYdX()) > 0.05)
494 // if (trkl->GetDetector() % 6 != 5)
497 // get MC particle for this tracklet
498 AliMCParticle *track = (AliMCParticle*) fMCEvent->GetTrack(label);
500 // don't look at tracks with too low pt
501 if (TMath::Abs(track->Pt() < fMinPt))
504 // serach track references corresponding to the current tracklet
505 AliTrackReference *tr[2] = { 0x0 };
506 Int_t nTrackRefs = 0;
508 for (Int_t iTrackRef = 0; iTrackRef < track->GetNumberOfTrackReferences(); iTrackRef++) {
509 AliTrackReference *trackRef = track->GetTrackReference(iTrackRef);
510 if (trackRef->DetectorId() != AliTrackReference::kTRD)
512 if (trackRef->Pt() < fMinPt)
515 if (TMath::Abs(trkl->GetX() - trackRef->LocalX()) > 5.)
518 tr[nTrackRefs++] = trackRef;
524 // if there were exactly 2 track references
525 // (otherwise something is strange and we want to look at clean cases)
526 // compare tracklet to them
527 if (nTrackRefs == 2) {
528 // sanity check to be in the same sector
529 if ( TMath::Abs((tr[0]->Alpha()*180./TMath::Pi()-10.)/20. - (trkl->GetDetector()/30)) > .1) {
530 AliError("Track reference in different sector");
532 // require minimal distance in X and maximum deflection in Y
533 // for the track references
534 else if ((tr[1]->LocalX() - tr[0]->LocalX()) > 0.1 && TMath::Abs(tr[1]->LocalY() - tr[0]->LocalY()) < 1.) {
535 // calculate slope from track references
536 // and check whether it's in the allowed range
537 Float_t slope = 3. * (tr[1]->LocalY() - tr[0]->LocalY()) / (tr[1]->LocalX() - tr[0]->LocalX());
538 if (TMath::Abs(slope) < 64*140e-4) {
539 AliDebug(1,Form("x1: %f, x0: %f, y1: %f, y0:%f",
540 tr[1]->LocalX(), tr[0]->LocalX(), tr[1]->LocalY(), tr[0]->LocalY() ));
541 // calculate y-position scaled to radial position of the tracklet
542 // and consider the tilting angle of the pads
543 // since the tracklets are affected by it
544 Float_t yMC = (tr[1]->LocalY() + (-0.5+trkl->GetX() - tr[1]->LocalX()) * (tr[1]->LocalY() - tr[0]->LocalY()) / (tr[1]->LocalX() - tr[0]->LocalX()));
545 Float_t yMCtilt = yMC + (TMath::Tan(TMath::Power(-1, (trkl->GetDetector() % 6))*2.*TMath::Pi()/180.) * (tr[1]->Z() - trkl->GetZ()));
546 if (TMath::Abs(trkl->GetY() - yMCtilt) > 10.) {
547 AliError(Form("Deviation too large for tracklet: 0x%08x in det. %i at x = %f, y = %f, z = %f, alpha = %f",
548 trkl->GetTrackletWord(), trkl->GetDetector(), trkl->GetX(), trkl->GetY(), trkl->GetZ(), tr[0]->Alpha()));
550 fHistYres->Fill(trkl->GetY() - yMCtilt);
551 fHistYresDy->Fill(trkl->GetY() - yMCtilt, trkl->GetdY());
552 // what about tilt correction here ???
553 fHistdYres->Fill(3. * trkl->GetdYdX() -
554 3. * (tr[1]->LocalY() - tr[0]->LocalY()) / (tr[1]->LocalX() - tr[0]->LocalX()));
555 // plot position deviation in pad-coordinates
556 // to study the influence of the position LUT
557 Float_t padWidth = fGeo->GetPadPlane(trkl->GetDetector())->GetWidthIPad();
558 Float_t yMClocal = yMCtilt/padWidth - floor(yMCtilt/padWidth) - padWidth/2.;
559 Int_t layer = trkl->GetDetector() % 6;
560 fHistYlocal[layer]->Fill(yMClocal,
561 trkl->GetY()/padWidth - floor(trkl->GetY()/padWidth) - padWidth/2. - yMClocal);
562 // and fill everything to the tree
565 fNHits = trkl->GetNHits();
566 fYdiff = trkl->GetY() - yMCtilt;
567 fDYdiff = 3. * trkl->GetdYdX() -
568 3. * (tr[1]->LocalY() - tr[0]->LocalY()) / (tr[1]->LocalX() - tr[0]->LocalX());
570 fDY = trkl->GetdYdX();
571 fTreeTracklets->Fill();
572 // output tracklets with large deviation
573 if (TMath::Abs(fYdiff) > 0.5) {
574 printf("tracklet: y=%4.2f, dy=%4.2f, ydiff=%4.2f, dydiff=%4.2f, q0=%5d, q1=%5d, nhits=%2d, label=%i\n",
575 trkl->GetY(), trkl->GetdYdX(), fYdiff, fDYdiff, fQ0, fQ1, fNHits, label);
583 void AliTRDonlineTrackletQA::PlotESD(AliTRDtrackletMCM *trkl)
585 // plot comparison to ESD
587 Float_t xTrkl = trkl->GetX();
588 Float_t yTrkl = trkl->GetY();
589 Float_t zTrkl = trkl->GetZ();
591 Float_t alpha = (trkl->GetDetector() / 30) * 20. + 10.;
592 alpha *= TMath::Pi() / 180.;
594 AliESDEvent *esdEvent = dynamic_cast<AliESDEvent*> (fInputEvent);
598 Float_t mag = ((AliMagF*) TGeoGlobalMagField::Instance()->GetField())->SolenoidField();
600 for (Int_t iTrack = 0; iTrack < esdEvent->GetNumberOfTracks(); iTrack++) {
601 AliESDtrack *track = esdEvent->GetTrack(iTrack);
603 if (!track->GetOuterParam())
606 AliExternalTrackParam *param = new AliExternalTrackParam(*(track->GetOuterParam()));
608 AliDebug(10, Form("track %i at x = %f, y = %f",
609 iTrack, param->GetX(), param->GetY()));
610 param->Propagate(alpha, xTrkl, mag);
611 AliDebug(10, Form("after propagating track %i at x = %f, y = %f",
612 iTrack, param->GetX(), param->GetY()));
614 if ((TMath::Abs(xTrkl - param->GetX()) < 10.) &&
615 (TMath::Abs(yTrkl - param->GetY()) < 5.) &&
616 (TMath::Abs(zTrkl - param->GetZ()) < 10.)) {
617 AliInfo(Form("match of tracklet-track: %i <-> %i",
618 trkl->GetLabel(), track->GetLabel()));
619 AliDebug(5, Form("tracklet position: det: %3i x = %f, y = %f, z = %f, alpha = %f",
620 trkl->GetDetector(), trkl->GetX(), trkl->GetY(), trkl->GetZ(), alpha));
621 AliDebug(5, Form("after propagating track %i at x = %f, y = %f, z = %f",
622 iTrack, param->GetX(), param->GetY(), param->GetZ()));
624 fHistYresESD->Fill(yTrkl - param->GetY());
632 void AliTRDonlineTrackletQA::PlotESD(AliTRDtrackletWord *trkl)
634 // plot comparison to ESD
636 Float_t xTrkl = trkl->GetX();
637 Float_t yTrkl = trkl->GetY();
638 Float_t zTrkl = trkl->GetZ();
640 Float_t alpha = (trkl->GetDetector() / 30) * 20. + 10.;
641 alpha *= TMath::Pi() / 180.;
643 AliESDEvent *esdEvent = dynamic_cast<AliESDEvent*> (fInputEvent);
647 Float_t mag = ((AliMagF*) TGeoGlobalMagField::Instance()->GetField())->SolenoidField();
649 for (Int_t iTrack = 0; iTrack < esdEvent->GetNumberOfTracks(); iTrack++) {
650 AliESDtrack *track = esdEvent->GetTrack(iTrack);
652 if (!track->GetOuterParam())
655 AliExternalTrackParam *param = new AliExternalTrackParam(*(track->GetOuterParam()));
657 AliDebug(10, Form("track %i at x = %f, y = %f",
658 iTrack, param->GetX(), param->GetY()));
659 param->Propagate(alpha, xTrkl, mag);
660 AliDebug(10, Form("after propagating track %i at x = %f, y = %f",
661 iTrack, param->GetX(), param->GetY()));
663 if ((TMath::Abs(xTrkl - param->GetX()) < 10.) &&
664 (TMath::Abs(yTrkl - param->GetY()) < 5.) &&
665 (TMath::Abs(zTrkl - param->GetZ()) < 10.)) {
666 AliDebug(5, Form("tracklet position: det: %3i x = %f, y = %f, z = %f, alpha = %f",
667 trkl->GetDetector(), trkl->GetX(), trkl->GetY(), trkl->GetZ(), alpha));
668 AliDebug(5, Form("after propagating track %i at x = %f, y = %f, z = %f",
669 iTrack, param->GetX(), param->GetY(), param->GetZ()));
671 fHistYresESD->Fill(yTrkl - param->GetY());
680 Int_t AliTRDonlineTrackletQA::GetTrackletsForMC(Int_t /* label */, Int_t /*idx*/ [])
682 // get tracklets for MC label