From: kharlov Date: Wed, 17 Jan 2007 17:28:56 +0000 (+0000) Subject: Extract ALTRO sample generation to a separate class AliPHOSPulseGenerator X-Git-Url: http://git.uio.no/git/?p=u%2Fmrichter%2FAliRoot.git;a=commitdiff_plain;h=431a92112f9f927bfbba614270fa326f8b342cb5 Extract ALTRO sample generation to a separate class AliPHOSPulseGenerator --- diff --git a/PHOS/AliPHOS.cxx b/PHOS/AliPHOS.cxx index 2ea0699fe56..6556010ee37 100644 --- a/PHOS/AliPHOS.cxx +++ b/PHOS/AliPHOS.cxx @@ -16,6 +16,9 @@ /* History of cvs commits: * * $Log$ + * Revision 1.105 2007/01/12 21:44:29 kharlov + * Simulate and reconstruct two gains simulaneouslsy + * * Revision 1.104 2006/11/23 13:40:44 hristov * Common class for raw data reading and ALTRO mappiing for PHOS and EMCAL (Gustavo, Cvetan) * @@ -104,20 +107,11 @@ class TFile; #include "AliCDBEntry.h" #include "AliCDBStorage.h" #include "AliPHOSCalibData.h" +#include "AliPHOSPulseGenerator.h" #include "AliDAQ.h" ClassImp(AliPHOS) -Double_t AliPHOS::fgCapa = 1.; // 1pF -Int_t AliPHOS::fgOrder = 2 ; -Double_t AliPHOS::fgTimeMax = 2.56E-5 ; // each sample is over 100 ns fTimeMax/fTimeBins -Double_t AliPHOS::fgTimePeak = 4.1E-6 ; // 4 micro seconds -Double_t AliPHOS::fgTimeTrigger = 100E-9 ; // 100ns, just for a reference - -Double_t AliPHOS::fgHighCharge = 8.2; // adjusted for a high gain range of 5.12 GeV (10 bits) -Double_t AliPHOS::fgHighGain = 6.64; -Double_t AliPHOS::fgHighLowGainFactor = 16.; // adjusted for a low gain range of 82 GeV (10 bits) - //____________________________________________________________________________ AliPHOS:: AliPHOS() : AliDetector() { @@ -446,15 +440,17 @@ void AliPHOS::Digits2Raw() } // some digitization constants -// const Int_t kThreshold = 1; // skip digits below this threshold // YVK const Float_t kThreshold = 0.001; // skip digits below 1 MeV const Int_t kAdcThreshold = 1; // Lower ADC threshold to write to raw data AliAltroBuffer* buffer = NULL; Int_t prevDDL = -1; - Int_t adcValuesLow[fkTimeBins]; - Int_t adcValuesHigh[fkTimeBins]; + // Create a shaper pulse object + AliPHOSPulseGenerator *pulse = new AliPHOSPulseGenerator(); + + Int_t *adcValuesLow = new Int_t[pulse->GetRawFormatTimeBins()]; + Int_t *adcValuesHigh= new Int_t[pulse->GetRawFormatTimeBins()]; //!!!!for debug!!! Int_t modMax=-111; @@ -472,10 +468,10 @@ void AliPHOS::Digits2Raw() geom->AbsToRelNumbering(digit->GetId(), relId); Int_t module = relId[0]; - // Begin FIXME + // Begin FIXME if (relId[1] != 0) continue; // ignore digits from CPV - // End FIXME + // End FIXME Int_t row = relId[2]-1; Int_t col = relId[3]-1; @@ -524,10 +520,10 @@ void AliPHOS::Digits2Raw() } // out of time range signal (?) - if (digit->GetTimeR() > GetRawFormatTimeMax() ) { + if (digit->GetTimeR() > pulse->GetRawFormatTimeMax() ) { AliInfo("Signal is out of time range.\n"); buffer->FillBuffer((Int_t)digit->GetEnergy()); - buffer->FillBuffer(GetRawFormatTimeBins() ); // time bin + buffer->FillBuffer(pulse->GetRawFormatTimeBins() ); // time bin buffer->FillBuffer(3); // bunch length buffer->WriteTrailer(3, relId[3], relId[2], module); // trailer @@ -543,12 +539,15 @@ void AliPHOS::Digits2Raw() else { energy = 0; // CPV raw data format is now know yet } - Bool_t lowgain = RawSampledResponse(digit->GetTimeR(), energy, adcValuesHigh, adcValuesLow) ; + pulse->SetAmplitude(energy); + pulse->SetTZero(digit->GetTimeR()); + pulse->MakeSamples(); + pulse->GetSamples(adcValuesHigh, adcValuesLow) ; - buffer->WriteChannel(relId[3]-1, relId[2]-1, 0, - GetRawFormatTimeBins(), adcValuesLow , kAdcThreshold); - buffer->WriteChannel(relId[3]-1, relId[2]-1, 1, - GetRawFormatTimeBins(), adcValuesHigh, kAdcThreshold); + buffer->WriteChannel(relId[3]-1, relId[2]-1, 0, + pulse->GetRawFormatTimeBins(), adcValuesLow , kAdcThreshold); + buffer->WriteChannel(relId[3]-1, relId[2]-1, 1, + pulse->GetRawFormatTimeBins(), adcValuesHigh, kAdcThreshold); } } @@ -563,6 +562,7 @@ void AliPHOS::Digits2Raw() AliDebug(1,Form("Digit with max. energy: modMax %d colMax %d rowMax %d eMax %f\n", modMax,colMax,rowMax,eMax)); + delete pulse; loader->UnloadDigits(); } @@ -585,79 +585,6 @@ AliLoader* AliPHOS::MakeLoader(const char* topfoldername) return fLoader; } -//__________________________________________________________________ -Double_t AliPHOS::RawResponseFunction(Double_t *x, Double_t *par) -{ - // Shape of the electronics raw reponse: - // It is a semi-gaussian, 2nd order Gamma function of the general form - // v(t) = n**n * Q * A**n / C *(t/tp)**n * exp(-n * t/tp) with - // tp : peaking time par[0] - // n : order of the function - // C : integrating capacitor in the preamplifier - // A : open loop gain of the preamplifier - // Q : the total APD charge to be measured Q = C * energy - - Double_t signal ; - Double_t xx = x[0] - ( fgTimeTrigger + par[3] ) ; - - if (xx < 0 || xx > fgTimeMax) - signal = 0. ; - else { - Double_t fac = par[0] * TMath::Power(fgOrder, fgOrder) * TMath::Power(par[1], fgOrder) / fgCapa ; - signal = fac * par[2] * TMath::Power(xx / fgTimePeak, fgOrder) * TMath::Exp(-fgOrder * (xx / fgTimePeak)) ; - } - return signal ; -} - -//__________________________________________________________________ -Double_t AliPHOS::RawResponseFunctionMax(Double_t charge, Double_t gain) -{ - return ( charge * TMath::Power(fgOrder, fgOrder) * TMath::Power(gain, fgOrder) - / ( fgCapa * TMath::Exp(fgOrder) ) ); - -} - -//__________________________________________________________________ -Bool_t AliPHOS::RawSampledResponse(Double_t dtime, Double_t damp, Int_t * adcH, Int_t * adcL) const -{ - // for a start time dtime and an amplitude damp given by digit, - // calculates the raw sampled response AliPHOS::RawResponseFunction - // Input: dtime - signal start time - // damp - signal amplitude (energy) - // Output: adcH - array[fkTimeBins] of 10-bit samples for high-gain channel - // adcL - array[fkTimeBins] of 10-bit samples for low-gain channel - - const Int_t kRawSignalOverflow = 0x3FF ; - Bool_t lowGain = kFALSE ; - - TF1 signalF("signal", RawResponseFunction, 0, GetRawFormatTimeMax(), 4); - - for (Int_t iTime = 0; iTime < GetRawFormatTimeBins(); iTime++) { - signalF.SetParameter(0, GetRawFormatHighCharge() ) ; - signalF.SetParameter(1, GetRawFormatHighGain() ) ; - signalF.SetParameter(2, damp) ; - signalF.SetParameter(3, dtime) ; - Double_t time = iTime * GetRawFormatTimeMax() / GetRawFormatTimeBins() ; - Double_t signal = signalF.Eval(time) ; - if ( static_cast(signal+0.5) > kRawSignalOverflow ){ // larger than 10 bits - signal = kRawSignalOverflow ; - lowGain = kTRUE ; - } - adcH[iTime] = static_cast(signal + 0.5) ; - AliDebug(4,Form("iTime: %d Energy: %f HG signal: %f adcH: %d ",iTime,damp,signal,adcH[iTime])); - - signalF.SetParameter(0, GetRawFormatLowCharge() ) ; - signalF.SetParameter(1, GetRawFormatLowGain() ) ; - signal = signalF.Eval(time) ; - if ( static_cast(signal+0.5) > kRawSignalOverflow) // larger than 10 bits - signal = kRawSignalOverflow ; - adcL[iTime] = static_cast(0.5 + signal ) ; - AliDebug(4,Form("..LG: %f adcL: %d\n",signal,adcL[iTime])); - - } - return lowGain ; -} - //____________________________________________________________________________ void AliPHOS::SetTreeAddress() { diff --git a/PHOS/AliPHOS.h b/PHOS/AliPHOS.h index aa394d8eeb4..b79044ee399 100644 --- a/PHOS/AliPHOS.h +++ b/PHOS/AliPHOS.h @@ -7,6 +7,9 @@ /* History of cvs commits: * * $Log$ + * Revision 1.69 2006/11/14 17:11:15 hristov + * Removing inheritances from TAttLine, TAttMarker and AliRndm in AliModule. The copy constructor and assignment operators are moved to the private part of the class and not implemented. The corresponding changes are propagated to the detectors + * * Revision 1.68 2006/08/11 12:36:25 cvetan * Update of the PHOS code needed in order to read and reconstruct the beam test raw data (i.e. without an existing galice.root) * @@ -80,42 +83,10 @@ public: virtual AliTriggerDetector* CreateTriggerDetector() const { return new AliPHOSTrigger(); } - // Raw Read Out - Double_t GetRawFormatCapa() const { return fgCapa ; } - static Double_t GetRawFormatHighCharge() { return fgHighCharge ; } - static Double_t GetRawFormatHighGain() { return fgHighGain ; } - static Double_t GetRawFormatHighLowGainFactor() { return fgHighLowGainFactor ; } - static Double_t GetRawFormatLowCharge() { return ( fgHighCharge * fgHighLowGainFactor ) ; } - static Double_t GetRawFormatLowGain() { return ( fgHighGain / fgHighLowGainFactor ) ; } - Int_t GetRawFormatOrder() const { return fgOrder ; } - static Int_t GetRawFormatTimeBins() { return fkTimeBins ; } - Double_t GetRawFormatTimeMax() const { return fgTimeMax ; } - Double_t GetRawFormatTimePeak() const { return fgTimePeak ; } - Double_t GetRawFormatTimeTrigger() const { return fgTimeTrigger ; } - static Double_t RawResponseFunctionMax(Double_t charge, Double_t gain) ; - static Double_t RawResponseFunction(Double_t *x, Double_t *par) ; - Bool_t RawSampledResponse(Double_t dtime, Double_t damp, Int_t * adcH, Int_t * adcL) const ; - // virtual AliLoader* MakeLoader(const char* topfoldername); virtual void SetTreeAddress(); virtual const TString Version() const {return TString(" ") ; } - -protected: - - - - static Double_t fgCapa ; // capacitor of the preamplifier for the raw RO signal - static Double_t fgHighCharge ; // high charge (to convert energy to charge) for the raw RO signal - static Double_t fgHighGain ; // high gain for the raw RO signal - static Double_t fgHighLowGainFactor ; // high to low gain factor for the raw RO signal - static Int_t fgOrder ; // order of the gamma function for the RO signal -// static const Int_t fkTimeBins = 256 ; // number of sampling bins of the raw RO signal - static const Int_t fkTimeBins = 64 ; // number of sampling bins of the raw RO signal - static Double_t fgTimeMax ; // maximum sampled time of the raw RO signal - static Double_t fgTimePeak ; // peaking time of the raw RO signal - static Double_t fgTimeTrigger ; // time of the trigger for the RO signal - private: AliPHOS(AliPHOS & phos); AliPHOS & operator = (const AliPHOS & /*rvalue*/); diff --git a/PHOS/AliPHOSGetter.cxx b/PHOS/AliPHOSGetter.cxx index c574b3d2369..4196794ca6d 100644 --- a/PHOS/AliPHOSGetter.cxx +++ b/PHOS/AliPHOSGetter.cxx @@ -60,6 +60,7 @@ #include "AliPHOSBeamTestEvent.h" #include "AliPHOSGetter.h" #include "AliPHOSLoader.h" +#include "AliPHOSPulseGenerator.h" #include "AliRunLoader.h" #include "AliStack.h" #include "AliCaloRawStream.h" @@ -638,12 +639,15 @@ void AliPHOSGetter::FitRaw(Bool_t lowGainFlag, TGraph * gLowGain, TGraph * gHigh time = 0. ; energy = 0. ; + // Create a shaper pulse object which contains all the shaper parameters + AliPHOSPulseGenerator *pulse = new AliPHOSPulseGenerator(); + if (lowGainFlag) { timezero1 = timezero2 = signalmax = timemax = 0. ; - signalF->FixParameter(0, PHOS()->GetRawFormatLowCharge()) ; - signalF->FixParameter(1, PHOS()->GetRawFormatLowGain()) ; + signalF->FixParameter(0, pulse->GetRawFormatLowCharge()) ; + signalF->FixParameter(1, pulse->GetRawFormatLowGain()) ; Int_t index ; - for (index = 0; index < PHOS()->GetRawFormatTimeBins(); index++) { + for (index = 0; index < pulse->GetRawFormatTimeBins(); index++) { gLowGain->GetPoint(index, time, signal) ; if (signal > kNoiseThreshold && timezero1 == 0.) timezero1 = time ; @@ -654,21 +658,22 @@ void AliPHOSGetter::FitRaw(Bool_t lowGainFlag, TGraph * gLowGain, TGraph * gHigh timemax = time ; } } - signalmax /= PHOS()->RawResponseFunctionMax(PHOS()->GetRawFormatLowCharge(), - PHOS()->GetRawFormatLowGain()) ; - if ( timezero1 + PHOS()->GetRawFormatTimePeak() < PHOS()->GetRawFormatTimeMax() * 0.4 ) { // else its noise + signalmax /= + pulse->RawResponseFunctionMax(pulse->GetRawFormatLowCharge(), + pulse->GetRawFormatLowGain()) ; + if ( timezero1 + pulse->GetRawFormatTimePeak() < pulse->GetRawFormatTimeMax() * 0.4 ) { // else its noise signalF->SetParameter(2, signalmax) ; signalF->SetParameter(3, timezero1) ; gLowGain->Fit(signalF, "QRO", "", 0., timezero2); //, "QRON") ; energy = signalF->GetParameter(2) ; - time = signalF->GetMaximumX() - PHOS()->GetRawFormatTimePeak() - PHOS()->GetRawFormatTimeTrigger() ; + time = signalF->GetMaximumX() - pulse->GetRawFormatTimePeak() - pulse->GetRawFormatTimeTrigger() ; } } else { timezero1 = timezero2 = signalmax = timemax = 0. ; - signalF->FixParameter(0, PHOS()->GetRawFormatHighCharge()) ; - signalF->FixParameter(1, PHOS()->GetRawFormatHighGain()) ; + signalF->FixParameter(0, pulse->GetRawFormatHighCharge()) ; + signalF->FixParameter(1, pulse->GetRawFormatHighGain()) ; Int_t index ; - for (index = 0; index < PHOS()->GetRawFormatTimeBins(); index++) { + for (index = 0; index < pulse->GetRawFormatTimeBins(); index++) { gHighGain->GetPoint(index, time, signal) ; if (signal > kNoiseThreshold && timezero1 == 0.) timezero1 = time ; @@ -679,14 +684,14 @@ void AliPHOSGetter::FitRaw(Bool_t lowGainFlag, TGraph * gLowGain, TGraph * gHigh timemax = time ; } } - signalmax /= PHOS()->RawResponseFunctionMax(PHOS()->GetRawFormatHighCharge(), - PHOS()->GetRawFormatHighGain()) ;; - if ( timezero1 + PHOS()->GetRawFormatTimePeak() < PHOS()->GetRawFormatTimeMax() * 0.4 ) { // else its noise + signalmax /= pulse->RawResponseFunctionMax(pulse->GetRawFormatHighCharge(), + pulse->GetRawFormatHighGain()) ;; + if ( timezero1 + pulse->GetRawFormatTimePeak() < pulse->GetRawFormatTimeMax() * 0.4 ) { // else its noise signalF->SetParameter(2, signalmax) ; signalF->SetParameter(3, timezero1) ; gHighGain->Fit(signalF, "QRO", "", 0., timezero2) ; energy = signalF->GetParameter(2) ; - time = signalF->GetMaximumX() - PHOS()->GetRawFormatTimePeak() - PHOS()->GetRawFormatTimeTrigger() ; + time = signalF->GetMaximumX() - pulse->GetRawFormatTimePeak() - pulse->GetRawFormatTimeTrigger() ; } } if (time == 0) energy = 0 ; @@ -736,7 +741,9 @@ Int_t AliPHOSGetter::ReadRaw(AliRawReader *rawReader,Bool_t isOldRCUFormat) AliCaloRawStream in(rawReader,"PHOS"); in.SetOldRCUFormat(isOldRCUFormat); - TF1 * signalF = new TF1("signal", AliPHOS::RawResponseFunction, 0, PHOS()->GetRawFormatTimeMax(), 4); + // Create a shaper pulse object + AliPHOSPulseGenerator *pulse = new AliPHOSPulseGenerator(); + TF1 * signalF = new TF1("signal", AliPHOSPulseGenerator::RawResponseFunction, 0, pulse->GetRawFormatTimeMax(), 4); signalF->SetParNames("Charge", "Gain", "Amplitude", "TimeZero") ; Int_t relId[4], absId =0; @@ -801,7 +808,7 @@ Int_t AliPHOSGetter::ReadRaw(AliRawReader *rawReader,Bool_t isOldRCUFormat) if(lowGainFlag) { energyLG = hLowGain ->GetMaximum(); // "digit amplitude" // energyLG -= hLowGain ->GetBinContent(0); // "pedestal subtraction" - energyLG *= AliPHOS::GetRawFormatHighLowGainFactor(); // *16 + energyLG *= pulse->GetRawFormatHighLowGainFactor(); // *16 if(AliLog::GetGlobalDebugLevel()>3) AliDebug(4,Form("----Printing hLowGain: ----\n")) ; hLowGain ->Print("all"); AliDebug(2,Form("AliPHOSGetter::ReadRaw: (mod,col,row)=(%d,%d,%d), low gain energy=%f\n\n", diff --git a/PHOS/AliPHOSPulseGenerator.cxx b/PHOS/AliPHOSPulseGenerator.cxx new file mode 100644 index 00000000000..4d396041a17 --- /dev/null +++ b/PHOS/AliPHOSPulseGenerator.cxx @@ -0,0 +1,290 @@ +/************************************************************************** + * Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved. * + * * + * Author: The ALICE Off-line Project. * + * Contributors are mentioned in the code where appropriate. * + * * + * Permission to use, copy, modify and distribute this software and its * + * documentation strictly for non-commercial purposes is hereby granted * + * without fee, provided that the above copyright notice appears in all * + * copies and that both the copyright notice and this permission notice * + * appear in the supporting documentation. The authors make no claims * + * about the suitability of this software for any purpose. It is * + * provided "as is" without express or implied warranty. * + **************************************************************************/ + +/* $Id$ */ + +// The class which simulates the pulse shape from the PHOS FEE shaper, +// make sampled amplitudes, digitize them. +// Use case: +// AliPHOSPulseGenerator *pulse = new AliPHOSPulseGenerator(energy,time); +// Int_t *adcHG = new Int_t[pulse->GetRawFormatTimeBins()]; +// Int_t *adcLG= new Int_t[pulse->GetRawFormatTimeBins()]; +// pulse->MakeSamples(); +// pulse->GetSamples(adcHG, adcHG) ; +// pulse->Print(); +// pulse->Draw(); +// +// Author: Yuri Kharlov, after Yves Schutz and Per Thomas Hille + +// --- ROOT system --- +#include "TMath.h" +#include "TF1.h" +#include "TGraph.h" +#include "TCanvas.h" + +// --- AliRoot header files --- +#include "AliLog.h" +#include "AliPHOSPulseGenerator.h" + +// --- Standard library --- +#include +#include + +using std::cout; +using std::endl; + +ClassImp(AliPHOSPulseGenerator) + +Double_t AliPHOSPulseGenerator::fgCapa = 1.; // 1pF +Int_t AliPHOSPulseGenerator::fgOrder = 2 ; // order of the Gamma function +Double_t AliPHOSPulseGenerator::fgTimeMax = 2.56E-5 ; // each sample is over 100 ns fTimeMax/fTimeBins +Double_t AliPHOSPulseGenerator::fgTimePeak = 4.1E-6 ; // 4 micro seconds +Double_t AliPHOSPulseGenerator::fgTimeTrigger = 100E-9 ; // 100ns, just for a reference +Double_t AliPHOSPulseGenerator::fgHighCharge = 8.2; // adjusted for a high gain range of 5.12 GeV (10 bits) +Double_t AliPHOSPulseGenerator::fgHighGain = 6.64; +Double_t AliPHOSPulseGenerator::fgHighLowGainFactor = 16.; // adjusted for a low gain range of 82 GeV (10 bits) + +//----------------------------------------------------------------------------- +AliPHOSPulseGenerator::AliPHOSPulseGenerator(Double_t a, Double_t t0) + : TObject(), fAmplitude(a), fTZero(t0), fDataHG(0), fDataLG(0), fDigitize(kTRUE) +{ + // Contruct a pulsegenrator object and initializes all necessary parameters + // @param a digit amplitude in GeV + // @param t0 time delay in nanoseconds of signal relative the first sample. + // This value should be between 0 and Ts, where Ts is the sample interval + + fDataHG = new Double_t[fkTimeBins]; + fDataLG = new Double_t[fkTimeBins]; +} + +//----------------------------------------------------------------------------- +AliPHOSPulseGenerator::AliPHOSPulseGenerator(const AliPHOSPulseGenerator & pulse) + : TObject(), fAmplitude(pulse.fAmplitude), fTZero(pulse.fTZero), fDataHG(0), fDataLG(0), fDigitize(kTRUE) +{ + fDataHG = new Double_t[pulse.fkTimeBins]; + fDataLG = new Double_t[pulse.fkTimeBins]; + for (Int_t i=0; i fgTimeMax) + signal = 0. ; + else { + Double_t fac = par[0] * TMath::Power(fgOrder, fgOrder) * TMath::Power(par[1], fgOrder)/fgCapa ; + signal = fac * par[2] * TMath::Power(xx/fgTimePeak, fgOrder) * TMath::Exp(-fgOrder*(xx/fgTimePeak)) ; + } + return signal ; +} + +//__________________________________________________________________ +Double_t AliPHOSPulseGenerator::RawResponseFunctionMax(Double_t charge, Double_t gain) +{ + // Maximum value of the shaper response function + return ( charge * TMath::Power(fgOrder, fgOrder) * TMath::Power(gain, fgOrder) + / ( fgCapa * TMath::Exp(fgOrder) ) ); +} + +//__________________________________________________________________ +Bool_t AliPHOSPulseGenerator::MakeSamples() +{ + // for a start time fTZero and an amplitude fAmplitude given by digit, + // calculates the raw sampled response AliPHOSPulseGenerator::RawResponseFunction + + const Int_t kRawSignalOverflow = 0x3FF ; + Bool_t lowGain = kFALSE ; + + TF1 signalF("signal", RawResponseFunction, 0, GetRawFormatTimeMax(), 4); + + for (Int_t iTime = 0; iTime < GetRawFormatTimeBins(); iTime++) { + signalF.SetParameter(0, fgHighCharge) ; + signalF.SetParameter(1, fgHighGain) ; + signalF.SetParameter(2, fAmplitude) ; + signalF.SetParameter(3, fTZero) ; + Double_t time = iTime * GetRawFormatTimeMax() / GetRawFormatTimeBins() ; + Double_t signal = signalF.Eval(time) ; + if ( static_cast(signal+0.5) > kRawSignalOverflow ){ // larger than 10 bits + signal = kRawSignalOverflow ; + lowGain = kTRUE ; + } + fDataHG[iTime] = signal; + + signalF.SetParameter(0, GetRawFormatLowCharge() ) ; + signalF.SetParameter(1, GetRawFormatLowGain() ) ; + signal = signalF.Eval(time) ; + if ( static_cast(signal+0.5) > kRawSignalOverflow) // larger than 10 bits + signal = kRawSignalOverflow ; + fDataLG[iTime] = signal; + + } + return lowGain ; +} + +//__________________________________________________________________ +void AliPHOSPulseGenerator::GetSamples(Int_t *adcHG, Int_t *adcLG) const +{ + // Return integer sample arrays adcHG and adcLG + for (Int_t iTime = 0; iTime < GetRawFormatTimeBins(); iTime++) { + adcHG[iTime] = static_cast(fDataHG[iTime]) ; + adcLG[iTime] = static_cast(fDataLG[iTime]) ; + } +} + +//__________________________________________________________________ +void AliPHOSPulseGenerator::Print(Option_t*) const +{ + // Prints sampled amplitudes to stdout + Int_t i; + cout << "High gain: "; + for (i=0; iSetMarkerStyle(20); + graphLG->SetMarkerStyle(24); + graphHG->SetMarkerSize(0.3); + graphLG->SetMarkerSize(0.3); + graphHG->SetTitle("High gain samples"); + graphLG->SetTitle("Low gain samples"); + + TCanvas *c1 = new TCanvas("c1","Raw ALTRO samples",10,10,700,500); + c1->Divide(2,1); + c1->cd(1); + gPad->SetLeftMargin(0.15); + graphHG->Draw("AP"); + graphHG->GetHistogram()->SetTitleOffset(1.6,"Y"); + graphHG->GetHistogram()->SetXTitle("time, #musec"); + graphHG->GetHistogram()->SetYTitle("Amplitude, ADC counts"); + c1->cd(2); + gPad->SetLeftMargin(0.15); + graphLG->Draw("AP"); + graphLG->GetHistogram()->SetTitleOffset(1.6,"Y"); + graphLG->GetHistogram()->SetXTitle("time, #musec"); + graphLG->GetHistogram()->SetYTitle("Amplitude, ADC counts"); + c1->Update(); +} diff --git a/PHOS/AliPHOSPulseGenerator.h b/PHOS/AliPHOSPulseGenerator.h new file mode 100644 index 00000000000..793150daaee --- /dev/null +++ b/PHOS/AliPHOSPulseGenerator.h @@ -0,0 +1,82 @@ +#ifndef ALIPHOSPULSEGENERATOR_H +#define ALIPHOSPULSEGENERATOR_H +/* Copyright(c) 2007, ALICE Experiment at CERN, All rights reserved. * + * See cxx source for full Copyright notice */ + +/* $Id$ */ + +// The class which simulates the pulse shape from the PHOS FEE shaper, +// make sampled amplitudes, digitize them. +// The shape is described by the function RawResponseFunction +// The input parameters for the shape function (time and aplitude) are passed +// to the class via constructor. +// Other parameters related to the shaper are hard-coded in this class + +#include + +class AliPHOSPulseGenerator : public TObject +{ +public: + AliPHOSPulseGenerator(Double_t a=0, Double_t t0=0); + AliPHOSPulseGenerator(const AliPHOSPulseGenerator & pulse); + virtual ~AliPHOSPulseGenerator(); + + void AddBaseline(Double_t baselineLevel); + void AddNoise (Double_t *sigma); + void AddNoise (Double_t *sigma, Double_t cutoff); + void AddPretriggerSamples(Int_t nPresamples); + void GetSamples(Int_t *adcHG, Int_t *adcLG) const; + Bool_t MakeSamples(); + void Digitize(); + Bool_t GetDigitize() {return fDigitize;} + void SetDigitise (Bool_t flag) {fDigitize = flag;} + void SetAmplitude(Double_t a) {fAmplitude = a ;} + void SetTZero (Double_t t0) {fTZero = t0 ;} + + // Raw Read Out + Double_t GetRawFormatCapa() const { return fgCapa ; } + static Double_t GetRawFormatHighCharge() { return fgHighCharge ; } + static Double_t GetRawFormatHighGain() { return fgHighGain ; } + static Double_t GetRawFormatHighLowGainFactor() { return fgHighLowGainFactor ; } + static Double_t GetRawFormatLowCharge() { return ( fgHighCharge * fgHighLowGainFactor ) ; } + static Double_t GetRawFormatLowGain() { return ( fgHighGain / fgHighLowGainFactor ) ; } + Int_t GetRawFormatOrder() const { return fgOrder ; } + static Int_t GetRawFormatTimeBins() { return fkTimeBins ; } + Double_t GetRawFormatTimeMax() const { return fgTimeMax ; } + Double_t GetRawFormatTimePeak() const { return fgTimePeak ; } + Double_t GetRawFormatTimeTrigger() const { return fgTimeTrigger ; } + static Double_t RawResponseFunctionMax(Double_t charge, Double_t gain) ; + static Double_t RawResponseFunction (Double_t *x, Double_t *par) ; + + virtual void Print(Option_t*) const; + virtual void Draw (Option_t*); + + AliPHOSPulseGenerator& operator = (const AliPHOSPulseGenerator &) { + Fatal("operator =", "not implemented") ; + return *this; + } + +private: + static Double_t fgCapa ; // capacitor of the preamplifier + static Double_t fgHighCharge ; // high charge (to convert energy to charge) + static Double_t fgHighGain ; // high gain + static Double_t fgHighLowGainFactor ; // high to low gain factor + static Int_t fgOrder ; // order of the gamma function + static const Int_t fkTimeBins = 64 ; // number of sampling bins + static Double_t fgTimeMax ; // maximum sampled time + static Double_t fgTimePeak ; // peaking time + static Double_t fgTimeTrigger ; // time of the trigger for the RO signal + +private: + Double_t fAmplitude; // signal amplitude in GeV + Double_t fTZero; // signal start time in ns + Double_t *fDataHG; // samples array for high gain + Double_t *fDataLG; // samples array for low gain + Bool_t fDigitize; // true is samples should be rounded to integers + + ClassDef(AliPHOSPulseGenerator,1) + +}; + +#endif + diff --git a/PHOS/AliPHOSTrigger.cxx b/PHOS/AliPHOSTrigger.cxx index 7e1ce6d7024..2496928229c 100644 --- a/PHOS/AliPHOSTrigger.cxx +++ b/PHOS/AliPHOSTrigger.cxx @@ -46,6 +46,7 @@ #include "AliPHOSTrigger.h" #include "AliPHOSGeometry.h" #include "AliPHOSGetter.h" +#include "AliPHOSPulseGenerator.h" #include "AliTriggerInput.h" //#include "AliLog.h" @@ -400,36 +401,37 @@ void AliPHOSTrigger::SetTriggers(const Int_t iMod, const TMatrixD * ampmax2, con //Set max amplitude if larger than in other Modules Float_t maxtimeR2 = -1 ; Float_t maxtimeRn = -1 ; - AliPHOSGetter * gime = AliPHOSGetter::Instance() ; - AliPHOS * phos = gime->PHOS(); - Int_t nTimeBins = phos->GetRawFormatTimeBins() ; + // Create a shaper pulse object + AliPHOSPulseGenerator *pulse = new AliPHOSPulseGenerator(); + Int_t nTimeBins = pulse->GetRawFormatTimeBins() ; //Set max 2x2 amplitude and select L0 trigger if(max2[0] > f2x2MaxAmp ){ f2x2MaxAmp = max2[0] ; f2x2SM = iMod ; maxtimeR2 = max2[3] ; - GetCrystalPhiEtaIndexInModuleFromTRUIndex(itru2,static_cast(max2[1]),static_cast(max2[2]),f2x2CrystalPhi,f2x2CrystalEta,geom) ; + GetCrystalPhiEtaIndexInModuleFromTRUIndex(itru2, + static_cast(max2[1]), + static_cast(max2[2]), + f2x2CrystalPhi,f2x2CrystalEta,geom) ; //Transform digit amplitude in Raw Samples fADCValuesLow2x2 = new Int_t[nTimeBins]; fADCValuesHigh2x2 = new Int_t[nTimeBins]; - phos->RawSampledResponse(maxtimeR2, f2x2MaxAmp, fADCValuesHigh2x2, fADCValuesLow2x2) ; + pulse->SetAmplitude(f2x2MaxAmp); + pulse->SetTZero(maxtimeR2); + pulse->MakeSamples(); + pulse->GetSamples(fADCValuesHigh2x2, fADCValuesLow2x2) ; //Set Trigger Inputs, compare ADC time bins until threshold is attained //Set L0 for(Int_t i = 0 ; i < nTimeBins ; i++){ - if(fADCValuesHigh2x2[i] >= fL0Threshold || fADCValuesLow2x2[i] >= fL0Threshold){ + if(fADCValuesHigh2x2[i] >= fL0Threshold || fADCValuesLow2x2[i] >= fL0Threshold) { SetInput("PHOS_L0") ; break; } } -// for(Int_t i = 0 ; i < 256 ; i++) -// if(fADCValuesLow2x2[i]!=0||fADCValuesHigh2x2[i]!=0) -// cout<< "2x2 Time Bin "<(maxn[1]),static_cast(maxn[2]),fnxnCrystalPhi,fnxnCrystalEta,geom) ; + GetCrystalPhiEtaIndexInModuleFromTRUIndex(itrun, + static_cast(maxn[1]), + static_cast(maxn[2]), + fnxnCrystalPhi,fnxnCrystalEta,geom) ; //Transform digit amplitude in Raw Samples fADCValuesHighnxn = new Int_t[nTimeBins]; fADCValuesLownxn = new Int_t[nTimeBins]; - phos->RawSampledResponse(maxtimeRn, fnxnMaxAmp, fADCValuesHighnxn, fADCValuesLownxn) ; + + pulse->SetAmplitude(maxtimeRn); + pulse->SetTZero(fnxnMaxAmp); + pulse->MakeSamples(); + pulse->GetSamples(fADCValuesHighnxn, fADCValuesLownxn) ; //Set Trigger Inputs, compare ADC time bins until threshold is attained //SetL1 Low @@ -459,11 +468,6 @@ void AliPHOSTrigger::SetTriggers(const Int_t iMod, const TMatrixD * ampmax2, con break; } } -// for(Int_t i = 0 ; i < 256 ; i++) -// if(fADCValuesLownxn[i]!=0||fADCValuesHighnxn[i]!=0) -// cout<< "nxn Time Bin "<