Fixing bug in setting scaler events for trigger
[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(const AliMUON& rMUON)
219  : AliDetector(rMUON)
220 {
221 /// Protected copy constructor
222
223   AliFatal("Not implemented.");
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 }
252
253 //________________________________________________________________________
254 AliMUON& AliMUON::operator = (const AliMUON& rhs)
255 {
256 /// Protected assignement operator
257
258   if (this == &rhs) return *this;
259
260   AliFatal("Not implemented.");
261     
262   return *this;  
263 }
264
265 //_____________________________________________________________________________
266 void AliMUON::AddGeometryBuilder(AliMUONVGeometryBuilder* geomBuilder)
267 {
268 /// Add the geometry builder to the list
269
270   fGeometryBuilder->AddBuilder(geomBuilder);
271 }
272
273 //____________________________________________________________________
274 void AliMUON::BuildGeometry()
275 {
276 /// Geometry for event display
277
278
279 //     for (Int_t i = 0; i < AliMUONConstants::NCh(); i++)     
280 //       this->Chamber(i).SegmentationModel2(1)->Draw("eventdisplay");// to be check !
281      
282   
283 }
284
285 //____________________________________________________________________
286 const AliMUONGeometry*  AliMUON::GetGeometry() const
287 {
288 /// Return geometry parametrisation
289
290   if ( !fGeometryBuilder) {
291     AliWarningStream() << "GeometryBuilder not defined." << std::endl;
292     return 0;
293   }
294   
295   return fGeometryBuilder->GetGeometry();
296 }   
297
298 //____________________________________________________________________
299 const AliMUONGeometryTransformer*  AliMUON::GetGeometryTransformer() const
300 {
301 /// Return geometry parametrisation
302
303   const AliMUONGeometry* kGeometry = GetGeometry();
304   
305   if ( !kGeometry) return 0;
306
307   return kGeometry->GetTransformer();
308 }   
309
310 //__________________________________________________________________
311 void  AliMUON::SetTreeAddress()
312 {
313 /// Set Hits tree address
314
315   GetMUONData()->SetLoader(fLoader); 
316   //  GetMUONData()->MakeBranch("D,S,RC");
317   //  GetMUONData()->SetTreeAddress("H,D,S,RC");
318   GetMUONData()->SetTreeAddress("H");
319   if (fHits !=  GetMUONData()->Hits())  {
320     if ( gAlice->GetMCApp() )
321       if ( gAlice->GetMCApp()->GetHitLists() ) {
322         fHits = GetMUONData()->Hits();
323         gAlice->GetMCApp()->AddHitList(fHits); // For purifyKine, only necessary when Hit list is created in AliMUONData
324       }  
325   }
326   fHits = GetMUONData()->Hits(); // Added by Ivana to use the methods FisrtHit, NextHit of AliDetector    
327 }
328
329 //_________________________________________________________________
330 void AliMUON::SetChargeSlope(Int_t id, Float_t p1)
331 {
332 /// Set the inverse charge slope for chamber id
333
334     Int_t i=2*(id-1);    //PH    ((AliMUONChamber*) (*fChambers)[i])->SetSigmaIntegration(p1);
335     //PH    ((AliMUONChamber*) (*fChambers)[i+1])->SetSigmaIntegration(p1);
336     ((AliMUONChamber*) fChambers->At(i))->SetChargeSlope(p1);
337     ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSlope(p1);
338 }
339 //__________________________________________________________________
340 void AliMUON::SetChargeSpread(Int_t id, Float_t p1, Float_t p2)
341 {
342 /// Set sigma of charge spread for chamber id
343
344     Int_t i=2*(id-1);
345     ((AliMUONChamber*) fChambers->At(i))->SetChargeSpread(p1,p2);
346     ((AliMUONChamber*) fChambers->At(i+1))->SetChargeSpread(p1,p2);
347 }
348 //___________________________________________________________________
349 void AliMUON::SetSigmaIntegration(Int_t id, Float_t p1)
350 {
351 /// Set integration limits for charge spread
352     Int_t i=2*(id-1);
353     ((AliMUONChamber*) fChambers->At(i))->SetSigmaIntegration(p1);
354     ((AliMUONChamber*) fChambers->At(i+1))->SetSigmaIntegration(p1);
355 }
356
357 //__________________________________________________________________
358 void AliMUON::SetMaxAdc(Int_t id, Int_t p1)
359 {
360 /// Set maximum number for ADCcounts (saturation)
361
362     Int_t i=2*(id-1);
363     ((AliMUONChamber*) fChambers->At(i))->SetMaxAdc(p1);
364     ((AliMUONChamber*) fChambers->At(i+1))->SetMaxAdc(p1);
365 }
366
367 //__________________________________________________________________
368 void AliMUON::SetMaxStepGas(Float_t p1)
369 {
370 /// Set stepsize in gas
371
372   fMaxStepGas=p1;
373 }
374 //__________________________________________________________________
375 void AliMUON::SetMaxStepAlu(Float_t p1)
376 {
377 /// Set step size in Alu
378
379     fMaxStepAlu=p1;
380 }
381 //__________________________________________________________________
382 void AliMUON::SetMaxDestepGas(Float_t p1)
383 {
384 /// Set maximum step size in Gas
385
386     fMaxDestepGas=p1;
387 }
388 //__________________________________________________________________
389 void AliMUON::SetMaxDestepAlu(Float_t p1)
390 {
391 /// Set maximum step size in Alu
392
393   fMaxDestepAlu=p1;
394 }
395
396 //____________________________________________________________________
397 Float_t  AliMUON::GetMaxStepGas() const
398 {
399 /// Return stepsize in gas
400   
401   return fMaxStepGas;
402 }  
403
404 //____________________________________________________________________
405 Float_t  AliMUON::GetMaxStepAlu() const
406 {
407 /// Return step size in Alu
408   
409   return fMaxStepAlu;
410 }
411   
412 //____________________________________________________________________
413 Float_t  AliMUON::GetMaxDestepGas() const
414 {
415 /// Return maximum step size in Gas
416   
417   return fMaxDestepGas;
418 }
419   
420 //____________________________________________________________________
421 Float_t  AliMUON::GetMaxDestepAlu() const
422 {
423 /// Return maximum step size in Gas
424   
425   return fMaxDestepAlu;
426 }
427
428 //____________________________________________________________________
429  void  AliMUON::SetAlign(Bool_t align)
430 {
431 /// Set option for alignement to geometry builder
432  
433    fGeometryBuilder->SetAlign(align);
434 }   
435
436 //____________________________________________________________________
437  void  AliMUON::SetAlign(const TString& fileName, Bool_t align)
438 {
439 /// Set option for alignement to geometry builder
440  
441    fGeometryBuilder->SetAlign(fileName, align);
442 }   
443
444 //____________________________________________________________________
445 void   AliMUON::SetResponseModel(Int_t id, AliMUONResponse *response)
446 {
447 /// Set the response for chamber id
448     ((AliMUONChamber*) fChambers->At(id))->SetResponseModel(response);
449 }
450
451 //____________________________________________________________________
452 AliDigitizer* AliMUON::CreateDigitizer(AliRunDigitizer* manager) const
453 {
454 /// FIXME: the selection of the class should be done through a factory
455 /// mechanism. (see also Hits2SDigits()).
456   
457   AliInfo(Form("Digitizer used : %s",fDigitizerType.Data()));
458   
459   if ( fDigitizerType == "digitizer:default" )
460   {
461     return new AliMUONDigitizerv2(manager);
462   }
463   else if ( fDigitizerType == "digitizer:NewDigitizerNewTrigger" ) 
464   {
465     return new AliMUONDigitizerV3(manager,AliMUONDigitizerV3::kTriggerElectronics);
466   }
467   else if ( fDigitizerType == "digitizer:NewDigitizerOldTrigger" )
468   {
469     return new AliMUONDigitizerV3(manager,AliMUONDigitizerV3::kTriggerDecision, kFALSE, kFALSE);
470   }
471   else if ( fDigitizerType == "digitizer:NewDigitizerEffTrigger" )
472   {
473     return new AliMUONDigitizerV3(manager,AliMUONDigitizerV3::kTriggerDecision, kTRUE, kFALSE);
474   }  
475   else if ( fDigitizerType == "digitizer:NewDigitizerWithNoiseOldTrigger" )
476   {
477     return new AliMUONDigitizerV3(manager,AliMUONDigitizerV3::kTriggerDecision, kFALSE, kTRUE);
478   }    
479   else
480   {
481     AliFatal(Form("Unknown digitizer type : %s",fDigitizerType.Data()));
482   }
483   return 0x0;
484 }
485
486 //_____________________________________________________________________
487 TString
488 AliMUON::SDigitizerType() const
489 {
490 /// Return digitizer type
491
492   return fSDigitizerType;
493 }
494
495 //_____________________________________________________________________
496 void AliMUON::SDigits2Digits()
497 {
498 /// Write TreeD here only 
499
500     char hname[30];
501     //    sprintf(hname,"TreeD%d",fLoader->GetHeader()->GetEvent());
502     fLoader->TreeD()->Write(hname,TObject::kOverwrite);
503     fLoader->TreeD()->Reset();
504 }
505
506 //_____________________________________________________________________
507 void AliMUON::Hits2SDigits()
508 {
509 /// FIXME: the selection of the sdigitizer should be done through a
510 /// factory mechanism.
511   
512   AliInfo(Form("SDigitizer used : %s",fSDigitizerType.Data()));
513
514   if ( fSDigitizerType == "sdigitizer:default" )
515   {
516     // Adaption of AliMUONSDigitizerv1 to be excuted by the AliSimulation framework
517     AliRunLoader* runLoader = fLoader->GetRunLoader();
518     AliRunDigitizer   * manager = new AliRunDigitizer(1,1);
519     manager->SetInputStream(0,runLoader->GetFileName(),AliConfig::GetDefaultEventFolderName());
520     AliMUONDigitizer * dMUON   = new AliMUONSDigitizerv1(manager);
521     fLoader->LoadHits("READ");
522     for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
523       runLoader->GetEvent(iEvent);
524       dMUON->Exec("");
525     }
526     fLoader->UnloadHits();
527   }
528   else if ( fSDigitizerType == "sdigitizer:AliMUONSDigitizerV2" )
529   {
530     TTask* sdigitizer = new AliMUONSDigitizerV2;
531     sdigitizer->ExecuteTask();
532   }
533   else
534   {
535     AliFatal(Form("Unknown sdigitizer classname : %s",fSDigitizerType.Data()));
536   }
537 }
538
539 //_____________________________________________________________________
540 TString
541 AliMUON::DigitizerType() const
542 {
543 /// Return digitizer type
544
545   return fDigitizerType;
546 }
547
548 //_____________________________________________________________________
549 void AliMUON::Digits2Raw()
550 {
551 /// Convert digits of the current event to raw data
552
553   if (!fRawWriter)
554   {
555     fRawWriter = new AliMUONRawWriter(fMUONData);
556     if (fTriggerScalerEvent == kTRUE) 
557     {
558       fRawWriter->SetScalersNumbers();
559     }
560   }
561   
562   if (!fRawWriter->Digits2Raw()) 
563   {
564     AliError("pb writting raw data");
565   }
566 }
567
568 //_______________________________________________________________________
569 AliLoader* AliMUON::MakeLoader(const char* topfoldername)
570
571 /// Build standard getter (AliLoader type);
572 /// if detector wants to use castomized getter, it must overload this method
573  
574  AliDebug(1,Form("Creating standard getter for detector %s. Top folder is %s.",
575          GetName(),topfoldername));
576  fLoader   = new AliLoader(GetName(),topfoldername);
577  fMUONData = new AliMUONData(fLoader,GetName(),GetName()); 
578  fMUONData->SetSplitLevel(fSplitLevel);
579  return fLoader;
580 }
581 //_______________________________________________________________________
582
583 AliMUONRawCluster *AliMUON::RawCluster(Int_t ichamber, Int_t icathod, Int_t icluster)
584 {
585 /// Return rawcluster (icluster) for chamber ichamber and cathode icathod
586 /// Obsolete ??
587
588     TClonesArray *muonRawCluster  = GetMUONData()->RawClusters(ichamber);
589     ResetRawClusters();
590     TTree *treeR = fLoader->TreeR();
591     Int_t nent=(Int_t)treeR->GetEntries();
592     treeR->GetEvent(nent-2+icathod-1);
593     //treeR->GetEvent(icathod);
594     //Int_t nrawcl = (Int_t)muonRawCluster->GetEntriesFast();
595
596     AliMUONRawCluster * mRaw = (AliMUONRawCluster*)muonRawCluster->UncheckedAt(icluster);
597     //printf("RawCluster _ nent nrawcl icluster mRaw %d %d %d%p\n",nent,nrawcl,icluster,mRaw);
598     
599     return  mRaw;
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 }