]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - MUON/AliMUONv1.cxx
Fixed memory leak
[u/mrichter/AliRoot.git] / MUON / AliMUONv1.cxx
index 85b03c7c807250970e3377ce591216ebacd88691..d25249e171405fa90f5cc8d0ea6be370f8fad68e 100644 (file)
 
 /* $Id$ */
 
-// --------------------
+//-----------------------------------------------------------------------------
 // Class AliMUONv1
 // --------------------
 // AliDetector class for MUON subsystem which implements
 // functions for simulation 
+//-----------------------------------------------------------------------------
 
 #include "AliMUONv1.h"
 #include "AliMUONConstants.h"
-#include "AliMUONSegFactory.h"
 #include "AliMUONResponseFactory.h"
-#include "AliMUONSegmentation.h"
 #include "AliMUONHit.h"
-#include "AliMUONTriggerCircuit.h"
-#include "AliMUONTriggerCircuitNew.h"
-#include "AliMUONTriggerCrateStore.h"
 #include "AliMUONGeometryBuilder.h"    
 #include "AliMUONGeometry.h"   
 #include "AliMUONGeometryTransformer.h"        
@@ -37,6 +33,9 @@
 #include "AliMUONStringIntMap.h"       
 #include "AliMUONGeometryDetElement.h" 
 
+#include "AliMpCDB.h"
+#include "AliMpDEManager.h"
+
 #include "AliConst.h" 
 #include "AliMagF.h"
 #include "AliRun.h"
 #include "AliTrackReference.h"
 #include "AliLog.h"
 
-#include <TRandom.h>
-#include <TF1.h>
 #include <TClonesArray.h>
+#include <TF1.h>
+#include <TF2.h>
+#include <TGeoGlobalMagField.h>
+#include <TGeoMatrix.h>
+#include <TRandom.h>
 #include <TRandom.h> 
 #include <TVirtualMC.h>
-#include <TGeoMatrix.h>
 
 #include <string>
 
+#include "AliMUONVHitStore.h"
+
+using std::endl;
+using std::cout;
+using std::setw;
 /// \cond CLASSIMP
 ClassImp(AliMUONv1)
 /// \endcond
@@ -61,6 +67,7 @@ ClassImp(AliMUONv1)
 AliMUONv1::AliMUONv1() 
   : AliMUON(),
     fAngleEffect(kTRUE),
+    fMagEffect(kTRUE),
     fStepMaxInActiveGas(0.6),
     fStepSum(0x0),
     fDestepSum(0x0),
@@ -68,7 +75,8 @@ AliMUONv1::AliMUONv1()
     fTrackPosition(),
     fElossRatio(0x0),
     fAngleEffect10(0x0),
-    fAngleEffectNorma(0x0)
+    fAngleEffectNorma(0x0),
+    fMagAngleEffectNorma(0x0)
 {
 /// Default constructor
   
@@ -76,11 +84,10 @@ AliMUONv1::AliMUONv1()
 } 
 
 //___________________________________________
-AliMUONv1::AliMUONv1(const char *name, const char *title,
-                     const char* sDigitizerClassName,
-                     const char* digitizerClassName)
-: AliMUON(name,title,sDigitizerClassName,digitizerClassName), 
+AliMUONv1::AliMUONv1(const char *name, const char* title)
+: AliMUON(name, title), 
     fAngleEffect(kTRUE),
+    fMagEffect(kTRUE),
     fStepMaxInActiveGas(0.6),
     fStepSum(0x0),
     fDestepSum(0x0),
@@ -88,12 +95,18 @@ AliMUONv1::AliMUONv1(const char *name, const char *title,
     fTrackPosition(),
     fElossRatio(0x0),
     fAngleEffect10(0x0),
-    fAngleEffectNorma(0x0)
+    fAngleEffectNorma(0x0),
+    fMagAngleEffectNorma(0x0)
 {
 /// Standard onstructor
 
     AliDebug(1,Form("ctor this=%p",this));     
        
+    // Load mapping
+    if ( ! AliMpCDB::LoadMpSegmentation() ) {
+      AliFatal("Could not access mapping from OCDB !");
+    }
+       
     // By default include all stations
 
     fStepSum   = new Float_t [AliMUONConstants::NCh()];
@@ -122,6 +135,11 @@ AliMUONv1::AliMUONv1(const char *name, const char *title,
     fAngleEffectNorma->SetParameter(1,-6.809e-01);
     fAngleEffectNorma->SetParameter(2,5.151e-02);
     fAngleEffectNorma->SetParameter(3,-1.490e-03);
+
+    // Magnetic field effect: Normalisation form theta=16 degres (eq. 10 degrees B=0) to theta between -20 and 20 (Lamia Benhabib jun 2006 )  
+    // Angle with respect to the wires assuming that chambers are perpendicular to the z axis.
+    fMagAngleEffectNorma = new TF2("MagAngleEffectNorma","121.24/(([1]+[2]*abs(y))+[3]*abs(x-[0]*y)+[4]*abs((x-[0]*y)*(x-[0]*y))+[5]*abs((x-[0]*y)*(x-[0]*y)*(x-[0]*y))+[6]*abs((x-[0]*y)*(x-[0]*y)*(x-[0]*y)*(x-[0]*y)))",-20.0,20.0,-1.,1.);
+    fMagAngleEffectNorma->SetParameters(8.6995, 25.4022, 13.8822, 2.4717, 1.1551, -0.0624, 0.0012);
 }
 
 //___________________________________________
@@ -135,6 +153,7 @@ AliMUONv1::~AliMUONv1()
   delete fElossRatio;
   delete fAngleEffect10;
   delete fAngleEffectNorma; 
+  delete fMagAngleEffectNorma;
 }
 
 //__________________________________________________
@@ -153,6 +172,19 @@ void AliMUONv1::CreateMaterials()
   fGeometryBuilder->CreateMaterials();
 }
 
+//________________________________________________________________
+void AliMUONv1::UpdateInternalGeometry()
+{
+/// Update geometry after applying mis-alignment
+
+  // Load mapping
+  if ( ! AliMpCDB::LoadMpSegmentation() ) {
+    AliFatal("Could not access mapping from OCDB !");
+  }
+
+  fGeometryBuilder->UpdateInternalGeometry();
+}
+
 //________________________________________________________________
 void AliMUONv1::AddAlignableVolumes() const
 {
@@ -173,58 +205,29 @@ void AliMUONv1::Init()
   AliDebug(1,"Finished Init for version 1 - CPC chamber type");   
  
 
-  std::string ftype(GetTitle());
-
   // Build segmentation
   // using geometry parametrisation
   //
-  AliMUONSegFactory segFactory(GetGeometryTransformer());
-  fSegmentation = segFactory.CreateSegmentation(ftype);
-
-  if (!fSegmentation) {
-    AliFatal(Form("Wrong factory type : %s",ftype.c_str()));
-  }        
-
   // Build response
   //
-  AliMUONResponseFactory respFactory("default");
+  AliMUONResponseFactory respFactory("default", fIsTailEffect);
   respFactory.Build(this);
   
-
-  // Initialize segmentation
-  //
-  fSegmentation->Init();
-
-  // Initialize trigger circuits
-  //
-  for (Int_t i=0; i<AliMUONConstants::NTriggerCircuit(); i++)  {
-    AliMUONTriggerCircuit* c = (AliMUONTriggerCircuit*)(fTriggerCircuits->At(i));
-    c->Init(i);
-  }
-  
-  AliMUONTriggerCrateStore store;
-  store.ReadFromFile();
-  for (Int_t i=0; i<AliMUONConstants::NTriggerCircuit(); i++)  
-  {
-    AliMUONTriggerCircuitNew* c = (AliMUONTriggerCircuitNew*)(fTriggerCircuitsNew->At(i));
-    c->Init(i,store);
-  }
-  
 }
 
 //__________________________________________________________________
-Int_t  AliMUONv1::GetChamberId(Int_t volId) const
+Int_t  AliMUONv1::GetGeomModuleId(Int_t volId) const
 {
 /// Check if the volume with specified  volId is a sensitive volume (gas) 
 /// of some chamber and return the chamber number;
 /// if not sensitive volume - return 0.
 
-  for (Int_t i = 0; i < AliMUONConstants::NCh(); i++) {
+  for (Int_t i = 0; i < AliMUONConstants::NGeomModules(); i++) {
     if ( GetGeometry()->GetModule(i)->IsSensitiveVolume(volId) )
-      return i+1;
+      return i;
   }    
 
-  return 0;
+  return -1;
 }
 
 //_______________________________________________________________________________
@@ -263,8 +266,6 @@ void AliMUONv1::StepManager()
   // Only gas gap inside chamber
   // Tag chambers and record hits when track enters 
   static Int_t   idvol=-1, iEnter = 0;
-  Int_t   iChamber=0;
-  Int_t   id=0;
   Int_t   copy;
   const  Float_t kBig = 1.e10;
   static Double_t xyzEnter[3];
@@ -272,25 +273,31 @@ void AliMUONv1::StepManager()
   //
   // Only gas gap inside chamber
   // Tag chambers and record hits when track enters 
-  id=gMC->CurrentVolID(copy);
-  iChamber = GetChamberId(id);
-  idvol = iChamber -1;
+  Int_t id=gMC->CurrentVolID(copy);
+  Int_t iGeomModule = GetGeomModuleId(id);
+  if (iGeomModule == -1) return;
 
-  if (idvol == -1) return;
-  
   // Detection elements id
   const AliMUONGeometryModule* kGeometryModule
-    = GetGeometry()->GetModule(iChamber-1);
-
+    = GetGeometry()->GetModule(iGeomModule);
   AliMUONGeometryDetElement* detElement
     = kGeometryModule->FindBySensitiveVolume(CurrentVolumePath());
+    
+  if (!detElement && iGeomModule < AliMUONConstants::NGeomModules()-2) {
+    iGeomModule++;
+    const AliMUONGeometryModule* kGeometryModule2
+      = GetGeometry()->GetModule(iGeomModule);
+    detElement 
+      = kGeometryModule2->FindBySensitiveVolume(CurrentVolumePath());
+  }    
 
   Int_t detElemId = 0;
   if (detElement) detElemId = detElement->GetUniqueID(); 
  
   if (!detElemId) {
-    cerr << "Chamber id: "
-        << setw(3) << iChamber << "  "
+    AliErrorStream() 
+         << "Geometry module id: "
+        << setw(3) << iGeomModule << "  "
         << "Current SV: " 
         <<  CurrentVolumePath() 
          << "  detElemId: "
@@ -298,22 +305,28 @@ void AliMUONv1::StepManager()
          << endl;
     Double_t x, y, z;
     gMC->TrackPosition(x, y, z);        
-    cerr << "  global position: "
+    AliErrorStream() 
+         << "  global position: "
         << x << ", " << y << ", " << z
         << endl;
-    AliError("DetElemId not identified.");
-  }  
+    AliErrorStream() << "DetElemId not identified." << endl;
+  } 
+  
+  Int_t iChamber = AliMpDEManager::GetChamberId(detElemId) + 1; 
+  idvol = iChamber -1;
     
   // Filling TrackRefs file for MUON. Our Track references are the active volume of the chambers
   if ( (gMC->IsTrackEntering() || gMC->IsTrackExiting() ) ) {
     AliTrackReference* trackReference    
-      = AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber());
+      = AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kMUON);
     trackReference->SetUserId(detElemId);
   }  
   
   if( gMC->IsTrackEntering() ) {
      Float_t theta = fTrackMomentum.Theta();
-     if ((TMath::Pi()-theta)*kRaddeg>=15.) gMC->SetMaxStep(fStepMaxInActiveGas); // We use Pi-theta because z is negative
+     if ( fIsMaxStep && (TMath::Pi()-theta)*kRaddeg>=15. ) {
+       gMC->SetMaxStep(fStepMaxInActiveGas); // We use Pi-theta because z is negative
+     }  
      iEnter = 1;
      gMC->TrackPosition(xyzEnter[0], xyzEnter[1], xyzEnter[2]); // save coordinates of entrance point
   }
@@ -347,9 +360,10 @@ void AliMUONv1::StepManager()
        gMC->IsTrackDisappeared()||
        (fStepSum[idvol]>fStepMaxInActiveGas) ) {
     
-    if   ( gMC->IsTrackExiting() || 
-           gMC->IsTrackStop() || 
-           gMC->IsTrackDisappeared() ) gMC->SetMaxStep(kBig);
+    if   ( fIsMaxStep && 
+           ( gMC->IsTrackExiting() || 
+             gMC->IsTrackStop() || 
+             gMC->IsTrackDisappeared() ) ) gMC->SetMaxStep(kBig);
     if (fDestepSum[idvol] == 0) {
       // AZ - no energy release
       fStepSum[idvol] = 0; // Reset for the next event
@@ -409,10 +423,13 @@ void AliMUONv1::StepManager()
     Float_t sigmaEffectThetadegrees;
     Float_t eLossParticleELossMip;
     Float_t yAngleEffect=0.;
-    Float_t thetawires      =  TMath::Abs( TMath::ASin( TMath::Sin(TMath::Pi()-theta) * TMath::Sin(phi) ) );// We use Pi-theta because z is negative
+    Float_t thetawires      =  TMath::ASin( TMath::Sin(TMath::Pi()-theta) * TMath::Sin(phi) ) ;// We use Pi-theta because z is negative
+    Double_t bField[3] = {0};
+    fTrackPosition.Vect().GetXYZ(tmp);
+    TGeoGlobalMagField::Instance()->Field(tmp,bField);
 
-
-    if (fAngleEffect){
+    if (fAngleEffect && !fMagEffect){
+      thetawires = TMath::Abs(thetawires);
     if ( (betaxGamma >3.2)   &&  (thetawires*kRaddeg<=15.) ) {
       betaxGamma=TMath::Log(betaxGamma);
       eLossParticleELossMip = fElossRatio->Eval(betaxGamma);
@@ -425,27 +442,37 @@ void AliMUONv1::StepManager()
       yAngleEffect=1.e-04*gRandom->Gaus(0,sigmaEffectThetadegrees); // Error due to the angle effect in cm
     }
     }
+    else if (fAngleEffect && fMagEffect) {
+      if ( (betaxGamma >3.2)   &&  (TMath::Abs(thetawires*kRaddeg)<=15.) ) {
+       betaxGamma=TMath::Log(betaxGamma);
+       eLossParticleELossMip = fElossRatio->Eval(betaxGamma);
+       // 10 degrees is a reference for a model (arbitrary)
+       sigmaEffect10degrees=fAngleEffect10->Eval(eLossParticleELossMip);// in micrometers
+       // Angle with respect to the wires assuming that chambers are perpendicular to the z axis.
+       sigmaEffectThetadegrees =  sigmaEffect10degrees/fMagAngleEffectNorma->Eval(thetawires*kRaddeg,bField[0]/10.);  // For 5mm gap  
+      if ( (iChamber==1)  ||  (iChamber==2) )  
+        sigmaEffectThetadegrees/=(1.09833e+00+1.70000e-02*(thetawires*kRaddeg)); // The gap is different (4mm)
+       yAngleEffect=1.e-04*gRandom->Gaus(0,sigmaEffectThetadegrees); // Error due to the angle effect in cm
+      }
+    }
+
+    AliMUONHit hit(fIshunt, 
+                  gAlice->GetMCApp()->GetCurrentTrackNumber(), 
+                  detElemId, ipart,
+                  fTrackPosition.X(), 
+                  fTrackPosition.Y()+yAngleEffect, 
+                  fTrackPosition.Z(), 
+                  gMC->TrackTime(),
+                  fTrackMomentum.P(),
+                  theta, 
+                  phi, 
+                  fStepSum[idvol], 
+                  fDestepSum[idvol],                        
+                  fTrackPosition.X(),
+                  fTrackPosition.Y(),
+                  fTrackPosition.Z());
     
-    // One hit per chamber
-    GetMUONData()->AddHit2(fIshunt, 
-                         gAlice->GetMCApp()->GetCurrentTrackNumber(), 
-                         detElemId, ipart,
-                         fTrackPosition.X(), 
-                         fTrackPosition.Y()+yAngleEffect, 
-                         fTrackPosition.Z(), 
-                         gMC->TrackTime(),
-                         fTrackMomentum.P(),
-                         theta, 
-                         phi, 
-                         fStepSum[idvol], 
-                         fDestepSum[idvol],                        
-                         fTrackPosition.X(),
-                         fTrackPosition.Y(),
-                         fTrackPosition.Z());
-
-    //       AliDebug(1,Form("Exit: Particle exiting from chamber %d",iChamber));
-    //       AliDebug(1,Form("Exit: StepSum %f eloss geant %g ",fStepSum[idvol],fDestepSum[idvol]));
-    //       AliDebug(1,Form("Exit: Track Position %f %f %f",fTrackPosition.X(),fTrackPosition.Y(),fTrackPosition.Z()) ;
+    fHitStore->Add(hit);
 
     fStepSum[idvol]  =0; // Reset for the next event
     fDestepSum[idvol]=0; // Reset for the next event