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.33 2000/10/09 14:01:57 morsch
18 Unused variables removed.
20 Revision 1.32 2000/10/06 09:08:10 morsch
21 Built geometry includes slat geometry for event display.
23 Revision 1.31 2000/10/02 21:28:08 fca
24 Removal of useless dependecies via forward declarations
26 Revision 1.30 2000/10/02 16:58:29 egangler
27 Cleaning of the code :
30 -> some useless includes removed or replaced by "class" statement
32 Revision 1.29 2000/07/28 13:49:38 morsch
33 SetAcceptance defines inner and outer chamber radii according to angular acceptance.
34 Can be used for simple acceptance studies.
36 Revision 1.28 2000/07/22 16:43:15 morsch
37 Same comment as before, but now done correctly I hope (sorry it's Saturday evening)
39 Revision 1.27 2000/07/22 16:36:50 morsch
40 Change order of indices in creation (new) of xhit and yhit
42 Revision 1.26 2000/07/03 11:54:57 morsch
43 AliMUONSegmentation and AliMUONHitMap have been replaced by AliSegmentation and AliHitMap in STEER
44 The methods GetPadIxy and GetPadXxy of AliMUONSegmentation have changed name to GetPadI and GetPadC.
46 Revision 1.25 2000/06/29 12:34:09 morsch
47 AliMUONSegmentation class has been made independent of AliMUONChamber. This makes
48 it usable with any other geometry class. The link to the object to which it belongs is
49 established via an index. This assumes that there exists a global geometry manager
50 from which the pointer to the parent object can be obtained (in our case gAlice).
52 Revision 1.24 2000/06/28 15:16:35 morsch
53 (1) Client code adapted to new method signatures in AliMUONSegmentation (see comments there)
54 to allow development of slat-muon chamber simulation and reconstruction code in the MUON
55 framework. The changes should have no side effects (mostly dummy arguments).
56 (2) Hit disintegration uses 3-dim hit coordinates to allow simulation
57 of chambers with overlapping modules (MakePadHits, Disintegration).
59 Revision 1.23 2000/06/28 12:19:17 morsch
60 More consequent seperation of global input data services (AliMUONClusterInput singleton) and the
61 cluster and hit reconstruction algorithms in AliMUONClusterFinderVS.
62 AliMUONClusterFinderVS becomes the base class for clustering and hit reconstruction.
63 It requires two cathode planes. Small modifications in the code will make it usable for
64 one cathode plane and, hence, more general (for test beam data).
65 AliMUONClusterFinder is now obsolete.
67 Revision 1.22 2000/06/28 08:06:10 morsch
68 Avoid global variables in AliMUONClusterFinderVS by seperating the input data for the fit from the
69 algorithmic part of the class. Input data resides inside the AliMUONClusterInput singleton.
70 It also naturally takes care of the TMinuit instance.
72 Revision 1.21 2000/06/27 08:54:41 morsch
73 Problems with on constant array sizes (in hitMap, nmuon, xhit, yhit) corrected.
75 Revision 1.20 2000/06/26 14:02:38 morsch
76 Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
78 Revision 1.19 2000/06/22 13:40:51 morsch
79 scope problem on HP, "i" declared once
80 pow changed to TMath::Power (PH, AM)
82 Revision 1.18 2000/06/15 07:58:48 morsch
83 Code from MUON-dev joined
85 Revision 1.14.4.17 2000/06/14 14:36:46 morsch
86 - add TriggerCircuit (PC)
87 - add GlobalTrigger and LocalTrigger and specific methods (PC)
89 Revision 1.14.4.16 2000/06/09 21:20:28 morsch
90 Most coding rule violations corrected
92 Revision 1.14.4.15 2000/05/02 09:54:32 morsch
93 RULE RN17 violations corrected
95 Revision 1.14.4.12 2000/04/26 12:25:02 morsch
96 Code revised by P. Crochet:
97 - Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
98 - ToF included in the method MakePadHits
99 - inner radius of flange between beam shielding and trigger corrected
100 - Trigger global volume updated (according to the new geometry)
102 Revision 1.14.4.11 2000/04/19 19:42:08 morsch
103 Some changes of variable names curing viols and methods concerning
104 correlated clusters removed.
106 Revision 1.14.4.10 2000/03/22 16:44:07 gosset
107 Memory leak suppressed in function Digitise:
108 p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
110 Revision 1.14.4.9 2000/03/20 18:15:25 morsch
111 Positions of trigger chambers corrected (P.C.)
113 Revision 1.14.4.8 2000/02/21 15:38:01 morsch
114 Call to AddHitList introduced to make this version compatible with head.
116 Revision 1.14.4.7 2000/02/20 07:45:53 morsch
117 Bugs in Trigger part of BuildGeomemetry corrected (P.C)
119 Revision 1.14.4.6 2000/02/17 14:28:54 morsch
120 Trigger included into initialization and digitization
122 Revision 1.14.4.5 2000/02/15 10:02:58 morsch
123 Log messages of previous revisions added
125 Revision 1.14.4.2 2000/02/04 10:57:34 gosset
126 Z position of the chambers:
127 it was the Z position of the stations;
128 it is now really the Z position of the chambers.
129 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
130 !!!! AND "AliMUONChamber::ZPosition"
131 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
132 !!!! AND "AliMUONChamber::Z"
134 Revision 1.14.4.3 2000/02/04 16:19:04 gosset
135 Correction for mis-spelling of NCH
137 Revision 1.14.4.4 2000/02/15 09:43:38 morsch
143 ///////////////////////////////////////////////
144 // Manager and hits classes for set:MUON //
145 ////////////////////////////////////////////////
149 #include <TRotMatrix.h>
150 #include <TGeometry.h>
156 #include <TObjArray.h>
158 #include <TParticle.h>
164 #include <TDirectory.h>
165 #include <TObjectTable.h>
170 #include "AliMUONHit.h"
171 #include "AliMUONPadHit.h"
172 #include "AliMUONDigit.h"
173 #include "AliMUONTransientDigit.h"
174 #include "AliMUONRawCluster.h"
175 #include "AliMUONLocalTrigger.h"
176 #include "AliMUONGlobalTrigger.h"
177 #include "AliMUONTriggerCircuit.h"
178 #include "AliHitMap.h"
179 #include "AliMUONHitMapA1.h"
180 #include "AliMUONChamberTrigger.h"
181 #include "AliMUONConstants.h"
182 #include "AliMUONClusterFinderVS.h"
183 #include "AliMUONTriggerDecision.h"
186 #include "AliMUONClusterInput.h"
187 #include "iostream.h"
188 #include "AliCallf77.h"
189 #include "AliConst.h"
191 // Defaults parameters for Z positions of chambers
192 // taken from values for "stations" in AliMUON::AliMUON
193 // const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
194 // and from array "dstation" in AliMUONv1::CreateGeometry
195 // Float_t dstation[5]={20., 20., 20, 20., 20.};
196 // for tracking chambers,
197 // according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
198 // for the first and second chambers in the station, respectively,
199 // and from "DTPLANES" in AliMUONv1::CreateGeometry
200 // const Float_t DTPLANES = 15.;
201 // for trigger chambers,
202 // according to (Z1 = zch) and (Z2 = zch + DTPLANES)
203 // for the first and second chambers in the station, respectively
206 //___________________________________________
214 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
227 //___________________________________________
228 AliMUON::AliMUON(const char *name, const char *title)
229 : AliDetector(name,title)
233 <img src="gif/alimuon.gif">
237 fHits = new TClonesArray("AliMUONHit",1000);
238 gAlice->AddHitList(fHits);
239 fPadHits = new TClonesArray("AliMUONPadHit",10000);
243 fNdch = new Int_t[AliMUONConstants::NCh()];
245 fDchambers = new TObjArray(AliMUONConstants::NCh());
249 for (i=0; i<AliMUONConstants::NCh() ;i++) {
250 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
254 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
256 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
258 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
259 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
263 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
265 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
268 SetMarkerColor(kRed);
276 fChambers = new TObjArray(AliMUONConstants::NCh());
278 // Loop over stations
279 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
280 // Loop over 2 chambers in the station
281 for (Int_t stCH = 0; stCH < 2; stCH++) {
284 // Default Parameters for Muon Tracking Stations
289 if (ch < AliMUONConstants::NTrackingCh()) {
290 (*fChambers)[ch] = new AliMUONChamber(ch);
292 (*fChambers)[ch] = new AliMUONChamberTrigger(ch);
295 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
298 // Default values for Z of chambers
299 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
301 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
302 // Set chamber inner and outer radius to default
303 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
304 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
306 } // Chamber stCH (0, 1) in
307 } // Station st (0...)
320 // cp new design of AliMUONTriggerDecision
321 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
322 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
323 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
325 // cp new design of AliMUONTriggerDecision
329 //___________________________________________
330 AliMUON::AliMUON(const AliMUON& rMUON)
332 // Dummy copy constructor
339 printf("Calling AliMUON destructor !!!\n");
346 delete fGlobalTrigger;
349 delete fLocalTrigger;
352 for (i=0;i<AliMUONConstants::NCh();i++) {
353 delete (*fDchambers)[i];
358 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
359 delete (*fRawClusters)[i];
364 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
365 delete (*fTriggerCircuits)[circ];
367 delete fTriggerCircuits;
370 //___________________________________________
371 void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
373 TClonesArray &lhits = *fHits;
374 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
376 //___________________________________________
377 void AliMUON::AddPadHit(Int_t *clhits)
379 TClonesArray &lclusters = *fPadHits;
380 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
382 //_____________________________________________________________________________
383 void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
386 // Add a MUON digit to the list
389 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
390 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
393 //_____________________________________________________________________________
394 void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
397 // Add a MUON digit to the list
400 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
401 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
404 //___________________________________________
405 void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
407 Int_t *pairUnlike, Int_t *pairLike)
409 // add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
410 TClonesArray &globalTrigger = *fGlobalTrigger;
411 new(globalTrigger[fNGlobalTrigger++])
412 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
415 //___________________________________________
416 void AliMUON::AddLocalTrigger(Int_t *localtr)
418 // add a MUON Local Trigger to the list
419 TClonesArray &localTrigger = *fLocalTrigger;
420 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
423 //___________________________________________
424 void AliMUON::BuildGeometry()
426 TNode *node, *nodeF, *top, *nodeS;
427 const int kColorMUON = kBlue;
428 const int kColorMUON2 = kYellow;
429 const int kColorMUON3 = kBlue;
431 top=gAlice->GetGeometry()->GetNode("alice");
434 // z-Positions of Chambers
435 const Float_t kCz[7]={511., 686., 971., 1245., 1445., 1600, 1700.};
436 // inner diameter (Xlenght for trigger chamber -> active area)
437 const Float_t kDmin[7]={ 35., 47., 67., 86., 100., 544., 544.};
438 // outer diameter (Ylenght for trigger chamber -> active area)
439 const Float_t kDmax[7]={183., 245., 346., 520., 520., 612., 612.};
441 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
442 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
443 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
444 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
446 Float_t rmin, rmax, dx, dy, dz, dr, xpos, ypos, zpos;
447 Float_t dzc1=4.; // tracking chambers
448 Float_t dzc2=15.; // trigger chambers
449 Float_t hole=102.; // x-y hole around beam pipe for trig. chambers
450 Float_t zscale; // scaling parameter trigger chambers
451 Float_t halfx, halfy;
452 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[9];
453 char nameSense1[9], nameSense2[9];
454 for (Int_t i=0; i<7; i++) {
455 for (Int_t j=0; j<2; j++) {
457 if (i<5) { // tracking chambers
470 sprintf(nameChamber,"C_MUON%d",id);
471 sprintf(nameSense,"S_MUON%d",id);
472 sprintf(nameSense1,"S1_MUON%d",id);
473 sprintf(nameSense2,"S2_MUON%d",id);
474 sprintf(nameFrame,"F_MUON%d",id);
475 if (i<3) { // tracking chambers
476 rmin = kDmin[i]/2.-3;
477 rmax = kDmax[i]/2.+3;
478 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
481 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
485 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
487 sprintf(nameNode,"MUON%d",100+id);
488 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,zpos,"");
489 node->SetLineColor(kColorMUON);
492 sprintf(nameNode,"MUON%d",200+id);
493 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
494 node->SetLineColor(kColorMUON);
497 sprintf(nameNode,"MUON%d",300+id);
498 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
499 nodeF->SetLineColor(kColorMUON);
501 sprintf(nameNode,"MUON%d",400+id);
502 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
503 nodeF->SetLineColor(kColorMUON);
505 sprintf(nameNode,"MUON%d",500+id);
506 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
507 nodeF->SetLineColor(kColorMUON);
509 sprintf(nameNode,"MUON%d",600+id);
510 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
511 nodeF->SetLineColor(kColorMUON);
512 } else if (i == 3 || i == 4) {
513 Int_t npcb[7] = {7, 7, 6, 6, 5, 4, 3};
517 Float_t ypos1=-0.75+20.;
518 Float_t ypos2= 0.75-20.;
520 new TBRIK(nameChamber,"Mother","void",340,340,5.);
522 sprintf(nameNode,"MUON%d",100+id);
523 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
524 node->SetLineColor(kBlack);
529 for (Int_t j=0; j<7; j++)
531 sprintf(nameSlat,"SLAT%d",100*id+j);
532 new TBRIK(nameSlat,"Slat Module","void",20.*npcb[j],20.,0.25);
537 color = TMath::Even(j) ? kColorMUON2 : kColorMUON3;
539 sprintf(nameNode,"SLAT%d",100*id+j);
541 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos1,0,"");
542 nodeSlat->SetLineColor(color);
545 sprintf(nameNode,"SLAT%d",100*id+j+7);
547 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos1,0,"");
548 nodeSlat->SetLineColor(color);
550 color = TMath::Even(j) ? kColorMUON3 : kColorMUON2;
551 sprintf(nameNode,"SLAT%d",100*id+j+14);
553 new TNode(nameNode,"Slat Module",nameSlat,xpos,ypos2,0,"");
554 nodeSlat->SetLineColor(color);
557 sprintf(nameNode,"SLAT%d",100*id+j+21);
559 new TNode(nameNode,"Slat Module",nameSlat,-xpos,ypos2,0,"");
560 nodeSlat->SetLineColor(color);
568 Float_t xsize=kDmin[i]*zscale;
569 Float_t ysize=kDmax[i]*zscale;
570 Float_t holeScaled=hole*zscale;
574 new TBRIK(nameChamber,"Mother","void",halfx,halfy,0.25);
576 sprintf(nameNode,"MUON%d",100+id);
577 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
578 node->SetLineColor(kColorMUON2);
581 // up/down of beam pipe
583 halfy=(ysize/2.-holeScaled/2.)/2.;
584 new TBRIK(nameSense,"Sens. region","void",halfx,halfy,0.25);
587 ypos=holeScaled/2.+((ysize/2.-holeScaled/2.)/2.);
588 sprintf(nameNode,"MUON%d",200+id);
589 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
590 nodeS->SetLineColor(kColorMUON2);
594 sprintf(nameNode,"MUON%d",300+id);
595 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
596 nodeS->SetLineColor(kColorMUON2);
598 // left/right of beam pipe
599 halfx=(xsize/2.-holeScaled/2.)/2.;
601 new TBRIK(nameSense1,"Sens. region","void",halfx,halfy,0.25);
604 xpos=holeScaled/2.+((xsize/2.-holeScaled/2.)/2.);
605 sprintf(nameNode,"MUON%d",400+id);
606 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
607 nodeS->SetLineColor(kColorMUON2);
611 sprintf(nameNode,"MUON%d",500+id);
612 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
613 nodeS->SetLineColor(kColorMUON2);
618 new TBRIK(nameSense2,"Sens. region","void",halfx,halfy,0.25);
621 xpos=holeScaled/2.-halfx;
623 sprintf(nameNode,"MUON%d",600+id);
624 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
625 nodeS->SetLineColor(kColorMUON2);
629 sprintf(nameNode,"MUON%d",700+id);
630 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
631 nodeS->SetLineColor(kColorMUON2);
635 sprintf(nameNode,"MUON%d",800+id);
636 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
637 nodeS->SetLineColor(kColorMUON2);
641 sprintf(nameNode,"MUON%d",900+id);
642 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
643 nodeS->SetLineColor(kColorMUON2);
650 //___________________________________________
651 Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
656 //___________________________________________
657 void AliMUON::MakeBranch(Option_t* option)
659 // Create Tree branches for the MUON.
660 const Int_t kBufferSize = 4000;
662 sprintf(branchname,"%sCluster",GetName());
664 AliDetector::MakeBranch(option);
666 if (fPadHits && gAlice->TreeH()) {
667 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
668 printf("Making Branch %s for clusters\n",branchname);
671 // one branch for digits per chamber
674 for (i=0; i<AliMUONConstants::NCh() ;i++) {
675 sprintf(branchname,"%sDigits%d",GetName(),i+1);
677 if (fDchambers && gAlice->TreeD()) {
678 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
679 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
683 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
685 // one branch for raw clusters per chamber
686 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
687 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
689 if (fRawClusters && gAlice->TreeR()) {
690 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
691 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
695 // one branch for global trigger
696 sprintf(branchname,"%sGlobalTrigger",GetName());
697 if (fGlobalTrigger && gAlice->TreeR()) {
698 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
699 printf("Making Branch %s for Global Trigger\n",branchname);
701 // one branch for local trigger
702 sprintf(branchname,"%sLocalTrigger",GetName());
703 if (fLocalTrigger && gAlice->TreeR()) {
704 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
705 printf("Making Branch %s for Local Trigger\n",branchname);
710 //___________________________________________
711 void AliMUON::SetTreeAddress()
713 // Set branch address for the Hits and Digits Tree.
715 AliDetector::SetTreeAddress();
718 TTree *treeH = gAlice->TreeH();
719 TTree *treeD = gAlice->TreeD();
720 TTree *treeR = gAlice->TreeR();
724 branch = treeH->GetBranch("MUONCluster");
725 if (branch) branch->SetAddress(&fPadHits);
730 for (int i=0; i<AliMUONConstants::NCh(); i++) {
731 sprintf(branchname,"%sDigits%d",GetName(),i+1);
733 branch = treeD->GetBranch(branchname);
734 if (branch) branch->SetAddress(&((*fDchambers)[i]));
739 // printf("SetTreeAddress --- treeR address %p \n",treeR);
742 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
743 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
745 branch = treeR->GetBranch(branchname);
746 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
751 branch = treeR->GetBranch("MUONLocalTrigger");
752 if (branch) branch->SetAddress(&fLocalTrigger);
754 if (fGlobalTrigger) {
755 branch = treeR->GetBranch("MUONGlobalTrigger");
756 if (branch) branch->SetAddress(&fGlobalTrigger);
760 //___________________________________________
761 void AliMUON::ResetHits()
763 // Reset number of clusters and the cluster array for this detector
764 AliDetector::ResetHits();
766 if (fPadHits) fPadHits->Clear();
769 //____________________________________________
770 void AliMUON::ResetDigits()
773 // Reset number of digits and the digits array for this detector
775 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
776 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
777 if (fNdch) fNdch[i]=0;
780 //____________________________________________
781 void AliMUON::ResetRawClusters()
784 // Reset number of raw clusters and the raw clust array for this detector
786 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
787 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
788 if (fNrawch) fNrawch[i]=0;
792 //____________________________________________
793 void AliMUON::ResetTrigger()
795 // Reset Local and Global Trigger
797 if (fGlobalTrigger) fGlobalTrigger->Clear();
799 if (fLocalTrigger) fLocalTrigger->Clear();
802 //____________________________________________
803 void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
806 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
807 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
810 //___________________________________________
811 void AliMUON::SetChambersZ(const Float_t *Z)
813 // Set Z values for all chambers (tracking and trigger)
814 // from the array pointed to by "Z"
815 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
816 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
820 //___________________________________________
821 void AliMUON::SetChambersZToDefault()
823 // Set Z values for all chambers (tracking and trigger)
825 SetChambersZ(AliMUONConstants::DefaultChamberZ());
829 //___________________________________________
830 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
833 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
834 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
837 //___________________________________________
838 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
841 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
842 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
845 //___________________________________________
846 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
849 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
850 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
853 //___________________________________________
854 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
857 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
858 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
861 //___________________________________________
862 void AliMUON::SetMaxStepGas(Float_t p1)
867 //___________________________________________
868 void AliMUON::SetMaxStepAlu(Float_t p1)
873 //___________________________________________
874 void AliMUON::SetMaxDestepGas(Float_t p1)
879 //___________________________________________
880 void AliMUON::SetMaxDestepAlu(Float_t p1)
884 //___________________________________________
885 void AliMUON::SetAcceptance(Bool_t acc, Float_t angmin, Float_t angmax)
888 fAccMin=angmin*TMath::Pi()/180;
889 fAccMax=angmax*TMath::Pi()/180;
892 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
893 // Loop over 2 chambers in the station
894 for (Int_t stCH = 0; stCH < 2; stCH++) {
896 // Set chamber inner and outer radius according to acceptance cuts
897 Chamber(ch).SetRInner(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMin));
898 Chamber(ch).SetROuter(AliMUONConstants::DefaultChamberZ(ch)*TMath::Tan(fAccMax));
903 //___________________________________________
904 void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliSegmentation *segmentation)
906 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
909 //___________________________________________
910 void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
912 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
915 void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinderVS *reconst)
917 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
920 void AliMUON::SetNsec(Int_t id, Int_t nsec)
922 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
926 //___________________________________________
930 void AliMUON::MakePadHits(Float_t xhit,Float_t yhit, Float_t zhit,
931 Float_t eloss, Float_t tof, Int_t idvol)
934 // Calls the charge disintegration method of the current chamber and adds
935 // the simulated cluster to the root treee
938 Float_t newclust[6][500];
943 // Integrated pulse height on chamber
949 // if (idvol == 6) printf("\n ->Disintegration %f %f %f", xhit, yhit, eloss );
952 ((AliMUONChamber*) (*fChambers)[idvol])
953 ->DisIntegration(eloss, tof, xhit, yhit, zhit, nnew, newclust);
955 // if (idvol == 6) printf("\n nnew %d \n", nnew);
958 for (Int_t i=0; i<nnew; i++) {
959 if (Int_t(newclust[3][i]) > 0) {
962 clhits[1] = Int_t(newclust[5][i]);
964 clhits[2] = Int_t(newclust[0][i]);
966 clhits[3] = Int_t(newclust[1][i]);
968 clhits[4] = Int_t(newclust[2][i]);
970 clhits[5] = Int_t(newclust[3][i]);
971 // Pad: chamber sector
972 clhits[6] = Int_t(newclust[4][i]);
979 //----------------------------------------------------------------------
981 void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
983 // keep galice.root for signal and name differently the file for
984 // background when add! otherwise the track info for signal will be lost !
986 static Bool_t first=kTRUE;
988 char *addBackground = strstr(option,"Add");
991 AliMUONChamber* iChamber;
992 AliSegmentation* segmentation;
997 TObjArray *list=new TObjArray;
998 static TClonesArray *pAddress=0;
999 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
1002 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
1003 AliHitMap** hitMap= new AliHitMap* [AliMUONConstants::NCh()];
1004 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
1005 if (addBackground ) {
1008 cout<<"filename"<<fFileName<<endl;
1009 file=new TFile(fFileName);
1010 cout<<"I have opened "<<fFileName<<" file "<<endl;
1011 fHits2 = new TClonesArray("AliMUONHit",1000 );
1012 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
1017 // Get Hits Tree header from file
1018 if(fHits2) fHits2->Clear();
1019 if(fPadHits2) fPadHits2->Clear();
1020 if(fTrH1) delete fTrH1;
1024 sprintf(treeName,"TreeH%d",bgrEvent);
1025 fTrH1 = (TTree*)gDirectory->Get(treeName);
1026 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
1029 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
1031 // Set branch addresses
1033 char branchname[20];
1034 sprintf(branchname,"%s",GetName());
1035 if (fTrH1 && fHits2) {
1036 branch = fTrH1->GetBranch(branchname);
1037 if (branch) branch->SetAddress(&fHits2);
1039 if (fTrH1 && fPadHits2) {
1040 branch = fTrH1->GetBranch("MUONCluster");
1041 if (branch) branch->SetAddress(&fPadHits2);
1044 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
1045 //printf("background - ntracks1 - %d\n",ntracks1);
1048 // loop over cathodes
1052 for (int icat=0; icat<2; icat++) {
1054 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
1055 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
1056 iChamber=(AliMUONChamber*) (*fChambers)[i];
1057 if (iChamber->Nsec()==1 && icat==1) {
1060 segmentation=iChamber->SegmentationModel(icat+1);
1062 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
1065 //printf("Start loop over tracks \n");
1070 TTree *treeH = gAlice->TreeH();
1071 Int_t ntracks =(Int_t) treeH->GetEntries();
1074 Float_t ** xhit = new Float_t * [AliMUONConstants::NCh()];
1075 for (jj=0; jj<AliMUONConstants::NCh(); jj++) xhit[jj] = new Float_t[2];
1076 Float_t ** yhit = new Float_t * [AliMUONConstants::NCh()];
1077 for (jj=0; jj<AliMUONConstants::NCh(); jj++) yhit[jj] = new Float_t[2];
1079 for (Int_t track=0; track<ntracks; track++) {
1080 gAlice->ResetHits();
1081 treeH->GetEvent(track);
1084 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
1086 mHit=(AliMUONHit*)pMUON->NextHit())
1088 Int_t nch = mHit->fChamber-1; // chamber number
1089 if (nch > AliMUONConstants::NCh()-1) continue;
1090 // if (nch > 9) continue;
1091 iChamber = &(pMUON->Chamber(nch));
1093 if (addBackground) {
1095 if (mHit->fParticle == kMuonPlus
1096 || mHit->fParticle == kMuonMinus) {
1097 xhit[nch][nmuon[nch]]=mHit->X();
1098 yhit[nch][nmuon[nch]]=mHit->Y();
1100 if (nmuon[nch] >2) printf("nmuon %d\n",nmuon[nch]);
1108 // Loop over pad hits
1109 for (AliMUONPadHit* mPad=
1110 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
1112 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
1114 Int_t cathode = mPad->fCathode; // cathode number
1115 Int_t ipx = mPad->fPadX; // pad number on X
1116 Int_t ipy = mPad->fPadY; // pad number on Y
1117 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1118 // printf("\n Pad: %d %d %d %d", ipx, ipy, cathode,nch);
1122 if (cathode != (icat+1)) continue;
1123 // fill the info array
1124 // Float_t thex, they, thez;
1125 segmentation=iChamber->SegmentationModel(cathode);
1126 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1127 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1128 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1130 new((*pAddress)[countadr++]) TVector(2);
1131 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1132 trinfo(0)=(Float_t)track;
1133 trinfo(1)=(Float_t)iqpad;
1139 if (mHit->fParticle == kMuonPlus ||
1140 mHit->fParticle == kMuonMinus) {
1141 digits[4]=mPad->fHitNumber;
1142 } else digits[4]=-1;
1144 AliMUONTransientDigit* pdigit;
1145 // build the list of fired pads and update the info
1146 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1148 list->AddAtAndExpand(
1149 new AliMUONTransientDigit(nch,digits),counter);
1151 hitMap[nch]->SetHit(ipx, ipy, counter);
1153 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1155 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1156 trlist->Add(&trinfo);
1158 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1160 (*pdigit).fSignal+=iqpad;
1161 (*pdigit).fPhysics+=iqpad;
1162 // update list of tracks
1163 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
1164 Int_t lastEntry=trlist->GetLast();
1165 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1166 TVector &ptrk=*pTrack;
1167 Int_t lastTrack = Int_t(ptrk(0));
1168 Int_t lastCharge = Int_t(ptrk(1));
1169 if (lastTrack==track) {
1171 trlist->RemoveAt(lastEntry);
1172 trinfo(0)=lastTrack;
1173 trinfo(1)=lastCharge;
1174 trlist->AddAt(&trinfo,lastEntry);
1176 trlist->Add(&trinfo);
1178 // check the track list
1179 Int_t nptracks=trlist->GetEntriesFast();
1181 for (Int_t tr=0;tr<nptracks;tr++) {
1182 TVector *ppTrack=(TVector*)trlist->At(tr);
1183 TVector &pptrk=*ppTrack;
1184 trk[tr] = Int_t(pptrk(0));
1185 chtrk[tr] = Int_t(pptrk(1));
1187 } // end if nptracks
1189 } //end loop over clusters
1193 // open the file with background
1195 if (addBackground) {
1196 ntracks =(Int_t)fTrH1->GetEntries();
1200 for (Int_t track=0; track<ntracks; track++) {
1202 if (fHits2) fHits2->Clear();
1203 if (fPadHits2) fPadHits2->Clear();
1205 fTrH1->GetEvent(track);
1209 for(int i=0;i<fHits2->GetEntriesFast();++i)
1211 mHit=(AliMUONHit*) (*fHits2)[i];
1212 Int_t nch = mHit->fChamber-1; // chamber number
1213 if (nch >9) continue;
1214 iChamber = &(pMUON->Chamber(nch));
1215 // Int_t rmin = (Int_t)iChamber->RInner();
1216 // Int_t rmax = (Int_t)iChamber->ROuter();
1217 Float_t xbgr=mHit->X();
1218 Float_t ybgr=mHit->Y();
1221 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1222 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1223 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
1224 if (dist<100) cond=kTRUE;
1226 if (!cond) continue;
1229 // Loop over pad hits
1230 for (AliMUONPadHit* mPad=
1231 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
1233 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
1235 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
1236 Int_t cathode = mPad->fCathode; // cathode number
1237 Int_t ipx = mPad->fPadX; // pad number on X
1238 Int_t ipy = mPad->fPadY; // pad number on Y
1239 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
1241 if (cathode != (icat+1)) continue;
1242 printf("\n Pad: %d %d %d", ipx, ipy, cathode);
1244 // Float_t thex, they, thez;
1245 // segmentation=iChamber->SegmentationModel(cathode);
1246 // segmentation->GetPadC(ipx,ipy,thex,they,thez);
1247 // Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1248 // if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
1249 new((*pAddress)[countadr++]) TVector(2);
1250 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1251 trinfo(0)=-1; // tag background
1260 AliMUONTransientDigit* pdigit;
1261 // build the list of fired pads and update the info
1262 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1263 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1265 hitMap[nch]->SetHit(ipx, ipy, counter);
1268 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
1270 TObjArray *trlist=(TObjArray*)pdigit->
1272 trlist->Add(&trinfo);
1274 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
1276 (*pdigit).fSignal+=iqpad;
1278 // update list of tracks
1279 TObjArray* trlist=(TObjArray*)pdigit->
1281 Int_t lastEntry=trlist->GetLast();
1282 TVector *pTrack=(TVector*)trlist->
1284 TVector &ptrk=*pTrack;
1285 Int_t lastTrack=Int_t(ptrk(0));
1286 if (lastTrack==-1) {
1289 trlist->Add(&trinfo);
1291 // check the track list
1292 Int_t nptracks=trlist->GetEntriesFast();
1294 for (Int_t tr=0;tr<nptracks;tr++) {
1295 TVector *ppTrack=(TVector*)trlist->At(tr);
1296 TVector &pptrk=*ppTrack;
1297 trk[tr]=Int_t(pptrk(0));
1298 chtrk[tr]=Int_t(pptrk(1));
1300 } // end if nptracks
1302 } //end loop over clusters
1305 //Int_t nentr2=list->GetEntriesFast();
1306 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1307 TTree *fAli=gAlice->TreeK();
1310 if (fAli) file =fAli->GetCurrentFile();
1312 } // if addBackground
1318 Int_t nentries=list->GetEntriesFast();
1320 for (Int_t nent=0;nent<nentries;nent++) {
1321 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
1322 if (address==0) continue;
1323 Int_t ich=address->fChamber;
1324 Int_t q=address->fSignal;
1325 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1327 // Digit Response (noise, threshold, saturation, ...)
1328 // if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1329 AliMUONResponse * response=iChamber->ResponseModel();
1330 q=response->DigitResponse(q);
1334 digits[0]=address->fPadX;
1335 digits[1]=address->fPadY;
1337 digits[3]=address->fPhysics;
1338 digits[4]=address->fHit;
1340 TObjArray* trlist=(TObjArray*)address->TrackList();
1341 Int_t nptracks=trlist->GetEntriesFast();
1342 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1344 // this was changed to accomodate the real number of tracks
1345 if (nptracks > 10) {
1346 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1350 printf("Attention - nptracks > 2 %d \n",nptracks);
1351 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1353 for (Int_t tr=0;tr<nptracks;tr++) {
1354 TVector *ppP=(TVector*)trlist->At(tr);
1355 if(!ppP ) printf("ppP - %p\n",ppP);
1357 tracks[tr]=Int_t(pp(0));
1358 charges[tr]=Int_t(pp(1));
1359 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
1360 } //end loop over list of tracks for one pad
1361 // Sort list of tracks according to charge
1363 SortTracks(tracks,charges,nptracks);
1365 if (nptracks < 10 ) {
1366 for (Int_t i=nptracks; i<10; i++) {
1373 pMUON->AddDigits(ich,tracks,charges,digits);
1376 //cout<<"I'm out of the loops for digitisation"<<endl;
1377 // gAlice->GetEvent(nev);
1378 gAlice->TreeD()->Fill();
1379 pMUON->ResetDigits();
1383 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
1391 } //end loop over cathodes
1394 sprintf(hname,"TreeD%d",nev);
1395 gAlice->TreeD()->Write(hname);
1397 gAlice->TreeD()->Reset();
1401 // gObjectTable->Print();
1404 void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1407 // Sort the list of tracks contributing to a given digit
1408 // Only the 3 most significant tracks are acctually sorted
1412 // Loop over signals, only 3 times
1417 Int_t idx[3] = {-2,-2,-2};
1418 Int_t jch[3] = {-2,-2,-2};
1419 Int_t jtr[3] = {-2,-2,-2};
1422 if (ntr<3) imax=ntr;
1424 for(i=0;i<imax;i++){
1430 if((i == 1 && j == idx[i-1])
1431 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1433 if(charges[j] > qmax) {
1441 jch[i]=charges[jmax];
1442 jtr[i]=tracks[jmax];
1459 //___________________________________________
1460 void AliMUON::Trigger(Int_t nev){
1461 // call the Trigger Algorithm and fill TreeR
1463 Int_t singlePlus[3] = {0,0,0};
1464 Int_t singleMinus[3] = {0,0,0};
1465 Int_t singleUndef[3] = {0,0,0};
1466 Int_t pairUnlike[3] = {0,0,0};
1467 Int_t pairLike[3] = {0,0,0};
1470 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1471 decision->Trigger();
1472 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1473 pairUnlike, pairLike);
1474 // add a local trigger in the list
1475 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
1478 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
1479 if(decision->GetITrigger(icirc)==1) {
1480 Int_t localtr[7]={0,0,0,0,0,0,0};
1481 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1482 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1484 localtr[1] = decision->GetStripX11(icirc);
1485 localtr[2] = decision->GetDev(icirc);
1486 localtr[3] = decision->GetStripY11(icirc);
1487 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1488 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1489 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1490 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1492 AddLocalTrigger(localtr); // add a local trigger in the list
1497 gAlice->TreeR()->Fill();
1500 sprintf(hname,"TreeR%d",nev);
1501 gAlice->TreeR()->Write(hname);
1502 gAlice->TreeR()->Reset();
1503 printf("\n End of trigger for event %d", nev);
1507 //____________________________________________
1508 void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1510 TClonesArray *dig1, *dig2;
1512 dig1 = new TClonesArray("AliMUONDigit",1000);
1513 dig2 = new TClonesArray("AliMUONDigit",1000);
1514 AliMUONDigit *digit;
1516 // Loop on chambers and on cathode planes
1519 for (Int_t ich=0;ich<10;ich++) {
1520 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1521 AliMUONClusterFinderVS* rec = iChamber->ReconstructionModel();
1522 gAlice->ResetDigits();
1523 gAlice->TreeD()->GetEvent(lastEntry);
1524 TClonesArray *muonDigits = this->DigitsAddress(ich);
1525 ndig=muonDigits->GetEntriesFast();
1526 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1527 TClonesArray &lhits1 = *dig1;
1529 for (k=0; k<ndig; k++) {
1530 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1531 if (rec->TestTrack(digit->fTracks[0]))
1532 new(lhits1[n++]) AliMUONDigit(*digit);
1534 gAlice->ResetDigits();
1535 gAlice->TreeD()->GetEvent(lastEntry+1);
1536 muonDigits = this->DigitsAddress(ich);
1537 ndig=muonDigits->GetEntriesFast();
1538 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1539 TClonesArray &lhits2 = *dig2;
1542 for (k=0; k<ndig; k++) {
1543 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1544 if (rec->TestTrack(digit->fTracks[0]))
1545 new(lhits2[n++]) AliMUONDigit(*digit);
1549 AliMUONClusterInput::Instance()->SetDigits(ich, dig1, dig2);
1550 rec->FindRawClusters();
1555 gAlice->TreeR()->Fill();
1558 sprintf(hname,"TreeR%d",nev);
1559 gAlice->TreeR()->Write(hname);
1560 gAlice->TreeR()->Reset();
1561 printf("\n End of cluster finding for event %d", nev);
1565 //gObjectTable->Print();
1569 void AliMUON::Streamer(TBuffer &R__b)
1571 // Stream an object of class AliMUON.
1572 AliMUONChamber *iChamber;
1573 AliMUONTriggerCircuit *iTriggerCircuit;
1574 AliSegmentation *segmentation;
1575 AliMUONResponse *response;
1576 TClonesArray *digitsaddress;
1577 TClonesArray *rawcladdress;
1579 if (R__b.IsReading()) {
1580 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1581 AliDetector::Streamer(R__b);
1583 R__b >> fPadHits; // diff
1584 R__b >> fNLocalTrigger;
1585 R__b >> fLocalTrigger;
1586 R__b >> fNGlobalTrigger;
1587 R__b >> fGlobalTrigger;
1589 R__b >> fRawClusters;
1590 R__b.ReadArray(fNdch);
1591 R__b.ReadArray(fNrawch);
1596 R__b >> fTriggerCircuits;
1597 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1598 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1599 iTriggerCircuit->Streamer(R__b);
1601 // Stream chamber related information
1602 for (i =0; i<AliMUONConstants::NCh(); i++) {
1603 iChamber=(AliMUONChamber*) (*fChambers)[i];
1604 iChamber->Streamer(R__b);
1605 if (iChamber->Nsec()==1) {
1606 segmentation=iChamber->SegmentationModel(1);
1608 segmentation->Streamer(R__b);
1610 segmentation=iChamber->SegmentationModel(1);
1612 segmentation->Streamer(R__b);
1614 segmentation=iChamber->SegmentationModel(2);
1615 segmentation->Streamer(R__b);
1617 response=iChamber->ResponseModel();
1619 response->Streamer(R__b);
1620 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1621 digitsaddress->Streamer(R__b);
1622 if (i < AliMUONConstants::NTrackingCh()) {
1623 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1624 rawcladdress->Streamer(R__b);
1629 R__b.WriteVersion(AliMUON::IsA());
1630 AliDetector::Streamer(R__b);
1632 R__b << fPadHits; // diff
1633 R__b << fNLocalTrigger;
1634 R__b << fLocalTrigger;
1635 R__b << fNGlobalTrigger;
1636 R__b << fGlobalTrigger;
1638 R__b << fRawClusters;
1639 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1640 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
1647 R__b << fTriggerCircuits;
1648 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
1649 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1650 iTriggerCircuit->Streamer(R__b);
1652 for (i =0; i<AliMUONConstants::NCh(); i++) {
1653 iChamber=(AliMUONChamber*) (*fChambers)[i];
1654 iChamber->Streamer(R__b);
1655 if (iChamber->Nsec()==1) {
1656 segmentation=iChamber->SegmentationModel(1);
1658 segmentation->Streamer(R__b);
1660 segmentation=iChamber->SegmentationModel(1);
1662 segmentation->Streamer(R__b);
1663 segmentation=iChamber->SegmentationModel(2);
1665 segmentation->Streamer(R__b);
1667 response=iChamber->ResponseModel();
1669 response->Streamer(R__b);
1670 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1671 digitsaddress->Streamer(R__b);
1672 if (i < AliMUONConstants::NTrackingCh()) {
1673 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1674 rawcladdress->Streamer(R__b);
1679 AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
1682 // Initialise the pad iterator
1683 // Return the address of the first padhit for hit
1684 TClonesArray *theClusters = clusters;
1685 Int_t nclust = theClusters->GetEntriesFast();
1686 if (nclust && hit->fPHlast > 0) {
1687 AliMUON::fMaxIterPad=hit->fPHlast;
1688 AliMUON::fCurIterPad=hit->fPHfirst;
1689 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1695 AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
1697 AliMUON::fCurIterPad++;
1698 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1699 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
1706 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1708 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
1710 TTree *treeR = gAlice->TreeR();
1711 Int_t nent=(Int_t)treeR->GetEntries();
1712 treeR->GetEvent(nent-2+icathod-1);
1713 //treeR->GetEvent(icathod);
1714 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
1716 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
1717 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1722 AliMUON& AliMUON::operator = (const AliMUON& rhs)