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