LCOV - code coverage report
Current view: top level - ITS/ITSsim - AliITSsimulationSSD.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 266 364 73.1 %
Date: 2016-06-14 17:26:59 Functions: 20 34 58.8 %

          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             : #include <stdio.h>
      19             : #include <stdlib.h>
      20             : #include <Riostream.h>
      21             : #include <TObjArray.h>
      22             : #include <TRandom.h>
      23             : 
      24             : #include <TGeoGlobalMagField.h>
      25             : #include "AliITSmodule.h"
      26             : #include "AliITSMapA2.h"
      27             : #include "AliITSpList.h"
      28             : #include "AliITSCalibrationSSD.h"
      29             : #include "AliITSsegmentationSSD.h"
      30             : //#include "AliITSdcsSSD.h"
      31             : #include "AliITS.h"
      32             : #include "AliITShit.h"
      33             : #include "AliITSdigitSSD.h"
      34             : #include "AliRun.h"
      35             : #include "AliMagF.h"
      36             : #include "AliITSgeom.h"
      37             : #include "AliITSsimulationSSD.h"
      38             : #include "AliITSTableSSD.h"
      39             : #include <TF1.h>
      40             : #include "AliMathBase.h"
      41             : 
      42             : using std::endl;
      43             : using std::cout;
      44         116 : ClassImp(AliITSsimulationSSD)
      45             : ////////////////////////////////////////////////////////////////////////
      46             : //                                                                    //
      47             : // Author: Enrico Fragiacomo                                          //
      48             : //         enrico.fragiacomo@ts.infn.it                               //
      49             : // Last revised: june 2008                                            // 
      50             : //                                                                    //
      51             : // AliITSsimulationSSD is the simulation of SSD.                     //
      52             : ////////////////////////////////////////////////////////////////////////
      53             : 
      54             : //----------------------------------------------------------------------
      55           0 : AliITSsimulationSSD::AliITSsimulationSSD():AliITSsimulation(),
      56             :                                            //fDCS(0),
      57           0 : fMapA2(0),
      58           0 : fIonE(0.0),
      59           0 : fDifConst(),
      60           0 : fDriftVel(),
      61           0 : fTimeResponse(NULL),
      62           0 : fLorentz(kFALSE),
      63           0 : fTanLorAngP(0),
      64           0 : fTanLorAngN(0)
      65           0 : {
      66             :     //default Constructor
      67             :     //Inputs:
      68             :     // none.
      69             :     // Outputs:
      70             :     // none.
      71             :     // Return:
      72             :     //  A default construction AliITSsimulationSSD class
      73           0 : }
      74             : //----------------------------------------------------------------------
      75             : AliITSsimulationSSD::AliITSsimulationSSD(AliITSDetTypeSim* dettyp):
      76           1 : AliITSsimulation(dettyp),
      77             : //fDCS(0),
      78           1 : fMapA2(0),
      79           1 : fIonE(0.0),
      80           1 : fDifConst(),
      81           1 : fDriftVel(),
      82           1 : fTimeResponse(NULL),
      83           1 : fLorentz(kFALSE),
      84           1 : fTanLorAngP(0),
      85           1 : fTanLorAngN(0)
      86           5 : {
      87             :     // Constructor 
      88             :     // Input:
      89             :     //   AliITSDetTypeSim    Pointer to the SSD dettype to be used
      90             :     // Outputs:
      91             :     //   none.
      92             :     // Return
      93             :     //   A standard constructed AliITSsimulationSSD class
      94             : 
      95           3 :   fTimeResponse = new TF1("ftimeresponse",".5*x*exp(1.-.5*x)");
      96           1 :     Init();
      97           2 : }
      98             : //----------------------------------------------------------------------
      99             : void AliITSsimulationSSD::Init(){
     100             :   // Inilizer, Inilizes all of the variable as needed in a standard place.
     101             :   // Input:
     102             :   //   AliITSsegmentationSSD *seg  Pointer to the SSD segmentation to be used
     103             :   //   AliITSCalibrationSSD   *resp Pointer to the SSD responce class to be used
     104             :   // Outputs:
     105             :   //   none.
     106             :   // Return
     107             :   //   none.
     108           2 :   AliITSsegmentationSSD* seg = (AliITSsegmentationSSD*)GetSegmentationModel(2);
     109           1 :   AliITSSimuParam* simpar = fDetType->GetSimuParam();
     110             :   
     111           1 :   SetDriftVelocity(); // use default values in .h file
     112           1 :   SetIonizeE();       // use default values in .h file
     113           1 :   SetDiffConst();     // use default values in .h file
     114           3 :   fpList           = new AliITSpList(2,GetNStrips());
     115           2 :   fMapA2           = new AliITSMapA2(seg);
     116           1 :   SetLorentzDrift(simpar->GetSSDLorentzDrift());
     117           2 :   if (fLorentz) SetTanLorAngle();
     118           1 : }
     119             : 
     120             : //______________________________________________________________________
     121             : Bool_t AliITSsimulationSSD::SetTanLorAngle() {
     122             :     // This function set the Tangent of the Lorentz angles. 
     123             :     // output: Bool_t : kTRUE in case of success
     124             :     //
     125             : 
     126           4 :     if(!fDetType) {
     127           0 :       AliError("AliITSsimulationSPD::SetTanLorAngle: AliITSDetTypeSim* fDetType not set ");
     128           0 :       return kFALSE;}
     129             : 
     130           2 :     AliITSSimuParam* simpar = fDetType->GetSimuParam();
     131           2 :     AliMagF* fld = (AliMagF*)TGeoGlobalMagField::Instance()->GetField();
     132           2 :     if (!fld) AliFatal("The field is not initialized");
     133           2 :     Double_t bz = fld->SolenoidField();
     134             : 
     135           2 :     fTanLorAngN = TMath::Tan( simpar->LorentzAngleElectron(bz) );
     136           2 :     fTanLorAngP = TMath::Tan( simpar->LorentzAngleHole(bz) );
     137             : 
     138             :     return kTRUE;
     139           2 : }
     140             : 
     141             : //______________________________________________________________________
     142             : AliITSsimulationSSD& AliITSsimulationSSD::operator=(
     143             :                                          const AliITSsimulationSSD &s){
     144             :   // Operator =
     145             : 
     146           0 :   if(this==&s) return *this;
     147             : 
     148             :   //  this->fDCS         = new AliITSdcsSSD(*(s.fDCS));
     149           0 :   this->fMapA2       = s.fMapA2;
     150           0 :   this->fIonE        = s.fIonE;
     151           0 :   this->fDifConst[0] = s.fDifConst[0];
     152           0 :   this->fDifConst[1] = s.fDifConst[1];
     153           0 :   this->fDriftVel[0] = s.fDriftVel[0];
     154           0 :   this->fDriftVel[1] = s.fDriftVel[1];
     155           0 :   this->fTimeResponse = s.fTimeResponse;
     156           0 :   this->fLorentz   = s.fLorentz;
     157           0 :   this->fTanLorAngP = s.fTanLorAngP;
     158           0 :   this->fTanLorAngN = s.fTanLorAngN;
     159           0 :   return *this;
     160           0 : }
     161             : /*
     162             : //______________________________________________________________________
     163             : AliITSsimulation& AliITSsimulationSSD::operator=(
     164             :                                          const AliITSsimulation &s){
     165             :   // Operator =
     166             : 
     167             :   if(this==&s) return *this;
     168             :   Error("AliITSsimulationSSD","Not allowed to make a = with "
     169             :         "AliITSsimulationSSD Using default creater instead");
     170             :   
     171             :   return *this;
     172             : }
     173             : */
     174             : //______________________________________________________________________
     175             : AliITSsimulationSSD::AliITSsimulationSSD(const AliITSsimulationSSD &source):
     176           0 :     AliITSsimulation(source),
     177           0 : fMapA2(source.fMapA2),
     178           0 : fIonE(source.fIonE),
     179           0 : fDifConst(),
     180           0 : fDriftVel(),
     181           0 : fTimeResponse(source.fTimeResponse),
     182           0 : fLorentz(source.fLorentz),
     183           0 : fTanLorAngP(source.fTanLorAngP),
     184           0 : fTanLorAngN(source.fTanLorAngN)
     185           0 : {
     186             :   // copy constructor
     187           0 :   fDifConst[0] = source.fDifConst[0];
     188           0 :   fDifConst[1] = source.fDifConst[1];
     189           0 :   fDriftVel[0] = source.fDriftVel[0];
     190           0 :   fDriftVel[1] = source.fDriftVel[1];
     191           0 : }
     192             : //______________________________________________________________________
     193           6 : AliITSsimulationSSD::~AliITSsimulationSSD() {
     194             :   // destructor
     195           2 :   delete fMapA2;
     196           2 :   delete fTimeResponse;
     197             :   //delete fDCS;
     198           3 : }
     199             : //______________________________________________________________________
     200             : void AliITSsimulationSSD::InitSimulationModule(Int_t module,Int_t event){
     201             :     // Creates maps to build the list of tracks for each sumable digit
     202             :     // Inputs:
     203             :     //   Int_t module    // Module number to be simulated
     204             :     //   Int_t event     // Event number to be simulated
     205             :     // Outputs:
     206             :     //   none.
     207             :     // Return
     208             :     //    none.
     209             : 
     210           0 :     SetModuleNumber(module);
     211           0 :     SetEventNumber(event);
     212           0 :     fMapA2->ClearMap();
     213           0 :     fpList->ClearMap();
     214           0 : }
     215             : //______________________________________________________________________
     216             : void AliITSsimulationSSD::FinishSDigitiseModule(){
     217             :     // Does the Sdigits to Digits work
     218             :     // Inputs:
     219             :     //   none.
     220             :     // Outputs:
     221             :     //   none.
     222             :     // Return:
     223             :     //   none.
     224             : 
     225           0 :   FillMapFrompList(fpList);  // need to check if needed here or not????
     226           0 :   SDigitToDigit(fModule,fpList);
     227           0 :   fpList->ClearMap();
     228           0 :   fMapA2->ClearMap();
     229           0 : }
     230             : //______________________________________________________________________
     231             : void AliITSsimulationSSD::DigitiseModule(AliITSmodule *mod,Int_t,Int_t) {
     232             :   // Digitizes hits for one SSD module
     233       13584 :   SetModuleNumber(mod->GetIndex());
     234             :   
     235        6792 :   HitsToAnalogDigits(mod,fpList);
     236        6792 :   SDigitToDigit(GetModuleNumber(),fpList);
     237             :   
     238        6792 :   fpList->ClearMap();
     239        6792 :   fMapA2->ClearMap();
     240        6792 : }
     241             : //______________________________________________________________________
     242             : void AliITSsimulationSSD::SDigitiseModule(AliITSmodule *mod,Int_t,Int_t) {
     243             :   // Produces Summable/Analog digits and writes them to the SDigit tree. 
     244             : 
     245           0 :     HitsToAnalogDigits(mod,fpList);
     246             : 
     247           0 :     WriteSDigits(fpList);
     248             :     
     249           0 :     fpList->ClearMap();
     250           0 :     fMapA2->ClearMap();
     251           0 : }
     252             : //______________________________________________________________________
     253             : void AliITSsimulationSSD::SDigitToDigit(Int_t module,AliITSpList *pList){
     254             :   // Takes the pList and finishes the digitization.
     255             :   
     256       13584 :   ApplyNoise(pList,module);
     257        6792 :   ApplyCoupling(pList,module);
     258        6792 :   ApplyDeadChannels(module);
     259             :   
     260        6792 :   ChargeToSignal(module,pList);
     261        6792 : }
     262             : //______________________________________________________________________
     263             : void AliITSsimulationSSD::HitsToAnalogDigits(AliITSmodule *mod,
     264             :                                              AliITSpList *pList){
     265             :     // Loops over all hits to produce Analog/floating point digits. This
     266             :     // is also the first task in producing standard digits.
     267             :   Int_t lasttrack     = -2;
     268       13584 :   Int_t idtrack       = -2;
     269        6792 :   Double_t x0=0.0, y0=0.0, z0=0.0;
     270        6792 :   Double_t x1=0.0, y1=0.0, z1=0.0;
     271        6792 :   Double_t de=0.0;
     272        6792 :   Int_t module = mod->GetIndex();
     273             :   Double_t tof = 0.;
     274             :   
     275             :   
     276        6792 :   AliITSsegmentationSSD* seg = (AliITSsegmentationSSD*)GetSegmentationModel(2);
     277             :   
     278        6792 :   TObjArray *hits = mod->GetHits();
     279        6792 :   Int_t nhits     = hits->GetEntriesFast();
     280       13429 :   if (nhits<=0) return;
     281         310 :   AliITSTableSSD * tav = new AliITSTableSSD(GetNStrips());
     282         155 :   module = mod->GetIndex();
     283         236 :   if ( mod->GetLayer() == 6 ) seg->SetLayer(6);
     284         229 :   if ( mod->GetLayer() == 5 ) seg->SetLayer(5);
     285             : 
     286        1256 :   for(Int_t i=0; i<nhits; i++) {    
     287             :     // LineSegmentL returns 0 if the hit is entering
     288             :     // If hits is exiting returns positions of entering and exiting hits
     289             :     // Returns also energy loss
     290         473 :     if(GetDebug(4)){
     291           0 :       cout << i << " ";
     292           0 :       cout << mod->GetHit(i)->GetXL() << " "<<mod->GetHit(i)->GetYL();
     293           0 :       cout << " " << mod->GetHit(i)->GetZL();
     294           0 :       cout << endl;
     295           0 :     } // end if
     296         473 :     if (mod->LineSegmentL(i, x0, x1, y0, y1, z0, z1, de, idtrack)) {
     297             : 
     298             :       // Scale down dE/dx according to the hit's TOF wrt to the trigger
     299             :       // Necessary for pileup simulation
     300             :       // EF - 21/04/09
     301         473 :       tof = mod->GetHit(i)->GetTOF();
     302         473 :       tof *= 1.E+6; // convert time in microsecond
     303         946 :       if(tof<2.) de = de * fTimeResponse->Eval(-1.*tof+2.);
     304           0 :       else de = 0.;
     305             :       //
     306             : 
     307         473 :       HitToDigit(module, x0, y0, z0, x1, y1, z1, de,tav);
     308         733 :       if (lasttrack != idtrack || i==(nhits-1)) {
     309         257 :         GetList(idtrack,i,module,pList,tav);
     310         257 :       } // end if
     311         473 :       lasttrack=idtrack;
     312         473 :     } // end if
     313             :   }  // end loop over hits
     314         310 :   delete tav; tav=0;
     315             :   return;
     316        6792 : }
     317             : //----------------------------------------------------------------------
     318             : void AliITSsimulationSSD::HitToDigit(Int_t module, Double_t x0, Double_t y0, 
     319             :                                      Double_t z0, Double_t x1, Double_t y1, 
     320             :                                      Double_t z1, Double_t de,
     321             :                                      AliITSTableSSD *tav) {
     322             :   
     323             :   // hit to digit conversion
     324             :   
     325         946 :   AliITSsegmentationSSD* seg = (AliITSsegmentationSSD*)GetSegmentationModel(2);
     326             :   // Turns hits in SSD module into one or more digits.
     327             :   //Float_t tang[2] = {0.0,0.0};
     328             :   //seg->Angles(tang[0], tang[1]);//stereo<<->tan(stereo)~=stereo
     329             :   Double_t x, y, z;
     330         473 :   Double_t dex=0.0, dey=0.0, dez=0.0; 
     331             :   Double_t pairs; // pair generation energy per step.
     332         473 :   Double_t sigma[2] = {0.,0.};// standard deviation of the diffusion gaussian
     333         473 :   Double_t tdrift[2] = {0.,0.}; // time of drift
     334             :   Double_t w;
     335         473 :   Double_t inf[2], sup[2], par0[2];                 
     336             :  
     337             :   // Set up corrections for Lorentz drift (ExB)
     338         473 :   Double_t tanLorAngP = fTanLorAngP;
     339         473 :   Double_t tanLorAngN = fTanLorAngN;
     340         473 :   if(seg->GetLayer()==6) {
     341         263 :     tanLorAngP = -1.*fTanLorAngP;
     342         263 :     tanLorAngN = -1.*fTanLorAngN;
     343         263 :   }
     344             : 
     345             :   // Steps in the module are determined "manually" (i.e. No Geant)
     346             :   // NumOfSteps divide path between entering and exiting hits in steps 
     347         473 :   Int_t numOfSteps = NumOfSteps(x1, y1, z1, dex, dey, dez);
     348             :   // Enery loss is equally distributed among steps
     349         473 :   de    = de/numOfSteps;
     350         473 :   pairs = de/GetIonizeE(); // e-h pairs generated
     351             : 
     352             :   //-----------------------------------------------------
     353             :   // stepping
     354             :   //-----------------------------------------------------
     355        5721 :   for(Int_t j=0; j<numOfSteps; j++) {     // stepping
     356             : 
     357        2187 :     x = x0 + (j+0.5)*dex;
     358        2187 :     y = y0 + (j+0.5)*dey;
     359        2187 :     if ( y > (seg->Dy()/2+10)*1.0E-4 ) {
     360             :       // check if particle is within the detector
     361           0 :       Warning("HitToDigit",
     362             :               "hit out of detector y0=%e,y=%e,dey=%e,j =%d module=%d,  exceed=%e",
     363           0 :               y0,y,dey,j,module, y-(seg->Dy()/2+10)*1.0E-4);
     364           0 :       return;
     365             :     } // end if
     366        2187 :     z = z0 + (j+0.5)*dez;
     367             : 
     368        2187 :     if(GetDebug(4)) cout <<"HitToDigit "<<x<<" "<<y<<" "<<z<< " "
     369           0 :                          <<dex<<" "<<dey<<" "<<dez<<endl;
     370             : 
     371        2187 :     if(seg->GetLayer()==6) {
     372        1140 :       y=-y; // Lay6 module has sensor up-side-down!!!
     373        1140 :     }
     374             :     
     375             :     Int_t k;
     376             :     //---------------------------------------------------------
     377             :     // Pside
     378             :     //------------------------------------------------------------
     379             :     k=0;
     380             : 
     381             :     // w is the coord. perpendicular to the strips
     382             :     //    Float_t xp=x*1.e+4,zp=z*1.e+4; // microns    
     383        2187 :     Float_t xp=x,zp=z; 
     384             : 
     385             :     // correction for the Lorentz's angle
     386        2187 :     if(fLorentz) {
     387        2187 :       Float_t deltaxp = (y+(seg->Dy()*1.0E-4)/2)*tanLorAngP;
     388        2187 :       xp+=deltaxp;  
     389        2187 :     }
     390             : 
     391        2187 :     seg->GetPadTxz(xp,zp);
     392             :     
     393             :     // calculate drift time
     394             :     // y is the minimum path
     395        2187 :     tdrift[0] = (y+(seg->Dy()*1.0E-4)/2)/GetDriftVelocity(0);
     396             :     
     397        2187 :     w = xp; // P side strip number
     398             :     
     399        4374 :     if((w<(-0.5)) || (w>(GetNStrips()-0.5))) {
     400             :       // this check rejects hits in regions not covered by strips
     401             :       // 0.5 takes into account boundaries 
     402           0 :       if(GetDebug(4)) cout << "Dead SSD region, x,z="<<x<<","<<z<<endl;
     403           0 :       return; // There are dead region on the SSD sensitive volume!!!
     404             :     } // end if
     405             :     // sigma is the standard deviation of the diffusion gaussian
     406        2192 :     if(tdrift[k]<0) return;
     407             :     
     408        2182 :     sigma[k] = TMath::Sqrt(2*GetDiffConst(k)*tdrift[k]);
     409        2182 :     sigma[k] /= (GetStripPitch()*1.0E-4);  //units of Pitch
     410             :     
     411        2182 :     if(sigma[k]==0.0) {         
     412           0 :       Error("HitToDigit"," sigma[%d]=0",k);
     413           0 :       exit(0);
     414             :     } // end if
     415             :     
     416        2182 :     par0[k] = pairs;
     417             :     // we integrate the diffusion gaussian from -3sigma to 3sigma 
     418        2182 :     inf[k] = w - 3*sigma[k]; // 3 sigma from the gaussian average  
     419        2182 :     sup[k] = w + 3*sigma[k]; // 3 sigma from the gaussian average
     420             :     // IntegrateGaussian does the actual
     421             :     // integration of diffusion gaussian
     422        2182 :     IntegrateGaussian(k, par0[k], w, sigma[k], inf[k], sup[k],tav);
     423             :     
     424             :     //------------------------------------------------------
     425             :     // end Pside
     426             :     //-------------------------------------------------------
     427             :     
     428             :     //------------------------------------------------------
     429             :     // Nside
     430             :     //-------------------------------------------------------
     431             :     k=1;
     432             : 
     433        2182 :     xp=x; zp=z; 
     434             : 
     435             :     // correction for the Lorentz's angle
     436        2182 :     if(fLorentz) {
     437        2182 :       Float_t deltaxn = ((seg->Dy()*1.0E-4)/2-y)*tanLorAngN;
     438        2182 :       xp+=deltaxn;
     439        2182 :     }
     440             :     
     441             : 
     442        2182 :     seg->GetPadTxz(xp,zp);
     443             : 
     444        2182 :     tdrift[1] = ((seg->Dy()*1.0E-4)/2-y)/GetDriftVelocity(1);
     445             :     
     446             :     //tang[k]=TMath::Tan(tang[k]);
     447             :     
     448        2182 :     w = zp; // N side strip number
     449             :     
     450        4359 :     if((w<(-0.5)) || (w>(GetNStrips()-0.5))) {
     451             :       // this check rejects hits in regions not covered by strips
     452             :       // 0.5 takes into account boundaries 
     453          11 :       if(GetDebug(4)) cout << "Dead SSD region, x,z="<<x<<","<<z<<endl;
     454          11 :       return; // There are dead region on the SSD sensitive volume.
     455             :     } // end if
     456             :     
     457             :       // sigma is the standard deviation of the diffusion gaussian
     458        2179 :     if(tdrift[k]<0) return;
     459             :     
     460        2163 :     sigma[k] = TMath::Sqrt(2*GetDiffConst(k)*tdrift[k]);
     461        2163 :     sigma[k] /= (GetStripPitch()*1.0E-4);  //units of Pitch
     462             :     
     463        2163 :     if(sigma[k]==0.0) {         
     464           0 :       Error("HitToDigit"," sigma[%d]=0",k);
     465           0 :       exit(0);
     466             :     } // end if
     467             :     
     468        2163 :     par0[k] = pairs;
     469             :     // we integrate the diffusion gaussian from -3sigma to 3sigma 
     470        2163 :     inf[k] = w - 3*sigma[k]; // 3 sigma from the gaussian average  
     471        2163 :     sup[k] = w + 3*sigma[k]; // 3 sigma from the gaussian average
     472             :     // IntegrateGaussian does the actual
     473             :     // integration of diffusion gaussian
     474        2163 :     IntegrateGaussian(k, par0[k], w, sigma[k], inf[k], sup[k],tav);
     475             :     
     476             :     //-------------------------------------------------
     477             :     // end Nside
     478             :     //-------------------------------------------------
     479             :     
     480             :     
     481        4350 :   } // end stepping
     482         922 : }
     483             : 
     484             : //______________________________________________________________________
     485             : void AliITSsimulationSSD::ApplyNoise(AliITSpList *pList,Int_t module){
     486             :   // Apply Noise.
     487             :   Int_t ix;
     488             :   Double_t signal,noise;
     489       13584 :   AliITSCalibrationSSD* res =(AliITSCalibrationSSD*)GetCalibrationModel(module);
     490             :    
     491             :   // Pside
     492    10446096 :   for(ix=0;ix<GetNStrips();ix++){      // loop over strips
     493             :     
     494             :     // noise is gaussian
     495     5216256 :     noise  = (Double_t) gRandom->Gaus(0,res->GetNoiseP(ix));
     496             :     
     497             :     // need to calibrate noise 
     498             :     // NOTE. noise from the calibration database comes uncalibrated, 
     499             :     // it needs to be calibrated in order to be added
     500             :     // to the signal. It will be decalibrated later on together with the noise    
     501     5216256 :     noise *= (Double_t) res->GetGainP(ix); 
     502             :     
     503             :     // noise comes in ADC channels from the calibration database
     504             :     // It needs to be converted back to electronVolts
     505     5216256 :     noise /= res->GetSSDDEvToADC(1.);
     506             :     
     507             :     // Finally, noise is added to the signal
     508     5216256 :     signal = noise + fMapA2->GetSignal(0,ix);//get signal from map
     509     5216256 :     fMapA2->SetHit(0,ix,signal); // give back signal to map
     510     7703635 :     if(signal>0.0) pList->AddNoise(0,ix,module,noise);
     511             :   } // loop over strip 
     512             :   
     513             :     // Nside
     514    10446096 :   for(ix=0;ix<GetNStrips();ix++){      // loop over strips
     515     5216256 :     noise  = (Double_t) gRandom->Gaus(0,res->GetNoiseN(ix));// give noise to signal
     516     5216256 :     noise *= (Double_t) res->GetGainN(ix); 
     517     5216256 :     noise /= res->GetSSDDEvToADC(1.);
     518     5216256 :     signal = noise + fMapA2->GetSignal(1,ix);//get signal from map
     519     5216256 :     fMapA2->SetHit(1,ix,signal); // give back signal to map
     520     7703561 :     if(signal>0.0) pList->AddNoise(1,ix,module,noise);
     521             :   } // loop over strip 
     522             :   
     523        6792 : }
     524             : //______________________________________________________________________
     525             : void AliITSsimulationSSD::ApplyCoupling(AliITSpList *pList,Int_t module) {
     526             :   // Apply the effect of electronic coupling between channels
     527             :   Int_t ix;
     528             :   Double_t signal=0;
     529             :   //AliITSCalibrationSSD* res =(AliITSCalibrationSSD*)GetCalibrationModel(module);
     530       13584 :   AliITSSimuParam* res = fDetType->GetSimuParam();
     531             :     
     532        6792 :   Double_t *contrLeft  = new Double_t[GetNStrips()];
     533        6792 :   Double_t *contrRight = new Double_t[GetNStrips()];
     534             :   
     535             :   // P side coupling
     536    10446096 :   for(ix=0;ix<GetNStrips();ix++){
     537    10425720 :     if(ix>0) contrLeft[ix] = fMapA2->GetSignal(0,ix-1)*res->GetSSDCouplingPL();
     538        6792 :     else contrLeft[ix] = 0.0;
     539    10425720 :     if(ix<(GetNStrips()-1)) contrRight[ix] = fMapA2->GetSignal(0,ix+1)*res->GetSSDCouplingPR();
     540        6792 :     else contrRight[ix] = 0.0;
     541             :   } // loop over strips 
     542             :   
     543    10446096 :   for(ix=0;ix<GetNStrips();ix++){
     544     5216256 :     signal = contrLeft[ix] + contrRight[ix] - res->GetSSDCouplingPL() * fMapA2->GetSignal(0,ix)
     545     5216256 :       - res->GetSSDCouplingPR() * fMapA2->GetSignal(0,ix);
     546     5216256 :     fMapA2->AddSignal(0,ix,signal);
     547     7711341 :     if(signal>0.0) pList->AddNoise(0,ix,module,signal);
     548             :   } // loop over strips 
     549             :   
     550             :   // N side coupling
     551    10446096 :   for(ix=0;ix<GetNStrips();ix++){
     552    10425720 :     if(ix>0) contrLeft[ix] = fMapA2->GetSignal(1,ix-1)*res->GetSSDCouplingNL();
     553        6792 :     else contrLeft[ix] = 0.0;
     554    10425720 :     if(ix<(GetNStrips()-1)) contrRight[ix] = fMapA2->GetSignal(1,ix+1)*res->GetSSDCouplingNR();
     555        6792 :     else contrRight[ix] = 0.0;
     556             :   } // loop over strips 
     557             :   
     558    10446096 :   for(ix=0;ix<GetNStrips();ix++){
     559     5216256 :     signal = contrLeft[ix] + contrRight[ix] - res->GetSSDCouplingNL() * fMapA2->GetSignal(0,ix)
     560     5216256 :       - res->GetSSDCouplingNR() * fMapA2->GetSignal(0,ix);
     561     5216256 :     fMapA2->AddSignal(1,ix,signal);
     562     7742833 :     if(signal>0.0) pList->AddNoise(1,ix,module,signal);
     563             :   } // loop over strips 
     564             :   
     565             : 
     566       13584 :   delete [] contrLeft;
     567       13584 :   delete [] contrRight; 
     568        6792 : }
     569             : 
     570             : //______________________________________________________________________
     571             : void AliITSsimulationSSD::ApplyDeadChannels(Int_t module) {
     572             :   // Kill dead channels setting gain to zero
     573             : 
     574       13584 :   AliITSCalibrationSSD* res = (AliITSCalibrationSSD*)GetCalibrationModel(module);
     575             : 
     576    10446096 :   for(Int_t i=0;i<GetNStrips();i++){
     577             : 
     578     5543396 :     if(res->IsPChannelBad(i)) res->SetGainP(i,0.0);
     579     5535644 :     if(res->IsNChannelBad(i)) res->SetGainN(i,0.0);
     580             : 
     581             :   } // loop over strips 
     582             : 
     583        6792 : }
     584             : 
     585             : //______________________________________________________________________
     586             : Float_t AliITSsimulationSSD::F(Float_t av, Float_t x, Float_t s) {
     587             :     // Computes the integral of a gaussian using Error Function
     588       13752 :     Float_t sqrt2 = TMath::Sqrt(2.0);
     589        6876 :     Float_t sigm2 = sqrt2*s;
     590             :     Float_t integral;
     591             : 
     592        6876 :     integral = 0.5 * AliMathBase::ErfFast( (x - av) / sigm2);
     593        6876 :     return integral;
     594             : }
     595             : //______________________________________________________________________
     596             : void AliITSsimulationSSD::IntegrateGaussian(Int_t k,Double_t par, Double_t w,
     597             :                                             Double_t sigma, 
     598             :                                             Double_t inf, Double_t sup,
     599             :                                             AliITSTableSSD *tav) {
     600             :     // integrate the diffusion gaussian
     601             :     // remind: inf and sup are w-3sigma and w+3sigma
     602             :     //         we could define them here instead of passing them
     603             :     //         this way we are free to introduce asimmetry
     604             : 
     605             :     Double_t a=0.0, b=0.0;
     606             :     Double_t dXCharge1 = 0.0, dXCharge2 = 0.0;
     607             :     // dXCharge1 and 2 are the charge to two neighbouring strips
     608             :     // Watch that we only involve at least two strips
     609             :     // Numbers greater than 2 of strips in a cluster depend on
     610             :     //  geometry of the track and delta rays, not charge diffusion!   
     611             : 
     612        8690 :     Double_t strip = TMath::Floor(w);         // closest strip on the left
     613             : 
     614        4345 :     if ( TMath::Abs((strip - w)) < 0.5) { 
     615             :         // gaussian mean is closer to strip on the left
     616             :         a = inf;                         // integration starting point
     617        2203 :         if((strip+0.5)<=sup) {
     618             :             // this means that the tail of the gaussian goes beyond
     619             :             // the middle point between strips ---> part of the signal
     620             :             // is given to the strip on the right
     621             :             b = strip + 0.5;               // integration stopping point
     622         919 :             dXCharge1 = F( w, b, sigma) - F(w, a, sigma);
     623         919 :             dXCharge2 = F( w, sup, sigma) - F(w ,b, sigma); 
     624         919 :         }else { 
     625             :             // this means that all the charge is given to the strip on the left
     626             :             b = sup;
     627             :             dXCharge1 = 0.9973;   // gaussian integral at 3 sigmas
     628             :             dXCharge2 = 0.0;
     629             :         } // end if
     630        2203 :         dXCharge1 = par * dXCharge1;// normalize by mean of number of carriers
     631        2203 :         dXCharge2 = par * dXCharge2;
     632             : 
     633             :         // for the time being, signal is the charge
     634             :         // in ChargeToSignal signal is converted in ADC channel
     635        2203 :         fMapA2->AddSignal(k,(Int_t)strip,dXCharge1);
     636        2203 :         tav->Add(k,(Int_t)strip);
     637        2203 :         if(((Int_t) strip) < (GetNStrips()-1)) {
     638             :             // strip doesn't have to be the last (remind: last=GetNStrips()-1)
     639             :             // otherwise part of the charge is lost
     640        2203 :             fMapA2->AddSignal(k,((Int_t)strip+1),dXCharge2);
     641        2203 :             tav->Add(k,((Int_t)(strip+1)));
     642        2203 :         } // end if
     643             :     }else{
     644             :         // gaussian mean is closer to strip on the right
     645        2142 :         strip++;     // move to strip on the rigth
     646             :         b = sup;     // now you know where to stop integrating
     647        2142 :         if((strip-0.5)>=inf) { 
     648             :             // tail of diffusion gaussian on the left goes left of
     649             :             // middle point between strips
     650             :             a = strip - 0.5;        // integration starting point
     651         800 :             dXCharge1 = F(w, b, sigma) - F(w, a, sigma);
     652         800 :             dXCharge2 = F(w, a, sigma) - F(w, inf, sigma);
     653         800 :         }else {
     654             :             a = inf;
     655             :             dXCharge1 = 0.9973;   // gaussian integral at 3 sigmas
     656             :             dXCharge2 = 0.0;
     657             :         } // end if
     658        2142 :         dXCharge1 = par * dXCharge1;    // normalize by means of carriers
     659        2142 :         dXCharge2 = par * dXCharge2;
     660             :         // for the time being, signal is the charge
     661             :         // in ChargeToSignal signal is converted in ADC channel
     662        2142 :         fMapA2->AddSignal(k,(Int_t)strip,dXCharge1);
     663        2142 :         tav->Add(k,(Int_t)strip);
     664        2142 :         if(((Int_t) strip) > 0) {
     665             :             // strip doesn't have to be the first
     666             :             // otherwise part of the charge is lost
     667        2142 :             fMapA2->AddSignal(k,((Int_t)strip-1),dXCharge2);
     668        2142 :             tav->Add(k,((Int_t)(strip-1)));
     669        2142 :         } // end if
     670             :     } // end if
     671        4345 : }
     672             : //______________________________________________________________________
     673             : Int_t AliITSsimulationSSD::NumOfSteps(Double_t x, Double_t y, Double_t z,
     674             :                                       Double_t &dex,Double_t &dey,
     675             :                                       Double_t &dez){
     676             :     // number of steps
     677             :     // it also returns steps for each coord
     678             :     //AliITSsegmentationSSD *seg = new AliITSsegmentationSSD();
     679             : 
     680             :     Double_t step = 25E-4;
     681             :     //step = (Double_t) seg->GetStepSize();  // step size (cm)
     682         946 :     Int_t numOfSteps = (Int_t) (TMath::Sqrt(x*x+y*y+z*z)/step); 
     683             : 
     684         473 :     if (numOfSteps < 1) numOfSteps = 1;       // one step, at least
     685             :     //numOfSteps=1;
     686             : 
     687             :     // we could condition the stepping depending on the incident angle
     688             :     // of the track
     689         473 :     dex = x/numOfSteps;
     690         473 :     dey = y/numOfSteps;
     691         473 :     dez = z/numOfSteps;
     692             :     
     693         473 :     return numOfSteps;
     694             : }
     695             : //----------------------------------------------------------------------
     696             : void AliITSsimulationSSD::GetList(Int_t label,Int_t hit,Int_t mod,
     697             :                                   AliITSpList *pList,AliITSTableSSD *tav) {
     698             :     // loop over nonzero digits
     699             :     Int_t ix,i;
     700             :     Double_t signal=0.;
     701             : 
     702        1799 :     for(Int_t k=0; k<2; k++) {
     703         514 :         ix=tav->Use(k);
     704        3081 :         while(ix>-1){
     705        1162 :             signal = fMapA2->GetSignal(k,ix);
     706        1162 :             if(signal==0.0) {
     707         271 :                 ix=tav->Use(k);
     708         271 :                 continue;
     709             :             } // end if signal==0.0
     710             :             // check the signal magnitude
     711        7302 :             for(i=0;i<pList->GetNSignals(k,ix);i++){
     712        2760 :                 signal -= pList->GetTSignal(k,ix,i);
     713             :             } // end for i
     714             :             //  compare the new signal with already existing list
     715        1755 :             if(signal>0)pList->AddSignal(k,ix,label,hit,mod,signal);
     716         891 :             ix=tav->Use(k);
     717             :         } // end of loop on strips
     718             :     } // end of loop on P/N side
     719         257 :     tav->Clear();
     720         257 : }
     721             : //----------------------------------------------------------------------
     722             : void AliITSsimulationSSD::ChargeToSignal(Int_t module,const AliITSpList *pList) {
     723             :     // charge to signal
     724       13587 :     static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
     725             :     Float_t threshold = 0.;
     726        6792 :     Int_t size = AliITSdigitSSD::GetNTracks();
     727        6792 :     Int_t * digits = new Int_t[size];
     728        6792 :     Int_t * tracks = new Int_t[size];
     729        6792 :     Int_t * hits = new Int_t[size];
     730             :     Int_t j1;
     731        6792 :     Float_t charges[3] = {0.0,0.0,0.0};
     732             :     Float_t signal;
     733        6792 :     AliITSCalibrationSSD* res =(AliITSCalibrationSSD*)GetCalibrationModel(module);
     734        6792 :     AliITSSimuParam* simpar = fDetType->GetSimuParam();
     735             : 
     736       40752 :     for(Int_t k=0;k<2;k++){         // both sides (0=Pside, 1=Nside)
     737    20892192 :       for(Int_t ix=0;ix<GetNStrips();ix++){     // loop over strips
     738             : 
     739             :         // if strip is dead -> gain=0
     740    30970396 :         if( ((k==0)&&(res->GetGainP(ix)==0)) || ((k==1)&&(res->GetGainN(ix)==0))) continue;
     741             :         
     742     9785984 :         signal = fMapA2->GetSignal(k,ix);
     743             :         // signal has to be uncalibrated
     744             :         // In real life, gains are supposed to be calculated from calibration runs,
     745             :         // stored in the calibration DB and used in the reconstruction
     746             :         // (see AliITSClusterFinderSSD.cxx)
     747    14675100 :         if(k==0) signal /= res->GetGainP(ix);
     748     4896868 :         else signal /= res->GetGainN(ix);
     749             : 
     750             :         // signal is converted in unit of ADC
     751     9785984 :         signal = res->GetSSDDEvToADC(signal);
     752     9785984 :         if(signal>4095.) signal = 4095.;//if exceeding, accumulate last one
     753             : 
     754             :         // threshold for zero suppression is set on the basis of the noise
     755             :         // A good value is 3*sigma_noise
     756    14675100 :         if(k==0) threshold = res->GetNoiseP(ix);
     757     4896868 :         else threshold = res->GetNoiseN(ix);
     758             : 
     759     9785984 :         threshold *= simpar->GetSSDZSThreshold(); // threshold at 3 sigma noise
     760             : 
     761     9785984 :         if(signal < threshold) continue;
     762             :         //cout<<signal<<" "<<threshold<<endl;
     763             : 
     764       12465 :         digits[0] = k;
     765       12465 :         digits[1] = ix;
     766       12465 :         digits[2] = TMath::Nint(signal);
     767      398880 :         for(j1=0;j1<size;j1++)if(j1<pList->GetNEntries()){
     768             :           // only three in digit.
     769      124650 :           tracks[j1]  = pList->GetTrack(k,ix,j1);
     770      124650 :           hits[j1]    = pList->GetHit(k,ix,j1);
     771      124650 :         }else{
     772           0 :           tracks[j1]  = -3;
     773           0 :           hits[j1]    = -1;
     774             :         } // end for j1
     775             :         // finally add digit
     776       12465 :         aliITS->AddSimDigit(2,0,digits,tracks,hits,charges);
     777       12465 :       } // end for ix
     778             :     } // end for k
     779       13584 :     delete [] digits;
     780       13584 :     delete [] tracks;
     781       13584 :     delete [] hits;
     782        6792 : }
     783             : //______________________________________________________________________
     784             : void AliITSsimulationSSD::WriteSDigits(AliITSpList *pList){
     785             :     // Fills the Summable digits Tree
     786           0 :     Int_t i,ni,j,nj;
     787           0 :     static AliITS *aliITS = (AliITS*)gAlice->GetModule("ITS");
     788             : 
     789           0 :     pList->GetMaxMapIndex(ni,nj);
     790           0 :     for(i=0;i<ni;i++)for(j=0;j<nj;j++){
     791           0 :         if(pList->GetSignalOnly(i,j)>0.0){
     792           0 :             aliITS->AddSumDigit(*(pList->GetpListItem(i,j)));
     793           0 :             if(GetDebug(4)) cout << "pListSSD: "<<*(pList->GetpListItem(i,j))
     794           0 :                                 << endl;
     795             :         } // end if
     796             :     } // end for i,j
     797             :   return;
     798           0 : }
     799             : //______________________________________________________________________
     800             : void AliITSsimulationSSD::FillMapFrompList(AliITSpList *pList){
     801             :     // Fills fMap2A from the pList of Summable digits
     802             :     Int_t k,ix;
     803             : 
     804           0 :     for(k=0;k<2;k++)for(ix=0;ix<GetNStrips();ix++) 
     805           0 :         fMapA2->AddSignal(k,ix,pList->GetSignal(k,ix));
     806             :     return;
     807           0 : }
     808             : //______________________________________________________________________
     809             : void AliITSsimulationSSD::Print(ostream *os){
     810             :     //Standard output format for this class
     811             : 
     812             :     //AliITSsimulation::Print(os);
     813           0 :     *os << fIonE <<",";
     814           0 :     *os << fDifConst[0] <<","<< fDifConst[1] <<",";
     815           0 :     *os << fDriftVel[0] <<","<< fDriftVel[1];
     816             :     //*os <<","; fDCS->Print(os);
     817             :     //*os <<","; fMapA2->Print(os);
     818           0 : }
     819             : //______________________________________________________________________
     820             : void AliITSsimulationSSD::Read(istream *is){
     821             :     // Standard output streaming function.
     822             : 
     823             :     //AliITSsimulation::Read(is);
     824           0 :     *is >> fIonE;
     825           0 :     *is >> fDifConst[0] >> fDifConst[1];
     826           0 :     *is >> fDriftVel[0] >> fDriftVel[1];
     827             :     //fDCS->Read(is);
     828             :     //fMapA2->Read(is);
     829           0 : }
     830             : //______________________________________________________________________
     831             : ostream &operator<<(ostream &os,AliITSsimulationSSD &source){
     832             :     // Standard output streaming function.
     833             : 
     834           0 :     source.Print(&os);
     835           0 :     return os;
     836             : }
     837             : //______________________________________________________________________
     838             : istream &operator>>(istream &os,AliITSsimulationSSD &source){
     839             :     // Standard output streaming function.
     840             : 
     841           0 :     source.Read(&os);
     842           0 :     return os;
     843             : }
     844             : //______________________________________________________________________
     845             : 
     846             : 
     847             : 

Generated by: LCOV version 1.11