// ESAF : Euso Simulation and Analysis Framework
// $Id: ScanPhotonsOnPupil.cc,v 1.11 2005/02/13 12:58:19 thea Exp $
// A.Thea, J.Watts created Mar, 18 2004
#include "ScanPhotonsOnPupil.hh"
#include "OpticsFactory.hh"
#include "OpticalSystem.hh"
#include "NumbersFileParser.hh"
#include "TMath.h"
ClassImp(ScanPhotonsOnPupil)
//______________________________________________________________________________
ScanPhotonsOnPupil::ScanPhotonsOnPupil(): fCurRow(0), fCurCol(0),
//
// Constructor
//
fCurPosId(0), fCurAngle(0), fCurWl(0){
fOptics = OpticsFactory::Get()->GetOpticalSystem();
fXYStep = Conf()->GetNum("ScanPhotonsOnPupil.fXYStep")*mm;
Int_t thNum = (Int_t)Conf()->GetNum("ScanPhotonsOnPupil.fNumThetaFOV");
Double_t thStep = Conf()->GetNum("ScanPhotonsOnPupil.fThetaFOVStep");
for ( Int_t k(0); k<thNum; k++)
fAngles.push_back( TMath::DegToRad()*thStep*k );
// calculate the entrance disc size using the last element in fAngles
fEntranceDiscRadius = fOptics->Radius()+
TMath::Tan(fAngles.back())*
(fOptics->FirstLensTop()-fOptics->FirstLensBottom());
fNumPos = 0;
fNumRows = (Int_t)TMath::Floor(fEntranceDiscRadius/fXYStep)*2+1;
Float_t ymax = TMath::Floor(fEntranceDiscRadius/fXYStep)*fXYStep;
for (Int_t i(0); i<fNumRows; i++){
Float_t y=ymax-i*fXYStep;
Float_t x=TMath::Sqrt(fEntranceDiscRadius*fEntranceDiscRadius-y*y);
Int_t cols = (Int_t)TMath::Ceil(x/fXYStep);
fNumCols.push_back(cols);
fNumPos+=cols;
}
// load wavelengths
string s = Conf()->GetStr("ScanPhotonsOnPupil.fWavelenghtsFile");
NumbersFileParser wls( s, 1 );
vector<Double_t> dummy = wls.GetCol(0);
if ( dummy.size() == 0 )
throw runtime_error("ScanPhotonsOnPupil: "+s+" is empty");
for( size_t i(0); i<dummy.size(); i++)
fWavelengths.push_back(dummy[i]*nm);
cout << fWavelengths.size() << " wl read" << endl;
}
//______________________________________________________________________________
ScanPhotonsOnPupil::~ScanPhotonsOnPupil() {
//
// Destructor
//
}
//______________________________________________________________________________
Photon *ScanPhotonsOnPupil::Get() {
//
// Returns a photon at the current position and then steps over.
//
if ( fCurRow >= fNumRows ) return NULL;
if ( fCurCol >= fNumCols[fCurRow] ) {
if ( fCurRow == fNumRows-1) return NULL;
fCurCol=0;
fCurRow++;
}
ResetPhoton(GetX(), GetY(), fAngles[fCurAngle], fWavelengths[fCurWl]);
fCurCol++;
fCurPosId++;
return &(fParent.GetPhoton());
}
//______________________________________________________________________________
void ScanPhotonsOnPupil::ResetPhoton( Double_t x, Double_t y, Double_t th, Double_t wl ){
// reset the parent photon into a new position
Double_t s_pos[3]={0,0,0};
Double_t p_pos[3]={x,y,fOptics->FirstLensBottom()};
fParent.Build(1,s_pos, p_pos, th, TMath::PiOver2(), wl, 0, Fluorescence);
}
//______________________________________________________________________________
Int_t ScanPhotonsOnPupil::GetNumCols(Int_t r) {
// return the number of columns of the r-th row
if ( r < 0 || r>= fNumRows)
throw runtime_error("ScanPhotonsOnPuil: index out of bounds");
return fNumCols[r];
}
//______________________________________________________________________________
void ScanPhotonsOnPupil::NextAngle() {
// switch to the next angle in the list
fCurAngle++;
ResetPos();
}
//______________________________________________________________________________
Bool_t ScanPhotonsOnPupil::IsAngleEnd() const {
// true if all the angles have been scanned
return (fCurAngle >= GetNumAngles());
}
//______________________________________________________________________________
void ScanPhotonsOnPupil::NextWl() {
// switch to the next wavelength in the list
fCurWl++;
ResetPos();
ResetAngle();
}
//______________________________________________________________________________
Bool_t ScanPhotonsOnPupil::IsWlEnd() const {
// true if all the wavelengths have been scanned
return (fCurWl >= GetNumWavelengths());
}