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.36 2000/10/25 19:51:18 morsch
18 Correct x-position of chambers.
20 Revision 1.35 2000/10/24 19:46:21 morsch
21 BuildGeometry updated for slats in station 3-4.
23 Revision 1.34 2000/10/18 11:42:06 morsch
24 - AliMUONRawCluster contains z-position.
25 - Some clean-up of useless print statements during initialisations.
27 Revision 1.33 2000/10/09 14:01:57 morsch
28 Unused variables removed.
30 Revision 1.32 2000/10/06 09:08:10 morsch
31 Built geometry includes slat geometry for event display.
33 Revision 1.31 2000/10/02 21:28:08 fca
34 Removal of useless dependecies via forward declarations
36 Revision 1.30 2000/10/02 16:58:29 egangler
37 Cleaning of the code :
40 -> some useless includes removed or replaced by "class" statement
42 Revision 1.29 2000/07/28 13:49:38 morsch
43 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
44 Can be used for simple acceptance studies.
46 Revision 1.28 2000/07/22 16:43:15 morsch
47 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
49 Revision 1.27 2000/07/22 16:36:50 morsch
50 Change order of indices in creation (new) of xhit and yhit
52 Revision 1.26 2000/07/03 11:54:57 morsch
53 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
54 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
56 Revision 1.25 2000/06/29 12:34:09 morsch
57 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
58 it usable with any other geometry class. The link to the object to which it belongs is
59 established via an index. This assumes that there exists a global geometry manager
60 from which the pointer to the parent object can be obtained (in our case gAlice).
62 Revision 1.24 2000/06/28 15:16:35 morsch
63 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
64 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
65 framework. The changes should have no side effects (mostly dummy arguments).
66 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
67 of chambers with overlapping modules (MakePadHits, Disintegration).
69 Revision 1.23 2000/06/28 12:19:17 morsch
70 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
71 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
72 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
73 It requires two cathode planes. Small modifications in the code will make it usable for
74 one cathode plane and, hence, more general (for test beam data).
75 AliMUONClusterFinder is now obsolete.
77 Revision 1.22 2000/06/28 08:06:10 morsch
78 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
79 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
80 It also naturally takes care of the TMinuit instance.
82 Revision 1.21 2000/06/27 08:54:41 morsch
83 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
85 Revision 1.20 2000/06/26 14:02:38 morsch
86 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
88 Revision 1.19 2000/06/22 13:40:51 morsch
89 scope problem on HP, "i" declared once
90 pow changed to TMath::Power (PH, AM)
92 Revision 1.18 2000/06/15 07:58:48 morsch
93 Code from MUON-dev joined
95 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
96 - add TriggerCircuit (PC)
97 - add GlobalTrigger and LocalTrigger and specific methods (PC)
99 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
100 Most coding rule violations corrected
102 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
103 RULE RN17 violations corrected
105 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
106 Code revised by P. Crochet:
107 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
108 - ToF included in the method MakePadHits
109 - inner radius of flange between beam shielding and trigger corrected
110 - Trigger global volume updated (according to the new geometry)
112 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
113 Some changes of variable names curing viols and methods concerning
114 correlated clusters removed.
116 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
117 Memory leak suppressed in function Digitise:
118 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
120 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
121 Positions of trigger chambers corrected (P.C.)
123 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
124 Call to AddHitList introduced to make this version compatible with head.
126 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
127 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
129 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
130 Trigger included into initialization and digitization
132 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
133 Log messages of previous revisions added
135 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
136 Z position of the chambers:
137 it was the Z position of the stations;
138 it is now really the Z position of the chambers.
139 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
140 !!!! AND "AliMUONChamber::ZPosition"
141 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
142 !!!! AND "AliMUONChamber::Z"
144 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
145 Correction for mis-spelling of NCH
147 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
153 ///////////////////////////////////////////////
154 // Manager and hits classes for set:MUON //
155 ////////////////////////////////////////////////
159 #include <TRotMatrix.h>
160 #include <TGeometry.h>
166 #include <TObjArray.h>
168 #include <TParticle.h>
174 #include <TDirectory.h>
175 #include <TObjectTable.h>
180 #include "AliMUONHit.h"
181 #include "AliMUONPadHit.h"
182 #include "AliMUONDigit.h"
183 #include "AliMUONTransientDigit.h"
184 #include "AliMUONRawCluster.h"
185 #include "AliMUONLocalTrigger.h"
186 #include "AliMUONGlobalTrigger.h"
187 #include "AliMUONTriggerCircuit.h"
188 #include "AliHitMap.h"
189 #include "AliMUONHitMapA1.h"
190 #include "AliMUONChamberTrigger.h"
191 #include "AliMUONConstants.h"
192 #include "AliMUONClusterFinderVS.h"
193 #include "AliMUONTriggerDecision.h"
196 #include "AliMUONClusterInput.h"
197 #include "iostream.h"
198 #include "AliCallf77.h"
199 #include "AliConst.h"
201 // Defaults parameters for Z positions of chambers
202 // taken from values for "stations" in AliMUON::AliMUON
203 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
204 // and from array "dstation" in AliMUONv1::CreateGeometry
205 // Float_t dstation[5]={20., 20., 20, 20., 20.};
206 // for tracking chambers,
207 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
208 // for the first and second chambers in the station, respectively,
209 // and from "DTPLANES" in AliMUONv1::CreateGeometry
210 // const Float_t DTPLANES = 15.;
211 // for trigger chambers,
212 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
213 // for the first and second chambers in the station, respectively
216 //___________________________________________
224 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
237 //___________________________________________
238 AliMUON::AliMUON(const char *name, const char *title)
239 : AliDetector(name,title)
243 <img src="gif/alimuon.gif">
247 fHits = new TClonesArray("AliMUONHit",1000);
248 gAlice->AddHitList(fHits);
249 fPadHits = new TClonesArray("AliMUONPadHit",10000);
253 fNdch = new Int_t[AliMUONConstants::NCh()];
255 fDchambers = new TObjArray(AliMUONConstants::NCh());
259 for (i=0; i<AliMUONConstants::NCh() ;i++) {
260 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
264 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
266 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
268 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
269 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
273 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
275 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
278 SetMarkerColor(kRed);
286 fChambers = new TObjArray(AliMUONConstants::NCh());
288 // Loop over stations
289 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
290 // Loop over 2 chambers in the station
291 for (Int_t stCH = 0; stCH < 2; stCH++) {
294 // Default Parameters for Muon Tracking Stations
299 if (ch < AliMUONConstants::NTrackingCh()) {
300 (*fChambers)[ch] = new AliMUONChamber(ch);
302 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
305 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
308 // Default values for Z of chambers
309 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
311 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
312 // Set chamber inner and outer radius to default
313 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
314 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
316 } // Chamber stCH (0, 1) in
317 } // Station st (0...)
330 // cp new design of AliMUONTriggerDecision
331 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
332 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
333 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
335 // cp new design of AliMUONTriggerDecision
339 //___________________________________________
340 AliMUON::AliMUON(const AliMUON& rMUON)
342 // Dummy copy constructor
349 printf("Calling AliMUON destructor !!!\n");
356 delete fGlobalTrigger;
359 delete fLocalTrigger;
362 for (i=0;i<AliMUONConstants::NCh();i++) {
363 delete (*fDchambers)[i];
368 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
369 delete (*fRawClusters)[i];
374 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
375 delete (*fTriggerCircuits)[circ];
377 delete fTriggerCircuits;
380 //___________________________________________
381 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
383 TClonesArray &lhits = *fHits;
384 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
386 //___________________________________________
387 void AliMUON::AddPadHit(Int_t *clhits)
389 TClonesArray &lclusters = *fPadHits;
390 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
392 //_____________________________________________________________________________
393 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
396 // Add a MUON digit to the list
399 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
400 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
403 //_____________________________________________________________________________
404 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
407 // Add a MUON digit to the list
410 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
411 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
414 //___________________________________________
415 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
417 Int_t *pairUnlike, Int_t *pairLike)
419 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
420 TClonesArray &globalTrigger = *fGlobalTrigger;
421 new(globalTrigger[fNGlobalTrigger++])
422 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
425 //___________________________________________
426 void AliMUON::AddLocalTrigger(Int_t *localtr)
428 // add a MUON Local Trigger to the list
429 TClonesArray &localTrigger = *fLocalTrigger;
430 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
433 //___________________________________________
434 void AliMUON::BuildGeometry()
436 TNode *node, *nodeF, *top, *nodeS;
437 const int kColorMUON = kBlue;
438 const int kColorMUON2 = kYellow;
439 const int kColorMUON3 = kBlue;
441 top=gAlice->GetGeometry()->GetNode("alice");
444 // z-Positions of Chambers
445 const Float_t kCz[7]={511., 686., 971., 1245., 1445., 1600, 1700.};
446 // inner diameter (Xlenght for trigger chamber -> active area)
447 const Float_t kDmin[7]={ 35., 47., 67., 86., 100., 544., 544.};
448 // outer diameter (Ylenght for trigger chamber -> active area)
449 const Float_t kDmax[7]={183., 245., 346., 520., 520., 612., 612.};
451 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
452 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
453 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
454 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
456 Float_t rmin, rmax, dx, dy, dz, dr, xpos, ypos, zpos;
457 Float_t dzc1=4.; // tracking chambers
458 Float_t dzc2=15.; // trigger chambers
459 Float_t hole=102.; // x-y hole around beam pipe for trig. chambers
460 Float_t zscale; // scaling parameter trigger chambers
461 Float_t halfx, halfy;
462 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
463 char nameSense1[9], nameSense2[9];
464 for (Int_t i=0; i<7; i++) {
465 for (Int_t j=0; j<2; j++) {
467 if (i<5) { // tracking chambers
480 sprintf(nameChamber,"C_MUON%d",id);
481 sprintf(nameSense,"S_MUON%d",id);
482 sprintf(nameSense1,"S1_MUON%d",id);
483 sprintf(nameSense2,"S2_MUON%d",id);
484 sprintf(nameFrame,"F_MUON%d",id);
485 if (i<2) { // tracking chambers
486 rmin = kDmin[i]/2.-3;
487 rmax = kDmax[i]/2.+3;
488 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
491 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
495 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
497 sprintf(nameNode,"MUON%d",100+id);
498 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,zpos,"");
499 node->SetLineColor(kColorMUON);
502 sprintf(nameNode,"MUON%d",200+id);
503 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
504 node->SetLineColor(kColorMUON);
507 sprintf(nameNode,"MUON%d",300+id);
508 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
509 nodeF->SetLineColor(kColorMUON);
511 sprintf(nameNode,"MUON%d",400+id);
512 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
513 nodeF->SetLineColor(kColorMUON);
515 sprintf(nameNode,"MUON%d",500+id);
516 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
517 nodeF->SetLineColor(kColorMUON);
519 sprintf(nameNode,"MUON%d",600+id);
520 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
521 nodeF->SetLineColor(kColorMUON);
522 } else if (i >= 2 && i <= 4) {
524 Int_t npcb[7]={0, 0, 0, 0, 0, 0, 0};
527 npcb[0] = 3; npcb[1] = 4; npcb[2] = 3; npcb[3] = 2;
530 npcb[0] = 4; npcb[1] = 5; npcb[2] = 5; npcb[3] = 4;
531 npcb[4] = 3; npcb[5] = 2;
534 npcb[0] = 7; npcb[1] = 7; npcb[2] = 6; npcb[3] = 6;
535 npcb[4] = 5; npcb[5] = 4; npcb[6] = 2;
541 Float_t ypos1=-0.75+20.;
542 Float_t ypos2= 0.75-20.;
547 new TBRIK(nameChamber,"Mother","void",340,340,5.);
549 sprintf(nameNode,"MUON%d",100+id);
550 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
551 node->SetLineColor(kBlack);
556 for (Int_t j=0; j<nslats; j++)
558 sprintf(nameSlat,"SLAT%d",100*id+j);
559 new TBRIK(nameSlat,"Slat Module","void",20.*npcb[j],20.,0.25);
563 if (j==0 && i!=2) xpos+=37.5;
564 if (j==0 && i==2) xpos+=40;
566 color = TMath::Even(j) ? kColorMUON2 : kColorMUON3;
568 sprintf(nameNode,"SLAT%d",100*id+j);
570 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos1,0,"");
571 nodeSlat->SetLineColor(color);
574 sprintf(nameNode,"SLAT%d",100*id+j+7);
576 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos1,0,"");
577 nodeSlat->SetLineColor(color);
579 if (i==2 || (i!=2 && j!=0)) {
582 color = TMath::Even(j) ? kColorMUON3 : kColorMUON2;
584 color = TMath::Even(j) ? kColorMUON2 : kColorMUON3;
588 sprintf(nameNode,"SLAT%d",100*id+j+14);
590 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos2,0,"");
591 nodeSlat->SetLineColor(color);
594 sprintf(nameNode,"SLAT%d",100*id+j+21);
596 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos2,0,"");
597 nodeSlat->SetLineColor(color);
606 Float_t xsize=kDmin[i]*zscale;
607 Float_t ysize=kDmax[i]*zscale;
608 Float_t holeScaled=hole*zscale;
612 new TBRIK(nameChamber,"Mother","void",halfx,halfy,0.25);
614 sprintf(nameNode,"MUON%d",100+id);
615 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
616 node->SetLineColor(kColorMUON2);
619 // up/down of beam pipe
621 halfy=(ysize/2.-holeScaled/2.)/2.;
622 new TBRIK(nameSense,"Sens. region","void",halfx,halfy,0.25);
625 ypos=holeScaled/2.+((ysize/2.-holeScaled/2.)/2.);
626 sprintf(nameNode,"MUON%d",200+id);
627 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
628 nodeS->SetLineColor(kColorMUON2);
632 sprintf(nameNode,"MUON%d",300+id);
633 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
634 nodeS->SetLineColor(kColorMUON2);
636 // left/right of beam pipe
637 halfx=(xsize/2.-holeScaled/2.)/2.;
639 new TBRIK(nameSense1,"Sens. region","void",halfx,halfy,0.25);
642 xpos=holeScaled/2.+((xsize/2.-holeScaled/2.)/2.);
643 sprintf(nameNode,"MUON%d",400+id);
644 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
645 nodeS->SetLineColor(kColorMUON2);
649 sprintf(nameNode,"MUON%d",500+id);
650 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
651 nodeS->SetLineColor(kColorMUON2);
656 new TBRIK(nameSense2,"Sens. region","void",halfx,halfy,0.25);
659 xpos=holeScaled/2.-halfx;
661 sprintf(nameNode,"MUON%d",600+id);
662 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
663 nodeS->SetLineColor(kColorMUON2);
667 sprintf(nameNode,"MUON%d",700+id);
668 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
669 nodeS->SetLineColor(kColorMUON2);
673 sprintf(nameNode,"MUON%d",800+id);
674 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
675 nodeS->SetLineColor(kColorMUON2);
679 sprintf(nameNode,"MUON%d",900+id);
680 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
681 nodeS->SetLineColor(kColorMUON2);
688 //___________________________________________
689 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
694 //___________________________________________
695 void AliMUON::MakeBranch(Option_t* option)
697 // Create Tree branches for the MUON.
698 const Int_t kBufferSize = 4000;
700 sprintf(branchname,"%sCluster",GetName());
702 AliDetector::MakeBranch(option);
704 if (fPadHits && gAlice->TreeH()) {
705 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
706 printf("Making Branch %s for clusters\n",branchname);
709 // one branch for digits per chamber
712 for (i=0; i<AliMUONConstants::NCh() ;i++) {
713 sprintf(branchname,"%sDigits%d",GetName(),i+1);
715 if (fDchambers && gAlice->TreeD()) {
716 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
717 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
721 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
723 // one branch for raw clusters per chamber
724 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
725 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
727 if (fRawClusters && gAlice->TreeR()) {
728 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
729 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
733 // one branch for global trigger
734 sprintf(branchname,"%sGlobalTrigger",GetName());
735 if (fGlobalTrigger && gAlice->TreeR()) {
736 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
737 printf("Making Branch %s for Global Trigger\n",branchname);
739 // one branch for local trigger
740 sprintf(branchname,"%sLocalTrigger",GetName());
741 if (fLocalTrigger && gAlice->TreeR()) {
742 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
743 printf("Making Branch %s for Local Trigger\n",branchname);
748 //___________________________________________
749 void AliMUON::SetTreeAddress()
751 // Set branch address for the Hits and Digits Tree.
753 AliDetector::SetTreeAddress();
756 TTree *treeH = gAlice->TreeH();
757 TTree *treeD = gAlice->TreeD();
758 TTree *treeR = gAlice->TreeR();
762 branch = treeH->GetBranch("MUONCluster");
763 if (branch) branch->SetAddress(&fPadHits);
768 for (int i=0; i<AliMUONConstants::NCh(); i++) {
769 sprintf(branchname,"%sDigits%d",GetName(),i+1);
771 branch = treeD->GetBranch(branchname);
772 if (branch) branch->SetAddress(&((*fDchambers)[i]));
777 // printf("SetTreeAddress --- treeR address %p \n",treeR);
780 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
781 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
783 branch = treeR->GetBranch(branchname);
784 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
789 branch = treeR->GetBranch("MUONLocalTrigger");
790 if (branch) branch->SetAddress(&fLocalTrigger);
792 if (fGlobalTrigger) {
793 branch = treeR->GetBranch("MUONGlobalTrigger");
794 if (branch) branch->SetAddress(&fGlobalTrigger);
798 //___________________________________________
799 void AliMUON::ResetHits()
801 // Reset number of clusters and the cluster array for this detector
802 AliDetector::ResetHits();
804 if (fPadHits) fPadHits->Clear();
807 //____________________________________________
808 void AliMUON::ResetDigits()
811 // Reset number of digits and the digits array for this detector
813 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
814 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
815 if (fNdch) fNdch[i]=0;
818 //____________________________________________
819 void AliMUON::ResetRawClusters()
822 // Reset number of raw clusters and the raw clust array for this detector
824 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
825 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
826 if (fNrawch) fNrawch[i]=0;
830 //____________________________________________
831 void AliMUON::ResetTrigger()
833 // Reset Local and Global Trigger
835 if (fGlobalTrigger) fGlobalTrigger->Clear();
837 if (fLocalTrigger) fLocalTrigger->Clear();
840 //____________________________________________
841 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
844 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
845 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
848 //___________________________________________
849 void AliMUON::SetChambersZ(const Float_t *Z)
851 // Set Z values for all chambers (tracking and trigger)
852 // from the array pointed to by "Z"
853 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
854 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
858 //___________________________________________
859 void AliMUON::SetChambersZToDefault()
861 // Set Z values for all chambers (tracking and trigger)
863 SetChambersZ(AliMUONConstants::DefaultChamberZ());
867 //___________________________________________
868 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
871 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
872 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
875 //___________________________________________
876 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
879 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
880 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
883 //___________________________________________
884 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
887 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
888 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
891 //___________________________________________
892 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
895 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
896 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
899 //___________________________________________
900 void AliMUON::SetMaxStepGas(Float_t p1)
905 //___________________________________________
906 void AliMUON::SetMaxStepAlu(Float_t p1)
911 //___________________________________________
912 void AliMUON::SetMaxDestepGas(Float_t p1)
917 //___________________________________________
918 void AliMUON::SetMaxDestepAlu(Float_t p1)
922 //___________________________________________
923 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
926 fAccMin=angmin*TMath::Pi()/180;
927 fAccMax=angmax*TMath::Pi()/180;
930 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
931 // Loop over 2 chambers in the station
932 for (Int_t stCH = 0; stCH < 2; stCH++) {
934 // Set chamber inner and outer radius according to acceptance cuts
935 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
936 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
941 //___________________________________________
942 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
944 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
947 //___________________________________________
948 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
950 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
953 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
955 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
958 void AliMUON::SetNsec(Int_t id, Int_t nsec)
960 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
964 //___________________________________________
968 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
969 Float_t eloss, Float_t tof, Int_t idvol)
972 // Calls the charge disintegration method of the current chamber and adds
973 // the simulated cluster to the root treee
976 Float_t newclust[6][500];
981 // Integrated pulse height on chamber
987 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
990 ((AliMUONChamber*) (*fChambers)[idvol])
991 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
993 // if (idvol == 6) printf("\n nnew %d \n", nnew);
996 for (Int_t i=0; i<nnew; i++) {
997 if (Int_t(newclust[3][i]) > 0) {
1000 clhits[1] = Int_t(newclust[5][i]);
1002 clhits[2] = Int_t(newclust[0][i]);
1004 clhits[3] = Int_t(newclust[1][i]);
1006 clhits[4] = Int_t(newclust[2][i]);
1008 clhits[5] = Int_t(newclust[3][i]);
1009 // Pad: chamber sector
1010 clhits[6] = Int_t(newclust[4][i]);
1017 //----------------------------------------------------------------------
1019 void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
1021 // keep galice.root for signal and name differently the file for
1022 // background when add! otherwise the track info for signal will be lost !
1024 static Bool_t first=kTRUE;
1026 char *addBackground = strstr(option,"Add");
1029 AliMUONChamber* iChamber;
1030 AliSegmentation* segmentation;
1035 TObjArray *list=new TObjArray;
1036 static TClonesArray *pAddress=0;
1037 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
1040 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
1041 AliHitMap** hitMap= new AliHitMap* [AliMUONConstants::NCh()];
1042 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
1043 if (addBackground ) {
1046 cout<<"filename"<<fFileName<<endl;
1047 file=new TFile(fFileName);
1048 cout<<"I have opened "<<fFileName<<" file "<<endl;
1049 fHits2 = new TClonesArray("AliMUONHit",1000 );
1050 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
1055 // Get Hits Tree header from file
1056 if(fHits2) fHits2->Clear();
1057 if(fPadHits2) fPadHits2->Clear();
1058 if(fTrH1) delete fTrH1;
1062 sprintf(treeName,"TreeH%d",bgrEvent);
1063 fTrH1 = (TTree*)gDirectory->Get(treeName);
1064 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
1067 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
1069 // Set branch addresses
1071 char branchname[20];
1072 sprintf(branchname,"%s",GetName());
1073 if (fTrH1 && fHits2) {
1074 branch = fTrH1->GetBranch(branchname);
1075 if (branch) branch->SetAddress(&fHits2);
1077 if (fTrH1 && fPadHits2) {
1078 branch = fTrH1->GetBranch("MUONCluster");
1079 if (branch) branch->SetAddress(&fPadHits2);
1082 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
1083 //printf("background - ntracks1 - %d\n",ntracks1);
1086 // loop over cathodes
1090 for (int icat=0; icat<2; icat++) {
1092 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
1093 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
1094 iChamber=(AliMUONChamber*) (*fChambers)[i];
1095 if (iChamber->Nsec()==1 && icat==1) {
1098 segmentation=iChamber->SegmentationModel(icat+1);
1100 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
1103 //printf("Start loop over tracks \n");
1108 TTree *treeH = gAlice->TreeH();
1109 Int_t ntracks =(Int_t) treeH->GetEntries();
1112 Float_t ** xhit = new Float_t * [AliMUONConstants::NCh()];
1113 for (jj=0; jj<AliMUONConstants::NCh(); jj++) xhit[jj] = new Float_t[2];
1114 Float_t ** yhit = new Float_t * [AliMUONConstants::NCh()];
1115 for (jj=0; jj<AliMUONConstants::NCh(); jj++) yhit[jj] = new Float_t[2];
1117 for (Int_t track=0; track<ntracks; track++) {
1118 gAlice->ResetHits();
1119 treeH->GetEvent(track);
1122 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
1124 mHit=(AliMUONHit*)pMUON->NextHit())
1126 Int_t nch = mHit->fChamber-1; // chamber number
1127 if (nch > AliMUONConstants::NCh()-1) continue;
1128 // if (nch > 9) continue;
1129 iChamber = &(pMUON->Chamber(nch));
1131 if (addBackground) {
1133 if (mHit->fParticle == kMuonPlus
1134 || mHit->fParticle == kMuonMinus) {
1135 xhit[nch][nmuon[nch]]=mHit->X();
1136 yhit[nch][nmuon[nch]]=mHit->Y();
1138 if (nmuon[nch] >2) printf("nmuon %d\n",nmuon[nch]);
1146 // Loop over pad hits
1147 for (AliMUONPadHit* mPad=
1148 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
1150 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
1152 Int_t cathode = mPad->fCathode; // cathode number
1153 Int_t ipx = mPad->fPadX; // pad number on X
1154 Int_t ipy = mPad->fPadY; // pad number on Y
1155 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1156 // printf("\n Pad: %d %d %d %d", ipx, ipy, cathode,nch);
1160 if (cathode != (icat+1)) continue;
1161 // fill the info array
1162 // Float_t thex, they, thez;
1163 segmentation=iChamber->SegmentationModel(cathode);
1164 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1165 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1166 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1168 new((*pAddress)[countadr++]) TVector(2);
1169 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1170 trinfo(0)=(Float_t)track;
1171 trinfo(1)=(Float_t)iqpad;
1177 if (mHit->fParticle == kMuonPlus ||
1178 mHit->fParticle == kMuonMinus) {
1179 digits[4]=mPad->fHitNumber;
1180 } else digits[4]=-1;
1182 AliMUONTransientDigit* pdigit;
1183 // build the list of fired pads and update the info
1184 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1186 list->AddAtAndExpand(
1187 new AliMUONTransientDigit(nch,digits),counter);
1189 hitMap[nch]->SetHit(ipx, ipy, counter);
1191 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1193 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1194 trlist->Add(&trinfo);
1196 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1198 (*pdigit).fSignal+=iqpad;
1199 (*pdigit).fPhysics+=iqpad;
1200 // update list of tracks
1201 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
1202 Int_t lastEntry=trlist->GetLast();
1203 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1204 TVector &ptrk=*pTrack;
1205 Int_t lastTrack = Int_t(ptrk(0));
1206 Int_t lastCharge = Int_t(ptrk(1));
1207 if (lastTrack==track) {
1209 trlist->RemoveAt(lastEntry);
1210 trinfo(0)=lastTrack;
1211 trinfo(1)=lastCharge;
1212 trlist->AddAt(&trinfo,lastEntry);
1214 trlist->Add(&trinfo);
1216 // check the track list
1217 Int_t nptracks=trlist->GetEntriesFast();
1219 for (Int_t tr=0;tr<nptracks;tr++) {
1220 TVector *ppTrack=(TVector*)trlist->At(tr);
1221 TVector &pptrk=*ppTrack;
1222 trk[tr] = Int_t(pptrk(0));
1223 chtrk[tr] = Int_t(pptrk(1));
1225 } // end if nptracks
1227 } //end loop over clusters
1231 // open the file with background
1233 if (addBackground) {
1234 ntracks =(Int_t)fTrH1->GetEntries();
1238 for (Int_t track=0; track<ntracks; track++) {
1240 if (fHits2) fHits2->Clear();
1241 if (fPadHits2) fPadHits2->Clear();
1243 fTrH1->GetEvent(track);
1247 for(int i=0;i<fHits2->GetEntriesFast();++i)
1249 mHit=(AliMUONHit*) (*fHits2)[i];
1250 Int_t nch = mHit->fChamber-1; // chamber number
1251 if (nch >9) continue;
1252 iChamber = &(pMUON->Chamber(nch));
1253 // Int_t rmin = (Int_t)iChamber->RInner();
1254 // Int_t rmax = (Int_t)iChamber->ROuter();
1255 Float_t xbgr=mHit->X();
1256 Float_t ybgr=mHit->Y();
1259 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1260 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1261 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
1262 if (dist<100) cond=kTRUE;
1264 if (!cond) continue;
1267 // Loop over pad hits
1268 for (AliMUONPadHit* mPad=
1269 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
1271 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
1273 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
1274 Int_t cathode = mPad->fCathode; // cathode number
1275 Int_t ipx = mPad->fPadX; // pad number on X
1276 Int_t ipy = mPad->fPadY; // pad number on Y
1277 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1279 if (cathode != (icat+1)) continue;
1280 printf("\n Pad: %d %d %d", ipx, ipy, cathode);
1282 // Float_t thex, they, thez;
1283 // segmentation=iChamber->SegmentationModel(cathode);
1284 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1285 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1286 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1287 new((*pAddress)[countadr++]) TVector(2);
1288 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1289 trinfo(0)=-1; // tag background
1298 AliMUONTransientDigit* pdigit;
1299 // build the list of fired pads and update the info
1300 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1301 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1303 hitMap[nch]->SetHit(ipx, ipy, counter);
1306 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1308 TObjArray *trlist=(TObjArray*)pdigit->
1310 trlist->Add(&trinfo);
1312 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1314 (*pdigit).fSignal+=iqpad;
1316 // update list of tracks
1317 TObjArray* trlist=(TObjArray*)pdigit->
1319 Int_t lastEntry=trlist->GetLast();
1320 TVector *pTrack=(TVector*)trlist->
1322 TVector &ptrk=*pTrack;
1323 Int_t lastTrack=Int_t(ptrk(0));
1324 if (lastTrack==-1) {
1327 trlist->Add(&trinfo);
1329 // check the track list
1330 Int_t nptracks=trlist->GetEntriesFast();
1332 for (Int_t tr=0;tr<nptracks;tr++) {
1333 TVector *ppTrack=(TVector*)trlist->At(tr);
1334 TVector &pptrk=*ppTrack;
1335 trk[tr]=Int_t(pptrk(0));
1336 chtrk[tr]=Int_t(pptrk(1));
1338 } // end if nptracks
1340 } //end loop over clusters
1343 //Int_t nentr2=list->GetEntriesFast();
1344 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1345 TTree *fAli=gAlice->TreeK();
1348 if (fAli) file =fAli->GetCurrentFile();
1350 } // if addBackground
1356 Int_t nentries=list->GetEntriesFast();
1358 for (Int_t nent=0;nent<nentries;nent++) {
1359 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
1360 if (address==0) continue;
1361 Int_t ich=address->fChamber;
1362 Int_t q=address->fSignal;
1363 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1365 // Digit Response (noise, threshold, saturation, ...)
1366 // if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1367 AliMUONResponse * response=iChamber->ResponseModel();
1368 q=response->DigitResponse(q);
1372 digits[0]=address->fPadX;
1373 digits[1]=address->fPadY;
1375 digits[3]=address->fPhysics;
1376 digits[4]=address->fHit;
1378 TObjArray* trlist=(TObjArray*)address->TrackList();
1379 Int_t nptracks=trlist->GetEntriesFast();
1380 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1382 // this was changed to accomodate the real number of tracks
1383 if (nptracks > 10) {
1384 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1388 printf("Attention - nptracks > 2 %d \n",nptracks);
1389 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1391 for (Int_t tr=0;tr<nptracks;tr++) {
1392 TVector *ppP=(TVector*)trlist->At(tr);
1393 if(!ppP ) printf("ppP - %p\n",ppP);
1395 tracks[tr]=Int_t(pp(0));
1396 charges[tr]=Int_t(pp(1));
1397 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
1398 } //end loop over list of tracks for one pad
1399 // Sort list of tracks according to charge
1401 SortTracks(tracks,charges,nptracks);
1403 if (nptracks < 10 ) {
1404 for (Int_t i=nptracks; i<10; i++) {
1411 pMUON->AddDigits(ich,tracks,charges,digits);
1414 //cout<<"I'm out of the loops for digitisation"<<endl;
1415 // gAlice->GetEvent(nev);
1416 gAlice->TreeD()->Fill();
1417 pMUON->ResetDigits();
1421 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
1429 } //end loop over cathodes
1432 sprintf(hname,"TreeD%d",nev);
1433 gAlice->TreeD()->Write(hname);
1435 gAlice->TreeD()->Reset();
1439 // gObjectTable->Print();
1442 void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1445 // Sort the list of tracks contributing to a given digit
1446 // Only the 3 most significant tracks are acctually sorted
1450 // Loop over signals, only 3 times
1455 Int_t idx[3] = {-2,-2,-2};
1456 Int_t jch[3] = {-2,-2,-2};
1457 Int_t jtr[3] = {-2,-2,-2};
1460 if (ntr<3) imax=ntr;
1462 for(i=0;i<imax;i++){
1468 if((i == 1 && j == idx[i-1])
1469 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1471 if(charges[j] > qmax) {
1479 jch[i]=charges[jmax];
1480 jtr[i]=tracks[jmax];
1497 //___________________________________________
1498 void AliMUON::Trigger(Int_t nev){
1499 // call the Trigger Algorithm and fill TreeR
1501 Int_t singlePlus[3] = {0,0,0};
1502 Int_t singleMinus[3] = {0,0,0};
1503 Int_t singleUndef[3] = {0,0,0};
1504 Int_t pairUnlike[3] = {0,0,0};
1505 Int_t pairLike[3] = {0,0,0};
1508 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1509 decision->Trigger();
1510 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1511 pairUnlike, pairLike);
1512 // add a local trigger in the list
1513 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
1516 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
1517 if(decision->GetITrigger(icirc)==1) {
1518 Int_t localtr[7]={0,0,0,0,0,0,0};
1519 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1520 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1522 localtr[1] = decision->GetStripX11(icirc);
1523 localtr[2] = decision->GetDev(icirc);
1524 localtr[3] = decision->GetStripY11(icirc);
1525 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1526 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1527 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1528 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1530 AddLocalTrigger(localtr); // add a local trigger in the list
1535 gAlice->TreeR()->Fill();
1538 sprintf(hname,"TreeR%d",nev);
1539 gAlice->TreeR()->Write(hname);
1540 gAlice->TreeR()->Reset();
1541 printf("\n End of trigger for event %d", nev);
1545 //____________________________________________
1546 void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1548 TClonesArray *dig1, *dig2;
1550 dig1 = new TClonesArray("AliMUONDigit",1000);
1551 dig2 = new TClonesArray("AliMUONDigit",1000);
1552 AliMUONDigit *digit;
1554 // Loop on chambers and on cathode planes
1557 for (Int_t ich=0;ich<10;ich++) {
1558 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1559 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1560 gAlice->ResetDigits();
1561 gAlice->TreeD()->GetEvent(lastEntry);
1562 TClonesArray *muonDigits = this->DigitsAddress(ich);
1563 ndig=muonDigits->GetEntriesFast();
1564 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1565 TClonesArray &lhits1 = *dig1;
1567 for (k=0; k<ndig; k++) {
1568 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1569 if (rec->TestTrack(digit->fTracks[0]))
1570 new(lhits1[n++]) AliMUONDigit(*digit);
1572 gAlice->ResetDigits();
1573 gAlice->TreeD()->GetEvent(lastEntry+1);
1574 muonDigits = this->DigitsAddress(ich);
1575 ndig=muonDigits->GetEntriesFast();
1576 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1577 TClonesArray &lhits2 = *dig2;
1580 for (k=0; k<ndig; k++) {
1581 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1582 if (rec->TestTrack(digit->fTracks[0]))
1583 new(lhits2[n++]) AliMUONDigit(*digit);
1587 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1588 rec->FindRawClusters();
1593 gAlice->TreeR()->Fill();
1596 sprintf(hname,"TreeR%d",nev);
1597 gAlice->TreeR()->Write(hname);
1598 gAlice->TreeR()->Reset();
1599 printf("\n End of cluster finding for event %d", nev);
1603 //gObjectTable->Print();
1607 void AliMUON::Streamer(TBuffer &R__b)
1609 // Stream an object of class AliMUON.
1610 AliMUONChamber *iChamber;
1611 AliMUONTriggerCircuit *iTriggerCircuit;
1612 AliSegmentation *segmentation;
1613 AliMUONResponse *response;
1614 TClonesArray *digitsaddress;
1615 TClonesArray *rawcladdress;
1617 if (R__b.IsReading()) {
1618 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1619 AliDetector::Streamer(R__b);
1621 R__b >> fPadHits; // diff
1622 R__b >> fNLocalTrigger;
1623 R__b >> fLocalTrigger;
1624 R__b >> fNGlobalTrigger;
1625 R__b >> fGlobalTrigger;
1627 R__b >> fRawClusters;
1628 R__b.ReadArray(fNdch);
1629 R__b.ReadArray(fNrawch);
1634 R__b >> fTriggerCircuits;
1635 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1636 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1637 iTriggerCircuit->Streamer(R__b);
1639 // Stream chamber related information
1640 for (i =0; i<AliMUONConstants::NCh(); i++) {
1641 iChamber=(AliMUONChamber*) (*fChambers)[i];
1642 iChamber->Streamer(R__b);
1643 if (iChamber->Nsec()==1) {
1644 segmentation=iChamber->SegmentationModel(1);
1646 segmentation->Streamer(R__b);
1648 segmentation=iChamber->SegmentationModel(1);
1650 segmentation->Streamer(R__b);
1652 segmentation=iChamber->SegmentationModel(2);
1653 segmentation->Streamer(R__b);
1655 response=iChamber->ResponseModel();
1657 response->Streamer(R__b);
1658 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1659 digitsaddress->Streamer(R__b);
1660 if (i < AliMUONConstants::NTrackingCh()) {
1661 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1662 rawcladdress->Streamer(R__b);
1667 R__b.WriteVersion(AliMUON::IsA());
1668 AliDetector::Streamer(R__b);
1670 R__b << fPadHits; // diff
1671 R__b << fNLocalTrigger;
1672 R__b << fLocalTrigger;
1673 R__b << fNGlobalTrigger;
1674 R__b << fGlobalTrigger;
1676 R__b << fRawClusters;
1677 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1678 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1685 R__b << fTriggerCircuits;
1686 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1687 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1688 iTriggerCircuit->Streamer(R__b);
1690 for (i =0; i<AliMUONConstants::NCh(); i++) {
1691 iChamber=(AliMUONChamber*) (*fChambers)[i];
1692 iChamber->Streamer(R__b);
1693 if (iChamber->Nsec()==1) {
1694 segmentation=iChamber->SegmentationModel(1);
1696 segmentation->Streamer(R__b);
1698 segmentation=iChamber->SegmentationModel(1);
1700 segmentation->Streamer(R__b);
1701 segmentation=iChamber->SegmentationModel(2);
1703 segmentation->Streamer(R__b);
1705 response=iChamber->ResponseModel();
1707 response->Streamer(R__b);
1708 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1709 digitsaddress->Streamer(R__b);
1710 if (i < AliMUONConstants::NTrackingCh()) {
1711 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1712 rawcladdress->Streamer(R__b);
1717 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1720 // Initialise the pad iterator
1721 // Return the address of the first padhit for hit
1722 TClonesArray *theClusters = clusters;
1723 Int_t nclust = theClusters->GetEntriesFast();
1724 if (nclust && hit->fPHlast > 0) {
1725 AliMUON::fMaxIterPad=hit->fPHlast;
1726 AliMUON::fCurIterPad=hit->fPHfirst;
1727 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1733 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1735 AliMUON::fCurIterPad++;
1736 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1737 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1744 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1746 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1748 TTree *treeR = gAlice->TreeR();
1749 Int_t nent=(Int_t)treeR->GetEntries();
1750 treeR->GetEvent(nent-2+icathod-1);
1751 //treeR->GetEvent(icathod);
1752 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1754 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1755 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1760 AliMUON& AliMUON::operator = (const AliMUON& rhs)