1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
16 //Class to check the response of the detection elements of the MUON tracking chambers
17 //in function of the position in the detection element.
18 //Author: Nicolas LE BRIS - SUBATECH Nantes
21 #include "AliAnalysisTaskMuonTrackingEff.h"
22 #include "AliCheckMuonDetEltResponse.h"
26 #include "AliESDEvent.h"
27 #include "AliTracker.h"
28 #include "AliESDMuonTrack.h"
31 #include "AliMUONTrack.h"
32 #include "AliMUONTrackParam.h"
33 #include "AliMUONTrackExtrap.h"
34 #include "AliMUONVCluster.h"
35 #include "AliMUONConstants.h"
36 #include "AliMUONGeometryTransformer.h"
37 #include "AliMUONESDInterface.h"
39 //include MUON/mapping:
40 #include "mapping/AliMpDEManager.h"
41 #include "mapping/AliMpSegmentation.h"
42 #include "mapping/AliMpSlat.h"
43 #include "mapping/AliMpSlatSegmentation.h"
44 #include "mapping/AliMpSector.h"
45 #include "mapping/AliMpSectorSegmentation.h"
46 #include "mapping/AliMpPad.h"
49 #include <Riostream.h>
55 #include <TClonesArray.h>
56 #include <TPaveLabel.h>
60 ClassImp(AliCheckMuonDetEltResponse)
63 const Int_t AliCheckMuonDetEltResponse::fNbrOfChamber = 10;
64 const Int_t AliCheckMuonDetEltResponse::fNbrOfStation = 5;
65 const Int_t AliCheckMuonDetEltResponse::fNbrOfDetectionElt[10] = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26};
66 const Int_t AliCheckMuonDetEltResponse::fFirstDetectionElt[10] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
67 const Int_t AliCheckMuonDetEltResponse::fOffset = 100;
68 const Int_t AliCheckMuonDetEltResponse::fOverlapSize = 15;
69 const Int_t AliCheckMuonDetEltResponse::fYSlatSize = 20;
71 //_____________________________________________________________________________
72 AliCheckMuonDetEltResponse::AliCheckMuonDetEltResponse()
80 fIsCosmicData(kFALSE),
84 fDetEltTDHistList(0x0),
85 fDetEltTTHistList(0x0),
86 fChamberTDHistList(0x0),
87 fChamberTTHistList(0x0)
89 /// Default constructor
91 fNCh = AliCheckMuonDetEltResponse::fNbrOfChamber;
92 fNSt = AliCheckMuonDetEltResponse::fNbrOfStation;
93 fNDE = AliAnalysisTaskMuonTrackingEff::fTotNbrOfDetectionElt;
95 for (Int_t iCluster = 0; iCluster<fNCh; ++iCluster)
96 fNbrClustersCh[iCluster] = 0;
98 for (Int_t i=0; i<fNCh; ++i)
102 //_____________________________________________________________________________
103 AliCheckMuonDetEltResponse::AliCheckMuonDetEltResponse(const AliCheckMuonDetEltResponse& src)
110 fTracksTotalNbr(0x0),
111 fIsCosmicData(kFALSE),
115 fDetEltTDHistList(0x0),
116 fDetEltTTHistList(0x0),
117 fChamberTDHistList(0x0),
118 fChamberTTHistList(0x0)
122 //_____________________________________________________________________________
123 AliCheckMuonDetEltResponse& AliCheckMuonDetEltResponse::operator=(const AliCheckMuonDetEltResponse& src)
125 /// assignement operator
133 //_____________________________________________________________________________
134 AliCheckMuonDetEltResponse::AliCheckMuonDetEltResponse(const AliMUONGeometryTransformer* transformer,
136 TClonesArray* detEltTDHistList,
137 TClonesArray* detEltTTHistList,
138 TClonesArray* chamberTDHistList,
139 TClonesArray* chamberTTHistList,
145 fTransformer(transformer),
148 fIsCosmicData(kFALSE),
152 fDetEltTDHistList(detEltTDHistList),
153 fDetEltTTHistList(detEltTTHistList),
154 fChamberTDHistList(chamberTDHistList),
155 fChamberTTHistList(chamberTTHistList)
159 fNCh = AliCheckMuonDetEltResponse::fNbrOfChamber;
160 fNSt = AliCheckMuonDetEltResponse::fNbrOfStation;
161 fNDE = AliAnalysisTaskMuonTrackingEff::fTotNbrOfDetectionElt;
162 fIsCosmicData = isCosmic;
164 for (Int_t iCluster = 0; iCluster<fNCh; ++iCluster)
165 fNbrClustersCh[iCluster] = 0;
167 for (Int_t i=0; i<fNCh; ++i)
173 //_____________________________________________________________________________
174 AliCheckMuonDetEltResponse::~AliCheckMuonDetEltResponse()
183 //_____________________________________________________________________________
184 void AliCheckMuonDetEltResponse::CheckDetEltResponse()
187 //Cataloging positions (X,Y) of the clusters detected in the detection elements
188 //(fDetEltTDHistList), and positions of crossing points between all the
189 //tracks and the detection elements (fDetEltTTHistList).
190 //Efficiency = 100 * fDetEltTDHistList / fDetEltTTHistList.
199 //_____________________________________________________________________________
200 void AliCheckMuonDetEltResponse::TrackLoop()
202 AliESDMuonTrack* esdTrack;
204 Int_t nTracks, iTrack;
206 nTracks = (Int_t)fESD -> GetNumberOfMuonTracks();
207 fTrackParams = new TClonesArray();
208 ///Begininig of the loop:
209 for (iTrack = 0; iTrack < nTracks; iTrack++)
211 esdTrack = fESD -> GetMuonTrack(iTrack);
213 if( esdTrack->ContainTrackerData() && esdTrack->GetMatchTrigger() > 0)
217 // Beginnig of long stuff to check the number of trigger hit (to only keep muon trigger and cut cosmic showers)
218 Int_t nTriggerHit = 0;
219 Int_t nTriggerHitStrip[8] = {0, 0, 0, 0,
221 UShort_t triggerPattern[8] = {esdTrack->GetTriggerX1Pattern(), esdTrack->GetTriggerX2Pattern(), esdTrack->GetTriggerX3Pattern(), esdTrack->GetTriggerX4Pattern(),
222 esdTrack->GetTriggerY1Pattern(), esdTrack->GetTriggerY2Pattern(), esdTrack->GetTriggerY3Pattern(), esdTrack->GetTriggerY4Pattern()};
224 for (Int_t ii = 0; ii < 8; ii++)
226 UShort_t pattern = triggerPattern[ii];
227 Int_t binaryValue[16] = {0, 0, 0, 0,
232 for (Int_t jj = 15; jj >= 0; jj--)
235 for (Int_t bb = 0; bb < jj; bb++)
238 if (pattern/base == 1)
241 pattern = pattern - base;
246 for (Int_t ii = 0; ii < 8; ii++)
247 nTriggerHit += nTriggerHitStrip[ii];
252 if (nTriggerHit < 10)
254 AliMUONESDInterface::ESDToMUON(*esdTrack, track);
255 fTrackParams = track.GetTrackParamAtCluster();
256 TrackParamLoop(); //!<Loop on trackParam.
260 // No trigger cut is required for non-cosmic data
263 AliMUONESDInterface::ESDToMUON(*esdTrack, track);
264 fTrackParams = track.GetTrackParamAtCluster();
265 TrackParamLoop(); //!<Loop on trackParam.
273 //_____________________________________________________________________________
274 void AliCheckMuonDetEltResponse::TrackParamLoop()
276 Int_t nTrackParams = (Int_t) fTrackParams->GetEntriesFast(); //!<Number of trackParams in the track.
277 Int_t iTrackParam = 0; //!<Number of the trackParam of the track.
278 Int_t oldChamber = -1, newChamber = 0; //!<To check if there is 0, 1 or 2 (overlap cases) clusters in the same chamber for a track.
279 Int_t detElt; //!<Detection element Id.
281 for (Int_t ch = 0; ch < fNCh; ++ch)
282 fTrackFilter[ch] = 0;
285 Double_t posXL, posYL, posZL; //!<Local positions.
286 Double_t posXG, posYG, posZG; //!<Global. positions.
287 Int_t chamberResponse [10] = {0}; //!<1 if the chamber has responded; 0 if not
289 for (iTrackParam = 0; iTrackParam < nTrackParams; ++iTrackParam)
291 fTrackParam = (AliMUONTrackParam*) fTrackParams->At(iTrackParam);
292 fCluster = (AliMUONVCluster* ) fTrackParam ->GetClusterPtr();
293 fTrackFilter [fCluster->GetChamberId()] = 1;
294 chamberResponse[fCluster->GetChamberId()] = 1;
297 for (Int_t station = 0; station < fNSt-1; ++station)
300 Int_t ch1, ch2, ch3, ch4; //<!
301 ch1 = 2*station; //<!
302 ch2 = 2*station + 1; //<!
303 ch3 = 2*station + 2; //<!
304 ch4 = 2*station + 3; //<!
305 //<!For the efficiency calculation the tracks
306 if (station < 3 ) //<!reconstructed must have responded to the
307 { //<!criteria of the tracking.
308 filter = fTrackFilter[ch1]; //<!And that's why the tracks usable for the
309 fTrackFilter[ch1] = fTrackFilter[ch2]; //<!intrinsic efficiency calculation are
310 fTrackFilter[ch2] = filter; //<!the tracks which have one or two clusters
311 } //<!in each station. So the case where a track
312 //<!hasn't a cluster in a station is not
313 else //<!taking into account.
314 { //<!This part solves the problem. See the ALICE
315 if (chamberResponse[ch3]*chamberResponse[ch4] != 0) //<!note of Diego STOCCO on the trigger efficiency
317 filter = fTrackFilter[ch1]; //<!
318 fTrackFilter[ch1] = fTrackFilter[ch2]; //<!
319 fTrackFilter[ch2] = filter; //<!
323 fTrackFilter[ch1] = 0; //<!
324 fTrackFilter[ch2] = 0; //<!
327 if (chamberResponse[ch1]*chamberResponse[ch2] != 0)
329 filter = fTrackFilter[ch3];
330 fTrackFilter[ch3] = fTrackFilter[ch4];
331 fTrackFilter[ch4] = filter;
335 fTrackFilter[ch3] = 0;
336 fTrackFilter[ch4] = 0;
342 ///Begining of the loop:
343 for (iTrackParam = 0; iTrackParam < nTrackParams; ++iTrackParam)
345 fTrackParam = (AliMUONTrackParam*) fTrackParams->At(iTrackParam);
346 fCluster = (AliMUONVCluster* ) fTrackParam ->GetClusterPtr();
348 newChamber = fCluster->GetChamberId();
349 detElt = fCluster->GetDetElemId();
351 ///Global and local positions calculation:
352 posXG = fTrackParam->GetNonBendingCoor();
353 posYG = fTrackParam->GetBendingCoor();
354 posZG = fTrackParam->GetZ();
356 fTransformer->Global2Local(detElt, posXG, posYG, posZG, posXL, posYL, posZL); //!<Transfomation from global to local positions.
358 ///Filling histograms of the cluster positions on the detection element of the TRACKS DETECTED (TD):
359 FillTDHistos(newChamber, detElt, posXL, posYL);
361 ///Filling histograms of the cluster positions on the detection element of ALL THE TRACKS (TT):
362 FillTTHistos(newChamber, detElt, posXL, posYL);
364 if (newChamber != oldChamber)
366 if (newChamber > oldChamber + 1) //!<Check if it doesn't miss a chamber.
368 Int_t nbrMissChamber = newChamber - (oldChamber + 1);
369 FindAndFillMissedDetElt(fTrackParam, oldChamber+1, nbrMissChamber); //!<Calculation of the parameters of the missing cluster(s).
372 if ( iTrackParam == nTrackParams - 1 && newChamber != fNCh-1) //!<Check if the last chamber, chamber 9 (from 0 to 9) has responded.
373 FindAndFillMissedDetElt(fTrackParam, fNCh-1, 1); //!<Calculation of the parameters of the missing cluster(s) in the last chamber.
376 oldChamber = newChamber;
382 //_____________________________________________________________________________
383 void AliCheckMuonDetEltResponse::FillTDHistos(Int_t chamber,
388 if(fTrackFilter[chamber]== 1)
390 Int_t iDet = 0; //!<Position of the detection element in the histograms' list.
391 iDet = FromDetElt2iDet(chamber, detElt);
392 ((TH2F*) fDetEltTDHistList->UncheckedAt(iDet))->Fill(posXL, posYL);
393 ((TH2F*) fDetEltTDHistList->UncheckedAt(fNDE))->Fill(chamber, 0);
395 Int_t detEltLocalId = 0; //!<Id of the detection element in the station
396 detEltLocalId = FromDetElt2LocalId(chamber, detElt);
397 ((TH1F*) fChamberTDHistList->UncheckedAt(chamber))->Fill(detEltLocalId);
398 ((TH1F*) fChamberTDHistList->UncheckedAt(10))->Fill(chamber);
405 //_____________________________________________________________________________
406 void AliCheckMuonDetEltResponse::FillTTHistos(Int_t chamber,
411 if(fTrackFilter[chamber] == 1)
413 Int_t iDet = 0; //!<Position of the detection element in the histograms' list.
414 iDet = FromDetElt2iDet(chamber, detElt);
415 ((TH2F*) fDetEltTTHistList->UncheckedAt(iDet)) -> Fill(posXL, posYL);
416 ((TH2F*) fDetEltTTHistList->UncheckedAt(fNDE))->Fill(chamber, 0);
418 Int_t detEltLocalId = 0; //!<Id of the detection element in the station
419 detEltLocalId = FromDetElt2LocalId(chamber, detElt);
420 ((TH1F*) fChamberTTHistList->UncheckedAt(chamber))->Fill(detEltLocalId);
421 ((TH1F*) fChamberTTHistList->UncheckedAt(10))->Fill(chamber);
429 //_____________________________________________________________________________
430 Int_t AliCheckMuonDetEltResponse::FromDetElt2iDet(Int_t chamber,
434 ///Connexion between the detection element X and its position in the list of histograms iX.
437 Int_t iDet = 0; //!<Position of the detection element (detElt) in the histograms' list.
439 if (chamber<4) iDet = detElt-fOffset*(chamber+1)+ 4* chamber ;
440 if (chamber>3 && chamber<6) iDet = detElt-fOffset*(chamber+1)+18*(chamber-4)+16;
441 if (chamber>5) iDet = detElt-fOffset*(chamber+1)+26*(chamber-6)+52;
448 //_____________________________________________________________________________
449 Int_t AliCheckMuonDetEltResponse::FromDetElt2LocalId(Int_t chamber,
453 ///Connexion between the detection element X and its number in the station.
456 Int_t localId = 0; //!<Position of the detection element (detElt) in the histograms' list.
457 localId = detElt - (chamber+1) * 100;
464 //_____________________________________________________________________________
465 void AliCheckMuonDetEltResponse::FindAndFillMissedDetElt(AliMUONTrackParam* extrapTrackParam,
470 ///Find which detection elements should have been hit but were missed,
471 ///and fill the TT histos appropriately
473 for (Int_t iCh = 0; iCh < nbrMissCh; ++iCh)
475 Int_t chamber = firstMissCh + iCh;
476 Int_t nbrOfDetElt = AliMpDEManager::GetNofDEInChamber(chamber, kTRUE); //!<Number of detection elements in the chamber.
478 Double_t pos1[6] = {0, 0, 0, 0, 0, 0}; //!<First point used to compute the extrapolated point (first 3 for global coordinates, last 3 for local).
479 Double_t pos2[6] = {0, 0, 0, 0, 0, 0}; //!<Second point used to compute the extrapolated point (first 3 for global coordinates, last 3 for local).
480 Double_t posMiss[2] = {0, 0}; //!<(X, Y) local coordinates of the missing cluster.
482 pos1[2] = AliMUONConstants::DefaultChamberZ(chamber); //!<Z of point 1, defined by being the Z of the chamber in "perfect" position.
483 AliMUONTrackExtrap::ExtrapToZ(extrapTrackParam, pos1[2]);
484 pos1[0] = extrapTrackParam->GetNonBendingCoor(); //!<X of point 1, extrapolated by following the Track.
485 pos1[1] = extrapTrackParam->GetBendingCoor(); //!<Y of point 1, extrapolated by following the Track.
487 pos2[2] = AliMUONConstants::DefaultChamberZ(chamber) + AliMUONConstants::DzCh(); //!<Z of point 2, defined by being the Z of the chamber in "perfect" position
488 AliMUONTrackExtrap::ExtrapToZ(extrapTrackParam, pos2[2]); //!< + plus a small shift (the distance between two stations in a same chamber).
489 pos2[0] = extrapTrackParam->GetNonBendingCoor(); //!<X of point 2, extrapolated by following the Track.
490 pos2[1] = extrapTrackParam->GetBendingCoor(); //!<Y of point 2, extrapolated by following the Track.
494 for (Int_t iDE = 0; iDE < nbrOfDetElt; iDE++) //!<Loop on all the detection element of the chamber
496 Int_t deId = (chamber + 1)*fOffset + iDE; //!<detection element Id
498 fTransformer->Global2Local(deId, pos1[0], pos1[1], pos1[2], pos1[3], pos1[4], pos1[5]); //!<convesrion of point 1 and 2 in the local coordinates
499 fTransformer->Global2Local(deId, pos2[0], pos2[1], pos2[2], pos2[3], pos2[4], pos2[5]);
501 CoordinatesOfMissingCluster(pos1[3], pos1[4], pos1[5], pos2[3], pos2[4], pos2[5], posMiss[0], posMiss[1]);
503 Bool_t isMissed = kFALSE;
505 isMissed = CoordinatesInDetEltSt12(deId, posMiss[0], posMiss[1]);
507 isMissed = CoordinatesInDetEltSt345(deId, posMiss[0], posMiss[1]);
510 FillTTHistos(chamber, deId, posMiss[0], posMiss[1]);
517 //_____________________________________________________________________________
518 void AliCheckMuonDetEltResponse::CoordinatesOfMissingCluster(Double_t x1, Double_t y1, Double_t z1,
519 Double_t x2, Double_t y2, Double_t z2,
520 Double_t& x, Double_t& y)
523 //Compute the coordinates of the missing cluster.
524 //There are defined by the intersection between the straigth line joining two extrapolated points (1 and 2) and the detection element plane.
525 //In the local coordinates, this means Z=0 in the parametric equation of the line.
529 t = - z1 / (z2 - z1);
531 x = t * (x2 - x1) + x1;
532 y = t * (y2 - y1) + y1;
536 //_____________________________________________________________________________
537 Bool_t AliCheckMuonDetEltResponse::CoordinatesInDetEltSt345(Int_t DeId, Double_t x, Double_t y)
540 //Return kTRUE if the coordinates are in the Detection Element, for station 3, 4 and 5.
541 //This is done by checking if a pad correspond to the (x, y) position.
547 AliMpSlatSegmentation *segm1 = new AliMpSlatSegmentation(AliMpSegmentation::Instance(kFALSE)->GetSlat(DeId, AliMp::kCath0));
548 AliMpSlatSegmentation *segm2 = new AliMpSlatSegmentation(AliMpSegmentation::Instance(kFALSE)->GetSlat(DeId, AliMp::kCath1));
549 pad1 = segm1->PadByPosition(x, y, kFALSE);
550 pad2 = segm2->PadByPosition(x, y, kFALSE);
552 if (pad1.IsValid() && pad2.IsValid())
559 //_____________________________________________________________________________
560 Bool_t AliCheckMuonDetEltResponse::CoordinatesInDetEltSt12(Int_t DeId, Double_t x, Double_t y)
562 //Return kTRUE if the coordinates are in the Detection Element, for station 1 and 2.
563 //This is done by checking if a pad correspond to the (x, y) position.
568 AliMpSectorSegmentation *segm1 = new AliMpSectorSegmentation(AliMpSegmentation::Instance(kFALSE)->GetSector(DeId, AliMp::kCath0));
569 AliMpSectorSegmentation *segm2 = new AliMpSectorSegmentation(AliMpSegmentation::Instance(kFALSE)->GetSector(DeId, AliMp::kCath1));
570 pad1 = segm1->PadByPosition(x, y, kFALSE);
571 pad2 = segm2->PadByPosition(x, y, kFALSE);
573 if (pad1.IsValid() && pad2.IsValid())