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.25 2000/06/29 12:34:09 morsch
18 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
19 it usable with any other geometry class. The link to the object to which it belongs is
20 established via an index. This assumes that there exists a global geometry manager
21 from which the pointer to the parent object can be obtained (in our case gAlice).
23 Revision 1.24 2000/06/28 15:16:35 morsch
24 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
25 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
26 framework. The changes should have no side effects (mostly dummy arguments).
27 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
28 of chambers with overlapping modules (MakePadHits, Disintegration).
30 Revision 1.23 2000/06/28 12:19:17 morsch
31 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
32 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
33 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
34 It requires two cathode planes. Small modifications in the code will make it usable for
35 one cathode plane and, hence, more general (for test beam data).
36 AliMUONClusterFinder is now obsolete.
38 Revision 1.22 2000/06/28 08:06:10 morsch
39 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
40 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
41 It also naturally takes care of the TMinuit instance.
43 Revision 1.21 2000/06/27 08:54:41 morsch
44 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
46 Revision 1.20 2000/06/26 14:02:38 morsch
47 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
49 Revision 1.19 2000/06/22 13:40:51 morsch
50 scope problem on HP, "i" declared once
51 pow changed to TMath::Power (PH, AM)
53 Revision 1.18 2000/06/15 07:58:48 morsch
54 Code from MUON-dev joined
56 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
57 - add TriggerCircuit (PC)
58 - add GlobalTrigger and LocalTrigger and specific methods (PC)
60 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
61 Most coding rule violations corrected
63 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
64 RULE RN17 violations corrected
66 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
67 Code revised by P. Crochet:
68 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
69 - ToF included in the method MakePadHits
70 - inner radius of flange between beam shielding and trigger corrected
71 - Trigger global volume updated (according to the new geometry)
73 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
74 Some changes of variable names curing viols and methods concerning
75 correlated clusters removed.
77 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
78 Memory leak suppressed in function Digitise:
79 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
81 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
82 Positions of trigger chambers corrected (P.C.)
84 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
85 Call to AddHitList introduced to make this version compatible with head.
87 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
88 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
90 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
91 Trigger included into initialization and digitization
93 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
94 Log messages of previous revisions added
96 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
97 Z position of the chambers:
98 it was the Z position of the stations;
99 it is now really the Z position of the chambers.
100 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
101 !!!! AND "AliMUONChamber::ZPosition"
102 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
103 !!!! AND "AliMUONChamber::Z"
105 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
106 Correction for mis-spelling of NCH
108 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
114 ///////////////////////////////////////////////
115 // Manager and hits classes for set:MUON //
116 ////////////////////////////////////////////////
120 #include <TRotMatrix.h>
126 #include <TObjArray.h>
128 #include <TParticle.h>
134 #include <TDirectory.h>
135 #include <TObjectTable.h>
140 #include "AliMUONHit.h"
141 #include "AliMUONPadHit.h"
142 #include "AliMUONDigit.h"
143 #include "AliMUONTransientDigit.h"
144 #include "AliMUONRawCluster.h"
145 #include "AliMUONLocalTrigger.h"
146 #include "AliMUONGlobalTrigger.h"
147 #include "AliHitMap.h"
148 #include "AliMUONHitMapA1.h"
149 #include "AliMUONChamberTrigger.h"
150 #include "AliMUONConstants.h"
151 #include "AliMUONClusterFinderVS.h"
152 #include "AliMUONTriggerDecision.h"
155 #include "AliMUONClusterInput.h"
156 #include "iostream.h"
157 #include "AliCallf77.h"
158 #include "AliConst.h"
160 // Defaults parameters for Z positions of chambers
161 // taken from values for "stations" in AliMUON::AliMUON
162 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
163 // and from array "dstation" in AliMUONv1::CreateGeometry
164 // Float_t dstation[5]={20., 20., 20, 20., 20.};
165 // for tracking chambers,
166 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
167 // for the first and second chambers in the station, respectively,
168 // and from "DTPLANES" in AliMUONv1::CreateGeometry
169 // const Float_t DTPLANES = 15.;
170 // for trigger chambers,
171 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
172 // for the first and second chambers in the station, respectively
175 //___________________________________________
183 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
193 //___________________________________________
194 AliMUON::AliMUON(const char *name, const char *title)
195 : AliDetector(name,title)
199 <img src="gif/alimuon.gif">
203 fHits = new TClonesArray("AliMUONHit",1000);
204 gAlice->AddHitList(fHits);
205 fPadHits = new TClonesArray("AliMUONPadHit",10000);
209 fNdch = new Int_t[AliMUONConstants::NCh()];
211 fDchambers = new TObjArray(AliMUONConstants::NCh());
215 for (i=0; i<AliMUONConstants::NCh() ;i++) {
216 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
220 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
222 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
224 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
225 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
228 cout << " here " << "\n";
230 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
232 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
236 // Transport angular cut
241 SetMarkerColor(kRed);
249 fChambers = new TObjArray(AliMUONConstants::NCh());
251 // Loop over stations
252 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
253 // Loop over 2 chambers in the station
254 for (Int_t stCH = 0; stCH < 2; stCH++) {
257 // Default Parameters for Muon Tracking Stations
262 if (ch < AliMUONConstants::NTrackingCh()) {
263 (*fChambers)[ch] = new AliMUONChamber(ch);
265 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
268 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
271 // Default values for Z of chambers
272 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
274 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
275 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
276 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
278 } // Chamber stCH (0, 1) in
279 } // Station st (0...)
288 // cp new design of AliMUONTriggerDecision
289 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
290 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
291 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
293 // cp new design of AliMUONTriggerDecision
297 //___________________________________________
298 AliMUON::AliMUON(const AliMUON& rMUON)
300 // Dummy copy constructor
307 printf("Calling AliMUON destructor !!!\n");
314 delete fGlobalTrigger;
317 delete fLocalTrigger;
320 for (i=0;i<AliMUONConstants::NCh();i++) {
321 delete (*fDchambers)[i];
326 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
327 delete (*fRawClusters)[i];
332 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
333 delete (*fTriggerCircuits)[circ];
335 delete fTriggerCircuits;
338 //___________________________________________
339 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
341 TClonesArray &lhits = *fHits;
342 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
344 //___________________________________________
345 void AliMUON::AddPadHit(Int_t *clhits)
347 TClonesArray &lclusters = *fPadHits;
348 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
350 //_____________________________________________________________________________
351 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
354 // Add a MUON digit to the list
357 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
358 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
361 //_____________________________________________________________________________
362 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
365 // Add a MUON digit to the list
368 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
369 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
372 //___________________________________________
373 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
375 Int_t *pairUnlike, Int_t *pairLike)
377 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
378 TClonesArray &globalTrigger = *fGlobalTrigger;
379 new(globalTrigger[fNGlobalTrigger++])
380 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
383 //___________________________________________
384 void AliMUON::AddLocalTrigger(Int_t *localtr)
386 // add a MUON Local Trigger to the list
387 TClonesArray &localTrigger = *fLocalTrigger;
388 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
391 //___________________________________________
392 void AliMUON::BuildGeometry()
394 TNode *node, *nodeF, *top, *nodeS;
395 const int kColorMUON = kBlue;
396 const int kColorMUON2 = kGreen;
398 top=gAlice->GetGeometry()->GetNode("alice");
401 // z-Positions of Chambers
402 const Float_t kCz[7]={511., 686., 971., 1245., 1445., 1600, 1700.};
403 // inner diameter (Xlenght for trigger chamber -> active area)
404 const Float_t kDmin[7]={ 35., 47., 67., 86., 100., 544., 544.};
405 // outer diameter (Ylenght for trigger chamber -> active area)
406 const Float_t kDmax[7]={183., 245., 346., 520., 520., 612., 612.};
408 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
409 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
410 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
411 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
413 Float_t rmin, rmax, dx, dy, dz, dr, xpos, ypos, zpos;
414 Float_t dzc1=4.; // tracking chambers
415 Float_t dzc2=15.; // trigger chambers
416 Float_t hole=102.; // x-y hole around beam pipe for trig. chambers
417 Float_t zscale; // scaling parameter trigger chambers
418 Float_t halfx, halfy;
419 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[8];
420 char nameSense1[9], nameSense2[9];
421 for (Int_t i=0; i<7; i++) {
422 for (Int_t j=0; j<2; j++) {
424 if (i<5) { // tracking chambers
437 sprintf(nameChamber,"C_MUON%d",id);
438 sprintf(nameSense,"S_MUON%d",id);
439 sprintf(nameSense1,"S1_MUON%d",id);
440 sprintf(nameSense2,"S2_MUON%d",id);
441 sprintf(nameFrame,"F_MUON%d",id);
442 if (i<5) { // tracking chambers
443 rmin = kDmin[i]/2.-3;
444 rmax = kDmax[i]/2.+3;
445 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
448 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
452 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
454 sprintf(nameNode,"MUON%d",100+id);
455 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,zpos,"");
456 node->SetLineColor(kColorMUON);
459 sprintf(nameNode,"MUON%d",200+id);
460 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
461 node->SetLineColor(kColorMUON);
464 sprintf(nameNode,"MUON%d",300+id);
465 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
466 nodeF->SetLineColor(kColorMUON);
468 sprintf(nameNode,"MUON%d",400+id);
469 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
470 nodeF->SetLineColor(kColorMUON);
472 sprintf(nameNode,"MUON%d",500+id);
473 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
474 nodeF->SetLineColor(kColorMUON);
476 sprintf(nameNode,"MUON%d",600+id);
477 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
478 nodeF->SetLineColor(kColorMUON);
481 Float_t xsize=kDmin[i]*zscale;
482 Float_t ysize=kDmax[i]*zscale;
483 Float_t holeScaled=hole*zscale;
487 new TBRIK(nameChamber,"Mother","void",halfx,halfy,0.25);
489 sprintf(nameNode,"MUON%d",100+id);
490 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
491 node->SetLineColor(kColorMUON2);
494 // up/down of beam pipe
496 halfy=(ysize/2.-holeScaled/2.)/2.;
497 new TBRIK(nameSense,"Sens. region","void",halfx,halfy,0.25);
500 ypos=holeScaled/2.+((ysize/2.-holeScaled/2.)/2.);
501 sprintf(nameNode,"MUON%d",200+id);
502 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
503 nodeS->SetLineColor(kColorMUON2);
507 sprintf(nameNode,"MUON%d",300+id);
508 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
509 nodeS->SetLineColor(kColorMUON2);
511 // left/right of beam pipe
512 halfx=(xsize/2.-holeScaled/2.)/2.;
514 new TBRIK(nameSense1,"Sens. region","void",halfx,halfy,0.25);
517 xpos=holeScaled/2.+((xsize/2.-holeScaled/2.)/2.);
518 sprintf(nameNode,"MUON%d",400+id);
519 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
520 nodeS->SetLineColor(kColorMUON2);
524 sprintf(nameNode,"MUON%d",500+id);
525 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
526 nodeS->SetLineColor(kColorMUON2);
531 new TBRIK(nameSense2,"Sens. region","void",halfx,halfy,0.25);
534 xpos=holeScaled/2.-halfx;
536 sprintf(nameNode,"MUON%d",600+id);
537 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
538 nodeS->SetLineColor(kColorMUON2);
542 sprintf(nameNode,"MUON%d",700+id);
543 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
544 nodeS->SetLineColor(kColorMUON2);
548 sprintf(nameNode,"MUON%d",800+id);
549 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
550 nodeS->SetLineColor(kColorMUON2);
554 sprintf(nameNode,"MUON%d",900+id);
555 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
556 nodeS->SetLineColor(kColorMUON2);
563 //___________________________________________
564 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
569 //___________________________________________
570 void AliMUON::MakeBranch(Option_t* option)
572 // Create Tree branches for the MUON.
573 const Int_t kBufferSize = 4000;
575 sprintf(branchname,"%sCluster",GetName());
577 AliDetector::MakeBranch(option);
579 if (fPadHits && gAlice->TreeH()) {
580 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
581 printf("Making Branch %s for clusters\n",branchname);
584 // one branch for digits per chamber
587 for (i=0; i<AliMUONConstants::NCh() ;i++) {
588 sprintf(branchname,"%sDigits%d",GetName(),i+1);
590 if (fDchambers && gAlice->TreeD()) {
591 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
592 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
596 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
598 // one branch for raw clusters per chamber
599 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
600 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
602 if (fRawClusters && gAlice->TreeR()) {
603 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
604 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
608 // one branch for global trigger
609 sprintf(branchname,"%sGlobalTrigger",GetName());
610 if (fGlobalTrigger && gAlice->TreeR()) {
611 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
612 printf("Making Branch %s for Global Trigger\n",branchname);
614 // one branch for local trigger
615 sprintf(branchname,"%sLocalTrigger",GetName());
616 if (fLocalTrigger && gAlice->TreeR()) {
617 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
618 printf("Making Branch %s for Local Trigger\n",branchname);
623 //___________________________________________
624 void AliMUON::SetTreeAddress()
626 // Set branch address for the Hits and Digits Tree.
628 AliDetector::SetTreeAddress();
631 TTree *treeH = gAlice->TreeH();
632 TTree *treeD = gAlice->TreeD();
633 TTree *treeR = gAlice->TreeR();
637 branch = treeH->GetBranch("MUONCluster");
638 if (branch) branch->SetAddress(&fPadHits);
643 for (int i=0; i<AliMUONConstants::NCh(); i++) {
644 sprintf(branchname,"%sDigits%d",GetName(),i+1);
646 branch = treeD->GetBranch(branchname);
647 if (branch) branch->SetAddress(&((*fDchambers)[i]));
652 // printf("SetTreeAddress --- treeR address %p \n",treeR);
655 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
656 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
658 branch = treeR->GetBranch(branchname);
659 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
664 branch = treeR->GetBranch("MUONLocalTrigger");
665 if (branch) branch->SetAddress(&fLocalTrigger);
667 if (fGlobalTrigger) {
668 branch = treeR->GetBranch("MUONGlobalTrigger");
669 if (branch) branch->SetAddress(&fGlobalTrigger);
673 //___________________________________________
674 void AliMUON::ResetHits()
676 // Reset number of clusters and the cluster array for this detector
677 AliDetector::ResetHits();
679 if (fPadHits) fPadHits->Clear();
682 //____________________________________________
683 void AliMUON::ResetDigits()
686 // Reset number of digits and the digits array for this detector
688 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
689 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
690 if (fNdch) fNdch[i]=0;
693 //____________________________________________
694 void AliMUON::ResetRawClusters()
697 // Reset number of raw clusters and the raw clust array for this detector
699 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
700 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
701 if (fNrawch) fNrawch[i]=0;
705 //____________________________________________
706 void AliMUON::ResetTrigger()
708 // Reset Local and Global Trigger
710 if (fGlobalTrigger) fGlobalTrigger->Clear();
712 if (fLocalTrigger) fLocalTrigger->Clear();
715 //____________________________________________
716 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
719 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
720 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
723 //___________________________________________
724 void AliMUON::SetChambersZ(const Float_t *Z)
726 // Set Z values for all chambers (tracking and trigger)
727 // from the array pointed to by "Z"
728 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
729 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
733 //___________________________________________
734 void AliMUON::SetChambersZToDefault()
736 // Set Z values for all chambers (tracking and trigger)
738 SetChambersZ(AliMUONConstants::DefaultChamberZ());
742 //___________________________________________
743 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
746 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
747 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
750 //___________________________________________
751 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
754 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
755 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
758 //___________________________________________
759 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
762 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
763 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
766 //___________________________________________
767 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
770 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
771 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
774 //___________________________________________
775 void AliMUON::SetMaxStepGas(Float_t p1)
780 //___________________________________________
781 void AliMUON::SetMaxStepAlu(Float_t p1)
786 //___________________________________________
787 void AliMUON::SetMaxDestepGas(Float_t p1)
792 //___________________________________________
793 void AliMUON::SetMaxDestepAlu(Float_t p1)
797 //___________________________________________
798 void AliMUON::SetMuonAcc(Bool_t acc, Float_t angmin, Float_t angmax)
804 //___________________________________________
805 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
807 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
810 //___________________________________________
811 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
813 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
816 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
818 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
821 void AliMUON::SetNsec(Int_t id, Int_t nsec)
823 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
827 //___________________________________________
831 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
832 Float_t eloss, Float_t tof, Int_t idvol)
835 // Calls the charge disintegration method of the current chamber and adds
836 // the simulated cluster to the root treee
839 Float_t newclust[6][500];
844 // Integrated pulse height on chamber
850 ((AliMUONChamber*) (*fChambers)[idvol])
851 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
856 for (Int_t i=0; i<nnew; i++) {
857 if (Int_t(newclust[3][i]) > 0) {
860 clhits[1] = Int_t(newclust[5][i]);
862 clhits[2] = Int_t(newclust[0][i]);
864 clhits[3] = Int_t(newclust[1][i]);
866 clhits[4] = Int_t(newclust[2][i]);
868 clhits[5] = Int_t(newclust[3][i]);
869 // Pad: chamber sector
870 clhits[6] = Int_t(newclust[4][i]);
877 //----------------------------------------------------------------------
879 void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
881 // keep galice.root for signal and name differently the file for
882 // background when add! otherwise the track info for signal will be lost !
884 static Bool_t first=kTRUE;
886 char *addBackground = strstr(option,"Add");
889 AliMUONChamber* iChamber;
890 AliSegmentation* segmentation;
895 TObjArray *list=new TObjArray;
896 static TClonesArray *pAddress=0;
897 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
900 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
901 AliHitMap** hitMap= new AliHitMap* [AliMUONConstants::NCh()];
902 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
903 if (addBackground ) {
906 cout<<"filename"<<fFileName<<endl;
907 file=new TFile(fFileName);
908 cout<<"I have opened "<<fFileName<<" file "<<endl;
909 fHits2 = new TClonesArray("AliMUONHit",1000 );
910 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
915 // Get Hits Tree header from file
916 if(fHits2) fHits2->Clear();
917 if(fPadHits2) fPadHits2->Clear();
918 if(fTrH1) delete fTrH1;
922 sprintf(treeName,"TreeH%d",bgrEvent);
923 fTrH1 = (TTree*)gDirectory->Get(treeName);
924 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
927 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
929 // Set branch addresses
932 sprintf(branchname,"%s",GetName());
933 if (fTrH1 && fHits2) {
934 branch = fTrH1->GetBranch(branchname);
935 if (branch) branch->SetAddress(&fHits2);
937 if (fTrH1 && fPadHits2) {
938 branch = fTrH1->GetBranch("MUONCluster");
939 if (branch) branch->SetAddress(&fPadHits2);
942 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
943 //printf("background - ntracks1 - %d\n",ntracks1);
946 // loop over cathodes
950 for (int icat=0; icat<2; icat++) {
952 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
953 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
954 iChamber=(AliMUONChamber*) (*fChambers)[i];
955 if (iChamber->Nsec()==1 && icat==1) {
958 segmentation=iChamber->SegmentationModel(icat+1);
960 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
963 //printf("Start loop over tracks \n");
968 TTree *treeH = gAlice->TreeH();
969 Int_t ntracks =(Int_t) treeH->GetEntries();
971 Float_t ** xhit = new Float_t * [2];
972 for (jj=0; jj<2; jj++) xhit[jj] = new Float_t [AliMUONConstants::NCh()];
973 Float_t ** yhit = new Float_t * [2];
974 for (jj=0; jj<2; jj++) yhit[jj] = new Float_t [AliMUONConstants::NCh()];
976 for (Int_t track=0; track<ntracks; track++) {
978 treeH->GetEvent(track);
982 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
984 mHit=(AliMUONHit*)pMUON->NextHit())
986 Int_t nch = mHit->fChamber-1; // chamber number
987 if (nch > AliMUONConstants::NCh()-1) continue;
988 iChamber = &(pMUON->Chamber(nch));
992 if (mHit->fParticle == kMuonPlus
993 || mHit->fParticle == kMuonMinus) {
994 xhit[nch][nmuon[nch]]=mHit->fX;
995 yhit[nch][nmuon[nch]]=mHit->fY;
997 if (nmuon[nch] >2) printf("nmuon %d\n",nmuon[nch]);
1005 // Loop over pad hits
1006 for (AliMUONPadHit* mPad=
1007 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
1009 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
1011 Int_t cathode = mPad->fCathode; // cathode number
1012 Int_t ipx = mPad->fPadX; // pad number on X
1013 Int_t ipy = mPad->fPadY; // pad number on Y
1014 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1018 if (cathode != (icat+1)) continue;
1019 // fill the info array
1020 Float_t thex, they, thez;
1021 segmentation=iChamber->SegmentationModel(cathode);
1022 segmentation->GetPadC(ipx,ipy,thex,they,thez);
1023 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1024 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1026 new((*pAddress)[countadr++]) TVector(2);
1027 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1028 trinfo(0)=(Float_t)track;
1029 trinfo(1)=(Float_t)iqpad;
1035 if (mHit->fParticle == kMuonPlus ||
1036 mHit->fParticle == kMuonMinus) {
1037 digits[4]=mPad->fHitNumber;
1038 } else digits[4]=-1;
1040 AliMUONTransientDigit* pdigit;
1041 // build the list of fired pads and update the info
1042 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1044 list->AddAtAndExpand(
1045 new AliMUONTransientDigit(nch,digits),counter);
1047 hitMap[nch]->SetHit(ipx, ipy, counter);
1049 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1051 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1052 trlist->Add(&trinfo);
1054 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1056 (*pdigit).fSignal+=iqpad;
1057 (*pdigit).fPhysics+=iqpad;
1058 // update list of tracks
1059 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
1060 Int_t lastEntry=trlist->GetLast();
1061 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1062 TVector &ptrk=*pTrack;
1063 Int_t lastTrack=Int_t(ptrk(0));
1064 Int_t lastCharge=Int_t(ptrk(1));
1065 if (lastTrack==track) {
1067 trlist->RemoveAt(lastEntry);
1068 trinfo(0)=lastTrack;
1069 trinfo(1)=lastCharge;
1070 trlist->AddAt(&trinfo,lastEntry);
1072 trlist->Add(&trinfo);
1074 // check the track list
1075 Int_t nptracks=trlist->GetEntriesFast();
1077 for (Int_t tr=0;tr<nptracks;tr++) {
1078 TVector *ppTrack=(TVector*)trlist->At(tr);
1079 TVector &pptrk=*ppTrack;
1080 trk[tr]=Int_t(pptrk(0));
1081 chtrk[tr]=Int_t(pptrk(1));
1083 } // end if nptracks
1085 } //end loop over clusters
1089 // open the file with background
1091 if (addBackground) {
1092 ntracks =(Int_t)fTrH1->GetEntries();
1096 for (Int_t track=0; track<ntracks; track++) {
1098 if (fHits2) fHits2->Clear();
1099 if (fPadHits2) fPadHits2->Clear();
1101 fTrH1->GetEvent(track);
1105 for(int i=0;i<fHits2->GetEntriesFast();++i)
1107 mHit=(AliMUONHit*) (*fHits2)[i];
1108 Int_t nch = mHit->fChamber-1; // chamber number
1109 if (nch >9) continue;
1110 iChamber = &(pMUON->Chamber(nch));
1111 Int_t rmin = (Int_t)iChamber->RInner();
1112 Int_t rmax = (Int_t)iChamber->ROuter();
1113 Float_t xbgr=mHit->fX;
1114 Float_t ybgr=mHit->fY;
1117 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1118 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1119 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
1120 if (dist<100) cond=kTRUE;
1122 if (!cond) continue;
1125 // Loop over pad hits
1126 for (AliMUONPadHit* mPad=
1127 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
1129 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
1131 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
1132 Int_t cathode = mPad->fCathode; // cathode number
1133 Int_t ipx = mPad->fPadX; // pad number on X
1134 Int_t ipy = mPad->fPadY; // pad number on Y
1135 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1137 if (cathode != (icat+1)) continue;
1138 Float_t thex, they, thez;
1139 segmentation=iChamber->SegmentationModel(cathode);
1140 segmentation->GetPadC(ipx,ipy,thex,they,thez);
1141 Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1142 if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1143 new((*pAddress)[countadr++]) TVector(2);
1144 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1145 trinfo(0)=-1; // tag background
1154 AliMUONTransientDigit* pdigit;
1155 // build the list of fired pads and update the info
1156 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1157 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1159 hitMap[nch]->SetHit(ipx, ipy, counter);
1162 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1164 TObjArray *trlist=(TObjArray*)pdigit->
1166 trlist->Add(&trinfo);
1168 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1170 (*pdigit).fSignal+=iqpad;
1172 // update list of tracks
1173 TObjArray* trlist=(TObjArray*)pdigit->
1175 Int_t lastEntry=trlist->GetLast();
1176 TVector *pTrack=(TVector*)trlist->
1178 TVector &ptrk=*pTrack;
1179 Int_t lastTrack=Int_t(ptrk(0));
1180 if (lastTrack==-1) {
1183 trlist->Add(&trinfo);
1185 // check the track list
1186 Int_t nptracks=trlist->GetEntriesFast();
1188 for (Int_t tr=0;tr<nptracks;tr++) {
1189 TVector *ppTrack=(TVector*)trlist->At(tr);
1190 TVector &pptrk=*ppTrack;
1191 trk[tr]=Int_t(pptrk(0));
1192 chtrk[tr]=Int_t(pptrk(1));
1194 } // end if nptracks
1196 } //end loop over clusters
1199 //Int_t nentr2=list->GetEntriesFast();
1200 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1201 TTree *fAli=gAlice->TreeK();
1204 if (fAli) file =fAli->GetCurrentFile();
1206 } // if addBackground
1212 Int_t nentries=list->GetEntriesFast();
1214 for (Int_t nent=0;nent<nentries;nent++) {
1215 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
1216 if (address==0) continue;
1217 Int_t ich=address->fChamber;
1218 Int_t q=address->fSignal;
1219 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1221 // Digit Response (noise, threshold, saturation, ...)
1222 // if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1223 AliMUONResponse * response=iChamber->ResponseModel();
1224 q=response->DigitResponse(q);
1228 digits[0]=address->fPadX;
1229 digits[1]=address->fPadY;
1231 digits[3]=address->fPhysics;
1232 digits[4]=address->fHit;
1234 TObjArray* trlist=(TObjArray*)address->TrackList();
1235 Int_t nptracks=trlist->GetEntriesFast();
1236 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1238 // this was changed to accomodate the real number of tracks
1239 if (nptracks > 10) {
1240 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1244 printf("Attention - nptracks > 2 %d \n",nptracks);
1245 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1247 for (Int_t tr=0;tr<nptracks;tr++) {
1248 TVector *ppP=(TVector*)trlist->At(tr);
1249 if(!ppP ) printf("ppP - %p\n",ppP);
1251 tracks[tr]=Int_t(pp(0));
1252 charges[tr]=Int_t(pp(1));
1253 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
1254 } //end loop over list of tracks for one pad
1255 // Sort list of tracks according to charge
1257 SortTracks(tracks,charges,nptracks);
1259 if (nptracks < 10 ) {
1260 for (Int_t i=nptracks; i<10; i++) {
1267 pMUON->AddDigits(ich,tracks,charges,digits);
1270 //cout<<"I'm out of the loops for digitisation"<<endl;
1271 // gAlice->GetEvent(nev);
1272 gAlice->TreeD()->Fill();
1273 pMUON->ResetDigits();
1277 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
1285 } //end loop over cathodes
1288 sprintf(hname,"TreeD%d",nev);
1289 gAlice->TreeD()->Write(hname);
1291 gAlice->TreeD()->Reset();
1295 // gObjectTable->Print();
1298 void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1301 // Sort the list of tracks contributing to a given digit
1302 // Only the 3 most significant tracks are acctually sorted
1306 // Loop over signals, only 3 times
1311 Int_t idx[3] = {-2,-2,-2};
1312 Int_t jch[3] = {-2,-2,-2};
1313 Int_t jtr[3] = {-2,-2,-2};
1316 if (ntr<3) imax=ntr;
1318 for(i=0;i<imax;i++){
1324 if((i == 1 && j == idx[i-1])
1325 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1327 if(charges[j] > qmax) {
1335 jch[i]=charges[jmax];
1336 jtr[i]=tracks[jmax];
1353 //___________________________________________
1354 void AliMUON::Trigger(Int_t nev){
1355 // call the Trigger Algorithm and fill TreeR
1357 Int_t singlePlus[3] = {0,0,0};
1358 Int_t singleMinus[3] = {0,0,0};
1359 Int_t singleUndef[3] = {0,0,0};
1360 Int_t pairUnlike[3] = {0,0,0};
1361 Int_t pairLike[3] = {0,0,0};
1364 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1365 decision->Trigger();
1366 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1367 pairUnlike, pairLike);
1368 // add a local trigger in the list
1369 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
1372 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
1373 if(decision->GetITrigger(icirc)==1) {
1374 Int_t localtr[7]={0,0,0,0,0,0,0};
1375 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1376 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1378 localtr[1] = decision->GetStripX11(icirc);
1379 localtr[2] = decision->GetDev(icirc);
1380 localtr[3] = decision->GetStripY11(icirc);
1381 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1382 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1383 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1384 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1386 AddLocalTrigger(localtr); // add a local trigger in the list
1391 gAlice->TreeR()->Fill();
1394 sprintf(hname,"TreeR%d",nev);
1395 gAlice->TreeR()->Write(hname);
1396 gAlice->TreeR()->Reset();
1397 printf("\n End of trigger for event %d", nev);
1401 //____________________________________________
1402 void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1404 TClonesArray *dig1, *dig2;
1406 dig1 = new TClonesArray("AliMUONDigit",1000);
1407 dig2 = new TClonesArray("AliMUONDigit",1000);
1408 AliMUONDigit *digit;
1410 // Loop on chambers and on cathode planes
1413 for (Int_t ich=0;ich<10;ich++) {
1414 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1415 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1416 gAlice->ResetDigits();
1417 gAlice->TreeD()->GetEvent(lastEntry);
1418 TClonesArray *muonDigits = this->DigitsAddress(ich);
1419 ndig=muonDigits->GetEntriesFast();
1420 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1421 TClonesArray &lhits1 = *dig1;
1423 for (k=0; k<ndig; k++) {
1424 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1425 if (rec->TestTrack(digit->fTracks[0]))
1426 new(lhits1[n++]) AliMUONDigit(*digit);
1428 gAlice->ResetDigits();
1429 gAlice->TreeD()->GetEvent(lastEntry+1);
1430 muonDigits = this->DigitsAddress(ich);
1431 ndig=muonDigits->GetEntriesFast();
1432 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1433 TClonesArray &lhits2 = *dig2;
1436 for (k=0; k<ndig; k++) {
1437 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1438 if (rec->TestTrack(digit->fTracks[0]))
1439 new(lhits2[n++]) AliMUONDigit(*digit);
1443 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1444 rec->FindRawClusters();
1449 gAlice->TreeR()->Fill();
1452 sprintf(hname,"TreeR%d",nev);
1453 gAlice->TreeR()->Write(hname);
1454 gAlice->TreeR()->Reset();
1455 printf("\n End of cluster finding for event %d", nev);
1459 //gObjectTable->Print();
1463 void AliMUON::Streamer(TBuffer &R__b)
1465 // Stream an object of class AliMUON.
1466 AliMUONChamber *iChamber;
1467 AliMUONTriggerCircuit *iTriggerCircuit;
1468 AliSegmentation *segmentation;
1469 AliMUONResponse *response;
1470 TClonesArray *digitsaddress;
1471 TClonesArray *rawcladdress;
1473 if (R__b.IsReading()) {
1474 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1475 AliDetector::Streamer(R__b);
1477 R__b >> fPadHits; // diff
1478 R__b >> fNLocalTrigger;
1479 R__b >> fLocalTrigger;
1480 R__b >> fNGlobalTrigger;
1481 R__b >> fGlobalTrigger;
1483 R__b >> fRawClusters;
1484 R__b.ReadArray(fNdch);
1485 R__b.ReadArray(fNrawch);
1490 R__b >> fTriggerCircuits;
1491 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1492 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1493 iTriggerCircuit->Streamer(R__b);
1495 // Stream chamber related information
1496 for (i =0; i<AliMUONConstants::NCh(); i++) {
1497 iChamber=(AliMUONChamber*) (*fChambers)[i];
1498 iChamber->Streamer(R__b);
1499 if (iChamber->Nsec()==1) {
1500 segmentation=iChamber->SegmentationModel(1);
1502 segmentation->Streamer(R__b);
1504 segmentation=iChamber->SegmentationModel(1);
1506 segmentation->Streamer(R__b);
1508 segmentation=iChamber->SegmentationModel(2);
1509 segmentation->Streamer(R__b);
1511 response=iChamber->ResponseModel();
1513 response->Streamer(R__b);
1514 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1515 digitsaddress->Streamer(R__b);
1516 if (i < AliMUONConstants::NTrackingCh()) {
1517 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1518 rawcladdress->Streamer(R__b);
1523 R__b.WriteVersion(AliMUON::IsA());
1524 AliDetector::Streamer(R__b);
1526 R__b << fPadHits; // diff
1527 R__b << fNLocalTrigger;
1528 R__b << fLocalTrigger;
1529 R__b << fNGlobalTrigger;
1530 R__b << fGlobalTrigger;
1532 R__b << fRawClusters;
1533 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1534 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1541 R__b << fTriggerCircuits;
1542 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1543 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1544 iTriggerCircuit->Streamer(R__b);
1546 for (i =0; i<AliMUONConstants::NCh(); i++) {
1547 iChamber=(AliMUONChamber*) (*fChambers)[i];
1548 iChamber->Streamer(R__b);
1549 if (iChamber->Nsec()==1) {
1550 segmentation=iChamber->SegmentationModel(1);
1552 segmentation->Streamer(R__b);
1554 segmentation=iChamber->SegmentationModel(1);
1556 segmentation->Streamer(R__b);
1557 segmentation=iChamber->SegmentationModel(2);
1559 segmentation->Streamer(R__b);
1561 response=iChamber->ResponseModel();
1563 response->Streamer(R__b);
1564 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1565 digitsaddress->Streamer(R__b);
1566 if (i < AliMUONConstants::NTrackingCh()) {
1567 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1568 rawcladdress->Streamer(R__b);
1573 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1576 // Initialise the pad iterator
1577 // Return the address of the first padhit for hit
1578 TClonesArray *theClusters = clusters;
1579 Int_t nclust = theClusters->GetEntriesFast();
1580 if (nclust && hit->fPHlast > 0) {
1581 AliMUON::fMaxIterPad=hit->fPHlast;
1582 AliMUON::fCurIterPad=hit->fPHfirst;
1583 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1589 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1591 AliMUON::fCurIterPad++;
1592 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1593 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1600 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1602 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1604 TTree *treeR = gAlice->TreeR();
1605 Int_t nent=(Int_t)treeR->GetEntries();
1606 treeR->GetEvent(nent-2+icathod-1);
1607 //treeR->GetEvent(icathod);
1608 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1610 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1611 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1616 AliMUON& AliMUON::operator = (const AliMUON& rhs)