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