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