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.35 2000/10/24 19:46:21 morsch
18 BuildGeometry updated for slats in station 3-4.
20 Revision 1.34 2000/10/18 11:42:06 morsch
21 - AliMUONRawCluster contains z-position.
22 - Some clean-up of useless print statements during initialisations.
24 Revision 1.33 2000/10/09 14:01:57 morsch
25 Unused variables removed.
27 Revision 1.32 2000/10/06 09:08:10 morsch
28 Built geometry includes slat geometry for event display.
30 Revision 1.31 2000/10/02 21:28:08 fca
31 Removal of useless dependecies via forward declarations
33 Revision 1.30 2000/10/02 16:58:29 egangler
34 Cleaning of the code :
37 -> some useless includes removed or replaced by "class" statement
39 Revision 1.29 2000/07/28 13:49:38 morsch
40 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
41 Can be used for simple acceptance studies.
43 Revision 1.28 2000/07/22 16:43:15 morsch
44 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
46 Revision 1.27 2000/07/22 16:36:50 morsch
47 Change order of indices in creation (new) of xhit and yhit
49 Revision 1.26 2000/07/03 11:54:57 morsch
50 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
51 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
53 Revision 1.25 2000/06/29 12:34:09 morsch
54 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
55 it usable with any other geometry class. The link to the object to which it belongs is
56 established via an index. This assumes that there exists a global geometry manager
57 from which the pointer to the parent object can be obtained (in our case gAlice).
59 Revision 1.24 2000/06/28 15:16:35 morsch
60 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
61 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
62 framework. The changes should have no side effects (mostly dummy arguments).
63 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
64 of chambers with overlapping modules (MakePadHits, Disintegration).
66 Revision 1.23 2000/06/28 12:19:17 morsch
67 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
68 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
69 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
70 It requires two cathode planes. Small modifications in the code will make it usable for
71 one cathode plane and, hence, more general (for test beam data).
72 AliMUONClusterFinder is now obsolete.
74 Revision 1.22 2000/06/28 08:06:10 morsch
75 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
76 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
77 It also naturally takes care of the TMinuit instance.
79 Revision 1.21 2000/06/27 08:54:41 morsch
80 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
82 Revision 1.20 2000/06/26 14:02:38 morsch
83 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
85 Revision 1.19 2000/06/22 13:40:51 morsch
86 scope problem on HP, "i" declared once
87 pow changed to TMath::Power (PH, AM)
89 Revision 1.18 2000/06/15 07:58:48 morsch
90 Code from MUON-dev joined
92 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
93 - add TriggerCircuit (PC)
94 - add GlobalTrigger and LocalTrigger and specific methods (PC)
96 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
97 Most coding rule violations corrected
99 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
100 RULE RN17 violations corrected
102 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
103 Code revised by P. Crochet:
104 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
105 - ToF included in the method MakePadHits
106 - inner radius of flange between beam shielding and trigger corrected
107 - Trigger global volume updated (according to the new geometry)
109 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
110 Some changes of variable names curing viols and methods concerning
111 correlated clusters removed.
113 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
114 Memory leak suppressed in function Digitise:
115 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
117 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
118 Positions of trigger chambers corrected (P.C.)
120 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
121 Call to AddHitList introduced to make this version compatible with head.
123 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
124 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
126 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
127 Trigger included into initialization and digitization
129 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
130 Log messages of previous revisions added
132 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
133 Z position of the chambers:
134 it was the Z position of the stations;
135 it is now really the Z position of the chambers.
136 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
137 !!!! AND "AliMUONChamber::ZPosition"
138 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
139 !!!! AND "AliMUONChamber::Z"
141 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
142 Correction for mis-spelling of NCH
144 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
150 ///////////////////////////////////////////////
151 // Manager and hits classes for set:MUON //
152 ////////////////////////////////////////////////
156 #include <TRotMatrix.h>
157 #include <TGeometry.h>
163 #include <TObjArray.h>
165 #include <TParticle.h>
171 #include <TDirectory.h>
172 #include <TObjectTable.h>
177 #include "AliMUONHit.h"
178 #include "AliMUONPadHit.h"
179 #include "AliMUONDigit.h"
180 #include "AliMUONTransientDigit.h"
181 #include "AliMUONRawCluster.h"
182 #include "AliMUONLocalTrigger.h"
183 #include "AliMUONGlobalTrigger.h"
184 #include "AliMUONTriggerCircuit.h"
185 #include "AliHitMap.h"
186 #include "AliMUONHitMapA1.h"
187 #include "AliMUONChamberTrigger.h"
188 #include "AliMUONConstants.h"
189 #include "AliMUONClusterFinderVS.h"
190 #include "AliMUONTriggerDecision.h"
193 #include "AliMUONClusterInput.h"
194 #include "iostream.h"
195 #include "AliCallf77.h"
196 #include "AliConst.h"
198 // Defaults parameters for Z positions of chambers
199 // taken from values for "stations" in AliMUON::AliMUON
200 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
201 // and from array "dstation" in AliMUONv1::CreateGeometry
202 // Float_t dstation[5]={20., 20., 20, 20., 20.};
203 // for tracking chambers,
204 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
205 // for the first and second chambers in the station, respectively,
206 // and from "DTPLANES" in AliMUONv1::CreateGeometry
207 // const Float_t DTPLANES = 15.;
208 // for trigger chambers,
209 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
210 // for the first and second chambers in the station, respectively
213 //___________________________________________
221 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
234 //___________________________________________
235 AliMUON::AliMUON(const char *name, const char *title)
236 : AliDetector(name,title)
240 <img src="gif/alimuon.gif">
244 fHits = new TClonesArray("AliMUONHit",1000);
245 gAlice->AddHitList(fHits);
246 fPadHits = new TClonesArray("AliMUONPadHit",10000);
250 fNdch = new Int_t[AliMUONConstants::NCh()];
252 fDchambers = new TObjArray(AliMUONConstants::NCh());
256 for (i=0; i<AliMUONConstants::NCh() ;i++) {
257 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
261 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
263 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
265 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
266 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
270 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
272 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
275 SetMarkerColor(kRed);
283 fChambers = new TObjArray(AliMUONConstants::NCh());
285 // Loop over stations
286 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
287 // Loop over 2 chambers in the station
288 for (Int_t stCH = 0; stCH < 2; stCH++) {
291 // Default Parameters for Muon Tracking Stations
296 if (ch < AliMUONConstants::NTrackingCh()) {
297 (*fChambers)[ch] = new AliMUONChamber(ch);
299 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
302 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
305 // Default values for Z of chambers
306 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
308 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
309 // Set chamber inner and outer radius to default
310 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
311 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
313 } // Chamber stCH (0, 1) in
314 } // Station st (0...)
327 // cp new design of AliMUONTriggerDecision
328 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
329 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
330 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
332 // cp new design of AliMUONTriggerDecision
336 //___________________________________________
337 AliMUON::AliMUON(const AliMUON& rMUON)
339 // Dummy copy constructor
346 printf("Calling AliMUON destructor !!!\n");
353 delete fGlobalTrigger;
356 delete fLocalTrigger;
359 for (i=0;i<AliMUONConstants::NCh();i++) {
360 delete (*fDchambers)[i];
365 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
366 delete (*fRawClusters)[i];
371 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
372 delete (*fTriggerCircuits)[circ];
374 delete fTriggerCircuits;
377 //___________________________________________
378 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
380 TClonesArray &lhits = *fHits;
381 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
383 //___________________________________________
384 void AliMUON::AddPadHit(Int_t *clhits)
386 TClonesArray &lclusters = *fPadHits;
387 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
389 //_____________________________________________________________________________
390 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
393 // Add a MUON digit to the list
396 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
397 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
400 //_____________________________________________________________________________
401 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
404 // Add a MUON digit to the list
407 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
408 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
411 //___________________________________________
412 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
414 Int_t *pairUnlike, Int_t *pairLike)
416 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
417 TClonesArray &globalTrigger = *fGlobalTrigger;
418 new(globalTrigger[fNGlobalTrigger++])
419 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
422 //___________________________________________
423 void AliMUON::AddLocalTrigger(Int_t *localtr)
425 // add a MUON Local Trigger to the list
426 TClonesArray &localTrigger = *fLocalTrigger;
427 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
430 //___________________________________________
431 void AliMUON::BuildGeometry()
433 TNode *node, *nodeF, *top, *nodeS;
434 const int kColorMUON = kBlue;
435 const int kColorMUON2 = kYellow;
436 const int kColorMUON3 = kBlue;
438 top=gAlice->GetGeometry()->GetNode("alice");
441 // z-Positions of Chambers
442 const Float_t kCz[7]={511., 686., 971., 1245., 1445., 1600, 1700.};
443 // inner diameter (Xlenght for trigger chamber -> active area)
444 const Float_t kDmin[7]={ 35., 47., 67., 86., 100., 544., 544.};
445 // outer diameter (Ylenght for trigger chamber -> active area)
446 const Float_t kDmax[7]={183., 245., 346., 520., 520., 612., 612.};
448 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
449 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
450 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
451 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
453 Float_t rmin, rmax, dx, dy, dz, dr, xpos, ypos, zpos;
454 Float_t dzc1=4.; // tracking chambers
455 Float_t dzc2=15.; // trigger chambers
456 Float_t hole=102.; // x-y hole around beam pipe for trig. chambers
457 Float_t zscale; // scaling parameter trigger chambers
458 Float_t halfx, halfy;
459 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
460 char nameSense1[9], nameSense2[9];
461 for (Int_t i=0; i<7; i++) {
462 for (Int_t j=0; j<2; j++) {
464 if (i<5) { // tracking chambers
477 sprintf(nameChamber,"C_MUON%d",id);
478 sprintf(nameSense,"S_MUON%d",id);
479 sprintf(nameSense1,"S1_MUON%d",id);
480 sprintf(nameSense2,"S2_MUON%d",id);
481 sprintf(nameFrame,"F_MUON%d",id);
482 if (i<2) { // tracking chambers
483 rmin = kDmin[i]/2.-3;
484 rmax = kDmax[i]/2.+3;
485 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
488 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
492 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
494 sprintf(nameNode,"MUON%d",100+id);
495 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,zpos,"");
496 node->SetLineColor(kColorMUON);
499 sprintf(nameNode,"MUON%d",200+id);
500 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
501 node->SetLineColor(kColorMUON);
504 sprintf(nameNode,"MUON%d",300+id);
505 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
506 nodeF->SetLineColor(kColorMUON);
508 sprintf(nameNode,"MUON%d",400+id);
509 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
510 nodeF->SetLineColor(kColorMUON);
512 sprintf(nameNode,"MUON%d",500+id);
513 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
514 nodeF->SetLineColor(kColorMUON);
516 sprintf(nameNode,"MUON%d",600+id);
517 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
518 nodeF->SetLineColor(kColorMUON);
519 } else if (i >= 2 || i <= 4) {
521 Int_t npcb[7]={0, 0, 0, 0, 0, 0, 0};
524 npcb[0] = 3; npcb[1] = 4; npcb[2] = 3; npcb[3] = 2;
527 npcb[0] = 4; npcb[1] = 5; npcb[2] = 5; npcb[3] = 4;
528 npcb[4] = 3; npcb[5] = 2;
531 npcb[0] = 7; npcb[1] = 7; npcb[2] = 6; npcb[3] = 6;
532 npcb[4] = 5; npcb[5] = 4; npcb[6] = 2;
538 Float_t ypos1=-0.75+20.;
539 Float_t ypos2= 0.75-20.;
544 new TBRIK(nameChamber,"Mother","void",340,340,5.);
546 sprintf(nameNode,"MUON%d",100+id);
547 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
548 node->SetLineColor(kBlack);
553 for (Int_t j=0; j<nslats; j++)
555 sprintf(nameSlat,"SLAT%d",100*id+j);
556 new TBRIK(nameSlat,"Slat Module","void",20.*npcb[j],20.,0.25);
560 if (j==0 && i!=2) xpos+=37.5;
561 if (j==0 && i==2) xpos+=40;
563 color = TMath::Even(j) ? kColorMUON2 : kColorMUON3;
565 sprintf(nameNode,"SLAT%d",100*id+j);
567 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos1,0,"");
568 nodeSlat->SetLineColor(color);
571 sprintf(nameNode,"SLAT%d",100*id+j+7);
573 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos1,0,"");
574 nodeSlat->SetLineColor(color);
576 if (i==2 || (i!=2 && j!=0)) {
579 color = TMath::Even(j) ? kColorMUON3 : kColorMUON2;
581 color = TMath::Even(j) ? kColorMUON2 : kColorMUON3;
585 sprintf(nameNode,"SLAT%d",100*id+j+14);
587 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos2,0,"");
588 nodeSlat->SetLineColor(color);
591 sprintf(nameNode,"SLAT%d",100*id+j+21);
593 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos2,0,"");
594 nodeSlat->SetLineColor(color);
603 Float_t xsize=kDmin[i]*zscale;
604 Float_t ysize=kDmax[i]*zscale;
605 Float_t holeScaled=hole*zscale;
609 new TBRIK(nameChamber,"Mother","void",halfx,halfy,0.25);
611 sprintf(nameNode,"MUON%d",100+id);
612 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
613 node->SetLineColor(kColorMUON2);
616 // up/down of beam pipe
618 halfy=(ysize/2.-holeScaled/2.)/2.;
619 new TBRIK(nameSense,"Sens. region","void",halfx,halfy,0.25);
622 ypos=holeScaled/2.+((ysize/2.-holeScaled/2.)/2.);
623 sprintf(nameNode,"MUON%d",200+id);
624 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
625 nodeS->SetLineColor(kColorMUON2);
629 sprintf(nameNode,"MUON%d",300+id);
630 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
631 nodeS->SetLineColor(kColorMUON2);
633 // left/right of beam pipe
634 halfx=(xsize/2.-holeScaled/2.)/2.;
636 new TBRIK(nameSense1,"Sens. region","void",halfx,halfy,0.25);
639 xpos=holeScaled/2.+((xsize/2.-holeScaled/2.)/2.);
640 sprintf(nameNode,"MUON%d",400+id);
641 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
642 nodeS->SetLineColor(kColorMUON2);
646 sprintf(nameNode,"MUON%d",500+id);
647 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
648 nodeS->SetLineColor(kColorMUON2);
653 new TBRIK(nameSense2,"Sens. region","void",halfx,halfy,0.25);
656 xpos=holeScaled/2.-halfx;
658 sprintf(nameNode,"MUON%d",600+id);
659 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
660 nodeS->SetLineColor(kColorMUON2);
664 sprintf(nameNode,"MUON%d",700+id);
665 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
666 nodeS->SetLineColor(kColorMUON2);
670 sprintf(nameNode,"MUON%d",800+id);
671 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
672 nodeS->SetLineColor(kColorMUON2);
676 sprintf(nameNode,"MUON%d",900+id);
677 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
678 nodeS->SetLineColor(kColorMUON2);
685 //___________________________________________
686 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
691 //___________________________________________
692 void AliMUON::MakeBranch(Option_t* option)
694 // Create Tree branches for the MUON.
695 const Int_t kBufferSize = 4000;
697 sprintf(branchname,"%sCluster",GetName());
699 AliDetector::MakeBranch(option);
701 if (fPadHits && gAlice->TreeH()) {
702 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
703 printf("Making Branch %s for clusters\n",branchname);
706 // one branch for digits per chamber
709 for (i=0; i<AliMUONConstants::NCh() ;i++) {
710 sprintf(branchname,"%sDigits%d",GetName(),i+1);
712 if (fDchambers && gAlice->TreeD()) {
713 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
714 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
718 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
720 // one branch for raw clusters per chamber
721 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
722 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
724 if (fRawClusters && gAlice->TreeR()) {
725 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
726 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
730 // one branch for global trigger
731 sprintf(branchname,"%sGlobalTrigger",GetName());
732 if (fGlobalTrigger && gAlice->TreeR()) {
733 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
734 printf("Making Branch %s for Global Trigger\n",branchname);
736 // one branch for local trigger
737 sprintf(branchname,"%sLocalTrigger",GetName());
738 if (fLocalTrigger && gAlice->TreeR()) {
739 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
740 printf("Making Branch %s for Local Trigger\n",branchname);
745 //___________________________________________
746 void AliMUON::SetTreeAddress()
748 // Set branch address for the Hits and Digits Tree.
750 AliDetector::SetTreeAddress();
753 TTree *treeH = gAlice->TreeH();
754 TTree *treeD = gAlice->TreeD();
755 TTree *treeR = gAlice->TreeR();
759 branch = treeH->GetBranch("MUONCluster");
760 if (branch) branch->SetAddress(&fPadHits);
765 for (int i=0; i<AliMUONConstants::NCh(); i++) {
766 sprintf(branchname,"%sDigits%d",GetName(),i+1);
768 branch = treeD->GetBranch(branchname);
769 if (branch) branch->SetAddress(&((*fDchambers)[i]));
774 // printf("SetTreeAddress --- treeR address %p \n",treeR);
777 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
778 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
780 branch = treeR->GetBranch(branchname);
781 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
786 branch = treeR->GetBranch("MUONLocalTrigger");
787 if (branch) branch->SetAddress(&fLocalTrigger);
789 if (fGlobalTrigger) {
790 branch = treeR->GetBranch("MUONGlobalTrigger");
791 if (branch) branch->SetAddress(&fGlobalTrigger);
795 //___________________________________________
796 void AliMUON::ResetHits()
798 // Reset number of clusters and the cluster array for this detector
799 AliDetector::ResetHits();
801 if (fPadHits) fPadHits->Clear();
804 //____________________________________________
805 void AliMUON::ResetDigits()
808 // Reset number of digits and the digits array for this detector
810 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
811 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
812 if (fNdch) fNdch[i]=0;
815 //____________________________________________
816 void AliMUON::ResetRawClusters()
819 // Reset number of raw clusters and the raw clust array for this detector
821 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
822 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
823 if (fNrawch) fNrawch[i]=0;
827 //____________________________________________
828 void AliMUON::ResetTrigger()
830 // Reset Local and Global Trigger
832 if (fGlobalTrigger) fGlobalTrigger->Clear();
834 if (fLocalTrigger) fLocalTrigger->Clear();
837 //____________________________________________
838 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
841 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
842 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
845 //___________________________________________
846 void AliMUON::SetChambersZ(const Float_t *Z)
848 // Set Z values for all chambers (tracking and trigger)
849 // from the array pointed to by "Z"
850 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
851 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
855 //___________________________________________
856 void AliMUON::SetChambersZToDefault()
858 // Set Z values for all chambers (tracking and trigger)
860 SetChambersZ(AliMUONConstants::DefaultChamberZ());
864 //___________________________________________
865 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
868 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
869 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
872 //___________________________________________
873 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
876 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
877 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
880 //___________________________________________
881 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
884 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
885 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
888 //___________________________________________
889 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
892 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
893 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
896 //___________________________________________
897 void AliMUON::SetMaxStepGas(Float_t p1)
902 //___________________________________________
903 void AliMUON::SetMaxStepAlu(Float_t p1)
908 //___________________________________________
909 void AliMUON::SetMaxDestepGas(Float_t p1)
914 //___________________________________________
915 void AliMUON::SetMaxDestepAlu(Float_t p1)
919 //___________________________________________
920 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
923 fAccMin=angmin*TMath::Pi()/180;
924 fAccMax=angmax*TMath::Pi()/180;
927 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
928 // Loop over 2 chambers in the station
929 for (Int_t stCH = 0; stCH < 2; stCH++) {
931 // Set chamber inner and outer radius according to acceptance cuts
932 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
933 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
938 //___________________________________________
939 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
941 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
944 //___________________________________________
945 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
947 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
950 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
952 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
955 void AliMUON::SetNsec(Int_t id, Int_t nsec)
957 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
961 //___________________________________________
965 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
966 Float_t eloss, Float_t tof, Int_t idvol)
969 // Calls the charge disintegration method of the current chamber and adds
970 // the simulated cluster to the root treee
973 Float_t newclust[6][500];
978 // Integrated pulse height on chamber
984 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
987 ((AliMUONChamber*) (*fChambers)[idvol])
988 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
990 // if (idvol == 6) printf("\n nnew %d \n", nnew);
993 for (Int_t i=0; i<nnew; i++) {
994 if (Int_t(newclust[3][i]) > 0) {
997 clhits[1] = Int_t(newclust[5][i]);
999 clhits[2] = Int_t(newclust[0][i]);
1001 clhits[3] = Int_t(newclust[1][i]);
1003 clhits[4] = Int_t(newclust[2][i]);
1005 clhits[5] = Int_t(newclust[3][i]);
1006 // Pad: chamber sector
1007 clhits[6] = Int_t(newclust[4][i]);
1014 //----------------------------------------------------------------------
1016 void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
1018 // keep galice.root for signal and name differently the file for
1019 // background when add! otherwise the track info for signal will be lost !
1021 static Bool_t first=kTRUE;
1023 char *addBackground = strstr(option,"Add");
1026 AliMUONChamber* iChamber;
1027 AliSegmentation* segmentation;
1032 TObjArray *list=new TObjArray;
1033 static TClonesArray *pAddress=0;
1034 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
1037 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
1038 AliHitMap** hitMap= new AliHitMap* [AliMUONConstants::NCh()];
1039 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
1040 if (addBackground ) {
1043 cout<<"filename"<<fFileName<<endl;
1044 file=new TFile(fFileName);
1045 cout<<"I have opened "<<fFileName<<" file "<<endl;
1046 fHits2 = new TClonesArray("AliMUONHit",1000 );
1047 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
1052 // Get Hits Tree header from file
1053 if(fHits2) fHits2->Clear();
1054 if(fPadHits2) fPadHits2->Clear();
1055 if(fTrH1) delete fTrH1;
1059 sprintf(treeName,"TreeH%d",bgrEvent);
1060 fTrH1 = (TTree*)gDirectory->Get(treeName);
1061 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
1064 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
1066 // Set branch addresses
1068 char branchname[20];
1069 sprintf(branchname,"%s",GetName());
1070 if (fTrH1 && fHits2) {
1071 branch = fTrH1->GetBranch(branchname);
1072 if (branch) branch->SetAddress(&fHits2);
1074 if (fTrH1 && fPadHits2) {
1075 branch = fTrH1->GetBranch("MUONCluster");
1076 if (branch) branch->SetAddress(&fPadHits2);
1079 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
1080 //printf("background - ntracks1 - %d\n",ntracks1);
1083 // loop over cathodes
1087 for (int icat=0; icat<2; icat++) {
1089 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
1090 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
1091 iChamber=(AliMUONChamber*) (*fChambers)[i];
1092 if (iChamber->Nsec()==1 && icat==1) {
1095 segmentation=iChamber->SegmentationModel(icat+1);
1097 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
1100 //printf("Start loop over tracks \n");
1105 TTree *treeH = gAlice->TreeH();
1106 Int_t ntracks =(Int_t) treeH->GetEntries();
1109 Float_t ** xhit = new Float_t * [AliMUONConstants::NCh()];
1110 for (jj=0; jj<AliMUONConstants::NCh(); jj++) xhit[jj] = new Float_t[2];
1111 Float_t ** yhit = new Float_t * [AliMUONConstants::NCh()];
1112 for (jj=0; jj<AliMUONConstants::NCh(); jj++) yhit[jj] = new Float_t[2];
1114 for (Int_t track=0; track<ntracks; track++) {
1115 gAlice->ResetHits();
1116 treeH->GetEvent(track);
1119 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
1121 mHit=(AliMUONHit*)pMUON->NextHit())
1123 Int_t nch = mHit->fChamber-1; // chamber number
1124 if (nch > AliMUONConstants::NCh()-1) continue;
1125 // if (nch > 9) continue;
1126 iChamber = &(pMUON->Chamber(nch));
1128 if (addBackground) {
1130 if (mHit->fParticle == kMuonPlus
1131 || mHit->fParticle == kMuonMinus) {
1132 xhit[nch][nmuon[nch]]=mHit->X();
1133 yhit[nch][nmuon[nch]]=mHit->Y();
1135 if (nmuon[nch] >2) printf("nmuon %d\n",nmuon[nch]);
1143 // Loop over pad hits
1144 for (AliMUONPadHit* mPad=
1145 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
1147 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
1149 Int_t cathode = mPad->fCathode; // cathode number
1150 Int_t ipx = mPad->fPadX; // pad number on X
1151 Int_t ipy = mPad->fPadY; // pad number on Y
1152 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1153 // printf("\n Pad: %d %d %d %d", ipx, ipy, cathode,nch);
1157 if (cathode != (icat+1)) continue;
1158 // fill the info array
1159 // Float_t thex, they, thez;
1160 segmentation=iChamber->SegmentationModel(cathode);
1161 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1162 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1163 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1165 new((*pAddress)[countadr++]) TVector(2);
1166 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1167 trinfo(0)=(Float_t)track;
1168 trinfo(1)=(Float_t)iqpad;
1174 if (mHit->fParticle == kMuonPlus ||
1175 mHit->fParticle == kMuonMinus) {
1176 digits[4]=mPad->fHitNumber;
1177 } else digits[4]=-1;
1179 AliMUONTransientDigit* pdigit;
1180 // build the list of fired pads and update the info
1181 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1183 list->AddAtAndExpand(
1184 new AliMUONTransientDigit(nch,digits),counter);
1186 hitMap[nch]->SetHit(ipx, ipy, counter);
1188 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1190 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1191 trlist->Add(&trinfo);
1193 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1195 (*pdigit).fSignal+=iqpad;
1196 (*pdigit).fPhysics+=iqpad;
1197 // update list of tracks
1198 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
1199 Int_t lastEntry=trlist->GetLast();
1200 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1201 TVector &ptrk=*pTrack;
1202 Int_t lastTrack = Int_t(ptrk(0));
1203 Int_t lastCharge = Int_t(ptrk(1));
1204 if (lastTrack==track) {
1206 trlist->RemoveAt(lastEntry);
1207 trinfo(0)=lastTrack;
1208 trinfo(1)=lastCharge;
1209 trlist->AddAt(&trinfo,lastEntry);
1211 trlist->Add(&trinfo);
1213 // check the track list
1214 Int_t nptracks=trlist->GetEntriesFast();
1216 for (Int_t tr=0;tr<nptracks;tr++) {
1217 TVector *ppTrack=(TVector*)trlist->At(tr);
1218 TVector &pptrk=*ppTrack;
1219 trk[tr] = Int_t(pptrk(0));
1220 chtrk[tr] = Int_t(pptrk(1));
1222 } // end if nptracks
1224 } //end loop over clusters
1228 // open the file with background
1230 if (addBackground) {
1231 ntracks =(Int_t)fTrH1->GetEntries();
1235 for (Int_t track=0; track<ntracks; track++) {
1237 if (fHits2) fHits2->Clear();
1238 if (fPadHits2) fPadHits2->Clear();
1240 fTrH1->GetEvent(track);
1244 for(int i=0;i<fHits2->GetEntriesFast();++i)
1246 mHit=(AliMUONHit*) (*fHits2)[i];
1247 Int_t nch = mHit->fChamber-1; // chamber number
1248 if (nch >9) continue;
1249 iChamber = &(pMUON->Chamber(nch));
1250 // Int_t rmin = (Int_t)iChamber->RInner();
1251 // Int_t rmax = (Int_t)iChamber->ROuter();
1252 Float_t xbgr=mHit->X();
1253 Float_t ybgr=mHit->Y();
1256 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1257 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1258 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
1259 if (dist<100) cond=kTRUE;
1261 if (!cond) continue;
1264 // Loop over pad hits
1265 for (AliMUONPadHit* mPad=
1266 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
1268 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
1270 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
1271 Int_t cathode = mPad->fCathode; // cathode number
1272 Int_t ipx = mPad->fPadX; // pad number on X
1273 Int_t ipy = mPad->fPadY; // pad number on Y
1274 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1276 if (cathode != (icat+1)) continue;
1277 printf("\n Pad: %d %d %d", ipx, ipy, cathode);
1279 // Float_t thex, they, thez;
1280 // segmentation=iChamber->SegmentationModel(cathode);
1281 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1282 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1283 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1284 new((*pAddress)[countadr++]) TVector(2);
1285 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1286 trinfo(0)=-1; // tag background
1295 AliMUONTransientDigit* pdigit;
1296 // build the list of fired pads and update the info
1297 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1298 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1300 hitMap[nch]->SetHit(ipx, ipy, counter);
1303 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1305 TObjArray *trlist=(TObjArray*)pdigit->
1307 trlist->Add(&trinfo);
1309 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1311 (*pdigit).fSignal+=iqpad;
1313 // update list of tracks
1314 TObjArray* trlist=(TObjArray*)pdigit->
1316 Int_t lastEntry=trlist->GetLast();
1317 TVector *pTrack=(TVector*)trlist->
1319 TVector &ptrk=*pTrack;
1320 Int_t lastTrack=Int_t(ptrk(0));
1321 if (lastTrack==-1) {
1324 trlist->Add(&trinfo);
1326 // check the track list
1327 Int_t nptracks=trlist->GetEntriesFast();
1329 for (Int_t tr=0;tr<nptracks;tr++) {
1330 TVector *ppTrack=(TVector*)trlist->At(tr);
1331 TVector &pptrk=*ppTrack;
1332 trk[tr]=Int_t(pptrk(0));
1333 chtrk[tr]=Int_t(pptrk(1));
1335 } // end if nptracks
1337 } //end loop over clusters
1340 //Int_t nentr2=list->GetEntriesFast();
1341 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1342 TTree *fAli=gAlice->TreeK();
1345 if (fAli) file =fAli->GetCurrentFile();
1347 } // if addBackground
1353 Int_t nentries=list->GetEntriesFast();
1355 for (Int_t nent=0;nent<nentries;nent++) {
1356 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
1357 if (address==0) continue;
1358 Int_t ich=address->fChamber;
1359 Int_t q=address->fSignal;
1360 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1362 // Digit Response (noise, threshold, saturation, ...)
1363 // if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1364 AliMUONResponse * response=iChamber->ResponseModel();
1365 q=response->DigitResponse(q);
1369 digits[0]=address->fPadX;
1370 digits[1]=address->fPadY;
1372 digits[3]=address->fPhysics;
1373 digits[4]=address->fHit;
1375 TObjArray* trlist=(TObjArray*)address->TrackList();
1376 Int_t nptracks=trlist->GetEntriesFast();
1377 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1379 // this was changed to accomodate the real number of tracks
1380 if (nptracks > 10) {
1381 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1385 printf("Attention - nptracks > 2 %d \n",nptracks);
1386 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1388 for (Int_t tr=0;tr<nptracks;tr++) {
1389 TVector *ppP=(TVector*)trlist->At(tr);
1390 if(!ppP ) printf("ppP - %p\n",ppP);
1392 tracks[tr]=Int_t(pp(0));
1393 charges[tr]=Int_t(pp(1));
1394 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
1395 } //end loop over list of tracks for one pad
1396 // Sort list of tracks according to charge
1398 SortTracks(tracks,charges,nptracks);
1400 if (nptracks < 10 ) {
1401 for (Int_t i=nptracks; i<10; i++) {
1408 pMUON->AddDigits(ich,tracks,charges,digits);
1411 //cout<<"I'm out of the loops for digitisation"<<endl;
1412 // gAlice->GetEvent(nev);
1413 gAlice->TreeD()->Fill();
1414 pMUON->ResetDigits();
1418 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
1426 } //end loop over cathodes
1429 sprintf(hname,"TreeD%d",nev);
1430 gAlice->TreeD()->Write(hname);
1432 gAlice->TreeD()->Reset();
1436 // gObjectTable->Print();
1439 void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1442 // Sort the list of tracks contributing to a given digit
1443 // Only the 3 most significant tracks are acctually sorted
1447 // Loop over signals, only 3 times
1452 Int_t idx[3] = {-2,-2,-2};
1453 Int_t jch[3] = {-2,-2,-2};
1454 Int_t jtr[3] = {-2,-2,-2};
1457 if (ntr<3) imax=ntr;
1459 for(i=0;i<imax;i++){
1465 if((i == 1 && j == idx[i-1])
1466 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1468 if(charges[j] > qmax) {
1476 jch[i]=charges[jmax];
1477 jtr[i]=tracks[jmax];
1494 //___________________________________________
1495 void AliMUON::Trigger(Int_t nev){
1496 // call the Trigger Algorithm and fill TreeR
1498 Int_t singlePlus[3] = {0,0,0};
1499 Int_t singleMinus[3] = {0,0,0};
1500 Int_t singleUndef[3] = {0,0,0};
1501 Int_t pairUnlike[3] = {0,0,0};
1502 Int_t pairLike[3] = {0,0,0};
1505 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1506 decision->Trigger();
1507 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1508 pairUnlike, pairLike);
1509 // add a local trigger in the list
1510 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
1513 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
1514 if(decision->GetITrigger(icirc)==1) {
1515 Int_t localtr[7]={0,0,0,0,0,0,0};
1516 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1517 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1519 localtr[1] = decision->GetStripX11(icirc);
1520 localtr[2] = decision->GetDev(icirc);
1521 localtr[3] = decision->GetStripY11(icirc);
1522 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1523 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1524 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1525 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1527 AddLocalTrigger(localtr); // add a local trigger in the list
1532 gAlice->TreeR()->Fill();
1535 sprintf(hname,"TreeR%d",nev);
1536 gAlice->TreeR()->Write(hname);
1537 gAlice->TreeR()->Reset();
1538 printf("\n End of trigger for event %d", nev);
1542 //____________________________________________
1543 void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1545 TClonesArray *dig1, *dig2;
1547 dig1 = new TClonesArray("AliMUONDigit",1000);
1548 dig2 = new TClonesArray("AliMUONDigit",1000);
1549 AliMUONDigit *digit;
1551 // Loop on chambers and on cathode planes
1554 for (Int_t ich=0;ich<10;ich++) {
1555 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1556 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1557 gAlice->ResetDigits();
1558 gAlice->TreeD()->GetEvent(lastEntry);
1559 TClonesArray *muonDigits = this->DigitsAddress(ich);
1560 ndig=muonDigits->GetEntriesFast();
1561 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1562 TClonesArray &lhits1 = *dig1;
1564 for (k=0; k<ndig; k++) {
1565 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1566 if (rec->TestTrack(digit->fTracks[0]))
1567 new(lhits1[n++]) AliMUONDigit(*digit);
1569 gAlice->ResetDigits();
1570 gAlice->TreeD()->GetEvent(lastEntry+1);
1571 muonDigits = this->DigitsAddress(ich);
1572 ndig=muonDigits->GetEntriesFast();
1573 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1574 TClonesArray &lhits2 = *dig2;
1577 for (k=0; k<ndig; k++) {
1578 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1579 if (rec->TestTrack(digit->fTracks[0]))
1580 new(lhits2[n++]) AliMUONDigit(*digit);
1584 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1585 rec->FindRawClusters();
1590 gAlice->TreeR()->Fill();
1593 sprintf(hname,"TreeR%d",nev);
1594 gAlice->TreeR()->Write(hname);
1595 gAlice->TreeR()->Reset();
1596 printf("\n End of cluster finding for event %d", nev);
1600 //gObjectTable->Print();
1604 void AliMUON::Streamer(TBuffer &R__b)
1606 // Stream an object of class AliMUON.
1607 AliMUONChamber *iChamber;
1608 AliMUONTriggerCircuit *iTriggerCircuit;
1609 AliSegmentation *segmentation;
1610 AliMUONResponse *response;
1611 TClonesArray *digitsaddress;
1612 TClonesArray *rawcladdress;
1614 if (R__b.IsReading()) {
1615 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1616 AliDetector::Streamer(R__b);
1618 R__b >> fPadHits; // diff
1619 R__b >> fNLocalTrigger;
1620 R__b >> fLocalTrigger;
1621 R__b >> fNGlobalTrigger;
1622 R__b >> fGlobalTrigger;
1624 R__b >> fRawClusters;
1625 R__b.ReadArray(fNdch);
1626 R__b.ReadArray(fNrawch);
1631 R__b >> fTriggerCircuits;
1632 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1633 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1634 iTriggerCircuit->Streamer(R__b);
1636 // Stream chamber related information
1637 for (i =0; i<AliMUONConstants::NCh(); i++) {
1638 iChamber=(AliMUONChamber*) (*fChambers)[i];
1639 iChamber->Streamer(R__b);
1640 if (iChamber->Nsec()==1) {
1641 segmentation=iChamber->SegmentationModel(1);
1643 segmentation->Streamer(R__b);
1645 segmentation=iChamber->SegmentationModel(1);
1647 segmentation->Streamer(R__b);
1649 segmentation=iChamber->SegmentationModel(2);
1650 segmentation->Streamer(R__b);
1652 response=iChamber->ResponseModel();
1654 response->Streamer(R__b);
1655 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1656 digitsaddress->Streamer(R__b);
1657 if (i < AliMUONConstants::NTrackingCh()) {
1658 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1659 rawcladdress->Streamer(R__b);
1664 R__b.WriteVersion(AliMUON::IsA());
1665 AliDetector::Streamer(R__b);
1667 R__b << fPadHits; // diff
1668 R__b << fNLocalTrigger;
1669 R__b << fLocalTrigger;
1670 R__b << fNGlobalTrigger;
1671 R__b << fGlobalTrigger;
1673 R__b << fRawClusters;
1674 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1675 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1682 R__b << fTriggerCircuits;
1683 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1684 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1685 iTriggerCircuit->Streamer(R__b);
1687 for (i =0; i<AliMUONConstants::NCh(); i++) {
1688 iChamber=(AliMUONChamber*) (*fChambers)[i];
1689 iChamber->Streamer(R__b);
1690 if (iChamber->Nsec()==1) {
1691 segmentation=iChamber->SegmentationModel(1);
1693 segmentation->Streamer(R__b);
1695 segmentation=iChamber->SegmentationModel(1);
1697 segmentation->Streamer(R__b);
1698 segmentation=iChamber->SegmentationModel(2);
1700 segmentation->Streamer(R__b);
1702 response=iChamber->ResponseModel();
1704 response->Streamer(R__b);
1705 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1706 digitsaddress->Streamer(R__b);
1707 if (i < AliMUONConstants::NTrackingCh()) {
1708 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1709 rawcladdress->Streamer(R__b);
1714 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1717 // Initialise the pad iterator
1718 // Return the address of the first padhit for hit
1719 TClonesArray *theClusters = clusters;
1720 Int_t nclust = theClusters->GetEntriesFast();
1721 if (nclust && hit->fPHlast > 0) {
1722 AliMUON::fMaxIterPad=hit->fPHlast;
1723 AliMUON::fCurIterPad=hit->fPHfirst;
1724 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1730 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1732 AliMUON::fCurIterPad++;
1733 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1734 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1741 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1743 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1745 TTree *treeR = gAlice->TreeR();
1746 Int_t nent=(Int_t)treeR->GetEntries();
1747 treeR->GetEvent(nent-2+icathod-1);
1748 //treeR->GetEvent(icathod);
1749 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1751 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1752 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1757 AliMUON& AliMUON::operator = (const AliMUON& rhs)