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 **************************************************************************/
19 ///////////////////////////////////////////////
20 // Manager and hits classes for set:MUON //
21 ////////////////////////////////////////////////
23 #include "Riostream.h"
28 #include <TDirectory.h>
30 #include <TGeometry.h>
34 #include <TObjArray.h>
36 #include <TObjectTable.h>
38 #include <TParticle.h>
41 #include <TRotMatrix.h>
46 #include <TVirtualMC.h>
49 #include "AliHeader.h"
50 #include "AliHitMap.h"
51 #include "AliLoader.h"
52 #include "AliMUONLoader.h"
54 #include "AliMUONChamberTrigger.h"
55 #include "AliMUONClusterFinderVS.h"
56 #include "AliMUONClusterInput.h"
57 #include "AliMUONConstants.h"
58 #include "AliMUONDigit.h"
59 #include "AliMUONGlobalTrigger.h"
60 #include "AliMUONHit.h"
61 #include "AliMUONHitMapA1.h"
62 #include "AliMUONLocalTrigger.h"
63 #include "AliMUONMerger.h"
64 #include "AliMUONPadHit.h"
65 #include "AliMUONRawCluster.h"
66 #include "AliMUONTransientDigit.h"
67 #include "AliMUONTriggerCircuit.h"
68 #include "AliMUONTriggerDecision.h"
72 // Defaults parameters for Z positions of chambers
73 // taken from values for "stations" in AliMUON::AliMUON
74 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
75 // and from array "dstation" in AliMUONv1::CreateGeometry
76 // Float_t dstation[5]={20., 20., 20, 20., 20.};
77 // for tracking chambers,
78 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
79 // for the first and second chambers in the station, respectively,
80 // and from "DTPLANES" in AliMUONv1::CreateGeometry
81 // const Float_t DTPLANES = 15.;
82 // for trigger chambers,
83 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
84 // for the first and second chambers in the station, respectively
87 //__________________________________________________________________
90 // Default Constructor
105 //__________________________________________________________________
106 AliMUON::AliMUON(const char *name, const char *title)
107 : AliDetector(name,title)
111 <img src="gif/alimuon.gif">
118 fNCh = AliMUONConstants::NCh();
119 fNTrackingCh = AliMUONConstants::NTrackingCh();
121 SetMarkerColor(kRed);//
123 // Creating List of Chambers
125 fChambers = new TObjArray(AliMUONConstants::NCh());
126 // Loop over stations
127 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
128 // Loop over 2 chambers in the station
129 for (Int_t stCH = 0; stCH < 2; stCH++) {
132 // Default Parameters for Muon Tracking Stations
134 if (ch < AliMUONConstants::NTrackingCh()) {
135 fChambers->AddAt(new AliMUONChamber(ch),ch);
137 fChambers->AddAt(new AliMUONChamberTrigger(ch),ch);
139 AliMUONChamber* chamber = (AliMUONChamber*) fChambers->At(ch);
141 // Default values for Z of chambers
142 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
144 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
145 // Set chamber inner and outer radius to default
146 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
147 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
149 } // Chamber stCH (0, 1) in
150 } // Station st (0...)
152 // Negatives values are ignored by geant3 CONS200 in the calculation of the tracking parameters
165 // cp new design of AliMUONTriggerDecision
166 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
167 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
168 fTriggerCircuits->AddAt(new AliMUONTriggerCircuit(),circ);
172 //____________________________________________________________________
173 AliMUON::AliMUON(const AliMUON& rMUON):AliDetector(rMUON)
175 // Dummy copy constructor
179 //____________________________________________________________________
183 if(fDebug) printf("%s: Calling AliMUON destructor !!!\n",ClassName());
185 if (fMerger) delete fMerger;
187 //____________________________________________________________________
188 void AliMUON::BuildGeometry()
190 // Geometry for event display
191 for (Int_t i=0; i<7; i++) {
192 for (Int_t j=0; j<2; j++) {
194 this->Chamber(id-1).SegmentationModel(1)->Draw("eventdisplay");
198 //___________________________________________________________________
199 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
203 //__________________________________________________________________
204 void AliMUON::SetTreeAddress()
206 GetMUONData()->SetLoader(fLoader);
207 GetMUONData()->SetTreeAddress("H,D,RC");
208 fHits = GetMUONData()->Hits(); // Added by Ivana to use the methods FisrtHit, NextHit of AliDetector
211 //____________________________________________________________________
212 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
214 // Set the pad size for chamber id and cathode isec
216 ((AliMUONChamber*) fChambers->At(i)) ->SetPadSize(isec,p1,p2);
217 ((AliMUONChamber*) fChambers->At(i+1))->SetPadSize(isec,p1,p2);
220 //___________________________________________
221 void AliMUON::SetChambersZ(const Float_t *Z)
223 // Set Z values for all chambers (tracking and trigger)
224 // from the array pointed to by "Z"
225 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
226 ((AliMUONChamber*) fChambers->At(ch))->SetZ(Z[ch]);
229 //_________________________________________________________________
230 void AliMUON::SetChambersZToDefault()
232 // Set Z values for all chambers (tracking and trigger)
234 SetChambersZ(AliMUONConstants::DefaultChamberZ());
237 //_________________________________________________________________
238 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
240 // Set the inverse charge slope for chamber id
241 Int_t i=2*(id-1); //PH ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
242 //PH ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
243 ((AliMUONChamber*) fChambers->At(i))->SetChargeSlope(p1);
244 ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSlope(p1);
246 //__________________________________________________________________
247 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
249 // Set sigma of charge spread for chamber id
251 ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
252 ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSpread(p1,p2);
254 //___________________________________________________________________
255 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
257 // Set integration limits for charge spread
259 ((AliMUONChamber*) fChambers->At(i))->SetSigmaIntegration(p1);
260 ((AliMUONChamber*) fChambers->At(i+1))->SetSigmaIntegration(p1);
263 //__________________________________________________________________
264 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
266 // Set maximum number for ADCcounts (saturation)
268 ((AliMUONChamber*) fChambers->At(i))->SetMaxAdc(p1);
269 ((AliMUONChamber*) fChambers->At(i+1))->SetMaxAdc(p1);
271 //__________________________________________________________________
272 void AliMUON::SetMaxStepGas(Float_t p1)
274 // Set stepsize in gas
277 //__________________________________________________________________
278 void AliMUON::SetMaxStepAlu(Float_t p1)
280 // Set step size in Alu
283 //__________________________________________________________________
284 void AliMUON::SetMaxDestepGas(Float_t p1)
286 // Set maximum step size in Gas
289 //__________________________________________________________________
290 void AliMUON::SetMaxDestepAlu(Float_t p1)
292 // Set maximum step size in Alu
295 //___________________________________________________________________
296 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
298 // Set acceptance cuts
300 fAccMin=angmin*TMath::Pi()/180;
301 fAccMax=angmax*TMath::Pi()/180;
304 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
305 // Loop over 2 chambers in the station
306 for (Int_t stCH = 0; stCH < 2; stCH++) {
308 // Set chamber inner and outer radius according to acceptance cuts
309 Chamber(ch).SetRInner(TMath::Abs(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin)));
310 Chamber(ch).SetROuter(TMath::Abs(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax)));
315 //____________________________________________________________________
316 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
318 // Set the segmentation for chamber id cathode isec
319 ((AliMUONChamber*) fChambers->At(id))->SetSegmentationModel(isec, segmentation);
322 //____________________________________________________________________
323 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
325 // Set the response for chamber id
326 ((AliMUONChamber*) fChambers->At(id))->SetResponseModel(response);
328 //____________________________________________________________________
329 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
331 // Set ClusterFinder for chamber id
332 ((AliMUONChamber*) fChambers->At(id))->SetReconstructionModel(reconst);
334 //____________________________________________________________________
335 void AliMUON::SetNsec(Int_t id, Int_t nsec)
337 // Set number of segmented cathods for chamber id
338 ((AliMUONChamber*) fChambers->At(id))->SetNsec(nsec);
340 //_____________________________________________________________________
341 void AliMUON::SDigits2Digits()
347 if (gAlice->GetDebug()>0) {
348 cerr<<"AliMUON::SDigits2Digits: create default AliMUONMerger "<<endl;
349 cerr<<" no merging, just digitization of 1 event will be done"<<endl;
351 fMerger = new AliMUONMerger();
356 // sprintf(hname,"TreeD%d",fLoader->GetHeader()->GetEvent());
357 fLoader->TreeD()->Write(hname,TObject::kOverwrite);
358 fLoader->TreeD()->Reset();
361 //_______________________________________________________________________
362 AliLoader* AliMUON::MakeLoader(const char* topfoldername)
364 //builds standard getter (AliLoader type)
365 //if detector wants to use castomized getter, it must overload this method
369 "Creating standard getter for detector %s. Top folder is %s.",
370 GetName(),topfoldername);
372 fLoader = new AliLoader(GetName(),topfoldername);
373 fMUONData = new AliMUONData(fLoader,GetName(),GetName());
374 fMUONData->SetSplitLevel(fSplitLevel);
378 //_______________________________________________________________________
379 void AliMUON::Trigger(Int_t nev){
380 // call the Trigger Algorithm and fill TreeR
382 Int_t singlePlus[3] = {0,0,0};
383 Int_t singleMinus[3] = {0,0,0};
384 Int_t singleUndef[3] = {0,0,0};
385 Int_t pairUnlike[3] = {0,0,0};
386 Int_t pairLike[3] = {0,0,0};
389 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
391 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
392 pairUnlike, pairLike);
394 // add a local trigger in the list
395 GetMUONData()->AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
398 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
399 if(decision->GetITrigger(icirc)==1) {
400 Int_t localtr[7]={0,0,0,0,0,0,0};
401 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
402 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
404 localtr[1] = decision->GetStripX11(icirc);
405 localtr[2] = decision->GetDev(icirc);
406 localtr[3] = decision->GetStripY11(icirc);
407 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
408 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
409 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
410 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
412 GetMUONData()->AddLocalTrigger(localtr); // add a local trigger in the list
418 // fLoader->TreeR()->Fill();
419 GetMUONData()->Fill("GLT"); //Filling Global and Local Trigger GLT
421 // sprintf(hname,"TreeR%d",nev);
422 // fLoader->TreeR()->Write(hname,TObject::kOverwrite);
423 // fLoader->TreeR()->Reset();
424 fLoader->WriteRecPoints("OVERWRITE");
426 printf("\n End of trigger for event %d", nev);
429 //____________________________________________________________________
430 void AliMUON::Digits2Reco()
433 Int_t nev = gAlice->GetHeader()->GetEvent();
434 GetMUONData()->Fill("RC"); //Filling Reconstructed Cluster
435 fLoader->WriteRecPoints("OVERWRITE");
436 GetMUONData()->ResetRawClusters();
437 Info("Digits2Reco","End of cluster finding for event %d", nev);
439 //____________________________________________________________________
440 void AliMUON::FindClusters()
443 // Perform cluster finding
445 TClonesArray *dig1, *dig2;
447 dig1 = new TClonesArray("AliMUONDigit",1000);
448 dig2 = new TClonesArray("AliMUONDigit",1000);
450 // Loop on chambers and on cathode planes
453 TClonesArray * muonDigits;
455 for (Int_t ich = 0; ich < 10; ich++) {
456 //PH AliMUONChamber* iChamber = (AliMUONChamber*) (*fChambers)[ich];
457 AliMUONChamber* iChamber = (AliMUONChamber*) fChambers->At(ich);
458 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
461 GetMUONData()->GetCathode(0);
463 muonDigits = GetMUONData()->Digits(ich);
464 ndig=muonDigits->GetEntriesFast();
465 printf("\n 1 Found %d digits in %p chamber %d", ndig, muonDigits,ich);
466 TClonesArray &lhits1 = *dig1;
468 for (k = 0; k < ndig; k++) {
469 digit = (AliMUONDigit*) muonDigits->UncheckedAt(k);
470 if (rec->TestTrack(digit->Track(0)))
471 new(lhits1[n++]) AliMUONDigit(*digit);
473 GetMUONData()->ResetDigits();
474 GetMUONData()->GetCathode(1);
475 muonDigits = GetMUONData()->Digits(ich);
476 ndig=muonDigits->GetEntriesFast();
477 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
478 TClonesArray &lhits2 = *dig2;
481 for (k=0; k<ndig; k++) {
482 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
483 if (rec->TestTrack(digit->Track(0)))
484 new(lhits2[n++]) AliMUONDigit(*digit);
488 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
489 rec->FindRawClusters();
497 //______________________________________________________________________
499 void AliMUON::Streamer(TBuffer &R__b)_
501 // Stream an object of class AliMUON.
502 AliMUONChamber *iChamber;
503 AliMUONTriggerCircuit *iTriggerCircuit;
504 AliSegmentation *segmentation;
505 AliMUONResponse *response;
506 TClonesArray *digitsaddress;
507 TClonesArray *rawcladdress;
509 if (R__b.IsReading()) {
510 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
511 AliDetector::Streamer(R__b);
513 R__b >> fPadHits; // diff
514 R__b >> fNLocalTrigger;
515 R__b >> fLocalTrigger;
516 R__b >> fNGlobalTrigger;
517 R__b >> fGlobalTrigger;
519 R__b >> fRawClusters;
520 R__b.ReadArray(fNdch);
521 R__b.ReadArray(fNrawch);
526 R__b >> fTriggerCircuits;
527 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
528 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
529 iTriggerCircuit->Streamer(R__b);
531 // Stream chamber related information
532 for (i =0; i<AliMUONConstants::NCh(); i++) {
533 iChamber=(AliMUONChamber*) (*fChambers)[i];
534 iChamber->Streamer(R__b);
535 if (iChamber->Nsec()==1) {
536 segmentation=iChamber->SegmentationModel(1);
538 segmentation->Streamer(R__b);
540 segmentation=iChamber->SegmentationModel(1);
542 segmentation->Streamer(R__b);
544 segmentation=iChamber->SegmentationModel(2);
545 segmentation->Streamer(R__b);
547 response=iChamber->ResponseModel();
549 response->Streamer(R__b);
550 digitsaddress=(TClonesArray*) (*fDchambers)[i];
551 digitsaddress->Streamer(R__b);
552 if (i < AliMUONConstants::NTrackingCh()) {
553 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
554 rawcladdress->Streamer(R__b);
559 R__b.WriteVersion(AliMUON::IsA());
560 AliDetector::Streamer(R__b);
562 R__b << fPadHits; // diff
563 R__b << fNLocalTrigger;
564 R__b << fLocalTrigger;
565 R__b << fNGlobalTrigger;
566 R__b << fGlobalTrigger;
568 R__b << fRawClusters;
569 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
570 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
577 R__b << fTriggerCircuits;
578 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
579 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
580 iTriggerCircuit->Streamer(R__b);
582 for (i =0; i<AliMUONConstants::NCh(); i++) {
583 iChamber=(AliMUONChamber*) (*fChambers)[i];
584 iChamber->Streamer(R__b);
585 if (iChamber->Nsec()==1) {
586 segmentation=iChamber->SegmentationModel(1);
588 segmentation->Streamer(R__b);
590 segmentation=iChamber->SegmentationModel(1);
592 segmentation->Streamer(R__b);
593 segmentation=iChamber->SegmentationModel(2);
595 segmentation->Streamer(R__b);
597 response=iChamber->ResponseModel();
599 response->Streamer(R__b);
600 digitsaddress=(TClonesArray*) (*fDchambers)[i];
601 digitsaddress->Streamer(R__b);
602 if (i < AliMUONConstants::NTrackingCh()) {
603 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
604 rawcladdress->Streamer(R__b);
610 //_______________________________________________________________________
611 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
614 // Initialise the pad iterator
615 // Return the address of the first padhit for hit
616 TClonesArray *theClusters = clusters;
617 Int_t nclust = theClusters->GetEntriesFast();
618 if (nclust && hit->PHlast() > 0) {
619 AliMUON::fMaxIterPad=hit->PHlast();
620 AliMUON::fCurIterPad=hit->PHfirst();
621 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
626 //_______________________________________________________________________
627 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
630 // Get next pad (in iterator)
632 AliMUON::fCurIterPad++;
633 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
634 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
639 //_______________________________________________________________________
641 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
644 // Return rawcluster (icluster) for chamber ichamber and cathode icathod
646 TClonesArray *muonRawCluster = GetMUONData()->RawClusters(ichamber);
648 TTree *treeR = fLoader->TreeR();
649 Int_t nent=(Int_t)treeR->GetEntries();
650 treeR->GetEvent(nent-2+icathod-1);
651 //treeR->GetEvent(icathod);
652 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
654 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
655 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
659 //________________________________________________________________________
660 void AliMUON::SetMerger(AliMUONMerger* merger)
662 // Set pointer to merger
665 //________________________________________________________________________
666 AliMUONMerger* AliMUON::Merger()
668 // Return pointer to merger
671 //________________________________________________________________________
672 AliMUON& AliMUON::operator = (const AliMUON& /*rhs*/)