X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=TOF%2FAliTOFSDigitizer.cxx;h=6854b09e34d56f92cd0d46e7aded6ed43bb95044;hb=de8b244081d1ac55431107d2f232cdba97ea7335;hp=d86265ce7bd51941f494dc0807c9cfb328929ef7;hpb=e939a978a98d29901b86bdb02cdcaf5157e717de;p=u%2Fmrichter%2FAliRoot.git diff --git a/TOF/AliTOFSDigitizer.cxx b/TOF/AliTOFSDigitizer.cxx index d86265ce7bd..6854b09e34d 100644 --- a/TOF/AliTOFSDigitizer.cxx +++ b/TOF/AliTOFSDigitizer.cxx @@ -17,7 +17,7 @@ //__________________________________________________________// // // -// This is a TTask that constructs SDigits out of Hits // +// This is a class that constructs SDigits out of Hits // // A Summable Digits is the "sum" of all hits in a pad // // Detector response has been simulated via the method // // SimulateDetectorResponse // @@ -27,11 +27,13 @@ //__________________________________________________________// #include +#include #include #include #include #include #include +#include #include "AliLoader.h" #include "AliLog.h" @@ -39,6 +41,8 @@ #include "AliRunLoader.h" #include "AliRun.h" +#include "AliTOFcalib.h" +#include "AliTOFRecoParam.h" #include "AliTOFGeometry.h" #include "AliTOFHitMap.h" #include "AliTOFhitT0.h" @@ -47,22 +51,22 @@ #include "AliTOFSDigit.h" #include "AliTOF.h" +extern TROOT *gROOT; ClassImp(AliTOFSDigitizer) //____________________________________________________________________________ AliTOFSDigitizer::AliTOFSDigitizer(): - TTask("TOFSDigitizer",""), + TNamed("TOFSDigitizer",""), fEvent1(-1), fEvent2(-1), ftail(0x0), fHeadersFile(""), fRunLoader(0x0), fTOFLoader(0x0), - fTOFGeometry(new AliTOFGeometry()), fSelectedSector(-1), fSelectedPlate(-1), - fTimeResolution(0), + fTimeResolution(100.), fpadefficiency(0), fEdgeEffect(-1), fEdgeTails(-1), @@ -91,24 +95,25 @@ AliTOFSDigitizer::AliTOFSDigitizer(): fAverageTimeFlag(-1), fAdcBin(0), fAdcMean(0), - fAdcRms(0) + fAdcRms(0), + fCalib(new AliTOFcalib()) { // ctor + } //------------------------------------------------------------------------ AliTOFSDigitizer::AliTOFSDigitizer(const AliTOFSDigitizer &source): - TTask(source), + TNamed(source), fEvent1(-1), fEvent2(-1), ftail(0x0), fHeadersFile(""), fRunLoader(0x0), fTOFLoader(0x0), - fTOFGeometry(0x0), fSelectedSector(-1), fSelectedPlate(-1), - fTimeResolution(0), + fTimeResolution(100.), fpadefficiency(0), fEdgeEffect(-1), fEdgeTails(-1), @@ -137,35 +142,34 @@ AliTOFSDigitizer::AliTOFSDigitizer(const AliTOFSDigitizer &source): fAverageTimeFlag(-1), fAdcBin(0), fAdcMean(0), - fAdcRms(0) + fAdcRms(0), + fCalib(new AliTOFcalib()) { // copy constructor - this->fTOFGeometry=source.fTOFGeometry; + //this->fTOFGeometry=source.fTOFGeometry; } //____________________________________________________________________________ -AliTOFSDigitizer& AliTOFSDigitizer::operator=(const AliTOFSDigitizer &source) +AliTOFSDigitizer& AliTOFSDigitizer::operator=(const AliTOFSDigitizer &/*source*/) { // ass. op. - this->fTOFGeometry=source.fTOFGeometry; return *this; } //____________________________________________________________________________ AliTOFSDigitizer::AliTOFSDigitizer(const char* HeaderFile, Int_t evNumber1, Int_t nEvents): - TTask("TOFSDigitizer",""), + TNamed("TOFSDigitizer",""), fEvent1(-1), fEvent2(-1), ftail(0x0), fHeadersFile(HeaderFile), // input filename (with hits) fRunLoader(0x0), fTOFLoader(0x0), - fTOFGeometry(0x0), fSelectedSector(-1), // by default we sdigitize all sectors fSelectedPlate(-1), // by default we sdigitize all plates in all sectors - fTimeResolution(0), + fTimeResolution(100.), fpadefficiency(0), fEdgeEffect(-1), fEdgeTails(-1), @@ -194,7 +198,8 @@ AliTOFSDigitizer::AliTOFSDigitizer(const char* HeaderFile, Int_t evNumber1, Int_ fAverageTimeFlag(-1), fAdcBin(0), fAdcMean(0), - fAdcRms(0) + fAdcRms(0), + fCalib(new AliTOFcalib()) { //ctor, reading from input file @@ -217,10 +222,13 @@ AliTOFSDigitizer::AliTOFSDigitizer(const char* HeaderFile, Int_t evNumber1, Int_ return; } + /* fRunLoader->CdGAFile(); TDirectory *savedir=gDirectory; TFile *in=(TFile*)gFile; + +// when fTOFGeometry was needed if (!in->IsOpen()) { AliWarning("Geometry file is not open default TOF geometry will be used"); fTOFGeometry = new AliTOFGeometry(); @@ -229,9 +237,9 @@ AliTOFSDigitizer::AliTOFSDigitizer(const char* HeaderFile, Int_t evNumber1, Int_ in->cd(); fTOFGeometry = (AliTOFGeometry*)in->Get("TOFgeometry"); } - + savedir->cd(); - + */ if (fRunLoader->TreeE() == 0x0) fRunLoader->LoadHeader(); if (evNumber1>=0) fEvent1 = evNumber1; @@ -257,16 +265,13 @@ AliTOFSDigitizer::AliTOFSDigitizer(const char* HeaderFile, Int_t evNumber1, Int_ AliFatal("Can not find TOF loader in event. Exiting."); return; } - fTOFLoader->PostSDigitizer(this); } //____________________________________________________________________________ AliTOFSDigitizer::~AliTOFSDigitizer() { // dtor - fTOFLoader->CleanSDigitizer(); - - delete fTOFGeometry; + if (fCalib) delete fCalib; } @@ -275,18 +280,29 @@ void AliTOFSDigitizer::InitParameters() { // set parameters for detector simulation - fTimeResolution = 0.080; //0.120; OLD - fpadefficiency = 0.99 ; - fEdgeEffect = 2 ; + fCalib->Init(); + + //fTimeResolution = 80.; //120.; OLD + AliTOFRecoParam *recoParams = (AliTOFRecoParam*)fCalib->ReadRecParFromCDB("TOF/Calib",fRunLoader->GetRunNumber()); + fTimeResolution = recoParams->GetTimeResolution(); // now from OCDB + if (fTimeResolution==0.) { + AliWarning("In OCDB found 0ps for TOF time resolution. It is set to 100ps."); + fTimeResolution = 100.; + } + AliDebug(1,Form(" TOF time resolution read from OCDB = %f ps",fTimeResolution)); + fpadefficiency = 0.995 ; + //fEdgeEffect = 2 ; // edge effects according to test beam results + fEdgeEffect = 1 ; // edge effects according to test beam results + // but with fixed time resolution, i.e. fTimeResolution fEdgeTails = 0 ; fHparameter = 0.4 ; fH2parameter = 0.15; - fKparameter = 0.5 ; - fK2parameter = 0.35; + fKparameter = 0.9 ; + fK2parameter = 0.55; fEffCenter = fpadefficiency; - fEffBoundary = 0.65; - fEff2Boundary = 0.90; - fEff3Boundary = 0.08; + fEffBoundary = 0.833; + fEff2Boundary = 0.94; + fEff3Boundary = 0.1; fAddTRes = 68. ; // \sqrt{2x20^2 + 15^2 + 2x10^2 + 30^2 + 50^2} (p-p) //fAddTRes = 48. ; // \sqrt{2x20^2 + 15^2 + 2x10^2 + 30^2 + 15^2} (Pb-Pb) // 30^2+20^2+40^2+50^2+50^2+50^2 = 10400 ps^2 (very old value) @@ -296,7 +312,7 @@ void AliTOFSDigitizer::InitParameters() fTimeWalkCenter = 0. ; fTimeWalkBoundary=0. ; fTimeWalkSlope = 0. ; - fTimeDelayFlag = 1 ; + fTimeDelayFlag = 0 ; fPulseHeightSlope=2.0 ; fTimeDelaySlope =0.060; // was fMinimumCharge = TMath::Exp(fPulseHeightSlope*fKparameter/2.); @@ -314,7 +330,7 @@ void AliTOFSDigitizer::InitParameters() } //__________________________________________________________________ -Double_t TimeWithTail(Double_t* x, Double_t* par) +Double_t TimeWithTail(const Double_t * const x, const Double_t * const par) { // sigma - par[0], alpha - par[1], part - par[2] // at xStart("TOFSDigitizer"); @@ -359,17 +375,26 @@ void AliTOFSDigitizer::Exec(Option_t *verboseOption) { AliError("TOF not found"); return; } - + fTOFLoader->LoadHits("read"); fTOFLoader->LoadSDigits("recreate"); + + Int_t vol[5]={-1,-1,-1,-1,-1}; // location for a digit + Int_t digit[2]={0,0}; // TOF digit variables + Int_t nselectedHitsinEv=0; + Int_t ntotalsdigitsinEv=0; + Int_t ntotalupdatesinEv=0; + Int_t nnoisesdigitsinEv=0; + Int_t nsignalsdigitsinEv=0; + for (Int_t iEvent=fEvent1; iEventGetEvent(iEvent); - TTree *hitTree = fTOFLoader->TreeH (); + TTree *hitTree = fTOFLoader->TreeH(); if (!hitTree) return; if (fTOFLoader->TreeS () == 0) fTOFLoader->MakeTree ("S"); @@ -388,30 +413,31 @@ void AliTOFSDigitizer::Exec(Option_t *verboseOption) { Int_t version=tof->IsVersion(); - Int_t nselectedHitsinEv=0; - Int_t ntotalsdigitsinEv=0; - Int_t ntotalupdatesinEv=0; - Int_t nnoisesdigitsinEv=0; - Int_t nsignalsdigitsinEv=0; + nselectedHitsinEv=0; + ntotalsdigitsinEv=0; + ntotalupdatesinEv=0; + nnoisesdigitsinEv=0; + nsignalsdigitsinEv=0; TParticle *particle; //AliTOFhit *tofHit; TClonesArray *tofHitArray = tof->Hits(); // create hit map - AliTOFHitMap *hitMap = new AliTOFHitMap(tof->SDigits(), fTOFGeometry); + //AliTOFHitMap *hitMap = new AliTOFHitMap(tof->SDigits(), fTOFGeometry); + AliTOFHitMap *hitMap = new AliTOFHitMap(tof->SDigits()); TBranch * tofHitsBranch = hitTree->GetBranch("TOF"); Int_t ntracks = static_cast(hitTree->GetEntries()); for (Int_t track = 0; track < ntracks; track++) { - gAlice->ResetHits(); + gAlice->GetMCApp()->ResetHits(); tofHitsBranch->GetEvent(track); AliMC *mcApplication = (AliMC*)gAlice->GetMCApp(); - particle = mcApplication->Particle(track); + particle = (TParticle*)mcApplication->Particle(track); Int_t nhits = tofHitArray->GetEntriesFast(); // cleaning all hits of the same track in the same pad volume // it is a rare event, however it happens @@ -424,16 +450,16 @@ void AliTOFSDigitizer::Exec(Option_t *verboseOption) { Int_t previousPadZ =-1; for (Int_t hit = 0; hit < nhits; hit++) { - Int_t vol[5]; // location for a digit - Float_t digit[2]; // TOF digit variables - Int_t tracknum; + for (Int_t aa=0; aa<5;aa++) vol[aa]=-1; // location for a digit + for (Int_t aa=0; aa<2;aa++) digit[aa]=0; // TOF digit variables + Int_t tracknum; Float_t dxPad; Float_t dzPad; Float_t geantTime; // fp: really sorry for this, it is a temporary trick to have // track length too - if(version!=6 && version!=7){ + if (version<6) { //(version!=6 && version!=7) AliTOFhit *tofHit = (AliTOFhit *) tofHitArray->UncheckedAt(hit); tracknum = tofHit->GetTrack(); vol[0] = tofHit->GetSector(); @@ -443,7 +469,7 @@ void AliTOFSDigitizer::Exec(Option_t *verboseOption) { vol[4] = tofHit->GetPadz(); dxPad = tofHit->GetDx(); dzPad = tofHit->GetDz(); - geantTime = tofHit->GetTof(); // unit [s] + geantTime = tofHit->GetTof(); // unit [s] // already corrected per event_time smearing } else { AliTOFhitT0 *tofHit = (AliTOFhitT0 *) tofHitArray->UncheckedAt(hit); tracknum = tofHit->GetTrack(); @@ -454,11 +480,17 @@ void AliTOFSDigitizer::Exec(Option_t *verboseOption) { vol[4] = tofHit->GetPadz(); dxPad = tofHit->GetDx(); dzPad = tofHit->GetDz(); - geantTime = tofHit->GetTof(); // unit [s] + geantTime = tofHit->GetTof(); // unit [s] // already corrected per event_time_smearing } geantTime *= 1.e+09; // conversion from [s] to [ns] - + // TOF matching window (~200ns) control + if (geantTime>=AliTOFGeometry::MatchingWindow()*1E-3) { + AliDebug(2,Form("Time measurement (%f) greater than the matching window (%f)", + geantTime, AliTOFGeometry::MatchingWindow()*1E-3)); + continue; + } + // selection case for sdigitizing only hits in a given plate of a given sector if(thereIsNotASelection || (vol[0]==fSelectedSector && vol[1]==fSelectedPlate)){ @@ -495,14 +527,22 @@ void AliTOFSDigitizer::Exec(Option_t *verboseOption) { if(nFiredPads) { for(Int_t indexOfPad=0; indexOfPad=AliTOFGeometry::MatchingWindow()*1E-3) { + AliDebug(2,Form("Time measurement (%f) greater than the matching window (%f)", + tofAfterSimul[indexOfPad], AliTOFGeometry::MatchingWindow()*1E-3)); + continue; + } + + if(timediff>=0.2) nlargeTofDiff++; // greater than 200ps - if(timediff>=0.2) nlargeTofDiff++; - - digit[0] = (Int_t) ((tofAfterSimul[indexOfPad]*1.e+03)/AliTOFGeometry::TdcBinWidth()); // TDC bin number (each bin -> 24.4 ps) + digit[0] = TMath::Nint((tofAfterSimul[indexOfPad]*1.e+03)/AliTOFGeometry::TdcBinWidth()); // TDC bin number (each bin -> 24.4 ps) Float_t landauFactor = gRandom->Landau(fAdcMean, fAdcRms); - digit[1] = (Int_t) (qInduced[indexOfPad] * landauFactor); // ADC bins (each bin -> 0.25 (or 0.03) pC) + digit[1] = TMath::Nint(qInduced[indexOfPad] * landauFactor); // ADC bins (each bin -> 0.25 (or 0.03) pC) // recalculate the volume only for neighbouring pads if(indexOfPad){ @@ -549,15 +589,14 @@ void AliTOFSDigitizer::Exec(Option_t *verboseOption) { if (tof->SDigits()) tof->ResetSDigits(); - if (strstr(verboseOption,"all")) { - AliInfo("----------------------------------------"); - AliInfo(" "); - AliInfo(Form("After sdigitizing %d hits in event %d", nselectedHitsinEv, iEvent)); + if (strstr(verboseOption,"all") || strstr(verboseOption,"partial")) { + AliDebug(2,"----------------------------------------"); + AliDebug(2,Form("After sdigitizing %d hits in event %d", nselectedHitsinEv, iEvent)); //" (" << nHitsFromPrim << " from primaries and " << nHitsFromSec << " from secondaries) TOF hits, " - AliInfo(Form("%d digits have been created", ntotalsdigitsinEv)); - AliInfo(Form("(%d due to signals and %d due to border effect)", nsignalsdigitsinEv, nnoisesdigitsinEv)); - AliInfo(Form("%d total updates of the hit map have been performed in current event", ntotalupdatesinEv)); - AliInfo("----------------------------------------"); + AliDebug(1,Form("%d sdigits have been created", ntotalsdigitsinEv)); + AliDebug(2,Form("(%d due to signals and %d due to border effect)", nsignalsdigitsinEv, nnoisesdigitsinEv)); + AliDebug(2,Form("%d total updates of the hit map have been performed in current event", ntotalupdatesinEv)); + AliDebug(2,"----------------------------------------"); } } //event loop on events @@ -574,19 +613,15 @@ void AliTOFSDigitizer::Exec(Option_t *verboseOption) { } nHitsFromSec=nselectedHits-nHitsFromPrim; - if(strstr(verboseOption,"all")){ - AliInfo("----------------------------------------"); - AliInfo("----------------------------------------"); - AliInfo("-----------SDigitization Summary--------"); - AliInfo(" "); - AliInfo(Form("After sdigitizing %d hits", nselectedHits)); - AliInfo(Form("in %d events", fEvent2-fEvent1)); -//" (" << nHitsFromPrim << " from primaries and " << nHitsFromSec << " from secondaries) TOF hits, " - AliInfo(Form("%d sdigits have been created", ntotalsdigits)); - AliInfo(Form("(%d due to signals and " - "%d due to border effect)", nsignalsdigits, nnoisesdigits)); - AliInfo(Form("%d total updates of the hit map have been performed", ntotalupdates)); - AliInfo(Form("in %d cases the time of flight difference is greater than 200 ps", nlargeTofDiff)); + if (strstr(verboseOption,"all") || strstr(verboseOption,"partial")) { + AliDebug(2,"----------------------------------------"); + AliDebug(2,Form("After sdigitizing %d hits in %d events ", nselectedHits, fEvent2-fEvent1)); + //" (" << nHitsFromPrim << " from primaries and " << nHitsFromSec << " from secondaries) TOF hits, " + AliDebug(2,Form("%d sdigits have been created", ntotalsdigits)); + AliDebug(2,Form("(%d due to signals and %d due to border effect)", nsignalsdigits, nnoisesdigits)); + AliDebug(2,Form("%d total updates of the hit map have been performed", ntotalupdates)); + AliDebug(2,Form("in %d cases the time of flight difference is greater than 200 ps", nlargeTofDiff)); + AliDebug(2,"----------------------------------------"); } @@ -687,8 +722,9 @@ void AliTOFSDigitizer::SimulateDetectorResponse(Float_t z0, Float_t x0, Float_t nPlace[nActivatedPads-1] = (iz - 1) * AliTOFGeometry::NpadX() + ix; qInduced[nActivatedPads-1] = qCenterPad; padId[nActivatedPads-1] = 1; - - if (fEdgeEffect == 0) { + + switch (fEdgeEffect) { + case 0: eff[nActivatedPads-1] = fEffCenter; if (gRandom->Rndm() < eff[nActivatedPads-1]) { nFiredPads = 1; @@ -697,8 +733,207 @@ void AliTOFSDigitizer::SimulateDetectorResponse(Float_t z0, Float_t x0, Float_t tofTime[nActivatedPads-1] = gRandom->Gaus(geantTime + fTimeWalkCenter, res[0]); averageTime = tofTime[nActivatedPads-1]; } - } else { - + break; + + case 1: + if(z < h) { + if(z < h2) { + effZ = fEffBoundary + (fEff2Boundary - fEffBoundary) * z / h2; + } else { + effZ = fEff2Boundary + (fEffCenter - fEff2Boundary) * (z - h2) / (h - h2); + } + //resZ = fTimeResolution; + //timeWalkZ = 0.; + nTail[nActivatedPads-1] = 1; + } else { + effZ = fEffCenter; + //resZ = fTimeResolution; + //timeWalkZ = 0.; + } + + if(x < h) { + if(x < h2) { + effX = fEffBoundary + (fEff2Boundary - fEffBoundary) * x / h2; + } else { + effX = fEff2Boundary + (fEffCenter - fEff2Boundary) * (x - h2) / (h - h2); + } + //resX = fTimeResolution; + //timeWalkX = 0.; + nTail[nActivatedPads-1] = 1; + } else { + effX = fEffCenter; + //resX = fTimeResolution; + //timeWalkX = 0.; + } + + (effZ 0) { + if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) { + nActivatedPads++; + nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX(); + eff[nActivatedPads-1] = effZ; + res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns + timeWalk[nActivatedPads-1] = 0.; // ns + nTail[nActivatedPads-1] = 2; + if (fTimeDelayFlag) { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing); + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 2; + } + } + + + ////// Pad C, D, E, F: + if(x < k2) { + effX = fEffBoundary - (fEffBoundary - fEff3Boundary) * (x / k2); + } else { + effX = fEff3Boundary * (k - x) / (k - k2); + } + //resX = fTimeResolution; + //timeWalkX = 0.; + + if(x < k && x > 0) { + // C: + if(ix > 1 && dX < 0) { + nActivatedPads++; + nPlace[nActivatedPads-1] = nPlace[0] - 1; + eff[nActivatedPads-1] = effX; + res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns + timeWalk[nActivatedPads-1] = 0.; // ns + nTail[nActivatedPads-1] = 2; + if (fTimeDelayFlag) { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing); + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 3; + + // D: + if(z < k && z > 0) { + if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) { + nActivatedPads++; + nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1; + eff[nActivatedPads-1] = effX * effZ; + res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns + timeWalk[nActivatedPads-1] = 0.; // ns + + nTail[nActivatedPads-1] = 2; + if (fTimeDelayFlag) { + if (TMath::Abs(x) < TMath::Abs(z)) { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing); + } else { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing); + } + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 4; + } + } // end D + } // end C + + // E: + if(ix < AliTOFGeometry::NpadX() && dX > 0) { + nActivatedPads++; + nPlace[nActivatedPads-1] = nPlace[0] + 1; + eff[nActivatedPads-1] = effX; + res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns + timeWalk[nActivatedPads-1] = 0.; // ns + nTail[nActivatedPads-1] = 2; + if (fTimeDelayFlag) { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing); + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 5; + + + // F: + if(z < k && z > 0) { + if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) { + nActivatedPads++; + nPlace[nActivatedPads - 1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() + 1; + eff[nActivatedPads - 1] = effX * effZ; + res[nActivatedPads-1] = 0.001 * fTimeResolution; // ns + timeWalk[nActivatedPads-1] = 0.; // ns + nTail[nActivatedPads-1] = 2; + if (fTimeDelayFlag) { + if (TMath::Abs(x) < TMath::Abs(z)) { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing); + } else { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing); + } + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 6; + } + } // end F + } // end E + } // end if(x < k) + + + for (Int_t iPad = 0; iPad < nActivatedPads; iPad++) { + if(gRandom->Rndm() < eff[iPad]) { + isFired[iPad] = kTRUE; + nFiredPads++; + if(fEdgeTails) { + if(nTail[iPad] == 0) { + tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]); + } else { + ftail->SetParameters(res[iPad], 2. * res[iPad], kSigmaForTail[nTail[iPad]-1]); + Double_t timeAB = ftail->GetRandom(); + tofTime[iPad] = geantTime + timeWalk[iPad] + timeDelay[iPad] + timeAB; + } + } else { + //AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad])); + tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]); + } + if (fAverageTimeFlag) { + averageTime += tofTime[iPad] * qInduced[iPad]; + weightsSum += qInduced[iPad]; + } else { + averageTime += tofTime[iPad]; + weightsSum += 1.; + } + + AliDebug(1,Form(" Activated pad %d: geantTime=%f, tw=%fns, td=%fns, tofTime=%fns, sigma=%fps",iPad,geantTime,timeWalk[iPad],timeDelay[iPad],tofTime[iPad],1000.*res[iPad])); + + } + + } + if (weightsSum!=0) averageTime /= weightsSum; + break; + + + case 2: if(z < h) { if(z < h2) { effZ = fEffBoundary + (fEff2Boundary - fEffBoundary) * z / h2; @@ -752,8 +987,6 @@ void AliTOFSDigitizer::SimulateDetectorResponse(Float_t z0, Float_t x0, Float_t timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ; // ns nTail[nActivatedPads-1] = 2; if (fTimeDelayFlag) { - // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * z / 2.); - // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * z / 2.); qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z); logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing); timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); @@ -783,6 +1016,307 @@ void AliTOFSDigitizer::SimulateDetectorResponse(Float_t z0, Float_t x0, Float_t res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX); // ns timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns nTail[nActivatedPads-1] = 2; + if (fTimeDelayFlag) { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing); + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 3; + + // D: + if(z < k && z > 0) { + if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) { + nActivatedPads++; + nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1; + eff[nActivatedPads-1] = effX * effZ; + (resZGaus(-fPulseHeightSlope * z, fLogChargeSmearing); + } else { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing); + } + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 4; + } + } // end D + } // end C + + // E: + if(ix < AliTOFGeometry::NpadX() && dX > 0) { + nActivatedPads++; + nPlace[nActivatedPads-1] = nPlace[0] + 1; + eff[nActivatedPads-1] = effX; + res[nActivatedPads-1] = 0.001 * (TMath::Sqrt(fAddTRes*fAddTRes + resX * resX)); // ns + timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns + nTail[nActivatedPads-1] = 2; + if (fTimeDelayFlag) { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing); + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 5; + + + // F: + if(z < k && z > 0) { + if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) { + nActivatedPads++; + nPlace[nActivatedPads - 1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() + 1; + eff[nActivatedPads - 1] = effX * effZ; + (resZGaus(-fPulseHeightSlope * z, fLogChargeSmearing); + } else { + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * x); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * x, fLogChargeSmearing); + } + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 6; + } + } // end F + } // end E + } // end if(x < k) + + + for (Int_t iPad = 0; iPad < nActivatedPads; iPad++) { + if (res[iPad] < fTimeResolution) res[iPad] = fTimeResolution; + if(gRandom->Rndm() < eff[iPad]) { + isFired[iPad] = kTRUE; + nFiredPads++; + if(fEdgeTails) { + if(nTail[iPad] == 0) { + tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]); + } else { + ftail->SetParameters(res[iPad], 2. * res[iPad], kSigmaForTail[nTail[iPad]-1]); + Double_t timeAB = ftail->GetRandom(); + tofTime[iPad] = geantTime + timeWalk[iPad] + timeDelay[iPad] + timeAB; + } + } else { + AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad])); + tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]); + } + if (fAverageTimeFlag) { + averageTime += tofTime[iPad] * qInduced[iPad]; + weightsSum += qInduced[iPad]; + } else { + averageTime += tofTime[iPad]; + weightsSum += 1.; + } + } + } + if (weightsSum!=0) averageTime /= weightsSum; + + } // switch (fEdgeEffect) + +} + +//__________________________________________________________________ +void AliTOFSDigitizer::SimulateDetectorResponseOLD(Float_t z0, Float_t x0, Float_t geantTime, Int_t& nActivatedPads, Int_t& nFiredPads, Bool_t* isFired, Int_t* nPlace, Float_t* qInduced, Float_t* tofTime, Float_t& averageTime) +{ + // Description: + // Input: z0, x0 - hit position in the strip system (0,0 - center of the strip), cm + // geantTime - time generated by Geant, ns + // Output: nActivatedPads - the number of pads activated by the hit (1 || 2 || 4) + // nFiredPads - the number of pads fired (really activated) by the hit (nFiredPads <= nActivatedPads) + // qInduced[iPad]- charge induced on pad, arb. units + // this array is initialized at zero by the caller + // tofAfterSimul[iPad] - time calculated with edge effect algorithm, ns + // this array is initialized at zero by the caller + // averageTime - time given by pad hited by the Geant track taking into account the times (weighted) given by the pads fired for edge effect also. + // The weight is given by the qInduced[iPad]/qCenterPad + // this variable is initialized at zero by the caller + // nPlace[iPad] - the number of the pad place, iPad = 0, 1, 2, 3 + // this variable is initialized at zero by the caller + // + // Description of used variables: + // eff[iPad] - efficiency of the pad + // res[iPad] - resolution of the pad, ns + // timeWalk[iPad] - time walk of the pad, ns + // timeDelay[iPad] - time delay for neighbouring pad to hited pad, ns + // PadId[iPad] - Pad Identifier + // E | F --> PadId[iPad] = 5 | 6 + // A | B --> PadId[iPad] = 1 | 2 + // C | D --> PadId[iPad] = 3 | 4 + // nTail[iPad] - the tail number, = 1 for tailA, = 2 for tailB + // qCenterPad - charge extimated for each pad, arb. units + // weightsSum - sum of weights extimated for each pad fired, arb. units + + const Float_t kSigmaForTail[2] = {AliTOFGeometry::SigmaForTail1(),AliTOFGeometry::SigmaForTail2()}; //for tail + Int_t iz = 0, ix = 0; + Float_t dX = 0., dZ = 0., x = 0., z = 0.; + Float_t h = fHparameter, h2 = fH2parameter, k = fKparameter, k2 = fK2parameter; + Float_t effX = 0., effZ = 0., resX = 0., resZ = 0., timeWalkX = 0., timeWalkZ = 0.; + Float_t logOfqInd = 0.; + Float_t weightsSum = 0.; + Int_t nTail[4] = {0,0,0,0}; + Int_t padId[4] = {0,0,0,0}; + Float_t eff[4] = {0.,0.,0.,0.}; + Float_t res[4] = {0.,0.,0.,0.}; + // Float_t qCenterPad = fMinimumCharge * fMinimumCharge; + Float_t qCenterPad = 1.; + Float_t timeWalk[4] = {0.,0.,0.,0.}; + Float_t timeDelay[4] = {0.,0.,0.,0.}; + + nActivatedPads = 0; + nFiredPads = 0; + + (z0 <= 0) ? iz = 0 : iz = 1; + dZ = z0 + (0.5 * AliTOFGeometry::NpadZ() - iz - 0.5) * AliTOFGeometry::ZPad(); // hit position in the pad frame, (0,0) - center of the pad + z = 0.5 * AliTOFGeometry::ZPad() - TMath::Abs(dZ); // variable for eff., res. and timeWalk. functions + iz++; // z row: 1, ..., AliTOFGeometry::NpadZ = 2 + ix = (Int_t)((x0 + 0.5 * AliTOFGeometry::NpadX() * AliTOFGeometry::XPad()) / AliTOFGeometry::XPad()); + dX = x0 + (0.5 * AliTOFGeometry::NpadX() - ix - 0.5) * AliTOFGeometry::XPad(); // hit position in the pad frame, (0,0) - center of the pad + x = 0.5 * AliTOFGeometry::XPad() - TMath::Abs(dX); // variable for eff., res. and timeWalk. functions; + ix++; // x row: 1, ..., AliTOFGeometry::NpadX = 48 + + ////// Pad A: + nActivatedPads++; + nPlace[nActivatedPads-1] = (iz - 1) * AliTOFGeometry::NpadX() + ix; + qInduced[nActivatedPads-1] = qCenterPad; + padId[nActivatedPads-1] = 1; + + if (fEdgeEffect == 0) { + eff[nActivatedPads-1] = fEffCenter; + if (gRandom->Rndm() < eff[nActivatedPads-1]) { + nFiredPads = 1; + res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + fResCenter * fResCenter); // ns + isFired[nActivatedPads-1] = kTRUE; + tofTime[nActivatedPads-1] = gRandom->Gaus(geantTime + fTimeWalkCenter, res[0]); + averageTime = tofTime[nActivatedPads-1]; + } + } else { // if (fEdgeEffet!=0) + + if(z < h) { + if(z < h2) { + effZ = fEffBoundary + (fEff2Boundary - fEffBoundary) * z / h2; + } else { + effZ = fEff2Boundary + (fEffCenter - fEff2Boundary) * (z - h2) / (h - h2); + } + if (fEdgeEffect==1) + resZ = fTimeResolution; + else if (fEdgeEffect==2) + resZ = fResBoundary + (fResCenter - fResBoundary) * z / h; + timeWalkZ = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * z / h; + nTail[nActivatedPads-1] = 1; + } else { + effZ = fEffCenter; + if (fEdgeEffect==1) + resZ = fTimeResolution; + else if (fEdgeEffect==2) + resZ = fResCenter; + timeWalkZ = fTimeWalkCenter; + } + + if(x < h) { + if(x < h2) { + effX = fEffBoundary + (fEff2Boundary - fEffBoundary) * x / h2; + } else { + effX = fEff2Boundary + (fEffCenter - fEff2Boundary) * (x - h2) / (h - h2); + } + if (fEdgeEffect==1) + resX = fTimeResolution; + else if (fEdgeEffect==2) + resX = fResBoundary + (fResCenter - fResBoundary) * x / h; + timeWalkX = fTimeWalkBoundary + (fTimeWalkCenter - fTimeWalkBoundary) * x / h; + nTail[nActivatedPads-1] = 1; + } else { + effX = fEffCenter; + if (fEdgeEffect==1) + resX = fTimeResolution; + else if (fEdgeEffect==2) + resX = fResCenter; + timeWalkX = fTimeWalkCenter; + } + + (effZ 0) { + if( (iz == 1 && dZ > 0) || (iz == 2 && dZ < 0) ) { + nActivatedPads++; + nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX(); + eff[nActivatedPads-1] = effZ; + if (fEdgeEffect==1) + res[nActivatedPads-1] = 0.001 * resZ; // ns + else + res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resZ * resZ); // ns + timeWalk[nActivatedPads-1] = 0.001 * timeWalkZ; // ns + nTail[nActivatedPads-1] = 2; + if (fTimeDelayFlag) { + // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * z / 2.); + // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * z / 2.); + qInduced[nActivatedPads-1] = TMath::Exp(-fPulseHeightSlope * z); + logOfqInd = gRandom->Gaus(-fPulseHeightSlope * z, fLogChargeSmearing); + timeDelay[nActivatedPads-1] = gRandom->Gaus(-fTimeDelaySlope * logOfqInd, fTimeSmearing); + } else { + timeDelay[nActivatedPads-1] = 0.; + } + padId[nActivatedPads-1] = 2; + } + } + + + ////// Pad C, D, E, F: + if(x < k2) { + effX = fEffBoundary - (fEffBoundary - fEff3Boundary) * (x / k2); + } else { + effX = fEff3Boundary * (k - x) / (k - k2); + } + if (fEdgeEffect==1) + resX = fTimeResolution; + else if (fEdgeEffect==2) + resX = fResBoundary + fResSlope*x/k; + timeWalkX = fTimeWalkBoundary + fTimeWalkSlope*x/k; + + if(x < k && x > 0) { + // C: + if(ix > 1 && dX < 0) { + nActivatedPads++; + nPlace[nActivatedPads-1] = nPlace[0] - 1; + eff[nActivatedPads-1] = effX; + if (fEdgeEffect==1) + res[nActivatedPads-1] = 0.001 * resX; // ns + else if (fEdgeEffect==2) + res[nActivatedPads-1] = 0.001 * TMath::Sqrt(fAddTRes*fAddTRes + resX * resX); // ns + timeWalk[nActivatedPads-1] = 0.001 * timeWalkX; // ns + nTail[nActivatedPads-1] = 2; if (fTimeDelayFlag) { // qInduced[0] = fMinimumCharge * TMath::Exp(fPulseHeightSlope * x / 2.); // qInduced[nActivatedPads-1] = fMinimumCharge * TMath::Exp(-fPulseHeightSlope * x / 2.); @@ -800,7 +1334,10 @@ void AliTOFSDigitizer::SimulateDetectorResponse(Float_t z0, Float_t x0, Float_t nActivatedPads++; nPlace[nActivatedPads-1] = nPlace[0] + (3 - 2 * iz) * AliTOFGeometry::NpadX() - 1; eff[nActivatedPads-1] = effX * effZ; - (resZRndm() < eff[iPad]) { isFired[iPad] = kTRUE; nFiredPads++; @@ -891,6 +1434,7 @@ void AliTOFSDigitizer::SimulateDetectorResponse(Float_t z0, Float_t x0, Float_t tofTime[iPad] = geantTime + timeWalk[iPad] + timeDelay[iPad] + timeAB; } } else { + AliDebug(1,Form(" ----------------- TOF time resolution = %f",res[iPad])); tofTime[iPad] = gRandom->Gaus(geantTime + timeWalk[iPad] + timeDelay[iPad], res[iPad]); } if (fAverageTimeFlag) { @@ -918,29 +1462,29 @@ void AliTOFSDigitizer::PrintParameters()const AliInfo(Form(" Number of events: %i ", (fEvent2-fEvent1))); AliInfo(Form(" from event %i to event %i", fEvent1, (fEvent2-1))); - AliInfo(Form(" Time Resolution (ns) %d Pad Efficiency: %d ", fTimeResolution, fpadefficiency)); + AliInfo(Form(" Time Resolution (ps) %f Pad Efficiency: %f ", fTimeResolution, fpadefficiency)); AliInfo(Form(" Edge Effect option: %d", fEdgeEffect)); AliInfo(" Boundary Effect Simulation Parameters "); - AliInfo(Form(" Hparameter: %d H2parameter: %d Kparameter: %d K2parameter: %d", fHparameter, fH2parameter, fKparameter, fK2parameter)); - AliInfo(Form(" Efficiency in the central region of the pad: %d", fEffCenter)); - AliInfo(Form(" Efficiency at the boundary region of the pad: %d", fEffBoundary)); - AliInfo(Form(" Efficiency value at H2parameter %d", fEff2Boundary)); - AliInfo(Form(" Efficiency value at K2parameter %d", fEff3Boundary)); - AliInfo(Form(" Resolution (ps) in the central region of the pad: %d", fResCenter)); - AliInfo(Form(" Resolution (ps) at the boundary of the pad : %d", fResBoundary)); - AliInfo(Form(" Slope (ps/K) for neighbouring pad : %d", fResSlope)); - AliInfo(Form(" Time walk (ps) in the central region of the pad : %d", fTimeWalkCenter)); - AliInfo(Form(" Time walk (ps) at the boundary of the pad : %d", fTimeWalkBoundary)); - AliInfo(Form(" Slope (ps/K) for neighbouring pad : %d", fTimeWalkSlope)); + AliInfo(Form(" Hparameter: %f H2parameter: %f Kparameter: %f K2parameter: %f", fHparameter, fH2parameter, fKparameter, fK2parameter)); + AliInfo(Form(" Efficiency in the central region of the pad: %f", fEffCenter)); + AliInfo(Form(" Efficiency at the boundary region of the pad: %f", fEffBoundary)); + AliInfo(Form(" Efficiency value at H2parameter %f", fEff2Boundary)); + AliInfo(Form(" Efficiency value at K2parameter %f", fEff3Boundary)); + AliInfo(Form(" Resolution (ps) in the central region of the pad: %f", fResCenter)); + AliInfo(Form(" Resolution (ps) at the boundary of the pad : %f", fResBoundary)); + AliInfo(Form(" Slope (ps/K) for neighbouring pad : %f", fResSlope)); + AliInfo(Form(" Time walk (ps) in the central region of the pad : %f", fTimeWalkCenter)); + AliInfo(Form(" Time walk (ps) at the boundary of the pad : %f", fTimeWalkBoundary)); + AliInfo(Form(" Slope (ps/K) for neighbouring pad : %f", fTimeWalkSlope)); AliInfo(" Pulse Heigth Simulation Parameters "); AliInfo(Form(" Flag for delay due to the PulseHeightEffect : %d", fTimeDelayFlag)); - AliInfo(Form(" Pulse Height Slope : %d", fPulseHeightSlope)); - AliInfo(Form(" Time Delay Slope : %d", fTimeDelaySlope)); - AliInfo(Form(" Minimum charge amount which could be induced : %d", fMinimumCharge)); - AliInfo(Form(" Smearing in charge in (q1/q2) vs x plot : %d", fChargeSmearing)); - AliInfo(Form(" Smearing in log of charge ratio : %d", fLogChargeSmearing)); - AliInfo(Form(" Smearing in time in time vs log(q1/q2) plot : %d", fTimeSmearing)); + AliInfo(Form(" Pulse Height Slope : %f", fPulseHeightSlope)); + AliInfo(Form(" Time Delay Slope : %f", fTimeDelaySlope)); + AliInfo(Form(" Minimum charge amount which could be induced : %f", fMinimumCharge)); + AliInfo(Form(" Smearing in charge in (q1/q2) vs x plot : %f", fChargeSmearing)); + AliInfo(Form(" Smearing in log of charge ratio : %f", fLogChargeSmearing)); + AliInfo(Form(" Smearing in time in time vs log(q1/q2) plot : %f", fTimeSmearing)); AliInfo(Form(" Flag for average time : %d", fAverageTimeFlag)); AliInfo(Form(" Edge tails option : %d", fEdgeTails));