Finally correct implementation of xm, ym, ixm, iym sizes
[u/mrichter/AliRoot.git] / MUON / AliMUON.cxx
CommitLineData
4c039060 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
4c039060 15/*
16$Log$
d09fafb0 17Revision 1.20 2000/06/26 14:02:38 morsch
18Add class AliMUONConstants with MUON specific constants using static memeber data and access methods.
19
f665c1ea 20Revision 1.19 2000/06/22 13:40:51 morsch
21scope problem on HP, "i" declared once
22pow changed to TMath::Power (PH, AM)
23
9ae15266 24Revision 1.18 2000/06/15 07:58:48 morsch
25Code from MUON-dev joined
26
a9e2aefa 27Revision 1.14.4.17 2000/06/14 14:36:46 morsch
28- add TriggerCircuit (PC)
29- add GlobalTrigger and LocalTrigger and specific methods (PC)
30
31Revision 1.14.4.16 2000/06/09 21:20:28 morsch
32Most coding rule violations corrected
33
34Revision 1.14.4.15 2000/05/02 09:54:32 morsch
35RULE RN17 violations corrected
36
37Revision 1.14.4.12 2000/04/26 12:25:02 morsch
38Code revised by P. Crochet:
39- Z position of TriggerChamber changed according to A.Tournaire Priv.Comm.
40- ToF included in the method MakePadHits
41- inner radius of flange between beam shielding and trigger corrected
42- Trigger global volume updated (according to the new geometry)
43
44Revision 1.14.4.11 2000/04/19 19:42:08 morsch
45Some changes of variable names curing viols and methods concerning
46correlated clusters removed.
47
48Revision 1.14.4.10 2000/03/22 16:44:07 gosset
49Memory leak suppressed in function Digitise:
50p_adr->Delete() instead of Clear (I.Chevrot and A.Baldisseri)
51
52Revision 1.14.4.9 2000/03/20 18:15:25 morsch
53Positions of trigger chambers corrected (P.C.)
dbe37a89 54
a9e2aefa 55Revision 1.14.4.8 2000/02/21 15:38:01 morsch
56Call to AddHitList introduced to make this version compatible with head.
dffd31ef 57
a9e2aefa 58Revision 1.14.4.7 2000/02/20 07:45:53 morsch
59Bugs in Trigger part of BuildGeomemetry corrected (P.C)
1cedd08a 60
a9e2aefa 61Revision 1.14.4.6 2000/02/17 14:28:54 morsch
62Trigger included into initialization and digitization
6a935c13 63
a9e2aefa 64Revision 1.14.4.5 2000/02/15 10:02:58 morsch
65Log messages of previous revisions added
5d84196c 66
a9e2aefa 67Revision 1.14.4.2 2000/02/04 10:57:34 gosset
68Z position of the chambers:
69it was the Z position of the stations;
70it is now really the Z position of the chambers.
71 !!!! WARNING: THE CALLS TO "AliMUONChamber::SetZPOS"
72 !!!! AND "AliMUONChamber::ZPosition"
73 !!!! HAVE TO BE CHANGED TO "AliMUONChamber::"SetZ"
74 !!!! AND "AliMUONChamber::Z"
50f986db 75
a9e2aefa 76Revision 1.14.4.3 2000/02/04 16:19:04 gosset
77Correction for mis-spelling of NCH
0b34885d 78
a9e2aefa 79Revision 1.14.4.4 2000/02/15 09:43:38 morsch
80Log message added
2b86633d 81
4c039060 82*/
83
a9e2aefa 84
85///////////////////////////////////////////////
fe4da5cc 86// Manager and hits classes for set:MUON //
87////////////////////////////////////////////////
88
89#include <TTUBE.h>
a897a37a 90#include <TBRIK.h>
91#include <TRotMatrix.h>
fe4da5cc 92#include <TNode.h>
a897a37a 93#include <TTree.h>
fe4da5cc 94#include <TRandom.h>
95#include <TObject.h>
96#include <TVector.h>
97#include <TObjArray.h>
a897a37a 98#include <TMinuit.h>
99#include <TParticle.h>
100#include <TROOT.h>
101#include <TFile.h>
102#include <TNtuple.h>
103#include <TCanvas.h>
104#include <TPad.h>
105#include <TDirectory.h>
106#include <TObjectTable.h>
107#include <AliPDG.h>
a9e2aefa 108#include <TTUBE.h>
fe4da5cc 109
110#include "AliMUON.h"
a9e2aefa 111#include "AliMUONHit.h"
112#include "AliMUONPadHit.h"
113#include "AliMUONDigit.h"
114#include "AliMUONTransientDigit.h"
115#include "AliMUONRawCluster.h"
116#include "AliMUONLocalTrigger.h"
117#include "AliMUONGlobalTrigger.h"
118#include "AliMUONHitMap.h"
119#include "AliMUONHitMapA1.h"
120#include "AliMUONChamberTrigger.h"
f665c1ea 121#include "AliMUONConstants.h"
a897a37a 122#include "AliMUONClusterFinder.h"
a9e2aefa 123#include "AliMUONTriggerDecision.h"
fe4da5cc 124#include "AliRun.h"
125#include "AliMC.h"
126#include "iostream.h"
127#include "AliCallf77.h"
a9e2aefa 128#include "AliConst.h"
129
130// Defaults parameters for Z positions of chambers
131// taken from values for "stations" in AliMUON::AliMUON
132// const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
133// and from array "dstation" in AliMUONv1::CreateGeometry
134// Float_t dstation[5]={20., 20., 20, 20., 20.};
135// for tracking chambers,
136// according to (Z1 = zch - dstation) and (Z2 = zch + dstation)
137// for the first and second chambers in the station, respectively,
138// and from "DTPLANES" in AliMUONv1::CreateGeometry
139// const Float_t DTPLANES = 15.;
140// for trigger chambers,
141// according to (Z1 = zch) and (Z2 = zch + DTPLANES)
142// for the first and second chambers in the station, respectively
fe4da5cc 143
fe4da5cc 144ClassImp(AliMUON)
fe4da5cc 145//___________________________________________
146AliMUON::AliMUON()
147{
a9e2aefa 148 fIshunt = 0;
149 fHits = 0;
150 fPadHits = 0;
151 fNPadHits = 0;
152 fDchambers = 0;
153 fTriggerCircuits = 0; // cp new design of AliMUONTriggerDecision
154 fNdch = 0;
155 fRawClusters = 0;
156 fNrawch = 0;
157 fGlobalTrigger = 0;
158 fNLocalTrigger = 0;
159 fLocalTrigger = 0;
160 fNLocalTrigger = 0;
fe4da5cc 161}
162
163//___________________________________________
164AliMUON::AliMUON(const char *name, const char *title)
165 : AliDetector(name,title)
166{
167//Begin_Html
168/*
a897a37a 169<img src="gif/alimuon.gif">
fe4da5cc 170*/
171//End_Html
f665c1ea 172
a9e2aefa 173 fHits = new TClonesArray("AliMUONHit",1000);
1cedd08a 174 gAlice->AddHitList(fHits);
a9e2aefa 175 fPadHits = new TClonesArray("AliMUONPadHit",10000);
176 fNPadHits = 0;
fe4da5cc 177 fIshunt = 0;
178
f665c1ea 179 fNdch = new Int_t[AliMUONConstants::NCh()];
fe4da5cc 180
f665c1ea 181 fDchambers = new TObjArray(AliMUONConstants::NCh());
fe4da5cc 182
183 Int_t i;
184
f665c1ea 185 for (i=0; i<AliMUONConstants::NCh() ;i++) {
a9e2aefa 186 (*fDchambers)[i] = new TClonesArray("AliMUONDigit",10000);
fe4da5cc 187 fNdch[i]=0;
188 }
189
f665c1ea 190 fNrawch = new Int_t[AliMUONConstants::NTrackingCh()];
a897a37a 191
f665c1ea 192 fRawClusters = new TObjArray(AliMUONConstants::NTrackingCh());
a897a37a 193
f665c1ea 194 for (i=0; i<AliMUONConstants::NTrackingCh();i++) {
a897a37a 195 (*fRawClusters)[i] = new TClonesArray("AliMUONRawCluster",10000);
196 fNrawch[i]=0;
197 }
a9e2aefa 198 cout << " here " << "\n";
a897a37a 199
a9e2aefa 200 fGlobalTrigger = new TClonesArray("AliMUONGlobalTrigger",1);
201 fNGlobalTrigger = 0;
202 fLocalTrigger = new TClonesArray("AliMUONLocalTrigger",234);
203 fNLocalTrigger = 0;
fe4da5cc 204
205//
206// Transport angular cut
207 fAccCut=0;
208 fAccMin=2;
209 fAccMax=9;
210
211 SetMarkerColor(kRed);
a9e2aefa 212//
213//
214//
215//
f665c1ea 216
a9e2aefa 217 Int_t ch;
218
f665c1ea 219 fChambers = new TObjArray(AliMUONConstants::NCh());
a9e2aefa 220
221 // Loop over stations
f665c1ea 222 for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
a9e2aefa 223 // Loop over 2 chambers in the station
224 for (Int_t stCH = 0; stCH < 2; stCH++) {
225//
226//
227// Default Parameters for Muon Tracking Stations
228
229
230 ch = 2 * st + stCH;
231//
f665c1ea 232 if (ch < AliMUONConstants::NTrackingCh()) {
a9e2aefa 233 (*fChambers)[ch] = new AliMUONChamber();
234 } else {
235 (*fChambers)[ch] = new AliMUONChamberTrigger();
236 }
237
238 AliMUONChamber* chamber = (AliMUONChamber*) (*fChambers)[ch];
239
240 chamber->SetGid(0);
241 // Default values for Z of chambers
f665c1ea 242 chamber->SetZ(AliMUONConstants::DefaultChamberZ(ch));
a9e2aefa 243//
f665c1ea 244 chamber->InitGeo(AliMUONConstants::DefaultChamberZ(ch));
245 chamber->SetRInner(AliMUONConstants::Dmin(st)/2);
246 chamber->SetROuter(AliMUONConstants::Dmax(st)/2);
a9e2aefa 247//
248 } // Chamber stCH (0, 1) in
249 } // Station st (0...)
250 fMaxStepGas=0.01;
251 fMaxStepAlu=0.1;
252 fMaxDestepGas=-1;
253 fMaxDestepAlu=-1;
254//
255 fMaxIterPad = 0;
256 fCurIterPad = 0;
257
258 // cp new design of AliMUONTriggerDecision
f665c1ea 259 fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
260 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
a9e2aefa 261 (*fTriggerCircuits)[circ] = new AliMUONTriggerCircuit();
262 }
263 // cp new design of AliMUONTriggerDecision
264
fe4da5cc 265}
266
267//___________________________________________
a9e2aefa 268AliMUON::AliMUON(const AliMUON& rMUON)
269{
270// Dummy copy constructor
271 ;
272
273}
274
fe4da5cc 275AliMUON::~AliMUON()
276{
a897a37a 277 printf("Calling AliMUON destructor !!!\n");
278
f665c1ea 279 Int_t i;
280 fIshunt = 0;
281 delete fHits;
282 delete fPadHits;
283
284 delete fGlobalTrigger;
285 fNGlobalTrigger = 0;
286
287 delete fLocalTrigger;
288 fNLocalTrigger = 0;
a897a37a 289
f665c1ea 290 for (i=0;i<AliMUONConstants::NCh();i++) {
291 delete (*fDchambers)[i];
292 fNdch[i]=0;
293 }
294 delete fDchambers;
295
296 for (i=0;i<AliMUONConstants::NTrackingCh();i++) {
297 delete (*fRawClusters)[i];
298 fNrawch[i]=0;
299 }
300 delete fRawClusters;
301
302 for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
303 delete (*fTriggerCircuits)[circ];
304 }
305 delete fTriggerCircuits;
fe4da5cc 306}
307
308//___________________________________________
309void AliMUON::AddHit(Int_t track, Int_t *vol, Float_t *hits)
310{
311 TClonesArray &lhits = *fHits;
a9e2aefa 312 new(lhits[fNhits++]) AliMUONHit(fIshunt,track,vol,hits);
fe4da5cc 313}
314//___________________________________________
a9e2aefa 315void AliMUON::AddPadHit(Int_t *clhits)
fe4da5cc 316{
a9e2aefa 317 TClonesArray &lclusters = *fPadHits;
318 new(lclusters[fNPadHits++]) AliMUONPadHit(clhits);
fe4da5cc 319}
320//_____________________________________________________________________________
321void AliMUON::AddDigits(Int_t id, Int_t *tracks, Int_t *charges, Int_t *digits)
322{
323 //
324 // Add a MUON digit to the list
325 //
326
327 TClonesArray &ldigits = *((TClonesArray*)(*fDchambers)[id]);
a9e2aefa 328 new(ldigits[fNdch[id]++]) AliMUONDigit(tracks,charges,digits);
fe4da5cc 329}
330
a897a37a 331//_____________________________________________________________________________
332void AliMUON::AddRawCluster(Int_t id, const AliMUONRawCluster& c)
333{
334 //
335 // Add a MUON digit to the list
336 //
337
338 TClonesArray &lrawcl = *((TClonesArray*)(*fRawClusters)[id]);
339 new(lrawcl[fNrawch[id]++]) AliMUONRawCluster(c);
340}
a897a37a 341
a9e2aefa 342//___________________________________________
343void AliMUON::AddGlobalTrigger(Int_t *singlePlus, Int_t *singleMinus,
344 Int_t *singleUndef,
345 Int_t *pairUnlike, Int_t *pairLike)
346{
347// add a MUON Global Trigger to the list (only one GlobalTrigger per event !)
348 TClonesArray &globalTrigger = *fGlobalTrigger;
349 new(globalTrigger[fNGlobalTrigger++])
350 AliMUONGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike,
351 pairLike);
352}
353//___________________________________________
354void AliMUON::AddLocalTrigger(Int_t *localtr)
355{
356// add a MUON Local Trigger to the list
357 TClonesArray &localTrigger = *fLocalTrigger;
358 new(localTrigger[fNLocalTrigger++]) AliMUONLocalTrigger(localtr);
a897a37a 359}
360
fe4da5cc 361//___________________________________________
362void AliMUON::BuildGeometry()
363{
a9e2aefa 364 TNode *node, *nodeF, *top, *nodeS;
365 const int kColorMUON = kBlue;
366 const int kColorMUON2 = kGreen;
a897a37a 367 //
a9e2aefa 368 top=gAlice->GetGeometry()->GetNode("alice");
a897a37a 369// MUON
370//
371// z-Positions of Chambers
a9e2aefa 372 const Float_t kCz[7]={511., 686., 971., 1245., 1445., 1600, 1700.};
373// inner diameter (Xlenght for trigger chamber -> active area)
374 const Float_t kDmin[7]={ 35., 47., 67., 86., 100., 544., 544.};
375// outer diameter (Ylenght for trigger chamber -> active area)
376 const Float_t kDmax[7]={183., 245., 346., 520., 520., 612., 612.};
a897a37a 377
378 TRotMatrix* rot000 = new TRotMatrix("Rot000"," ", 90, 0, 90, 90, 0, 0);
379 TRotMatrix* rot090 = new TRotMatrix("Rot090"," ", 90, 90, 90,180, 0, 0);
380 TRotMatrix* rot180 = new TRotMatrix("Rot180"," ", 90,180, 90,270, 0, 0);
381 TRotMatrix* rot270 = new TRotMatrix("Rot270"," ", 90,270, 90, 0, 0, 0);
382
a9e2aefa 383 Float_t rmin, rmax, dx, dy, dz, dr, xpos, ypos, zpos;
384 Float_t dzc1=4.; // tracking chambers
385 Float_t dzc2=15.; // trigger chambers
386 Float_t hole=102.; // x-y hole around beam pipe for trig. chambers
387 Float_t zscale; // scaling parameter trigger chambers
388 Float_t halfx, halfy;
389 char nameChamber[9], nameSense[9], nameFrame[9], nameNode[8];
390 char nameSense1[9], nameSense2[9];
391 for (Int_t i=0; i<7; i++) {
a897a37a 392 for (Int_t j=0; j<2; j++) {
393 Int_t id=2*i+j+1;
a9e2aefa 394 if (i<5) { // tracking chambers
395 if (j==0) {
396 zpos=kCz[i]-dzc1;
397 } else {
398 zpos=kCz[i]+dzc1;
399 }
a897a37a 400 } else {
a9e2aefa 401 if (j==0) {
402 zpos=kCz[i];
403 } else {
404 zpos=kCz[i]+dzc2;
405 }
a897a37a 406 }
a9e2aefa 407 sprintf(nameChamber,"C_MUON%d",id);
408 sprintf(nameSense,"S_MUON%d",id);
409 sprintf(nameSense1,"S1_MUON%d",id);
410 sprintf(nameSense2,"S2_MUON%d",id);
411 sprintf(nameFrame,"F_MUON%d",id);
412 if (i<5) { // tracking chambers
413 rmin = kDmin[i]/2.-3;
414 rmax = kDmax[i]/2.+3;
415 new TTUBE(nameChamber,"Mother","void",rmin,rmax,0.25,1.);
416 rmin = kDmin[i]/2.;
417 rmax = kDmax[i]/2.;
418 new TTUBE(nameSense,"Sens. region","void",rmin,rmax,0.25, 1.);
419 dx=(rmax-rmin)/2;
420 dy=3.;
421 dz=0.25;
422 TBRIK* frMUON = new TBRIK(nameFrame,"Frame","void",dx,dy,dz);
423 top->cd();
424 sprintf(nameNode,"MUON%d",100+id);
425 node = new TNode(nameNode,"ChamberNode",nameChamber,0,0,zpos,"");
426 node->SetLineColor(kColorMUON);
427 fNodes->Add(node);
428 node->cd();
429 sprintf(nameNode,"MUON%d",200+id);
430 node = new TNode(nameNode,"Sens. Region Node",nameSense,0,0,0,"");
431 node->SetLineColor(kColorMUON);
432 node->cd();
433 dr=dx+rmin;
434 sprintf(nameNode,"MUON%d",300+id);
435 nodeF = new TNode(nameNode,"Frame0",frMUON,dr, 0, 0,rot000,"");
436 nodeF->SetLineColor(kColorMUON);
437 node->cd();
438 sprintf(nameNode,"MUON%d",400+id);
439 nodeF = new TNode(nameNode,"Frame1",frMUON,0 ,dr,0,rot090,"");
440 nodeF->SetLineColor(kColorMUON);
441 node->cd();
442 sprintf(nameNode,"MUON%d",500+id);
443 nodeF = new TNode(nameNode,"Frame2",frMUON,-dr,0,0,rot180,"");
444 nodeF->SetLineColor(kColorMUON);
445 node ->cd();
446 sprintf(nameNode,"MUON%d",600+id);
447 nodeF = new TNode(nameNode,"Frame3",frMUON,0,-dr,0,rot270,"");
448 nodeF->SetLineColor(kColorMUON);
449 } else {
450 zscale=zpos/kCz[5];
451 Float_t xsize=kDmin[i]*zscale;
452 Float_t ysize=kDmax[i]*zscale;
453 Float_t holeScaled=hole*zscale;
454
455 halfx=xsize/2.+3.;
456 halfy=ysize/2.+3.;
457 new TBRIK(nameChamber,"Mother","void",halfx,halfy,0.25);
458 top->cd();
459 sprintf(nameNode,"MUON%d",100+id);
460 node = new TNode(nameNode,"Chambernode",nameChamber,0,0,zpos,"");
461 node->SetLineColor(kColorMUON2);
462 fNodes->Add(node);
463
464// up/down of beam pipe
465 halfx=xsize/2.;
466 halfy=(ysize/2.-holeScaled/2.)/2.;
467 new TBRIK(nameSense,"Sens. region","void",halfx,halfy,0.25);
468
469 node->cd();
470 ypos=holeScaled/2.+((ysize/2.-holeScaled/2.)/2.);
471 sprintf(nameNode,"MUON%d",200+id);
472 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
473 nodeS->SetLineColor(kColorMUON2);
474
475 node->cd();
476 ypos=-1.*ypos;
477 sprintf(nameNode,"MUON%d",300+id);
478 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense,0,ypos,0,"");
479 nodeS->SetLineColor(kColorMUON2);
480
481// left/right of beam pipe
482 halfx=(xsize/2.-holeScaled/2.)/2.;
483 halfy=holeScaled/2.;
484 new TBRIK(nameSense1,"Sens. region","void",halfx,halfy,0.25);
485
486 node->cd();
487 xpos=holeScaled/2.+((xsize/2.-holeScaled/2.)/2.);
488 sprintf(nameNode,"MUON%d",400+id);
489 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
490 nodeS->SetLineColor(kColorMUON2);
491
492 node->cd();
493 xpos=-1.*xpos;
494 sprintf(nameNode,"MUON%d",500+id);
495 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense1,xpos,0,0,"");
496 nodeS->SetLineColor(kColorMUON2);
497
498// missing corners
499 halfx=17.*zscale/2.;
500 halfy=halfx;
501 new TBRIK(nameSense2,"Sens. region","void",halfx,halfy,0.25);
502
503 node->cd();
504 xpos=holeScaled/2.-halfx;
505 ypos=xpos;
506 sprintf(nameNode,"MUON%d",600+id);
507 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
508 nodeS->SetLineColor(kColorMUON2);
509
510 node->cd();
511 ypos=-1.*xpos;
512 sprintf(nameNode,"MUON%d",700+id);
513 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
514 nodeS->SetLineColor(kColorMUON2);
515
516 node->cd();
517 xpos=-1.*xpos;
518 sprintf(nameNode,"MUON%d",800+id);
519 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
520 nodeS->SetLineColor(kColorMUON2);
521
522 node->cd();
523 ypos=-1.*xpos;
524 sprintf(nameNode,"MUON%d",900+id);
525 nodeS = new TNode(nameNode,"Sens. Region Node",nameSense2,xpos,ypos,0,"");
526 nodeS->SetLineColor(kColorMUON2);
527 }
a897a37a 528 }
529 }
fe4da5cc 530}
531
a897a37a 532
fe4da5cc 533//___________________________________________
534Int_t AliMUON::DistancetoPrimitive(Int_t , Int_t )
535{
536 return 9999;
537}
538
539//___________________________________________
540void AliMUON::MakeBranch(Option_t* option)
541{
f665c1ea 542 // Create Tree branches for the MUON.
543 const Int_t kBufferSize = 4000;
544 char branchname[30];
545 sprintf(branchname,"%sCluster",GetName());
546
547 AliDetector::MakeBranch(option);
548
549 if (fPadHits && gAlice->TreeH()) {
550 gAlice->TreeH()->Branch(branchname,&fPadHits, kBufferSize);
551 printf("Making Branch %s for clusters\n",branchname);
552 }
553
fe4da5cc 554// one branch for digits per chamber
f665c1ea 555 Int_t i;
556
557 for (i=0; i<AliMUONConstants::NCh() ;i++) {
558 sprintf(branchname,"%sDigits%d",GetName(),i+1);
559
560 if (fDchambers && gAlice->TreeD()) {
561 gAlice->TreeD()->Branch(branchname,&((*fDchambers)[i]), kBufferSize);
562 printf("Making Branch %s for digits in chamber %d\n",branchname,i+1);
563 }
564 }
565
566 printf("Make Branch - TreeR address %p\n",gAlice->TreeR());
567
a897a37a 568// one branch for raw clusters per chamber
f665c1ea 569 for (i=0; i<AliMUONConstants::NTrackingCh() ;i++) {
570 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
571
572 if (fRawClusters && gAlice->TreeR()) {
573 gAlice->TreeR()->Branch(branchname,&((*fRawClusters)[i]), kBufferSize);
574 printf("Making Branch %s for raw clusters in chamber %d\n",branchname,i+1);
575 }
576 }
577
a9e2aefa 578// one branch for global trigger
f665c1ea 579 sprintf(branchname,"%sGlobalTrigger",GetName());
580 if (fGlobalTrigger && gAlice->TreeR()) {
581 gAlice->TreeR()->Branch(branchname,&fGlobalTrigger,kBufferSize);
582 printf("Making Branch %s for Global Trigger\n",branchname);
583 }
a9e2aefa 584// one branch for local trigger
f665c1ea 585 sprintf(branchname,"%sLocalTrigger",GetName());
586 if (fLocalTrigger && gAlice->TreeR()) {
587 gAlice->TreeR()->Branch(branchname,&fLocalTrigger,kBufferSize);
588 printf("Making Branch %s for Local Trigger\n",branchname);
589 }
590
fe4da5cc 591}
592
593//___________________________________________
594void AliMUON::SetTreeAddress()
595{
596 // Set branch address for the Hits and Digits Tree.
a897a37a 597 char branchname[30];
fe4da5cc 598 AliDetector::SetTreeAddress();
599
600 TBranch *branch;
601 TTree *treeH = gAlice->TreeH();
602 TTree *treeD = gAlice->TreeD();
a897a37a 603 TTree *treeR = gAlice->TreeR();
fe4da5cc 604
605 if (treeH) {
a9e2aefa 606 if (fPadHits) {
fe4da5cc 607 branch = treeH->GetBranch("MUONCluster");
a9e2aefa 608 if (branch) branch->SetAddress(&fPadHits);
fe4da5cc 609 }
610 }
611
612 if (treeD) {
f665c1ea 613 for (int i=0; i<AliMUONConstants::NCh(); i++) {
fe4da5cc 614 sprintf(branchname,"%sDigits%d",GetName(),i+1);
615 if (fDchambers) {
616 branch = treeD->GetBranch(branchname);
617 if (branch) branch->SetAddress(&((*fDchambers)[i]));
618 }
619 }
620 }
a897a37a 621
622 // printf("SetTreeAddress --- treeR address %p \n",treeR);
623
624 if (treeR) {
f665c1ea 625 for (int i=0; i<AliMUONConstants::NTrackingCh(); i++) {
a897a37a 626 sprintf(branchname,"%sRawClusters%d",GetName(),i+1);
627 if (fRawClusters) {
628 branch = treeR->GetBranch(branchname);
629 if (branch) branch->SetAddress(&((*fRawClusters)[i]));
630 }
631 }
a897a37a 632
a9e2aefa 633 if (fLocalTrigger) {
634 branch = treeR->GetBranch("MUONLocalTrigger");
635 if (branch) branch->SetAddress(&fLocalTrigger);
636 }
637 if (fGlobalTrigger) {
638 branch = treeR->GetBranch("MUONGlobalTrigger");
639 if (branch) branch->SetAddress(&fGlobalTrigger);
640 }
641 }
fe4da5cc 642}
643//___________________________________________
644void AliMUON::ResetHits()
645{
646 // Reset number of clusters and the cluster array for this detector
647 AliDetector::ResetHits();
a9e2aefa 648 fNPadHits = 0;
649 if (fPadHits) fPadHits->Clear();
fe4da5cc 650}
651
652//____________________________________________
653void AliMUON::ResetDigits()
654{
655 //
656 // Reset number of digits and the digits array for this detector
657 //
f665c1ea 658 for ( int i=0;i<AliMUONConstants::NCh();i++ ) {
a897a37a 659 if ((*fDchambers)[i]) ((TClonesArray*)(*fDchambers)[i])->Clear();
fe4da5cc 660 if (fNdch) fNdch[i]=0;
661 }
662}
663//____________________________________________
a897a37a 664void AliMUON::ResetRawClusters()
665{
666 //
667 // Reset number of raw clusters and the raw clust array for this detector
668 //
f665c1ea 669 for ( int i=0;i<AliMUONConstants::NTrackingCh();i++ ) {
a897a37a 670 if ((*fRawClusters)[i]) ((TClonesArray*)(*fRawClusters)[i])->Clear();
671 if (fNrawch) fNrawch[i]=0;
672 }
673}
a9e2aefa 674
a897a37a 675//____________________________________________
a9e2aefa 676void AliMUON::ResetTrigger()
a897a37a 677{
a9e2aefa 678 // Reset Local and Global Trigger
679 fNGlobalTrigger = 0;
680 if (fGlobalTrigger) fGlobalTrigger->Clear();
681 fNLocalTrigger = 0;
682 if (fLocalTrigger) fLocalTrigger->Clear();
683}
684
685//____________________________________________
686void AliMUON::SetPadSize(Int_t id, Int_t isec, Float_t p1, Float_t p2)
687{
688 Int_t i=2*(id-1);
689 ((AliMUONChamber*) (*fChambers)[i]) ->SetPadSize(isec,p1,p2);
690 ((AliMUONChamber*) (*fChambers)[i+1])->SetPadSize(isec,p1,p2);
a897a37a 691}
692
fe4da5cc 693//___________________________________________
a9e2aefa 694void AliMUON::SetChambersZ(const Float_t *Z)
695{
696 // Set Z values for all chambers (tracking and trigger)
697 // from the array pointed to by "Z"
f665c1ea 698 for (Int_t ch = 0; ch < AliMUONConstants::NCh(); ch++)
699 ((AliMUONChamber*) ((*fChambers)[ch]))->SetZ(Z[ch]);
700 return;
a9e2aefa 701}
fe4da5cc 702
a9e2aefa 703//___________________________________________
704void AliMUON::SetChambersZToDefault()
fe4da5cc 705{
a9e2aefa 706 // Set Z values for all chambers (tracking and trigger)
707 // to default values
f665c1ea 708 SetChambersZ(AliMUONConstants::DefaultChamberZ());
a9e2aefa 709 return;
fe4da5cc 710}
711
712//___________________________________________
a897a37a 713void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
fe4da5cc 714{
715 Int_t i=2*(id-1);
a9e2aefa 716 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSlope(p1);
717 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSlope(p1);
fe4da5cc 718}
719
720//___________________________________________
a897a37a 721void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
fe4da5cc 722{
723 Int_t i=2*(id-1);
a9e2aefa 724 ((AliMUONChamber*) (*fChambers)[i])->SetChargeSpread(p1,p2);
725 ((AliMUONChamber*) (*fChambers)[i+1])->SetChargeSpread(p1,p2);
fe4da5cc 726}
727
728//___________________________________________
a897a37a 729void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
fe4da5cc 730{
731 Int_t i=2*(id-1);
a9e2aefa 732 ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
733 ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
fe4da5cc 734}
735
736//___________________________________________
d09fafb0 737void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
fe4da5cc 738{
739 Int_t i=2*(id-1);
a9e2aefa 740 ((AliMUONChamber*) (*fChambers)[i])->SetMaxAdc(p1);
741 ((AliMUONChamber*) (*fChambers)[i+1])->SetMaxAdc(p1);
fe4da5cc 742}
743
744//___________________________________________
a897a37a 745void AliMUON::SetMaxStepGas(Float_t p1)
fe4da5cc 746{
747 fMaxStepGas=p1;
748}
749
750//___________________________________________
a897a37a 751void AliMUON::SetMaxStepAlu(Float_t p1)
fe4da5cc 752{
753 fMaxStepAlu=p1;
754}
755
756//___________________________________________
a897a37a 757void AliMUON::SetMaxDestepGas(Float_t p1)
fe4da5cc 758{
759 fMaxDestepGas=p1;
760}
761
762//___________________________________________
a897a37a 763void AliMUON::SetMaxDestepAlu(Float_t p1)
fe4da5cc 764{
765 fMaxDestepAlu=p1;
766}
767//___________________________________________
a897a37a 768void AliMUON::SetMuonAcc(Bool_t acc, Float_t angmin, Float_t angmax)
fe4da5cc 769{
770 fAccCut=acc;
771 fAccMin=angmin;
772 fAccMax=angmax;
773}
774//___________________________________________
a9e2aefa 775void AliMUON::SetSegmentationModel(Int_t id, Int_t isec, AliMUONSegmentation *segmentation)
fe4da5cc 776{
a9e2aefa 777 ((AliMUONChamber*) (*fChambers)[id])->SetSegmentationModel(isec, segmentation);
fe4da5cc 778
779}
780//___________________________________________
a9e2aefa 781void AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
fe4da5cc 782{
a9e2aefa 783 ((AliMUONChamber*) (*fChambers)[id])->SetResponseModel(response);
fe4da5cc 784}
785
a897a37a 786void AliMUON::SetReconstructionModel(Int_t id, AliMUONClusterFinder *reconst)
787{
a9e2aefa 788 ((AliMUONChamber*) (*fChambers)[id])->SetReconstructionModel(reconst);
a897a37a 789}
790
fe4da5cc 791void AliMUON::SetNsec(Int_t id, Int_t nsec)
792{
a9e2aefa 793 ((AliMUONChamber*) (*fChambers)[id])->SetNsec(nsec);
fe4da5cc 794}
795
796
797//___________________________________________
798
a897a37a 799
a9e2aefa 800
801void AliMUON::MakePadHits(Float_t xhit,Float_t yhit,
802 Float_t eloss, Float_t tof, Int_t idvol)
fe4da5cc 803{
804//
a897a37a 805// Calls the charge disintegration method of the current chamber and adds
806// the simulated cluster to the root treee
fe4da5cc 807//
a897a37a 808 Int_t clhits[7];
809 Float_t newclust[6][500];
810 Int_t nnew;
811
812
fe4da5cc 813//
a897a37a 814// Integrated pulse height on chamber
815
816
817 clhits[0]=fNhits+1;
fe4da5cc 818//
a897a37a 819//
a9e2aefa 820 ((AliMUONChamber*) (*fChambers)[idvol])
821 ->DisIntegration(eloss, tof, xhit, yhit, nnew, newclust);
a897a37a 822 Int_t ic=0;
823
824//
825// Add new clusters
826 for (Int_t i=0; i<nnew; i++) {
827 if (Int_t(newclust[3][i]) > 0) {
828 ic++;
829// Cathode plane
830 clhits[1] = Int_t(newclust[5][i]);
831// Cluster Charge
832 clhits[2] = Int_t(newclust[0][i]);
833// Pad: ix
834 clhits[3] = Int_t(newclust[1][i]);
835// Pad: iy
836 clhits[4] = Int_t(newclust[2][i]);
837// Pad: charge
838 clhits[5] = Int_t(newclust[3][i]);
839// Pad: chamber sector
840 clhits[6] = Int_t(newclust[4][i]);
841
a9e2aefa 842 AddPadHit(clhits);
a897a37a 843 }
844 }
a897a37a 845}
846
a9e2aefa 847//----------------------------------------------------------------------
848
849void AliMUON::Digitise(Int_t nev,Int_t bgrEvent,Option_t *option,Option_t *opt,Text_t *filename)
a897a37a 850{
851 // keep galice.root for signal and name differently the file for
852 // background when add! otherwise the track info for signal will be lost !
853
a6f39961 854 static Bool_t first=kTRUE;
a9e2aefa 855 static TFile *file;
856 char *addBackground = strstr(option,"Add");
a897a37a 857
f665c1ea 858
a9e2aefa 859 AliMUONChamber* iChamber;
860 AliMUONSegmentation* segmentation;
a897a37a 861
862
863 Int_t trk[50];
864 Int_t chtrk[50];
865 TObjArray *list=new TObjArray;
a9e2aefa 866 static TClonesArray *pAddress=0;
867 if(!pAddress) pAddress=new TClonesArray("TVector",1000);
a897a37a 868 Int_t digits[5];
869
a9e2aefa 870 AliMUON *pMUON = (AliMUON *) gAlice->GetModule("MUON");
d09fafb0 871 AliMUONHitMap** hitMap= new AliMUONHitMap* [AliMUONConstants::NCh()];
f665c1ea 872 for (Int_t i=0; i<AliMUONConstants::NCh(); i++) {hitMap[i]=0;}
a9e2aefa 873 if (addBackground ) {
a897a37a 874 if(first) {
875 fFileName=filename;
876 cout<<"filename"<<fFileName<<endl;
a9e2aefa 877 file=new TFile(fFileName);
a897a37a 878 cout<<"I have opened "<<fFileName<<" file "<<endl;
a9e2aefa 879 fHits2 = new TClonesArray("AliMUONHit",1000 );
880 fPadHits2 = new TClonesArray("AliMUONPadHit",10000);
a897a37a 881 }
a6f39961 882 first=kFALSE;
a9e2aefa 883 file->cd();
884 //file->ls();
a897a37a 885 // Get Hits Tree header from file
886 if(fHits2) fHits2->Clear();
a9e2aefa 887 if(fPadHits2) fPadHits2->Clear();
888 if(fTrH1) delete fTrH1;
889 fTrH1=0;
a897a37a 890
891 char treeName[20];
a9e2aefa 892 sprintf(treeName,"TreeH%d",bgrEvent);
893 fTrH1 = (TTree*)gDirectory->Get(treeName);
894 //printf("fTrH1 %p of treename %s for event %d \n",fTrH1,treeName,bgrEvent);
a897a37a 895
a9e2aefa 896 if (!fTrH1) {
897 printf("ERROR: cannot find Hits Tree for event:%d\n",bgrEvent);
a897a37a 898 }
899 // Set branch addresses
900 TBranch *branch;
901 char branchname[20];
902 sprintf(branchname,"%s",GetName());
a9e2aefa 903 if (fTrH1 && fHits2) {
904 branch = fTrH1->GetBranch(branchname);
a897a37a 905 if (branch) branch->SetAddress(&fHits2);
906 }
a9e2aefa 907 if (fTrH1 && fPadHits2) {
908 branch = fTrH1->GetBranch("MUONCluster");
909 if (branch) branch->SetAddress(&fPadHits2);
a897a37a 910 }
911// test
a9e2aefa 912 //Int_t ntracks1 =(Int_t)fTrH1->GetEntries();
a897a37a 913 //printf("background - ntracks1 - %d\n",ntracks1);
914 }
915 //
916 // loop over cathodes
917 //
918 AliMUONHitMap* hm;
919 Int_t countadr=0;
920 for (int icat=0; icat<2; icat++) {
a897a37a 921 Int_t counter=0;
d09fafb0 922 Int_t * nmuon = new Int_t [AliMUONConstants::NCh()];
f665c1ea 923 for (Int_t i =0; i<AliMUONConstants::NCh(); i++) {
a9e2aefa 924 iChamber=(AliMUONChamber*) (*fChambers)[i];
a897a37a 925 if (iChamber->Nsec()==1 && icat==1) {
fe4da5cc 926 continue;
a897a37a 927 } else {
a9e2aefa 928 segmentation=iChamber->SegmentationModel(icat+1);
fe4da5cc 929 }
a9e2aefa 930 hitMap[i] = new AliMUONHitMapA1(segmentation, list);
f665c1ea 931 nmuon[i]=0;
a897a37a 932 }
933 //printf("Start loop over tracks \n");
934//
935// Loop over tracks
936//
937
a9e2aefa 938 TTree *treeH = gAlice->TreeH();
939 Int_t ntracks =(Int_t) treeH->GetEntries();
d09fafb0 940 Int_t jj;
941 Float_t ** xhit = new Float_t * [2];
942 for (jj=0; jj<2; jj++) xhit[jj] = new Float_t [AliMUONConstants::NCh()];
943 Float_t ** yhit = new Float_t * [2];
944 for (jj=0; jj<2; jj++) yhit[jj] = new Float_t [AliMUONConstants::NCh()];
a897a37a 945
946 for (Int_t track=0; track<ntracks; track++) {
947 gAlice->ResetHits();
a9e2aefa 948 treeH->GetEvent(track);
a897a37a 949
950//
951// Loop over hits
a9e2aefa 952 for(AliMUONHit* mHit=(AliMUONHit*)pMUON->FirstHit(-1);
a897a37a 953 mHit;
a9e2aefa 954 mHit=(AliMUONHit*)pMUON->NextHit())
a897a37a 955 {
956 Int_t nch = mHit->fChamber-1; // chamber number
f665c1ea 957 if (nch > AliMUONConstants::NCh()-1) continue;
a9e2aefa 958 iChamber = &(pMUON->Chamber(nch));
a897a37a 959 // new 17.07.99
a9e2aefa 960 if (addBackground) {
961
962 if (mHit->fParticle == kMuonPlus
963 || mHit->fParticle == kMuonMinus) {
964 xhit[nch][nmuon[nch]]=mHit->fX;
965 yhit[nch][nmuon[nch]]=mHit->fY;
966 nmuon[nch]++;
967 if (nmuon[nch] >2) printf("nmuon %d\n",nmuon[nch]);
968 }
fe4da5cc 969 }
a9e2aefa 970
a897a37a 971
972
973
974//
975// Loop over pad hits
a9e2aefa 976 for (AliMUONPadHit* mPad=
977 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits);
a897a37a 978 mPad;
a9e2aefa 979 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits))
a897a37a 980 {
981 Int_t cathode = mPad->fCathode; // cathode number
982 Int_t ipx = mPad->fPadX; // pad number on X
983 Int_t ipy = mPad->fPadY; // pad number on Y
a9e2aefa 984 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
a897a37a 985//
986//
987
988 if (cathode != (icat+1)) continue;
989 // fill the info array
990 Float_t thex, they;
a9e2aefa 991 segmentation=iChamber->SegmentationModel(cathode);
a897a37a 992 segmentation->GetPadCxy(ipx,ipy,thex,they);
a9e2aefa 993// Float_t rpad=TMath::Sqrt(thex*thex+they*they);
994// if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
a897a37a 995
a9e2aefa 996 new((*pAddress)[countadr++]) TVector(2);
997 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
a897a37a 998 trinfo(0)=(Float_t)track;
999 trinfo(1)=(Float_t)iqpad;
1000
1001 digits[0]=ipx;
1002 digits[1]=ipy;
1003 digits[2]=iqpad;
1004 digits[3]=iqpad;
a9e2aefa 1005 if (mHit->fParticle == kMuonPlus ||
1006 mHit->fParticle == kMuonMinus) {
1007 digits[4]=mPad->fHitNumber;
a897a37a 1008 } else digits[4]=-1;
1009
a9e2aefa 1010 AliMUONTransientDigit* pdigit;
a897a37a 1011 // build the list of fired pads and update the info
a9e2aefa 1012 if (!hitMap[nch]->TestHit(ipx, ipy)) {
a897a37a 1013
1014 list->AddAtAndExpand(
a9e2aefa 1015 new AliMUONTransientDigit(nch,digits),counter);
a897a37a 1016
a9e2aefa 1017 hitMap[nch]->SetHit(ipx, ipy, counter);
a897a37a 1018 counter++;
a9e2aefa 1019 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
a897a37a 1020 // list of tracks
1021 TObjArray *trlist=(TObjArray*)pdigit->TrackList();
1022 trlist->Add(&trinfo);
1023 } else {
a9e2aefa 1024 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
a897a37a 1025 // update charge
1026 (*pdigit).fSignal+=iqpad;
1027 (*pdigit).fPhysics+=iqpad;
1028 // update list of tracks
1029 TObjArray* trlist=(TObjArray*)pdigit->TrackList();
a9e2aefa 1030 Int_t lastEntry=trlist->GetLast();
1031 TVector *pTrack=(TVector*)trlist->At(lastEntry);
1032 TVector &ptrk=*pTrack;
1033 Int_t lastTrack=Int_t(ptrk(0));
1034 Int_t lastCharge=Int_t(ptrk(1));
1035 if (lastTrack==track) {
1036 lastCharge+=iqpad;
1037 trlist->RemoveAt(lastEntry);
1038 trinfo(0)=lastTrack;
1039 trinfo(1)=lastCharge;
1040 trlist->AddAt(&trinfo,lastEntry);
a897a37a 1041 } else {
1042 trlist->Add(&trinfo);
1043 }
1044 // check the track list
1045 Int_t nptracks=trlist->GetEntriesFast();
1046 if (nptracks > 2) {
1047 for (Int_t tr=0;tr<nptracks;tr++) {
a9e2aefa 1048 TVector *ppTrack=(TVector*)trlist->At(tr);
1049 TVector &pptrk=*ppTrack;
a897a37a 1050 trk[tr]=Int_t(pptrk(0));
1051 chtrk[tr]=Int_t(pptrk(1));
1052 }
1053 } // end if nptracks
1054 } // end if pdigit
1055 } //end loop over clusters
1056 } // hit loop
1057 } // track loop
a897a37a 1058
1059 // open the file with background
1060
a9e2aefa 1061 if (addBackground) {
1062 ntracks =(Int_t)fTrH1->GetEntries();
a897a37a 1063//
1064// Loop over tracks
1065//
1066 for (Int_t track=0; track<ntracks; track++) {
1067
1068 if (fHits2) fHits2->Clear();
a9e2aefa 1069 if (fPadHits2) fPadHits2->Clear();
a897a37a 1070
a9e2aefa 1071 fTrH1->GetEvent(track);
a897a37a 1072//
1073// Loop over hits
a9e2aefa 1074 AliMUONHit* mHit;
a897a37a 1075 for(int i=0;i<fHits2->GetEntriesFast();++i)
a9e2aefa 1076 {
1077 mHit=(AliMUONHit*) (*fHits2)[i];
a897a37a 1078 Int_t nch = mHit->fChamber-1; // chamber number
1079 if (nch >9) continue;
a9e2aefa 1080 iChamber = &(pMUON->Chamber(nch));
a897a37a 1081 Int_t rmin = (Int_t)iChamber->RInner();
1082 Int_t rmax = (Int_t)iChamber->ROuter();
1083 Float_t xbgr=mHit->fX;
1084 Float_t ybgr=mHit->fY;
a6f39961 1085 Bool_t cond=kFALSE;
a897a37a 1086
1087 for (Int_t imuon =0; imuon < nmuon[nch]; imuon++) {
1088 Float_t dist= (xbgr-xhit[nch][imuon])*(xbgr-xhit[nch][imuon])
1089 +(ybgr-yhit[nch][imuon])*(ybgr-yhit[nch][imuon]);
a6f39961 1090 if (dist<100) cond=kTRUE;
a897a37a 1091 }
1092 if (!cond) continue;
1093
1094//
1095// Loop over pad hits
a9e2aefa 1096 for (AliMUONPadHit* mPad=
1097 (AliMUONPadHit*)pMUON->FirstPad(mHit,fPadHits2);
a897a37a 1098 mPad;
a9e2aefa 1099 mPad=(AliMUONPadHit*)pMUON->NextPad(fPadHits2))
a897a37a 1100 {
a9e2aefa 1101 // mPad = (AliMUONPadHit*) (*fPadHits2)[j];
a897a37a 1102 Int_t cathode = mPad->fCathode; // cathode number
1103 Int_t ipx = mPad->fPadX; // pad number on X
1104 Int_t ipy = mPad->fPadY; // pad number on Y
a9e2aefa 1105 Int_t iqpad = Int_t(mPad->fQpad);// charge per pad
a897a37a 1106
1107 if (cathode != (icat+1)) continue;
a897a37a 1108 Float_t thex, they;
a9e2aefa 1109 segmentation=iChamber->SegmentationModel(cathode);
a897a37a 1110 segmentation->GetPadCxy(ipx,ipy,thex,they);
1111 Float_t rpad=TMath::Sqrt(thex*thex+they*they);
1112 if (rpad < rmin || iqpad ==0 || rpad > rmax) continue;
a9e2aefa 1113 new((*pAddress)[countadr++]) TVector(2);
1114 TVector &trinfo=*((TVector*) (*pAddress)[countadr-1]);
1115 trinfo(0)=-1; // tag background
1116 trinfo(1)=-1;
1117
a897a37a 1118 digits[0]=ipx;
1119 digits[1]=ipy;
1120 digits[2]=iqpad;
1121 digits[3]=0;
1122 digits[4]=-1;
a897a37a 1123
a9e2aefa 1124 AliMUONTransientDigit* pdigit;
1125 // build the list of fired pads and update the info
1126 if (!hitMap[nch]->TestHit(ipx, ipy)) {
1127 list->AddAtAndExpand(new AliMUONTransientDigit(nch,digits),counter);
1128
1129 hitMap[nch]->SetHit(ipx, ipy, counter);
a897a37a 1130 counter++;
1131
a9e2aefa 1132 pdigit=(AliMUONTransientDigit*)list->At(list->GetLast());
a897a37a 1133 // list of tracks
a9e2aefa 1134 TObjArray *trlist=(TObjArray*)pdigit->
1135 TrackList();
1136 trlist->Add(&trinfo);
a897a37a 1137 } else {
a9e2aefa 1138 pdigit=(AliMUONTransientDigit*) hitMap[nch]->GetHit(ipx, ipy);
a897a37a 1139 // update charge
1140 (*pdigit).fSignal+=iqpad;
a9e2aefa 1141
a897a37a 1142 // update list of tracks
a9e2aefa 1143 TObjArray* trlist=(TObjArray*)pdigit->
1144 TrackList();
1145 Int_t lastEntry=trlist->GetLast();
1146 TVector *pTrack=(TVector*)trlist->
1147 At(lastEntry);
1148 TVector &ptrk=*pTrack;
1149 Int_t lastTrack=Int_t(ptrk(0));
1150 if (lastTrack==-1) {
1151 continue;
1152 } else {
1153 trlist->Add(&trinfo);
1154 }
a897a37a 1155 // check the track list
a9e2aefa 1156 Int_t nptracks=trlist->GetEntriesFast();
1157 if (nptracks > 0) {
1158 for (Int_t tr=0;tr<nptracks;tr++) {
1159 TVector *ppTrack=(TVector*)trlist->At(tr);
1160 TVector &pptrk=*ppTrack;
1161 trk[tr]=Int_t(pptrk(0));
1162 chtrk[tr]=Int_t(pptrk(1));
1163 }
1164 } // end if nptracks
a897a37a 1165 } // end if pdigit
1166 } //end loop over clusters
1167 } // hit loop
1168 } // track loop
1169 //Int_t nentr2=list->GetEntriesFast();
1170 //printf(" \n counter2, nentr2 %d %d \n",counter,nentr2);
1171 TTree *fAli=gAlice->TreeK();
a9e2aefa 1172 TFile *file=NULL;
a897a37a 1173
1174 if (fAli) file =fAli->GetCurrentFile();
1175 file->cd();
d09fafb0 1176 } // if addBackground
1177 delete [] xhit;
1178 delete [] yhit;
1179
a897a37a 1180 Int_t tracks[10];
1181 Int_t charges[10];
a897a37a 1182 Int_t nentries=list->GetEntriesFast();
a897a37a 1183
1184 for (Int_t nent=0;nent<nentries;nent++) {
a9e2aefa 1185 AliMUONTransientDigit *address=(AliMUONTransientDigit*)list->At(nent);
a897a37a 1186 if (address==0) continue;
1187 Int_t ich=address->fChamber;
1188 Int_t q=address->fSignal;
a9e2aefa 1189 iChamber=(AliMUONChamber*) (*fChambers)[ich];
1190//
1191// Digit Response (noise, threshold, saturation, ...)
1192// if (address->fPhysics !=0 ) address->fPhysics+=(Int_t)Noise;
1193 AliMUONResponse * response=iChamber->ResponseModel();
1194 q=response->DigitResponse(q);
1195
1196 if (!q) continue;
1197
a897a37a 1198 digits[0]=address->fPadX;
1199 digits[1]=address->fPadY;
1200 digits[2]=q;
1201 digits[3]=address->fPhysics;
1202 digits[4]=address->fHit;
a897a37a 1203
1204 TObjArray* trlist=(TObjArray*)address->TrackList();
1205 Int_t nptracks=trlist->GetEntriesFast();
1206 //printf("nptracks, trlist %d %p\n",nptracks,trlist);
1207
a9e2aefa 1208 // this was changed to accomodate the real number of tracks
1209 if (nptracks > 10) {
1210 cout<<"Attention - nptracks > 10 "<<nptracks<<endl;
1211 nptracks=10;
1212 }
1213 if (nptracks > 2) {
1214 printf("Attention - nptracks > 2 %d \n",nptracks);
1215 printf("cat,ich,ix,iy,q %d %d %d %d %d \n",icat,ich,digits[0],digits[1],q);
1216 }
1217 for (Int_t tr=0;tr<nptracks;tr++) {
1218 TVector *ppP=(TVector*)trlist->At(tr);
1219 if(!ppP ) printf("ppP - %p\n",ppP);
1220 TVector &pp =*ppP;
1221 tracks[tr]=Int_t(pp(0));
1222 charges[tr]=Int_t(pp(1));
a897a37a 1223 //printf("tracks, charges - %d %d\n",tracks[tr],charges[tr]);
a9e2aefa 1224 } //end loop over list of tracks for one pad
a897a37a 1225 // Sort list of tracks according to charge
a9e2aefa 1226 if (nptracks > 1) {
1227 SortTracks(tracks,charges,nptracks);
1228 }
1229 if (nptracks < 10 ) {
1230 for (Int_t i=nptracks; i<10; i++) {
1231 tracks[i]=0;
1232 charges[i]=0;
a897a37a 1233 }
a9e2aefa 1234 }
1235
a897a37a 1236 // fill digits
a9e2aefa 1237 pMUON->AddDigits(ich,tracks,charges,digits);
1238 // delete trlist;
a897a37a 1239 }
1240 //cout<<"I'm out of the loops for digitisation"<<endl;
a9e2aefa 1241 // gAlice->GetEvent(nev);
a897a37a 1242 gAlice->TreeD()->Fill();
a9e2aefa 1243 pMUON->ResetDigits();
a897a37a 1244 list->Delete();
d09fafb0 1245
a9e2aefa 1246
f665c1ea 1247 for(Int_t ii=0;ii<AliMUONConstants::NCh();++ii) {
a9e2aefa 1248 if (hitMap[ii]) {
1249 hm=hitMap[ii];
a897a37a 1250 delete hm;
a9e2aefa 1251 hitMap[ii]=0;
fe4da5cc 1252 }
a897a37a 1253 }
d09fafb0 1254 delete [] nmuon;
a897a37a 1255 } //end loop over cathodes
d09fafb0 1256 delete [] hitMap;
a9e2aefa 1257 char hname[30];
1258 sprintf(hname,"TreeD%d",nev);
1259 gAlice->TreeD()->Write(hname);
1260 // reset tree
1261 gAlice->TreeD()->Reset();
1262 delete list;
1263
1264 pAddress->Delete();
1265 // gObjectTable->Print();
a897a37a 1266}
1267
1268void AliMUON::SortTracks(Int_t *tracks,Int_t *charges,Int_t ntr)
1269{
1270 //
1271 // Sort the list of tracks contributing to a given digit
1272 // Only the 3 most significant tracks are acctually sorted
1273 //
1274
1275 //
1276 // Loop over signals, only 3 times
1277 //
1278
1279 Int_t qmax;
1280 Int_t jmax;
1281 Int_t idx[3] = {-2,-2,-2};
1282 Int_t jch[3] = {-2,-2,-2};
1283 Int_t jtr[3] = {-2,-2,-2};
1284 Int_t i,j,imax;
1285
1286 if (ntr<3) imax=ntr;
1287 else imax=3;
1288 for(i=0;i<imax;i++){
1289 qmax=0;
1290 jmax=0;
1291
1292 for(j=0;j<ntr;j++){
1293
1294 if((i == 1 && j == idx[i-1])
1295 ||(i == 2 && (j == idx[i-1] || j == idx[i-2]))) continue;
1296
1297 if(charges[j] > qmax) {
1298 qmax = charges[j];
1299 jmax=j;
1300 }
1301 }
1302
1303 if(qmax > 0) {
1304 idx[i]=jmax;
1305 jch[i]=charges[jmax];
1306 jtr[i]=tracks[jmax];
1307 }
1308
1309 }
1310
1311 for(i=0;i<3;i++){
1312 if (jtr[i] == -2) {
1313 charges[i]=0;
1314 tracks[i]=0;
1315 } else {
1316 charges[i]=jch[i];
1317 tracks[i]=jtr[i];
1318 }
1319 }
1320
fe4da5cc 1321}
1322
a9e2aefa 1323//___________________________________________
1324void AliMUON::Trigger(Int_t nev){
1325// call the Trigger Algorithm and fill TreeR
1326
1327 Int_t singlePlus[3] = {0,0,0};
1328 Int_t singleMinus[3] = {0,0,0};
1329 Int_t singleUndef[3] = {0,0,0};
1330 Int_t pairUnlike[3] = {0,0,0};
1331 Int_t pairLike[3] = {0,0,0};
1332
1333 ResetTrigger();
a9e2aefa 1334 AliMUONTriggerDecision* decision= new AliMUONTriggerDecision(1);
1335 decision->Trigger();
1336 decision->GetGlobalTrigger(singlePlus, singleMinus, singleUndef,
1337 pairUnlike, pairLike);
1338// add a local trigger in the list
1339 AddGlobalTrigger(singlePlus, singleMinus, singleUndef, pairUnlike, pairLike);
9ae15266 1340 Int_t i;
a9e2aefa 1341
f665c1ea 1342 for (Int_t icirc=0; icirc<AliMUONConstants::NTriggerCircuit(); icirc++) {
9ae15266 1343 if(decision->GetITrigger(icirc)==1) {
1344 Int_t localtr[7]={0,0,0,0,0,0,0};
1345 Int_t loLpt[2]={0,0}; Int_t loHpt[2]={0,0}; Int_t loApt[2]={0,0};
1346 decision->GetLutOutput(icirc, loLpt, loHpt, loApt);
1347 localtr[0] = icirc;
1348 localtr[1] = decision->GetStripX11(icirc);
1349 localtr[2] = decision->GetDev(icirc);
1350 localtr[3] = decision->GetStripY11(icirc);
1351 for (i=0; i<2; i++) { // convert the Lut output in 1 digit
1352 localtr[4] = localtr[4]+Int_t(loLpt[i]*TMath::Power(2,i));
1353 localtr[5] = localtr[5]+Int_t(loHpt[i]*TMath::Power(2,i));
1354 localtr[6] = localtr[6]+Int_t(loApt[i]*TMath::Power(2,i));
1355 }
1356 AddLocalTrigger(localtr); // add a local trigger in the list
a897a37a 1357 }
a9e2aefa 1358 }
1359 delete decision;
a897a37a 1360
a9e2aefa 1361 gAlice->TreeR()->Fill();
1362 ResetTrigger();
a897a37a 1363 char hname[30];
1364 sprintf(hname,"TreeR%d",nev);
1365 gAlice->TreeR()->Write(hname);
1366 gAlice->TreeR()->Reset();
a9e2aefa 1367 printf("\n End of trigger for event %d", nev);
a897a37a 1368}
a897a37a 1369
a897a37a 1370
a9e2aefa 1371//____________________________________________
1372void AliMUON::FindClusters(Int_t nev,Int_t lastEntry)
1373{
1374 TClonesArray *dig1, *dig2;
1375 Int_t ndig, k;
1376 dig1 = new TClonesArray("AliMUONDigit",1000);
1377 dig2 = new TClonesArray("AliMUONDigit",1000);
1378 AliMUONDigit *digit;
a897a37a 1379//
a9e2aefa 1380// Loop on chambers and on cathode planes
a897a37a 1381//
a897a37a 1382
a9e2aefa 1383 for (Int_t ich=0;ich<10;ich++) {
1384 AliMUONChamber* iChamber=(AliMUONChamber*) (*fChambers)[ich];
1385 AliMUONClusterFinder* rec = iChamber->ReconstructionModel();
1386 gAlice->ResetDigits();
1387 gAlice->TreeD()->GetEvent(lastEntry);
1388 TClonesArray *muonDigits = this->DigitsAddress(ich);
1389 ndig=muonDigits->GetEntriesFast();
1390 printf("\n 1 Found %d digits in %p %d", ndig, muonDigits,ich);
1391 TClonesArray &lhits1 = *dig1;
1392 Int_t n=0;
1393 for (k=0; k<ndig; k++) {
1394 digit=(AliMUONDigit*) muonDigits->UncheckedAt(k);
1395 if (rec->TestTrack(digit->fTracks[0]))
1396 new(lhits1[n++]) AliMUONDigit(*digit);
1397 }
1398 gAlice->ResetDigits();
1399 gAlice->TreeD()->GetEvent(lastEntry+1);
1400 muonDigits = this->DigitsAddress(ich);
1401 ndig=muonDigits->GetEntriesFast();
1402 printf("\n 2 Found %d digits in %p %d", ndig, muonDigits, ich);
1403 TClonesArray &lhits2 = *dig2;
1404 n=0;
1405
1406 for (k=0; k<ndig; k++) {
1407 digit= (AliMUONDigit*) muonDigits->UncheckedAt(k);
1408 if (rec->TestTrack(digit->fTracks[0]))
1409 new(lhits2[n++]) AliMUONDigit(*digit);
a897a37a 1410 }
a897a37a 1411
a9e2aefa 1412 if (rec) {
1413 rec->SetDigits(dig1, dig2);
1414 rec->SetChamber(ich);
1415 rec->FindRawClusters();
1416 }
1417 dig1->Delete();
1418 dig2->Delete();
1419 } // for ich
1420 gAlice->TreeR()->Fill();
1421 ResetRawClusters();
1422 char hname[30];
1423 sprintf(hname,"TreeR%d",nev);
1424 gAlice->TreeR()->Write(hname);
1425 gAlice->TreeR()->Reset();
1426 printf("\n End of cluster finding for event %d", nev);
1427
1428 delete dig1;
1429 delete dig2;
1430 //gObjectTable->Print();
a897a37a 1431}
a9e2aefa 1432
a897a37a 1433
fe4da5cc 1434void AliMUON::Streamer(TBuffer &R__b)
1435{
1436 // Stream an object of class AliMUON.
a9e2aefa 1437 AliMUONChamber *iChamber;
1438 AliMUONTriggerCircuit *iTriggerCircuit;
1439 AliMUONSegmentation *segmentation;
1440 AliMUONResponse *response;
fe4da5cc 1441 TClonesArray *digitsaddress;
a897a37a 1442 TClonesArray *rawcladdress;
9ae15266 1443 Int_t i;
9ae15266 1444 if (R__b.IsReading()) {
1445 Version_t R__v = R__b.ReadVersion(); if (R__v) { }
1446 AliDetector::Streamer(R__b);
1447 R__b >> fNPadHits;
1448 R__b >> fPadHits; // diff
1449 R__b >> fNLocalTrigger;
1450 R__b >> fLocalTrigger;
1451 R__b >> fNGlobalTrigger;
1452 R__b >> fGlobalTrigger;
1453 R__b >> fDchambers;
1454 R__b >> fRawClusters;
1455 R__b.ReadArray(fNdch);
1456 R__b.ReadArray(fNrawch);
1457 R__b >> fAccCut;
1458 R__b >> fAccMin;
1459 R__b >> fAccMax;
1460 R__b >> fChambers;
1461 R__b >> fTriggerCircuits;
f665c1ea 1462 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
9ae15266 1463 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1464 iTriggerCircuit->Streamer(R__b);
fe4da5cc 1465 }
9ae15266 1466// Stream chamber related information
f665c1ea 1467 for (i =0; i<AliMUONConstants::NCh(); i++) {
9ae15266 1468 iChamber=(AliMUONChamber*) (*fChambers)[i];
1469 iChamber->Streamer(R__b);
1470 if (iChamber->Nsec()==1) {
1471 segmentation=iChamber->SegmentationModel(1);
1472 if (segmentation)
1473 segmentation->Streamer(R__b);
1474 } else {
1475 segmentation=iChamber->SegmentationModel(1);
1476 if (segmentation)
1477 segmentation->Streamer(R__b);
1478 if (segmentation)
1479 segmentation=iChamber->SegmentationModel(2);
1480 segmentation->Streamer(R__b);
1481 }
1482 response=iChamber->ResponseModel();
1483 if (response)
1484 response->Streamer(R__b);
1485 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1486 digitsaddress->Streamer(R__b);
f665c1ea 1487 if (i < AliMUONConstants::NTrackingCh()) {
9ae15266 1488 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1489 rawcladdress->Streamer(R__b);
1490 }
a9e2aefa 1491 }
9ae15266 1492
1493 } else {
1494 R__b.WriteVersion(AliMUON::IsA());
1495 AliDetector::Streamer(R__b);
1496 R__b << fNPadHits;
1497 R__b << fPadHits; // diff
1498 R__b << fNLocalTrigger;
1499 R__b << fLocalTrigger;
1500 R__b << fNGlobalTrigger;
1501 R__b << fGlobalTrigger;
1502 R__b << fDchambers;
1503 R__b << fRawClusters;
f665c1ea 1504 R__b.WriteArray(fNdch, AliMUONConstants::NCh());
1505 R__b.WriteArray(fNrawch, AliMUONConstants::NTrackingCh());
9ae15266 1506
1507 R__b << fAccCut;
1508 R__b << fAccMin;
1509 R__b << fAccMax;
1510
1511 R__b << fChambers;
1512 R__b << fTriggerCircuits;
f665c1ea 1513 for (i =0; i<AliMUONConstants::NTriggerCircuit(); i++) {
9ae15266 1514 iTriggerCircuit=(AliMUONTriggerCircuit*) (*fTriggerCircuits)[i];
1515 iTriggerCircuit->Streamer(R__b);
fe4da5cc 1516 }
f665c1ea 1517 for (i =0; i<AliMUONConstants::NCh(); i++) {
9ae15266 1518 iChamber=(AliMUONChamber*) (*fChambers)[i];
1519 iChamber->Streamer(R__b);
1520 if (iChamber->Nsec()==1) {
1521 segmentation=iChamber->SegmentationModel(1);
1522 if (segmentation)
1523 segmentation->Streamer(R__b);
1524 } else {
1525 segmentation=iChamber->SegmentationModel(1);
1526 if (segmentation)
1527 segmentation->Streamer(R__b);
1528 segmentation=iChamber->SegmentationModel(2);
1529 if (segmentation)
1530 segmentation->Streamer(R__b);
1531 }
1532 response=iChamber->ResponseModel();
1533 if (response)
1534 response->Streamer(R__b);
1535 digitsaddress=(TClonesArray*) (*fDchambers)[i];
1536 digitsaddress->Streamer(R__b);
f665c1ea 1537 if (i < AliMUONConstants::NTrackingCh()) {
9ae15266 1538 rawcladdress=(TClonesArray*) (*fRawClusters)[i];
1539 rawcladdress->Streamer(R__b);
1540 }
a9e2aefa 1541 }
fe4da5cc 1542 }
fe4da5cc 1543}
a9e2aefa 1544AliMUONPadHit* AliMUON::FirstPad(AliMUONHit* hit, TClonesArray *clusters)
fe4da5cc 1545{
1546//
1547 // Initialise the pad iterator
1548 // Return the address of the first padhit for hit
a897a37a 1549 TClonesArray *theClusters = clusters;
fe4da5cc 1550 Int_t nclust = theClusters->GetEntriesFast();
1551 if (nclust && hit->fPHlast > 0) {
a9e2aefa 1552 AliMUON::fMaxIterPad=hit->fPHlast;
1553 AliMUON::fCurIterPad=hit->fPHfirst;
1554 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
fe4da5cc 1555 } else {
1556 return 0;
1557 }
1558}
1559
a9e2aefa 1560AliMUONPadHit* AliMUON::NextPad(TClonesArray *clusters)
fe4da5cc 1561{
a9e2aefa 1562 AliMUON::fCurIterPad++;
1563 if (AliMUON::fCurIterPad <= AliMUON::fMaxIterPad) {
1564 return (AliMUONPadHit*) clusters->UncheckedAt(AliMUON::fCurIterPad-1);
fe4da5cc 1565 } else {
1566 return 0;
1567 }
1568}
1569
a897a37a 1570
1571AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
1572{
a9e2aefa 1573 TClonesArray *muonRawCluster = RawClustAddress(ichamber);
a897a37a 1574 ResetRawClusters();
a9e2aefa 1575 TTree *treeR = gAlice->TreeR();
1576 Int_t nent=(Int_t)treeR->GetEntries();
1577 treeR->GetEvent(nent-2+icathod-1);
1578 //treeR->GetEvent(icathod);
1579 //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
a897a37a 1580
a9e2aefa 1581 AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
a897a37a 1582 //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
1583
1584 return mRaw;
1585}
1586
a9e2aefa 1587AliMUON& AliMUON::operator = (const AliMUON& rhs)
a897a37a 1588{
a9e2aefa 1589// copy operator
1590// dummy version
1591 return *this;
a897a37a 1592}
1593
1594
1595
a897a37a 1596
1597
fe4da5cc 1598
fe4da5cc 1599
fe4da5cc 1600
fe4da5cc 1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611