X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=PHOS%2FAliPHOSDigitizer.cxx;h=8b8acf535a5495b89e569ed9cda97cb197ba0d0f;hb=b5279783a101714eeead7bba07fe66269b3f28f4;hp=b12a8f2d8ecfd9c33f6a788d837f2b2cd1a546e0;hpb=bca3b32a854748ceacb47480928a751b6d98f81b;p=u%2Fmrichter%2FAliRoot.git diff --git a/PHOS/AliPHOSDigitizer.cxx b/PHOS/AliPHOSDigitizer.cxx index b12a8f2d8ec..8b8acf535a5 100644 --- a/PHOS/AliPHOSDigitizer.cxx +++ b/PHOS/AliPHOSDigitizer.cxx @@ -15,21 +15,26 @@ /* $Id$ */ + //_________________________________________________________________________ //*-- Author : Dmitri Peressounko (SUBATECH & Kurchatov Institute) ////////////////////////////////////////////////////////////////////////////// -// Class performs digitization of Summable digits (in the PHOS case this is just -// sum of contributions of all primary particles into given cell). +// This TTask performs digitization of Summable digits (in the PHOS case it is just +// the sum of contributions from all primary particles into a given cell). // In addition it performs mixing of summable digits from different events. +// The name of the TTask is also the title of the branch that will contain +// the created SDigits +// The title of the TTAsk is the name of the file that contains the hits from +// which the SDigits are created // // For each event two branches are created in TreeD: // "PHOS" - list of digits // "AliPHOSDigitizer" - AliPHOSDigitizer with all parameters used in digitization // -// Note, that one cset title for new digits branch, and repeat digitization with +// Note, that one can set a title for new digits branch, and repeat digitization with // another set of parameters. // -// Examples of use: +// Use case: // root[0] AliPHOSDigitizer * d = new AliPHOSDigitizer() ; // root[1] d->ExecuteTask() // Warning in : object already instantiated @@ -39,9 +44,9 @@ // // Will read sdigits from galice1.root // root[3] d1->MixWith("galice2.root") // Warning in : object already instantiated -// // Reads another portion of sdigits from galice2.root +// // Reads another set of sdigits from galice2.root // root[3] d1->MixWith("galice3.root") -// // Reads another portion of sdigits from galice3.root +// // Reads another set of sdigits from galice3.root // root[4] d->ExecuteTask("deb timing") // // Reads SDigits from files galice1.root, galice2.root .... // // mixes them and stores produced Digits in file galice1.root @@ -51,666 +56,672 @@ // // --- ROOT system --- -#include "TFile.h" #include "TTree.h" #include "TSystem.h" -#include "TROOT.h" -#include "TFolder.h" -#include "TObjString.h" #include "TBenchmark.h" +#include "TRandom.h" + // --- Standard library --- -#include // --- AliRoot header files --- -#include "AliRun.h" +#include "AliRunDigitizer.h" #include "AliPHOSDigit.h" -#include "AliPHOSHit.h" -#include "AliPHOSv1.h" +#include "AliPHOSGetter.h" #include "AliPHOSDigitizer.h" #include "AliPHOSSDigitizer.h" #include "AliPHOSGeometry.h" +#include "AliPHOSTick.h" ClassImp(AliPHOSDigitizer) //____________________________________________________________________________ - AliPHOSDigitizer::AliPHOSDigitizer():TTask("AliPHOSDigitizer","") + AliPHOSDigitizer::AliPHOSDigitizer():AliDigitizer("",""), + fInput(0), + fInputFileNames(0x0), + fEventNames(0x0) { // ctor - - fSDigitizer = 0 ; - fNinputs = 1 ; - fPinNoise = 0.01 ; - fEMCDigitThreshold = 0.01 ; - fCPVNoise = 0.01; - fCPVDigitThreshold = 0.09 ; - fPPSDNoise = 0.0000001; - fPPSDDigitThreshold = 0.0000002 ; - fInitialized = kFALSE ; - - fHeaderFiles = 0; - fSDigitsTitles = 0; - fSDigits = 0 ; - fDigits = 0; - + InitParameters() ; + fDefaultInit = kTRUE ; + fManager = 0 ; // We work in the standalong mode + fEventFolderName = "" ; } -//____________________________________________________________________________ -void AliPHOSDigitizer::Init(){ -// Makes all memory allocations - if(!fInitialized){ - - cout << "In Init" << endl ; +//____________________________________________________________________________ +AliPHOSDigitizer::AliPHOSDigitizer(const TString alirunFileName, const TString eventFolderName): + AliDigitizer("PHOS"+AliConfig::fgkDigitizerTaskName, alirunFileName), + fInputFileNames(0), fEventNames(0), fEventFolderName(eventFolderName) +{ + // ctor - fHeaderFiles = new TClonesArray("TObjString",1) ; - new((*fHeaderFiles)[0]) TObjString("galice.root") ; - - //Test, if this file already open - - TFile *file = (TFile*) gROOT->GetFile(((TObjString *) fHeaderFiles->At(0))->GetString() ) ; - - if(file == 0){ - file = new TFile(((TObjString *) fHeaderFiles->At(0))->GetString(),"update") ; - gAlice = (AliRun *) file->Get("gAlice") ; - } - else - file = new TFile(((TObjString *) fHeaderFiles->At(0))->GetString()) ; - - file->cd() ; - - fSDigitsTitles = new TClonesArray("TObjString",1); - new((*fSDigitsTitles)[0]) TObjString("") ; - - fSDigits = new TClonesArray("TClonesArray",1) ; - new((*fSDigits)[0]) TClonesArray("AliPHOSDigit",1000) ; + InitParameters() ; + Init() ; + fDefaultInit = kFALSE ; + fManager = 0 ; // We work in the standalong mode +} - fSDigitizer = 0 ; - - fDigitsTitle = "" ; - - fDigits = new TClonesArray("AliPHOSDigit",200000) ; - - fIevent = new TArrayI(1) ; - fIevent->AddAt(-1,0 ) ; - fIeventMax = new TArrayI(1) ; - - fIeventMax->AddAt((Int_t) gAlice->TreeE()->GetEntries(), 0 ); - - // add Task to //root/Tasks folder - TTask * roottasks = (TTask*)gROOT->GetRootFolder()->FindObject("Tasks") ; - roottasks->Add(this) ; - - fInitialized = kTRUE ; - } - +//____________________________________________________________________________ +AliPHOSDigitizer::AliPHOSDigitizer(const AliPHOSDigitizer & d) + : AliDigitizer(d) +{ + // copyy ctor + + SetName(d.GetName()) ; + SetTitle(d.GetTitle()) ; + fPinNoise = d.fPinNoise ; + fEMCDigitThreshold = d.fEMCDigitThreshold ; + fCPVNoise = d.fCPVNoise ; + fCPVDigitThreshold = d.fCPVDigitThreshold ; + fTimeResolution = d.fTimeResolution ; + fTimeThreshold = d.fTimeThreshold ; + fTimeSignalLength = d.fTimeSignalLength ; + fADCchanelEmc = d.fADCchanelEmc ; + fADCpedestalEmc = d.fADCpedestalEmc ; + fNADCemc = d.fNADCemc ; + fADCchanelCpv = d.fADCchanelCpv ; + fADCpedestalCpv = d.fADCpedestalCpv ; + fNADCcpv = d.fNADCcpv ; + fEventFolderName = d.fEventFolderName; } //____________________________________________________________________________ -AliPHOSDigitizer::AliPHOSDigitizer(const char *HeaderFile,const char *sDigitsTitle): - TTask("AliPHOSDigitizer","") +AliPHOSDigitizer::AliPHOSDigitizer(AliRunDigitizer * rd): + AliDigitizer(rd,"PHOS"+AliConfig::fgkDigitizerTaskName), + fEventFolderName(0) { // ctor - fHeaderFiles = new TClonesArray("TObjString",1) ; - new((*fHeaderFiles)[0]) TObjString(HeaderFile) ; - - // Header file, where result will be stored - TFile * file = (TFile*) gROOT->GetFile(((TObjString *) fHeaderFiles->At(0))->GetString() ) ; - if(file==0){ - file = new TFile(((TObjString *) fHeaderFiles->At(0))->GetString(),"update") ; - gAlice = (AliRun *) file->Get("gAlice") ; //If not read yet - } - - file->cd() ; - - fSDigitsTitles = new TClonesArray("TObjString",1); // Title name of the SDigits branch - new((*fSDigitsTitles)[0]) TObjString(sDigitsTitle) ; - - fSDigits = new TClonesArray("TClonesArray",1) ; // here list of SDigits wil be stored - new((*fSDigits)[0]) TClonesArray("AliPHOSDigit",1000) ; - - fDigits = new TClonesArray("AliPHOSDigit",200000) ; - - fDigitsTitle = "" ; - - - fSDigitizer = 0 ; - - fIevent = new TArrayI(1) ; - fIevent->AddAt(-1,0 ) ; - fIeventMax = new TArrayI(1) ; - - // Get number of events to process - fIeventMax->AddAt((Int_t) gAlice->TreeE()->GetEntries(), 0 ); - - fNinputs = 1 ; - - fPinNoise = 0.01 ; - fEMCDigitThreshold = 0.01 ; - fCPVNoise = 0.01; - fCPVDigitThreshold = 0.09 ; - fPPSDNoise = 0.0000001; - fPPSDDigitThreshold = 0.0000002 ; - - // add Task to //root/Tasks folder - TTask * roottasks = (TTask*)gROOT->GetRootFolder()->FindObject("Tasks") ; - roottasks->Add(this) ; - fInitialized = kTRUE ; - + fManager = rd ; + SetName(fManager->GetInputFolderName(0)) ; + // take title as name of stream 0 + SetTitle(dynamic_cast(fManager->GetInputStream(0))->GetFileName(0)); + InitParameters() ; + Init() ; + fDefaultInit = kFALSE ; } //____________________________________________________________________________ AliPHOSDigitizer::~AliPHOSDigitizer() { // dtor - - if(fHeaderFiles) delete fHeaderFiles ; - if(fSDigitsTitles) delete fSDigitsTitles ; - if(fSDigits) delete fSDigits ; - if(fDigits) delete fDigits ; + delete [] fInputFileNames ; + delete [] fEventNames ; + } -//____________________________________________________________________________ -void AliPHOSDigitizer::Reset() { - //sets current event number to the first simulated event - if(!fInitialized) - Init() ; - - Int_t inputs ; - for(inputs = 0; inputs < fNinputs ;inputs++) - fIevent->AddAt(-1, inputs ) ; - -} //____________________________________________________________________________ -Bool_t AliPHOSDigitizer::Combinator() { - - //Makes all desirable combinations Signal+Background, - // returns kFALSE when all combinations are made - // May be useful to introduce some options like "One-to-One", "All-to-One" and "All-to-All" ? - - //realizing "One-to-One" option... - - if(!fInitialized) - Init() ; - - Int_t inputs ; - Bool_t endNotReached = kTRUE ; - - for(inputs = 0; (inputs < fNinputs) && endNotReached ;inputs++){ - if(fIevent->At(inputs)+1 < fIeventMax->At(inputs)) - fIevent->AddAt(fIevent->At(inputs)+1, inputs ) ; - else - if(inputs == 0) - endNotReached = kFALSE ; - else //for inputs other than base one start from the beginning - fIevent->AddAt(0, inputs ) ; - - } - return endNotReached ; +void AliPHOSDigitizer::Digitize(const Int_t event) +{ -} - -//____________________________________________________________________________ -void AliPHOSDigitizer::Digitize(Option_t *option) { - - // Makes the digitization of the collected summable digits - // for this it first creates the array of all PHOS modules - // filled with noise (different for EMC, CPV and PPSD) and - // after that adds contributions from SDigits. This design - // helps to avoid scanning over the list of digits to add - // contribution of any new SDigit. - - if(!fInitialized) - Init() ; + // Makes the digitization of the collected summable digits. + // It first creates the array of all PHOS modules + // filled with noise (different for EMC, CPV and PPSD) and + // then adds contributions from SDigits. + // This design avoids scanning over the list of digits to add + // contribution to new SDigits only. - fDigits->Clear() ; - - AliPHOS * PHOS = (AliPHOS *) gAlice->GetDetector("PHOS") ; - AliPHOSGeometry *geom = AliPHOSGeometry::GetInstance( PHOS->GetGeometry()->GetName(), PHOS->GetGeometry()->GetTitle() ); + AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; + TClonesArray * digits = gime->Digits() ; + digits->Clear() ; + const AliPHOSGeometry *geom = gime->PHOSGeometry() ; //Making digits with noise, first EMC Int_t nEMC = geom->GetNModules()*geom->GetNPhi()*geom->GetNZ(); Int_t nCPV ; - Int_t nPPSD ; Int_t absID ; - TString name = geom->GetName() ; - if ( name == "IHEP" || name == "MIXT" ) - nCPV =nEMC + geom->GetNumberOfCPVPadsZ()*geom->GetNumberOfCPVPadsPhi()* - geom->GetNCPVModules()*geom->GetNumberOfCPVLayers() ; - else - nCPV = nEMC; + nCPV = nEMC + geom->GetNumberOfCPVPadsZ() * geom->GetNumberOfCPVPadsPhi() * geom->GetNModules() ; - if ( name == "GPS2" || name == "MIXT" ) - nPPSD =nCPV+2*geom->GetNPPSDModules()*geom->GetNumberOfModulesPhi()*geom->GetNumberOfModulesZ()* - geom->GetNumberOfPadsPhi()*geom->GetNumberOfPadsZ() ; - else - nPPSD = nCPV; + digits->Expand(nCPV) ; + // get first the sdigitizer from the tasks list + if ( !gime->SDigitizer() ) + gime->LoadSDigitizer(); + AliPHOSSDigitizer * sDigitizer = gime->SDigitizer(); - fDigits->Expand(nPPSD) ; + if ( !sDigitizer ) + Fatal("Digitize", "SDigitizer with name %s %s not found", fEventFolderName.Data(), GetTitle() ) ; + //take all the inputs to add together and load the SDigits + TObjArray * sdigArray = new TObjArray(fInput) ; + sdigArray->AddAt(gime->SDigits(), 0) ; + Int_t i ; + for(i = 1 ; i < fInput ; i++){ + TString tempo(fEventNames[i]) ; + tempo += i ; + AliPHOSGetter * gime = AliPHOSGetter::Instance(fInputFileNames[i], tempo) ; + gime->Event(event,"S"); + sdigArray->AddAt(gime->SDigits(), i) ; + } + + //Find the first crystall with signal + Int_t nextSig = 200000 ; + TClonesArray * sdigits ; + for(i = 0 ; i < fInput ; i++){ + sdigits = dynamic_cast(sdigArray->At(i)) ; + if ( !sdigits->GetEntriesFast() ) + continue ; + Int_t curNext = dynamic_cast(sdigits->At(0))->GetId() ; + if(curNext < nextSig) + nextSig = curNext ; + } + + TArrayI index(fInput) ; + index.Reset() ; //Set all indexes to zero - for(absID = 1; absID <= nEMC; absID++){ + AliPHOSDigit * digit ; + AliPHOSDigit * curSDigit ; + + TClonesArray * ticks = new TClonesArray("AliPHOSTick",1000) ; + + //Put Noise contribution + for(absID = 1 ; absID <= nEMC ; absID++){ Float_t noise = gRandom->Gaus(0., fPinNoise) ; - new((*fDigits)[absID-1]) AliPHOSDigit( -1,absID,fSDigitizer->Digitize(noise) ) ; + new((*digits)[absID-1]) AliPHOSDigit( -1, absID, sDigitizer->Digitize(noise), TimeOfNoise() ) ; + //look if we have to add signal? + digit = dynamic_cast(digits->At(absID-1)) ; + + if(absID==nextSig){ + //Add SDigits from all inputs + ticks->Clear() ; + Int_t contrib = 0 ; + Float_t a = digit->GetAmp() ; + Float_t b = TMath::Abs( a / fTimeSignalLength) ; + //Mark the beginning of the signal + new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime(),0, b); + //Mark the end of the ignal + new((*ticks)[contrib++]) AliPHOSTick(digit->GetTime()+fTimeSignalLength, -a, -b); + + //loop over inputs + for(i = 0 ; i < fInput ; i++){ + if( dynamic_cast(sdigArray->At(i))->GetEntriesFast() > index[i] ) + curSDigit = dynamic_cast(dynamic_cast(sdigArray->At(i))->At(index[i])) ; + else + curSDigit = 0 ; + //May be several digits will contribute from the same input + while(curSDigit && curSDigit->GetId() == absID){ + //Shift primary to separate primaries belonging different inputs + Int_t primaryoffset ; + if(fManager) + primaryoffset = fManager->GetMask(i) ; + else + primaryoffset = 10000000*i ; + curSDigit->ShiftPrimary(primaryoffset) ; + + a = curSDigit->GetAmp() ; + b = a /fTimeSignalLength ; + new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime(),0, b); + new((*ticks)[contrib++]) AliPHOSTick(curSDigit->GetTime()+fTimeSignalLength, -a, -b); + + *digit = *digit + *curSDigit ; //add energies + + index[i]++ ; + if( dynamic_cast(sdigArray->At(i))->GetEntriesFast() > index[i] ) + curSDigit = dynamic_cast(dynamic_cast(sdigArray->At(i))->At(index[i])) ; + else + curSDigit = 0 ; + } + } + + //calculate and set time + Float_t time = FrontEdgeTime(ticks) ; + digit->SetTime(time) ; + + //Find next signal module + nextSig = 200000 ; + for(i = 0 ; i < fInput ; i++){ + sdigits = dynamic_cast(sdigArray->At(i)) ; + Int_t curNext = nextSig ; + if(sdigits->GetEntriesFast() > index[i] ){ + curNext = dynamic_cast(sdigits->At(index[i]))->GetId() ; + } + if(curNext < nextSig) nextSig = curNext ; + } + } } + ticks->Delete() ; + delete ticks ; + + //Now CPV digits (different noise and no timing) for(absID = nEMC+1; absID <= nCPV; absID++){ Float_t noise = gRandom->Gaus(0., fCPVNoise) ; - new((*fDigits)[absID-1]) AliPHOSDigit( -1,absID,fSDigitizer->Digitize(noise) ) ; - } - - for(absID = nCPV+1; absID <= nPPSD; absID++){ - Float_t noise = gRandom->Gaus(0., fPPSDNoise) ; - new((*fDigits)[absID-1]) AliPHOSDigit( -1,absID,fSDigitizer->Digitize(noise) ) ; - } - + new((*digits)[absID-1]) AliPHOSDigit( -1,absID,sDigitizer->Digitize(noise), TimeOfNoise() ) ; + //look if we have to add signal? + if(absID==nextSig){ + digit = dynamic_cast(digits->At(absID-1)) ; + //Add SDigits from all inputs + for(i = 0 ; i < fInput ; i++){ + if( dynamic_cast(sdigArray->At(i))->GetEntriesFast() > index[i] ) + curSDigit = dynamic_cast( dynamic_cast(sdigArray->At(i))->At(index[i])) ; + else + curSDigit = 0 ; + + //May be several digits will contribute from the same input + while(curSDigit && curSDigit->GetId() == absID){ + //Shift primary to separate primaries belonging different inputs + Int_t primaryoffset ; + if(fManager) + primaryoffset = fManager->GetMask(i) ; + else + primaryoffset = 10000000*i ; + curSDigit->ShiftPrimary(primaryoffset) ; + + //add energies + *digit = *digit + *curSDigit ; + index[i]++ ; + if( dynamic_cast(sdigArray->At(i))->GetEntriesFast() > index[i] ) + curSDigit = dynamic_cast( dynamic_cast(sdigArray->At(i))->At(index[i]) ) ; + else + curSDigit = 0 ; + } + } - // Now look throught (unsorted) list of SDigits and add corresponding digits - AliPHOSDigit *curSDigit ; - AliPHOSDigit *digit ; - - Int_t inputs; - for(inputs = 0; inputs< fNinputs ; inputs++){ //loop over (possible) merge sources - - TClonesArray * sdigits= (TClonesArray *)fSDigits->At(inputs) ; - Int_t isdigit ; - - Int_t nSDigits = sdigits->GetEntries() ; - for(isdigit=0;isdigit< nSDigits; isdigit++){ - curSDigit = (AliPHOSDigit *)sdigits->At(isdigit) ; - if(inputs) //Shift primaries for non-background sdigits - curSDigit->ShiftPrimary(inputs) ; - digit = (AliPHOSDigit *)fDigits->At(curSDigit->GetId() - 1); - *digit = *digit + *curSDigit ; - } + //Find next signal module + nextSig = 200000 ; + for(i = 0 ; i < fInput ; i++){ + sdigits = dynamic_cast(sdigArray->At(i)) ; + Int_t curNext = nextSig ; + if(sdigits->GetEntriesFast() > index[i] ) + curNext = dynamic_cast( sdigits->At(index[i]) )->GetId() ; + if(curNext < nextSig) nextSig = curNext ; + } + + } } - - //remove digits below thresholds - for(absID = 0; absID < nEMC ; absID++) - if(fSDigitizer->Calibrate(((AliPHOSDigit*)fDigits->At(absID))->GetAmp()) < fEMCDigitThreshold) - fDigits->RemoveAt(absID) ; - for(absID = nEMC; absID < nCPV ; absID++) - if(fSDigitizer->Calibrate(((AliPHOSDigit*)fDigits->At(absID))->GetAmp()) < fCPVDigitThreshold) - fDigits->RemoveAt(absID) ; - for(absID = nCPV; absID < nPPSD ; absID++) - if(fSDigitizer->Calibrate(((AliPHOSDigit *)fDigits->At(absID))->GetAmp()) < fPPSDDigitThreshold) - fDigits->RemoveAt(absID) ; + delete sdigArray ; //We should not delete its contents - fDigits->Compress() ; - - Int_t ndigits = fDigits->GetEntriesFast() ; + //remove digits below thresholds + for(i = 0 ; i < nEMC ; i++){ + digit = dynamic_cast( digits->At(i) ) ; + if(sDigitizer->Calibrate( digit->GetAmp() ) < fEMCDigitThreshold) + digits->RemoveAt(i) ; + else + digit->SetTime(gRandom->Gaus(digit->GetTime(),fTimeResolution) ) ; + } - fDigits->Expand(ndigits) ; + for(i = nEMC; i < nCPV ; i++) + if( sDigitizer->Calibrate( dynamic_cast(digits->At(i))->GetAmp() ) < fCPVDigitThreshold ) + digits->RemoveAt(i) ; + + digits->Compress() ; + + Int_t ndigits = digits->GetEntriesFast() ; + digits->Expand(ndigits) ; - //Set indexes in list of digits - Int_t i ; + //Set indexes in list of digits and make true digitization of the energy for (i = 0 ; i < ndigits ; i++) { - AliPHOSDigit * digit = (AliPHOSDigit *) fDigits->At(i) ; + digit = dynamic_cast( digits->At(i) ) ; digit->SetIndexInList(i) ; + Float_t energy = sDigitizer->Calibrate(digit->GetAmp()) ; + digit->SetAmp(DigitizeEnergy(energy,digit->GetId()) ) ; } } -//____________________________________________________________________________ -void AliPHOSDigitizer::WriteDigits(){ - - // Made TreeD in the output file. Check if branch already exists: if yes, exits - // without writing: ROOT TTree does not suppert overwriting/updating of the - // already existing branches. Creates branch with Digits, named "PHOS", title "...", - // and branch "AliPHOSDigitizer", with the same title to keep all the parameters - // and names of files, from which digits are made. - gAlice->GetEvent(fIevent->At(0)) ; // Suitable only for One-To-One mixing - gAlice->SetEvent(fIevent->At(0)) ; // for all-to-all will produce a lot of branches in TreeD - - if(gAlice->TreeD()==0) - gAlice->MakeTree("D") ; +//____________________________________________________________________________ +Int_t AliPHOSDigitizer::DigitizeEnergy(Float_t energy, Int_t absId) +{ + // Returns digitized value of the energy in a cell absId - - //Check, if this branch already exits? - TBranch * digitsBranch = 0; - TBranch * digitizerBranch = 0; - - TObjArray * branches = gAlice->TreeD()->GetListOfBranches() ; - Int_t ibranch; - Bool_t phosNotFound = kTRUE ; - Bool_t digitizerNotFound = kTRUE ; - - for(ibranch = 0;ibranch GetEntries();ibranch++){ - - if(phosNotFound){ - digitsBranch=(TBranch *) branches->At(ibranch) ; - if( (strcmp("PHOS",digitsBranch->GetName())==0 ) && - (fDigitsTitle.CompareTo(digitsBranch->GetTitle()) == 0) ) - phosNotFound = kFALSE ; - } - if(digitizerNotFound){ - digitizerBranch = (TBranch *) branches->At(ibranch) ; - if( (strcmp(digitizerBranch->GetName(),"AliPHOSDigitizer") == 0) && - (fDigitsTitle.CompareTo(digitizerBranch->GetTitle()) == 0)) - digitizerNotFound = kFALSE ; - } + Int_t chanel ; + if(absId <= fEmcCrystals){ //digitize as EMC + chanel = (Int_t) TMath::Ceil((energy - fADCpedestalEmc)/fADCchanelEmc) ; + if(chanel > fNADCemc ) chanel = fNADCemc ; } - - - if(!(digitizerNotFound && phosNotFound)){ - cout << "AliPHOSDigitizer error: " << endl ; - cout << " can not update/overwrite existing branches "<< endl ; - cout << " do not write " << endl ; - return ; + else{ //Digitize as CPV + chanel = (Int_t) TMath::Ceil((energy - fADCpedestalCpv)/fADCchanelCpv) ; + if(chanel > fNADCcpv ) chanel = fNADCcpv ; } + return chanel ; +} - // create new branches +//____________________________________________________________________________ +void AliPHOSDigitizer::Exec(Option_t *option) +{ + // Does the job - //First generate file name - char * file =0; - if(gSystem->Getenv("CONFIG_SPLIT_FILE")){ //generating file name - file = new char[strlen(gAlice->GetBaseFile())+20] ; - sprintf(file,"%s/PHOS.Digits.root",gAlice->GetBaseFile()) ; + if (!fInit) { // to prevent overwrite existing file + Error( "Exec", "Give a version name different from %s", fEventFolderName.Data() ) ; + return ; + } + + if (strstr(option,"print")) { + Print(); + return ; } - TDirectory *cwd = gDirectory; + if(strstr(option,"tim")) + gBenchmark->Start("PHOSDigitizer"); - //First create list of sdigits - Int_t bufferSize = 32000 ; - digitsBranch = gAlice->TreeD()->Branch("PHOS",&fDigits,bufferSize); - digitsBranch->SetTitle(fDigitsTitle.Data()); - if (file) { - digitsBranch->SetFile(file); - TIter next( digitsBranch->GetListOfBranches()); - while ((digitsBranch=(TBranch*)next())) { - digitsBranch->SetFile(file); - } - cwd->cd(); - } - - //second - create Digitizer - Int_t splitlevel = 0 ; - AliPHOSDigitizer * d = this ; - digitizerBranch = gAlice->TreeD()->Branch("AliPHOSDigitizer","AliPHOSDigitizer", - &d,bufferSize,splitlevel); - digitizerBranch->SetTitle(fDigitsTitle.Data()); - if (file) { - digitizerBranch->SetFile(file); - TIter next( digitizerBranch->GetListOfBranches()); - while ((digitizerBranch=(TBranch*)next())) { - digitizerBranch->SetFile(file); - } - cwd->cd(); - } - - gAlice->TreeD()->Fill() ; + if (fManager) + fInput = fManager->GetNinputs() ; - gAlice->TreeD()->Write(0,kOverwrite) ; + AliPHOSGetter * gime = AliPHOSGetter::Instance() ; - //remove fSDigitizer before new event. - if(fSDigitizer){ - delete fSDigitizer ; - fSDigitizer = 0 ; - } - - -} - -//____________________________________________________________________________ -void AliPHOSDigitizer::Exec(Option_t *option) { - // Managing method + Int_t nevents = gime->MaxEvent() ; + + Int_t ievent ; - if(!fInitialized) Init() ; + for(ievent = 0; ievent < nevents; ievent++){ + + gime->Event(ievent,"S") ; - if(strstr(option,"tim")) - gBenchmark->Start("PHOSDigitizer"); + Digitize(ievent) ; //Add prepared SDigits to digits and add the noise - //reset events numbers to start from the beginnig - Reset() ; - - while(Combinator()){ - - if(!ReadSDigits()) //read sdigits event(s) evaluated by Combinator() from file(s) - return ; - - Digitize(option) ; //Add prepared SDigits to digits and add the noise WriteDigits() ; - + if(strstr(option,"deb")) PrintDigits(option); - - } - + + //increment the total number of Digits per run + fDigitsInRun += gime->Digits()->GetEntriesFast() ; + } + if(strstr(option,"tim")){ gBenchmark->Stop("PHOSDigitizer"); - cout << "AliPHOSDigitizer:" << endl ; - cout << " took " << gBenchmark->GetCpuTime("PHOSDigitizer") << " seconds for SDigitizing " - << gBenchmark->GetCpuTime("PHOSDigitizer")/(fIeventMax->At(0)) << " seconds per event " << endl ; - cout << endl ; + TString message ; + message = " took %f seconds for Digitizing %f seconds per event\n" ; + Info("Exec", message.Data(), + gBenchmark->GetCpuTime("PHOSDigitizer"), + gBenchmark->GetCpuTime("PHOSDigitizer")/nevents ); + } +} + +//____________________________________________________________________________ +Float_t AliPHOSDigitizer::FrontEdgeTime(TClonesArray * ticks) const +{ + // Returns the shortest time among all time ticks + + ticks->Sort() ; //Sort in accordance with times of ticks + TIter it(ticks) ; + AliPHOSTick * ctick = (AliPHOSTick *) it.Next() ; + Float_t time = ctick->CrossingTime(fTimeThreshold) ; + + AliPHOSTick * t ; + while((t=(AliPHOSTick*) it.Next())){ + if(t->GetTime() < time) //This tick starts before crossing + *ctick+=*t ; + else + return time ; + + time = ctick->CrossingTime(fTimeThreshold) ; } - + return time ; } -//__________________________________________________________________ -Bool_t AliPHOSDigitizer::ReadSDigits(){ -// Reads summable digits from the opened files for the particular set of events given by fIevent +//____________________________________________________________________________ +Bool_t AliPHOSDigitizer::Init() +{ + // Makes all memory allocations + fInit = kTRUE ; + AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; + if ( gime == 0 ) { + Fatal("Init" ,"Could not obtain the Getter object for file %s and event %s !", GetTitle(), fEventFolderName.Data()) ; + return kFALSE; + } + + const AliPHOSGeometry * geom = gime->PHOSGeometry() ; - if(!fInitialized) Init() ; + fEmcCrystals = geom->GetNModules() * geom->GetNCristalsInModule() ; + + TString opt("Digits") ; + if(gime->VersionExists(opt) ) { + Error( "Init", "Give a version name different from %s", fEventFolderName.Data() ) ; + fInit = kFALSE ; + } + // Post Digitizer to the white board + gime->PostDigitizer(this) ; + + if (fManager) + fInput = fManager->GetNinputs() ; + else + fInput = 1 ; + + fInputFileNames = new TString[fInput] ; + fEventNames = new TString[fInput] ; + fInputFileNames[0] = GetTitle() ; + fEventNames[0] = fEventFolderName.Data() ; + Int_t index ; + for (index = 1 ; index < fInput ; index++) { + fInputFileNames[index] = dynamic_cast(fManager->GetInputStream(index))->GetFileName(0); + TString tempo = fManager->GetInputFolderName(index) ; + fEventNames[index] = tempo.Remove(tempo.Length()-1) ; // strip of the stream number added bt fManager + } - Int_t inputs ; - for(inputs = fNinputs-1; inputs >= 0; inputs --){ + //to prevent cleaning of this object while GetEvent is called + gime->PhosLoader()->GetDigitsDataLoader()->GetBaseTaskLoader()->SetDoNotReload(kTRUE); - Int_t event = fIevent->At(inputs) ; + return fInit ; +} - TFile * file = (TFile*) gROOT->GetFile(((TObjString *) fHeaderFiles->At(inputs))->GetString() ) ; - file->cd() ; +//____________________________________________________________________________ +void AliPHOSDigitizer::InitParameters() +{ + // Set initial parameters for Digitizer - // Get SDigits Tree header from file - char treeName[20]; - sprintf(treeName,"TreeS%d",event); - TTree * treeS = (TTree*)file->Get(treeName); - - if(treeS==0){ - cout << "Error at AliPHOSDigitizer: no "<GetName() << endl ; - cout << "Do nothing " << endl ; - return kFALSE ; - } + fPinNoise = 0.004 ; + fEMCDigitThreshold = 0.012 ; + fCPVNoise = 0.01; + fCPVDigitThreshold = 0.09 ; + fTimeResolution = 0.5e-9 ; + fTimeSignalLength = 1.0e-9 ; + fDigitsInRun = 0 ; + fADCchanelEmc = 0.0015; // width of one ADC channel in GeV + fADCpedestalEmc = 0.005 ; // + fNADCemc = (Int_t) TMath::Power(2,16) ; // number of channels in EMC ADC - TBranch * sdigitsBranch = 0; - TBranch * sdigitizerBranch = 0; + fADCchanelCpv = 0.0012 ; // width of one ADC channel in CPV 'popugais' + fADCpedestalCpv = 0.012 ; // + fNADCcpv = (Int_t) TMath::Power(2,12); // number of channels in CPV ADC - TObjArray * branches = treeS->GetListOfBranches() ; - Int_t ibranch; - Bool_t phosNotFound = kTRUE ; - Bool_t sdigitizerNotFound = kTRUE ; - - for(ibranch = 0;ibranch GetEntries();ibranch++){ - - if(phosNotFound){ - sdigitsBranch=(TBranch *) branches->At(ibranch) ; - if(( strcmp("PHOS",sdigitsBranch->GetName())==0 ) && - ((TObjString*) fSDigitsTitles->At(inputs))->GetString().CompareTo(sdigitsBranch->GetTitle())== 0 ) - phosNotFound = kFALSE ; - - } - - if(sdigitizerNotFound){ - sdigitizerBranch = (TBranch *) branches->At(ibranch) ; - if(( strcmp(sdigitizerBranch->GetName(),"AliPHOSSDigitizer") == 0) && - ((TObjString*) fSDigitsTitles->At(inputs))->GetString().CompareTo(sdigitizerBranch->GetTitle())== 0 ) - sdigitizerNotFound = kFALSE ; - - } - } - - if(sdigitizerNotFound || phosNotFound){ - cout << "Can't find Branch with sdigits or SDigitizer in the file " ; - if( ((TObjString*)fSDigitsTitles->At(inputs))->GetString().IsNull() ) - cout << file->GetName() << endl ; - else - cout << ((TObjString*)fSDigitsTitles->At(inputs))->GetString().Data() << endl ; - cout << "Do nothing" <At(inputs) ; - sdigitsBranch->SetAddress(&sdigits) ; + fTimeThreshold = 0.001*10000000 ; //Means 1 MeV in terms of SDigits amplitude - AliPHOSSDigitizer *sDigitizer = new AliPHOSSDigitizer(); - sdigitizerBranch->SetAddress(&sDigitizer) ; - treeS->GetEvent(0) ; - - if(fSDigitizer == 0) - fSDigitizer = sDigitizer ; - else - if(!((*fSDigitizer)==(*sDigitizer)) ){ - cout << "AliPHOSDigitizer ERROR:" << endl ; - cout << " you are using sdigits made with different SDigitizers" << endl ; - cout << "fSD " << fSDigitizer << " SD" << sDigitizer << endl ; - fSDigitizer->Print("") ; - sDigitizer->Print("") ; - cout << "Do Nothing " << endl ; - return kFALSE ; - } - - } - fPedestal = fSDigitizer->GetPedestalParameter() ; - fSlope = fSDigitizer->GetCalibrationParameter() ; - - return kTRUE ; - } + //__________________________________________________________________ -void AliPHOSDigitizer::MixWith(char* HeaderFile, char* sDigitsTitle){ - // Alows produce digits by superimposing background and signal event. +void AliPHOSDigitizer::MixWith(const TString alirunFileName, const TString eventFolderName) +{ + // Allows to produce digits by superimposing background and signal event. // It is assumed, that headers file with SIGNAL events is opened in - // constructor, and now we set the BACKGROUND event, with which we - // will mix. Thus we avoid writing (changing) huge and expencive + // the constructor. + // Sets the BACKGROUND event, with which the SIGNAL event is to be mixed + // Thus we avoid writing (changing) huge and expensive // backgound files: all output will be writen into SIGNAL, i.e. // opened in constructor file. // - // One can open as many files to mix with as one wants. + // One can open as many files to mix with as one needs. + // However only Sdigits with the same name (i.e. constructed with the same SDigitizer) + // can be mixed. - - if(!fInitialized) + if( strcmp(fEventFolderName, "") == 0 ) Init() ; - - if(HeaderFile == 0){ - cout << "Specify at least header file to merge"<< endl ; + if(fManager){ + Warning("MixWith", "Cannot use this method with AliRunDigitizer\n" ) ; return ; } - - Int_t inputs ; - for(inputs = 0; inputs < fNinputs ; inputs++){ - if(strcmp(((TObjString *)fHeaderFiles->At(inputs))->GetString(),HeaderFile) == 0 ){ - if(sDigitsTitle == 0){ - if(((TObjString*)fSDigitsTitles->At(inputs))->GetString().CompareTo("") == 0){ - cout << "Entry already exists, do not add" << endl ; - return ; - } - } - else - if(((TObjString*)fSDigitsTitles->At(inputs))->GetString().CompareTo(sDigitsTitle)){ - cout << "Entry already exists, do not add" << endl ; - return; - } - } - } - - fHeaderFiles->Expand(fNinputs+1) ; - new((*fHeaderFiles)[fNinputs]) TObjString(HeaderFile) ; - - - TFile * file = new TFile(((TObjString *) fHeaderFiles->At(fNinputs))->GetString()) ; - - file->cd() ; - - fSDigitsTitles->Expand(fNinputs+1) ; - new((*fSDigitsTitles)[fNinputs]) TObjString(sDigitsTitle) ; - - fSDigits->Expand(fNinputs+1) ; - new((*fSDigits)[fNinputs]) TClonesArray("AliPHOSDigit",1000) ; - - fIevent->Set(fNinputs+1) ; - fIevent->AddAt(-1, fNinputs) ; - - fIeventMax->Set(fNinputs+1) ; - - TTree * te = (TTree *) file->Get("TE") ; - fIeventMax->AddAt((Int_t) te->GetEntries(), fNinputs ); - - fNinputs++ ; - + // looking for file which contains AliRun + if (gSystem->AccessPathName(alirunFileName)) {// file does not exist + Error("MixWith", "File %s does not exist!", alirunFileName.Data()) ; + return ; + } + // looking for the file which contains SDigits + AliPHOSGetter * gime = AliPHOSGetter::Instance() ; + TString fileName( gime->GetSDigitsFileName() ) ; + if ( eventFolderName != AliConfig::fgkDefaultEventFolderName) // only if not the default folder name + fileName = fileName.ReplaceAll(".root", "") + "_" + eventFolderName + ".root" ; + if ( (gSystem->AccessPathName(fileName)) ) { + Error("MixWith", "The file %s does not exist!", fileName.Data()) ; + return ; + } + // need to increase the arrays + TString tempo = fInputFileNames[fInput-1] ; + delete [] fInputFileNames ; + fInputFileNames = new TString[fInput+1] ; + fInputFileNames[fInput-1] = tempo ; + + tempo = fEventNames[fInput-1] ; + delete [] fEventNames ; + fEventNames = new TString[fInput+1] ; + fEventNames[fInput-1] = tempo ; + + fInputFileNames[fInput] = alirunFileName ; + fEventNames[fInput] = eventFolderName ; + fInput++ ; } + //__________________________________________________________________ -void AliPHOSDigitizer::Print(Option_t* option)const { - - if(fInitialized){ - - cout << "------------------- "<< GetName() << " -------------" << endl ; - cout << "Digitizing sDigits from file(s): " <At(input))->GetString() << - " Branch title:" << ((TObjString *) fSDigitsTitles->At(input))->GetString() << endl ; +void AliPHOSDigitizer::Print()const +{ + // Print Digitizer's parameters + Info("Print", "\n------------------- %s -------------", GetName() ) ; + if( strcmp(fEventFolderName.Data(), "") != 0 ){ + printf(" Writing Digits to branch with title %s\n", fEventFolderName.Data()) ; + + Int_t nStreams ; + if (fManager) + nStreams = GetNInputStreams() ; + else + nStreams = fInput ; + + Int_t index = 0 ; + for (index = 0 ; index < nStreams ; index++) { + TString tempo(fEventNames[index]) ; + tempo += index ; + AliPHOSGetter * gime = AliPHOSGetter::Instance(fInputFileNames[index], tempo) ; + TString fileName( gime->GetSDigitsFileName() ) ; + if ( fEventNames[index] != AliConfig::fgkDefaultEventFolderName) // only if not the default folder name + fileName = fileName.ReplaceAll(".root", "") + "_" + fEventNames[index] + ".root" ; + printf ("Adding SDigits from %s %s\n", fInputFileNames[index].Data(), fileName.Data()) ; } - cout << endl ; - cout << "Writing digits to " << ((TObjString *) fHeaderFiles->At(0))->GetString() << endl ; - - cout << endl ; - cout << "With following parameters: " << endl ; - cout << " Electronics noise in EMC (fPinNoise) = " << fPinNoise << endl ; - cout << " Threshold in EMC (fEMCDigitThreshold) = " << fEMCDigitThreshold << endl ; ; - cout << " Noise in CPV (fCPVNoise) = " << fCPVNoise << endl ; - cout << " Threshold in CPV (fCPVDigitThreshold) = " << fCPVDigitThreshold << endl ; - cout << " Noise in PPSD (fPPSDNoise) = " << fPPSDNoise << endl ; - cout << " Threshold in PPSD (fPPSDDigitThreshold) = " << fPPSDDigitThreshold << endl ; - cout << "---------------------------------------------------" << endl ; + AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; + printf("\nWriting digits to %s", gime->GetDigitsFileName().Data()) ; + + printf("\nWith following parameters:\n") ; + printf(" Electronics noise in EMC (fPinNoise) = %f\n", fPinNoise ) ; + printf(" Threshold in EMC (fEMCDigitThreshold) = %f\n", fEMCDigitThreshold ) ; + printf(" Noise in CPV (fCPVNoise) = %f\n", fCPVNoise ) ; + printf(" Threshold in CPV (fCPVDigitThreshold) = %f\n",fCPVDigitThreshold ) ; + printf(" ---------------------------------------------------\n") ; } else - cout << "AliPHOSDigitizer not initialized " << endl ; + Info("Print", "AliPHOSDigitizer not initialized" ) ; } + //__________________________________________________________________ -void AliPHOSDigitizer::PrintDigits(Option_t * option){ - - cout << "AliPHOSDigitiser:"<< endl ; - cout << " Number of entries in Digits list " << fDigits->GetEntriesFast() << endl ; - cout << endl ; - if(strstr(option,"all")){ - + void AliPHOSDigitizer::PrintDigits(Option_t * option) +{ + // Print a table of digits + + AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; + TClonesArray * digits = gime->Digits() ; + + Info("PrintDigits", "%d", digits->GetEntriesFast()) ; + printf("\nevent %d", gAlice->GetEvNumber()) ; + printf("\n Number of entries in Digits list %d", digits->GetEntriesFast() ) ; + + + if(strstr(option,"all")||strstr(option,"EMC")){ //loop over digits AliPHOSDigit * digit; - cout << "Digit Id " << " Amplitude " << " Index " << " Nprim " << " Primaries list " << endl; + printf("\nEMC digits (with primaries):\n") ; + printf("\n Id Amplitude Time Index Nprim: Primaries list \n") ; + Int_t maxEmc = gime->PHOSGeometry()->GetNModules()*gime->PHOSGeometry()->GetNCristalsInModule() ; Int_t index ; - for (index = 0 ; index < fDigits->GetEntries() ; index++) { - digit = (AliPHOSDigit * ) fDigits->At(index) ; - cout << setw(8) << digit->GetId() << " " << setw(3) << digit->GetAmp() << " " - << setw(6) << digit->GetIndexInList() << " " - << setw(5) << digit->GetNprimary() <<" "; - + for (index = 0 ; (index < digits->GetEntriesFast()) && + (dynamic_cast(digits->At(index))->GetId() <= maxEmc) ; index++) { + digit = (AliPHOSDigit * ) digits->At(index) ; + if(digit->GetNprimary() == 0) + continue; + printf("%6d %8d %6.5e %4d %2d :", + digit->GetId(), digit->GetAmp(), digit->GetTime(), digit->GetIndexInList(), digit->GetNprimary()) ; Int_t iprimary; - for (iprimary=0; iprimaryGetNprimary(); iprimary++) - cout << setw(5) << digit->GetPrimary(iprimary+1) << " "; - cout << endl; + for (iprimary=0; iprimaryGetNprimary(); iprimary++) { + printf("%d ",digit->GetPrimary(iprimary+1) ) ; + } + printf("\n") ; } + } + + if(strstr(option,"all")||strstr(option,"CPV")){ + //loop over CPV digits + AliPHOSDigit * digit; + printf("\nCPV digits (with primaries):\n") ; + printf("\n Id Amplitude Time Index Nprim: Primaries list \n") ; + Int_t maxEmc = gime->PHOSGeometry()->GetNModules()*gime->PHOSGeometry()->GetNCristalsInModule() ; + Int_t index ; + for (index = 0 ; index < digits->GetEntriesFast(); index++) { + digit = (AliPHOSDigit * ) digits->At(index) ; + if(digit->GetId() > maxEmc){ + printf("%6d %8d %4d %2d :", + digit->GetId(), digit->GetAmp(), digit->GetIndexInList(), digit->GetNprimary()) ; + Int_t iprimary; + for (iprimary=0; iprimaryGetNprimary(); iprimary++) { + printf("%d ",digit->GetPrimary(iprimary+1) ) ; + } + printf("\n") ; + } + } } + } -//__________________________________________________________________ -void AliPHOSDigitizer::SetSDigitsBranch(const char* title){ - // we set title (comment) of the SDigits branch in the first! header file - if(!fInitialized) Init() ; - ((TObjString*) fSDigitsTitles->At(0) )->SetString((char*)title) ; +//__________________________________________________________________ +Float_t AliPHOSDigitizer::TimeOfNoise(void) const +{ // Calculates the time signal generated by noise + //to be rewritten, now returns just big number + return 1. ; } + //__________________________________________________________________ -void AliPHOSDigitizer::SetDigitsBranch(const char* title){ - //Sets the title (comment) of the branch to which Digits branch - if(!fInitialized) Init() ; +void AliPHOSDigitizer::Unload() +{ + + Int_t i ; + for(i = 1 ; i < fInput ; i++){ + TString tempo(fEventNames[i]) ; + tempo += i ; + AliPHOSGetter * gime = AliPHOSGetter::Instance(fInputFileNames[i], tempo) ; + gime->PhosLoader()->UnloadSDigits() ; + } + + AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; + gime->PhosLoader()->UnloadDigits() ; +} + +//____________________________________________________________________________ +void AliPHOSDigitizer::WriteDigits() +{ + + // Makes TreeD in the output file. + // Check if branch already exists: + // if yes, exit without writing: ROOT TTree does not support overwriting/updating of + // already existing branches. + // else creates branch with Digits, named "PHOS", title "...", + // and branch "AliPHOSDigitizer", with the same title to keep all the parameters + // and names of files, from which digits are made. + + AliPHOSGetter * gime = AliPHOSGetter::Instance(GetTitle(), fEventFolderName) ; + const TClonesArray * digits = gime->Digits() ; + TTree * treeD = gime->TreeD(); + + // -- create Digits branch + Int_t bufferSize = 32000 ; + TBranch * digitsBranch = treeD->Branch("PHOS",&digits,bufferSize); + digitsBranch->SetTitle(fEventFolderName); + digitsBranch->Fill() ; - fDigitsTitle = title ; + gime->WriteDigits("OVERWRITE"); + gime->WriteDigitizer("OVERWRITE"); + + Unload() ; }