00001 // $Header: /nfs/slac/g/glast/ground/cvs/FluxSvc/src/CompositeSource.cxx,v 1.12 2002/07/25 05:18:58 srobinsn Exp $ 00002 00003 #ifdef HAVE_CONFIG_H 00004 #include "config.h" 00005 #endif 00006 00007 #include "CompositeSource.h" //TAKE THE /.. OUT! 00008 00009 #include "dom/DOM_Element.hpp" 00010 #include "facilities/Scheduler.h" 00011 #include "facilities/SimpleEvent.h" 00012 #include "CLHEP/Random/RandFlat.h" 00013 00014 // see coment below: #include "control/EventLoop.h" 00015 00016 00017 #include <strstream> 00018 #include <cassert> 00019 #include <numeric> // for accumulate 00020 #include <functional> 00021 #include <iomanip> 00022 00023 CompositeSource::CompositeSource (double aRate) 00024 : EventSource(aRate), m_recent(0),m_numofiters(0)//,m_time(0) 00025 { 00026 } 00027 00028 CompositeSource::~CompositeSource() 00029 { 00030 for (std::vector<EventSource*>::iterator it = m_sourceList.begin(); 00031 it != m_sourceList.end(); ++it ) delete (*it); 00032 } 00033 00034 00035 void CompositeSource::addSource (EventSource* aSource) 00036 { 00037 m_sourceList.push_back(aSource); 00038 EventSource::setFlux( flux(EventSource::time()) ); 00039 //here, set up the associated vectors by default. 00040 m_unusedSource.push_back(0); 00041 m_sourceInterval.push_back(-1.); 00042 } 00043 00044 void CompositeSource::rmvSource (EventSource* aSource) 00045 { 00046 std::vector<EventSource*>::iterator it = m_sourceList.begin(); 00047 for (;it != m_sourceList.end(); ++it) { 00048 if ((*it) == aSource) break; 00049 } 00050 if (it != m_sourceList.end()) { 00051 m_sourceList.erase(it); 00052 EventSource::setFlux( flux(EventSource::time()) ); 00053 } 00054 } 00055 00056 FluxSource* CompositeSource::event (double time) 00057 { 00058 int i=0; //for iterating through the m_unusedSource vector 00059 int winningsourcenum; //the number of the "winning" source 00060 00061 EventSource::setTime(time); 00062 00063 m_numofiters=0; 00064 double mr = rate(EventSource::time()); 00065 00066 if( m_sourceList.size()==1 || mr ==0) { 00067 m_recent = m_sourceList.front(); 00068 }else { 00069 00070 // more than one:: choose on basis of relative rates 00071 // NOT used? THB double x = RandFlat::shoot(mr), y = 0; 00072 std::vector<EventSource*>::iterator now = m_sourceList.begin(); 00073 std::vector<EventSource*>::iterator it = now; 00074 00075 double intrval=0.,intrmin=100000.; 00076 for (int q=0 ; now != m_sourceList.end(); ++now) { 00077 if(m_unusedSource[i]==1){ 00078 intrval=m_sourceInterval[i]; 00079 //std::cout << i << " is unused, interval is "<< intrval << std::endl; 00080 }else{ 00081 (*now)->event(time); // to initialize particles, so that the real interval for the particle is gotten. 00082 intrval=(*now)->interval(EventSource::time()); //this picks out the interval of each source 00083 m_unusedSource[i]=1; 00084 m_sourceInterval[i]=intrval; 00085 } 00086 00087 if(intrval < intrmin){ 00088 //the present source is "winning" here 00089 it=now; 00090 intrmin=intrval; 00091 m_numofiters=q; 00092 winningsourcenum=i; 00093 } 00094 00095 m_recent = (*it); 00096 q++; 00097 i++; 00098 } 00099 setInterval(intrmin); 00100 now = m_sourceList.begin(); 00101 for (q=0 ; now != m_sourceList.end(); ++now) { 00102 //this loop sets the intervals back in accordance with 00103 //how far ahead time will move. 00104 //std::cout << "decrementing source " << q << " , by " << intrmin << std::endl; 00105 m_sourceInterval[q] = m_sourceInterval[q] - intrmin; 00106 q++; 00107 } 00108 } 00109 m_unusedSource[winningsourcenum]=0; //the current "winning" source is getting used.. 00110 // now ask the chosen one to return the event. 00111 return (FluxSource*)m_recent; 00112 } 00113 00114 std::string CompositeSource::fullTitle () const 00115 { 00116 std::strstream s; 00117 std::vector<EventSource*>::const_iterator it = m_sourceList.begin(); 00118 00119 while (it != m_sourceList.end()) { 00120 00121 s << (*it)->fullTitle() << " "; 00122 ++it; 00123 if (it != m_sourceList.end()) s << "+ "; 00124 } 00125 s << '\0'; 00126 std::string t(s.str()); 00127 s.freeze(false); 00128 return t; 00129 } 00130 00131 std::string CompositeSource::displayTitle () const 00132 { 00133 return (m_recent == 0) ? "" : m_recent->displayTitle(); 00134 } 00135 00136 double CompositeSource::rate(double time) const 00137 { 00138 //m_time += m_time-time; 00139 std::vector<EventSource*>::const_iterator it = m_sourceList.begin(); 00140 double total_rate = 0.; 00141 for(;it != m_sourceList.end();++it) { 00142 double rr = fabs((*it)->rate(time)); 00143 total_rate += rr; 00144 } 00145 return total_rate; 00146 } 00147 00148 void CompositeSource::setRate ( double value ) 00149 { 00150 double f = rate(EventSource::time()); 00151 if (f == 0.) return; 00152 00153 std::vector<float> fvec; 00154 std::vector<EventSource*>::iterator it = m_sourceList.begin(); 00155 00156 while (it != m_sourceList.end()) { 00157 00158 (*it)->setRate( value * (*it)->rate(EventSource::time())/f ); 00159 ++it; 00160 } 00161 EventSource::setRate( value ); 00162 } 00163 00164 // implement virtual function 00165 void CompositeSource::setupXML (const DOM_Element&) {} 00166 00167 void CompositeSource::printOn(std::ostream& out)const 00168 { 00169 out << "Source(s), total rate="<< rate(EventSource::time()) << std::endl; 00170 00171 for( std::vector<EventSource*>::const_iterator it = m_sourceList.begin(); 00172 it != m_sourceList.end();++it) { 00173 out << std::setw(8) << std::setprecision(4) << (*it)->rate(EventSource::time()) <<" Hz, " 00174 << '#' << std::setw(6) << (*it)->eventNumber() <<' ' 00175 << (*it)->name() << ' '<< (*it)->fullTitle() << std::endl; 00176 00177 } 00178 00179 } 00180 00181 std::string CompositeSource::findSource()const 00182 { 00183 return m_recent->fullTitle(); 00184 } 00185 00186 int CompositeSource::numSource()const 00187 { 00189 return m_numofiters; 00190 } 00191
1.2.13.1 written by Dimitri van Heesch,
© 1997-2001