+ Int_t ntracks = static_cast<Int_t>(hitTree->GetEntries());
+ for (Int_t track = 0; track < ntracks; track++)
+ {
+ gAlice->ResetHits();
+ tofHitsBranch->GetEvent(track);
+
+ AliMC *mcApplication = (AliMC*)gAlice->GetMCApp();
+
+ particle = 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
+
+ Int_t previousTrack =-1;
+ Int_t previousSector=-1;
+ Int_t previousPlate =-1;
+ Int_t previousStrip =-1;
+ Int_t previousPadX =-1;
+ Int_t previousPadZ =-1;
+
+ for (Int_t hit = 0; hit < nhits; hit++) {
+ Int_t vol[5]; // location for a digit
+ Int_t digit[2]; // 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!=6 && version!=7)
+ AliTOFhit *tofHit = (AliTOFhit *) tofHitArray->UncheckedAt(hit);
+ tracknum = tofHit->GetTrack();
+ vol[0] = tofHit->GetSector();
+ vol[1] = tofHit->GetPlate();
+ vol[2] = tofHit->GetStrip();
+ vol[3] = tofHit->GetPadx();
+ vol[4] = tofHit->GetPadz();
+ dxPad = tofHit->GetDx();
+ dzPad = tofHit->GetDz();
+ geantTime = tofHit->GetTof(); // unit [s]
+ } else {
+ AliTOFhitT0 *tofHit = (AliTOFhitT0 *) tofHitArray->UncheckedAt(hit);
+ tracknum = tofHit->GetTrack();
+ vol[0] = tofHit->GetSector();
+ vol[1] = tofHit->GetPlate();
+ vol[2] = tofHit->GetStrip();
+ vol[3] = tofHit->GetPadx();
+ vol[4] = tofHit->GetPadz();
+ dxPad = tofHit->GetDx();
+ dzPad = tofHit->GetDz();
+ geantTime = tofHit->GetTof(); // unit [s]
+ }
+
+ geantTime *= 1.e+09; // conversion from [s] to [ns]
+
+ // selection case for sdigitizing only hits in a given plate of a given sector
+ if(thereIsNotASelection || (vol[0]==fSelectedSector && vol[1]==fSelectedPlate)){
+
+ Bool_t dummy=((tracknum==previousTrack) && (vol[0]==previousSector) && (vol[1]==previousPlate) && (vol[2]==previousStrip));
+
+ Bool_t isCloneOfThePrevious=dummy && ((vol[3]==previousPadX) && (vol[4]==previousPadZ));
+
+ Bool_t isNeighOfThePrevious=dummy && ((((vol[3]==previousPadX-1) || (vol[3]==previousPadX+1)) && (vol[4]==previousPadZ)) || ((vol[3]==previousPadX) && ((vol[4]==previousPadZ+1) || (vol[4]==previousPadZ-1))));
+
+ if(!isCloneOfThePrevious && !isNeighOfThePrevious){
+ // update "previous" values
+ // in fact, we are yet in the future, so the present is past
+ previousTrack=tracknum;
+ previousSector=vol[0];
+ previousPlate=vol[1];
+ previousStrip=vol[2];
+ previousPadX=vol[3];
+ previousPadZ=vol[4];
+
+ nselectedHits++;
+ nselectedHitsinEv++;
+ if (particle->GetFirstMother() < 0) nHitsFromPrim++; // counts hits due to primary particles
+
+ Float_t xStrip=AliTOFGeometry::XPad()*(vol[3]+0.5-0.5*AliTOFGeometry::NpadX())+dxPad;
+ Float_t zStrip=AliTOFGeometry::ZPad()*(vol[4]+0.5-0.5*AliTOFGeometry::NpadZ())+dzPad;
+
+ Int_t nActivatedPads = 0, nFiredPads = 0;
+ Bool_t isFired[4] = {kFALSE, kFALSE, kFALSE, kFALSE};
+ Float_t tofAfterSimul[4] = {0., 0., 0., 0.};
+ Float_t qInduced[4] = {0.,0.,0.,0.};
+ Int_t nPlace[4] = {0, 0, 0, 0};
+ Float_t averageTime = 0.;
+ SimulateDetectorResponse(zStrip,xStrip,geantTime,nActivatedPads,nFiredPads,isFired,nPlace,qInduced,tofAfterSimul,averageTime);
+ if(nFiredPads) {
+ for(Int_t indexOfPad=0; indexOfPad<nActivatedPads; indexOfPad++) {
+ if(isFired[indexOfPad]){ // the pad has fired
+ Float_t timediff=geantTime-tofAfterSimul[indexOfPad];
+
+ if(timediff>=0.2) nlargeTofDiff++;
+
+ digit[0] = (Int_t) ((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)
+
+ // recalculate the volume only for neighbouring pads
+ if(indexOfPad){
+ (nPlace[indexOfPad]<=AliTOFGeometry::NpadX()) ? vol[4] = 0 : vol[4] = 1;
+ (nPlace[indexOfPad]<=AliTOFGeometry::NpadX()) ? vol[3] = nPlace[indexOfPad] - 1 : vol[3] = nPlace[indexOfPad] - AliTOFGeometry::NpadX() - 1;
+ }
+ // check if two sdigit are on the same pad;
+ // in that case we sum the two or more sdigits
+ if (hitMap->TestHit(vol) != kEmpty) {
+ AliTOFSDigit *sdig = static_cast<AliTOFSDigit*>(hitMap->GetHit(vol));
+ Int_t tdctime = (Int_t) digit[0];
+ Int_t adccharge = (Int_t) digit[1];
+ sdig->Update(AliTOFGeometry::TdcBinWidth(),tdctime,adccharge,tracknum);
+ ntotalupdatesinEv++;
+ ntotalupdates++;
+ } else {
+
+ tof->AddSDigit(tracknum, vol, digit);
+
+ if(indexOfPad){
+ nnoisesdigits++;
+ nnoisesdigitsinEv++;
+ } else {
+ nsignalsdigits++;
+ nsignalsdigitsinEv++;
+ }
+ ntotalsdigitsinEv++;
+ ntotalsdigits++;
+ hitMap->SetHit(vol);
+ } // if (hitMap->TestHit(vol) != kEmpty)
+ } // if(isFired[indexOfPad])
+ } // end loop on nActivatedPads
+ } // if(nFiredPads) i.e. if some pads has fired
+ } // close if(!isCloneOfThePrevious)
+ } // close the selection on sector and plate
+ } // end loop on hits for the current track
+ } // end loop on ntracks
+
+ delete hitMap;
+
+ fTOFLoader->TreeS()->Reset();
+ fTOFLoader->TreeS()->Fill();
+ fTOFLoader->WriteSDigits("OVERWRITE");
+
+ if (tof->SDigits()) tof->ResetSDigits();
+
+ if (strstr(verboseOption,"all")) {
+ AliInfo("----------------------------------------");
+ AliInfo(" <AliTOFSDigitizer> ");
+ AliInfo(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("----------------------------------------");
+ }
+
+ } //event loop on events
+
+ fTOFLoader->UnloadSDigits();
+ fTOFLoader->UnloadHits();
+ fRunLoader->UnloadKinematics();
+ //fRunLoader->UnloadgAlice();
+
+ // free used memory
+ if (ftail){
+ delete ftail;
+ ftail = 0;
+ }
+
+ nHitsFromSec=nselectedHits-nHitsFromPrim;
+ if(strstr(verboseOption,"all")){
+ AliInfo("----------------------------------------");
+ AliInfo("----------------------------------------");
+ AliInfo("-----------SDigitization Summary--------");
+ AliInfo(" <AliTOFSDigitizer> ");
+ 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,"tim") || strstr(verboseOption,"all")){
+ gBenchmark->Stop("TOFSDigitizer");
+ AliInfo("AliTOFSDigitizer:");
+ AliInfo(Form(" took %f seconds in order to make sdigits "
+ "%f seconds per event", gBenchmark->GetCpuTime("TOFSDigitizer"), gBenchmark->GetCpuTime("TOFSDigitizer")/(fEvent2-fEvent1)));
+ AliInfo(" +++++++++++++++++++++++++++++++++++++++++++++++++++ ");
+ }