00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "FluxSvc/PointingInfo.h"
00010
00011
00012 #include "GaudiKernel/Algorithm.h"
00013 #include "GaudiKernel/MsgStream.h"
00014 #include "GaudiKernel/AlgFactory.h"
00015 #include "GaudiKernel/IDataProviderSvc.h"
00016 #include "GaudiKernel/SmartDataPtr.h"
00017 #include "GaudiKernel/SmartRefVector.h"
00018
00019 #include "astro/SkyDir.h"
00020 #include "astro/EarthCoordinate.h"
00021 #include "astro/SolarSystem.h"
00022
00023
00024 #include "FluxSvc/IFluxSvc.h"
00025 #include "flux/IFlux.h"
00026 #include "astro/GPS.h"
00027
00028
00029 #include "ntupleWriterSvc/INTupleWriterSvc.h"
00030 #include "facilities/Util.h"
00031 #include "facilities/Observer.h"
00032
00033
00034 #include "Trigger/ILivetimeSvc.h"
00035
00036 #include <cassert>
00037 #include <vector>
00038 #include <fstream>
00039 #include <iomanip>
00040 #include <map>
00041
00054 class ExposureAlg : public Algorithm {
00055 public:
00056 ExposureAlg(const std::string& name, ISvcLocator* pSvcLocator);
00057
00058
00059 StatusCode initialize();
00060 StatusCode execute();
00061 StatusCode finalize();
00062
00063
00064 private:
00065
00066 double m_lasttime;
00067 double m_last_livetime;
00068 double m_initial_time;
00069
00070 StringProperty m_root_tree;
00071 StringProperty m_pointing_history_input_file;
00072 StringProperty m_clockName;
00073
00074 IntegerProperty m_print_frequency;
00075 IFluxSvc* m_fluxSvc;
00076
00077 int m_tickCount;
00078 INTupleWriterSvc* m_rootTupleSvc;;
00079 ILivetimeSvc * m_livetimeSvc;
00080
00081 PointingInfo m_history;
00082
00083
00084 bool m_insideSAA;
00085 ObserverAdapter< ExposureAlg > m_observer;
00086 int askGPS();
00087
00088 void createEntry();
00089
00090 astro::GPS * m_gps;
00091 std::map<std::string, int> m_ticks;
00092 };
00093
00094
00095 static const AlgFactory<ExposureAlg> Factory;
00096 const IAlgFactory& ExposureAlgFactory = Factory;
00097
00098
00100 ExposureAlg::ExposureAlg(const std::string& name, ISvcLocator* pSvcLocator)
00101 : Algorithm(name, pSvcLocator)
00102 , m_lasttime(0)
00103 , m_tickCount(0)
00104 , m_insideSAA(false)
00105 {
00106
00107 declareProperty("root_tree",m_root_tree="pointing_history");
00108
00109 declareProperty("PrintFrequency", m_print_frequency=1);
00110 declareProperty("clockName" , m_clockName = "clock" );
00111 }
00112
00113
00115 StatusCode ExposureAlg::initialize(){
00116 StatusCode sc = StatusCode::SUCCESS;
00117 MsgStream log(msgSvc(), name());
00118
00119
00120 setProperties();
00121
00122 if ( service("FluxSvc", m_fluxSvc).isFailure() ){
00123 log << MSG::ERROR << "Couldn't find the FluxSvc!" << endreq;
00124 return StatusCode::FAILURE;
00125 }
00126
00127
00128 IProperty* propMgr=0;
00129 sc = serviceLocator()->service("FluxSvc", propMgr );
00130 if( sc.isFailure()) {
00131 log << MSG::ERROR << "Unable to locate PropertyManager Service" << endreq;
00132 return sc;
00133 }
00134
00135
00136 DoubleProperty startTime("StartTime",0);
00137 sc = propMgr->getProperty( &startTime );
00138 if (sc.isFailure()) return sc;
00139
00140 m_initial_time =m_lasttime = startTime.value();
00141
00142
00143 if( (sc = service("RootTupleSvc", m_rootTupleSvc, true) ). isFailure() ) {
00144 log << MSG::ERROR << " failed to get the RootTupleSvc" << endreq;
00145 return sc;
00146 }
00147
00148 if( (service("LivetimeSvc", m_livetimeSvc, true) ). isFailure() ) {
00149 log << MSG::ERROR << " LivetimeSvc is not available" << endreq;
00150 return StatusCode::FAILURE;
00151 }
00152
00153 m_history.setFT2Tuple(m_rootTupleSvc, m_root_tree.value());
00154
00155 log << MSG::INFO << "Using the clock \""<< m_clockName<< "\" to generate FT2 entries" << endreq;
00156
00157
00158
00159 m_observer.setAdapter( new ActionAdapter<ExposureAlg>
00160 (this, &ExposureAlg::askGPS) );
00161
00162 m_fluxSvc->attachGpsObserver(&m_observer);
00163 m_gps = astro::GPS::instance();
00164
00165 return sc;
00166 }
00167
00168 int ExposureAlg::askGPS()
00169 {
00170
00171 astro::EarthCoordinate pos = astro::GPS::instance()->earthpos();
00172 bool inside = pos.insideSAA();
00173 if( inside != m_insideSAA){
00174
00175
00176 m_insideSAA= inside;
00177 createEntry();
00178 }
00179
00180 return 0;
00181 }
00182
00183
00185 StatusCode ExposureAlg::execute()
00186 {
00187 StatusCode sc = StatusCode::SUCCESS;
00188 MsgStream log(msgSvc(), name());
00189
00190 IFlux* flux=m_fluxSvc->currentFlux();
00191
00192 std::string name( flux->name());
00193
00194 log << MSG::DEBUG << "Clock tick at "<< m_gps->time()<<", clock: "<<name << endreq;
00195
00196 m_ticks[name]++;
00197
00198 if(m_clockName.value() == name){
00199 createEntry();
00200 setFilterPassed(false);
00201 }
00202
00203 return sc;
00204 }
00205
00206 void ExposureAlg::createEntry()
00207 {
00208 m_lasttime = astro::GPS::instance()->time();
00209 if( m_tickCount!=0){
00210 double interval = m_lasttime - m_history.start_time();
00211 if( interval<=1e-10) return;
00212 m_history.finish( m_lasttime, m_livetimeSvc->livetime()-m_last_livetime);
00213
00214 m_rootTupleSvc->saveRow(this->m_root_tree.value());
00215 }
00216 m_last_livetime = m_livetimeSvc->livetime();
00217
00218
00219 m_history.set();
00220
00221 if( m_tickCount% m_print_frequency==0){
00222 MsgStream log( msgSvc(), name() );
00223 log << MSG::INFO;
00224 if( log.isActive() ){
00225 std::stringstream t;
00226 t << "tick at " << std::setprecision(10)
00227 << m_lasttime - m_initial_time << " sec"
00228 << std::setprecision(3)
00229 << ", lat, lon, magLat, zenithTheta, SAA = "
00230 << m_history.lat_geo << ", "
00231 << m_history.lon_geo << ", "
00232 << m_history.lat_mag << ", "
00233 << ( fabs(m_history.zenith_scz)<1e-8? 0: m_history.zenith_scz) << ", "
00234 << m_history.in_saa;
00235 log << t.str();
00236 }
00237 log << endreq;
00238 }
00239
00240 m_tickCount++;
00241 }
00242
00243
00245 StatusCode ExposureAlg::finalize(){
00246
00247 if( m_tickCount>0 ) createEntry();
00248
00249 StatusCode sc = StatusCode::SUCCESS;
00250 MsgStream log(msgSvc(), name());
00251
00252 log << MSG::INFO <<" clock Name ticks"<<endreq;;
00253 for(std::map<std::string,int>::const_iterator im=m_ticks.begin(); im !=m_ticks.end(); ++im) {
00254 log<< MSG::INFO
00255 <<std::setw(15) << std::left << im->first
00256 << std::setw(10)<< std::right << im->second << endreq;
00257 }
00258 log << std::endl;
00259
00260 return sc;
00261 }
00262