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