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