////////////////////////////////////////////////////////////////////
/// \file PlotPMTResponse.cc
///
/// \brief Functions to select and plot MCPhoton features
///
/// \author P G Jones
///
/// REVISION HISTORY:\n
/// 2014-05-26: P. Jones - First Revision.\n
///
/// \details Functions to plot the PMT response.
///
////////////////////////////////////////////////////////////////////
#include
using CLHEP::pi; using CLHEP::twopi; using CLHEP::halfpi;
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
/// Plot the photoelectron and reflection responses
///
/// The photoelectron response is the number of photoelectrons/number of hits per bin.
/// The reflection response is the number of reflected photons/number of hits per bin.
///
/// @param[in] fileName of the RAT::DS root file to analyse
/// @return the histogram plot
TH1D* PlotAngularResponse( const string& fileName )
{
gStyle->SetOptStat(111111); // to show overflow / underflow stats
TH1D* hResponse = new TH1D( "hResponse", "PMT Response as function of angle", 90, 0.0, 90.0 );
TH1D* hReflected = new TH1D( "hReflected", "PMT Response as function of angle", 90, 0.0, 90.0 );
TH1D* hHits = new TH1D( "hHits", "PMT hits as function of angle", 90, 0.0, 90.0 );
// If this is being done on data that does not require remote database connection
// eg.: a simple simulation with default run number (0)
// We can disable the remote connections:
//
// NOTE: Don't do this if you are using real data!!!
RAT::DB::Get()->SetAirplaneModeStatus(true);
RAT::DU::DSReader dsReader( fileName );
for( size_t iEntry = 0; iEntry < dsReader.GetEntryCount(); iEntry++ )
{
const RAT::DS::Entry& rDS = dsReader.GetEntry( iEntry );
const RAT::DS::MC& mc = rDS.GetMC();
for( size_t iPMT = 0; iPMT < mc.GetMCPMTCount(); iPMT++ )
{
const RAT::DS::MCPMT& mcPMT = mc.GetMCPMT( iPMT );
const TVector3 pmtDirection = TVector3( 0.0, 0.0, -1.0 );
for( size_t iPhoton = 0; iPhoton < mcPMT.GetMCPhotonCount(); iPhoton++ )
{
const RAT::DS::MCPhoton& mcPhoton = mcPMT.GetMCPhoton( iPhoton );
const double xyRadius = sqrt( mcPhoton.GetInPosition().X() * mcPhoton.GetInPosition().X() + mcPhoton.GetInPosition().Y() * mcPhoton.GetInPosition().Y() );
if( mcPhoton.GetInPosition().Z() < 132.0 || xyRadius > 137.0 )
continue;
const double angle = TMath::ACos( mcPhoton.GetInDirection().Dot( pmtDirection ) ) * TMath::RadToDeg();
hHits->Fill( angle );
if( mcPhoton.GetFate() == RAT::DS::MCPhoton::ePhotoelectron )
hResponse->Fill( angle );
else if( mcPhoton.GetFate() == RAT::DS::MCPhoton::eReflected )
hReflected->Fill( angle );
}
}
}
hResponse->Sumw2();
hHits->Sumw2();
hReflected->Sumw2();
hResponse->Divide( hHits );
hResponse->Draw("E");
hReflected->Divide( hHits );
hReflected->SetLineColor( kRed );
//hReflected->Draw("SAMEE");
TLegend* t1 = new TLegend( 0.7, 0.7, 0.88, 0.88 );
t1->AddEntry( hResponse, "Signal", "l" );
//t1->AddEntry( hReflected, "Reflection", "l" );
t1->SetLineColor( kWhite );
t1->SetFillColor( kWhite );
t1->Draw();
return hResponse;
}
/// Plot the photoelectron and reflection responses
///
/// The photoelectron response is the number of photoelectrons/number of hits per bin.
/// The reflection response is the number of reflected photons/number of hits per bin.
///
/// @param[in] fileName of the RAT::DS root file to analyse
/// @return the histogram plot
TH1D* PlotPositionResponse( const string& fileName )
{
gStyle->SetOptStat(111111); // to show overflow / underflow stats
TH1D* hResponse = new TH1D( "hResponse", "PMT Response as function of position", 200, 0.0, 200.0 );
TH1D* hReflected = new TH1D( "hReflected", "PMT Response as function of position", 200, 0.0, 200.0 );
TH1D* hHits = new TH1D( "hHits", "PMT hits as function of position", 200, 0.0, 200.0 );
// If this is being done on data that does not require remote database connection
// eg.: a simple simulation with default run number (0)
// We can disable the remote connections:
//
// NOTE: Don't do this if you are using real data!!!
RAT::DB::Get()->SetAirplaneModeStatus(true);
RAT::DU::DSReader dsReader( fileName );
for( size_t iEntry = 0; iEntry < dsReader.GetEntryCount(); iEntry++ )
{
const RAT::DS::Entry& rDS = dsReader.GetEntry( iEntry );
const RAT::DS::MC& mc = rDS.GetMC();
for( size_t iPMT = 0; iPMT < mc.GetMCPMTCount(); iPMT++ )
{
const RAT::DS::MCPMT& mcPMT = mc.GetMCPMT( iPMT );
const TVector3 pmtDirection = TVector3( 0.0, 0.0, -1.0 );
for( size_t iPhoton = 0; iPhoton < mcPMT.GetMCPhotonCount(); iPhoton++ )
{
const RAT::DS::MCPhoton& mcPhoton = mcPMT.GetMCPhoton( iPhoton );
if( mcPhoton.GetInPosition().Z() < 132.0 )
continue;
const double xyRadius = sqrt( mcPhoton.GetInPosition().X() * mcPhoton.GetInPosition().X() + mcPhoton.GetInPosition().Y() * mcPhoton.GetInPosition().Y() );
hHits->Fill( xyRadius );
if( mcPhoton.GetFate() == RAT::DS::MCPhoton::ePhotoelectron )
hResponse->Fill( xyRadius );
else if( mcPhoton.GetFate() == RAT::DS::MCPhoton::eReflected )
hReflected->Fill( xyRadius );
}
}
}
hResponse->Sumw2();
hHits->Sumw2();
hReflected->Sumw2();
hResponse->Divide( hHits );
hResponse->Draw("E");
hReflected->Divide( hHits );
hReflected->SetLineColor( kRed );
hReflected->Draw("SAMEE");
TLegend* t1 = new TLegend( 0.7, 0.7, 0.88, 0.88 );
t1->AddEntry( hResponse, "Signal", "l" );
t1->AddEntry( hReflected, "Reflection", "l" );
t1->SetLineColor( kWhite );
t1->SetFillColor( kWhite );
t1->Draw();
return hResponse;
}
/// Plot the photoelectron and reflection responses
///
/// The photoelectron response is the number of photoelectrons/number of hits per bin.
/// The reflection response is the number of reflected photons/number of hits per bin.
///
/// @param[in] fileName of the RAT::DS root file to analyse
/// @return the histogram plot
TH1D* PlotWavelengthResponse( const string& fileName )
{
gStyle->SetOptStat(111111); // to show overflow / underflow stats
TH1D* hResponse = new TH1D( "hResponse", "PMT Response as function of wavelength", 600, 200.0, 800.0 );
TH1D* hReflected = new TH1D( "hReflected", "PMT Response as function of wavelength", 600, 200.0, 800.0 );
TH1D* hHits = new TH1D( "hHits", "PMT hits as function of wavelength", 600, 200.0, 800.0 );
// If this is being done on data that does not require remote database connection
// eg.: a simple simulation with default run number (0)
// We can disable the remote connections:
//
// NOTE: Don't do this if you are using real data!!!
RAT::DB::Get()->SetAirplaneModeStatus(true);
RAT::DU::DSReader dsReader( fileName );
for( size_t iEntry = 0; iEntry < dsReader.GetEntryCount(); iEntry++ )
{
const RAT::DS::Entry& rDS = dsReader.GetEntry( iEntry );
const RAT::DS::MC& mc = rDS.GetMC();
for( size_t iPMT = 0; iPMT < mc.GetMCPMTCount(); iPMT++ )
{
const RAT::DS::MCPMT& mcPMT = mc.GetMCPMT( iPMT );
const TVector3 pmtDirection = TVector3( 0.0, 0.0, -1.0 );
for( size_t iPhoton = 0; iPhoton < mcPMT.GetMCPhotonCount(); iPhoton++ )
{
const RAT::DS::MCPhoton& mcPhoton = mcPMT.GetMCPhoton( iPhoton );
if( mcPhoton.GetInPosition().Z() < 132.0 )
continue;
const double wavelength = twopi * 197.32705e-6 / mcPhoton.GetEnergy(); // In nm
hHits->Fill( wavelength );
if( mcPhoton.GetFate() == RAT::DS::MCPhoton::ePhotoelectron )
hResponse->Fill( wavelength );
else if( mcPhoton.GetFate() == RAT::DS::MCPhoton::eReflected )
hReflected->Fill( wavelength );
}
}
}
hResponse->Sumw2();
hHits->Sumw2();
hReflected->Sumw2();
hResponse->Divide( hHits );
hResponse->Draw("E");
hReflected->Divide( hHits );
hReflected->SetLineColor( kRed );
hReflected->Draw("SAMEE");
TLegend* t1 = new TLegend( 0.7, 0.7, 0.88, 0.88 );
t1->AddEntry( hResponse, "Signal", "l" );
t1->AddEntry( hReflected, "Reflection", "l" );
t1->SetLineColor( kWhite );
t1->SetFillColor( kWhite );
t1->Draw();
return hResponse;
}