Added comments for inline functions
[u/mrichter/AliRoot.git] / MUON / AliMUON.cxx
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  **************************************************************************/
15
16 /* $Id$ */
17
18 // ------------------
19 // Class AliMUON
20 // ------------------
21 // AliDetector class for MUON subsystem 
22 // providing simulation data management 
23
24 #include "Riostream.h"
25
26 #include <AliPDG.h>
27 #include <TBRIK.h>
28 #include <TCanvas.h>
29 #include <TDirectory.h>
30 #include <TFile.h>
31 #include <TGeometry.h>
32 #include <TMinuit.h>
33 #include <TNode.h> 
34 #include <TNtuple.h>
35 #include <TObjArray.h>
36 #include <TObject.h>
37 #include <TObjectTable.h>
38 #include <TPad.h>
39 #include <TParticle.h>
40 #include <TROOT.h>
41 #include <TRandom.h> 
42 #include <TRotMatrix.h>
43 #include <TTUBE.h>
44 #include <TTUBE.h>
45 #include <TTree.h> 
46 #include <TVector.h>
47 #include <TVirtualMC.h>
48
49 //#include "AliHeader.h"
50 #include "AliLoader.h"
51 #include "AliRunDigitizer.h"
52 #include "AliMC.h"
53 #include "AliRun.h"     
54 #include "AliMUON.h"
55 #include "AliMUONChamberTrigger.h"
56 #include "AliMUONConstants.h"
57 #include "AliMUONHit.h" 
58 #include "AliMUONRawCluster.h"
59 #include "AliMUONTransientDigit.h"
60 #include "AliMUONTriggerCircuit.h"
61 #include "AliMUONTriggerCircuitNew.h"
62 #include "AliMUONGeometry.h"
63 #include "AliMUONGeometryTransformer.h"
64 #include "AliMUONGeometryBuilder.h"
65 #include "AliMUONCommonGeometryBuilder.h"
66 #include "AliMUONVGeometryBuilder.h"    
67 #include "AliMUONGeometrySegmentation.h"
68 #include "AliMUONDigitizerv2.h"
69 #include "AliMUONSDigitizerv1.h"
70 #include "AliMUONRawWriter.h"
71 #include "AliMUONSegmentation.h"
72 #include "AliLog.h"
73
74 #include "AliMUONSDigitizerV2.h"
75 #include "AliMUONDigitizerV3.h"
76
77 #include "AliMUONSt1GeometryBuilderV2.h"
78 #include "AliMUONSt2GeometryBuilderV2.h"
79 #include "AliMUONSlatGeometryBuilder.h"
80 #include "AliMUONTriggerGeometryBuilder.h"
81
82 // Defaults parameters for Z positions of chambers
83 // taken from values for "stations" in AliMUON::AliMUON
84 //     const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
85 // and from array "dstation" in AliMUONv1::CreateGeometry
86 //          Float_t dstation[5]={20., 20., 20, 20., 20.};
87 //     for tracking chambers,
88 //          according to (Z1 = zch - dstation) and  (Z2 = zch + dstation)
89 //          for the first and second chambers in the station, respectively,
90 // and from "DTPLANES" in AliMUONv1::CreateGeometry
91 //           const Float_t DTPLANES = 15.;
92 //     for trigger chambers,
93 //          according to (Z1 = zch) and  (Z2 = zch + DTPLANES)
94 //          for the first and second chambers in the station, respectively
95
96 ClassImp(AliMUON)
97
98 //__________________________________________________________________
99 AliMUON::AliMUON()
100   : AliDetector(),
101     fNCh(0),
102     fNTrackingCh(0),
103     fMUONData(0),
104     fSplitLevel(0),
105     fChambers(0),
106     fTriggerCircuits(0),
107     fTriggerCircuitsNew(0),
108     fGeometryBuilder(0),
109     fSegmentation(0),
110     fAccCut(kFALSE),
111     fAccMin(0.),
112     fAccMax(0.),   
113     fMaxStepGas(0.),
114     fMaxStepAlu(0.),
115     fMaxDestepGas(0.),
116     fMaxDestepAlu(0.),
117     fMaxIterPad(0),
118     fCurIterPad(0),
119     fTriggerScalerEvent(kFALSE),
120     fSDigitizerType(""),
121     fDigitizerType(""),
122   fRawWriter(0x0)
123 {
124 /// Default Constructor
125     
126     AliDebug(1,Form("default (empty) ctor this=%p",this));
127     fIshunt          = 0;
128 }
129
130 //__________________________________________________________________
131 AliMUON::AliMUON(const char *name, const char *title,
132                  const char* sDigitizerClassName,
133                  const char* digitizerClassName)
134   : AliDetector(name,title),
135     fNCh(AliMUONConstants::NCh()),
136     fNTrackingCh(AliMUONConstants::NTrackingCh()),
137     fMUONData(0),
138     fSplitLevel(0),
139     fChambers(0),
140     fTriggerCircuits(0),
141     fTriggerCircuitsNew(0),
142     fGeometryBuilder(0),
143     fSegmentation(0),
144     fAccCut(kFALSE),
145     fAccMin(0.),
146     fAccMax(0.),   
147     fMaxStepGas(0.1),
148     fMaxStepAlu(0.1),
149     fMaxDestepGas(-1), // Negatives values are ignored by geant3 CONS200 
150     fMaxDestepAlu(-1), // in the calculation of the tracking parameters
151     fMaxIterPad(0),
152     fCurIterPad(0),
153           fTriggerScalerEvent(kFALSE),
154     fSDigitizerType(sDigitizerClassName),
155     fDigitizerType(digitizerClassName),
156   fRawWriter(0x0)
157 {
158 /// Standard constructor  
159   
160   AliDebug(1,Form("ctor this=%p",this));
161   fIshunt =  0;
162
163   SetMarkerColor(kRed);//
164     
165   // Geometry builder
166   fGeometryBuilder = new AliMUONGeometryBuilder(this);
167   
168   // Common geometry definitions
169   fGeometryBuilder
170     ->AddBuilder(new AliMUONCommonGeometryBuilder(this));
171
172   // By default, add also all the needed geometry builders.
173   // If you want to change this from outside, please use ResetGeometryBuilder
174   // method, followed by AddGeometryBuilder ones.
175
176   AddGeometryBuilder(new AliMUONSt1GeometryBuilderV2(this));
177   AddGeometryBuilder(new AliMUONSt2GeometryBuilderV2(this));
178   AddGeometryBuilder(new AliMUONSlatGeometryBuilder(this));
179   AddGeometryBuilder(new AliMUONTriggerGeometryBuilder(this));
180   
181   //
182   // Creating List of Chambers
183     Int_t ch;
184     fChambers = new TObjArray(AliMUONConstants::NCh());
185
186     // Loop over stations
187     for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
188       // Loop over 2 chambers in the station
189       for (Int_t stCH = 0; stCH < 2; stCH++) {
190         //
191         //    
192         //    Default Parameters for Muon Tracking Stations
193         ch = 2 * st + stCH;
194         if (ch < AliMUONConstants::NTrackingCh()) {
195           fChambers->AddAt(new AliMUONChamber(ch),ch);
196         } else {
197           fChambers->AddAt(new AliMUONChamberTrigger(ch, GetGeometryTransformer()),ch);
198         }
199       } // Chamber stCH (0, 1) in 
200     }     // Station st (0...)
201     
202     // cp new design of AliMUONTriggerDecision
203     fTriggerCircuits = new TObjArray(AliMUONConstants::NTriggerCircuit());
204     for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
205       fTriggerCircuits->AddAt(new AliMUONTriggerCircuit(),circ);          
206     }
207
208     fTriggerCircuitsNew = new TObjArray(AliMUONConstants::NTriggerCircuit());
209     for (Int_t circ=0; circ<AliMUONConstants::NTriggerCircuit(); circ++) {
210       fTriggerCircuitsNew->AddAt(new AliMUONTriggerCircuitNew(),circ);          
211     }
212     
213 }
214
215 //____________________________________________________________________
216 AliMUON::AliMUON(const AliMUON& rMUON)
217  : AliDetector(rMUON)
218 {
219 /// Protected copy constructor
220
221   AliFatal("Not implemented.");
222 }
223
224 //____________________________________________________________________
225 AliMUON::~AliMUON()
226 {
227 /// Destructor
228
229   AliDebug(1,Form("dtor this=%p",this));
230   fIshunt  = 0;
231
232   if (fChambers){
233     fChambers->Delete();
234     delete fChambers;
235   }
236   if (fTriggerCircuits){
237     fTriggerCircuits->Delete();
238     delete fTriggerCircuits;
239   }
240   if (fTriggerCircuitsNew){
241     fTriggerCircuitsNew->Delete();
242     delete fTriggerCircuitsNew;
243   }
244   
245   delete fMUONData;
246   delete fGeometryBuilder;
247   delete fSegmentation;
248   delete fRawWriter;
249 }
250
251 //________________________________________________________________________
252 AliMUON& AliMUON::operator = (const AliMUON& rhs)
253 {
254 /// Protected assignement operator
255
256   if (this == &rhs) return *this;
257
258   AliFatal("Not implemented.");
259     
260   return *this;  
261 }
262
263 //_____________________________________________________________________________
264 void AliMUON::AddGeometryBuilder(AliMUONVGeometryBuilder* geomBuilder)
265 {
266 /// Add the geometry builder to the list
267
268   fGeometryBuilder->AddBuilder(geomBuilder);
269 }
270
271 //____________________________________________________________________
272 void AliMUON::BuildGeometry()
273 {
274 /// Geometry for event display
275
276
277 //     for (Int_t i = 0; i < AliMUONConstants::NCh(); i++)     
278 //       this->Chamber(i).SegmentationModel2(1)->Draw("eventdisplay");// to be check !
279      
280   
281 }
282
283 //____________________________________________________________________
284 const AliMUONGeometry*  AliMUON::GetGeometry() const
285 {
286 /// Return geometry parametrisation
287
288   if ( !fGeometryBuilder) {
289     AliWarningStream() << "GeometryBuilder not defined." << std::endl;
290     return 0;
291   }
292   
293   return fGeometryBuilder->GetGeometry();
294 }   
295
296 //____________________________________________________________________
297 const AliMUONGeometryTransformer*  AliMUON::GetGeometryTransformer() const
298 {
299 /// Return geometry parametrisation
300
301   const AliMUONGeometry* kGeometry = GetGeometry();
302   
303   if ( !kGeometry) return 0;
304
305   return kGeometry->GetTransformer();
306 }   
307
308 //__________________________________________________________________
309 void  AliMUON::SetTreeAddress()
310 {
311 /// Set Hits tree address
312
313   GetMUONData()->SetLoader(fLoader); 
314   //  GetMUONData()->MakeBranch("D,S,RC");
315   //  GetMUONData()->SetTreeAddress("H,D,S,RC");
316   GetMUONData()->SetTreeAddress("H");
317   if (fHits !=  GetMUONData()->Hits())  {
318     if ( gAlice->GetMCApp() )
319       if ( gAlice->GetMCApp()->GetHitLists() ) {
320         fHits = GetMUONData()->Hits();
321         gAlice->GetMCApp()->AddHitList(fHits); // For purifyKine, only necessary when Hit list is created in AliMUONData
322       }  
323   }
324   fHits = GetMUONData()->Hits(); // Added by Ivana to use the methods FisrtHit, NextHit of AliDetector    
325 }
326
327 //_________________________________________________________________
328 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
329 {
330 /// Set the inverse charge slope for chamber id
331
332     Int_t i=2*(id-1);    //PH    ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
333     //PH    ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
334     ((AliMUONChamber*) fChambers->At(i))->SetChargeSlope(p1);
335     ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSlope(p1);
336 }
337 //__________________________________________________________________
338 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
339 {
340 /// Set sigma of charge spread for chamber id
341
342     Int_t i=2*(id-1);
343     ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
344     ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSpread(p1,p2);
345 }
346 //___________________________________________________________________
347 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
348 {
349 /// Set integration limits for charge spread
350     Int_t i=2*(id-1);
351     ((AliMUONChamber*) fChambers->At(i))->SetSigmaIntegration(p1);
352     ((AliMUONChamber*) fChambers->At(i+1))->SetSigmaIntegration(p1);
353 }
354
355 //__________________________________________________________________
356 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
357 {
358 /// Set maximum number for ADCcounts (saturation)
359
360     Int_t i=2*(id-1);
361     ((AliMUONChamber*) fChambers->At(i))->SetMaxAdc(p1);
362     ((AliMUONChamber*) fChambers->At(i+1))->SetMaxAdc(p1);
363 }
364
365 //__________________________________________________________________
366 void AliMUON::SetMaxStepGas(Float_t p1)
367 {
368 /// Set stepsize in gas
369
370   fMaxStepGas=p1;
371 }
372 //__________________________________________________________________
373 void AliMUON::SetMaxStepAlu(Float_t p1)
374 {
375 /// Set step size in Alu
376
377     fMaxStepAlu=p1;
378 }
379 //__________________________________________________________________
380 void AliMUON::SetMaxDestepGas(Float_t p1)
381 {
382 /// Set maximum step size in Gas
383
384     fMaxDestepGas=p1;
385 }
386 //__________________________________________________________________
387 void AliMUON::SetMaxDestepAlu(Float_t p1)
388 {
389 /// Set maximum step size in Alu
390
391   fMaxDestepAlu=p1;
392 }
393
394 //____________________________________________________________________
395 Float_t  AliMUON::GetMaxStepGas() const
396 {
397 /// Return stepsize in gas
398   
399   return fMaxStepGas;
400 }  
401
402 //____________________________________________________________________
403 Float_t  AliMUON::GetMaxStepAlu() const
404 {
405 /// Return step size in Alu
406   
407   return fMaxStepAlu;
408 }
409   
410 //____________________________________________________________________
411 Float_t  AliMUON::GetMaxDestepGas() const
412 {
413 /// Return maximum step size in Gas
414   
415   return fMaxDestepGas;
416 }
417   
418 //____________________________________________________________________
419 Float_t  AliMUON::GetMaxDestepAlu() const
420 {
421 /// Return maximum step size in Gas
422   
423   return fMaxDestepAlu;
424 }
425
426 //____________________________________________________________________
427  void  AliMUON::SetAlign(Bool_t align)
428 {
429 /// Set option for alignement to geometry builder
430  
431    fGeometryBuilder->SetAlign(align);
432 }   
433
434 //____________________________________________________________________
435  void  AliMUON::SetAlign(const TString& fileName, Bool_t align)
436 {
437 /// Set option for alignement to geometry builder
438  
439    fGeometryBuilder->SetAlign(fileName, align);
440 }   
441
442 //____________________________________________________________________
443 void   AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
444 {
445 /// Set the response for chamber id
446     ((AliMUONChamber*) fChambers->At(id))->SetResponseModel(response);
447 }
448
449 //____________________________________________________________________
450 AliDigitizer* AliMUON::CreateDigitizer(AliRunDigitizer* manager) const
451 {
452 /// FIXME: the selection of the class should be done through a factory
453 /// mechanism. (see also Hits2SDigits()).
454   
455   AliInfo(Form("Digitizer used : %s",fDigitizerType.Data()));
456   
457   if ( fDigitizerType == "digitizer:default" )
458   {
459     return new AliMUONDigitizerv2(manager);
460   }
461   else if ( fDigitizerType == "digitizer:NewDigitizerNewTrigger" ) 
462   {
463     return new AliMUONDigitizerV3(manager,AliMUONDigitizerV3::kTriggerElectronics);
464   }
465   else if ( fDigitizerType == "digitizer:NewDigitizerOldTrigger" )
466   {
467     return new AliMUONDigitizerV3(manager,AliMUONDigitizerV3::kTriggerDecision, kFALSE, kFALSE);
468   }
469   else if ( fDigitizerType == "digitizer:NewDigitizerEffTrigger" )
470   {
471     return new AliMUONDigitizerV3(manager,AliMUONDigitizerV3::kTriggerDecision, kTRUE, kFALSE);
472   }  
473   else if ( fDigitizerType == "digitizer:NewDigitizerWithNoiseOldTrigger" )
474   {
475     return new AliMUONDigitizerV3(manager,AliMUONDigitizerV3::kTriggerDecision, kFALSE, kTRUE);
476   }    
477   else
478   {
479     AliFatal(Form("Unknown digitizer type : %s",fDigitizerType.Data()));
480   }
481   return 0x0;
482 }
483
484 //_____________________________________________________________________
485 TString
486 AliMUON::SDigitizerType() const
487 {
488 /// Return digitizer type
489
490   return fSDigitizerType;
491 }
492
493 //_____________________________________________________________________
494 void AliMUON::SDigits2Digits()
495 {
496 /// Write TreeD here only 
497
498     char hname[30];
499     //    sprintf(hname,"TreeD%d",fLoader->GetHeader()->GetEvent());
500     fLoader->TreeD()->Write(hname,TObject::kOverwrite);
501     fLoader->TreeD()->Reset();
502 }
503
504 //_____________________________________________________________________
505 void AliMUON::Hits2SDigits()
506 {
507 /// FIXME: the selection of the sdigitizer should be done through a
508 /// factory mechanism.
509   
510   AliInfo(Form("SDigitizer used : %s",fSDigitizerType.Data()));
511
512   if ( fSDigitizerType == "sdigitizer:default" )
513   {
514     // Adaption of AliMUONSDigitizerv1 to be excuted by the AliSimulation framework
515     AliRunLoader* runLoader = fLoader->GetRunLoader();
516     AliRunDigitizer   * manager = new AliRunDigitizer(1,1);
517     manager->SetInputStream(0,runLoader->GetFileName(),AliConfig::GetDefaultEventFolderName());
518     AliMUONDigitizer * dMUON   = new AliMUONSDigitizerv1(manager);
519     fLoader->LoadHits("READ");
520     for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
521       runLoader->GetEvent(iEvent);
522       dMUON->Exec("");
523     }
524     fLoader->UnloadHits();
525   }
526   else if ( fSDigitizerType == "sdigitizer:AliMUONSDigitizerV2" )
527   {
528     TTask* sdigitizer = new AliMUONSDigitizerV2;
529     sdigitizer->ExecuteTask();
530   }
531   else
532   {
533     AliFatal(Form("Unknown sdigitizer classname : %s",fSDigitizerType.Data()));
534   }
535 }
536
537 //_____________________________________________________________________
538 TString
539 AliMUON::DigitizerType() const
540 {
541 /// Return digitizer type
542
543   return fDigitizerType;
544 }
545
546 //_____________________________________________________________________
547 void AliMUON::Digits2Raw()
548 {
549 /// Convert digits of the current event to raw data
550
551   if (!fRawWriter)
552   {
553     fRawWriter = new AliMUONRawWriter(fMUONData);
554     if (fTriggerScalerEvent == kTRUE) 
555     {
556       fRawWriter->SetScalerEvent();
557     }
558   }
559   
560   if (!fRawWriter->Digits2Raw()) 
561   {
562     AliError("pb writting raw data");
563   }
564 }
565
566 //_______________________________________________________________________
567 AliLoader* AliMUON::MakeLoader(const char* topfoldername)
568
569 /// Build standard getter (AliLoader type);
570 /// if detector wants to use castomized getter, it must overload this method
571  
572  AliDebug(1,Form("Creating standard getter for detector %s. Top folder is %s.",
573          GetName(),topfoldername));
574  fLoader   = new AliLoader(GetName(),topfoldername);
575  fMUONData = new AliMUONData(fLoader,GetName(),GetName()); 
576  fMUONData->SetSplitLevel(fSplitLevel);
577  return fLoader;
578 }
579 //_______________________________________________________________________
580
581 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
582 {
583 /// Return rawcluster (icluster) for chamber ichamber and cathode icathod
584 /// Obsolete ??
585
586     TClonesArray *muonRawCluster  = GetMUONData()->RawClusters(ichamber);
587     ResetRawClusters();
588     TTree *treeR = fLoader->TreeR();
589     Int_t nent=(Int_t)treeR->GetEntries();
590     treeR->GetEvent(nent-2+icathod-1);
591     //treeR->GetEvent(icathod);
592     //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
593
594     AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
595     //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
596     
597     return  mRaw;
598 }
599
600 //________________________________________________________________________
601 void
602 AliMUON::ResetGeometryBuilder()
603 {
604 /// Only to be used by "experts" wanting to change the geometry builders
605 /// to be used. 
606 /// As the ctor of AliMUON now defines a default geometrybuilder, this
607 /// ResetGeometryBuilder() must be called prior to call the 
608 /// AddGeometryBuilder()
609
610   delete fGeometryBuilder;
611   fGeometryBuilder = new AliMUONGeometryBuilder(this);
612   fGeometryBuilder
613     ->AddBuilder(new AliMUONCommonGeometryBuilder(this));
614 }