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 **************************************************************************/
17 Revision 1.30 2000/10/02 16:58:29 egangler
18 Cleaning of the code :
21 -> some useless includes removed or replaced by "class" statement
23 Revision 1.29 2000/07/28 13:49:38 morsch
24 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
25 Can be used for simple acceptance studies.
27 Revision 1.28 2000/07/22 16:43:15 morsch
28 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
30 Revision 1.27 2000/07/22 16:36:50 morsch
31 Change order of indices in creation (new) of xhit and yhit
33 Revision 1.26 2000/07/03 11:54:57 morsch
34 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
35 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
37 Revision 1.25 2000/06/29 12:34:09 morsch
38 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
39 it usable with any other geometry class. The link to the object to which it belongs is
40 established via an index. This assumes that there exists a global geometry manager
41 from which the pointer to the parent object can be obtained (in our case gAlice).
43 Revision 1.24 2000/06/28 15:16:35 morsch
44 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
45 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
46 framework. The changes should have no side effects (mostly dummy arguments).
47 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
48 of chambers with overlapping modules (MakePadHits, Disintegration).
50 Revision 1.23 2000/06/28 12:19:17 morsch
51 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
52 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
53 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
54 It requires two cathode planes. Small modifications in the code will make it usable for
55 one cathode plane and, hence, more general (for test beam data).
56 AliMUONClusterFinder is now obsolete.
58 Revision 1.22 2000/06/28 08:06:10 morsch
59 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
60 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
61 It also naturally takes care of the TMinuit instance.
63 Revision 1.21 2000/06/27 08:54:41 morsch
64 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
66 Revision 1.20 2000/06/26 14:02:38 morsch
67 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
69 Revision 1.19 2000/06/22 13:40:51 morsch
70 scope problem on HP, "i" declared once
71 pow changed to TMath::Power (PH, AM)
73 Revision 1.18 2000/06/15 07:58:48 morsch
74 Code from MUON-dev joined
76 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
77 - add TriggerCircuit (PC)
78 - add GlobalTrigger and LocalTrigger and specific methods (PC)
80 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
81 Most coding rule violations corrected
83 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
84 RULE RN17 violations corrected
86 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
87 Code revised by P. Crochet:
88 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
89 - ToF included in the method MakePadHits
90 - inner radius of flange between beam shielding and trigger corrected
91 - Trigger global volume updated (according to the new geometry)
93 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
94 Some changes of variable names curing viols and methods concerning
95 correlated clusters removed.
97 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
98 Memory leak suppressed in function Digitise:
99 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
101 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
102 Positions of trigger chambers corrected (P.C.)
104 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
105 Call to AddHitList introduced to make this version compatible with head.
107 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
108 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
110 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
111 Trigger included into initialization and digitization
113 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
114 Log messages of previous revisions added
116 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
117 Z position of the chambers:
118 it was the Z position of the stations;
119 it is now really the Z position of the chambers.
120 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
121 !!!! AND "AliMUONChamber::ZPosition"
122 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
123 !!!! AND "AliMUONChamber::Z"
125 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
126 Correction for mis-spelling of NCH
128 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
134 ///////////////////////////////////////////////
135 // Manager and hits classes for set:MUON //
136 ////////////////////////////////////////////////
140 #include <TRotMatrix.h>
141 #include <TGeometry.h>
147 #include <TObjArray.h>
149 #include <TParticle.h>
155 #include <TDirectory.h>
156 #include <TObjectTable.h>
161 #include "AliMUONHit.h"
162 #include "AliMUONPadHit.h"
163 #include "AliMUONDigit.h"
164 #include "AliMUONTransientDigit.h"
165 #include "AliMUONRawCluster.h"
166 #include "AliMUONLocalTrigger.h"
167 #include "AliMUONGlobalTrigger.h"
168 #include "AliMUONTriggerCircuit.h"
169 #include "AliHitMap.h"
170 #include "AliMUONHitMapA1.h"
171 #include "AliMUONChamberTrigger.h"
172 #include "AliMUONConstants.h"
173 #include "AliMUONClusterFinderVS.h"
174 #include "AliMUONTriggerDecision.h"
177 #include "AliMUONClusterInput.h"
178 #include "iostream.h"
179 #include "AliCallf77.h"
180 #include "AliConst.h"
182 // Defaults parameters for Z positions of chambers
183 // taken from values for "stations" in AliMUON::AliMUON
184 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
185 // and from array "dstation" in AliMUONv1::CreateGeometry
186 // Float_t dstation[5]={20., 20., 20, 20., 20.};
187 // for tracking chambers,
188 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
189 // for the first and second chambers in the station, respectively,
190 // and from "DTPLANES" in AliMUONv1::CreateGeometry
191 // const Float_t DTPLANES = 15.;
192 // for trigger chambers,
193 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
194 // for the first and second chambers in the station, respectively
197 //___________________________________________
205 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
218 //___________________________________________
219 AliMUON::AliMUON(const char *name, const char *title)
220 : AliDetector(name,title)
224 <img src="gif/alimuon.gif">
228 fHits = new TClonesArray("AliMUONHit",1000);
229 gAlice->AddHitList(fHits);
230 fPadHits = new TClonesArray("AliMUONPadHit",10000);
234 fNdch = new Int_t[AliMUONConstants::NCh()];
236 fDchambers = new TObjArray(AliMUONConstants::NCh());
240 for (i=0; i<AliMUONConstants::NCh() ;i++) {
241 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
245 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
247 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
249 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
250 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
254 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
256 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
259 SetMarkerColor(kRed);
267 fChambers = new TObjArray(AliMUONConstants::NCh());
269 // Loop over stations
270 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
271 // Loop over 2 chambers in the station
272 for (Int_t stCH = 0; stCH < 2; stCH++) {
275 // Default Parameters for Muon Tracking Stations
280 if (ch < AliMUONConstants::NTrackingCh()) {
281 (*fChambers)[ch] = new AliMUONChamber(ch);
283 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
286 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
289 // Default values for Z of chambers
290 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
292 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
293 // Set chamber inner and outer radius to default
294 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
295 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
297 } // Chamber stCH (0, 1) in
298 } // Station st (0...)
311 // cp new design of AliMUONTriggerDecision
312 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
313 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
314 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
316 // cp new design of AliMUONTriggerDecision
320 //___________________________________________
321 AliMUON::AliMUON(const AliMUON& rMUON)
323 // Dummy copy constructor
330 printf("Calling AliMUON destructor !!!\n");
337 delete fGlobalTrigger;
340 delete fLocalTrigger;
343 for (i=0;i<AliMUONConstants::NCh();i++) {
344 delete (*fDchambers)[i];
349 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
350 delete (*fRawClusters)[i];
355 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
356 delete (*fTriggerCircuits)[circ];
358 delete fTriggerCircuits;
361 //___________________________________________
362 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
364 TClonesArray &lhits = *fHits;
365 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
367 //___________________________________________
368 void AliMUON::AddPadHit(Int_t *clhits)
370 TClonesArray &lclusters = *fPadHits;
371 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
373 //_____________________________________________________________________________
374 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
377 // Add a MUON digit to the list
380 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
381 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
384 //_____________________________________________________________________________
385 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
388 // Add a MUON digit to the list
391 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
392 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
395 //___________________________________________
396 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
398 Int_t *pairUnlike, Int_t *pairLike)
400 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
401 TClonesArray &globalTrigger = *fGlobalTrigger;
402 new(globalTrigger[fNGlobalTrigger++])
403 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
406 //___________________________________________
407 void AliMUON::AddLocalTrigger(Int_t *localtr)
409 // add a MUON Local Trigger to the list
410 TClonesArray &localTrigger = *fLocalTrigger;
411 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
414 //___________________________________________
415 void AliMUON::BuildGeometry()
417 TNode *node, *nodeF, *top, *nodeS;
418 const int kColorMUON = kBlue;
419 const int kColorMUON2 = kGreen;
421 top=gAlice->GetGeometry()->GetNode("alice");
424 // z-Positions of Chambers
425 const Float_t kCz[7]={511., 686., 971., 1245., 1445., 1600, 1700.};
426 // inner diameter (Xlenght for trigger chamber -> active area)
427 const Float_t kDmin[7]={ 35., 47., 67., 86., 100., 544., 544.};
428 // outer diameter (Ylenght for trigger chamber -> active area)
429 const Float_t kDmax[7]={183., 245., 346., 520., 520., 612., 612.};
431 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
432 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
433 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
434 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
436 Float_t rmin, rmax, dx, dy, dz, dr, xpos, ypos, zpos;
437 Float_t dzc1=4.; // tracking chambers
438 Float_t dzc2=15.; // trigger chambers
439 Float_t hole=102.; // x-y hole around beam pipe for trig. chambers
440 Float_t zscale; // scaling parameter trigger chambers
441 Float_t halfx, halfy;
442 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[8];
443 char nameSense1[9], nameSense2[9];
444 for (Int_t i=0; i<7; i++) {
445 for (Int_t j=0; j<2; j++) {
447 if (i<5) { // tracking chambers
460 sprintf(nameChamber,"C_MUON%d",id);
461 sprintf(nameSense,"S_MUON%d",id);
462 sprintf(nameSense1,"S1_MUON%d",id);
463 sprintf(nameSense2,"S2_MUON%d",id);
464 sprintf(nameFrame,"F_MUON%d",id);
465 if (i<5) { // tracking chambers
466 rmin = kDmin[i]/2.-3;
467 rmax = kDmax[i]/2.+3;
468 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
471 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
475 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
477 sprintf(nameNode,"MUON%d",100+id);
478 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,zpos,"");
479 node->SetLineColor(kColorMUON);
482 sprintf(nameNode,"MUON%d",200+id);
483 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
484 node->SetLineColor(kColorMUON);
487 sprintf(nameNode,"MUON%d",300+id);
488 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
489 nodeF->SetLineColor(kColorMUON);
491 sprintf(nameNode,"MUON%d",400+id);
492 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
493 nodeF->SetLineColor(kColorMUON);
495 sprintf(nameNode,"MUON%d",500+id);
496 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
497 nodeF->SetLineColor(kColorMUON);
499 sprintf(nameNode,"MUON%d",600+id);
500 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
501 nodeF->SetLineColor(kColorMUON);
504 Float_t xsize=kDmin[i]*zscale;
505 Float_t ysize=kDmax[i]*zscale;
506 Float_t holeScaled=hole*zscale;
510 new TBRIK(nameChamber,"Mother","void",halfx,halfy,0.25);
512 sprintf(nameNode,"MUON%d",100+id);
513 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
514 node->SetLineColor(kColorMUON2);
517 // up/down of beam pipe
519 halfy=(ysize/2.-holeScaled/2.)/2.;
520 new TBRIK(nameSense,"Sens. region","void",halfx,halfy,0.25);
523 ypos=holeScaled/2.+((ysize/2.-holeScaled/2.)/2.);
524 sprintf(nameNode,"MUON%d",200+id);
525 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
526 nodeS->SetLineColor(kColorMUON2);
530 sprintf(nameNode,"MUON%d",300+id);
531 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
532 nodeS->SetLineColor(kColorMUON2);
534 // left/right of beam pipe
535 halfx=(xsize/2.-holeScaled/2.)/2.;
537 new TBRIK(nameSense1,"Sens. region","void",halfx,halfy,0.25);
540 xpos=holeScaled/2.+((xsize/2.-holeScaled/2.)/2.);
541 sprintf(nameNode,"MUON%d",400+id);
542 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
543 nodeS->SetLineColor(kColorMUON2);
547 sprintf(nameNode,"MUON%d",500+id);
548 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
549 nodeS->SetLineColor(kColorMUON2);
554 new TBRIK(nameSense2,"Sens. region","void",halfx,halfy,0.25);
557 xpos=holeScaled/2.-halfx;
559 sprintf(nameNode,"MUON%d",600+id);
560 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
561 nodeS->SetLineColor(kColorMUON2);
565 sprintf(nameNode,"MUON%d",700+id);
566 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
567 nodeS->SetLineColor(kColorMUON2);
571 sprintf(nameNode,"MUON%d",800+id);
572 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
573 nodeS->SetLineColor(kColorMUON2);
577 sprintf(nameNode,"MUON%d",900+id);
578 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
579 nodeS->SetLineColor(kColorMUON2);
586 //___________________________________________
587 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
592 //___________________________________________
593 void AliMUON::MakeBranch(Option_t* option)
595 // Create Tree branches for the MUON.
596 const Int_t kBufferSize = 4000;
598 sprintf(branchname,"%sCluster",GetName());
600 AliDetector::MakeBranch(option);
602 if (fPadHits && gAlice->TreeH()) {
603 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
604 printf("Making Branch %s for clusters\n",branchname);
607 // one branch for digits per chamber
610 for (i=0; i<AliMUONConstants::NCh() ;i++) {
611 sprintf(branchname,"%sDigits%d",GetName(),i+1);
613 if (fDchambers && gAlice->TreeD()) {
614 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
615 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
619 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
621 // one branch for raw clusters per chamber
622 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
623 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
625 if (fRawClusters && gAlice->TreeR()) {
626 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
627 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
631 // one branch for global trigger
632 sprintf(branchname,"%sGlobalTrigger",GetName());
633 if (fGlobalTrigger && gAlice->TreeR()) {
634 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
635 printf("Making Branch %s for Global Trigger\n",branchname);
637 // one branch for local trigger
638 sprintf(branchname,"%sLocalTrigger",GetName());
639 if (fLocalTrigger && gAlice->TreeR()) {
640 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
641 printf("Making Branch %s for Local Trigger\n",branchname);
646 //___________________________________________
647 void AliMUON::SetTreeAddress()
649 // Set branch address for the Hits and Digits Tree.
651 AliDetector::SetTreeAddress();
654 TTree *treeH = gAlice->TreeH();
655 TTree *treeD = gAlice->TreeD();
656 TTree *treeR = gAlice->TreeR();
660 branch = treeH->GetBranch("MUONCluster");
661 if (branch) branch->SetAddress(&fPadHits);
666 for (int i=0; i<AliMUONConstants::NCh(); i++) {
667 sprintf(branchname,"%sDigits%d",GetName(),i+1);
669 branch = treeD->GetBranch(branchname);
670 if (branch) branch->SetAddress(&((*fDchambers)[i]));
675 // printf("SetTreeAddress --- treeR address %p \n",treeR);
678 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
679 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
681 branch = treeR->GetBranch(branchname);
682 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
687 branch = treeR->GetBranch("MUONLocalTrigger");
688 if (branch) branch->SetAddress(&fLocalTrigger);
690 if (fGlobalTrigger) {
691 branch = treeR->GetBranch("MUONGlobalTrigger");
692 if (branch) branch->SetAddress(&fGlobalTrigger);
696 //___________________________________________
697 void AliMUON::ResetHits()
699 // Reset number of clusters and the cluster array for this detector
700 AliDetector::ResetHits();
702 if (fPadHits) fPadHits->Clear();
705 //____________________________________________
706 void AliMUON::ResetDigits()
709 // Reset number of digits and the digits array for this detector
711 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
712 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
713 if (fNdch) fNdch[i]=0;
716 //____________________________________________
717 void AliMUON::ResetRawClusters()
720 // Reset number of raw clusters and the raw clust array for this detector
722 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
723 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
724 if (fNrawch) fNrawch[i]=0;
728 //____________________________________________
729 void AliMUON::ResetTrigger()
731 // Reset Local and Global Trigger
733 if (fGlobalTrigger) fGlobalTrigger->Clear();
735 if (fLocalTrigger) fLocalTrigger->Clear();
738 //____________________________________________
739 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
742 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
743 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
746 //___________________________________________
747 void AliMUON::SetChambersZ(const Float_t *Z)
749 // Set Z values for all chambers (tracking and trigger)
750 // from the array pointed to by "Z"
751 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
752 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
756 //___________________________________________
757 void AliMUON::SetChambersZToDefault()
759 // Set Z values for all chambers (tracking and trigger)
761 SetChambersZ(AliMUONConstants::DefaultChamberZ());
765 //___________________________________________
766 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
769 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
770 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
773 //___________________________________________
774 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
777 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
778 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
781 //___________________________________________
782 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
785 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
786 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
789 //___________________________________________
790 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
793 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
794 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
797 //___________________________________________
798 void AliMUON::SetMaxStepGas(Float_t p1)
803 //___________________________________________
804 void AliMUON::SetMaxStepAlu(Float_t p1)
809 //___________________________________________
810 void AliMUON::SetMaxDestepGas(Float_t p1)
815 //___________________________________________
816 void AliMUON::SetMaxDestepAlu(Float_t p1)
820 //___________________________________________
821 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
824 fAccMin=angmin*TMath::Pi()/180;
825 fAccMax=angmax*TMath::Pi()/180;
828 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
829 // Loop over 2 chambers in the station
830 for (Int_t stCH = 0; stCH < 2; stCH++) {
832 // Set chamber inner and outer radius according to acceptance cuts
833 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
834 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
839 //___________________________________________
840 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
842 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
845 //___________________________________________
846 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
848 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
851 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
853 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
856 void AliMUON::SetNsec(Int_t id, Int_t nsec)
858 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
862 //___________________________________________
866 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
867 Float_t eloss, Float_t tof, Int_t idvol)
870 // Calls the charge disintegration method of the current chamber and adds
871 // the simulated cluster to the root treee
874 Float_t newclust[6][500];
879 // Integrated pulse height on chamber
885 ((AliMUONChamber*) (*fChambers)[idvol])
886 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
891 for (Int_t i=0; i<nnew; i++) {
892 if (Int_t(newclust[3][i]) > 0) {
895 clhits[1] = Int_t(newclust[5][i]);
897 clhits[2] = Int_t(newclust[0][i]);
899 clhits[3] = Int_t(newclust[1][i]);
901 clhits[4] = Int_t(newclust[2][i]);
903 clhits[5] = Int_t(newclust[3][i]);
904 // Pad: chamber sector
905 clhits[6] = Int_t(newclust[4][i]);
912 //----------------------------------------------------------------------
914 void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
916 // keep galice.root for signal and name differently the file for
917 // background when add! otherwise the track info for signal will be lost !
919 static Bool_t first=kTRUE;
921 char *addBackground = strstr(option,"Add");
924 AliMUONChamber* iChamber;
925 AliSegmentation* segmentation;
930 TObjArray *list=new TObjArray;
931 static TClonesArray *pAddress=0;
932 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
935 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
936 AliHitMap** hitMap= new AliHitMap* [AliMUONConstants::NCh()];
937 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
938 if (addBackground ) {
941 cout<<"filename"<<fFileName<<endl;
942 file=new TFile(fFileName);
943 cout<<"I have opened "<<fFileName<<" file "<<endl;
944 fHits2 = new TClonesArray("AliMUONHit",1000 );
945 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
950 // Get Hits Tree header from file
951 if(fHits2) fHits2->Clear();
952 if(fPadHits2) fPadHits2->Clear();
953 if(fTrH1) delete fTrH1;
957 sprintf(treeName,"TreeH%d",bgrEvent);
958 fTrH1 = (TTree*)gDirectory->Get(treeName);
959 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
962 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
964 // Set branch addresses
967 sprintf(branchname,"%s",GetName());
968 if (fTrH1 && fHits2) {
969 branch = fTrH1->GetBranch(branchname);
970 if (branch) branch->SetAddress(&fHits2);
972 if (fTrH1 && fPadHits2) {
973 branch = fTrH1->GetBranch("MUONCluster");
974 if (branch) branch->SetAddress(&fPadHits2);
977 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
978 //printf("background - ntracks1 - %d\n",ntracks1);
981 // loop over cathodes
985 for (int icat=0; icat<2; icat++) {
987 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
988 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
989 iChamber=(AliMUONChamber*) (*fChambers)[i];
990 if (iChamber->Nsec()==1 && icat==1) {
993 segmentation=iChamber->SegmentationModel(icat+1);
995 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
998 //printf("Start loop over tracks \n");
1003 TTree *treeH = gAlice->TreeH();
1004 Int_t ntracks =(Int_t) treeH->GetEntries();
1007 Float_t ** xhit = new Float_t * [AliMUONConstants::NCh()];
1008 for (jj=0; jj<AliMUONConstants::NCh(); jj++) xhit[jj] = new Float_t[2];
1009 Float_t ** yhit = new Float_t * [AliMUONConstants::NCh()];
1010 for (jj=0; jj<AliMUONConstants::NCh(); jj++) yhit[jj] = new Float_t[2];
1012 for (Int_t track=0; track<ntracks; track++) {
1013 gAlice->ResetHits();
1014 treeH->GetEvent(track);
1017 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
1019 mHit=(AliMUONHit*)pMUON->NextHit())
1021 Int_t nch = mHit->fChamber-1; // chamber number
1022 if (nch > AliMUONConstants::NCh()-1) continue;
1023 iChamber = &(pMUON->Chamber(nch));
1025 if (addBackground) {
1027 if (mHit->fParticle == kMuonPlus
1028 || mHit->fParticle == kMuonMinus) {
1029 xhit[nch][nmuon[nch]]=mHit->X();
1030 yhit[nch][nmuon[nch]]=mHit->Y();
1032 if (nmuon[nch] >2) printf("nmuon %d\n",nmuon[nch]);
1040 // Loop over pad hits
1041 for (AliMUONPadHit* mPad=
1042 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
1044 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
1046 Int_t cathode = mPad->fCathode; // cathode number
1047 Int_t ipx = mPad->fPadX; // pad number on X
1048 Int_t ipy = mPad->fPadY; // pad number on Y
1049 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1053 if (cathode != (icat+1)) continue;
1054 // fill the info array
1055 Float_t thex, they, thez;
1056 segmentation=iChamber->SegmentationModel(cathode);
1057 segmentation->GetPadC(ipx,ipy,thex,they,thez);
1058 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1059 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1061 new((*pAddress)[countadr++]) TVector(2);
1062 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1063 trinfo(0)=(Float_t)track;
1064 trinfo(1)=(Float_t)iqpad;
1070 if (mHit->fParticle == kMuonPlus ||
1071 mHit->fParticle == kMuonMinus) {
1072 digits[4]=mPad->fHitNumber;
1073 } else digits[4]=-1;
1075 AliMUONTransientDigit* pdigit;
1076 // build the list of fired pads and update the info
1077 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1079 list->AddAtAndExpand(
1080 new AliMUONTransientDigit(nch,digits),counter);
1082 hitMap[nch]->SetHit(ipx, ipy, counter);
1084 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1086 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1087 trlist->Add(&trinfo);
1089 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1091 (*pdigit).fSignal+=iqpad;
1092 (*pdigit).fPhysics+=iqpad;
1093 // update list of tracks
1094 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
1095 Int_t lastEntry=trlist->GetLast();
1096 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1097 TVector &ptrk=*pTrack;
1098 Int_t lastTrack=Int_t(ptrk(0));
1099 Int_t lastCharge=Int_t(ptrk(1));
1100 if (lastTrack==track) {
1102 trlist->RemoveAt(lastEntry);
1103 trinfo(0)=lastTrack;
1104 trinfo(1)=lastCharge;
1105 trlist->AddAt(&trinfo,lastEntry);
1107 trlist->Add(&trinfo);
1109 // check the track list
1110 Int_t nptracks=trlist->GetEntriesFast();
1112 for (Int_t tr=0;tr<nptracks;tr++) {
1113 TVector *ppTrack=(TVector*)trlist->At(tr);
1114 TVector &pptrk=*ppTrack;
1115 trk[tr]=Int_t(pptrk(0));
1116 chtrk[tr]=Int_t(pptrk(1));
1118 } // end if nptracks
1120 } //end loop over clusters
1124 // open the file with background
1126 if (addBackground) {
1127 ntracks =(Int_t)fTrH1->GetEntries();
1131 for (Int_t track=0; track<ntracks; track++) {
1133 if (fHits2) fHits2->Clear();
1134 if (fPadHits2) fPadHits2->Clear();
1136 fTrH1->GetEvent(track);
1140 for(int i=0;i<fHits2->GetEntriesFast();++i)
1142 mHit=(AliMUONHit*) (*fHits2)[i];
1143 Int_t nch = mHit->fChamber-1; // chamber number
1144 if (nch >9) continue;
1145 iChamber = &(pMUON->Chamber(nch));
1146 Int_t rmin = (Int_t)iChamber->RInner();
1147 Int_t rmax = (Int_t)iChamber->ROuter();
1148 Float_t xbgr=mHit->X();
1149 Float_t ybgr=mHit->Y();
1152 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1153 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1154 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
1155 if (dist<100) cond=kTRUE;
1157 if (!cond) continue;
1160 // Loop over pad hits
1161 for (AliMUONPadHit* mPad=
1162 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
1164 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
1166 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
1167 Int_t cathode = mPad->fCathode; // cathode number
1168 Int_t ipx = mPad->fPadX; // pad number on X
1169 Int_t ipy = mPad->fPadY; // pad number on Y
1170 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1172 if (cathode != (icat+1)) continue;
1173 Float_t thex, they, thez;
1174 segmentation=iChamber->SegmentationModel(cathode);
1175 segmentation->GetPadC(ipx,ipy,thex,they,thez);
1176 Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1177 if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1178 new((*pAddress)[countadr++]) TVector(2);
1179 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1180 trinfo(0)=-1; // tag background
1189 AliMUONTransientDigit* pdigit;
1190 // build the list of fired pads and update the info
1191 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1192 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1194 hitMap[nch]->SetHit(ipx, ipy, counter);
1197 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1199 TObjArray *trlist=(TObjArray*)pdigit->
1201 trlist->Add(&trinfo);
1203 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1205 (*pdigit).fSignal+=iqpad;
1207 // update list of tracks
1208 TObjArray* trlist=(TObjArray*)pdigit->
1210 Int_t lastEntry=trlist->GetLast();
1211 TVector *pTrack=(TVector*)trlist->
1213 TVector &ptrk=*pTrack;
1214 Int_t lastTrack=Int_t(ptrk(0));
1215 if (lastTrack==-1) {
1218 trlist->Add(&trinfo);
1220 // check the track list
1221 Int_t nptracks=trlist->GetEntriesFast();
1223 for (Int_t tr=0;tr<nptracks;tr++) {
1224 TVector *ppTrack=(TVector*)trlist->At(tr);
1225 TVector &pptrk=*ppTrack;
1226 trk[tr]=Int_t(pptrk(0));
1227 chtrk[tr]=Int_t(pptrk(1));
1229 } // end if nptracks
1231 } //end loop over clusters
1234 //Int_t nentr2=list->GetEntriesFast();
1235 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1236 TTree *fAli=gAlice->TreeK();
1239 if (fAli) file =fAli->GetCurrentFile();
1241 } // if addBackground
1247 Int_t nentries=list->GetEntriesFast();
1249 for (Int_t nent=0;nent<nentries;nent++) {
1250 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
1251 if (address==0) continue;
1252 Int_t ich=address->fChamber;
1253 Int_t q=address->fSignal;
1254 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1256 // Digit Response (noise, threshold, saturation, ...)
1257 // if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1258 AliMUONResponse * response=iChamber->ResponseModel();
1259 q=response->DigitResponse(q);
1263 digits[0]=address->fPadX;
1264 digits[1]=address->fPadY;
1266 digits[3]=address->fPhysics;
1267 digits[4]=address->fHit;
1269 TObjArray* trlist=(TObjArray*)address->TrackList();
1270 Int_t nptracks=trlist->GetEntriesFast();
1271 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1273 // this was changed to accomodate the real number of tracks
1274 if (nptracks > 10) {
1275 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1279 printf("Attention - nptracks > 2 %d \n",nptracks);
1280 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1282 for (Int_t tr=0;tr<nptracks;tr++) {
1283 TVector *ppP=(TVector*)trlist->At(tr);
1284 if(!ppP ) printf("ppP - %p\n",ppP);
1286 tracks[tr]=Int_t(pp(0));
1287 charges[tr]=Int_t(pp(1));
1288 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
1289 } //end loop over list of tracks for one pad
1290 // Sort list of tracks according to charge
1292 SortTracks(tracks,charges,nptracks);
1294 if (nptracks < 10 ) {
1295 for (Int_t i=nptracks; i<10; i++) {
1302 pMUON->AddDigits(ich,tracks,charges,digits);
1305 //cout<<"I'm out of the loops for digitisation"<<endl;
1306 // gAlice->GetEvent(nev);
1307 gAlice->TreeD()->Fill();
1308 pMUON->ResetDigits();
1312 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
1320 } //end loop over cathodes
1323 sprintf(hname,"TreeD%d",nev);
1324 gAlice->TreeD()->Write(hname);
1326 gAlice->TreeD()->Reset();
1330 // gObjectTable->Print();
1333 void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1336 // Sort the list of tracks contributing to a given digit
1337 // Only the 3 most significant tracks are acctually sorted
1341 // Loop over signals, only 3 times
1346 Int_t idx[3] = {-2,-2,-2};
1347 Int_t jch[3] = {-2,-2,-2};
1348 Int_t jtr[3] = {-2,-2,-2};
1351 if (ntr<3) imax=ntr;
1353 for(i=0;i<imax;i++){
1359 if((i == 1 && j == idx[i-1])
1360 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1362 if(charges[j] > qmax) {
1370 jch[i]=charges[jmax];
1371 jtr[i]=tracks[jmax];
1388 //___________________________________________
1389 void AliMUON::Trigger(Int_t nev){
1390 // call the Trigger Algorithm and fill TreeR
1392 Int_t singlePlus[3] = {0,0,0};
1393 Int_t singleMinus[3] = {0,0,0};
1394 Int_t singleUndef[3] = {0,0,0};
1395 Int_t pairUnlike[3] = {0,0,0};
1396 Int_t pairLike[3] = {0,0,0};
1399 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1400 decision->Trigger();
1401 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1402 pairUnlike, pairLike);
1403 // add a local trigger in the list
1404 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
1407 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
1408 if(decision->GetITrigger(icirc)==1) {
1409 Int_t localtr[7]={0,0,0,0,0,0,0};
1410 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1411 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1413 localtr[1] = decision->GetStripX11(icirc);
1414 localtr[2] = decision->GetDev(icirc);
1415 localtr[3] = decision->GetStripY11(icirc);
1416 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1417 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1418 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1419 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1421 AddLocalTrigger(localtr); // add a local trigger in the list
1426 gAlice->TreeR()->Fill();
1429 sprintf(hname,"TreeR%d",nev);
1430 gAlice->TreeR()->Write(hname);
1431 gAlice->TreeR()->Reset();
1432 printf("\n End of trigger for event %d", nev);
1436 //____________________________________________
1437 void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1439 TClonesArray *dig1, *dig2;
1441 dig1 = new TClonesArray("AliMUONDigit",1000);
1442 dig2 = new TClonesArray("AliMUONDigit",1000);
1443 AliMUONDigit *digit;
1445 // Loop on chambers and on cathode planes
1448 for (Int_t ich=0;ich<10;ich++) {
1449 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1450 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1451 gAlice->ResetDigits();
1452 gAlice->TreeD()->GetEvent(lastEntry);
1453 TClonesArray *muonDigits = this->DigitsAddress(ich);
1454 ndig=muonDigits->GetEntriesFast();
1455 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1456 TClonesArray &lhits1 = *dig1;
1458 for (k=0; k<ndig; k++) {
1459 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1460 if (rec->TestTrack(digit->fTracks[0]))
1461 new(lhits1[n++]) AliMUONDigit(*digit);
1463 gAlice->ResetDigits();
1464 gAlice->TreeD()->GetEvent(lastEntry+1);
1465 muonDigits = this->DigitsAddress(ich);
1466 ndig=muonDigits->GetEntriesFast();
1467 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1468 TClonesArray &lhits2 = *dig2;
1471 for (k=0; k<ndig; k++) {
1472 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1473 if (rec->TestTrack(digit->fTracks[0]))
1474 new(lhits2[n++]) AliMUONDigit(*digit);
1478 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1479 rec->FindRawClusters();
1484 gAlice->TreeR()->Fill();
1487 sprintf(hname,"TreeR%d",nev);
1488 gAlice->TreeR()->Write(hname);
1489 gAlice->TreeR()->Reset();
1490 printf("\n End of cluster finding for event %d", nev);
1494 //gObjectTable->Print();
1498 void AliMUON::Streamer(TBuffer &R__b)
1500 // Stream an object of class AliMUON.
1501 AliMUONChamber *iChamber;
1502 AliMUONTriggerCircuit *iTriggerCircuit;
1503 AliSegmentation *segmentation;
1504 AliMUONResponse *response;
1505 TClonesArray *digitsaddress;
1506 TClonesArray *rawcladdress;
1508 if (R__b.IsReading()) {
1509 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1510 AliDetector::Streamer(R__b);
1512 R__b >> fPadHits; // diff
1513 R__b >> fNLocalTrigger;
1514 R__b >> fLocalTrigger;
1515 R__b >> fNGlobalTrigger;
1516 R__b >> fGlobalTrigger;
1518 R__b >> fRawClusters;
1519 R__b.ReadArray(fNdch);
1520 R__b.ReadArray(fNrawch);
1525 R__b >> fTriggerCircuits;
1526 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1527 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1528 iTriggerCircuit->Streamer(R__b);
1530 // Stream chamber related information
1531 for (i =0; i<AliMUONConstants::NCh(); i++) {
1532 iChamber=(AliMUONChamber*) (*fChambers)[i];
1533 iChamber->Streamer(R__b);
1534 if (iChamber->Nsec()==1) {
1535 segmentation=iChamber->SegmentationModel(1);
1537 segmentation->Streamer(R__b);
1539 segmentation=iChamber->SegmentationModel(1);
1541 segmentation->Streamer(R__b);
1543 segmentation=iChamber->SegmentationModel(2);
1544 segmentation->Streamer(R__b);
1546 response=iChamber->ResponseModel();
1548 response->Streamer(R__b);
1549 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1550 digitsaddress->Streamer(R__b);
1551 if (i < AliMUONConstants::NTrackingCh()) {
1552 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1553 rawcladdress->Streamer(R__b);
1558 R__b.WriteVersion(AliMUON::IsA());
1559 AliDetector::Streamer(R__b);
1561 R__b << fPadHits; // diff
1562 R__b << fNLocalTrigger;
1563 R__b << fLocalTrigger;
1564 R__b << fNGlobalTrigger;
1565 R__b << fGlobalTrigger;
1567 R__b << fRawClusters;
1568 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1569 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1576 R__b << fTriggerCircuits;
1577 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1578 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1579 iTriggerCircuit->Streamer(R__b);
1581 for (i =0; i<AliMUONConstants::NCh(); i++) {
1582 iChamber=(AliMUONChamber*) (*fChambers)[i];
1583 iChamber->Streamer(R__b);
1584 if (iChamber->Nsec()==1) {
1585 segmentation=iChamber->SegmentationModel(1);
1587 segmentation->Streamer(R__b);
1589 segmentation=iChamber->SegmentationModel(1);
1591 segmentation->Streamer(R__b);
1592 segmentation=iChamber->SegmentationModel(2);
1594 segmentation->Streamer(R__b);
1596 response=iChamber->ResponseModel();
1598 response->Streamer(R__b);
1599 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1600 digitsaddress->Streamer(R__b);
1601 if (i < AliMUONConstants::NTrackingCh()) {
1602 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1603 rawcladdress->Streamer(R__b);
1608 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1611 // Initialise the pad iterator
1612 // Return the address of the first padhit for hit
1613 TClonesArray *theClusters = clusters;
1614 Int_t nclust = theClusters->GetEntriesFast();
1615 if (nclust && hit->fPHlast > 0) {
1616 AliMUON::fMaxIterPad=hit->fPHlast;
1617 AliMUON::fCurIterPad=hit->fPHfirst;
1618 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1624 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1626 AliMUON::fCurIterPad++;
1627 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1628 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1635 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1637 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1639 TTree *treeR = gAlice->TreeR();
1640 Int_t nent=(Int_t)treeR->GetEntries();
1641 treeR->GetEvent(nent-2+icathod-1);
1642 //treeR->GetEvent(icathod);
1643 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1645 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1646 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1651 AliMUON& AliMUON::operator = (const AliMUON& rhs)