| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

CenterOfChargePosTool.cc

Go to the documentation of this file.
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   // Get Cable Service
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   // Context for this data
00075   int task = 0;
00076   ServiceMode svcMode(readout.header()->context(), task);
00077 
00078   // Loop over hits and determine charge-weighted mean position
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; }  // Ignore calibration pmts
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     // Apply empirical rho, z scaling to vertex position
00127     // This is not very good, but is useful as a prefit
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     //warning() << "Scaling by: " << rhoScaled << " , " << zScaled << endreq;
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   // Set quality to charge-weighted standard deviation of hit positions
00145   recTrigger.setPositionQuality( posStdDev );
00146   recTrigger.setPositionStatus( ReconStatus::kGood );
00147 
00148   return StatusCode::SUCCESS;
00149 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:41:54 2011 for CenterOfChargePos by doxygen 1.4.7