00001 #include "CenterOfChargePosTool.h"
00002
00003 #include "Event/CalibReadout.h"
00004 #include "Event/CalibReadoutPmtCrate.h"
00005 #include "Event/CalibReadoutPmtChannel.h"
00006 #include "Event/RecTrigger.h"
00007 #include "Conventions/Reconstruction.h"
00008 #include "Conventions/Detectors.h"
00009
00010 #include "DataSvc/ICableSvc.h"
00011 #include "DataSvc/ICalibDataSvc.h"
00012 #include "DetHelpers/IPmtGeomInfoSvc.h"
00013 #include "CLHEP/Vector/LorentzVector.h"
00014
00015 #include "TMath.h"
00016
00017 using namespace DayaBay;
00018
00019 CenterOfChargePosTool::CenterOfChargePosTool(const std::string& type,
00020 const std::string& name,
00021 const IInterface* parent)
00022 : GaudiTool(type,name,parent)
00023 , m_cableSvc(0)
00024 , m_calibDataSvc(0)
00025 , m_pmtGeomSvc(0)
00026 {
00027 declareInterface< IReconTool >(this) ;
00028 declareProperty("CableSvcName",m_cableSvcName="StaticCableSvc",
00029 "Name of service to map between detector, hardware, and electronic IDs");
00030 declareProperty("CalibDataSvcName", m_calibDataSvcName="StaticCalibDataSvc",
00031 "Name of calibration data service");
00032 declareProperty("PmtGeomSvcName", m_pmtGeomSvcName="PmtGeomInfoSvc",
00033 "Name of PMT geometry data service");
00034 declareProperty("ApplyScaling", m_applyScaling=true,
00035 "Apply empirical scaling factor to get a 'reconstructed' position");
00036 }
00037
00038 CenterOfChargePosTool::~CenterOfChargePosTool(){}
00039
00040 StatusCode CenterOfChargePosTool::initialize()
00041 {
00042
00043 m_cableSvc = svc<ICableSvc>(m_cableSvcName,true);
00044 m_calibDataSvc = svc<ICalibDataSvc>(m_calibDataSvcName,true);
00045 m_pmtGeomSvc = svc<IPmtGeomInfoSvc>(m_pmtGeomSvcName,true);
00046
00047 return StatusCode::SUCCESS;
00048 }
00049
00050 StatusCode CenterOfChargePosTool::finalize()
00051 {
00052 return StatusCode::SUCCESS;
00053 }
00054
00055 StatusCode CenterOfChargePosTool::reconstruct(const CalibReadout& readout,
00056 RecTrigger& recTrigger)
00057 {
00058 if( !readout.detector().isAD() ){
00059 debug() << "Not an AD readout; ignoring detector "
00060 << readout.detector().detName() << endreq;
00061 recTrigger.setPositionStatus( ReconStatus::kNotProcessed );
00062 return StatusCode::SUCCESS;
00063 }
00064
00065 const CalibReadoutPmtCrate* pmtReadout
00066 = dynamic_cast<const CalibReadoutPmtCrate*>(&readout);
00067 if(!pmtReadout){
00068 error() << "Incorrect type of readout crate for detector "
00069 << readout.detector().detName() << endreq;
00070 recTrigger.setPositionStatus( ReconStatus::kBadReadout );
00071 return StatusCode::FAILURE;
00072 }
00073
00074
00075 int task = 0;
00076 ServiceMode svcMode(readout.header()->context(), task);
00077
00078
00079 double pos[3];
00080 double posSquare[3];
00081 for(int idx = 0; idx<3; idx++){ pos[idx]=0; posSquare[idx]=0; }
00082 double time = 0;
00083 double qSum = 0;
00084 int nHits = 0;
00085 CalibReadoutPmtCrate::PmtChannelReadouts::const_iterator chanIter,
00086 chanEnd = pmtReadout->channelReadout().end();
00087 for(chanIter=pmtReadout->channelReadout().begin(); chanIter != chanEnd;
00088 chanIter++){
00089 const CalibReadoutPmtChannel& channel = *chanIter;
00090 AdPmtSensor pmtId(channel.pmtSensorId().fullPackedData());
00091 if( pmtId.ring()<1 ){ continue; }
00092 const PmtCalibData* pmtCalib = m_calibDataSvc->pmtCalibData(pmtId, svcMode);
00093 if( !pmtCalib ){
00094 error() << "No calibration data for pmt ID: " << pmtId << endreq;
00095 recTrigger.setPositionStatus( ReconStatus::kBadReadout );
00096 return StatusCode::FAILURE;
00097 }
00098 if( pmtCalib->m_status != PmtCalibData::kGood ) { continue; }
00099 const CLHEP::Hep3Vector& pmtPos
00100 = m_pmtGeomSvc->get(pmtId.fullPackedData())->localPosition();
00101 double peakAdc = channel.maxCharge();
00102 double firstTdc = channel.earliestTime();
00103 for(int idx = 0; idx<3; idx++){
00104 pos[idx] += peakAdc*pmtPos[idx];
00105 posSquare[idx] += peakAdc*pmtPos[idx]*pmtPos[idx];
00106 }
00107 time += firstTdc;
00108 qSum += peakAdc;
00109 nHits++;
00110 }
00111
00112 if(nHits<1){
00113 recTrigger.setPositionStatus( ReconStatus::kNoHits );
00114 return StatusCode::SUCCESS;
00115 }
00116 double posStdDev = 0;
00117 for(int idx = 0; idx<3; idx++){
00118 posStdDev += posSquare[idx] - pos[idx]*pos[idx]/qSum;
00119 pos[idx] /= qSum;
00120 }
00121 posStdDev /= qSum;
00122 posStdDev = sqrt(posStdDev);
00123 time /= qSum;
00124
00125 if(m_applyScaling){
00126
00127
00128 double rho = sqrt(pos[0]*pos[0] + pos[1]*pos[1]);
00129 double rhoNorm = rho/2340.;
00130 double zNorm = pos[2]/1750.;
00131 if(zNorm<0) zNorm *= -1;
00132 double rhoScaled = 1-(1-rhoNorm)/TMath::Power((1+rhoNorm), 3.13);
00133 double zScaled =
00134 1-(1-zNorm)/TMath::Power((1+zNorm),
00135 10.0*(1-sqrt(rhoNorm)));
00136
00137 pos[0] *= rhoScaled/rhoNorm;
00138 pos[1] *= rhoScaled/rhoNorm;
00139 pos[2] *= zScaled/zNorm;
00140 }
00141
00142 CLHEP::HepLorentzVector position(pos[0], pos[1], pos[2], time);
00143 recTrigger.setPosition( position );
00144
00145 recTrigger.setPositionQuality( posStdDev );
00146 recTrigger.setPositionStatus( ReconStatus::kGood );
00147
00148 return StatusCode::SUCCESS;
00149 }