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
19 //Modified by Matthieu LENHARDT - SUBATECH Nantes
22 #include "AliCheckMuonDetEltResponse.h"
25 #include "AliESDEvent.h"
26 #include "AliESDMuonTrack.h"
29 #include "AliMUONTrack.h"
30 #include "AliMUONTrackParam.h"
31 #include "AliMUONTrackExtrap.h"
32 #include "AliMUONVCluster.h"
33 #include "AliMUONConstants.h"
34 #include "AliMUONESDInterface.h"
35 #include "AliMUONGeometryTransformer.h"
37 //include MUON/mapping:
38 #include "mapping/AliMpDEManager.h"
39 #include "mapping/AliMpSegmentation.h"
40 #include "mapping/AliMpSlatSegmentation.h"
41 #include "mapping/AliMpSectorSegmentation.h"
42 #include "mapping/AliMpPad.h"
46 #include <TClonesArray.h>
49 ClassImp(AliCheckMuonDetEltResponse)
52 const Int_t AliCheckMuonDetEltResponse::fgkNCh = AliMUONConstants::NTrackingCh();
53 const Int_t AliCheckMuonDetEltResponse::fgkNSt = AliMUONConstants::NTrackingSt();
54 const Int_t AliCheckMuonDetEltResponse::fgkNDE = 156;
55 const Int_t AliCheckMuonDetEltResponse::fgkNbrOfDetectionElt[10] = {4, 4, 4, 4, 18, 18, 26, 26, 26, 26};
56 const Int_t AliCheckMuonDetEltResponse::fgkFirstDetectionElt[10] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000};
57 const Int_t AliCheckMuonDetEltResponse::fgkOffset = 100;
59 //_____________________________________________________________________________
60 AliCheckMuonDetEltResponse::AliCheckMuonDetEltResponse()
65 fIsCosmicData(kFALSE),
70 fDetEltTDHistList(0x0),
71 fDetEltTTHistList(0x0),
72 fChamberTDHistList(0x0),
73 fChamberTTHistList(0x0)
75 /// Default constructor
77 fIsCosmicData = kFALSE;
80 for (Int_t iCluster = 0; iCluster<fgkNCh; ++iCluster)
81 fNbrClustersCh[iCluster] = 0;
83 for (Int_t i=0; i<fgkNCh; ++i)
87 //_____________________________________________________________________________
88 AliCheckMuonDetEltResponse::AliCheckMuonDetEltResponse(const AliCheckMuonDetEltResponse& src)
93 fIsCosmicData(kFALSE),
98 fDetEltTDHistList(0x0),
99 fDetEltTTHistList(0x0),
100 fChamberTDHistList(0x0),
101 fChamberTTHistList(0x0)
105 //_____________________________________________________________________________
106 AliCheckMuonDetEltResponse& AliCheckMuonDetEltResponse::operator=(const AliCheckMuonDetEltResponse& src)
108 /// assignement operator
116 //_____________________________________________________________________________
117 AliCheckMuonDetEltResponse::AliCheckMuonDetEltResponse(const AliMUONGeometryTransformer* transformer,
119 TClonesArray* detEltTDHistList,
120 TClonesArray* detEltTTHistList,
121 TClonesArray* chamberTDHistList,
122 TClonesArray* chamberTTHistList,
125 fkTransformer(transformer),
128 fIsCosmicData(kFALSE),
133 fDetEltTDHistList(detEltTDHistList),
134 fDetEltTTHistList(detEltTTHistList),
135 fChamberTDHistList(chamberTDHistList),
136 fChamberTTHistList(chamberTTHistList)
140 fIsCosmicData = isCosmic;
141 fNbrUsableTracks = 0;
143 for (Int_t iCluster = 0; iCluster<fgkNCh; ++iCluster)
144 fNbrClustersCh[iCluster] = 0;
146 for (Int_t i=0; i<fgkNCh; ++i)
152 //_____________________________________________________________________________
153 AliCheckMuonDetEltResponse::~AliCheckMuonDetEltResponse()
162 //_____________________________________________________________________________
163 void AliCheckMuonDetEltResponse::CheckDetEltResponse()
166 //Cataloging positions (X,Y) of the clusters detected in the detection elements
167 //(fDetEltTDHistList), and positions of crossing points between all the
168 //tracks and the detection elements (fDetEltTTHistList).
169 //Efficiency = 100 * fDetEltTDHistList / fDetEltTTHistList.
178 //_____________________________________________________________________________
179 void AliCheckMuonDetEltResponse::TrackLoop()
181 // Check if the track is kept
182 AliESDMuonTrack* esdTrack;
184 Int_t nTracks, iTrack;
186 nTracks = (Int_t)fESD -> GetNumberOfMuonTracks();
187 fTrackParams = new TClonesArray();
188 ///Begininig of the loop:
189 //if (fESD->IsTriggerClassFired("CINT1B-ABCE-NOPF-ALL"))
191 for (iTrack = 0; iTrack < nTracks; iTrack++)
193 esdTrack = fESD -> GetMuonTrack(iTrack);
195 if(esdTrack->ContainTrackerData() && esdTrack->GetMatchTrigger() > 0)
199 // Beginnig of long stuff to check the number of trigger hit (to only keep muon trigger and cut cosmic showers)
200 Int_t nTriggerHit = 0;
201 Int_t nTriggerHitStrip[8] = {0, 0, 0, 0,
203 UShort_t triggerPattern[8] = {esdTrack->GetTriggerX1Pattern(), esdTrack->GetTriggerX2Pattern(), esdTrack->GetTriggerX3Pattern(), esdTrack->GetTriggerX4Pattern(),
204 esdTrack->GetTriggerY1Pattern(), esdTrack->GetTriggerY2Pattern(), esdTrack->GetTriggerY3Pattern(), esdTrack->GetTriggerY4Pattern()};
206 for (Int_t ii = 0; ii < 8; ii++)
208 UShort_t pattern = triggerPattern[ii];
209 Int_t binaryValue[16] = {0, 0, 0, 0,
214 for (Int_t jj = 15; jj >= 0; jj--)
217 for (Int_t bb = 0; bb < jj; bb++)
220 if (pattern/base == 1)
223 pattern = pattern - base;
228 for (Int_t ii = 0; ii < 8; ii++)
229 nTriggerHit += nTriggerHitStrip[ii];
234 if (nTriggerHit < 10)
236 AliMUONESDInterface::ESDToMUON(*esdTrack, track);
237 fTrackParams = track.GetTrackParamAtCluster();
238 TrackParamLoop(); //!<Loop on trackParam.
239 fNbrUsableTracks += 1;
243 // No trigger cut is required for non-cosmic data
246 AliMUONESDInterface::ESDToMUON(*esdTrack, track);
247 fTrackParams = track.GetTrackParamAtCluster();
248 TrackParamLoop(); //!<Loop on trackParam.
249 fNbrUsableTracks += 1;
258 //_____________________________________________________________________________
259 void AliCheckMuonDetEltResponse::TrackParamLoop()
261 // Loop on all the track params and fill the histos
262 Int_t nTrackParams = (Int_t) fTrackParams->GetEntriesFast(); //!<Number of trackParams in the track.
263 Int_t iTrackParam = 0; //!<Number of the trackParam of the track.
264 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.
265 Int_t detElt; //!<Detection element Id.
267 for (Int_t ch = 0; ch < fgkNCh; ++ch)
268 fTrackFilter[ch] = 0;
271 Double_t posXL, posYL, posZL; //!<Local positions.
272 Double_t posXG, posYG, posZG; //!<Global. positions.
273 Int_t chamberResponse [10] = {0}; //!<1 if the chamber has responded; 0 if not
275 for (iTrackParam = 0; iTrackParam < nTrackParams; ++iTrackParam)
277 fTrackParam = (AliMUONTrackParam*) fTrackParams->At(iTrackParam);
278 fCluster = (AliMUONVCluster* ) fTrackParam ->GetClusterPtr();
279 fTrackFilter [fCluster->GetChamberId()] = 1;
280 chamberResponse[fCluster->GetChamberId()] = 1;
283 for (Int_t station = 0; station < fgkNSt-1; ++station)
286 Int_t ch1, ch2, ch3, ch4; //<!
287 ch1 = 2*station; //<!
288 ch2 = 2*station + 1; //<!
289 ch3 = 2*station + 2; //<!
290 ch4 = 2*station + 3; //<!
291 //<!For the efficiency calculation the tracks
292 if (station < 3 ) //<!reconstructed must have responded to the
293 { //<!criteria of the tracking.
294 filter = fTrackFilter[ch1]; //<!And that's why the tracks usable for the
295 fTrackFilter[ch1] = fTrackFilter[ch2]; //<!intrinsic efficiency calculation are
296 fTrackFilter[ch2] = filter; //<!the tracks which have one or two clusters
297 } //<!in each station. So the case where a track
298 //<!hasn't a cluster in a station is not
299 else //<!taking into account.
300 { //<!This part solves the problem. See the ALICE
301 if (chamberResponse[ch3]*chamberResponse[ch4] != 0) //<!note of Diego STOCCO on the trigger efficiency
303 filter = fTrackFilter[ch1]; //<!
304 fTrackFilter[ch1] = fTrackFilter[ch2]; //<!
305 fTrackFilter[ch2] = filter; //<!
309 fTrackFilter[ch1] = 0; //<!
310 fTrackFilter[ch2] = 0; //<!
313 if (chamberResponse[ch1]*chamberResponse[ch2] != 0)
315 filter = fTrackFilter[ch3];
316 fTrackFilter[ch3] = fTrackFilter[ch4];
317 fTrackFilter[ch4] = filter;
321 fTrackFilter[ch3] = 0;
322 fTrackFilter[ch4] = 0;
328 ///Begining of the loop:
329 for (iTrackParam = 0; iTrackParam < nTrackParams; ++iTrackParam)
331 fTrackParam = (AliMUONTrackParam*) fTrackParams->At(iTrackParam);
332 fCluster = (AliMUONVCluster* ) fTrackParam ->GetClusterPtr();
334 newChamber = fCluster->GetChamberId();
335 detElt = fCluster->GetDetElemId();
337 ///Global and local positions calculation:
338 posXG = fTrackParam->GetNonBendingCoor();
339 posYG = fTrackParam->GetBendingCoor();
340 posZG = fTrackParam->GetZ();
342 fkTransformer->Global2Local(detElt, posXG, posYG, posZG, posXL, posYL, posZL); //!<Transfomation from global to local positions.
344 ///Filling histograms of the cluster positions on the detection element of the TRACKS DETECTED (TD):
345 FillTDHistos(newChamber, detElt, posXL, posYL);
347 ///Filling histograms of the cluster positions on the detection element of ALL THE TRACKS (TT):
348 FillTTHistos(newChamber, detElt, posXL, posYL);
350 if (newChamber != oldChamber)
352 if (newChamber > oldChamber + 1) //!<Check if it doesn't miss a chamber.
354 Int_t nbrMissChamber = newChamber - (oldChamber + 1);
355 FindAndFillMissedDetElt(fTrackParam, oldChamber+1, nbrMissChamber); //!<Calculation of the parameters of the missing cluster(s).
358 if ( iTrackParam == nTrackParams - 1 && newChamber != fgkNCh-1) //!<Check if the last chamber, chamber 9 (from 0 to 9) has responded.
359 FindAndFillMissedDetElt(fTrackParam, fgkNCh-1, 1); //!<Calculation of the parameters of the missing cluster(s) in the last chamber.
362 oldChamber = newChamber;
368 //_____________________________________________________________________________
369 void AliCheckMuonDetEltResponse::FillTDHistos(Int_t chamber,
374 // Fill the histo for tracks detected
375 if(fTrackFilter[chamber]== 1)
377 Int_t iDet = 0; //!<Position of the detection element in the histograms' list.
378 iDet = FromDetElt2iDet(chamber, detElt);
379 ((TH2F*) fDetEltTDHistList->UncheckedAt(iDet))->Fill(posXL, posYL);
380 ((TH2F*) fDetEltTDHistList->UncheckedAt(fgkNDE))->Fill(chamber, 0);
382 Int_t detEltLocalId = 0; //!<Id of the detection element in the station
383 detEltLocalId = FromDetElt2LocalId(chamber, detElt);
384 ((TH1F*) fChamberTDHistList->UncheckedAt(chamber))->Fill(detEltLocalId);
385 ((TH1F*) fChamberTDHistList->UncheckedAt(10))->Fill(chamber);
392 //_____________________________________________________________________________
393 void AliCheckMuonDetEltResponse::FillTTHistos(Int_t chamber,
398 // Fill the histo for total number of tracks
399 if(fTrackFilter[chamber] == 1)
401 Int_t iDet = 0; //!<Position of the detection element in the histograms' list.
402 iDet = FromDetElt2iDet(chamber, detElt);
403 ((TH2F*) fDetEltTTHistList->UncheckedAt(iDet)) -> Fill(posXL, posYL);
404 ((TH2F*) fDetEltTTHistList->UncheckedAt(fgkNDE))->Fill(chamber, 0);
406 Int_t detEltLocalId = 0; //!<Id of the detection element in the station
407 detEltLocalId = FromDetElt2LocalId(chamber, detElt);
408 ((TH1F*) fChamberTTHistList->UncheckedAt(chamber))->Fill(detEltLocalId);
409 ((TH1F*) fChamberTTHistList->UncheckedAt(10))->Fill(chamber);
417 //_____________________________________________________________________________
418 Int_t AliCheckMuonDetEltResponse::FromDetElt2iDet(Int_t chamber,
422 ///Connexion between the detection element X and its position in the list of histograms iX.
425 Int_t iDet = 0; //!<Position of the detection element (detElt) in the histograms' list.
427 if (chamber<4) iDet = detElt-fgkOffset*(chamber+1)+ 4* chamber ;
428 if (chamber>3 && chamber<6) iDet = detElt-fgkOffset*(chamber+1)+18*(chamber-4)+16;
429 if (chamber>5) iDet = detElt-fgkOffset*(chamber+1)+26*(chamber-6)+52;
436 //_____________________________________________________________________________
437 Int_t AliCheckMuonDetEltResponse::FromDetElt2LocalId(Int_t chamber,
441 ///Connexion between the detection element X and its number in the station.
444 Int_t localId = 0; //!<Position of the detection element (detElt) in the histograms' list.
445 localId = detElt - (chamber+1) * 100;
452 //_____________________________________________________________________________
453 void AliCheckMuonDetEltResponse::FindAndFillMissedDetElt(AliMUONTrackParam* extrapTrackParam,
458 ///Find which detection elements should have been hit but were missed,
459 ///and fill the TT histos appropriately
461 for (Int_t iCh = 0; iCh < nbrMissCh; ++iCh)
463 Int_t chamber = firstMissCh + iCh;
464 Int_t nbrOfDetElt = AliMpDEManager::GetNofDEInChamber(chamber, kTRUE); //!<Number of detection elements in the chamber.
466 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).
467 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).
468 Double_t posMiss[2] = {0, 0}; //!<(X, Y) local coordinates of the missing cluster.
470 pos1[2] = AliMUONConstants::DefaultChamberZ(chamber); //!<Z of point 1, defined by being the Z of the chamber in "perfect" position.
471 AliMUONTrackExtrap::ExtrapToZ(extrapTrackParam, pos1[2]);
472 pos1[0] = extrapTrackParam->GetNonBendingCoor(); //!<X of point 1, extrapolated by following the Track.
473 pos1[1] = extrapTrackParam->GetBendingCoor(); //!<Y of point 1, extrapolated by following the Track.
475 pos2[2] = AliMUONConstants::DefaultChamberZ(chamber) + AliMUONConstants::DzCh(); //!<Z of point 2, defined by being the Z of the chamber in "perfect" position
476 AliMUONTrackExtrap::ExtrapToZ(extrapTrackParam, pos2[2]); //!< + plus a small shift (the distance between two stations in a same chamber).
477 pos2[0] = extrapTrackParam->GetNonBendingCoor(); //!<X of point 2, extrapolated by following the Track.
478 pos2[1] = extrapTrackParam->GetBendingCoor(); //!<Y of point 2, extrapolated by following the Track.
482 for (Int_t iDE = 0; iDE < nbrOfDetElt; iDE++) //!<Loop on all the detection element of the chamber
484 Int_t deId = (chamber + 1)*fgkOffset + iDE; //!<detection element Id
486 fkTransformer->Global2Local(deId, pos1[0], pos1[1], pos1[2], pos1[3], pos1[4], pos1[5]); //!<convesrion of point 1 and 2 in the local coordinates
487 fkTransformer->Global2Local(deId, pos2[0], pos2[1], pos2[2], pos2[3], pos2[4], pos2[5]);
489 CoordinatesOfMissingCluster(pos1[3], pos1[4], pos1[5], pos2[3], pos2[4], pos2[5], posMiss[0], posMiss[1]);
491 Bool_t isMissed = kFALSE;
493 isMissed = CoordinatesInDetEltSt12(deId, posMiss[0], posMiss[1]);
495 isMissed = CoordinatesInDetEltSt345(deId, posMiss[0], posMiss[1]);
498 FillTTHistos(chamber, deId, posMiss[0], posMiss[1]);
505 //_____________________________________________________________________________
506 void AliCheckMuonDetEltResponse::CoordinatesOfMissingCluster(Double_t x1, Double_t y1, Double_t z1,
507 Double_t x2, Double_t y2, Double_t z2,
508 Double_t& x, Double_t& y) const
511 //Compute the coordinates of the missing cluster.
512 //There are defined by the intersection between the straigth line joining two extrapolated points (1 and 2) and the detection element plane.
513 //In the local coordinates, this means Z=0 in the parametric equation of the line.
517 t = - z1 / (z2 - z1);
519 x = t * (x2 - x1) + x1;
520 y = t * (y2 - y1) + y1;
524 //_____________________________________________________________________________
525 Bool_t AliCheckMuonDetEltResponse::CoordinatesInDetEltSt345(Int_t DeId, Double_t x, Double_t y)
528 //Return kTRUE if the coordinates are in the Detection Element, for station 3, 4 and 5.
529 //This is done by checking if a pad correspond to the (x, y) position.
535 AliMpSlatSegmentation *segm1 = new AliMpSlatSegmentation(AliMpSegmentation::Instance(kFALSE)->GetSlat(DeId, AliMp::kCath0));
536 AliMpSlatSegmentation *segm2 = new AliMpSlatSegmentation(AliMpSegmentation::Instance(kFALSE)->GetSlat(DeId, AliMp::kCath1));
537 pad1 = segm1->PadByPosition(x, y, kFALSE);
538 pad2 = segm2->PadByPosition(x, y, kFALSE);
540 if (pad1.IsValid() && pad2.IsValid())
547 //_____________________________________________________________________________
548 Bool_t AliCheckMuonDetEltResponse::CoordinatesInDetEltSt12(Int_t DeId, Double_t x, Double_t y)
550 //Return kTRUE if the coordinates are in the Detection Element, for station 1 and 2.
551 //This is done by checking if a pad correspond to the (x, y) position.
556 AliMpSectorSegmentation *segm1 = new AliMpSectorSegmentation(AliMpSegmentation::Instance(kFALSE)->GetSector(DeId, AliMp::kCath0));
557 AliMpSectorSegmentation *segm2 = new AliMpSectorSegmentation(AliMpSegmentation::Instance(kFALSE)->GetSector(DeId, AliMp::kCath1));
558 pad1 = segm1->PadByPosition(x, y, kFALSE);
559 pad2 = segm2->PadByPosition(x, y, kFALSE);
561 if (pad1.IsValid() && pad2.IsValid())