00001
00006 #include "FloatingFeePedestalSvc.h"
00007 #include "Event/ReadoutPmtCrate.h"
00008 #include "Event/ReadoutPmtChannel.h"
00009 #include "Event/Readout.h"
00010
00011 #include "Conventions/Electronics.h"
00012 #include "Context/TimeStamp.h"
00013
00014 using namespace std;
00015 using namespace DayaBay;
00016
00017 FloatingFeePedestalSvc::FloatingFeePedestalSvc(const std::string& name, ISvcLocator *svc)
00018 : Service(name,svc)
00019 {
00020 declareProperty("Limit",m_limit=500,
00021 "Number of preAdcs to document");
00022
00023 declareProperty("TimeCutInSec",m_timeCutInSec=0.0001,
00024 "Time cut in second to remove afterpulses");
00025 }
00026
00027 FloatingFeePedestalSvc::~FloatingFeePedestalSvc()
00028 {
00029 }
00030
00031 StatusCode FloatingFeePedestalSvc::initialize()
00032 {
00033 StatusCode sc;
00034 sc = this->Service::initialize();
00035
00036 m_finePreAdc.clear();
00037 m_crsePreAdc.clear();
00038
00039 m_finePedes.clear();
00040 m_crsePedes.clear();
00041
00042 m_lastTrig = TimeStamp::GetBOT();
00043
00044 return sc;
00045 }
00046
00047 StatusCode FloatingFeePedestalSvc::finalize()
00048 {
00049 StatusCode sc;
00050 sc = this->Service::finalize();
00051
00052 return sc;
00053 }
00054
00055 StatusCode FloatingFeePedestalSvc::queryInterface(const InterfaceID& riid,
00056 void** ppvInterface)
00057 {
00058 StatusCode sc = StatusCode::FAILURE;
00059 if (ppvInterface) {
00060 *ppvInterface = 0;
00061
00062 if (IFloatingFeePedestalSvc::interfaceID().versionMatch(riid)) {
00063 *ppvInterface = static_cast<IFloatingFeePedestalSvc*>(this);
00064 sc = StatusCode::SUCCESS;
00065 addRef();
00066 }
00067 else sc = Service::queryInterface( riid, ppvInterface );
00068 }
00069 return sc;
00070 }
00071
00072
00073 StatusCode FloatingFeePedestalSvc::cumulate( const DayaBay::ReadoutHeader* rh )
00074 {
00075 MsgStream log(msgSvc(), "FloatingFeePedestalSvc");
00076
00078 const Readout* readout = rh->readout();
00079 if(!readout) {
00080 log << MSG::ERROR <<"Failed to get readout from header"<<endreq;
00081 return StatusCode::FAILURE;
00082 }
00083
00085 if( readout->detector().detectorId() != DetectorId::kAD1 &&
00086 readout->detector().detectorId() != DetectorId::kAD2 &&
00087 readout->detector().detectorId() != DetectorId::kAD3 &&
00088 readout->detector().detectorId() != DetectorId::kAD4 &&
00089 readout->detector().detectorId() != DetectorId::kIWS &&
00090 readout->detector().detectorId() != DetectorId::kOWS ) {
00091 return StatusCode::SUCCESS;
00092 }
00093
00095 TimeStamp trigTime = readout->triggerTime();
00096
00098 if( (m_lastTrig == TimeStamp::GetBOT()) ||
00099 ((trigTime-m_lastTrig).GetSeconds() > m_timeCutInSec) ) {
00100
00102 const ReadoutPmtCrate* pPmtCrate=0;
00103 pPmtCrate = dynamic_cast< const DayaBay::ReadoutPmtCrate* > ( readout );
00104 if(!pPmtCrate) {
00105 log << MSG::ERROR <<"Failed to get ReadoutPmtCrate"<<endreq;
00106 return StatusCode::FAILURE;
00107 }
00108
00110 ReadoutPmtCrate::PmtChannelReadouts channels = pPmtCrate->channelReadout();
00111 ReadoutPmtCrate::PmtChannelReadouts::iterator ci, ci_end = channels.end();
00112
00113 for(ci = channels.begin(); ci!=ci_end; ci++) {
00114
00116 ReadoutPmtChannel channel = ci->second;
00117 FeeChannelId channelId = channel.channelId();
00118
00119 int preAdc = channel.pedestal()[0];
00120 int range = channel.adcRange()[0];
00121
00123 if( range == FeeGain::kHigh ) {
00124 list<unsigned int>& preAdcs = m_finePreAdc[ channelId ];
00125 m_finePedes[ channelId ] = updatePedestal( preAdcs, preAdc );
00126 }
00127 if( range == FeeGain::kLow ) {
00128 list<unsigned int>& preAdcs = m_crsePreAdc[ channelId ];
00129 m_crsePedes[ channelId ] = updatePedestal( preAdcs, preAdc );
00130 }
00131 }
00132
00133 m_lastTrig = trigTime;
00134 }
00135
00136 return StatusCode::SUCCESS;
00137 }
00138
00139
00140 double FloatingFeePedestalSvc::pedestal( const DayaBay::FeeChannelId& channelId,
00141 int gain ) const
00142 {
00143 MsgStream log(msgSvc(), "FloatingFeePedestalSvc");
00144
00145 if( gain==FeeGain::kHigh ) {
00146 PedestalArray::const_iterator ci;
00147 ci = m_finePedes.find( channelId );
00148 if( ci != m_finePedes.end() ) {
00149 return ci->second;
00150 } else {
00151 log << MSG::WARNING <<"Incomplete fine range pedestal map. Try preADC."<<endreq;
00152 return -1000;
00153 }
00154 }
00155
00156 if( gain==FeeGain::kLow ) {
00157 PedestalArray::const_iterator ci;
00158 ci = m_crsePedes.find( channelId );
00159 if( ci != m_crsePedes.end() ) {
00160 return ci->second;
00161 } else {
00162 log << MSG::WARNING <<"Incomplete coarse range pedestal map. Try preADC."<<endreq;
00163 return -1000;
00164 }
00165 }
00166
00167 log << MSG::ERROR <<"Query with wrong gain parameter"<<endreq;
00168 return -1000;
00169 }
00170
00171 double FloatingFeePedestalSvc::updatePedestal( list<unsigned int>& PreAdcs, unsigned int newPreAdc )
00172 {
00174 PreAdcs.push_front( newPreAdc );
00175 if( PreAdcs.size()>m_limit ) PreAdcs.pop_back();
00176
00177 double sum=0;
00178 int count = PreAdcs.size();
00179 list<unsigned int>::iterator li,liend=PreAdcs.end();
00180 for( li=PreAdcs.begin(); li!=liend; li++ ) {
00181 sum+= (*li);
00182 }
00183
00184 sum = sum/count;
00185
00186 return sum;
00187 }