CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/IORawData/DaqSource/plugins/DaqSource.cc

Go to the documentation of this file.
00001 
00008 #include "DaqSource.h"
00009 
00010 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00011 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00012 #include "EventFilter/FEDInterface/interface/GlobalEventNumber.h"
00013 
00014 #include "IORawData/DaqSource/interface/DaqBaseReader.h"
00015 #include "IORawData/DaqSource/interface/DaqReaderPluginFactory.h"
00016 
00017 #include "DataFormats/Provenance/interface/Timestamp.h" 
00018 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00019 #include "FWCore/Framework/interface/EventPrincipal.h"
00020 #include "FWCore/Framework/interface/Event.h"
00021 #include "DataFormats/Provenance/interface/EventAuxiliary.h"
00022 #include "DataFormats/Provenance/interface/LuminosityBlockAuxiliary.h"
00023 #include "DataFormats/Provenance/interface/RunAuxiliary.h"
00024 #include "DataFormats/Provenance/interface/EventID.h"
00025 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00026 
00027 #include <string>
00028 #include <iostream>
00029 #include <time.h>
00030 #include <sys/time.h>
00031 #include <sys/types.h>
00032 
00033 #include "xgi/Method.h"
00034 #include "xgi/Utils.h"
00035 
00036 #include "cgicc/Cgicc.h"
00037 #include "cgicc/FormEntry.h"
00038 #include "cgicc/HTMLClasses.h"
00039 
00040 #include "boost/tokenizer.hpp"
00041 
00042 
00044 // construction/destruction
00046 
00047 
00048 
00049 namespace edm {
00050  namespace daqsource{
00051   static unsigned int gtpEvmId_ =  FEDNumbering::MINTriggerGTPFEDID;
00052   static unsigned int gtpeId_ =  FEDNumbering::MINTriggerEGTPFEDID;
00053  }
00054 
00055   //______________________________________________________________________________
00056   DaqSource::DaqSource(const ParameterSet& pset, 
00057                      const InputSourceDescription& desc) 
00058     : InputSource(pset,desc)
00059     , evf::ModuleWeb("DaqSource")
00060     , reader_(0)
00061     , lumiSegmentSizeInEvents_(pset.getUntrackedParameter<unsigned int>("evtsPerLS",0))
00062     , useEventCounter_(pset.getUntrackedParameter<bool>("useEventCounter",false))
00063     , eventCounter_(0)
00064     , keepUsingPsidFromTrigger_(pset.getUntrackedParameter<bool>("keepUsingPsidFromTrigger",false))
00065     , fakeLSid_(lumiSegmentSizeInEvents_ != 0)
00066     , runNumber_(RunID::firstValidRun().run())
00067     , luminosityBlockNumber_(LuminosityBlockID::firstValidLuminosityBlock().luminosityBlock())
00068     , noMoreEvents_(false)
00069     , newRun_(true)
00070     , newLumi_(true)
00071     , eventCached_(false)
00072     , alignLsToLast_(false)
00073     , is_(0)
00074     , mis_(0)
00075     , thisEventLSid(0)
00076     , goToStopping(false)
00077   {
00078     count = 0;
00079     pthread_mutex_init(&mutex_,0);
00080     pthread_mutex_init(&signal_lock_,0);
00081     pthread_cond_init(&cond_,0);
00082     produces<FEDRawDataCollection>();
00083     setTimestamp(Timestamp::beginOfTime());
00084     
00085     // Instantiate the requested data source
00086     std::string reader = pset.getUntrackedParameter<std::string>("readerPluginName");
00087     
00088     try{
00089       reader_=
00090         DaqReaderPluginFactory::get()->create(reader,
00091                                             pset.getUntrackedParameter<ParameterSet>("readerPset"));
00092       reader_->setRunNumber(runNumber_);
00093     }
00094     catch(edm::Exception &e) {
00095       if(e.category() == "Configuration" && reader_ == 0) {
00096         reader_ = DaqReaderPluginFactoryU::get()->create(reader);
00097         if(reader_ == 0) throw;
00098         else reader_->setRunNumber(runNumber_);
00099       }
00100       else {
00101         throw;
00102       }
00103     }
00104   }
00105   
00106   //______________________________________________________________________________
00107   DaqSource::~DaqSource() {
00108     delete reader_;
00109   }
00110   
00111   
00113   // implementation of member functions
00115   
00116   //______________________________________________________________________________
00117   InputSource::ItemType 
00118   DaqSource::getNextItemType() {
00119     //    std::cout << getpid() << " enter getNextItemType " << std::endl;
00120     if(goToStopping){noMoreEvents_ = true; goToStopping=false;}
00121     if (noMoreEvents_) {
00122       pthread_mutex_lock(&mutex_);
00123       pthread_cond_signal(&cond_);
00124       pthread_mutex_unlock(&mutex_);
00125       return IsStop;
00126     }
00127     if (newRun_) {
00128       return IsRun;
00129     }
00130     if (newLumi_ && luminosityBlockAuxiliary()) {
00131       //      std::cout << "newLumi & lumiblock valid " << std::endl;
00132       return IsLumi;
00133     }
00134     if (alignLsToLast_) { //here we are recovering from a gap in Ls number so an event may already be cached but 
00135       // we hold onto it until we have issued all the necessary endLumi/beginLumi
00136 //       std::cout << getpid() << "alignLsToLast was set and ls number is " 
00137 //              << luminosityBlockNumber_ << " before signaling" << std::endl;
00138       signalWaitingThreadAndBlock();
00139       luminosityBlockNumber_++;
00140 //       std::cout << getpid() << "alignLsToLast signaled and incremented " 
00141 //              << luminosityBlockNumber_ << " eventcached " 
00142 //              << eventCached_ << std::endl;
00143       newLumi_ = true;
00144       lumiSectionIndex_->value_ = luminosityBlockNumber_;
00145       resetLuminosityBlockAuxiliary();
00146       if(luminosityBlockNumber_ == thisEventLSid+1) 
00147         {
00148           alignLsToLast_ = false;
00149         }
00150       if (!luminosityBlockAuxiliary() || luminosityBlockAuxiliary()->luminosityBlock() != luminosityBlockNumber_) {
00151         setLuminosityBlockAuxiliary(new LuminosityBlockAuxiliary(
00152                                                                  runNumber_, luminosityBlockNumber_, timestamp(), Timestamp::invalidTimestamp()));
00153         
00154         readAndCacheLumi();
00155         setLumiPrematurelyRead();
00156         //      std::cout << "nextItemType: dealt with new lumi block principal, retval is " << retval << std::endl;
00157       }
00158       return IsLumi;
00159     }
00160     if (eventCached_) {
00161       //      std::cout << "read event already cached " << std::endl;
00162       return IsEvent;
00163     }
00164     if(reader_ == 0) {
00165       throw edm::Exception(errors::LogicError)
00166         << "DaqSource is used without a reader. Check your configuration !";
00167     }
00168     EventID eventId;
00169     TimeValue_t time = 0LL;
00170     timeval stv;
00171     gettimeofday(&stv,0);
00172     time = stv.tv_sec;
00173     time = (time << 32) + stv.tv_usec;
00174     Timestamp tstamp(time);
00175 
00176     int bunchCrossing = EventAuxiliary::invalidBunchXing;
00177     int orbitNumber   = EventAuxiliary::invalidBunchXing;
00178     
00179     // pass a 0 pointer to fillRawData()!
00180     FEDRawDataCollection* fedCollection(0);
00181 
00182     edm::EventAuxiliary::ExperimentType evttype = EventAuxiliary::Undefined;
00183   
00184     // let reader_ fill the fedCollection 
00185     int retval = reader_->fillRawData(eventId, tstamp, fedCollection);
00186     if(retval==0) {
00187       // fillRawData() failed, clean up the fedCollection in case it was allocated!
00188       if (0 != fedCollection) delete fedCollection;
00189       noMoreEvents_ = true;
00190       pthread_mutex_lock(&mutex_);
00191       pthread_cond_signal(&cond_);
00192       pthread_mutex_unlock(&mutex_);
00193       return IsStop;
00194     }
00195     else if(retval<0)
00196       {
00197  
00198         unsigned int nextLsFromSignal = (-1)*retval+1;
00199 //      std::cout << getpid() << "::got end-of-lumi for " << (-1)*retval
00200 //                << " was " << luminosityBlockNumber_ << std::endl;
00201         if(luminosityBlockNumber_ < nextLsFromSignal)
00202           {
00203             if(lsToBeRecovered_->value_){
00204 //            std::cout << getpid() << "eol::recover ls::for " << (-1)*retval << std::endl;
00205               signalWaitingThreadAndBlock();
00206               luminosityBlockNumber_++;
00207               newLumi_ = true;
00208               lumiSectionIndex_->value_ = luminosityBlockNumber_;
00209               resetLuminosityBlockAuxiliary();
00210               thisEventLSid = nextLsFromSignal - 1;
00211               if(luminosityBlockNumber_ != thisEventLSid+1) 
00212                 alignLsToLast_ = true;
00213               //              std::cout << getpid() << "eol::::alignLsToLast_ " << alignLsToLast_ << std::endl;
00214             }
00215             else{
00216               //              std::cout << getpid() << "eol::realign ls::for " << (-1)*retval << std::endl;
00217               luminosityBlockNumber_ = nextLsFromSignal;
00218               newLumi_ = true;
00219               lumiSectionIndex_->value_ = luminosityBlockNumber_;
00220               resetLuminosityBlockAuxiliary();
00221             }
00222           }
00223         //      else
00224         //        std::cout << getpid() << "::skipping end-of-lumi for " << (-1)*retval << std::endl;
00225       }
00226     else
00227       {
00228         if (eventId.event() == 0) {
00229           throw edm::Exception(errors::LogicError)
00230             << "The reader used with DaqSource has returned an invalid (zero) event number!\n"
00231             << "Event numbers must begin at 1, not 0.";
00232         }
00233         EventSourceSentry(*this);
00234         setTimestamp(tstamp);
00235     
00236         unsigned char *gtpFedAddr = fedCollection->FEDData(daqsource::gtpEvmId_).size()!=0 ? fedCollection->FEDData(daqsource::gtpEvmId_).data() : 0;
00237         uint32_t gtpsize = 0;
00238         if(gtpFedAddr !=0) gtpsize = fedCollection->FEDData(daqsource::gtpEvmId_).size();
00239         unsigned char *gtpeFedAddr = fedCollection->FEDData(daqsource::gtpeId_).size()!=0 ? fedCollection->FEDData(daqsource::gtpeId_).data() : 0; 
00240 
00241         unsigned int nextFakeLs = 0;
00242         eventCounter_++;
00243         if(fakeLSid_ && luminosityBlockNumber_ != 
00244            (nextFakeLs = useEventCounter_ ? ((eventCounter_-1)/lumiSegmentSizeInEvents_ + 1) :
00245             ((eventId.event() - 1)/lumiSegmentSizeInEvents_ + 1))) {
00246           lastLumiPrescaleIndex_->value_ = prescaleSetIndex_->value_;
00247           prescaleSetIndex_->value_ = 0; // since we do not know better but we want to be able to run
00248           
00249           if(luminosityBlockNumber_ == nextFakeLs-1)
00250             signalWaitingThreadAndBlock();
00251           luminosityBlockNumber_ = nextFakeLs;
00252           thisEventLSid = nextFakeLs-1;
00253           newLumi_ = true;
00254           lumiSectionIndex_->value_ = luminosityBlockNumber_;
00255           resetLuminosityBlockAuxiliary();
00256           if(keepUsingPsidFromTrigger_ && 
00257              gtpFedAddr!=0 && evf::evtn::evm_board_sense(gtpFedAddr,gtpsize)){
00258             prescaleSetIndex_->value_  = (evf::evtn::getfdlpsc(gtpFedAddr) & 0xffff);
00259           }       
00260         }
00261         else if(!fakeLSid_){ 
00262 
00263           if(gtpFedAddr!=0 && evf::evtn::evm_board_sense(gtpFedAddr,gtpsize)){
00264             lastLumiPrescaleIndex_->value_ = prescaleSetIndex_->value_;
00265             thisEventLSid = evf::evtn::getlbn(gtpFedAddr);
00266             prescaleSetIndex_->value_  = (evf::evtn::getfdlpsc(gtpFedAddr) & 0xffff);
00267             evttype =  edm::EventAuxiliary::ExperimentType(evf::evtn::getevtyp(gtpFedAddr));
00268             if(luminosityBlockNumber_ != (thisEventLSid + 1)){
00269               // we got here in a running process and some Ls might have been skipped so set the flag, 
00270               // increase by one, check and if appropriate set the flag then continue
00271               if(lsToBeRecovered_->value_){
00272                 //              std::cout << getpid() << "eve::recover ls::for " << thisEventLSid << std::endl;
00273                 signalWaitingThreadAndBlock();
00274                 luminosityBlockNumber_++;
00275                 newLumi_ = true;
00276                 lumiSectionIndex_->value_ = luminosityBlockNumber_;
00277                 resetLuminosityBlockAuxiliary();
00278                 if(luminosityBlockNumber_ != thisEventLSid+1) alignLsToLast_ = true;
00279                 //              std::cout << getpid() << "eve::::alignLsToLast_ " << alignLsToLast_ << std::endl;
00280               }
00281               else{ // we got here because the process was restarted. just realign the ls id and proceed with this event
00282                 //              std::cout << getpid() << "eve::realign ls::for " << thisEventLSid << std::endl;
00283                 luminosityBlockNumber_ = thisEventLSid + 1;
00284                 newLumi_ = true;
00285                 lumiSectionIndex_->value_ = luminosityBlockNumber_;
00286                 resetLuminosityBlockAuxiliary();
00287                 lsToBeRecovered_->value_ = true;
00288               }
00289             }
00290           }
00291           else if(gtpeFedAddr!=0 && evf::evtn::gtpe_board_sense(gtpeFedAddr)){
00292             lastLumiPrescaleIndex_->value_ = prescaleSetIndex_->value_;
00293             thisEventLSid = evf::evtn::gtpe_getlbn(gtpeFedAddr);
00294             prescaleSetIndex_->value_ = 0; //waiting to get a PS index from gtpe
00295             evttype =  edm::EventAuxiliary::PhysicsTrigger; 
00296             if(luminosityBlockNumber_ != (thisEventLSid + 1)){
00297               if(luminosityBlockNumber_ == thisEventLSid)
00298                 signalWaitingThreadAndBlock();
00299               luminosityBlockNumber_ = thisEventLSid + 1;
00300               newLumi_ = true;
00301               lumiSectionIndex_->value_ = luminosityBlockNumber_;
00302               resetLuminosityBlockAuxiliary();
00303             }
00304           }
00305         }
00306         if(gtpFedAddr!=0 && evf::evtn::evm_board_sense(gtpFedAddr,gtpsize)){
00307           bunchCrossing =  int(evf::evtn::getfdlbx(gtpFedAddr));
00308           orbitNumber =  int(evf::evtn::getorbit(gtpFedAddr));
00309           TimeValue_t time = evf::evtn::getgpshigh(gtpFedAddr);
00310           time = (time << 32) + evf::evtn::getgpslow(gtpFedAddr);
00311           Timestamp tstamp(time);
00312           setTimestamp(tstamp);      
00313         }
00314         else if(gtpeFedAddr!=0 && evf::evtn::gtpe_board_sense(gtpeFedAddr)){
00315           bunchCrossing =  int(evf::evtn::gtpe_getbx(gtpeFedAddr));
00316           orbitNumber =  int(evf::evtn::gtpe_getorbit(gtpeFedAddr));
00317         }
00318       }    
00319           
00320     //    std::cout << "lumiblockaux = " << luminosityBlockAuxiliary() << std::endl;
00321     // If there is no luminosity block principal, make one.
00322     if (!luminosityBlockAuxiliary() || luminosityBlockAuxiliary()->luminosityBlock() != luminosityBlockNumber_) {
00323       newLumi_ = true;
00324       setLuminosityBlockAuxiliary(new LuminosityBlockAuxiliary(
00325         runNumber_, luminosityBlockNumber_, timestamp(), Timestamp::invalidTimestamp()));
00326 
00327       readAndCacheLumi();
00328       setLumiPrematurelyRead();
00329       //      std::cout << "nextItemType: dealt with new lumi block principal, retval is " << retval << std::endl;
00330     }
00331     //    std::cout << "here retval = " << retval << std::endl;
00332     if(retval<0){
00333       //      std::cout << getpid() << " returning from getnextitem because retval < 0 - IsLumi "
00334       //                << IsLumi << std::endl;
00335       if(newLumi_) return IsLumi; else return getNextItemType();
00336     }
00337 
00338     // make a brand new event
00339     eventId = EventID(runNumber_,thisEventLSid+1, eventId.event());
00340     std::auto_ptr<EventAuxiliary> eventAux(
00341       new EventAuxiliary(eventId, processGUID(),
00342                          timestamp(),
00343                          true,
00344                          evttype,
00345                          bunchCrossing,
00346                          EventAuxiliary::invalidStoreNumber,
00347                          orbitNumber));
00348     eventPrincipalCache()->fillEventPrincipal(eventAux, luminosityBlockPrincipal());
00349     eventCached_ = true;
00350     
00351     // have fedCollection managed by a std::auto_ptr<>
00352     std::auto_ptr<FEDRawDataCollection> bare_product(fedCollection);
00353 
00354     std::auto_ptr<Event> e(new Event(*eventPrincipalCache(), moduleDescription()));
00355     // put the fed collection into the transient event store
00356     e->put(bare_product);
00357     // The commit is needed to complete the "put" transaction.
00358     e->commit_();
00359     if (newLumi_) {
00360       return IsLumi;
00361     }
00362     return IsEvent;
00363   }
00364 
00365   void
00366   DaqSource::setRun(RunNumber_t r) {
00367     assert(!eventCached_);
00368     reset();
00369     newRun_ = newLumi_ = true;
00370     runNumber_ = r;
00371     if (reader_) reader_->setRunNumber(runNumber_);
00372     noMoreEvents_ = false;
00373     resetLuminosityBlockAuxiliary();
00374   }
00375 
00376   boost::shared_ptr<RunAuxiliary>
00377   DaqSource::readRunAuxiliary_() {
00378     assert(newRun_);
00379     assert(!noMoreEvents_);
00380     newRun_ = false;
00381     return boost::shared_ptr<RunAuxiliary>(new RunAuxiliary(runNumber_, timestamp(), Timestamp::invalidTimestamp()));
00382   }
00383 
00384   boost::shared_ptr<LuminosityBlockAuxiliary>
00385   DaqSource::readLuminosityBlockAuxiliary_() {
00386     assert(!newRun_);
00387     assert(newLumi_);
00388     assert(!noMoreEvents_);
00389     assert(luminosityBlockAuxiliary());
00390     //assert(eventCached_); //the event may or may not be cached - rely on 
00391     // the call to getNextItemType to detect that.
00392     newLumi_ = false;
00393     return luminosityBlockAuxiliary();
00394   }
00395 
00396   EventPrincipal*
00397   DaqSource::readEvent_() {
00398     //    std::cout << "assert not newRun " << std::endl;
00399     assert(!newRun_);
00400     //    std::cout << "assert not newLumi " << std::endl;
00401     assert(!newLumi_);
00402     //    std::cout << "assert not noMoreEvents " << std::endl;
00403     assert(!noMoreEvents_);
00404     //    std::cout << "assert eventCached " << std::endl;
00405     assert(eventCached_);
00406     //    std::cout << "asserts done " << std::endl;
00407     eventCached_ = false;
00408     return eventPrincipalCache();
00409   }
00410 
00411   void
00412   DaqSource::setLumi(LuminosityBlockNumber_t) {
00413       throw edm::Exception(errors::LogicError,"DaqSource::setLumi(LuminosityBlockNumber_t lumiNumber)")
00414         << "The luminosity block number cannot be set externally for DaqSource.\n"
00415         << "Contact a Framework developer.\n";
00416   }
00417 
00418   EventPrincipal*
00419   DaqSource::readIt(EventID const&) {
00420       throw edm::Exception(errors::LogicError,"DaqSource::readIt(EventID const& eventID)")
00421         << "Random access read cannot be used for DaqSource.\n"
00422         << "Contact a Framework developer.\n";
00423   }
00424 
00425   void
00426   DaqSource::skip(int) {
00427       throw edm::Exception(errors::LogicError,"DaqSource::skip(int offset)")
00428         << "Random access skip cannot be used for DaqSource\n"
00429         << "Contact a Framework developer.\n";
00430   }
00431 
00432   void DaqSource::publish(xdata::InfoSpace *is)
00433   {
00434     is_ = is;
00435     lumiSectionIndex_      = (xdata::UnsignedInteger32*)is_->find("lumiSectionIndex");
00436     prescaleSetIndex_      = (xdata::UnsignedInteger32*)is_->find("prescaleSetIndex");
00437     lastLumiPrescaleIndex_ = (xdata::UnsignedInteger32*)is_->find("lastLumiPrescaleIndex");
00438     lsTimedOut_            = (xdata::Boolean*)is_->find("lsTimedOut");
00439     lsToBeRecovered_       = (xdata::Boolean*)is_->find("lsToBeRecovered");
00440   }
00441   void DaqSource::publishToXmas(xdata::InfoSpace *is)
00442   {
00443     mis_ = is;
00444   }
00445 
00446   void DaqSource::openBackDoor(unsigned int timeout_sec)
00447   {
00448     count++;
00449     if(count==2) throw;
00450     pthread_mutex_lock(&mutex_);
00451     pthread_mutex_unlock(&signal_lock_);
00452     timespec ts;
00453 #if _POSIX_TIMERS > 0
00454     clock_gettime(CLOCK_REALTIME, &ts);
00455 #else
00456     struct timeval tv; 
00457     gettimeofday(&tv, NULL);
00458     ts.tv_sec = tv.tv_sec + 0;
00459     ts.tv_nsec = 0;
00460 #endif
00461     ts.tv_sec += timeout_sec;
00462 
00463     int rc = pthread_cond_timedwait(&cond_, &mutex_, &ts);
00464     if(rc == ETIMEDOUT) lsTimedOut_->value_ = true; 
00465   }
00466   
00467   void DaqSource::closeBackDoor()
00468   {
00469     count--;
00470     pthread_cond_signal(&cond_);
00471     pthread_mutex_unlock(&mutex_);
00472     pthread_mutex_lock(&signal_lock_);
00473     lsTimedOut_->value_ = false; 
00474   }
00475 
00476   void DaqSource::signalWaitingThreadAndBlock()
00477   {
00478     pthread_mutex_lock(&signal_lock_);
00479     pthread_mutex_lock(&mutex_);
00480     pthread_mutex_unlock(&signal_lock_);
00481     //    std::cout << getpid() << " DS::signal from evloop " << std::endl;
00482     pthread_cond_signal(&cond_);
00483     //    std::cout << getpid() << " DS::go to wait for scalers wl " << std::endl;
00484     pthread_cond_wait(&cond_, &mutex_);
00485     pthread_mutex_unlock(&mutex_);
00486     ::usleep(1000);//allow other thread to lock
00487   }  
00488 
00489   void DaqSource::defaultWebPage(xgi::Input *in, xgi::Output *out)
00490   {
00491       std::string path;
00492       std::string urn;
00493       std::string mname;
00494       std::string query;
00495       std::string original_referrer_;
00496       try 
00497         {
00498           cgicc::Cgicc cgi(in);
00499           if ( xgi::Utils::hasFormElement(cgi,"gotostopping") )
00500             {
00501               goToStopping=true;
00502             }
00503           if ( xgi::Utils::hasFormElement(cgi,"module") )
00504             mname = xgi::Utils::getFormElement(cgi, "module")->getValue();
00505           cgicc::CgiEnvironment cgie(in);
00506           if(original_referrer_ == "")
00507             original_referrer_ = cgie.getReferrer();
00508           path = cgie.getPathInfo();
00509           query = cgie.getQueryString();
00510         }
00511       catch (const std::exception & e) 
00512         {
00513           // don't care if it did not work
00514         }
00515 
00516       using std::endl;
00517       *out << "<html>"                                                   << endl;
00518       *out << "<head>"                                                   << endl;
00519 
00520 
00521       *out << "<STYLE type=\"text/css\"> #T1 {border-width: 2px; border: solid blue; text-align: center} </STYLE> "                                      << endl; 
00522       *out << "<link type=\"text/css\" rel=\"stylesheet\"";
00523       *out << " href=\"/" <<  urn
00524            << "/styles.css\"/>"                   << endl;
00525 
00526       *out << "<title>" << moduleName_
00527            << " MAIN</title>"                                            << endl;
00528 
00529       *out << "</head>"                                                  << endl;
00530       *out << "<body onload=\"loadXMLDoc()\">"                           << endl;
00531       *out << "<table border=\"0\" width=\"100%\">"                      << endl;
00532       *out << "<tr>"                                                     << endl;
00533       *out << "  <td align=\"left\">"                                    << endl;
00534       *out << "    <img"                                                 << endl;
00535       *out << "     align=\"middle\""                                    << endl;
00536       *out << "     src=\"/evf/images/bugicon.jpg\""                     << endl;
00537       *out << "     alt=\"main\""                                        << endl;
00538       *out << "     width=\"90\""                                        << endl;
00539       *out << "     height=\"64\""                                       << endl;
00540       *out << "     border=\"\"/>"                                       << endl;
00541       *out << "    <b>"                                                  << endl;
00542       *out <<             moduleName_                                    << endl;
00543       *out << "    </b>"                                                 << endl;
00544       *out << "  </td>"                                                  << endl;
00545       *out << "  <td width=\"32\">"                                      << endl;
00546       *out << "    <a href=\"/urn:xdaq-application:lid=3\">"             << endl;
00547       *out << "      <img"                                               << endl;
00548       *out << "       align=\"middle\""                                  << endl;
00549       *out << "       src=\"/hyperdaq/images/HyperDAQ.jpg\""             << endl;
00550       *out << "       alt=\"HyperDAQ\""                                  << endl;
00551       *out << "       width=\"32\""                                      << endl;
00552       *out << "       height=\"32\""                                     << endl;
00553       *out << "       border=\"\"/>"                                     << endl;
00554       *out << "    </a>"                                                 << endl;
00555       *out << "  </td>"                                                  << endl;
00556       *out << "  <td width=\"32\">"                                      << endl;
00557       *out << "  </td>"                                                  << endl;
00558       *out << "  <td width=\"32\">"                                      << endl;
00559       *out << "    <a href=\"" << original_referrer_  << "\">"           << endl;
00560       *out << "      <img"                                               << endl;
00561       *out << "       align=\"middle\""                                  << endl;
00562       *out << "       src=\"/evf/images/spoticon.jpg\""                  << endl;
00563       *out << "       alt=\"main\""                                      << endl;
00564       *out << "       width=\"32\""                                      << endl;
00565       *out << "       height=\"32\""                                     << endl;
00566       *out << "       border=\"\"/>"                                     << endl;
00567       *out << "    </a>"                                                 << endl;
00568       *out << "  </td>"                                                  << endl;
00569       *out << "</tr>"                                                    << endl;
00570       *out << "</table>"                                                 << endl;
00571 
00572       *out << "<hr/>"                                                    << endl;
00573   
00574       *out << cgicc::form().set("method","GET").set("action", path ) 
00575            << std::endl;
00576       boost::char_separator<char> sep("&");
00577       boost::tokenizer<boost::char_separator<char> > tokens(query, sep);
00578       for (boost::tokenizer<boost::char_separator<char> >::iterator tok_iter = tokens.begin();
00579            tok_iter != tokens.end(); ++tok_iter){
00580         size_t pos = (*tok_iter).find_first_of("=");
00581         if(pos != std::string::npos){
00582           std::string first  = (*tok_iter).substr(0    ,                        pos);
00583           std::string second = (*tok_iter).substr(pos+1, (*tok_iter).length()-pos-1);
00584           *out << cgicc::input().set("type","hidden").set("name",first).set("value", second) 
00585                << std::endl;
00586         }
00587       }
00588 
00589       *out << cgicc::input().set("type","hidden").set("name","gotostopping").set("value","true")
00590            << std::endl;
00591       *out << cgicc::input().set("type","submit").set("value","Go To Stopping")              << std::endl;
00592       *out << cgicc::form()                                                << std::endl;  
00593 
00594       *out << "</body>"                                                  << endl;
00595       *out << "</html>"                                                  << endl;
00596   }
00597 }