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