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