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.34 2000/10/18 11:42:06 morsch
18 - AliMUONRawCluster contains z-position.
19 - Some clean-up of useless print statements during initialisations.
21 Revision 1.33 2000/10/09 14:01:57 morsch
22 Unused variables removed.
24 Revision 1.32 2000/10/06 09:08:10 morsch
25 Built geometry includes slat geometry for event display.
27 Revision 1.31 2000/10/02 21:28:08 fca
28 Removal of useless dependecies via forward declarations
30 Revision 1.30 2000/10/02 16:58:29 egangler
31 Cleaning of the code :
34 -> some useless includes removed or replaced by "class" statement
36 Revision 1.29 2000/07/28 13:49:38 morsch
37 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
38 Can be used for simple acceptance studies.
40 Revision 1.28 2000/07/22 16:43:15 morsch
41 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
43 Revision 1.27 2000/07/22 16:36:50 morsch
44 Change order of indices in creation (new) of xhit and yhit
46 Revision 1.26 2000/07/03 11:54:57 morsch
47 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
48 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
50 Revision 1.25 2000/06/29 12:34:09 morsch
51 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
52 it usable with any other geometry class. The link to the object to which it belongs is
53 established via an index. This assumes that there exists a global geometry manager
54 from which the pointer to the parent object can be obtained (in our case gAlice).
56 Revision 1.24 2000/06/28 15:16:35 morsch
57 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
58 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
59 framework. The changes should have no side effects (mostly dummy arguments).
60 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
61 of chambers with overlapping modules (MakePadHits, Disintegration).
63 Revision 1.23 2000/06/28 12:19:17 morsch
64 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
65 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
66 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
67 It requires two cathode planes. Small modifications in the code will make it usable for
68 one cathode plane and, hence, more general (for test beam data).
69 AliMUONClusterFinder is now obsolete.
71 Revision 1.22 2000/06/28 08:06:10 morsch
72 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
73 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
74 It also naturally takes care of the TMinuit instance.
76 Revision 1.21 2000/06/27 08:54:41 morsch
77 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
79 Revision 1.20 2000/06/26 14:02:38 morsch
80 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
82 Revision 1.19 2000/06/22 13:40:51 morsch
83 scope problem on HP, "i" declared once
84 pow changed to TMath::Power (PH, AM)
86 Revision 1.18 2000/06/15 07:58:48 morsch
87 Code from MUON-dev joined
89 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
90 - add TriggerCircuit (PC)
91 - add GlobalTrigger and LocalTrigger and specific methods (PC)
93 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
94 Most coding rule violations corrected
96 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
97 RULE RN17 violations corrected
99 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
100 Code revised by P. Crochet:
101 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
102 - ToF included in the method MakePadHits
103 - inner radius of flange between beam shielding and trigger corrected
104 - Trigger global volume updated (according to the new geometry)
106 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
107 Some changes of variable names curing viols and methods concerning
108 correlated clusters removed.
110 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
111 Memory leak suppressed in function Digitise:
112 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
114 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
115 Positions of trigger chambers corrected (P.C.)
117 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
118 Call to AddHitList introduced to make this version compatible with head.
120 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
121 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
123 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
124 Trigger included into initialization and digitization
126 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
127 Log messages of previous revisions added
129 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
130 Z position of the chambers:
131 it was the Z position of the stations;
132 it is now really the Z position of the chambers.
133 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
134 !!!! AND "AliMUONChamber::ZPosition"
135 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
136 !!!! AND "AliMUONChamber::Z"
138 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
139 Correction for mis-spelling of NCH
141 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
147 ///////////////////////////////////////////////
148 // Manager and hits classes for set:MUON //
149 ////////////////////////////////////////////////
153 #include <TRotMatrix.h>
154 #include <TGeometry.h>
160 #include <TObjArray.h>
162 #include <TParticle.h>
168 #include <TDirectory.h>
169 #include <TObjectTable.h>
174 #include "AliMUONHit.h"
175 #include "AliMUONPadHit.h"
176 #include "AliMUONDigit.h"
177 #include "AliMUONTransientDigit.h"
178 #include "AliMUONRawCluster.h"
179 #include "AliMUONLocalTrigger.h"
180 #include "AliMUONGlobalTrigger.h"
181 #include "AliMUONTriggerCircuit.h"
182 #include "AliHitMap.h"
183 #include "AliMUONHitMapA1.h"
184 #include "AliMUONChamberTrigger.h"
185 #include "AliMUONConstants.h"
186 #include "AliMUONClusterFinderVS.h"
187 #include "AliMUONTriggerDecision.h"
190 #include "AliMUONClusterInput.h"
191 #include "iostream.h"
192 #include "AliCallf77.h"
193 #include "AliConst.h"
195 // Defaults parameters for Z positions of chambers
196 // taken from values for "stations" in AliMUON::AliMUON
197 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
198 // and from array "dstation" in AliMUONv1::CreateGeometry
199 // Float_t dstation[5]={20., 20., 20, 20., 20.};
200 // for tracking chambers,
201 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
202 // for the first and second chambers in the station, respectively,
203 // and from "DTPLANES" in AliMUONv1::CreateGeometry
204 // const Float_t DTPLANES = 15.;
205 // for trigger chambers,
206 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
207 // for the first and second chambers in the station, respectively
210 //___________________________________________
218 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
231 //___________________________________________
232 AliMUON::AliMUON(const char *name, const char *title)
233 : AliDetector(name,title)
237 <img src="gif/alimuon.gif">
241 fHits = new TClonesArray("AliMUONHit",1000);
242 gAlice->AddHitList(fHits);
243 fPadHits = new TClonesArray("AliMUONPadHit",10000);
247 fNdch = new Int_t[AliMUONConstants::NCh()];
249 fDchambers = new TObjArray(AliMUONConstants::NCh());
253 for (i=0; i<AliMUONConstants::NCh() ;i++) {
254 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
258 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
260 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
262 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
263 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
267 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
269 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
272 SetMarkerColor(kRed);
280 fChambers = new TObjArray(AliMUONConstants::NCh());
282 // Loop over stations
283 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
284 // Loop over 2 chambers in the station
285 for (Int_t stCH = 0; stCH < 2; stCH++) {
288 // Default Parameters for Muon Tracking Stations
293 if (ch < AliMUONConstants::NTrackingCh()) {
294 (*fChambers)[ch] = new AliMUONChamber(ch);
296 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
299 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
302 // Default values for Z of chambers
303 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
305 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
306 // Set chamber inner and outer radius to default
307 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
308 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
310 } // Chamber stCH (0, 1) in
311 } // Station st (0...)
324 // cp new design of AliMUONTriggerDecision
325 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
326 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
327 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
329 // cp new design of AliMUONTriggerDecision
333 //___________________________________________
334 AliMUON::AliMUON(const AliMUON& rMUON)
336 // Dummy copy constructor
343 printf("Calling AliMUON destructor !!!\n");
350 delete fGlobalTrigger;
353 delete fLocalTrigger;
356 for (i=0;i<AliMUONConstants::NCh();i++) {
357 delete (*fDchambers)[i];
362 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
363 delete (*fRawClusters)[i];
368 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
369 delete (*fTriggerCircuits)[circ];
371 delete fTriggerCircuits;
374 //___________________________________________
375 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
377 TClonesArray &lhits = *fHits;
378 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
380 //___________________________________________
381 void AliMUON::AddPadHit(Int_t *clhits)
383 TClonesArray &lclusters = *fPadHits;
384 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
386 //_____________________________________________________________________________
387 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
390 // Add a MUON digit to the list
393 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
394 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
397 //_____________________________________________________________________________
398 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
401 // Add a MUON digit to the list
404 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
405 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
408 //___________________________________________
409 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
411 Int_t *pairUnlike, Int_t *pairLike)
413 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
414 TClonesArray &globalTrigger = *fGlobalTrigger;
415 new(globalTrigger[fNGlobalTrigger++])
416 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
419 //___________________________________________
420 void AliMUON::AddLocalTrigger(Int_t *localtr)
422 // add a MUON Local Trigger to the list
423 TClonesArray &localTrigger = *fLocalTrigger;
424 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
427 //___________________________________________
428 void AliMUON::BuildGeometry()
430 TNode *node, *nodeF, *top, *nodeS;
431 const int kColorMUON = kBlue;
432 const int kColorMUON2 = kYellow;
433 const int kColorMUON3 = kBlue;
435 top=gAlice->GetGeometry()->GetNode("alice");
438 // z-Positions of Chambers
439 const Float_t kCz[7]={511., 686., 971., 1245., 1445., 1600, 1700.};
440 // inner diameter (Xlenght for trigger chamber -> active area)
441 const Float_t kDmin[7]={ 35., 47., 67., 86., 100., 544., 544.};
442 // outer diameter (Ylenght for trigger chamber -> active area)
443 const Float_t kDmax[7]={183., 245., 346., 520., 520., 612., 612.};
445 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
446 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
447 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
448 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
450 Float_t rmin, rmax, dx, dy, dz, dr, xpos, ypos, zpos;
451 Float_t dzc1=4.; // tracking chambers
452 Float_t dzc2=15.; // trigger chambers
453 Float_t hole=102.; // x-y hole around beam pipe for trig. chambers
454 Float_t zscale; // scaling parameter trigger chambers
455 Float_t halfx, halfy;
456 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
457 char nameSense1[9], nameSense2[9];
458 for (Int_t i=0; i<7; i++) {
459 for (Int_t j=0; j<2; j++) {
461 if (i<5) { // tracking chambers
474 sprintf(nameChamber,"C_MUON%d",id);
475 sprintf(nameSense,"S_MUON%d",id);
476 sprintf(nameSense1,"S1_MUON%d",id);
477 sprintf(nameSense2,"S2_MUON%d",id);
478 sprintf(nameFrame,"F_MUON%d",id);
479 if (i<2) { // tracking chambers
480 rmin = kDmin[i]/2.-3;
481 rmax = kDmax[i]/2.+3;
482 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
485 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
489 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
491 sprintf(nameNode,"MUON%d",100+id);
492 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,zpos,"");
493 node->SetLineColor(kColorMUON);
496 sprintf(nameNode,"MUON%d",200+id);
497 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
498 node->SetLineColor(kColorMUON);
501 sprintf(nameNode,"MUON%d",300+id);
502 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
503 nodeF->SetLineColor(kColorMUON);
505 sprintf(nameNode,"MUON%d",400+id);
506 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
507 nodeF->SetLineColor(kColorMUON);
509 sprintf(nameNode,"MUON%d",500+id);
510 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
511 nodeF->SetLineColor(kColorMUON);
513 sprintf(nameNode,"MUON%d",600+id);
514 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
515 nodeF->SetLineColor(kColorMUON);
516 } else if (i >= 2 || i <= 4) {
518 Int_t npcb[7]={0, 0, 0, 0, 0, 0, 0};
521 npcb[0] = 3; npcb[1] = 4; npcb[2] = 3; npcb[3] = 2;
524 npcb[0] = 4; npcb[1] = 5; npcb[2] = 5; npcb[3] = 4;
525 npcb[4] = 3; npcb[5] = 2;
528 npcb[0] = 7; npcb[1] = 7; npcb[2] = 6; npcb[3] = 6;
529 npcb[4] = 5; npcb[5] = 4; npcb[6] = 2;
535 Float_t ypos1=-0.75+20.;
536 Float_t ypos2= 0.75-20.;
541 new TBRIK(nameChamber,"Mother","void",340,340,5.);
543 sprintf(nameNode,"MUON%d",100+id);
544 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
545 node->SetLineColor(kBlack);
550 for (Int_t j=0; j<nslats; j++)
552 sprintf(nameSlat,"SLAT%d",100*id+j);
553 new TBRIK(nameSlat,"Slat Module","void",20.*npcb[j],20.,0.25);
558 color = TMath::Even(j) ? kColorMUON2 : kColorMUON3;
560 sprintf(nameNode,"SLAT%d",100*id+j);
562 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos1,0,"");
563 nodeSlat->SetLineColor(color);
566 sprintf(nameNode,"SLAT%d",100*id+j+7);
568 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos1,0,"");
569 nodeSlat->SetLineColor(color);
571 if (i==2 || (i!=2 && j!=0)) {
574 color = TMath::Even(j) ? kColorMUON3 : kColorMUON2;
576 color = TMath::Even(j) ? kColorMUON2 : kColorMUON3;
580 sprintf(nameNode,"SLAT%d",100*id+j+14);
582 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos2,0,"");
583 nodeSlat->SetLineColor(color);
586 sprintf(nameNode,"SLAT%d",100*id+j+21);
588 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos2,0,"");
589 nodeSlat->SetLineColor(color);
598 Float_t xsize=kDmin[i]*zscale;
599 Float_t ysize=kDmax[i]*zscale;
600 Float_t holeScaled=hole*zscale;
604 new TBRIK(nameChamber,"Mother","void",halfx,halfy,0.25);
606 sprintf(nameNode,"MUON%d",100+id);
607 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
608 node->SetLineColor(kColorMUON2);
611 // up/down of beam pipe
613 halfy=(ysize/2.-holeScaled/2.)/2.;
614 new TBRIK(nameSense,"Sens. region","void",halfx,halfy,0.25);
617 ypos=holeScaled/2.+((ysize/2.-holeScaled/2.)/2.);
618 sprintf(nameNode,"MUON%d",200+id);
619 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
620 nodeS->SetLineColor(kColorMUON2);
624 sprintf(nameNode,"MUON%d",300+id);
625 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
626 nodeS->SetLineColor(kColorMUON2);
628 // left/right of beam pipe
629 halfx=(xsize/2.-holeScaled/2.)/2.;
631 new TBRIK(nameSense1,"Sens. region","void",halfx,halfy,0.25);
634 xpos=holeScaled/2.+((xsize/2.-holeScaled/2.)/2.);
635 sprintf(nameNode,"MUON%d",400+id);
636 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
637 nodeS->SetLineColor(kColorMUON2);
641 sprintf(nameNode,"MUON%d",500+id);
642 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
643 nodeS->SetLineColor(kColorMUON2);
648 new TBRIK(nameSense2,"Sens. region","void",halfx,halfy,0.25);
651 xpos=holeScaled/2.-halfx;
653 sprintf(nameNode,"MUON%d",600+id);
654 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
655 nodeS->SetLineColor(kColorMUON2);
659 sprintf(nameNode,"MUON%d",700+id);
660 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
661 nodeS->SetLineColor(kColorMUON2);
665 sprintf(nameNode,"MUON%d",800+id);
666 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
667 nodeS->SetLineColor(kColorMUON2);
671 sprintf(nameNode,"MUON%d",900+id);
672 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
673 nodeS->SetLineColor(kColorMUON2);
680 //___________________________________________
681 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
686 //___________________________________________
687 void AliMUON::MakeBranch(Option_t* option)
689 // Create Tree branches for the MUON.
690 const Int_t kBufferSize = 4000;
692 sprintf(branchname,"%sCluster",GetName());
694 AliDetector::MakeBranch(option);
696 if (fPadHits && gAlice->TreeH()) {
697 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
698 printf("Making Branch %s for clusters\n",branchname);
701 // one branch for digits per chamber
704 for (i=0; i<AliMUONConstants::NCh() ;i++) {
705 sprintf(branchname,"%sDigits%d",GetName(),i+1);
707 if (fDchambers && gAlice->TreeD()) {
708 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
709 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
713 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
715 // one branch for raw clusters per chamber
716 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
717 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
719 if (fRawClusters && gAlice->TreeR()) {
720 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
721 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
725 // one branch for global trigger
726 sprintf(branchname,"%sGlobalTrigger",GetName());
727 if (fGlobalTrigger && gAlice->TreeR()) {
728 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
729 printf("Making Branch %s for Global Trigger\n",branchname);
731 // one branch for local trigger
732 sprintf(branchname,"%sLocalTrigger",GetName());
733 if (fLocalTrigger && gAlice->TreeR()) {
734 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
735 printf("Making Branch %s for Local Trigger\n",branchname);
740 //___________________________________________
741 void AliMUON::SetTreeAddress()
743 // Set branch address for the Hits and Digits Tree.
745 AliDetector::SetTreeAddress();
748 TTree *treeH = gAlice->TreeH();
749 TTree *treeD = gAlice->TreeD();
750 TTree *treeR = gAlice->TreeR();
754 branch = treeH->GetBranch("MUONCluster");
755 if (branch) branch->SetAddress(&fPadHits);
760 for (int i=0; i<AliMUONConstants::NCh(); i++) {
761 sprintf(branchname,"%sDigits%d",GetName(),i+1);
763 branch = treeD->GetBranch(branchname);
764 if (branch) branch->SetAddress(&((*fDchambers)[i]));
769 // printf("SetTreeAddress --- treeR address %p \n",treeR);
772 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
773 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
775 branch = treeR->GetBranch(branchname);
776 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
781 branch = treeR->GetBranch("MUONLocalTrigger");
782 if (branch) branch->SetAddress(&fLocalTrigger);
784 if (fGlobalTrigger) {
785 branch = treeR->GetBranch("MUONGlobalTrigger");
786 if (branch) branch->SetAddress(&fGlobalTrigger);
790 //___________________________________________
791 void AliMUON::ResetHits()
793 // Reset number of clusters and the cluster array for this detector
794 AliDetector::ResetHits();
796 if (fPadHits) fPadHits->Clear();
799 //____________________________________________
800 void AliMUON::ResetDigits()
803 // Reset number of digits and the digits array for this detector
805 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
806 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
807 if (fNdch) fNdch[i]=0;
810 //____________________________________________
811 void AliMUON::ResetRawClusters()
814 // Reset number of raw clusters and the raw clust array for this detector
816 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
817 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
818 if (fNrawch) fNrawch[i]=0;
822 //____________________________________________
823 void AliMUON::ResetTrigger()
825 // Reset Local and Global Trigger
827 if (fGlobalTrigger) fGlobalTrigger->Clear();
829 if (fLocalTrigger) fLocalTrigger->Clear();
832 //____________________________________________
833 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
836 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
837 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
840 //___________________________________________
841 void AliMUON::SetChambersZ(const Float_t *Z)
843 // Set Z values for all chambers (tracking and trigger)
844 // from the array pointed to by "Z"
845 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
846 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
850 //___________________________________________
851 void AliMUON::SetChambersZToDefault()
853 // Set Z values for all chambers (tracking and trigger)
855 SetChambersZ(AliMUONConstants::DefaultChamberZ());
859 //___________________________________________
860 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
863 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
864 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
867 //___________________________________________
868 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
871 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
872 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
875 //___________________________________________
876 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
879 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
880 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
883 //___________________________________________
884 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
887 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
888 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
891 //___________________________________________
892 void AliMUON::SetMaxStepGas(Float_t p1)
897 //___________________________________________
898 void AliMUON::SetMaxStepAlu(Float_t p1)
903 //___________________________________________
904 void AliMUON::SetMaxDestepGas(Float_t p1)
909 //___________________________________________
910 void AliMUON::SetMaxDestepAlu(Float_t p1)
914 //___________________________________________
915 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
918 fAccMin=angmin*TMath::Pi()/180;
919 fAccMax=angmax*TMath::Pi()/180;
922 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
923 // Loop over 2 chambers in the station
924 for (Int_t stCH = 0; stCH < 2; stCH++) {
926 // Set chamber inner and outer radius according to acceptance cuts
927 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
928 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
933 //___________________________________________
934 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
936 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
939 //___________________________________________
940 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
942 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
945 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
947 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
950 void AliMUON::SetNsec(Int_t id, Int_t nsec)
952 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
956 //___________________________________________
960 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
961 Float_t eloss, Float_t tof, Int_t idvol)
964 // Calls the charge disintegration method of the current chamber and adds
965 // the simulated cluster to the root treee
968 Float_t newclust[6][500];
973 // Integrated pulse height on chamber
979 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
982 ((AliMUONChamber*) (*fChambers)[idvol])
983 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
985 // if (idvol == 6) printf("\n nnew %d \n", nnew);
988 for (Int_t i=0; i<nnew; i++) {
989 if (Int_t(newclust[3][i]) > 0) {
992 clhits[1] = Int_t(newclust[5][i]);
994 clhits[2] = Int_t(newclust[0][i]);
996 clhits[3] = Int_t(newclust[1][i]);
998 clhits[4] = Int_t(newclust[2][i]);
1000 clhits[5] = Int_t(newclust[3][i]);
1001 // Pad: chamber sector
1002 clhits[6] = Int_t(newclust[4][i]);
1009 //----------------------------------------------------------------------
1011 void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
1013 // keep galice.root for signal and name differently the file for
1014 // background when add! otherwise the track info for signal will be lost !
1016 static Bool_t first=kTRUE;
1018 char *addBackground = strstr(option,"Add");
1021 AliMUONChamber* iChamber;
1022 AliSegmentation* segmentation;
1027 TObjArray *list=new TObjArray;
1028 static TClonesArray *pAddress=0;
1029 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
1032 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
1033 AliHitMap** hitMap= new AliHitMap* [AliMUONConstants::NCh()];
1034 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
1035 if (addBackground ) {
1038 cout<<"filename"<<fFileName<<endl;
1039 file=new TFile(fFileName);
1040 cout<<"I have opened "<<fFileName<<" file "<<endl;
1041 fHits2 = new TClonesArray("AliMUONHit",1000 );
1042 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
1047 // Get Hits Tree header from file
1048 if(fHits2) fHits2->Clear();
1049 if(fPadHits2) fPadHits2->Clear();
1050 if(fTrH1) delete fTrH1;
1054 sprintf(treeName,"TreeH%d",bgrEvent);
1055 fTrH1 = (TTree*)gDirectory->Get(treeName);
1056 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
1059 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
1061 // Set branch addresses
1063 char branchname[20];
1064 sprintf(branchname,"%s",GetName());
1065 if (fTrH1 && fHits2) {
1066 branch = fTrH1->GetBranch(branchname);
1067 if (branch) branch->SetAddress(&fHits2);
1069 if (fTrH1 && fPadHits2) {
1070 branch = fTrH1->GetBranch("MUONCluster");
1071 if (branch) branch->SetAddress(&fPadHits2);
1074 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
1075 //printf("background - ntracks1 - %d\n",ntracks1);
1078 // loop over cathodes
1082 for (int icat=0; icat<2; icat++) {
1084 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
1085 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
1086 iChamber=(AliMUONChamber*) (*fChambers)[i];
1087 if (iChamber->Nsec()==1 && icat==1) {
1090 segmentation=iChamber->SegmentationModel(icat+1);
1092 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
1095 //printf("Start loop over tracks \n");
1100 TTree *treeH = gAlice->TreeH();
1101 Int_t ntracks =(Int_t) treeH->GetEntries();
1104 Float_t ** xhit = new Float_t * [AliMUONConstants::NCh()];
1105 for (jj=0; jj<AliMUONConstants::NCh(); jj++) xhit[jj] = new Float_t[2];
1106 Float_t ** yhit = new Float_t * [AliMUONConstants::NCh()];
1107 for (jj=0; jj<AliMUONConstants::NCh(); jj++) yhit[jj] = new Float_t[2];
1109 for (Int_t track=0; track<ntracks; track++) {
1110 gAlice->ResetHits();
1111 treeH->GetEvent(track);
1114 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
1116 mHit=(AliMUONHit*)pMUON->NextHit())
1118 Int_t nch = mHit->fChamber-1; // chamber number
1119 if (nch > AliMUONConstants::NCh()-1) continue;
1120 // if (nch > 9) continue;
1121 iChamber = &(pMUON->Chamber(nch));
1123 if (addBackground) {
1125 if (mHit->fParticle == kMuonPlus
1126 || mHit->fParticle == kMuonMinus) {
1127 xhit[nch][nmuon[nch]]=mHit->X();
1128 yhit[nch][nmuon[nch]]=mHit->Y();
1130 if (nmuon[nch] >2) printf("nmuon %d\n",nmuon[nch]);
1138 // Loop over pad hits
1139 for (AliMUONPadHit* mPad=
1140 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
1142 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
1144 Int_t cathode = mPad->fCathode; // cathode number
1145 Int_t ipx = mPad->fPadX; // pad number on X
1146 Int_t ipy = mPad->fPadY; // pad number on Y
1147 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1148 // printf("\n Pad: %d %d %d %d", ipx, ipy, cathode,nch);
1152 if (cathode != (icat+1)) continue;
1153 // fill the info array
1154 // Float_t thex, they, thez;
1155 segmentation=iChamber->SegmentationModel(cathode);
1156 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1157 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1158 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1160 new((*pAddress)[countadr++]) TVector(2);
1161 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1162 trinfo(0)=(Float_t)track;
1163 trinfo(1)=(Float_t)iqpad;
1169 if (mHit->fParticle == kMuonPlus ||
1170 mHit->fParticle == kMuonMinus) {
1171 digits[4]=mPad->fHitNumber;
1172 } else digits[4]=-1;
1174 AliMUONTransientDigit* pdigit;
1175 // build the list of fired pads and update the info
1176 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1178 list->AddAtAndExpand(
1179 new AliMUONTransientDigit(nch,digits),counter);
1181 hitMap[nch]->SetHit(ipx, ipy, counter);
1183 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1185 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1186 trlist->Add(&trinfo);
1188 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1190 (*pdigit).fSignal+=iqpad;
1191 (*pdigit).fPhysics+=iqpad;
1192 // update list of tracks
1193 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
1194 Int_t lastEntry=trlist->GetLast();
1195 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1196 TVector &ptrk=*pTrack;
1197 Int_t lastTrack = Int_t(ptrk(0));
1198 Int_t lastCharge = Int_t(ptrk(1));
1199 if (lastTrack==track) {
1201 trlist->RemoveAt(lastEntry);
1202 trinfo(0)=lastTrack;
1203 trinfo(1)=lastCharge;
1204 trlist->AddAt(&trinfo,lastEntry);
1206 trlist->Add(&trinfo);
1208 // check the track list
1209 Int_t nptracks=trlist->GetEntriesFast();
1211 for (Int_t tr=0;tr<nptracks;tr++) {
1212 TVector *ppTrack=(TVector*)trlist->At(tr);
1213 TVector &pptrk=*ppTrack;
1214 trk[tr] = Int_t(pptrk(0));
1215 chtrk[tr] = Int_t(pptrk(1));
1217 } // end if nptracks
1219 } //end loop over clusters
1223 // open the file with background
1225 if (addBackground) {
1226 ntracks =(Int_t)fTrH1->GetEntries();
1230 for (Int_t track=0; track<ntracks; track++) {
1232 if (fHits2) fHits2->Clear();
1233 if (fPadHits2) fPadHits2->Clear();
1235 fTrH1->GetEvent(track);
1239 for(int i=0;i<fHits2->GetEntriesFast();++i)
1241 mHit=(AliMUONHit*) (*fHits2)[i];
1242 Int_t nch = mHit->fChamber-1; // chamber number
1243 if (nch >9) continue;
1244 iChamber = &(pMUON->Chamber(nch));
1245 // Int_t rmin = (Int_t)iChamber->RInner();
1246 // Int_t rmax = (Int_t)iChamber->ROuter();
1247 Float_t xbgr=mHit->X();
1248 Float_t ybgr=mHit->Y();
1251 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1252 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1253 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
1254 if (dist<100) cond=kTRUE;
1256 if (!cond) continue;
1259 // Loop over pad hits
1260 for (AliMUONPadHit* mPad=
1261 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
1263 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
1265 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
1266 Int_t cathode = mPad->fCathode; // cathode number
1267 Int_t ipx = mPad->fPadX; // pad number on X
1268 Int_t ipy = mPad->fPadY; // pad number on Y
1269 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1271 if (cathode != (icat+1)) continue;
1272 printf("\n Pad: %d %d %d", ipx, ipy, cathode);
1274 // Float_t thex, they, thez;
1275 // segmentation=iChamber->SegmentationModel(cathode);
1276 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1277 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1278 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1279 new((*pAddress)[countadr++]) TVector(2);
1280 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1281 trinfo(0)=-1; // tag background
1290 AliMUONTransientDigit* pdigit;
1291 // build the list of fired pads and update the info
1292 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1293 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1295 hitMap[nch]->SetHit(ipx, ipy, counter);
1298 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1300 TObjArray *trlist=(TObjArray*)pdigit->
1302 trlist->Add(&trinfo);
1304 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1306 (*pdigit).fSignal+=iqpad;
1308 // update list of tracks
1309 TObjArray* trlist=(TObjArray*)pdigit->
1311 Int_t lastEntry=trlist->GetLast();
1312 TVector *pTrack=(TVector*)trlist->
1314 TVector &ptrk=*pTrack;
1315 Int_t lastTrack=Int_t(ptrk(0));
1316 if (lastTrack==-1) {
1319 trlist->Add(&trinfo);
1321 // check the track list
1322 Int_t nptracks=trlist->GetEntriesFast();
1324 for (Int_t tr=0;tr<nptracks;tr++) {
1325 TVector *ppTrack=(TVector*)trlist->At(tr);
1326 TVector &pptrk=*ppTrack;
1327 trk[tr]=Int_t(pptrk(0));
1328 chtrk[tr]=Int_t(pptrk(1));
1330 } // end if nptracks
1332 } //end loop over clusters
1335 //Int_t nentr2=list->GetEntriesFast();
1336 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1337 TTree *fAli=gAlice->TreeK();
1340 if (fAli) file =fAli->GetCurrentFile();
1342 } // if addBackground
1348 Int_t nentries=list->GetEntriesFast();
1350 for (Int_t nent=0;nent<nentries;nent++) {
1351 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
1352 if (address==0) continue;
1353 Int_t ich=address->fChamber;
1354 Int_t q=address->fSignal;
1355 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1357 // Digit Response (noise, threshold, saturation, ...)
1358 // if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1359 AliMUONResponse * response=iChamber->ResponseModel();
1360 q=response->DigitResponse(q);
1364 digits[0]=address->fPadX;
1365 digits[1]=address->fPadY;
1367 digits[3]=address->fPhysics;
1368 digits[4]=address->fHit;
1370 TObjArray* trlist=(TObjArray*)address->TrackList();
1371 Int_t nptracks=trlist->GetEntriesFast();
1372 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1374 // this was changed to accomodate the real number of tracks
1375 if (nptracks > 10) {
1376 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1380 printf("Attention - nptracks > 2 %d \n",nptracks);
1381 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1383 for (Int_t tr=0;tr<nptracks;tr++) {
1384 TVector *ppP=(TVector*)trlist->At(tr);
1385 if(!ppP ) printf("ppP - %p\n",ppP);
1387 tracks[tr]=Int_t(pp(0));
1388 charges[tr]=Int_t(pp(1));
1389 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
1390 } //end loop over list of tracks for one pad
1391 // Sort list of tracks according to charge
1393 SortTracks(tracks,charges,nptracks);
1395 if (nptracks < 10 ) {
1396 for (Int_t i=nptracks; i<10; i++) {
1403 pMUON->AddDigits(ich,tracks,charges,digits);
1406 //cout<<"I'm out of the loops for digitisation"<<endl;
1407 // gAlice->GetEvent(nev);
1408 gAlice->TreeD()->Fill();
1409 pMUON->ResetDigits();
1413 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
1421 } //end loop over cathodes
1424 sprintf(hname,"TreeD%d",nev);
1425 gAlice->TreeD()->Write(hname);
1427 gAlice->TreeD()->Reset();
1431 // gObjectTable->Print();
1434 void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1437 // Sort the list of tracks contributing to a given digit
1438 // Only the 3 most significant tracks are acctually sorted
1442 // Loop over signals, only 3 times
1447 Int_t idx[3] = {-2,-2,-2};
1448 Int_t jch[3] = {-2,-2,-2};
1449 Int_t jtr[3] = {-2,-2,-2};
1452 if (ntr<3) imax=ntr;
1454 for(i=0;i<imax;i++){
1460 if((i == 1 && j == idx[i-1])
1461 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1463 if(charges[j] > qmax) {
1471 jch[i]=charges[jmax];
1472 jtr[i]=tracks[jmax];
1489 //___________________________________________
1490 void AliMUON::Trigger(Int_t nev){
1491 // call the Trigger Algorithm and fill TreeR
1493 Int_t singlePlus[3] = {0,0,0};
1494 Int_t singleMinus[3] = {0,0,0};
1495 Int_t singleUndef[3] = {0,0,0};
1496 Int_t pairUnlike[3] = {0,0,0};
1497 Int_t pairLike[3] = {0,0,0};
1500 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1501 decision->Trigger();
1502 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1503 pairUnlike, pairLike);
1504 // add a local trigger in the list
1505 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
1508 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
1509 if(decision->GetITrigger(icirc)==1) {
1510 Int_t localtr[7]={0,0,0,0,0,0,0};
1511 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1512 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1514 localtr[1] = decision->GetStripX11(icirc);
1515 localtr[2] = decision->GetDev(icirc);
1516 localtr[3] = decision->GetStripY11(icirc);
1517 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1518 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1519 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1520 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1522 AddLocalTrigger(localtr); // add a local trigger in the list
1527 gAlice->TreeR()->Fill();
1530 sprintf(hname,"TreeR%d",nev);
1531 gAlice->TreeR()->Write(hname);
1532 gAlice->TreeR()->Reset();
1533 printf("\n End of trigger for event %d", nev);
1537 //____________________________________________
1538 void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1540 TClonesArray *dig1, *dig2;
1542 dig1 = new TClonesArray("AliMUONDigit",1000);
1543 dig2 = new TClonesArray("AliMUONDigit",1000);
1544 AliMUONDigit *digit;
1546 // Loop on chambers and on cathode planes
1549 for (Int_t ich=0;ich<10;ich++) {
1550 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1551 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1552 gAlice->ResetDigits();
1553 gAlice->TreeD()->GetEvent(lastEntry);
1554 TClonesArray *muonDigits = this->DigitsAddress(ich);
1555 ndig=muonDigits->GetEntriesFast();
1556 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1557 TClonesArray &lhits1 = *dig1;
1559 for (k=0; k<ndig; k++) {
1560 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1561 if (rec->TestTrack(digit->fTracks[0]))
1562 new(lhits1[n++]) AliMUONDigit(*digit);
1564 gAlice->ResetDigits();
1565 gAlice->TreeD()->GetEvent(lastEntry+1);
1566 muonDigits = this->DigitsAddress(ich);
1567 ndig=muonDigits->GetEntriesFast();
1568 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1569 TClonesArray &lhits2 = *dig2;
1572 for (k=0; k<ndig; k++) {
1573 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1574 if (rec->TestTrack(digit->fTracks[0]))
1575 new(lhits2[n++]) AliMUONDigit(*digit);
1579 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1580 rec->FindRawClusters();
1585 gAlice->TreeR()->Fill();
1588 sprintf(hname,"TreeR%d",nev);
1589 gAlice->TreeR()->Write(hname);
1590 gAlice->TreeR()->Reset();
1591 printf("\n End of cluster finding for event %d", nev);
1595 //gObjectTable->Print();
1599 void AliMUON::Streamer(TBuffer &R__b)
1601 // Stream an object of class AliMUON.
1602 AliMUONChamber *iChamber;
1603 AliMUONTriggerCircuit *iTriggerCircuit;
1604 AliSegmentation *segmentation;
1605 AliMUONResponse *response;
1606 TClonesArray *digitsaddress;
1607 TClonesArray *rawcladdress;
1609 if (R__b.IsReading()) {
1610 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1611 AliDetector::Streamer(R__b);
1613 R__b >> fPadHits; // diff
1614 R__b >> fNLocalTrigger;
1615 R__b >> fLocalTrigger;
1616 R__b >> fNGlobalTrigger;
1617 R__b >> fGlobalTrigger;
1619 R__b >> fRawClusters;
1620 R__b.ReadArray(fNdch);
1621 R__b.ReadArray(fNrawch);
1626 R__b >> fTriggerCircuits;
1627 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1628 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1629 iTriggerCircuit->Streamer(R__b);
1631 // Stream chamber related information
1632 for (i =0; i<AliMUONConstants::NCh(); i++) {
1633 iChamber=(AliMUONChamber*) (*fChambers)[i];
1634 iChamber->Streamer(R__b);
1635 if (iChamber->Nsec()==1) {
1636 segmentation=iChamber->SegmentationModel(1);
1638 segmentation->Streamer(R__b);
1640 segmentation=iChamber->SegmentationModel(1);
1642 segmentation->Streamer(R__b);
1644 segmentation=iChamber->SegmentationModel(2);
1645 segmentation->Streamer(R__b);
1647 response=iChamber->ResponseModel();
1649 response->Streamer(R__b);
1650 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1651 digitsaddress->Streamer(R__b);
1652 if (i < AliMUONConstants::NTrackingCh()) {
1653 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1654 rawcladdress->Streamer(R__b);
1659 R__b.WriteVersion(AliMUON::IsA());
1660 AliDetector::Streamer(R__b);
1662 R__b << fPadHits; // diff
1663 R__b << fNLocalTrigger;
1664 R__b << fLocalTrigger;
1665 R__b << fNGlobalTrigger;
1666 R__b << fGlobalTrigger;
1668 R__b << fRawClusters;
1669 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1670 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1677 R__b << fTriggerCircuits;
1678 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1679 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1680 iTriggerCircuit->Streamer(R__b);
1682 for (i =0; i<AliMUONConstants::NCh(); i++) {
1683 iChamber=(AliMUONChamber*) (*fChambers)[i];
1684 iChamber->Streamer(R__b);
1685 if (iChamber->Nsec()==1) {
1686 segmentation=iChamber->SegmentationModel(1);
1688 segmentation->Streamer(R__b);
1690 segmentation=iChamber->SegmentationModel(1);
1692 segmentation->Streamer(R__b);
1693 segmentation=iChamber->SegmentationModel(2);
1695 segmentation->Streamer(R__b);
1697 response=iChamber->ResponseModel();
1699 response->Streamer(R__b);
1700 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1701 digitsaddress->Streamer(R__b);
1702 if (i < AliMUONConstants::NTrackingCh()) {
1703 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1704 rawcladdress->Streamer(R__b);
1709 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1712 // Initialise the pad iterator
1713 // Return the address of the first padhit for hit
1714 TClonesArray *theClusters = clusters;
1715 Int_t nclust = theClusters->GetEntriesFast();
1716 if (nclust && hit->fPHlast > 0) {
1717 AliMUON::fMaxIterPad=hit->fPHlast;
1718 AliMUON::fCurIterPad=hit->fPHfirst;
1719 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1725 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1727 AliMUON::fCurIterPad++;
1728 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1729 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1736 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1738 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1740 TTree *treeR = gAlice->TreeR();
1741 Int_t nent=(Int_t)treeR->GetEntries();
1742 treeR->GetEvent(nent-2+icathod-1);
1743 //treeR->GetEvent(icathod);
1744 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1746 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1747 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1752 AliMUON& AliMUON::operator = (const AliMUON& rhs)