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