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.31 2000/10/02 21:28:08 fca
18 Removal of useless dependecies via forward declarations
20 Revision 1.30 2000/10/02 16:58:29 egangler
21 Cleaning of the code :
24 -> some useless includes removed or replaced by "class" statement
26 Revision 1.29 2000/07/28 13:49:38 morsch
27 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
28 Can be used for simple acceptance studies.
30 Revision 1.28 2000/07/22 16:43:15 morsch
31 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
33 Revision 1.27 2000/07/22 16:36:50 morsch
34 Change order of indices in creation (new) of xhit and yhit
36 Revision 1.26 2000/07/03 11:54:57 morsch
37 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
38 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
40 Revision 1.25 2000/06/29 12:34:09 morsch
41 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
42 it usable with any other geometry class. The link to the object to which it belongs is
43 established via an index. This assumes that there exists a global geometry manager
44 from which the pointer to the parent object can be obtained (in our case gAlice).
46 Revision 1.24 2000/06/28 15:16:35 morsch
47 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
48 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
49 framework. The changes should have no side effects (mostly dummy arguments).
50 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
51 of chambers with overlapping modules (MakePadHits, Disintegration).
53 Revision 1.23 2000/06/28 12:19:17 morsch
54 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
55 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
56 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
57 It requires two cathode planes. Small modifications in the code will make it usable for
58 one cathode plane and, hence, more general (for test beam data).
59 AliMUONClusterFinder is now obsolete.
61 Revision 1.22 2000/06/28 08:06:10 morsch
62 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
63 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
64 It also naturally takes care of the TMinuit instance.
66 Revision 1.21 2000/06/27 08:54:41 morsch
67 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
69 Revision 1.20 2000/06/26 14:02:38 morsch
70 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
72 Revision 1.19 2000/06/22 13:40:51 morsch
73 scope problem on HP, "i" declared once
74 pow changed to TMath::Power (PH, AM)
76 Revision 1.18 2000/06/15 07:58:48 morsch
77 Code from MUON-dev joined
79 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
80 - add TriggerCircuit (PC)
81 - add GlobalTrigger and LocalTrigger and specific methods (PC)
83 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
84 Most coding rule violations corrected
86 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
87 RULE RN17 violations corrected
89 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
90 Code revised by P. Crochet:
91 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
92 - ToF included in the method MakePadHits
93 - inner radius of flange between beam shielding and trigger corrected
94 - Trigger global volume updated (according to the new geometry)
96 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
97 Some changes of variable names curing viols and methods concerning
98 correlated clusters removed.
100 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
101 Memory leak suppressed in function Digitise:
102 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
104 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
105 Positions of trigger chambers corrected (P.C.)
107 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
108 Call to AddHitList introduced to make this version compatible with head.
110 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
111 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
113 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
114 Trigger included into initialization and digitization
116 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
117 Log messages of previous revisions added
119 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
120 Z position of the chambers:
121 it was the Z position of the stations;
122 it is now really the Z position of the chambers.
123 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
124 !!!! AND "AliMUONChamber::ZPosition"
125 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
126 !!!! AND "AliMUONChamber::Z"
128 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
129 Correction for mis-spelling of NCH
131 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
137 ///////////////////////////////////////////////
138 // Manager and hits classes for set:MUON //
139 ////////////////////////////////////////////////
143 #include <TRotMatrix.h>
144 #include <TGeometry.h>
150 #include <TObjArray.h>
152 #include <TParticle.h>
158 #include <TDirectory.h>
159 #include <TObjectTable.h>
164 #include "AliMUONHit.h"
165 #include "AliMUONPadHit.h"
166 #include "AliMUONDigit.h"
167 #include "AliMUONTransientDigit.h"
168 #include "AliMUONRawCluster.h"
169 #include "AliMUONLocalTrigger.h"
170 #include "AliMUONGlobalTrigger.h"
171 #include "AliMUONTriggerCircuit.h"
172 #include "AliHitMap.h"
173 #include "AliMUONHitMapA1.h"
174 #include "AliMUONChamberTrigger.h"
175 #include "AliMUONConstants.h"
176 #include "AliMUONClusterFinderVS.h"
177 #include "AliMUONTriggerDecision.h"
180 #include "AliMUONClusterInput.h"
181 #include "iostream.h"
182 #include "AliCallf77.h"
183 #include "AliConst.h"
185 // Defaults parameters for Z positions of chambers
186 // taken from values for "stations" in AliMUON::AliMUON
187 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
188 // and from array "dstation" in AliMUONv1::CreateGeometry
189 // Float_t dstation[5]={20., 20., 20, 20., 20.};
190 // for tracking chambers,
191 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
192 // for the first and second chambers in the station, respectively,
193 // and from "DTPLANES" in AliMUONv1::CreateGeometry
194 // const Float_t DTPLANES = 15.;
195 // for trigger chambers,
196 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
197 // for the first and second chambers in the station, respectively
200 //___________________________________________
208 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
221 //___________________________________________
222 AliMUON::AliMUON(const char *name, const char *title)
223 : AliDetector(name,title)
227 <img src="gif/alimuon.gif">
231 fHits = new TClonesArray("AliMUONHit",1000);
232 gAlice->AddHitList(fHits);
233 fPadHits = new TClonesArray("AliMUONPadHit",10000);
237 fNdch = new Int_t[AliMUONConstants::NCh()];
239 fDchambers = new TObjArray(AliMUONConstants::NCh());
243 for (i=0; i<AliMUONConstants::NCh() ;i++) {
244 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
248 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
250 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
252 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
253 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
257 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
259 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
262 SetMarkerColor(kRed);
270 fChambers = new TObjArray(AliMUONConstants::NCh());
272 // Loop over stations
273 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
274 // Loop over 2 chambers in the station
275 for (Int_t stCH = 0; stCH < 2; stCH++) {
278 // Default Parameters for Muon Tracking Stations
283 if (ch < AliMUONConstants::NTrackingCh()) {
284 (*fChambers)[ch] = new AliMUONChamber(ch);
286 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
289 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
292 // Default values for Z of chambers
293 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
295 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
296 // Set chamber inner and outer radius to default
297 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
298 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
300 } // Chamber stCH (0, 1) in
301 } // Station st (0...)
314 // cp new design of AliMUONTriggerDecision
315 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
316 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
317 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
319 // cp new design of AliMUONTriggerDecision
323 //___________________________________________
324 AliMUON::AliMUON(const AliMUON& rMUON)
326 // Dummy copy constructor
333 printf("Calling AliMUON destructor !!!\n");
340 delete fGlobalTrigger;
343 delete fLocalTrigger;
346 for (i=0;i<AliMUONConstants::NCh();i++) {
347 delete (*fDchambers)[i];
352 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
353 delete (*fRawClusters)[i];
358 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
359 delete (*fTriggerCircuits)[circ];
361 delete fTriggerCircuits;
364 //___________________________________________
365 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
367 TClonesArray &lhits = *fHits;
368 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
370 //___________________________________________
371 void AliMUON::AddPadHit(Int_t *clhits)
373 TClonesArray &lclusters = *fPadHits;
374 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
376 //_____________________________________________________________________________
377 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
380 // Add a MUON digit to the list
383 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
384 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
387 //_____________________________________________________________________________
388 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
391 // Add a MUON digit to the list
394 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
395 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
398 //___________________________________________
399 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
401 Int_t *pairUnlike, Int_t *pairLike)
403 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
404 TClonesArray &globalTrigger = *fGlobalTrigger;
405 new(globalTrigger[fNGlobalTrigger++])
406 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
409 //___________________________________________
410 void AliMUON::AddLocalTrigger(Int_t *localtr)
412 // add a MUON Local Trigger to the list
413 TClonesArray &localTrigger = *fLocalTrigger;
414 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
417 //___________________________________________
418 void AliMUON::BuildGeometry()
420 TNode *node, *nodeF, *top, *nodeS;
421 const int kColorMUON = kBlue;
422 const int kColorMUON2 = kYellow;
423 const int kColorMUON3 = kBlue;
425 top=gAlice->GetGeometry()->GetNode("alice");
428 // z-Positions of Chambers
429 const Float_t kCz[7]={511., 686., 971., 1245., 1445., 1600, 1700.};
430 // inner diameter (Xlenght for trigger chamber -> active area)
431 const Float_t kDmin[7]={ 35., 47., 67., 86., 100., 544., 544.};
432 // outer diameter (Ylenght for trigger chamber -> active area)
433 const Float_t kDmax[7]={183., 245., 346., 520., 520., 612., 612.};
435 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
436 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
437 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
438 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
440 Float_t rmin, rmax, dx, dy, dz, dr, xpos, ypos, zpos;
441 Float_t dzc1=4.; // tracking chambers
442 Float_t dzc2=15.; // trigger chambers
443 Float_t hole=102.; // x-y hole around beam pipe for trig. chambers
444 Float_t zscale; // scaling parameter trigger chambers
445 Float_t halfx, halfy;
446 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
447 char nameSense1[9], nameSense2[9];
448 for (Int_t i=0; i<7; i++) {
449 for (Int_t j=0; j<2; j++) {
451 if (i<5) { // tracking chambers
464 sprintf(nameChamber,"C_MUON%d",id);
465 sprintf(nameSense,"S_MUON%d",id);
466 sprintf(nameSense1,"S1_MUON%d",id);
467 sprintf(nameSense2,"S2_MUON%d",id);
468 sprintf(nameFrame,"F_MUON%d",id);
469 if (i<3) { // tracking chambers
470 rmin = kDmin[i]/2.-3;
471 rmax = kDmax[i]/2.+3;
472 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
475 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
479 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
481 sprintf(nameNode,"MUON%d",100+id);
482 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,zpos,"");
483 node->SetLineColor(kColorMUON);
486 sprintf(nameNode,"MUON%d",200+id);
487 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
488 node->SetLineColor(kColorMUON);
491 sprintf(nameNode,"MUON%d",300+id);
492 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
493 nodeF->SetLineColor(kColorMUON);
495 sprintf(nameNode,"MUON%d",400+id);
496 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
497 nodeF->SetLineColor(kColorMUON);
499 sprintf(nameNode,"MUON%d",500+id);
500 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
501 nodeF->SetLineColor(kColorMUON);
503 sprintf(nameNode,"MUON%d",600+id);
504 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
505 nodeF->SetLineColor(kColorMUON);
506 } else if (i == 3 || i == 4) {
507 Int_t npcb[7] = {7, 7, 6, 6, 5, 4, 3};
511 Float_t ypos1=-0.75+20.;
512 Float_t ypos2= 0.75-20.;
514 new TBRIK(nameChamber,"Mother","void",340,340,5.);
516 sprintf(nameNode,"MUON%d",100+id);
517 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
518 node->SetLineColor(kBlack);
523 for (Int_t j=0; j<7; j++)
525 printf("\n BuildGeometry %d", j);
527 sprintf(nameSlat,"SLAT%d",100*id+j);
528 new TBRIK(nameSlat,"Slat Module","void",20.*npcb[j],20.,0.25);
533 color = TMath::Even(j) ? kColorMUON2 : kColorMUON3;
535 sprintf(nameNode,"SLAT%d",100*id+j);
537 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos1,0,"");
538 nodeSlat->SetLineColor(color);
541 sprintf(nameNode,"SLAT%d",100*id+j+7);
543 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos1,0,"");
544 nodeSlat->SetLineColor(color);
546 color = TMath::Even(j) ? kColorMUON3 : kColorMUON2;
547 sprintf(nameNode,"SLAT%d",100*id+j+14);
549 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos2,0,"");
550 nodeSlat->SetLineColor(color);
553 sprintf(nameNode,"SLAT%d",100*id+j+21);
555 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos2,0,"");
556 nodeSlat->SetLineColor(color);
564 Float_t xsize=kDmin[i]*zscale;
565 Float_t ysize=kDmax[i]*zscale;
566 Float_t holeScaled=hole*zscale;
570 new TBRIK(nameChamber,"Mother","void",halfx,halfy,0.25);
572 sprintf(nameNode,"MUON%d",100+id);
573 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
574 node->SetLineColor(kColorMUON2);
577 // up/down of beam pipe
579 halfy=(ysize/2.-holeScaled/2.)/2.;
580 new TBRIK(nameSense,"Sens. region","void",halfx,halfy,0.25);
583 ypos=holeScaled/2.+((ysize/2.-holeScaled/2.)/2.);
584 sprintf(nameNode,"MUON%d",200+id);
585 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
586 nodeS->SetLineColor(kColorMUON2);
590 sprintf(nameNode,"MUON%d",300+id);
591 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
592 nodeS->SetLineColor(kColorMUON2);
594 // left/right of beam pipe
595 halfx=(xsize/2.-holeScaled/2.)/2.;
597 new TBRIK(nameSense1,"Sens. region","void",halfx,halfy,0.25);
600 xpos=holeScaled/2.+((xsize/2.-holeScaled/2.)/2.);
601 sprintf(nameNode,"MUON%d",400+id);
602 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
603 nodeS->SetLineColor(kColorMUON2);
607 sprintf(nameNode,"MUON%d",500+id);
608 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
609 nodeS->SetLineColor(kColorMUON2);
614 new TBRIK(nameSense2,"Sens. region","void",halfx,halfy,0.25);
617 xpos=holeScaled/2.-halfx;
619 sprintf(nameNode,"MUON%d",600+id);
620 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
621 nodeS->SetLineColor(kColorMUON2);
625 sprintf(nameNode,"MUON%d",700+id);
626 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
627 nodeS->SetLineColor(kColorMUON2);
631 sprintf(nameNode,"MUON%d",800+id);
632 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
633 nodeS->SetLineColor(kColorMUON2);
637 sprintf(nameNode,"MUON%d",900+id);
638 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
639 nodeS->SetLineColor(kColorMUON2);
646 //___________________________________________
647 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
652 //___________________________________________
653 void AliMUON::MakeBranch(Option_t* option)
655 // Create Tree branches for the MUON.
656 const Int_t kBufferSize = 4000;
658 sprintf(branchname,"%sCluster",GetName());
660 AliDetector::MakeBranch(option);
662 if (fPadHits && gAlice->TreeH()) {
663 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
664 printf("Making Branch %s for clusters\n",branchname);
667 // one branch for digits per chamber
670 for (i=0; i<AliMUONConstants::NCh() ;i++) {
671 sprintf(branchname,"%sDigits%d",GetName(),i+1);
673 if (fDchambers && gAlice->TreeD()) {
674 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
675 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
679 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
681 // one branch for raw clusters per chamber
682 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
683 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
685 if (fRawClusters && gAlice->TreeR()) {
686 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
687 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
691 // one branch for global trigger
692 sprintf(branchname,"%sGlobalTrigger",GetName());
693 if (fGlobalTrigger && gAlice->TreeR()) {
694 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
695 printf("Making Branch %s for Global Trigger\n",branchname);
697 // one branch for local trigger
698 sprintf(branchname,"%sLocalTrigger",GetName());
699 if (fLocalTrigger && gAlice->TreeR()) {
700 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
701 printf("Making Branch %s for Local Trigger\n",branchname);
706 //___________________________________________
707 void AliMUON::SetTreeAddress()
709 // Set branch address for the Hits and Digits Tree.
711 AliDetector::SetTreeAddress();
714 TTree *treeH = gAlice->TreeH();
715 TTree *treeD = gAlice->TreeD();
716 TTree *treeR = gAlice->TreeR();
720 branch = treeH->GetBranch("MUONCluster");
721 if (branch) branch->SetAddress(&fPadHits);
726 for (int i=0; i<AliMUONConstants::NCh(); i++) {
727 sprintf(branchname,"%sDigits%d",GetName(),i+1);
729 branch = treeD->GetBranch(branchname);
730 if (branch) branch->SetAddress(&((*fDchambers)[i]));
735 // printf("SetTreeAddress --- treeR address %p \n",treeR);
738 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
739 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
741 branch = treeR->GetBranch(branchname);
742 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
747 branch = treeR->GetBranch("MUONLocalTrigger");
748 if (branch) branch->SetAddress(&fLocalTrigger);
750 if (fGlobalTrigger) {
751 branch = treeR->GetBranch("MUONGlobalTrigger");
752 if (branch) branch->SetAddress(&fGlobalTrigger);
756 //___________________________________________
757 void AliMUON::ResetHits()
759 // Reset number of clusters and the cluster array for this detector
760 AliDetector::ResetHits();
762 if (fPadHits) fPadHits->Clear();
765 //____________________________________________
766 void AliMUON::ResetDigits()
769 // Reset number of digits and the digits array for this detector
771 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
772 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
773 if (fNdch) fNdch[i]=0;
776 //____________________________________________
777 void AliMUON::ResetRawClusters()
780 // Reset number of raw clusters and the raw clust array for this detector
782 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
783 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
784 if (fNrawch) fNrawch[i]=0;
788 //____________________________________________
789 void AliMUON::ResetTrigger()
791 // Reset Local and Global Trigger
793 if (fGlobalTrigger) fGlobalTrigger->Clear();
795 if (fLocalTrigger) fLocalTrigger->Clear();
798 //____________________________________________
799 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
802 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
803 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
806 //___________________________________________
807 void AliMUON::SetChambersZ(const Float_t *Z)
809 // Set Z values for all chambers (tracking and trigger)
810 // from the array pointed to by "Z"
811 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
812 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
816 //___________________________________________
817 void AliMUON::SetChambersZToDefault()
819 // Set Z values for all chambers (tracking and trigger)
821 SetChambersZ(AliMUONConstants::DefaultChamberZ());
825 //___________________________________________
826 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
829 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
830 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
833 //___________________________________________
834 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
837 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
838 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
841 //___________________________________________
842 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
845 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
846 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
849 //___________________________________________
850 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
853 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
854 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
857 //___________________________________________
858 void AliMUON::SetMaxStepGas(Float_t p1)
863 //___________________________________________
864 void AliMUON::SetMaxStepAlu(Float_t p1)
869 //___________________________________________
870 void AliMUON::SetMaxDestepGas(Float_t p1)
875 //___________________________________________
876 void AliMUON::SetMaxDestepAlu(Float_t p1)
880 //___________________________________________
881 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
884 fAccMin=angmin*TMath::Pi()/180;
885 fAccMax=angmax*TMath::Pi()/180;
888 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
889 // Loop over 2 chambers in the station
890 for (Int_t stCH = 0; stCH < 2; stCH++) {
892 // Set chamber inner and outer radius according to acceptance cuts
893 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
894 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
899 //___________________________________________
900 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
902 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
905 //___________________________________________
906 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
908 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
911 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
913 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
916 void AliMUON::SetNsec(Int_t id, Int_t nsec)
918 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
922 //___________________________________________
926 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
927 Float_t eloss, Float_t tof, Int_t idvol)
930 // Calls the charge disintegration method of the current chamber and adds
931 // the simulated cluster to the root treee
934 Float_t newclust[6][500];
939 // Integrated pulse height on chamber
945 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
948 ((AliMUONChamber*) (*fChambers)[idvol])
949 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
951 // if (idvol == 6) printf("\n nnew %d \n", nnew);
954 for (Int_t i=0; i<nnew; i++) {
955 if (Int_t(newclust[3][i]) > 0) {
958 clhits[1] = Int_t(newclust[5][i]);
960 clhits[2] = Int_t(newclust[0][i]);
962 clhits[3] = Int_t(newclust[1][i]);
964 clhits[4] = Int_t(newclust[2][i]);
966 clhits[5] = Int_t(newclust[3][i]);
967 // Pad: chamber sector
968 clhits[6] = Int_t(newclust[4][i]);
975 //----------------------------------------------------------------------
977 void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
979 // keep galice.root for signal and name differently the file for
980 // background when add! otherwise the track info for signal will be lost !
982 static Bool_t first=kTRUE;
984 char *addBackground = strstr(option,"Add");
987 AliMUONChamber* iChamber;
988 AliSegmentation* segmentation;
993 TObjArray *list=new TObjArray;
994 static TClonesArray *pAddress=0;
995 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
998 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
999 AliHitMap** hitMap= new AliHitMap* [AliMUONConstants::NCh()];
1000 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
1001 if (addBackground ) {
1004 cout<<"filename"<<fFileName<<endl;
1005 file=new TFile(fFileName);
1006 cout<<"I have opened "<<fFileName<<" file "<<endl;
1007 fHits2 = new TClonesArray("AliMUONHit",1000 );
1008 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
1013 // Get Hits Tree header from file
1014 if(fHits2) fHits2->Clear();
1015 if(fPadHits2) fPadHits2->Clear();
1016 if(fTrH1) delete fTrH1;
1020 sprintf(treeName,"TreeH%d",bgrEvent);
1021 fTrH1 = (TTree*)gDirectory->Get(treeName);
1022 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
1025 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
1027 // Set branch addresses
1029 char branchname[20];
1030 sprintf(branchname,"%s",GetName());
1031 if (fTrH1 && fHits2) {
1032 branch = fTrH1->GetBranch(branchname);
1033 if (branch) branch->SetAddress(&fHits2);
1035 if (fTrH1 && fPadHits2) {
1036 branch = fTrH1->GetBranch("MUONCluster");
1037 if (branch) branch->SetAddress(&fPadHits2);
1040 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
1041 //printf("background - ntracks1 - %d\n",ntracks1);
1044 // loop over cathodes
1048 for (int icat=0; icat<2; icat++) {
1050 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
1051 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
1052 iChamber=(AliMUONChamber*) (*fChambers)[i];
1053 if (iChamber->Nsec()==1 && icat==1) {
1056 segmentation=iChamber->SegmentationModel(icat+1);
1058 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
1061 //printf("Start loop over tracks \n");
1066 TTree *treeH = gAlice->TreeH();
1067 Int_t ntracks =(Int_t) treeH->GetEntries();
1070 Float_t ** xhit = new Float_t * [AliMUONConstants::NCh()];
1071 for (jj=0; jj<AliMUONConstants::NCh(); jj++) xhit[jj] = new Float_t[2];
1072 Float_t ** yhit = new Float_t * [AliMUONConstants::NCh()];
1073 for (jj=0; jj<AliMUONConstants::NCh(); jj++) yhit[jj] = new Float_t[2];
1075 for (Int_t track=0; track<ntracks; track++) {
1076 gAlice->ResetHits();
1077 treeH->GetEvent(track);
1080 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
1082 mHit=(AliMUONHit*)pMUON->NextHit())
1084 Int_t nch = mHit->fChamber-1; // chamber number
1085 if (nch > AliMUONConstants::NCh()-1) continue;
1086 // if (nch > 9) continue;
1087 iChamber = &(pMUON->Chamber(nch));
1089 if (addBackground) {
1091 if (mHit->fParticle == kMuonPlus
1092 || mHit->fParticle == kMuonMinus) {
1093 xhit[nch][nmuon[nch]]=mHit->X();
1094 yhit[nch][nmuon[nch]]=mHit->Y();
1096 if (nmuon[nch] >2) printf("nmuon %d\n",nmuon[nch]);
1104 // Loop over pad hits
1105 for (AliMUONPadHit* mPad=
1106 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
1108 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
1110 Int_t cathode = mPad->fCathode; // cathode number
1111 Int_t ipx = mPad->fPadX; // pad number on X
1112 Int_t ipy = mPad->fPadY; // pad number on Y
1113 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1114 // printf("\n Pad: %d %d %d %d", ipx, ipy, cathode,nch);
1118 if (cathode != (icat+1)) continue;
1119 // fill the info array
1120 // Float_t thex, they, thez;
1121 segmentation=iChamber->SegmentationModel(cathode);
1122 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1123 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1124 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1126 new((*pAddress)[countadr++]) TVector(2);
1127 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1128 trinfo(0)=(Float_t)track;
1129 trinfo(1)=(Float_t)iqpad;
1135 if (mHit->fParticle == kMuonPlus ||
1136 mHit->fParticle == kMuonMinus) {
1137 digits[4]=mPad->fHitNumber;
1138 } else digits[4]=-1;
1140 AliMUONTransientDigit* pdigit;
1141 // build the list of fired pads and update the info
1142 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1144 list->AddAtAndExpand(
1145 new AliMUONTransientDigit(nch,digits),counter);
1147 hitMap[nch]->SetHit(ipx, ipy, counter);
1149 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1151 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1152 trlist->Add(&trinfo);
1154 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1156 (*pdigit).fSignal+=iqpad;
1157 (*pdigit).fPhysics+=iqpad;
1158 // update list of tracks
1159 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
1160 Int_t lastEntry=trlist->GetLast();
1161 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1162 TVector &ptrk=*pTrack;
1163 Int_t lastTrack = Int_t(ptrk(0));
1164 Int_t lastCharge = Int_t(ptrk(1));
1165 if (lastTrack==track) {
1167 trlist->RemoveAt(lastEntry);
1168 trinfo(0)=lastTrack;
1169 trinfo(1)=lastCharge;
1170 trlist->AddAt(&trinfo,lastEntry);
1172 trlist->Add(&trinfo);
1174 // check the track list
1175 Int_t nptracks=trlist->GetEntriesFast();
1177 for (Int_t tr=0;tr<nptracks;tr++) {
1178 TVector *ppTrack=(TVector*)trlist->At(tr);
1179 TVector &pptrk=*ppTrack;
1180 trk[tr] = Int_t(pptrk(0));
1181 chtrk[tr] = Int_t(pptrk(1));
1183 } // end if nptracks
1185 } //end loop over clusters
1189 // open the file with background
1191 if (addBackground) {
1192 ntracks =(Int_t)fTrH1->GetEntries();
1196 for (Int_t track=0; track<ntracks; track++) {
1198 if (fHits2) fHits2->Clear();
1199 if (fPadHits2) fPadHits2->Clear();
1201 fTrH1->GetEvent(track);
1205 for(int i=0;i<fHits2->GetEntriesFast();++i)
1207 mHit=(AliMUONHit*) (*fHits2)[i];
1208 Int_t nch = mHit->fChamber-1; // chamber number
1209 if (nch >9) continue;
1210 iChamber = &(pMUON->Chamber(nch));
1211 Int_t rmin = (Int_t)iChamber->RInner();
1212 Int_t rmax = (Int_t)iChamber->ROuter();
1213 Float_t xbgr=mHit->X();
1214 Float_t ybgr=mHit->Y();
1217 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1218 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1219 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
1220 if (dist<100) cond=kTRUE;
1222 if (!cond) continue;
1225 // Loop over pad hits
1226 for (AliMUONPadHit* mPad=
1227 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
1229 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
1231 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
1232 Int_t cathode = mPad->fCathode; // cathode number
1233 Int_t ipx = mPad->fPadX; // pad number on X
1234 Int_t ipy = mPad->fPadY; // pad number on Y
1235 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1237 if (cathode != (icat+1)) continue;
1238 printf("\n Pad: %d %d %d", ipx, ipy, cathode);
1240 // Float_t thex, they, thez;
1241 // segmentation=iChamber->SegmentationModel(cathode);
1242 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1243 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1244 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1245 new((*pAddress)[countadr++]) TVector(2);
1246 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1247 trinfo(0)=-1; // tag background
1256 AliMUONTransientDigit* pdigit;
1257 // build the list of fired pads and update the info
1258 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1259 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1261 hitMap[nch]->SetHit(ipx, ipy, counter);
1264 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1266 TObjArray *trlist=(TObjArray*)pdigit->
1268 trlist->Add(&trinfo);
1270 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1272 (*pdigit).fSignal+=iqpad;
1274 // update list of tracks
1275 TObjArray* trlist=(TObjArray*)pdigit->
1277 Int_t lastEntry=trlist->GetLast();
1278 TVector *pTrack=(TVector*)trlist->
1280 TVector &ptrk=*pTrack;
1281 Int_t lastTrack=Int_t(ptrk(0));
1282 if (lastTrack==-1) {
1285 trlist->Add(&trinfo);
1287 // check the track list
1288 Int_t nptracks=trlist->GetEntriesFast();
1290 for (Int_t tr=0;tr<nptracks;tr++) {
1291 TVector *ppTrack=(TVector*)trlist->At(tr);
1292 TVector &pptrk=*ppTrack;
1293 trk[tr]=Int_t(pptrk(0));
1294 chtrk[tr]=Int_t(pptrk(1));
1296 } // end if nptracks
1298 } //end loop over clusters
1301 //Int_t nentr2=list->GetEntriesFast();
1302 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1303 TTree *fAli=gAlice->TreeK();
1306 if (fAli) file =fAli->GetCurrentFile();
1308 } // if addBackground
1314 Int_t nentries=list->GetEntriesFast();
1316 for (Int_t nent=0;nent<nentries;nent++) {
1317 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
1318 if (address==0) continue;
1319 Int_t ich=address->fChamber;
1320 Int_t q=address->fSignal;
1321 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1323 // Digit Response (noise, threshold, saturation, ...)
1324 // if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1325 AliMUONResponse * response=iChamber->ResponseModel();
1326 q=response->DigitResponse(q);
1330 digits[0]=address->fPadX;
1331 digits[1]=address->fPadY;
1333 digits[3]=address->fPhysics;
1334 digits[4]=address->fHit;
1336 TObjArray* trlist=(TObjArray*)address->TrackList();
1337 Int_t nptracks=trlist->GetEntriesFast();
1338 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1340 // this was changed to accomodate the real number of tracks
1341 if (nptracks > 10) {
1342 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1346 printf("Attention - nptracks > 2 %d \n",nptracks);
1347 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1349 for (Int_t tr=0;tr<nptracks;tr++) {
1350 TVector *ppP=(TVector*)trlist->At(tr);
1351 if(!ppP ) printf("ppP - %p\n",ppP);
1353 tracks[tr]=Int_t(pp(0));
1354 charges[tr]=Int_t(pp(1));
1355 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
1356 } //end loop over list of tracks for one pad
1357 // Sort list of tracks according to charge
1359 SortTracks(tracks,charges,nptracks);
1361 if (nptracks < 10 ) {
1362 for (Int_t i=nptracks; i<10; i++) {
1369 pMUON->AddDigits(ich,tracks,charges,digits);
1372 //cout<<"I'm out of the loops for digitisation"<<endl;
1373 // gAlice->GetEvent(nev);
1374 gAlice->TreeD()->Fill();
1375 pMUON->ResetDigits();
1379 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
1387 } //end loop over cathodes
1390 sprintf(hname,"TreeD%d",nev);
1391 gAlice->TreeD()->Write(hname);
1393 gAlice->TreeD()->Reset();
1397 // gObjectTable->Print();
1400 void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1403 // Sort the list of tracks contributing to a given digit
1404 // Only the 3 most significant tracks are acctually sorted
1408 // Loop over signals, only 3 times
1413 Int_t idx[3] = {-2,-2,-2};
1414 Int_t jch[3] = {-2,-2,-2};
1415 Int_t jtr[3] = {-2,-2,-2};
1418 if (ntr<3) imax=ntr;
1420 for(i=0;i<imax;i++){
1426 if((i == 1 && j == idx[i-1])
1427 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1429 if(charges[j] > qmax) {
1437 jch[i]=charges[jmax];
1438 jtr[i]=tracks[jmax];
1455 //___________________________________________
1456 void AliMUON::Trigger(Int_t nev){
1457 // call the Trigger Algorithm and fill TreeR
1459 Int_t singlePlus[3] = {0,0,0};
1460 Int_t singleMinus[3] = {0,0,0};
1461 Int_t singleUndef[3] = {0,0,0};
1462 Int_t pairUnlike[3] = {0,0,0};
1463 Int_t pairLike[3] = {0,0,0};
1466 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1467 decision->Trigger();
1468 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1469 pairUnlike, pairLike);
1470 // add a local trigger in the list
1471 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
1474 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
1475 if(decision->GetITrigger(icirc)==1) {
1476 Int_t localtr[7]={0,0,0,0,0,0,0};
1477 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1478 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1480 localtr[1] = decision->GetStripX11(icirc);
1481 localtr[2] = decision->GetDev(icirc);
1482 localtr[3] = decision->GetStripY11(icirc);
1483 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1484 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1485 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1486 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1488 AddLocalTrigger(localtr); // add a local trigger in the list
1493 gAlice->TreeR()->Fill();
1496 sprintf(hname,"TreeR%d",nev);
1497 gAlice->TreeR()->Write(hname);
1498 gAlice->TreeR()->Reset();
1499 printf("\n End of trigger for event %d", nev);
1503 //____________________________________________
1504 void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1506 TClonesArray *dig1, *dig2;
1508 dig1 = new TClonesArray("AliMUONDigit",1000);
1509 dig2 = new TClonesArray("AliMUONDigit",1000);
1510 AliMUONDigit *digit;
1512 // Loop on chambers and on cathode planes
1515 for (Int_t ich=0;ich<10;ich++) {
1516 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1517 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1518 gAlice->ResetDigits();
1519 gAlice->TreeD()->GetEvent(lastEntry);
1520 TClonesArray *muonDigits = this->DigitsAddress(ich);
1521 ndig=muonDigits->GetEntriesFast();
1522 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1523 TClonesArray &lhits1 = *dig1;
1525 for (k=0; k<ndig; k++) {
1526 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1527 if (rec->TestTrack(digit->fTracks[0]))
1528 new(lhits1[n++]) AliMUONDigit(*digit);
1530 gAlice->ResetDigits();
1531 gAlice->TreeD()->GetEvent(lastEntry+1);
1532 muonDigits = this->DigitsAddress(ich);
1533 ndig=muonDigits->GetEntriesFast();
1534 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1535 TClonesArray &lhits2 = *dig2;
1538 for (k=0; k<ndig; k++) {
1539 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1540 if (rec->TestTrack(digit->fTracks[0]))
1541 new(lhits2[n++]) AliMUONDigit(*digit);
1545 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1546 rec->FindRawClusters();
1551 gAlice->TreeR()->Fill();
1554 sprintf(hname,"TreeR%d",nev);
1555 gAlice->TreeR()->Write(hname);
1556 gAlice->TreeR()->Reset();
1557 printf("\n End of cluster finding for event %d", nev);
1561 //gObjectTable->Print();
1565 void AliMUON::Streamer(TBuffer &R__b)
1567 // Stream an object of class AliMUON.
1568 AliMUONChamber *iChamber;
1569 AliMUONTriggerCircuit *iTriggerCircuit;
1570 AliSegmentation *segmentation;
1571 AliMUONResponse *response;
1572 TClonesArray *digitsaddress;
1573 TClonesArray *rawcladdress;
1575 if (R__b.IsReading()) {
1576 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1577 AliDetector::Streamer(R__b);
1579 R__b >> fPadHits; // diff
1580 R__b >> fNLocalTrigger;
1581 R__b >> fLocalTrigger;
1582 R__b >> fNGlobalTrigger;
1583 R__b >> fGlobalTrigger;
1585 R__b >> fRawClusters;
1586 R__b.ReadArray(fNdch);
1587 R__b.ReadArray(fNrawch);
1592 R__b >> fTriggerCircuits;
1593 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1594 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1595 iTriggerCircuit->Streamer(R__b);
1597 // Stream chamber related information
1598 for (i =0; i<AliMUONConstants::NCh(); i++) {
1599 iChamber=(AliMUONChamber*) (*fChambers)[i];
1600 iChamber->Streamer(R__b);
1601 if (iChamber->Nsec()==1) {
1602 segmentation=iChamber->SegmentationModel(1);
1604 segmentation->Streamer(R__b);
1606 segmentation=iChamber->SegmentationModel(1);
1608 segmentation->Streamer(R__b);
1610 segmentation=iChamber->SegmentationModel(2);
1611 segmentation->Streamer(R__b);
1613 response=iChamber->ResponseModel();
1615 response->Streamer(R__b);
1616 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1617 digitsaddress->Streamer(R__b);
1618 if (i < AliMUONConstants::NTrackingCh()) {
1619 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1620 rawcladdress->Streamer(R__b);
1625 R__b.WriteVersion(AliMUON::IsA());
1626 AliDetector::Streamer(R__b);
1628 R__b << fPadHits; // diff
1629 R__b << fNLocalTrigger;
1630 R__b << fLocalTrigger;
1631 R__b << fNGlobalTrigger;
1632 R__b << fGlobalTrigger;
1634 R__b << fRawClusters;
1635 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1636 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1643 R__b << fTriggerCircuits;
1644 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1645 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1646 iTriggerCircuit->Streamer(R__b);
1648 for (i =0; i<AliMUONConstants::NCh(); i++) {
1649 iChamber=(AliMUONChamber*) (*fChambers)[i];
1650 iChamber->Streamer(R__b);
1651 if (iChamber->Nsec()==1) {
1652 segmentation=iChamber->SegmentationModel(1);
1654 segmentation->Streamer(R__b);
1656 segmentation=iChamber->SegmentationModel(1);
1658 segmentation->Streamer(R__b);
1659 segmentation=iChamber->SegmentationModel(2);
1661 segmentation->Streamer(R__b);
1663 response=iChamber->ResponseModel();
1665 response->Streamer(R__b);
1666 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1667 digitsaddress->Streamer(R__b);
1668 if (i < AliMUONConstants::NTrackingCh()) {
1669 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1670 rawcladdress->Streamer(R__b);
1675 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1678 // Initialise the pad iterator
1679 // Return the address of the first padhit for hit
1680 TClonesArray *theClusters = clusters;
1681 Int_t nclust = theClusters->GetEntriesFast();
1682 if (nclust && hit->fPHlast > 0) {
1683 AliMUON::fMaxIterPad=hit->fPHlast;
1684 AliMUON::fCurIterPad=hit->fPHfirst;
1685 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1691 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1693 AliMUON::fCurIterPad++;
1694 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1695 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1702 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1704 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1706 TTree *treeR = gAlice->TreeR();
1707 Int_t nent=(Int_t)treeR->GetEntries();
1708 treeR->GetEvent(nent-2+icathod-1);
1709 //treeR->GetEvent(icathod);
1710 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1712 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1713 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1718 AliMUON& AliMUON::operator = (const AliMUON& rhs)