X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=VZERO%2FAliVZERO.cxx;h=0e69e9dbb072bd359d798c3433256ad93f476b03;hb=1dc767cff5d8138ee4eb310fbe0368a724ae1b78;hp=dfe9d589397579c2ea40d88c50b27cf09a447e51;hpb=832f19227bb76ad4445ca1fc8ece502b8d7e1272;p=u%2Fmrichter%2FAliRoot.git diff --git a/VZERO/AliVZERO.cxx b/VZERO/AliVZERO.cxx index dfe9d589397..0e69e9dbb07 100755 --- a/VZERO/AliVZERO.cxx +++ b/VZERO/AliVZERO.cxx @@ -13,137 +13,585 @@ * provided "as is" without express or implied warranty. * **************************************************************************/ - +/* $Id$ */ /////////////////////////////////////////////////////////////////////////// // // // V-Zero Detector // // This class contains the base procedures for the VZERO detector // +// Default geometry of November 2003 : V0R box is 4.4 cm thick // +// scintillators are 2 cm thick // // All comments should be sent to Brigitte CHEYNIS : // // b.cheynis@ipnl.in2p3.fr // // // // // /////////////////////////////////////////////////////////////////////////// + +// --- Standard libraries --- #include -#include +#include -#include "TMath.h" -#include "TTUBE.h" -#include "TNode.h" -#include "TGeometry.h" +// --- ROOT libraries --- +#include +#include "TROOT.h" +#include "TFile.h" +#include "TNetFile.h" +#include "TRandom.h" +#include "TTree.h" +#include "TBranch.h" +#include "TClonesArray.h" +#include "TStopwatch.h" +#include "TParameter.h" +#include "TF1.h" + +// --- AliRoot header files --- #include "AliRun.h" +#include "AliMC.h" #include "AliVZERO.h" +#include "AliVZEROLoader.h" +#include "AliVZERODigitizer.h" +#include "AliVZEROBuffer.h" +#include "AliDigitizationInput.h" #include "AliVZEROdigit.h" -#include "AliVZEROhit.h" +#include "AliVZEROSDigit.h" +#include "AliDAQ.h" +#include "AliRawReader.h" +#include "AliCDBManager.h" +#include "AliCDBEntry.h" +#include "AliVZERORawStream.h" +#include "AliVZEROCalibData.h" +#include "AliVZERORecoParam.h" +#include "AliVZEROReconstructor.h" ClassImp(AliVZERO) - + //__________________________________________________________________ +AliVZERO::AliVZERO(): AliDetector(), + fIdSens1(0), + fThickness(0.), + fThickness1(0.), + fMaxStepQua(0.), + fMaxStepAlu(0.), + fMaxDestepQua(0.), + fMaxDestepAlu(0.), + fCalibData(NULL), + fTimeSlewing(NULL), + fSignalShape(NULL), + fRecoParam(NULL) +{ +/// Default Constructor + + AliDebug(1,Form("default (empty) ctor this=%p",this)); + fIshunt = 0; + + for(Int_t i = 0 ; i < 64; ++i) { + fNBins[i] = 0; + fBinSize[i] = 0; + } +} //_____________________________________________________________________________ AliVZERO::AliVZERO(const char *name, const char *title) - : AliDetector(name,title) + : AliDetector(name,title), + fIdSens1(0), + fThickness(4.4), + fThickness1(2.0), + fMaxStepQua(0.05), + fMaxStepAlu(0.01), + fMaxDestepQua(-1.0), + fMaxDestepAlu(-1.0), + fCalibData(NULL), + fTimeSlewing(NULL), + fSignalShape(NULL), + fRecoParam(NULL) { - // + // Standard constructor for VZERO Detector - // - fIshunt = 1; // All hits are associated with primary particles + AliDebug(1,Form("ctor this=%p",this)); + + // fIshunt = 1; // All hits are associated with primary particles fHits = new TClonesArray("AliVZEROhit", 400); fDigits = new TClonesArray("AliVZEROdigit",400); - gAlice->AddHitList(fHits); + gAlice->GetMCApp()->AddHitList(fHits); -// fDigits = new TClonesArray("AliVZEROdigit",400) ; - - fThickness = 3.1; // total thickness of the V0R box - fThickness1 = 1.0; // thickness of the thickest cell (2.5 in version 0) - - fMaxStepQua = 0.05; - fMaxStepAlu = 0.01; +// fThickness = 4.4; // total thickness of the V0R box in cm +// fThickness1 = 2.0; // thickness of scintillating cells in cm +// +// fMaxStepQua = 0.05; +// fMaxStepAlu = 0.01; +// +// fMaxDestepQua = -1.0; +// fMaxDestepAlu = -1.0; - fMaxDestepQua = -1.0; - fMaxDestepAlu = -1.0; - - SetMarkerColor(kRed); + for(Int_t i = 0 ; i < 64; ++i) { + fNBins[i] = 0; + fBinSize[i] = 0; + } } //_____________________________________________________________________________ AliVZERO::~AliVZERO() { + // + // Default destructor for VZERO Detector + // + if (fHits) { fHits->Delete(); delete fHits; + fHits=0; } + + if (fDigits) { + fDigits->Delete(); + delete fDigits; + fDigits=0; } + if (fSignalShape) { + delete fSignalShape; + fSignalShape = NULL; + } + if (fRecoParam) { + delete fRecoParam; + fRecoParam = NULL; } } //_____________________________________________________________________________ -void AliVZERO::BuildGeometry() +void AliVZERO::CreateGeometry() { // - // Build simple ROOT TNode geometry for event display + // Builds simple Geant3 geometry // } - //_____________________________________________________________________________ -void AliVZERO::CreateGeometry() +void AliVZERO::CreateMaterials() { // - // Build simple ROOT TNode geometry for event display + // Creates materials used for Geant3 geometry // } + //_____________________________________________________________________________ -void AliVZERO::CreateMaterials() +void AliVZERO::Init() +{ + // + // Initialises the VZERO class after it has been built + // +} + + +//_____________________________________________________________________________ +void AliVZERO::SetMaxStepQua(Float_t p1) { // - // Build simple ROOT TNode geometry for event display + // Possible parametrisation of steps in active materials // + fMaxStepQua = p1; } +//_____________________________________________________________________________ +void AliVZERO::SetMaxStepAlu(Float_t p1) +{ + // + // Possible parametrisation of steps in Aluminum foils (not used in + // version v2) + // + fMaxStepAlu = p1; +} +//_____________________________________________________________________________ +void AliVZERO::SetMaxDestepQua(Float_t p1) +{ + // + // Possible parametrisation of steps in active materials (quartz) + // + fMaxDestepQua = p1; +} //_____________________________________________________________________________ -Int_t AliVZERO::DistanceToPrimitive(Int_t px, Int_t py) +void AliVZERO::SetMaxDestepAlu(Float_t p1) { // - // Calculate the distance from the mouse to the VZERO on the screen - // Dummy routine + // Possible parametrisation of steps in Aluminum (not used in + // version v2) // - - return 9999; + fMaxDestepAlu = p1; } + +//_____________________________________________________________________________ +AliLoader* AliVZERO::MakeLoader(const char* topfoldername) +{ + // + // Builds VZEROgetter (AliLoader type) + // if detector wants to use customized getter, it must overload this method + // +// Info("MakeLoader","Creating AliVZEROLoader. Top folder is %s.",topfoldername); -//------------------------------------------------------------------------- -void AliVZERO::Init() + AliDebug(1,Form("Creating AliVZEROLoader, Top folder is %s ",topfoldername)); + fLoader = new AliVZEROLoader(GetName(),topfoldername); + return fLoader; +} + +//_____________________________________________________________________________ +void AliVZERO::SetTreeAddress() +{ + // + // Sets tree address for hits. + // + if (fLoader->TreeH() && (fHits == 0x0)) + fHits = new TClonesArray("AliVZEROhit", 400); + + AliDetector::SetTreeAddress(); +} + +//_____________________________________________________________________________ +AliDigitizer* AliVZERO::CreateDigitizer(AliDigitizationInput* digInput) const { // - // Initialise the VZERO after it has been built + // Creates a digitizer for VZERO // + return new AliVZERODigitizer(digInput); } +//_____________________________________________________________________________ +void AliVZERO::Hits2Digits(){ + // + // Converts hits to digits + // + // Creates the VZERO digitizer + AliVZERODigitizer* dig = new AliVZERODigitizer(this,AliVZERODigitizer::kHits2Digits); -//------------------------------------------------------------------------- + // Creates the digits + dig->Digitize(""); -void AliVZERO::SetMaxStepQua(Float_t p1) + // deletes the digitizer + delete dig; +} + +//_____________________________________________________________________________ +void AliVZERO::Hits2SDigits(){ + // + // Converts hits to summable digits + // + // Creates the VZERO digitizer + AliVZERODigitizer* dig = new AliVZERODigitizer(this,AliVZERODigitizer::kHits2SDigits); + + // Creates the sdigits + dig->Digitize(""); + + // deletes the digitizer + delete dig; +} + +//_____________________________________________________________________________ +void AliVZERO::Digits2Raw() { - fMaxStepQua = p1; + // + // Converts digits of the current event to raw data + // + + AliVZERO *fVZERO = (AliVZERO*)gAlice->GetDetector("VZERO"); + fLoader->LoadDigits(); + TTree* digits = fLoader->TreeD(); + if (!digits) { + Error("Digits2Raw", "no digits tree"); + return; + } + TClonesArray * VZEROdigits = new TClonesArray("AliVZEROdigit",1000); + fVZERO->SetTreeAddress(); + digits->GetBranch("VZERODigit")->SetAddress(&VZEROdigits); + + const char *fileName = AliDAQ::DdlFileName("VZERO",0); + AliVZEROBuffer* buffer = new AliVZEROBuffer(fileName); + + // Get Trigger information first + // Read trigger inputs from trigger-detector object + AliDataLoader * dataLoader = fLoader->GetDigitsDataLoader(); + if( !dataLoader->IsFileOpen() ) + dataLoader->OpenFile( "READ" ); + AliTriggerDetector* trgdet = (AliTriggerDetector*)dataLoader->GetDirectory()->Get( "Trigger" ); + UInt_t triggerInfo = 0; + if(trgdet) { + triggerInfo = trgdet->GetMask() & 0xffff; + } + else { + AliError(Form("There is no trigger object for %s",fLoader->GetName())); + } + + buffer->WriteTriggerInfo((UInt_t)triggerInfo); + buffer->WriteTriggerScalers(); + buffer->WriteBunchNumbers(); + + Int_t aBBflagsV0A = 0; + Int_t aBBflagsV0C = 0; + Int_t aBGflagsV0A = 0; + Int_t aBGflagsV0C = 0; + + if (digits->GetUserInfo()->FindObject("BBflagsV0A")) { + aBBflagsV0A = ((TParameter*)digits->GetUserInfo()->FindObject("BBflagsV0A"))->GetVal(); + } + else + AliWarning("V0A beam-beam flags not found in digits tree UserInfo! The flags will not be written to the raw-data stream!"); + + if (digits->GetUserInfo()->FindObject("BBflagsV0C")) { + aBBflagsV0C = ((TParameter*)digits->GetUserInfo()->FindObject("BBflagsV0C"))->GetVal(); + } + else + AliWarning("V0C beam-beam flags not found in digits tree UserInfo! The flags will not be written to the raw-data stream!"); + + if (digits->GetUserInfo()->FindObject("BGflagsV0A")) { + aBGflagsV0A = ((TParameter*)digits->GetUserInfo()->FindObject("BGflagsV0A"))->GetVal(); + } + else + AliWarning("V0A beam-gas flags not found in digits tree UserInfo! The flags will not be written to the raw-data stream!"); + + if (digits->GetUserInfo()->FindObject("BGflagsV0C")) { + aBGflagsV0C = ((TParameter*)digits->GetUserInfo()->FindObject("BGflagsV0C"))->GetVal(); + } + else + AliWarning("V0C beam-gas flags not found in digits tree UserInfo! The flags will not be written to the raw-data stream!"); + + // Now retrieve the channel information: charge smaples + time and + // dump it into ADC and Time arrays + Int_t nEntries = Int_t(digits->GetEntries()); + Short_t aADC[64][AliVZEROdigit::kNClocks]; + Float_t aTime[64]; + Float_t aWidth[64]; + Bool_t aIntegrator[64]; + Bool_t aBBflag[64]; + Bool_t aBGflag[64]; + + for (Int_t i = 0; i < nEntries; i++) { + fVZERO->ResetDigits(); + digits->GetEvent(i); + Int_t ndig = VZEROdigits->GetEntriesFast(); + + if(ndig == 0) continue; + for(Int_t k=0; kAt(k); + // Convert aliroot channel k into FEE channel iChannel before writing data + Int_t iChannel = AliVZEROCalibData::GetBoardNumber(fVZERODigit->PMNumber()) * 8 + + AliVZEROCalibData::GetFEEChannelNumber(fVZERODigit->PMNumber()); + for(Int_t iClock = 0; iClock < AliVZEROdigit::kNClocks; ++iClock) aADC[iChannel][iClock] = fVZERODigit->ChargeADC(iClock); + aTime[iChannel] = fVZERODigit->Time(); + aWidth[iChannel] = fVZERODigit->Width(); + aIntegrator[iChannel]= fVZERODigit->Integrator(); + if(fVZERODigit->PMNumber() < 32) { + aBBflag[iChannel] = (aBBflagsV0C >> fVZERODigit->PMNumber()) & 0x1; + aBGflag[iChannel] = (aBGflagsV0C >> fVZERODigit->PMNumber()) & 0x1; + } + else { + aBBflag[iChannel] = (aBBflagsV0A >> (fVZERODigit->PMNumber()-32)) & 0x1; + aBGflag[iChannel] = (aBGflagsV0A >> (fVZERODigit->PMNumber()-32)) & 0x1; + } + AliDebug(1,Form("DDL: %s\tdigit number: %d\tPM number: %d\tADC: %d\tTime: %f", + fileName,k,fVZERODigit->PMNumber(),aADC[iChannel][AliVZEROdigit::kNClocks/2],aTime[iChannel])); + } + } + + // Now fill raw data + + for (Int_t iCIU = 0; iCIU < 8; iCIU++) { + + // decoding of one Channel Interface Unit numbered iCIU - there are 8 channels per CIU (and 8 CIUs) : + + for(Int_t iChannel_Offset = iCIU*8; iChannel_Offset < (iCIU*8)+8; iChannel_Offset=iChannel_Offset+4) { + for(Int_t iChannel = iChannel_Offset; iChannel < iChannel_Offset+4; iChannel++) { + buffer->WriteChannel(iChannel, aADC[iChannel], aIntegrator[iChannel]); + } + buffer->WriteBeamFlags(&aBBflag[iChannel_Offset],&aBGflag[iChannel_Offset]); + buffer->WriteMBInfo(); + buffer->WriteMBFlags(); + buffer->WriteBeamScalers(); + } + + for(Int_t iChannel = iCIU*8 + 7; iChannel >= iCIU*8; iChannel--) { + buffer->WriteTiming(aTime[iChannel], aWidth[iChannel]); + } + + // End of decoding of one CIU card + + } // end of decoding the eight CIUs + + delete buffer; + fLoader->UnloadDigits(); } -//___________________________________________ -void AliVZERO::SetMaxStepAlu(Float_t p1) +//_____________________________________________________________________________ +Bool_t AliVZERO::Raw2SDigits(AliRawReader* rawReader){ + // Converts the VZERO raw data into digits + // The method is used for merging simulated and + // real data events + TStopwatch timer; + timer.Start(); + + if(!fLoader) { + AliError("no VZERO loader found"); + return kFALSE; + } + fLoader->LoadSDigits("UPDATE"); + + if (!fLoader->TreeS()) fLoader->MakeTree("S"); + fLoader->MakeSDigitsContainer(); + TTree* treeS = fLoader->TreeS(); + + TClonesArray *sdigits = new TClonesArray("AliVZEROSDigit", 64); + treeS->Branch("VZEROSDigit", &sdigits); + + { + rawReader->Reset(); + AliVZERORawStream rawStream(rawReader); + + if (!rawStream.Next()) return kFALSE; // No VZERO data found + + GetCalibData(); + + Int_t nSDigits = 0; + Float_t *charges = NULL; + Int_t nbins = 0; + for(Int_t iChannel=0; iChannel < 64; ++iChannel) { + Int_t offlineCh = rawStream.GetOfflineChannel(iChannel); + Short_t chargeADC[AliVZEROdigit::kNClocks]; + for(Int_t iClock=0; iClock < AliVZEROdigit::kNClocks; ++iClock) { + chargeADC[iClock] = rawStream.GetPedestal(iChannel,iClock); + } + // Integrator flag + Bool_t integrator = rawStream.GetIntegratorFlag(iChannel,AliVZEROdigit::kNClocks/2); + // HPTDC data (leading time and width) + Int_t board = AliVZEROCalibData::GetBoardNumber(offlineCh); + Float_t time = rawStream.GetTime(iChannel)*fCalibData->GetTimeResolution(board); + // Float_t width = rawStream.GetWidth(iChannel)*fCalibData->GetWidthResolution(board); + Float_t adc = 0; + + // Pedestal retrieval and suppression + Float_t maxadc = 0; + Int_t imax = -1; + Float_t adcPedSub[AliVZEROdigit::kNClocks]; + Float_t integral = fSignalShape->Integral(0,200); + for(Int_t iClock=0; iClock < AliVZEROdigit::kNClocks; ++iClock) { + Bool_t iIntegrator = (iClock%2 == 0) ? integrator : !integrator; + Int_t k = offlineCh + 64*iIntegrator; + adcPedSub[iClock] = (Float_t)chargeADC[iClock] - fCalibData->GetPedestal(k); + if(adcPedSub[iClock] <= fRecoParam->GetNSigmaPed()*fCalibData->GetSigma(k)) { + adcPedSub[iClock] = 0; + continue; + } + if(iClock < fRecoParam->GetStartClock() || iClock > fRecoParam->GetEndClock()) continue; + if(adcPedSub[iClock] > maxadc) { + maxadc = adcPedSub[iClock]; + imax = iClock; + } + } + if (imax != -1) { + Int_t start = imax - fRecoParam->GetNPreClocks(); + if (start < 0) start = 0; + Int_t end = imax + fRecoParam->GetNPostClocks(); + if (end > 20) end = 20; + for(Int_t iClock = start; iClock <= end; iClock++) { + adc += adcPedSub[iClock]; + } + } + Float_t correctedTime = CorrectLeadingTime(offlineCh,time,adc); + + if (!charges) { + nbins = fNBins[offlineCh]; + charges = new Float_t[nbins]; + } + else if (nbins != fNBins[offlineCh]) { + delete [] charges; + nbins = fNBins[offlineCh]; + charges = new Float_t[nbins]; + } + memset(charges,0,nbins*sizeof(Float_t)); + + // Now lets produce SDigit + if ((correctedTime > (AliVZEROReconstructor::kInvalidTime + 1e-6)) && + (adc > 1e-6)) { + for(Int_t iBin = 0; iBin < nbins; ++iBin) { + Float_t t = fBinSize[offlineCh]*Float_t(iBin); + if ((t < correctedTime) || + (t > (correctedTime+200.))) continue; + charges[iBin] = kChargePerADC*adc*(fSignalShape->Eval(t-correctedTime)*fBinSize[offlineCh]/integral); + } + } + + TClonesArray &sdigitsref = *sdigits; + new (sdigitsref[nSDigits++]) AliVZEROSDigit(offlineCh,fNBins[offlineCh],charges); + } + if (charges) delete [] charges; + } + + treeS->Fill(); + fLoader->WriteSDigits("OVERWRITE"); + fLoader->UnloadSDigits(); + + timer.Stop(); + timer.Print(); + return kTRUE; +} + +//_____________________________________________________________________________ +void AliVZERO::GetCalibData() { - fMaxStepAlu = p1; + // Gets calibration object for VZERO set + // Do nothing in case it is already loaded + if (fCalibData) return; + + AliCDBEntry *entry = AliCDBManager::Instance()->Get("VZERO/Calib/Data"); + if (entry) fCalibData = (AliVZEROCalibData*) entry->GetObject(); + if (!fCalibData) AliFatal("No calibration data from calibration database !"); + + AliCDBEntry *entry2 = AliCDBManager::Instance()->Get("VZERO/Calib/TimeSlewing"); + if (!entry2) AliFatal("VZERO time slewing function is not found in OCDB !"); + fTimeSlewing = (TF1*)entry2->GetObject(); + + for(Int_t i = 0 ; i < 64; ++i) { + Int_t board = AliVZEROCalibData::GetBoardNumber(i); + fNBins[i] = TMath::Nint(((Float_t)(fCalibData->GetMatchWindow(board)+1)*25.0+ + (Float_t)kMaxTDCWidth*fCalibData->GetWidthResolution(board))/ + fCalibData->GetTimeResolution(board)); + fBinSize[i] = fCalibData->GetTimeResolution(board); + } + + fSignalShape = new TF1("VZEROSDigitSignalShape",this,&AliVZERO::SignalShape,0,200,6,"AliVZERO","SignalShape"); + fSignalShape->SetParameters(0,1.57345e1,-4.25603e-1, + 2.9,6.40982,3.69339e-01); + + fRecoParam = new AliVZERORecoParam; + + return; } -//___________________________________________ -void AliVZERO::SetMaxDestepQua(Float_t p1) +Float_t AliVZERO::CorrectLeadingTime(Int_t i, Float_t time, Float_t adc) const { - fMaxDestepQua = p1; + // Correct the leading time + // for slewing effect and + // misalignment of the channels + if (time < 1e-6) return -1024; + + // In case of pathological signals + if (adc < 1e-6) return time; + + // Slewing correction + Float_t thr = fCalibData->GetCalibDiscriThr(i,kTRUE); + time -= fTimeSlewing->Eval(adc/thr); + + return time; } -//___________________________________________ -void AliVZERO::SetMaxDestepAlu(Float_t p1) +double AliVZERO::SignalShape(double *x, double *par) { - fMaxDestepAlu = p1; + // this function simulates the signal + // shape used in Raw->SDigits method + + Double_t xx = x[0]; + if (xx <= par[0]) return 0; + Double_t a = 1./TMath::Power((xx-par[0])/par[1],1./par[2]); + if (xx <= par[3]) return a; + Double_t b = 1./TMath::Power((xx-par[3])/par[4],1./par[5]); + Double_t f = a*b/(a+b); + AliDebug(100,Form("x=%f func=%f",xx,f)); + return f; }