text: /**
   * @file Simulator.h
   * @brief Declaration for Simulator class.
   * @author J. Chiang
   * $Header: /nfs/slac/g/glast/ground/cvs/observationSim/observationSim/Simulator.h,v 1.27 2007/01/25 06:55:58 jchiang Exp $
   */
  
  #ifndef observationSim_Simulator_h
  #define observationSim_Simulator_h
  
  #include <iostream>
  #include <string>
  #include <vector>
  
  #include "CLHEP/Geometry/Vector3D.h"
  
  #include "st_stream/StreamFormatter.h"
  
  #include "astro/GPS.h"
  #include "astro/SkyDir.h"
  
  #include "flux/FluxMgr.h"
  
  namespace irfInterface {
     class Irfs;
  }
  
  #include "observationSim/Spacecraft.h"
  
  class CompositeSource;
  
  namespace observationSim {
  
  class EventContainer;
  class ScDataContainer;
  
  /**
   * @class Simulator
   * @brief This class provides an interface to FluxSvc::FluxMgr for
   * generating gamma-ray events in the LAT.
   *
   * In addition to producing photon events, this class manages the
   * output of the spacecraft data and writes the events and spacecraft
   * data to FITS files.
   *
   * @author J. Chiang
   *
   * $Header: /nfs/slac/g/glast/ground/cvs/observationSim/observationSim/Simulator.h,v 1.27 2007/01/25 06:55:58 jchiang Exp $
   */
  
  class Simulator {
  
  public:
  
     Simulator() : m_fluxMgr(0), m_source(0), m_newEvent(0) {}
  
     /// @param sourceName The name of the source as it appears in the xml file.
     /// @param fileList A vector of xml file names using the source.dtd.
     /// @param totalArea The cross-sectional area of the sphere enclosing
     ///        the instrument in square meters.
     /// @param startTime Absolute starting time of the simulation in seconds.
     Simulator(const std::string & sourceName, 
               const std::vector<std::string> & fileList,
               double totalArea,
               double startTime=0.,
               const std::string & pointingHistory="",
               double maxSimTime=3.155e8,
               double pointingHistoryOffset=0)
        : m_formatter(new st_stream::StreamFormatter("Simulator", "", 2)),
          m_fluxMgr(0), m_source(0), m_newEvent(0) {
        init(sourceName, fileList, totalArea, startTime, pointingHistory,
             maxSimTime, pointingHistoryOffset);
     }
  
     /// @param sourceNames A vector of source names as they appear in 
     ///        the xml file.
     Simulator(const std::vector<std::string> & sourceNames,
               const std::vector<std::string> & fileList,
               double totalArea,
               double startTime=0.,
               const std::string & pointingHistory="",
               double maxSimTime=3.155e8,
               double pointingHistoryOffset=0)
        : m_formatter(new st_stream::StreamFormatter("Simulator", "", 2)),
          m_fluxMgr(0), m_source(0), m_newEvent(0) {
        init(sourceNames, fileList, totalArea, startTime, pointingHistory,
             maxSimTime, pointingHistoryOffset);
     }
  
     ~Simulator();
  
     /// Set the pointing history file.
     void setPointingHistoryFile(const std::string &filename, double offset) {
        m_fluxMgr->setRockType(astro::GPS::HISTORY, 0);
        astro::GPS::instance()->setPointingHistoryFile(filename, offset);
        m_usePointingHistory = true;
     }   
  
     /// Specify the rocking strategy from among those defined by
     /// flux::GPS::RockType.  
     /// @param rockType Integer representation of the desired strategy.
     ///        The default value of 3 corresponds to step-rocking, once
     ///        per orbit.
     /// @param angle Rocking angle in degrees.
     void setRocking(int rockType = 3, double angle = 35.) {
        m_fluxMgr->setRockType(s_rockTypes.at(rockType), angle);
        m_usePointingHistory = false; 
     }
  
     /// List the available sources by xml name for each file in the fileList.
     void listSources() const;
     
     /// List the avaiable particle spectra.
     void listSpectra() const;
  
     /// Generate photon events for a given elapsed simulation time.
     void generateEvents(double simulationTime, 
                         EventContainer &events,
                         ScDataContainer &scData, 
                         std::vector<irfInterface::Irfs*> &respPtrs,
                         Spacecraft *spacecraft) {
        m_simTime = simulationTime;
        makeEvents(events, scData, respPtrs, spacecraft, true);
     }
  
     /// Generate a specified number of events.
     void generateEvents(long numberOfEvents, 
                         EventContainer &events,
                         ScDataContainer &scData, 
                         std::vector<irfInterface::Irfs*> &respPtrs,
                         Spacecraft *spacecraft) {
        m_maxNumEvents = numberOfEvents;
        makeEvents(events, scData, respPtrs, spacecraft, false);
     }
  
     void setIdOffset(int id) {
        m_fluxMgr->setIdOffset(id);
     }
  
  protected:
  
     Simulator(const Simulator &) {}
     Simulator & operator=(const Simulator &) {return *this;}
  
  private:
  
     st_stream::StreamFormatter * m_formatter;
  
     FluxMgr * m_fluxMgr;
     CompositeSource * m_source;
     EventSource * m_newEvent;
  
     static std::vector<astro::GPS::RockType> s_rockTypes;
  
     double m_interval;
     
     long m_numEvents;
     long m_maxNumEvents;
  
     double m_absTime;
     double m_simTime;
     double m_elapsedTime;
     bool m_useSimTime;
  
     double m_maxSimTime;
  
     bool m_usePointingHistory;
  
     void init(const std::string & sourceName, 
               const std::vector<std::string> & fileList,
               double totalArea, double startTime, 
               const std::string &, double, double);
  
     void init(const std::vector<std::string> & sourceNames, 
               const std::vector<std::string> & fileList,
               double totalArea, double startTime,
               std::string, double, double);
  
     void makeEvents(EventContainer &, ScDataContainer &, 
                     std::vector<irfInterface::Irfs *> &, 
                     Spacecraft * spacecraft,
                     bool useSimTime);
  
     bool done();
  
  };
  
  } // namespace observationSim
  
  #endif // observationSim_Simulator_h
  