#include "TF1.h"
#include "TMath.h"
#include "TRandom.h"
#include "TVector.h"
#include "hades.h"
#include "hcategory.h"
#include "hdebug.h"
#include "hevent.h"
#include "heventheader.h"
#include "hgeantrich.h"
#include "hlinearcatiter.h"
#include "hmatrixcatiter.h"
#include "hparset.h"
#include "hrichanalysispar.h"
#include "hrichanalysissim.h"
#include "hrichcalpar.h"
#include "hrichcalparcell.h"
#include "hrichcalsim.h"
#include "hrichdetector.h"
#include "hrichdigitisationpar.h"
#include "hrichdigitizer.h"
#include "hrichgeometrypar.h"
#include "hrichpad.h"
#include "hrichpadfilter.h"
#include "hrichtrack.h"
#include "hrichwiresignal.h"
#include "hruntimedb.h"
#include "hspectrometer.h"
#include "richdef.h"
#include <iomanip>
#include <iostream>
#include <stdlib.h>
using namespace std;
ClassImp(HRichDigitizer)
HRichDigitizer::HRichDigitizer(const Text_t* name,
const Text_t* title,
Bool_t kNoise,
Float_t slope,
Bool_t oem) : HReconstructor(name, title)
{
setDefaults();
isOEM = oem;
isActiveNoise = kNoise;
fSlopeCorrection = slope;
}
HRichDigitizer::HRichDigitizer()
{
setDefaults();
}
void
HRichDigitizer::setDefaults()
{
catRichPhoton = NULL;
catRichDirect = NULL;
catTrack = NULL;
catCal = NULL;
iterRichPhoton = NULL;
iterRichDirect = NULL;
iterRichTrack = NULL;
iterRichCal = NULL;
pDigitisationPar = NULL;
pGeometryPar = NULL;
pCalPar = NULL;
ga = NULL;
isOEM = kFALSE;
isActiveNoise = kFALSE;
countFBphot = 0;
countNoisePad = 0;
fWiresNr = 0;
fWiresDist = 0.0;
distWirePads = 0.0;
fYShift = 0.0;
binsQE = 0;
fChargePerChannel = 0.0;
fChargeScaling = 1.0;
fElectronsNr = 0.0;
fFactor1 = 0.0;
fFactor1Sig = 0.0;
fFactor2 = 0.0;
fFactor2Sig = 0.0;
fIncreaseNoise = 1.0;
fParam1 = 0.0;
fParam2 = 0.0;
fQupper = 0.0;
fSigmaValue = 0.0;
fExpSlope .Set(6);
fExpSlope .Reset(0.0);
fSlopeCorrection = 1.0;
photlength .Set(18);
photlength .Reset(0.0);
photeffic .Set(18);
photeffic .Reset(0.0);
for (Int_t sec = 0; sec < 6; ++sec)
{
correction[sec].Set(18);
correction[sec].Reset(0.0);
}
noiseProb = 0.0;
for ( Int_t i = 0; i < 9; ++i )
fDigitPadMatrix[i] = 0.0;
for (Int_t i = 0; i < 9; ++i)
fDigitPadMatrix[i] = 0.0;
}
HRichDigitizer::~HRichDigitizer()
{
if ( iterRichPhoton )
{
delete iterRichPhoton;
iterRichPhoton = NULL;
}
if ( iterRichDirect )
{
delete iterRichDirect;
iterRichDirect = NULL;
}
if ( iterRichTrack )
{
delete iterRichTrack;
iterRichTrack = NULL;
}
if ( iterRichCal )
{
delete iterRichCal;
iterRichCal = NULL;
}
fChargeOnWireList.Delete();
fTrackNumberList.Delete();
if( ga ) {
delete ga;
ga = NULL;
}
}
Bool_t
HRichDigitizer::init()
{
HRichDetector* pRichDet = static_cast<HRichDetector*>(gHades->getSetup()
->getDetector("Rich"));
HRuntimeDb* rtdb = gHades->getRuntimeDb();
if ( kTRUE == isActiveNoise )
{
Info("init", "------------------------------------------------------");
Info("init", "RICH digitizer NOISE MODE is ON");
Info("init", "------------------------------------------------------");
}
else
{
Info("init", "------------------------------------------------------");
Info("init", "RICH digitizer NOISE is OFF");
Info("init", "------------------------------------------------------");
}
pCalPar = static_cast<HRichCalPar*>(rtdb->getContainer("RichCalPar"));
if ( NULL == pCalPar )
{
Error("init", "Initialization of calibration parameters failed, returning...");
return kFALSE;
}
pGeometryPar = static_cast<HRichGeometryPar*>(rtdb->getContainer("RichGeometryParameters"));
if (NULL == pGeometryPar )
{
pGeometryPar = new HRichGeometryPar;
rtdb->addContainer( pGeometryPar );
}
if ( NULL == pGeometryPar )
{
Error("init", "Initialization of geometry parameters failed, returning...");
return kFALSE;
}
pDigitisationPar = static_cast<HRichDigitisationPar*>(rtdb->getContainer("RichDigitisationParameters"));
if ( NULL == pDigitisationPar )
{
pDigitisationPar = new HRichDigitisationPar;
rtdb->addContainer( pDigitisationPar );
}
if ( NULL == pDigitisationPar )
{
Error("init", "Initialization of digitization parameters failed, returning...");
return kFALSE;
}
catRichPhoton = gHades->getCurrentEvent()->getCategory(catRichGeantRaw);
if ( NULL == catRichPhoton )
{
Error("init", "Initializatin of Cherenkov photon category failed, returning...");
return kFALSE;
}
iterRichPhoton = static_cast<HIterator*>(catRichPhoton->MakeIterator());
if ( NULL == iterRichPhoton )
{
Error("init", "Can not create catRichPhoton iterator, returning...");
return kFALSE;
}
catRichDirect = gHades->getCurrentEvent()->getCategory(catRichGeantRaw + 1);
if ( NULL == catRichDirect )
{
Error("init", "Initialization of geant category for direct hits failed, returning...");
return kFALSE;
}
iterRichDirect = static_cast<HIterator*>(catRichDirect->MakeIterator());
if ( NULL == iterRichDirect )
{
Error("init", "Can not create catRichDirect iterator, returning...");
return kFALSE;
}
catTrack = gHades->getCurrentEvent()->getCategory(catRichTrack);
if ( NULL == catTrack )
{
catTrack = pRichDet->buildCategory(catRichTrack);
if ( NULL == catTrack )
{
Error("init", "Can not build output category catRichTrack, returning...");
return kFALSE;
}
else
gHades->getCurrentEvent()->addCategory(catRichTrack, catTrack, "Rich");
}
iterRichTrack = static_cast<HIterator*>(catTrack->MakeIterator());
if ( NULL == iterRichTrack )
{
Error("init", "Can not create catRichTrack iterator, returning...");
return kFALSE;
}
catCal = gHades->getCurrentEvent()->getCategory(catRichCal);
if ( NULL == catCal)
{
catCal = pRichDet->buildMatrixCat("HRichCalSim",1);
if ( NULL == catCal )
{
Error("init", "Can not build output category catRichCalSim, returning...");
return kFALSE;
}
else gHades->getCurrentEvent()->addCategory(catRichCal, catCal, "Rich");
}
iterRichCal = static_cast<HIterator*>(catCal->MakeIterator());
if ( NULL == iterRichCal )
{
Error("init", "Can not create catRichCalSim iterator, returning...");
return kFALSE;
}
ga = new TF1("ga", "[0]*exp([1]*(x-[2])*(x-[2]))", -10, 10);
return kTRUE;
}
Bool_t
HRichDigitizer::reinit()
{
if ( NULL == pDigitisationPar || NULL == pGeometryPar )
{
Error("reinit", "One of the needed pointers is NULL, returning...");
return kFALSE;
}
pDigitisationPar->printParam();
fWiresNr = pGeometryPar->getWiresPar()->getWiresNr();
fWiresDist = pGeometryPar->getWiresPar()->getDistWire();
distWirePads = pGeometryPar->getDistanceWiresPads();
fYShift = pGeometryPar->getSectorShift();
fYShift = fYShift / cos(20. * TMath::DegToRad());
fChargePerChannel = pDigitisationPar->getChargePerChannel();
fChargeScaling = pDigitisationPar->getChargeScaling();
fElectronsNr = pDigitisationPar->getElectronsNr();
fFactor1 = pDigitisationPar->getFactor1();
fFactor1Sig = pDigitisationPar->getFactor1Sig();
fFactor2 = pDigitisationPar->getFactor2();
fFactor2Sig = pDigitisationPar->getFactor2Sig();
fIncreaseNoise = pDigitisationPar->getIncreaseNoise();
fParam1 = pDigitisationPar->getParameter1();
fParam2 = pDigitisationPar->getParameter2();
fQupper = pDigitisationPar->getQupper();
fSigmaValue = pDigitisationPar->getSigmaValue();
binsQE = pDigitisationPar->getQEBinsNr();
photlength.Set(binsQE, pDigitisationPar->getPhotonLenArray());
photeffic .Set(binsQE, pDigitisationPar->getPhotonEffArray());
fExpSlope .Set(6, pDigitisationPar->getExpSlope());
for (Int_t sec = 0; sec < 6; ++sec)
correction[sec].Set(binsQE, pDigitisationPar->getCorrectionParams(sec));
ga->SetRange(-10.0, 10.0);
ga->SetParameters( 1.0 / ((TMath::Sqrt(2. * TMath::Pi())) * fIncreaseNoise),
-1.0 / (2. * fIncreaseNoise * fIncreaseNoise));
noiseProb = 0.5 - ga->Integral(0.0, fSigmaValue);
return kTRUE;
}
Int_t
HRichDigitizer::execute()
{
HGeantRichPhoton* pCherenkovHit = NULL;
HGeantRichDirect* pDirectHit = NULL;
HRichCalSim* calsimobj = NULL;
HRichTrack* trackobj = NULL;
HRichPadFilter padFilter;
Bool_t wasReal = kFALSE;
Int_t temp = -1;
Int_t addPad = -1;
Int_t addTrack = -1;
Int_t indTrack1 = -1;
Int_t countTrackR = 0;
Int_t fCerNr = 0;
Int_t fDirNr = 0;
countNoisePad = 0;
fChargeOnWireList.Delete();
fTrackNumberList.Delete();
if ( NULL == pCalPar )
{
Error("execute", "Pointer to HRichCalPar is NULL, needed for THR, noise,... simulation!!!");
return kSkipEvent;
}
vector < Int_t > addr_Real(200,0);
addr_Real.clear();
if( gHades->getEmbeddingMode() > 0 )
{
HRichCalSim* cal = NULL;
iterRichCal->Reset();
while( (cal = static_cast<HRichCalSim*>(iterRichCal->Next())) )
{
addr_Real.push_back(cal->getAddress());
cal->setEventNr( gHades->getCurrentEvent()->getHeader()->getEventSeqNumber() );
cal->setEnergy(0);
Float_t dummy[2];
dummy[0] = gHades->getEmbeddingRealTrackId();
dummy[1] = 0;
TVector rTrack(1,2,dummy);
HLocation loc;
loc.set(3, cal->getSector(), cal->getRow(), cal->getCol());
updateTrack(cal, loc, &rTrack);
}
}
iterRichPhoton->Reset();
while( (pCherenkovHit = static_cast<HGeantRichPhoton*>(iterRichPhoton->Next())) )
{
++fCerNr;
if ( kTRUE == isOEM )
digitiseCherenkovHits(pCherenkovHit, fCerNr);
else digitiseCherenkovHits(pCherenkovHit, 0);
}
iterRichDirect->Reset();
while( (pDirectHit = static_cast<HGeantRichDirect*>(iterRichDirect->Next())) )
{
digitiseDirectHits(pDirectHit);
fDirNr++;
}
digitisePads();
catTrack->sort();
iterRichCal->Reset();
while( (calsimobj = static_cast<HRichCalSim*>(iterRichCal->Next())) )
{
wasReal = kFALSE;
if( find(addr_Real.begin(), addr_Real.end(), calsimobj->getAddress()) != addr_Real.end() )
{
wasReal = kTRUE;
}
if( kTRUE == isActiveNoise && kFALSE == wasReal && NULL != pCalPar )
{
addNoiseToCharge(calsimobj);
}
if ( NULL != pCalPar )
{
if( 0 == checkPad(calsimobj) && kFALSE == wasReal )
{
calsimobj->setCharge(0.);
}
}
temp = 0;
addPad = calsimobj->getAddress();
if( 0 != calsimobj->getNTrack1() )
calsimobj->setEnergy(calsimobj->getEnergy() / calsimobj->getNTrack1());
calsimobj->setNTrack1(0);
iterRichTrack->Reset();
while( (trackobj = static_cast<HRichTrack*>(iterRichTrack->Next())) )
{
addTrack = trackobj->getAddress();
if ( 0 != trackobj->getTrack() )
countTrackR++;
if ( addPad == addTrack )
{
indTrack1 = catTrack->getIndex(trackobj);
if ( temp != addPad )
{
calsimobj->setNTrack1(indTrack1);
calsimobj->setNTrack2(indTrack1);
}
else
{
calsimobj->setNTrack2(indTrack1);
}
temp = addTrack;
}
else if( 0 != temp ) break;
}
}
if ( kTRUE == isActiveNoise && gHades->getEmbeddingMode() == 0 && NULL != pCalPar )
makeNoiseOnPads();
catCal->filter(padFilter);
return 0;
}
Float_t
HRichDigitizer::GaussFun(const Float_t mean,
const Float_t sigma)
{
Double_t x = 0.0;
Double_t y = 0.0;
Double_t z = 0.0;
do {
y = gRandom->Rndm();
} while (!y);
z = gRandom->Rndm();
x = z * 2 * TMath::Pi();
return mean + sigma * static_cast<Float_t>(sin(x) * sqrt(-2.0 * log(y)));
}
Bool_t
HRichDigitizer::calcQE(const Float_t photlen,
const Int_t sec)
{
Int_t i = 0;
Float_t fDraw = 0.0;
if ( 100 == photlen )
return kTRUE;
fDraw = gRandom->Rndm();
for (i = 0; i < binsQE; ++i)
{
if ( i == 0 )
{
if ( photlen < ((photlength[i] + photlength[i+1]) / 2) ) {
if ( fSlopeCorrection * fDraw > photeffic[i] * correction[sec][i] ) { return kFALSE; }
else { return kTRUE;}
}
}
else if ( i == binsQE - 1 )
{
if ( photlen >= ((photlength[i-1] + photlength[i]) / 2) ) {
if ( fSlopeCorrection * fDraw > photeffic[i] * correction[sec][i]) { return kFALSE; }
else { return kTRUE; }
}
}
else if ( ((photlength[i-1] + photlength[i]) / 2) <= photlen &&
((photlength[i] + photlength[i+1]) / 2) > photlen)
{
if ( fSlopeCorrection * fDraw > photeffic[i] * correction[sec][i] ) { return kFALSE; }
else { return kTRUE; }
}
}
return kTRUE;
}
Int_t
HRichDigitizer::getWireNr(const Float_t xhit)
{
Int_t i = 0;
Int_t nWireNr = -1;
Float_t Xwir = 0.0;
for (i = 0; i < fWiresNr; ++i)
{
Xwir = pGeometryPar->getWiresPar()->getWire(i)->getXWire();
if ( (xhit >= Xwir - fWiresDist) && (xhit < Xwir + fWiresDist) )
{
nWireNr = i;
break;
}
}
return nWireNr;
}
Float_t
HRichDigitizer::calcChargeOnWire(const Int_t sector,
const Float_t xhit,
const Float_t yhit,
const Float_t nTrack,
const Float_t nFlag,
Float_t ene )
{
Bool_t endLoop = kFALSE;
Int_t fHitedWireNr = 0;
Float_t fX = 0.0;
Float_t fY = 0.0;
Float_t fQ = 0.0;
Float_t charge = 0.0;
HRichFrame* pFrame = NULL;
TVector* gTrack1 = NULL;
Float_t dummy[2];
if ( NULL == (pFrame = pGeometryPar->getFramePar()) )
{
Error("calcChargeOnWire", "Can not get RICH frame parameters");
return -1;
}
if ( -1 == ( fHitedWireNr = getWireNr(xhit)) ) return -1;
dummy[0] = nTrack;
dummy[1] = nFlag;
gTrack1 = new TVector(1, 2, dummy);
fX = pGeometryPar->getWiresPar()->getWire(fHitedWireNr)->getXWire();
fY = yhit;
while( kFALSE == endLoop )
{
charge = 1.0 / fExpSlope[sector] * log(gRandom->Rndm() * (exp(fExpSlope[sector] * fQupper) - 1.0) + 1.0);
if( charge <= fQupper ) endLoop = kTRUE;
}
fQ = charge * fChargePerChannel;
if ( ene == 100 )
{
ene = 0.;
}
if (fQ > 0. && kFALSE == pFrame->isOut(fX, fY) )
{
fChargeOnWireList.Add(new HRichWireSignal(sector, fHitedWireNr,
fQ, fX, fY, ene));
fTrackNumberList.Add(gTrack1);
} else {
delete gTrack1;
}
return fQ;
}
void
HRichDigitizer::digitiseCherenkovHits(HGeantRichPhoton *pCerHit,
const Int_t count)
{
Float_t xHitcm = (pCerHit->getX() / 10.0);
Float_t yHitcm = (pCerHit->getY() / 10.0 + fYShift);
countFBphot = 0;
if( 0 == count )
processPhoton(pCerHit->getEnergy(), xHitcm, yHitcm,
pCerHit->getTrack(), pCerHit->getSector());
else processPhoton(pCerHit->getEnergy(), xHitcm, yHitcm,
count, pCerHit->getSector());
}
void
HRichDigitizer::processPhoton(const Float_t ene,
const Float_t xPos,
const Float_t yPos,
const Int_t track,
const Int_t sector )
{
Float_t eneFeedBack = 0.0;
Float_t xHitcmFB = 0.0;
Float_t yHitcmFB = 0.0;
Float_t chargeOnWire = 0.0;
HRichFrame* pFrame = NULL;
if ( NULL == (pFrame = pGeometryPar->getFramePar()) )
{
Error("processPhoton", "Can not get RICH frame parameters");
return;
}
if ( kTRUE == calcQE(ene, sector) &&
kFALSE == pFrame->isOut(xPos, yPos) )
{
chargeOnWire = calcChargeOnWire(sector, xPos, yPos, track, 0, ene);
if( calcFeedBack(sector, xPos, yPos, eneFeedBack,
xHitcmFB, yHitcmFB, chargeOnWire) && countFBphot < 7 )
{
processPhoton(eneFeedBack,xHitcmFB,yHitcmFB,-5,sector);
}
}
}
Bool_t
HRichDigitizer::calcFeedBack(const Int_t sec,
const Float_t xhit,
const Float_t yhit,
Float_t &ene,
Float_t &xhittFB,
Float_t &yhittFB,
const Float_t charge )
{
countFBphot++;
Float_t thetaDir = 0.0;
Float_t phiDir = 0.0;
Float_t r = 0.0;
Float_t fDraw1 = 0.0;
Float_t fDraw2 = 0.0;
if( gRandom->Rndm() < (charge * 7.8e-6) )
{
fDraw1 = gRandom->Rndm();
fDraw2 = gRandom->Rndm();
thetaDir = fDraw1 * 90;
phiDir = fDraw1 * 360;
r = distWirePads * TMath::Tan(thetaDir * TMath::DegToRad());
xhittFB = xhit + r * TMath::Cos(phiDir * TMath::DegToRad());
yhittFB = yhit + r * TMath::Sin(phiDir * TMath::DegToRad());
if ( fDraw2 < 0.13 ) ene = 6.42;
else if ( fDraw2 < 0.43 ) ene = 7.94;
else ene = 7.46;
return kTRUE;
}
else
{
ene = 0;
xhittFB = 0;
yhittFB = 0;
return kFALSE;
}
}
void
HRichDigitizer::digitiseDirectHits(HGeantRichDirect *pDirHit)
{
Int_t i = 0;
Int_t fStepsNr = 0;
Int_t dTrack = -1;
Int_t dId = -1;
Float_t fStepLength = 0.0;
Float_t fNewX = 0.0;
Float_t fNewY = 0.0;
HRichFrame* pFrame = NULL;
Float_t xHitcm = pDirHit->getX() / 10.0F;
Float_t yHitcm = pDirHit->getY() / 10.0F + fYShift ;
if ( NULL == (pFrame = pGeometryPar->getFramePar()) )
{
Error("digitiseDirectHits", "Can not get RICH frame parameters");
return;
}
if ( pDirHit->getEnergyLoss() > 0.0F &&
kFALSE == pFrame->isOut(xHitcm, yHitcm) )
{
fStepsNr = static_cast<Int_t>(1+ fElectronsNr * 1000 * pDirHit->getEnergyLoss());
if ( fStepsNr > 5000 )
{
#ifdef HRICH_DEBUGMODE
Warning("digitiseDirectHits",
"Evt %d: number of maximum steps (5000) exceeded by %d!",
gHades->getCurrentEvent()->getHeader()->getEventSeqNumber(), fStepsNr);
#endif
fStepsNr = 5000;
}
fStepLength = pDirHit->getTrackLengthInPhotDet() / static_cast<Float_t>(fStepsNr);
for (i = 0; i < fStepsNr; ++i)
{
fNewX = xHitcm + (i + 1) * fStepLength *
sin(TMath::DegToRad() * pDirHit->getTheta()) * cos(TMath::DegToRad() * pDirHit->getPhi());
fNewY = yHitcm + (i + 1) * fStepLength *
sin(TMath::DegToRad() * pDirHit->getTheta()) * sin(TMath::DegToRad() * pDirHit->getPhi());
pDirHit->getTrack(dTrack, dId);
calcChargeOnWire(pDirHit->getSector(), fNewX, fNewY, dTrack, 1, 0);
}
}
}
HRichPad*
HRichDigitizer::translateCorners(HRichPad *pPad,
const Float_t dx,
const Float_t dy )
{
Int_t i;
HRichPad* fpTranslatedPad = new HRichPad(*pPad);
if ( NULL == fpTranslatedPad )
{
Error("translateCorners", "Can not get pointer to HRichPad");
return NULL;
}
for (i = 0; i < fpTranslatedPad->getCornersNr(); ++i)
{
fpTranslatedPad->getCorner(i)->setX(fpTranslatedPad->getCorner(i)->getX() - dx);
fpTranslatedPad->getCorner(i)->setY(fpTranslatedPad->getCorner(i)->getY() - dy);
}
fpTranslatedPad->setXmin(fpTranslatedPad->getXmin() - dx);
fpTranslatedPad->setYmin(fpTranslatedPad->getYmin() - dy);
fpTranslatedPad->setXmax(fpTranslatedPad->getXmax() - dx);
fpTranslatedPad->setYmax(fpTranslatedPad->getYmax() - dy);
return fpTranslatedPad;
}
void
HRichDigitizer::makeNoiseOnPads()
{
HRichCalSim* pCalSim = NULL;
HRichCalParCell* pCell = NULL;
const Int_t maxCols = pGeometryPar->getColumns();
const Int_t maxPads = pGeometryPar->getPadsNr();
Int_t nbNoisePads = 0;
Int_t padNr = 0;
Int_t iCol = 0;
Int_t iRow = 0;
Float_t fCharge = 0.0;
Float_t fSigmaPad = 0.0;
Float_t fMeanPad = 0.0;
Float_t fFloatMean = 0.0;
nbNoisePads = static_cast<Int_t>(TMath::Floor(4800 * noiseProb));
nbNoisePads = gRandom->Poisson(nbNoisePads) - static_cast<Int_t>(countNoisePad / 6.);
if ( nbNoisePads < 0 )
{
nbNoisePads = 0;
}
for ( Int_t sec = 0; sec < 6; ++sec )
{
if (pGeometryPar->getSectorActive(sec) > 0)
{
for(Int_t j = 0; j < nbNoisePads; ++j)
{
do
{
padNr = static_cast<Int_t>(TMath::Floor(maxPads * gRandom->Rndm()));
iRow = pGeometryPar->calcRow(padNr);
iCol = pGeometryPar->calcCol(padNr);
if ( padNr >= maxPads )
{
Error("makeNoiseOnPads", "Index %d out of bounds...", maxPads);
continue;
}
} while(!pGeometryPar->getPadsPar()->getPad(padNr)->getPadActive() && iCol < maxCols);
loc.set(3, sec, iRow, iCol);
pCell = static_cast<HRichCalParCell*>(pCalPar->getObject(loc));
if ( NULL != pCell )
{
fSigmaPad = pCell->getSigma();
}
else
{
Error("makeNoiseOnPads", "Did not get any valid HRichCalParCell...");
fSigmaPad = 0.0;
}
if ( fSigmaPad > 0.4 )
{
fMeanPad = pCell->getOffset();
fFloatMean = fMeanPad - (TMath::Floor(fMeanPad));
fCharge = calcNoiseOnPad(fSigmaPad, fFloatMean);
pCalSim = static_cast<HRichCalSim*>(catCal->getObject(loc));
if ( NULL == pCalSim && fCharge > 0 )
{
pCalSim = static_cast<HRichCalSim*>(catCal->getSlot(loc));
if ( NULL != pCalSim )
{
pCalSim = new(pCalSim) HRichCalSim;
pCalSim->setEventNr(gHades->getCurrentEvent()->getHeader()->getEventSeqNumber());
pCalSim->setSector(loc[0]);
pCalSim->setCol(loc[2]);
pCalSim->setRow(loc[1]);
pCalSim->setCharge(fCharge);
Float_t dummy[2];
dummy[0] = -1;
dummy[1] = 0;
TVector rTrack(1,2,dummy);
updateTrack(pCalSim, loc, &rTrack);
}
}
else j--;
}
else j--;
}
}
}
}
Float_t
HRichDigitizer::calcNoiseOnPad( const Float_t fSigmaPad,
const Float_t fFloatMean)
{
const Int_t cutLoop = 10;
const Int_t iThreshold = static_cast<Int_t>(fFloatMean + fSigmaValue * fSigmaPad);
Int_t count = 0;
Int_t chan = 0;
Float_t fCharge = 0.0;
if ( fSigmaValue < 2.0 )
return static_cast<Int_t>(TMath::Sqrt(2.) * fSigmaPad * fIncreaseNoise
* noiseCharge[0] + fFloatMean) - fFloatMean + gRandom->Rndm();
do
{
chan = static_cast<Int_t>( ((1. - 2. * noiseProb * gRandom->Rndm()) - 0.95) / (0.05 / 1000.));
if( chan >= 0 && chan < 1000 )
{
fCharge = TMath::Sqrt(2.) * fSigmaPad * fIncreaseNoise * noiseCharge[chan] + fFloatMean;
}
else fCharge = 0.;
count++;
} while ( (static_cast<Int_t>(fCharge) <= iThreshold || fCharge > 1000.) && count < cutLoop );
if ( (static_cast<Int_t>(fCharge) <= iThreshold || fCharge > 1000.) && count == cutLoop )
return 0.;
return static_cast<Int_t>(fCharge) - fFloatMean + gRandom->Rndm();
}
void
HRichDigitizer::addNoiseToCharge(HRichCalSim* calSim)
{
HRichCalParCell* pCell = NULL;
Float_t fCharge = 0.0;
Float_t fSigmaPad = 0.0;
loc.set(3, calSim->getSector(), calSim->getRow(), calSim->getCol());
pCell = static_cast<HRichCalParCell*>(pCalPar->getObject(loc));
if ( NULL != pCell )
{
fSigmaPad = pCell->getSigma();
}
else
{
Error("addNoiseToCharge", "Did not get any valid HRichCalParCell...");
fSigmaPad = 1.0;
}
fCharge = GaussFun(0, fSigmaPad * fIncreaseNoise);
if ( fCharge > fSigmaPad * fSigmaValue )
{
countNoisePad++;
}
calSim->addCharge(fCharge);
}
Int_t
HRichDigitizer::checkPad(HRichCalSim *calSim)
{
HRichCalParCell* pCell = NULL;
Float_t fCharge = calSim->getCharge();
Int_t iRow = calSim->getRow();
Int_t iCol = calSim->getCol();
Int_t iSec = calSim->getSector();
Int_t padNr = iCol + iRow * pGeometryPar->getColumns();
Int_t iCharge = 0;
Int_t iThreshold = 0;
Float_t fSigmaPad = 0.0;
Float_t fMeanPad = 0.0;
Float_t fFloatMean = 0.0;
loc.set(3, iSec, iRow, iCol);
pCell = static_cast<HRichCalParCell*>(pCalPar->getObject(loc));
if ( NULL != pCell )
{
fSigmaPad = pCell->getSigma();
fMeanPad = pCell->getOffset();
}
else
{
Error("checkPad", "Did not get any valid HRichCalParCell...");
Error("checkPad", "Is pad active??? %d", pGeometryPar->getPadsPar()->getPad(padNr)->getPadActive());
fSigmaPad = 1.0;
}
if ( 0 == fSigmaPad && 0 == fMeanPad )
{
return 0;
}
fFloatMean = fMeanPad - static_cast<Int_t>(fMeanPad);
fCharge += fFloatMean;
iCharge = static_cast<Int_t>(fCharge);
iThreshold = static_cast<Int_t>(fFloatMean + fSigmaValue * fSigmaPad);
if( iCharge > iThreshold )
{
fCharge = iCharge - fFloatMean + gRandom->Rndm();
calSim->setCharge(fCharge);
return iCharge;
}
else return 0;
}
void
HRichDigitizer::digitisePads()
{
Int_t xcenter = 0;
Int_t ycenter = 0;
Int_t sector = -1;
Int_t iPadInd = 0;
Float_t energyPhot = 0.0;
Float_t yRel = 0.0;
Float_t charge4 = 0.0;
Float_t param11 = 0.0;
Float_t param21 = 0.0;
HRichPadTab* pPadsPar = NULL;
HRichPad* pPad = NULL;
HRichPad* pTmpPad = NULL;
TVector* nTrackTemp = NULL;
HRichWireSignal* pCharge = NULL;
if ( NULL == (pPadsPar = pGeometryPar->getPadsPar()) )
{
Error("digitisePads", "Can not get RICH pad parameters");
return;
}
for ( Int_t i = 0; i < fChargeOnWireList.GetSize(); ++i)
{
for ( Int_t j = 0; j < 9; ++j )
fDigitPadMatrix[j] = 0.;
pCharge = static_cast<HRichWireSignal*>(fChargeOnWireList.At(i));
nTrackTemp = static_cast<TVector*>(fTrackNumberList.At(i));
energyPhot = pCharge->getEnergy();
sector = pCharge->getSector();
pPad = pPadsPar->getPad(pCharge->getX(), pCharge->getY());
xcenter = pPad->getPadX();
ycenter = pPad->getPadY();
yRel = TMath::Abs((pCharge->getY() - pPad->getYmin()) / (pPad->getYmax() - pPad->getYmin()));
pTmpPad = translateCorners(pPad, pCharge->getX(), pCharge->getY());
charge4 = 0.;
if ( 2 == pTmpPad->getPadFlag() )
{
param11 = gRandom->Landau(fFactor1, fFactor1Sig);
param21 = GaussFun(fFactor2, fFactor2Sig);
if( param21 < 0. )
param21 = 0.;
charge4 = q4Calc(pCharge->getCharge(), yRel, param11, param21);
if (charge4 < 0.) fDigitPadMatrix[4] = 0.;
else
{
updateCharge(sector, pPad, charge4, nTrackTemp, energyPhot);
fDigitPadMatrix[4] = charge4;
}
}
iPadInd = 0;
for ( Int_t n = -1; n < 2; ++n )
{
for ( Int_t m = -1; m < 2; ++m)
{
if(m != 0 || n != 0 )
{
if ( pPadsPar->getPad(xcenter+m, ycenter+n) &&
pPadsPar->getPad(xcenter+m, ycenter+n)->getPadActive() )
{
delete pTmpPad;
pTmpPad = translateCorners(pPadsPar->getPad(xcenter + m, ycenter + n),
pCharge->getX(), pCharge->getY());
if ( 2 == pTmpPad->getPadFlag() )
{
fDigitPadMatrix[iPadInd] = calcIndCharge(yRel, fDigitPadMatrix[4],
iPadInd, pCharge->getWireNr(),
param11, param21);
if ( fDigitPadMatrix[iPadInd] <= 0. )
fDigitPadMatrix[iPadInd] = 0.;
else
updateCharge(sector, pTmpPad, fDigitPadMatrix[iPadInd], nTrackTemp, energyPhot);
}
}
}
iPadInd ++;
}
}
delete pTmpPad;
}
}
Float_t
HRichDigitizer::calcIndCharge(const Float_t yCharge,
const Float_t q4,
const Int_t iPdaIndex,
const Int_t iWireNr,
const Float_t param11,
const Float_t param21 )
{
switch(iPdaIndex)
{
case 1:
return ( qX(1 - yCharge) * q4);
case 7:
return ( qX(yCharge) * q4 );
case 3:
{
if ( iWireNr % 2 == 0) return (param21 * q4);
else return (param11 * q4);
}
case 5:
{
if( iWireNr % 2 == 0 ) return ( param11 * q4 );
else return ( param21* q4 );
}
case 2:
{
if( iWireNr % 2 == 0 ) return ( 1.37 * param11 * q4 * qX(1 - yCharge));
else return ( 1.37 * param21 * q4 * qX(1 - yCharge));
}
case 8:
{
if( iWireNr % 2 == 0) return ( 1.37 * param11 * q4 * qX(yCharge) );
else return ( 1.37 * param21 * q4 * qX(yCharge) );
}
case 6:
{
if( iWireNr % 2 == 0) return ( 1.37 * param21 * q4 * qX(yCharge) );
else return ( 1.37 * param11 * q4 * qX(yCharge) );
}
case 0:
{
if( iWireNr % 2 == 0) return ( 1.37 * param21 * q4 * qX(1 - yCharge));
else return ( 1.37 * param11 * q4 * qX(1 - yCharge) );
}
}
return 0;
}
Float_t
HRichDigitizer::qX(const Float_t pos)
{
Float_t charge = 0.0;
Float_t q0 = -0.03;
Float_t integral = 0.0;
integral = 1.0 / (fParam1 * fParam1 * q0 + fParam1*fParam2) -
1.0 / (fParam1 * fParam1 + fParam1 * fParam2);
charge = ( (q0 + fParam2 / fParam1) / (1.0 - (q0 + fParam2 / fParam1)
* fParam1 * fParam1 * integral * pos) )
- fParam2 / fParam1;
if (charge < 0.) charge = 0.;
return charge;
}
Float_t
HRichDigitizer::q4Calc(const Float_t charge,
const Float_t pos,
const Float_t par1,
const Float_t par2 )
{
Float_t gX = 1 + qX(pos) + qX(1 - pos);
Float_t gX1 = 1 + 1.37 * qX(pos) + 1.37 * qX(1 - pos);
if( 0 != gX )
return charge / ((par1 + par2) * gX1 + gX);
else return 0.0;
}
void
HRichDigitizer::updateCharge(const Int_t sector,
HRichPad* pPad,
const Float_t charge,
TVector* rTrack,
const Float_t ene )
{
HLocation locat;
Int_t fCol = 0;
Int_t fRow = 0;
HRichCalSim* pCalSim = NULL;
pPad->getPadXY(&fCol, &fRow);
locat.set(3, sector, fRow, fCol);
pCalSim = static_cast<HRichCalSim*>(catCal->getObject(locat));
if ( NULL == pCalSim )
{
pCalSim = static_cast<HRichCalSim*>(catCal->getSlot(locat));
if ( NULL != pCalSim )
{
pCalSim = new(pCalSim) HRichCalSim;
pCalSim->setEventNr(gHades->getCurrentEvent()->getHeader()->getEventSeqNumber());
pCalSim->setSector(locat[0]);
pCalSim->setCol(locat[2]);
pCalSim->setRow(locat[1]);
updateTrack(pCalSim, locat, rTrack);
}
}
if ( NULL != pCalSim )
{
pCalSim->addCharge(charge * fChargeScaling / fChargePerChannel);
if ( pCalSim->getCharge() > 800.0 )
pCalSim->setCharge(800.0);
if(ene>0)
{
pCalSim->addHit();
pCalSim->addEnergy(ene);
}
updateTrack(pCalSim,locat,rTrack);
}
}
void
HRichDigitizer::updateTrack(HRichCalSim* pCal,
HLocation& loc,
TVector* rTrack )
{
HRichTrack *pRichTrack = NULL;
Int_t Ad = pCal->getAddress();
iterRichTrack->Reset();
while( NULL != (pRichTrack = static_cast<HRichTrack*>(iterRichTrack->Next())) )
{
if ( (pRichTrack->getTrack() == (*rTrack)(1)) &&
pRichTrack->getFlag() == (*rTrack)(2) &&
pRichTrack->getAddress() == Ad ) return;
}
HLocation loc1;
loc1.set(1,0);
pRichTrack = static_cast<HRichTrack*>(catTrack->getNewSlot(loc1));
if ( NULL != pRichTrack )
{
pRichTrack = new (pRichTrack) HRichTrack;
pRichTrack->setEventNr(pCal->getEventNr());
pRichTrack->setTrack((Int_t)((*rTrack)(1)));
pRichTrack->setFlag((Int_t)((*rTrack)(2)));
pRichTrack->setAddress(Ad);
}
}
Bool_t
HRichDigitizer::finalize()
{
return kTRUE;
}
const Float_t HRichDigitizer::noiseCharge[] = {1.3859,1.38621,1.38651,1.38681,1.38712,1.38742,
1.38772,1.38803,1.38833,1.38864,1.38894,1.38925,1.38955,1.38986,1.39016,
1.39047,1.39078,1.39108,1.39139,1.3917,1.392,1.39231,1.39262,1.39293,
1.39324,1.39355,1.39386,1.39416,1.39447,1.39478,1.39509,1.3954,1.39572,
1.39603,1.39634,1.39665,1.39696,1.39727,1.39759,1.3979,1.39821,1.39852,
1.39884,1.39915,1.39946,1.39978,1.40009,1.40041,1.40072,1.40104,1.40135,
1.40167,1.40199,1.4023,1.40262,1.40294,1.40325,1.40357,1.40389,1.40421,
1.40453,1.40485,1.40516,1.40548,1.4058,1.40612,1.40644,1.40676,1.40708,
1.40741,1.40773,1.40805,1.40837,1.40869,1.40901,1.40934,1.40966,1.40998,
1.41031,1.41063,1.41096,1.41128,1.41161,1.41193,1.41226,1.41258,1.41291,
1.41323,1.41356,1.41389,1.41422,1.41454,1.41487,1.4152,1.41553,1.41586,
1.41619,1.41651,1.41684,1.41717,1.4175,1.41784,1.41817,1.4185,1.41883,
1.41916,1.41949,1.41983,1.42016,1.42049,1.42083,1.42116,1.42149,1.42183,
1.42216,1.4225,1.42283,1.42317,1.4235,1.42384,1.42418,1.42451,1.42485,
1.42519,1.42553,1.42587,1.4262,1.42654,1.42688,1.42722,1.42756,1.4279,
1.42824,1.42858,1.42892,1.42927,1.42961,1.42995,1.43029,1.43064,1.43098,
1.43132,1.43167,1.43201,1.43236,1.4327,1.43305,1.43339,1.43374,1.43408,
1.43443,1.43478,1.43512,1.43547,1.43582,1.43617,1.43652,1.43687,1.43722,
1.43757,1.43792,1.43827,1.43862,1.43897,1.43932,1.43967,1.44002,1.44038,
1.44073,1.44108,1.44144,1.44179,1.44215,1.4425,1.44286,1.44321,1.44357,
1.44392,1.44428,1.44464,1.44499,1.44535,1.44571,1.44607,1.44643,1.44679,
1.44715,1.44751,1.44787,1.44823,1.44859,1.44895,1.44931,1.44967,1.45004,
1.4504,1.45076,1.45113,1.45149,1.45185,1.45222,1.45259,1.45295,1.45332,
1.45368,1.45405,1.45442,1.45479,1.45515,1.45552,1.45589,1.45626,1.45663,
1.457,1.45737,1.45774,1.45811,1.45848,1.45886,1.45923,1.4596,1.45997,
1.46035,1.46072,1.4611,1.46147,1.46185,1.46222,1.4626,1.46297,1.46335,
1.46373,1.46411,1.46448,1.46486,1.46524,1.46562,1.466,1.46638,1.46676,
1.46714,1.46753,1.46791,1.46829,1.46867,1.46906,1.46944,1.46982,1.47021,
1.47059,1.47098,1.47136,1.47175,1.47214,1.47253,1.47291,1.4733,1.47369,
1.47408,1.47447,1.47486,1.47525,1.47564,1.47603,1.47642,1.47681,1.47721,
1.4776,1.47799,1.47839,1.47878,1.47918,1.47957,1.47997,1.48036,1.48076,
1.48116,1.48156,1.48195,1.48235,1.48275,1.48315,1.48355,1.48395,1.48435,
1.48475,1.48516,1.48556,1.48596,1.48636,1.48677,1.48717,1.48758,1.48798,
1.48839,1.4888,1.4892,1.48961,1.49002,1.49043,1.49083,1.49124,1.49165,
1.49206,1.49247,1.49289,1.4933,1.49371,1.49412,1.49454,1.49495,1.49536,
1.49578,1.49619,1.49661,1.49703,1.49744,1.49786,1.49828,1.4987,1.49912,
1.49954,1.49996,1.50038,1.5008,1.50122,1.50164,1.50207,1.50249,1.50291,
1.50334,1.50376,1.50419,1.50461,1.50504,1.50547,1.50589,1.50632,1.50675,
1.50718,1.50761,1.50804,1.50847,1.5089,1.50934,1.50977,1.5102,1.51064,
1.51107,1.5115,1.51194,1.51238,1.51281,1.51325,1.51369,1.51413,1.51457,
1.51501,1.51545,1.51589,1.51633,1.51677,1.51721,1.51765,1.5181,1.51854,
1.51899,1.51943,1.51988,1.52033,1.52077,1.52122,1.52167,1.52212,1.52257,
1.52302,1.52347,1.52392,1.52437,1.52483,1.52528,1.52573,1.52619,1.52665,
1.5271,1.52756,1.52802,1.52847,1.52893,1.52939,1.52985,1.53031,1.53077,
1.53123,1.5317,1.53216,1.53262,1.53309,1.53355,1.53402,1.53449,1.53495,
1.53542,1.53589,1.53636,1.53683,1.5373,1.53777,1.53824,1.53871,1.53919,
1.53966,1.54014,1.54061,1.54109,1.54156,1.54204,1.54252,1.543,1.54348,
1.54396,1.54444,1.54492,1.5454,1.54589,1.54637,1.54685,1.54734,1.54783,
1.54831,1.5488,1.54929,1.54978,1.55027,1.55076,1.55125,1.55174,1.55223,
1.55273,1.55322,1.55372,1.55421,1.55471,1.55521,1.5557,1.5562,1.5567,
1.5572,1.5577,1.55821,1.55871,1.55921,1.55972,1.56022,1.56073,1.56123,
1.56174,1.56225,1.56276,1.56327,1.56378,1.56429,1.5648,1.56532,1.56583,
1.56635,1.56686,1.56738,1.56789,1.56841,1.56893,1.56945,1.56997,1.57049,
1.57102,1.57154,1.57206,1.57259,1.57312,1.57364,1.57417,1.5747,1.57523,
1.57576,1.57629,1.57682,1.57735,1.57789,1.57842,1.57896,1.57949,1.58003,
1.58057,1.58111,1.58165,1.58219,1.58273,1.58328,1.58382,1.58437,1.58491,
1.58546,1.58601,1.58655,1.5871,1.58765,1.58821,1.58876,1.58931,1.58987,
1.59042,1.59098,1.59154,1.59209,1.59265,1.59321,1.59378,1.59434,1.5949,
1.59547,1.59603,1.5966,1.59717,1.59773,1.5983,1.59887,1.59945,1.60002,
1.60059,1.60117,1.60174,1.60232,1.6029,1.60348,1.60406,1.60464,1.60522,
1.6058,1.60639,1.60697,1.60756,1.60815,1.60874,1.60933,1.60992,1.61051,
1.6111,1.6117,1.6123,1.61289,1.61349,1.61409,1.61469,1.61529,1.61589,
1.6165,1.6171,1.61771,1.61832,1.61892,1.61953,1.62015,1.62076,1.62137,
1.62199,1.6226,1.62322,1.62384,1.62446,1.62508,1.6257,1.62632,1.62695,
1.62757,1.6282,1.62883,1.62946,1.63009,1.63072,1.63136,1.63199,1.63263,
1.63327,1.6339,1.63454,1.63519,1.63583,1.63647,1.63712,1.63777,1.63841,
1.63906,1.63972,1.64037,1.64102,1.64168,1.64233,1.64299,1.64365,1.64431,
1.64498,1.64564,1.64631,1.64697,1.64764,1.64831,1.64898,1.64966,1.65033,
1.65101,1.65168,1.65236,1.65304,1.65372,1.65441,1.65509,1.65578,1.65647,
1.65716,1.65785,1.65854,1.65924,1.65993,1.66063,1.66133,1.66203,1.66273,
1.66344,1.66414,1.66485,1.66556,1.66627,1.66698,1.6677,1.66841,1.66913,
1.66985,1.67057,1.67129,1.67202,1.67274,1.67347,1.6742,1.67493,1.67567,
1.6764,1.67714,1.67788,1.67862,1.67936,1.68011,1.68085,1.6816,1.68235,
1.6831,1.68386,1.68461,1.68537,1.68613,1.68689,1.68766,1.68842,1.68919,
1.68996,1.69073,1.69151,1.69228,1.69306,1.69384,1.69462,1.6954,1.69619,
1.69698,1.69777,1.69856,1.69936,1.70015,1.70095,1.70175,1.70256,1.70336,
1.70417,1.70498,1.70579,1.7066,1.70742,1.70824,1.70906,1.70988,1.71071,
1.71154,1.71237,1.7132,1.71404,1.71487,1.71571,1.71656,1.7174,1.71825,
1.7191,1.71995,1.72081,1.72166,1.72252,1.72339,1.72425,1.72512,1.72599,
1.72686,1.72774,1.72862,1.7295,1.73038,1.73127,1.73216,1.73305,1.73394,
1.73484,1.73574,1.73664,1.73755,1.73846,1.73937,1.74028,1.7412,1.74212,
1.74304,1.74397,1.7449,1.74583,1.74677,1.7477,1.74865,1.74959,1.75054,
1.75149,1.75244,1.7534,1.75436,1.75532,1.75629,1.75726,1.75823,1.75921,
1.76019,1.76117,1.76216,1.76315,1.76415,1.76514,1.76614,1.76715,1.76816,
1.76917,1.77018,1.7712,1.77223,1.77325,1.77428,1.77532,1.77635,1.7774,
1.77844,1.77949,1.78054,1.7816,1.78266,1.78373,1.7848,1.78587,1.78695,
1.78803,1.78912,1.79021,1.7913,1.7924,1.7935,1.79461,1.79572,1.79684,
1.79796,1.79909,1.80022,1.80135,1.80249,1.80363,1.80478,1.80594,1.80709,
1.80826,1.80942,1.8106,1.81178,1.81296,1.81415,1.81534,1.81654,1.81774,
1.81895,1.82017,1.82139,1.82261,1.82384,1.82508,1.82632,1.82757,1.82882,
1.83008,1.83135,1.83262,1.83389,1.83518,1.83646,1.83776,1.83906,1.84037,
1.84168,1.843,1.84433,1.84566,1.847,1.84835,1.8497,1.85106,1.85243,
1.8538,1.85518,1.85657,1.85796,1.85937,1.86078,1.86219,1.86362,1.86505,
1.86649,1.86794,1.86939,1.87086,1.87233,1.87381,1.8753,1.87679,1.8783,
1.87981,1.88133,1.88286,1.8844,1.88595,1.88751,1.88908,1.89065,1.89224,
1.89383,1.89544,1.89705,1.89868,1.90031,1.90196,1.90361,1.90528,1.90696,
1.90864,1.91034,1.91205,1.91377,1.9155,1.91725,1.919,1.92077,1.92255,
1.92434,1.92615,1.92796,1.92979,1.93163,1.93349,1.93536,1.93724,1.93914,
1.94105,1.94297,1.94491,1.94687,1.94884,1.95082,1.95282,1.95484,1.95687,
1.95892,1.96098,1.96306,1.96516,1.96728,1.96941,1.97156,1.97373,1.97592,
1.97813,1.98036,1.98261,1.98487,1.98716,1.98947,1.9918,1.99415,1.99653,
1.99892,2.00135,2.00379,2.00626,2.00875,2.01127,2.01381,2.01638,2.01898,
2.02161,2.02426,2.02694,2.02965,2.0324,2.03517,2.03797,2.04081,2.04368,
2.04658,2.04952,2.0525,2.05551,2.05856,2.06164,2.06477,2.06794,2.07115,
2.0744,2.0777,2.08105,2.08444,2.08788,2.09137,2.09491,2.09851,2.10216,
2.10587,2.10963,2.11346,2.11735,2.1213,2.12533,2.12942,2.13358,2.13783,
2.14214,2.14654,2.15103,2.1556,2.16027,2.16503,2.16989,2.17486,2.17993,
2.18512,2.19044,2.19587,2.20144,2.20716,2.21301,2.21903,2.22521,2.23156,
2.2381,2.24484,2.25179,2.25896,2.26637,2.27404,2.28199,2.29023,2.2988,
2.30773,2.31703,2.32675,2.33694,2.34763,2.35889,2.37078,2.38339,2.39679,
2.41112,2.42652,2.44316,2.46127,2.48115,2.50322,2.52803,2.5564,2.58961,
2.62974,2.68069,2.75106,2.86776};
Last change: Sat May 22 13:08:41 2010
Last generated: 2010-05-22 13:08
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.