LCOV - code coverage report
Current view: top level - TRD/TRDsim - AliTRDtestG4.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 1 221 0.5 %
Date: 2016-06-14 17:26:59 Functions: 1 14 7.1 %

          Line data    Source code
       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             : //                                                                        //
      20             : //  Transition Radiation Detector version 1 -- slow simulator             //
      21             : //                                                                        //
      22             : ////////////////////////////////////////////////////////////////////////////
      23             : 
      24             : #include <TLorentzVector.h>
      25             : #include <TMath.h>
      26             : #include <TRandom.h>
      27             : #include <TVirtualMC.h>
      28             : #include <TGeoManager.h>
      29             : #include <TGeoMatrix.h>
      30             : #include <TGeoPhysicalNode.h>
      31             : 
      32             : #include "AliTrackReference.h"
      33             : #include "AliMC.h"
      34             : #include "AliRun.h"
      35             : #include "AliGeomManager.h"
      36             : 
      37             : #include "AliTRDgeometry.h"
      38             : #include "AliTRDCommonParam.h"
      39             : #include "AliTRDsimTR.h"
      40             : #include "AliTRDtestG4.h"
      41             : #include "AliLog.h"
      42             : 
      43          12 : ClassImp(AliTRDtestG4)
      44             :  
      45             : //_____________________________________________________________________________
      46             : AliTRDtestG4::AliTRDtestG4()
      47           0 :   :AliTRD()
      48           0 :   ,fTRon(kTRUE)
      49           0 :   ,fTR(NULL)
      50           0 :   ,fStepSize(0)
      51           0 :   ,fWion(0)
      52           0 :   ,fScaleG4(1.164)
      53           0 : {
      54             :   //
      55             :   // Default constructor
      56             :   //
      57             : 
      58           0 : }
      59             : 
      60             : //_____________________________________________________________________________
      61             : AliTRDtestG4::AliTRDtestG4(const char *name, const char *title) 
      62           0 :   :AliTRD(name,title) 
      63           0 :   ,fTRon(kTRUE)
      64           0 :   ,fTR(NULL)
      65           0 :   ,fStepSize(0.1)
      66           0 :   ,fWion(0)
      67           0 :   ,fScaleG4(1.164)
      68           0 : {
      69             :   //
      70             :   // Standard constructor for Transition Radiation Detector version 1
      71             :   //
      72             : 
      73           0 :   SetBufferSize(128000);
      74             : 
      75           0 :   if      (AliTRDCommonParam::Instance()->IsXenon()) {
      76           0 :     fWion = 23.53; // Ionization energy XeCO2 (85/15)
      77           0 :   }
      78           0 :   else if (AliTRDCommonParam::Instance()->IsArgon()) {
      79           0 :     fWion = 27.21; // Ionization energy ArCO2 (82/18)
      80             :   }
      81             :   else {
      82           0 :     AliFatal("Wrong gas mixture");
      83           0 :     exit(1);
      84             :   }
      85             : 
      86           0 : }
      87             : 
      88             : //_____________________________________________________________________________
      89             : AliTRDtestG4::~AliTRDtestG4()
      90           0 : {
      91             :   //
      92             :   // AliTRDtestG4 destructor
      93             :   //
      94             : 
      95           0 :   if (fTR) {
      96           0 :     delete fTR;
      97           0 :     fTR     = 0;
      98           0 :   }
      99             : 
     100           0 : }
     101             :  
     102             : //_____________________________________________________________________________
     103             : void AliTRDtestG4::AddAlignableVolumes() const
     104             : {
     105             :   //
     106             :   // Create entries for alignable volumes associating the symbolic volume
     107             :   // name with the corresponding volume path. Needs to be syncronized with
     108             :   // eventual changes in the geometry.
     109             :   //
     110             : 
     111           0 :   TString volPath;
     112           0 :   TString symName;
     113             : 
     114           0 :   TString vpStr   = "ALIC_1/B077_1/BSEGMO";
     115           0 :   TString vpApp1  = "_1/BTRD";
     116           0 :   TString vpApp2  = "_1";
     117           0 :   TString vpApp3a = "/UTR1_1/UTS1_1/UTI1_1/UT";
     118           0 :   TString vpApp3b = "/UTR2_1/UTS2_1/UTI2_1/UT";
     119           0 :   TString vpApp3c = "/UTR3_1/UTS3_1/UTI3_1/UT";
     120           0 :   TString vpApp3d = "/UTR4_1/UTS4_1/UTI4_1/UT";
     121             : 
     122           0 :   TString snStr   = "TRD/sm";
     123           0 :   TString snApp1  = "/st";
     124           0 :   TString snApp2  = "/pl";
     125             : 
     126             :   //
     127             :   // The super modules
     128             :   // The symbolic names are: TRD/sm00
     129             :   //                           ...
     130             :   //                         TRD/sm17
     131             :   //
     132           0 :   for (Int_t isector = 0; isector < AliTRDgeometry::Nsector(); isector++) {
     133             : 
     134           0 :     volPath  = vpStr;
     135           0 :     volPath += isector;
     136           0 :     volPath += vpApp1;
     137           0 :     volPath += isector;
     138           0 :     volPath += vpApp2;
     139             : 
     140           0 :     symName  = snStr;
     141           0 :     symName += Form("%02d",isector);
     142             : 
     143           0 :     gGeoManager->SetAlignableEntry(symName.Data(),volPath.Data());
     144             : 
     145             :   }
     146             : 
     147             :   //
     148             :   // The readout chambers
     149             :   // The symbolic names are: TRD/sm00/st0/pl0
     150             :   //                           ...
     151             :   //                         TRD/sm17/st4/pl5
     152             :   //
     153             :   AliGeomManager::ELayerID idTRD1 = AliGeomManager::kTRD1;
     154             :   Int_t layer, modUID;
     155             :   
     156           0 :   for (Int_t isector = 0; isector < AliTRDgeometry::Nsector(); isector++) {
     157             : 
     158           0 :     if (fGeometry->GetSMstatus(isector) == 0) continue;
     159             : 
     160           0 :     for (Int_t istack = 0; istack < AliTRDgeometry::Nstack(); istack++) {
     161           0 :       for (Int_t ilayer = 0; ilayer < AliTRDgeometry::Nlayer(); ilayer++) {
     162             : 
     163           0 :         layer = idTRD1 + ilayer;
     164           0 :         modUID = AliGeomManager::LayerToVolUIDSafe(layer,isector*5+istack);
     165             : 
     166           0 :         Int_t idet = AliTRDgeometry::GetDetectorSec(ilayer,istack);
     167             : 
     168           0 :         volPath  = vpStr;
     169           0 :         volPath += isector;
     170           0 :         volPath += vpApp1;
     171           0 :         volPath += isector;
     172           0 :         volPath += vpApp2;
     173           0 :         switch (isector) {
     174             :         case 17:
     175           0 :           if ((istack == 4) && (ilayer == 4)) {
     176           0 :             continue;
     177             :           }
     178           0 :           volPath += vpApp3d;
     179             :           break;
     180             :         case 13:
     181             :         case 14:
     182             :         case 15:
     183           0 :           if (istack == 2) {
     184           0 :             continue;
     185             :           }
     186           0 :           volPath += vpApp3c;
     187             :           break;
     188             :         case 11:
     189             :         case 12:
     190           0 :           volPath += vpApp3b;
     191             :           break;
     192             :         default:
     193           0 :           volPath += vpApp3a;
     194             :         };
     195           0 :         volPath += Form("%02d",idet);
     196           0 :         volPath += vpApp2;
     197             : 
     198           0 :         symName  = snStr;
     199           0 :         symName += Form("%02d",isector);
     200           0 :         symName += snApp1;
     201           0 :         symName += istack;
     202           0 :         symName += snApp2;
     203           0 :         symName += ilayer;
     204             : 
     205             :         TGeoPNEntry *alignableEntry = 
     206           0 :           gGeoManager->SetAlignableEntry(symName.Data(),volPath.Data(),modUID);
     207             : 
     208             :         // Add the tracking to local matrix following the TPC example
     209           0 :         if (alignableEntry) {
     210           0 :           TGeoHMatrix *globMatrix = alignableEntry->GetGlobalOrig();
     211           0 :           Double_t sectorAngle = 20.0 * (isector % 18) + 10.0;
     212           0 :           TGeoHMatrix *t2lMatrix  = new TGeoHMatrix();
     213           0 :           t2lMatrix->RotateZ(sectorAngle);
     214           0 :           t2lMatrix->MultiplyLeft(&(globMatrix->Inverse()));
     215           0 :           alignableEntry->SetMatrix(t2lMatrix);
     216           0 :         }
     217             :         else {
     218           0 :           AliError(Form("Alignable entry %s is not valid!",symName.Data()));
     219             :         }
     220             : 
     221           0 :       }
     222             :     }
     223           0 :   }
     224             : 
     225           0 : }
     226             : 
     227             : //_____________________________________________________________________________
     228             : void AliTRDtestG4::CreateGeometry()
     229             : {
     230             :   //
     231             :   // Create the GEANT geometry for the Transition Radiation Detector - Version 1
     232             :   // This version covers the full azimuth. 
     233             :   //
     234             : 
     235             :   // Check that FRAME is there otherwise we have no place where to put the TRD
     236           0 :   AliModule* frame = gAlice->GetModule("FRAME");
     237           0 :   if (!frame) {
     238           0 :     AliError("TRD needs FRAME to be present\n");
     239           0 :     return;
     240             :   }
     241             : 
     242             :   // Define the chambers
     243           0 :   AliTRD::CreateGeometry();
     244             : 
     245           0 : }
     246             : 
     247             : //_____________________________________________________________________________
     248             : void AliTRDtestG4::CreateMaterials()
     249             : {
     250             :   //
     251             :   // Create materials for the Transition Radiation Detector version 1
     252             :   //
     253             : 
     254           0 :   AliTRD::CreateMaterials();
     255             : 
     256           0 : }
     257             : 
     258             : //_____________________________________________________________________________
     259             : void AliTRDtestG4::CreateTRhit(Int_t det)
     260             : {
     261             :   //
     262             :   // Creates an electron cluster from a TR photon.
     263             :   // The photon is assumed to be created a the end of the radiator. The 
     264             :   // distance after which it deposits its energy takes into account the 
     265             :   // absorbtion of the entrance window and of the gas mixture in drift
     266             :   // volume.
     267             :   //
     268             : 
     269             :   // Maximum number of TR photons per track
     270             :   const Int_t   kNTR         = 50;
     271             : 
     272           0 :   TLorentzVector mom;
     273           0 :   TLorentzVector pos;
     274             : 
     275           0 :   Float_t eTR[kNTR];
     276           0 :   Int_t   nTR;
     277             : 
     278             :   // Create TR photons
     279           0 :   TVirtualMC::GetMC()->TrackMomentum(mom);
     280           0 :   Float_t pTot = mom.Rho();
     281           0 :   fTR->CreatePhotons(11,pTot,nTR,eTR);
     282           0 :   if (nTR > kNTR) {
     283           0 :     AliFatal(Form("Boundary error: nTR = %d, kNTR = %d",nTR,kNTR));
     284             :   }
     285             : 
     286             :   // Loop through the TR photons
     287           0 :   for (Int_t iTR = 0; iTR < nTR; iTR++) {
     288             : 
     289           0 :     Float_t energyMeV = eTR[iTR] * 0.001;
     290           0 :     Float_t energyeV  = eTR[iTR] * 1000.0;
     291             :     Float_t absLength = 0.0;
     292             :     Float_t sigma     = 0.0;
     293             : 
     294             :     // Take the absorbtion in the entrance window into account
     295           0 :     Double_t muMy = fTR->GetMuMy(energyMeV);
     296           0 :     sigma         = muMy * fFoilDensity;
     297           0 :     if (sigma > 0.0) {
     298           0 :       absLength = gRandom->Exp(1.0/sigma);
     299           0 :       if (absLength < AliTRDgeometry::MyThick()) {
     300           0 :         continue;
     301             :       }
     302             :     }
     303             :     else {
     304           0 :       continue;
     305             :     }
     306             : 
     307             :     // The absorbtion cross sections in the drift gas
     308             :     // Gas-mixture (Xe/CO2)
     309             :     Double_t muNo = 0.0;
     310           0 :     if      (AliTRDCommonParam::Instance()->IsXenon()) {
     311           0 :       muNo = fTR->GetMuXe(energyMeV);
     312           0 :     }
     313           0 :     else if (AliTRDCommonParam::Instance()->IsArgon()) {
     314           0 :       muNo = fTR->GetMuAr(energyMeV);
     315           0 :     }
     316           0 :     Double_t muCO = fTR->GetMuCO(energyMeV);
     317           0 :     sigma = (fGasNobleFraction * muNo + (1.0 - fGasNobleFraction) * muCO) 
     318           0 :           * fGasDensity 
     319           0 :           * fTR->GetTemp();
     320             : 
     321             :     // The distance after which the energy of the TR photon
     322             :     // is deposited.
     323           0 :     if (sigma > 0.0) {
     324           0 :       absLength = gRandom->Exp(1.0/sigma);
     325           0 :       if (absLength > (AliTRDgeometry::DrThick()
     326           0 :                      + AliTRDgeometry::AmThick())) {
     327           0 :         continue;
     328             :       }
     329             :     }
     330             :     else {
     331           0 :       continue;
     332             :     }
     333             : 
     334             :     // The position of the absorbtion
     335           0 :     Float_t posHit[3];
     336           0 :     TVirtualMC::GetMC()->TrackPosition(pos);
     337           0 :     posHit[0] = pos[0] + mom[0] / pTot * absLength;
     338           0 :     posHit[1] = pos[1] + mom[1] / pTot * absLength;
     339           0 :     posHit[2] = pos[2] + mom[2] / pTot * absLength;
     340             : 
     341             :     // Create the charge 
     342           0 :     Int_t q = ((Int_t) (energyeV / fWion));
     343             : 
     344             :     // Add the hit to the array. TR photon hits are marked 
     345             :     // by negative charge
     346           0 :     AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
     347             :           ,det
     348           0 :           ,posHit
     349           0 :           ,-q
     350           0 :           ,TVirtualMC::GetMC()->TrackTime()*1.0e06
     351             :           ,kTRUE);
     352             : 
     353           0 :   }
     354             : 
     355           0 : }
     356             : 
     357             : //_____________________________________________________________________________
     358             : void AliTRDtestG4::Init() 
     359             : {
     360             :   //
     361             :   // Initialise Transition Radiation Detector after geometry has been built.
     362             :   //
     363             : 
     364           0 :   AliTRD::Init();
     365             : 
     366           0 :   AliDebug(1,"Slow simulator\n");
     367             : 
     368             :   // Switch on TR simulation as default
     369           0 :   if (!fTRon) {
     370           0 :     AliInfo("TR simulation off");
     371           0 :   }
     372             :   else {
     373           0 :     fTR = new AliTRDsimTR();
     374             :   }
     375             : 
     376           0 :   AliDebug(1,"+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
     377             : 
     378           0 : }
     379             : 
     380             : //_____________________________________________________________________________
     381             : void AliTRDtestG4::StepManager()
     382             : {
     383             :   //
     384             :   // Slow simulator. Every charged track produces electron cluster as hits 
     385             :   // along its path across the drift volume. The step size is fixed in
     386             :   // this version of the step manager.
     387             :   //
     388             :   // Works for Xe/CO2 as well as Ar/CO2
     389             :   //
     390             : 
     391             :   // PDG code electron
     392             :   const Int_t   kPdgElectron = 11;
     393             : 
     394             :   Int_t    layer  = 0;
     395             :   Int_t    stack  = 0;
     396             :   Int_t    sector = 0;
     397             :   Int_t    det    = 0;
     398             :   Int_t    qTot;
     399             : 
     400           0 :   Float_t  hits[3];
     401             :   Double_t eDep;
     402             : 
     403             :   Bool_t   drRegion = kFALSE;
     404             :   Bool_t   amRegion = kFALSE;
     405             : 
     406           0 :   TString  cIdPath;
     407           0 :   Char_t   cIdSector[3];
     408           0 :            cIdSector[2]  = 0;
     409             : 
     410           0 :   TString  cIdCurrent;
     411           0 :   TString  cIdSensDr = "J";
     412           0 :   TString  cIdSensAm = "K";
     413           0 :   Char_t   cIdChamber[3];
     414           0 :            cIdChamber[2] = 0;
     415             : 
     416           0 :   TLorentzVector pos;
     417           0 :   TLorentzVector mom;
     418             : 
     419           0 :   const Int_t    kNlayer      = AliTRDgeometry::Nlayer();
     420           0 :   const Int_t    kNstack      = AliTRDgeometry::Nstack();
     421           0 :   const Int_t    kNdetsec     = kNlayer * kNstack;
     422             : 
     423             :   const Double_t kBig         = 1.0e+12;
     424             :   const Float_t  kEkinMinStep = 1.0e-5;  // Minimum energy for the step size adjustment
     425             : 
     426             :   //  const Double_t kScaleG4     = 1.12;
     427             : 
     428             :   // Set the maximum step size to a very large number for all 
     429             :   // neutral particles and those outside the driftvolume
     430           0 :   if (!fPrimaryIonisation) TVirtualMC::GetMC()->SetMaxStep(kBig); 
     431             : 
     432             :   // If not charged track or already stopped or disappeared, just return.
     433             :  
     434           0 :   if ((!TVirtualMC::GetMC()->TrackCharge())) {
     435           0 :     return;
     436             :   }
     437             : 
     438             :   // Inside a sensitive volume?
     439           0 :   cIdCurrent = TVirtualMC::GetMC()->CurrentVolName();
     440             : 
     441           0 :   if (cIdSensDr == cIdCurrent[1]) {
     442             :     drRegion = kTRUE;
     443           0 :   }
     444           0 :   if (cIdSensAm == cIdCurrent[1]) {
     445             :     amRegion = kTRUE;
     446           0 :   }
     447             : 
     448           0 :   if ((!drRegion) && 
     449           0 :       (!amRegion)) {
     450           0 :     return;
     451             :   }
     452             : 
     453             :   // The hit coordinates and charge
     454           0 :   TVirtualMC::GetMC()->TrackPosition(pos);
     455           0 :   hits[0] = pos[0];
     456           0 :   hits[1] = pos[1];
     457           0 :   hits[2] = pos[2];
     458             : 
     459             :   // The sector number (0 - 17), according to standard coordinate system
     460           0 :   cIdPath      = gGeoManager->GetPath();
     461           0 :   cIdSector[0] = cIdPath[21];
     462           0 :   cIdSector[1] = cIdPath[22];
     463           0 :   sector = atoi(cIdSector);
     464             : 
     465             :   // The plane and chamber number
     466           0 :   cIdChamber[0]   = cIdCurrent[2];
     467           0 :   cIdChamber[1]   = cIdCurrent[3];
     468           0 :   Int_t idChamber = (atoi(cIdChamber) % kNdetsec);
     469           0 :   stack = ((Int_t) idChamber / kNlayer);
     470           0 :   layer = ((Int_t) idChamber % kNlayer);
     471             : 
     472             :   // The detector number
     473           0 :   det = fGeometry->GetDetector(layer,stack,sector);
     474             : 
     475             :   // 0: InFlight 1:Entering 2:Exiting
     476             :   Int_t trkStat = 0;
     477             : 
     478             :   // Special hits only in the drift region
     479           0 :   if      ((drRegion) &&
     480           0 :            (TVirtualMC::GetMC()->IsTrackEntering())) {
     481             : 
     482             :     // Create a track reference at the entrance of each
     483             :     // chamber that contains the momentum components of the particle
     484           0 :     TVirtualMC::GetMC()->TrackMomentum(mom);
     485           0 :     AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kTRD);
     486             :     trkStat = 1;
     487             : 
     488             :     // Create the hits from TR photons if electron/positron is
     489             :     // entering the drift volume
     490           0 :     if ((fTR)   &&
     491           0 :         (fTRon) &&
     492           0 :         (TMath::Abs(TVirtualMC::GetMC()->TrackPid()) == kPdgElectron)) {
     493           0 :       CreateTRhit(det);
     494             :     }
     495             : 
     496             :   }
     497           0 :   else if ((amRegion) && 
     498           0 :            (TVirtualMC::GetMC()->IsTrackExiting())) {
     499             : 
     500             :     // Create a track reference at the exit of each
     501             :     // chamber that contains the momentum components of the particle
     502           0 :     TVirtualMC::GetMC()->TrackMomentum(mom);
     503           0 :     AddTrackReference(gAlice->GetMCApp()->GetCurrentTrackNumber(), AliTrackReference::kTRD);
     504             :     trkStat = 2;
     505             : 
     506           0 :   }
     507             :   
     508             :   // Calculate the charge according to GEANT Edep
     509             :   // Create a new dEdx hit
     510           0 :   eDep = TMath::Max(TVirtualMC::GetMC()->Edep(),0.0) * 1.0e+09;
     511           0 :   eDep /= fScaleG4;
     512           0 :   qTot = (Int_t) (eDep / fWion);
     513           0 :   if ((qTot) ||
     514           0 :       (trkStat)) {
     515           0 :     AddHit(gAlice->GetMCApp()->GetCurrentTrackNumber()
     516             :           ,det
     517           0 :           ,hits
     518             :           ,qTot
     519           0 :           ,TVirtualMC::GetMC()->TrackTime()*1.0e06
     520             :           ,drRegion);
     521             :   }
     522             : 
     523             :   // Set Maximum Step Size
     524             :   // Produce only one hit if Ekin is below cutoff
     525           0 :   if ((TVirtualMC::GetMC()->Etot() - TVirtualMC::GetMC()->TrackMass()) < kEkinMinStep) {
     526           0 :     return;
     527             :   }
     528           0 :   if (!fPrimaryIonisation) TVirtualMC::GetMC()->SetMaxStep(fStepSize);
     529             : 
     530           0 : }

Generated by: LCOV version 1.11