caf48cca304bd7d26abb6369e97bb8d45dc9b9bd
[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
25 #include "AliMUON.h"
26
27 #include "AliMUONSDigitizerV2.h"
28 #include "AliMUONDigitizerV3.h"
29 #include "AliMUONDigitMaker.h"
30 #include "AliMUONDigit.h"
31 #include "AliMUONCalibrationData.h"
32
33 #include "AliMUONDigitStoreV1.h"
34 #include "AliMUONVTriggerStore.h"
35 #include "AliMUONHitStoreV1.h"
36
37 #include "AliMUONChamberTrigger.h"
38 #include "AliMUONConstants.h"
39 #include "AliMUONGeometry.h"
40 #include "AliMUONGeometryTransformer.h"
41 #include "AliMUONGeometryBuilder.h"
42 #include "AliMUONVGeometryBuilder.h"    
43 #include "AliMUONCommonGeometryBuilder.h"
44 #include "AliMUONSt1GeometryBuilderV2.h"
45 #include "AliMUONSt2GeometryBuilderV2.h"
46 #include "AliMUONSlatGeometryBuilder.h"
47 #include "AliMUONTriggerGeometryBuilder.h"
48 #include "AliMUONDigitCalibrator.h"
49 #include "AliMUONRecoParam.h"
50 #include "AliCDBManager.h"
51 #include "AliCDBEntry.h"
52
53 #include "AliMUONRawWriter.h"
54
55 #include "AliLoader.h"
56 #include "AliCDBManager.h"
57 #include "AliRunDigitizer.h"
58 #include "AliMC.h"
59 #include "AliRun.h"
60 #include "AliRawDataHeaderSim.h"
61 #include "AliLog.h"
62
63 #include <TObjArray.h>
64
65 // Defaults parameters for Z positions of chambers
66 // taken from values for "stations" in AliMUON::AliMUON
67 //     const Float_t zch[7]={528, 690., 975., 1249., 1449., 1610, 1710.};
68 // and from array "dstation" in AliMUONv1::CreateGeometry
69 //          Float_t dstation[5]={20., 20., 20, 20., 20.};
70 //     for tracking chambers,
71 //          according to (Z1 = zch - dstation) and  (Z2 = zch + dstation)
72 //          for the first and second chambers in the station, respectively,
73 // and from "DTPLANES" in AliMUONv1::CreateGeometry
74 //           const Float_t DTPLANES = 15.;
75 //     for trigger chambers,
76 //          according to (Z1 = zch) and  (Z2 = zch + DTPLANES)
77 //          for the first and second chambers in the station, respectively
78
79 /// \cond CLASSIMP
80 ClassImp(AliMUON)  
81 /// \endcond
82
83 //__________________________________________________________________
84 AliMUON::AliMUON()
85   : AliDetector(),
86     fNCh(0),
87     fNTrackingCh(0),
88     fSplitLevel(0),
89     fChambers(0),
90     fGeometryBuilder(0),
91     fAccCut(kFALSE),
92     fAccMin(0.),
93     fAccMax(0.),   
94     fMaxStepGas(0.),
95     fMaxStepAlu(0.),
96     fMaxDestepGas(0.),
97     fMaxDestepAlu(0.),
98     fMaxIterPad(0),
99     fCurIterPad(0),
100     fIsMaxStep(kTRUE),
101     fTriggerScalerEvent(kFALSE),
102     fTriggerResponseV1(kFALSE),
103     fTriggerCoinc44(0),
104     fTriggerEffCells(0),
105     fDigitizerWithNoise(1),
106     fDigitizerNSigmas(4.0),
107     fIsTailEffect(kTRUE),
108     fRawWriter(0x0),
109     fDigitMaker(0x0),
110     fHitStore(0x0),
111     fDigitStoreConcreteClassName(),
112     fCalibrationData(0x0),
113     fDigitCalibrator(0x0)
114 {
115 /// Default Constructor
116     
117     AliDebug(1,Form("default (empty) ctor this=%p",this));
118     fIshunt          = 0;
119 }
120
121 //__________________________________________________________________
122 AliMUON::AliMUON(const char *name, const char* title)
123   : AliDetector(name, title),
124     fNCh(AliMUONConstants::NCh()),
125     fNTrackingCh(AliMUONConstants::NTrackingCh()),
126     fSplitLevel(0),
127     fChambers(0),
128     fGeometryBuilder(0),
129     fAccCut(kFALSE),
130     fAccMin(0.),
131     fAccMax(0.),   
132     fMaxStepGas(0.1),
133     fMaxStepAlu(0.1),
134     fMaxDestepGas(-1), // Negatives values are ignored by geant3 CONS200 
135     fMaxDestepAlu(-1), // in the calculation of the tracking parameters
136     fMaxIterPad(0),
137     fCurIterPad(0),
138     fIsMaxStep(kTRUE),
139     fTriggerScalerEvent(kFALSE),
140     fTriggerResponseV1(kFALSE),
141     fTriggerCoinc44(0),
142     fTriggerEffCells(0),
143     fDigitizerWithNoise(1),
144     fDigitizerNSigmas(4.0),
145     fIsTailEffect(kTRUE),
146     fRawWriter(0x0),
147     fDigitMaker(new AliMUONDigitMaker),
148     fHitStore(0x0),
149     fDigitStoreConcreteClassName("AliMUONDigitStoreV2S"),
150     fCalibrationData(),
151     fDigitCalibrator(0x0)
152 {
153   /// Standard constructor  
154   
155   AliDebug(1,Form("ctor this=%p",this));
156   fIshunt =  0;
157   
158   //PH SetMarkerColor(kRed);//
159     
160   // Geometry builder
161   fGeometryBuilder = new AliMUONGeometryBuilder(this);
162   
163   // Common geometry definitions
164   fGeometryBuilder
165     ->AddBuilder(new AliMUONCommonGeometryBuilder(this));
166   
167   // By default, add also all the needed geometry builders.
168   // If you want to change this from outside, please use ResetGeometryBuilder
169   // method, followed by AddGeometryBuilder ones.
170   
171   AddGeometryBuilder(new AliMUONSt1GeometryBuilderV2(this));
172   AddGeometryBuilder(new AliMUONSt2GeometryBuilderV2(this));
173   AddGeometryBuilder(new AliMUONSlatGeometryBuilder(this));
174   AddGeometryBuilder(new AliMUONTriggerGeometryBuilder(this));
175   
176   //
177   // Creating List of Chambers
178     Int_t ch;
179     fChambers = new TObjArray(AliMUONConstants::NCh());
180     fChambers->SetOwner(kTRUE);
181     
182     // Loop over stations
183     for (Int_t st = 0; st < AliMUONConstants::NCh() / 2; st++) {
184       // Loop over 2 chambers in the station
185       for (Int_t stCH = 0; stCH < 2; stCH++) {
186         //
187         //    
188         //    Default Parameters for Muon Tracking Stations
189         ch = 2 * st + stCH;
190         if (ch < AliMUONConstants::NTrackingCh()) {
191           fChambers->AddAt(new AliMUONChamber(ch),ch);
192         } else {
193           fChambers->AddAt(new AliMUONChamberTrigger(ch, GetGeometryTransformer()),ch);
194         }
195       } // Chamber stCH (0, 1) in 
196     }     // Station st (0...)
197   
198   Int_t runnumber = AliCDBManager::Instance()->GetRun();
199   
200   fCalibrationData = new AliMUONCalibrationData(runnumber);
201 }
202
203 //____________________________________________________________________
204 AliMUON::~AliMUON()
205 {
206 /// Destructor
207
208   AliDebug(1,Form("dtor this=%p",this));
209   delete fChambers;
210   delete fGeometryBuilder;
211   delete fRawWriter;
212   delete fDigitMaker;
213   delete fHitStore;
214   delete fCalibrationData;
215   delete fDigitCalibrator;
216 }
217
218 //_____________________________________________________________________________
219 void AliMUON::AddGeometryBuilder(AliMUONVGeometryBuilder* geomBuilder)
220 {
221 /// Add the geometry builder to the list
222
223   fGeometryBuilder->AddBuilder(geomBuilder);
224 }
225
226 //____________________________________________________________________
227 const AliMUONGeometry*  AliMUON::GetGeometry() const
228 {
229 /// Return geometry parametrisation
230
231   if ( !fGeometryBuilder) {
232     AliWarningStream() << "GeometryBuilder not defined." << std::endl;
233     return 0;
234   }
235   
236   return fGeometryBuilder->GetGeometry();
237 }   
238
239 //____________________________________________________________________
240 const AliMUONGeometryTransformer*  AliMUON::GetGeometryTransformer() const
241 {
242 /// Return geometry parametrisation
243
244   const AliMUONGeometry* kGeometry = GetGeometry();
245   
246   if ( !kGeometry) return 0;
247
248   return kGeometry->GetTransformer();
249 }   
250
251 //__________________________________________________________________
252 void 
253 AliMUON::MakeBranch(Option_t* opt)
254 {
255   /// Create branche(s) to hold MUON hits
256   AliDebug(1,"");
257   
258   TString sopt(opt);
259   if ( sopt != "H" ) return;
260     
261   if (!fHitStore)
262   {
263     fHitStore = new AliMUONHitStoreV1;
264     if ( gAlice->GetMCApp() )
265     {
266       if ( gAlice->GetMCApp()->GetHitLists() ) 
267       {
268         // AliStack::PurifyKine needs to be able to loop on our hits
269         // to remap the track numbers.
270         gAlice->GetMCApp()->AddHitList(fHitStore->Collection()); 
271       }  
272     }
273   }
274
275   TTree* treeH = fLoader->TreeH();
276   
277   if (!treeH)
278   {
279     AliFatal("No TreeH");
280   }
281   
282   fHitStore->Connect(*treeH);
283 }
284
285 //__________________________________________________________________
286 void  
287 AliMUON::SetTreeAddress()
288 {
289   /// Set Hits tree address  
290  
291 //  if ( gAlice->GetMCApp() && fHitStore )
292 //  {
293 //    TList* l = gAlice->GetMCApp()->GetHitLists();
294 //    if ( l )
295 //    {
296 //      TObject* o = l->First();
297 //      if (o!=fHitStore->HitCollection())
298 //      {
299 //        AliError(Form("Something is strange hitcollection=%x",fHitStore->HitCollection()));
300 //        l->Print();        
301 //      }
302 //    }  
303 //  }  
304 }
305
306 //_________________________________________________________________
307 void
308 AliMUON::ResetHits()
309 {
310   /// Reset hits
311   
312   AliDebug(1,"");
313   if (fHitStore) fHitStore->Clear();
314 }
315
316 //_________________________________________________________________
317 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
318 {
319 /// Set the inverse charge slope for chamber id
320
321     Int_t i=2*(id-1);    //PH    ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
322     //PH    ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
323     ((AliMUONChamber*) fChambers->At(i))->SetChargeSlope(p1);
324     ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSlope(p1);
325 }
326 //__________________________________________________________________
327 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
328 {
329 /// Set sigma of charge spread for chamber id
330
331     Int_t i=2*(id-1);
332     ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
333     ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSpread(p1,p2);
334 }
335 //___________________________________________________________________
336 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
337 {
338 /// Set integration limits for charge spread
339     Int_t i=2*(id-1);
340     ((AliMUONChamber*) fChambers->At(i))->SetSigmaIntegration(p1);
341     ((AliMUONChamber*) fChambers->At(i+1))->SetSigmaIntegration(p1);
342 }
343
344 //__________________________________________________________________
345 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
346 {
347 /// Set maximum number for ADCcounts (saturation)
348
349     Int_t i=2*(id-1);
350     ((AliMUONChamber*) fChambers->At(i))->SetMaxAdc(p1);
351     ((AliMUONChamber*) fChambers->At(i+1))->SetMaxAdc(p1);
352 }
353
354 //__________________________________________________________________
355 void AliMUON::SetMaxStepGas(Float_t p1)
356 {
357 /// Set stepsize in gas
358
359   fMaxStepGas=p1;
360 }
361 //__________________________________________________________________
362 void AliMUON::SetMaxStepAlu(Float_t p1)
363 {
364 /// Set step size in Alu
365
366     fMaxStepAlu=p1;
367 }
368 //__________________________________________________________________
369 void AliMUON::SetMaxDestepGas(Float_t p1)
370 {
371 /// Set maximum step size in Gas
372
373     fMaxDestepGas=p1;
374 }
375 //__________________________________________________________________
376 void AliMUON::SetMaxDestepAlu(Float_t p1)
377 {
378 /// Set maximum step size in Alu
379
380   fMaxDestepAlu=p1;
381 }
382
383 //____________________________________________________________________
384 Float_t  AliMUON::GetMaxStepGas() const
385 {
386 /// Return stepsize in gas
387   
388   return fMaxStepGas;
389 }  
390
391 //____________________________________________________________________
392 Float_t  AliMUON::GetMaxStepAlu() const
393 {
394 /// Return step size in Alu
395   
396   return fMaxStepAlu;
397 }
398   
399 //____________________________________________________________________
400 Float_t  AliMUON::GetMaxDestepGas() const
401 {
402 /// Return maximum step size in Gas
403   
404   return fMaxDestepGas;
405 }
406   
407 //____________________________________________________________________
408 Float_t  AliMUON::GetMaxDestepAlu() const
409 {
410 /// Return maximum step size in Gas
411   
412   return fMaxDestepAlu;
413 }
414
415 //____________________________________________________________________
416  void  AliMUON::SetAlign(Bool_t align)
417 {
418 /// Set option for alignement to geometry builder
419  
420    fGeometryBuilder->SetAlign(align);
421 }   
422
423 //____________________________________________________________________
424  void  AliMUON::SetAlign(const TString& fileName, Bool_t align)
425 {
426 /// Set option for alignement to geometry builder
427  
428    fGeometryBuilder->SetAlign(fileName, align);
429 }   
430
431 //____________________________________________________________________
432 void   AliMUON::SetResponseModel(Int_t id, const AliMUONResponse& response)
433 {
434 /// Set the response for chamber id
435     ((AliMUONChamber*) fChambers->At(id))->SetResponseModel(response);
436 }
437
438 //____________________________________________________________________
439 AliDigitizer* AliMUON::CreateDigitizer(AliRunDigitizer* manager) const
440 {
441 /// Return digitizer
442   
443   AliMUONDigitizerV3* digitizer = new AliMUONDigitizerV3(manager, fDigitizerWithNoise);
444   AliMUONDigitizerV3::SetNSigmas(fDigitizerNSigmas);
445   digitizer->SetCalibrationData(fCalibrationData);
446   return digitizer;
447 }
448
449 //_____________________________________________________________________
450 void AliMUON::SDigits2Digits()
451 {
452 /// Write TreeD here only 
453
454     char hname[30];
455     //    sprintf(hname,"TreeD%d",fLoader->GetHeader()->GetEvent());
456     fLoader->TreeD()->Write(hname,TObject::kOverwrite);
457     fLoader->TreeD()->Reset();
458 }
459
460 //_____________________________________________________________________
461 void AliMUON::Hits2SDigits()
462 {
463 /// Perform Hits2Digits using SDigitizerV2
464   
465   AliMUONSDigitizerV2 sdigitizer;
466   sdigitizer.ExecuteTask();
467 }
468
469 //_____________________________________________________________________
470 void AliMUON::Digits2Raw()
471 {
472 /// Convert digits of the current event to raw data
473
474   AliRawDataHeaderSim header;
475
476   if (!fRawWriter)
477   {
478     fRawWriter = new AliMUONRawWriter;
479     AliDebug(1,Form("Creating %s",fRawWriter->ClassName()));
480     if (fTriggerScalerEvent == kTRUE) 
481     {
482       fRawWriter->SetScalersNumbers();
483     }
484   }
485   
486   fLoader->LoadDigits("READ");
487   
488   TTree* treeD = fLoader->TreeD();
489   
490   if (!treeD)
491   {
492     AliError("Could not get TreeD");
493     return;
494   }
495   
496   AliMUONVTriggerStore*  triggerStore = AliMUONVTriggerStore::Create(*treeD);
497   AliMUONVDigitStore* digitStore = AliMUONVDigitStore::Create(*treeD);
498
499   triggerStore->Connect(*treeD,kFALSE);
500   digitStore->Connect(*treeD,kFALSE);
501   
502   treeD->GetEvent(0);
503   
504   fRawWriter->SetHeader(header);
505   if (!fRawWriter->Digits2Raw(digitStore,triggerStore))
506   {
507     AliError("pb writting raw data");
508   }
509   
510   delete triggerStore;
511   delete digitStore;
512   
513   fLoader->UnloadDigits();
514 }
515
516 //_____________________________________________________________________
517 Bool_t AliMUON::Raw2SDigits(AliRawReader* rawReader)
518 {
519   /// Convert raw data to SDigit
520   
521   if (!fLoader->TreeS()) fLoader->MakeSDigitsContainer();
522   
523   TTree* treeS = fLoader->TreeS();
524   
525   AliMUONVDigitStore* sDigitStore = AliMUONVDigitStore::Create(DigitStoreClassName());
526   
527   sDigitStore->Connect(*treeS);
528   
529   if (!fDigitMaker) fDigitMaker = new AliMUONDigitMaker;
530   
531   if (!fDigitCalibrator)
532   {
533     AliMUONRecoParam* recoParam = 0x0;
534     
535     AliCDBEntry* entry = AliCDBManager::Instance()->Get("MUON/Calib/RecoParam");
536     
537     if (entry) 
538     {      
539       // load recoParam according OCDB content (single or array)
540       if (!(recoParam = dynamic_cast<AliMUONRecoParam*>(entry->GetObject()))) 
541       {        
542         TObjArray* recoParamArray = static_cast<TObjArray*>(entry->GetObject());
543         
544         for(Int_t i = 0; i < recoParamArray->GetEntriesFast(); ++i)
545         {
546           recoParam = static_cast<AliMUONRecoParam*>(recoParamArray->UncheckedAt(i));
547           if (recoParam && recoParam->IsDefault()) break;
548           recoParam = 0x0;
549         }        
550       }      
551     }
552     
553     if (!recoParam)
554     {
555       AliFatal("Cannot work without recoparams !");
556     }
557     
558     TString calibMode = recoParam->GetCalibrationMode();
559   
560     fDigitCalibrator = new AliMUONDigitCalibrator(*fCalibrationData,recoParam,calibMode.Data());
561   }
562   
563   fDigitMaker->Raw2Digits(rawReader,sDigitStore,0x0);
564   
565   fDigitCalibrator->Calibrate(*sDigitStore);
566
567   TIter next(sDigitStore->CreateIterator());
568   AliMUONDigit* sdigit;
569   
570   // now tweak the digits to make them "as fresh as possible", i.e.
571   // reset their calibrated status, as they'll be calibrated again
572   // once embedded.
573   while ( ( sdigit = static_cast<AliMUONDigit*>(next()) ) )
574   {
575     sdigit->Calibrated(kFALSE);
576   }
577   
578   treeS->Fill();
579   
580   fLoader->WriteSDigits("OVERWRITE");
581   
582   fLoader->UnloadSDigits();
583   
584   delete sDigitStore;
585   
586   return kTRUE;
587 }
588
589 //_______________________________________________________________________
590 AliLoader* AliMUON::MakeLoader(const char* topfoldername)
591
592 /// Build standard getter (AliLoader type);
593 /// if detector wants to use castomized getter, it must overload this method
594  
595  AliDebug(1,Form("Creating standard getter for detector %s. Top folder is %s.",
596          GetName(),topfoldername));
597  fLoader   = new AliLoader(GetName(),topfoldername);
598
599  return fLoader;
600 }
601
602 //________________________________________________________________________
603 void
604 AliMUON::ResetGeometryBuilder()
605 {
606 /// Only to be used by "experts" wanting to change the geometry builders
607 /// to be used. 
608 /// As the ctor of AliMUON now defines a default geometrybuilder, this
609 /// ResetGeometryBuilder() must be called prior to call the 
610 /// AddGeometryBuilder()
611
612   delete fGeometryBuilder;
613   fGeometryBuilder = new AliMUONGeometryBuilder(this);
614   fGeometryBuilder
615     ->AddBuilder(new AliMUONCommonGeometryBuilder(this));
616 }
617
618 //____________________________________________________________________
619 Bool_t  AliMUON::GetTriggerResponseV1() const
620 {
621 ///
622 /// Returns fTriggerResponseV1
623 ///  
624     return fTriggerResponseV1;
625     
626 }  
627
628 //____________________________________________________________________
629 Int_t  AliMUON::GetTriggerCoinc44() const
630 {
631 ///
632 /// Returns fTriggerCoinc44
633 ///  
634     return fTriggerCoinc44;
635     
636 }
637
638 //____________________________________________________________________
639 Bool_t  AliMUON::GetTriggerEffCells() const
640 {
641 ///
642 /// Returns fTriggerEffCells
643 ///  
644     return fTriggerEffCells;
645     
646 }  
647
648 //____________________________________________________________________
649 Int_t  AliMUON::GetDigitizerWithNoise() const
650 {
651 ///
652 /// Returns fDigitizerWithNoise
653 ///  
654     return fDigitizerWithNoise;
655     
656 }  
657
658