Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

CompositeDiffuse.cxx

Go to the documentation of this file.
00001 #include "CompositeDiffuse.h"
00002 #include "CLHEP/Random/RandFlat.h"
00003 #include "FluxSvc/FluxSource.h"
00004 #include "SimpleSpectrum.h"
00005 #include <strstream>
00006 
00007 void CompositeDiffuse::addSource (EventSource* aSource)
00008 {
00009     m_sourceList.push_back(aSource);
00010     //flux should ensure proper units.
00011     // want EVERYTHING in particles/sec/m^2/steradian.
00012     double flux = aSource->flux(EventSource::time());
00013     //std::cout << "adding source of flux " << flux << std::endl;
00014     //EventSource::setFlux( flux );
00015     m_unclaimedFlux-=flux;
00016 }
00017 
00018 FluxSource* CompositeDiffuse::event (double time)
00019 {
00020     //Purpose: To determine which contained source is currently represented
00021     //Input: Current time
00022     //Output: Pointer to the current represented FluxSource object.
00023     EventSource::setTime(time);
00024     
00025     int m_numofiters=0;
00026     
00027     // here we should be setting the total rate as the maximum sum rate of everything - FIX!
00028     // double mr = rate(EventSource::time());
00029     double mr = m_totalFlux;
00030     
00031     // do this once if there is no source, or no rate at all (null source?)
00032     if( m_sourceList.size()==0 || mr == 0) {
00033         m_recent = m_sourceList.front();
00034     }else {
00035         
00036         // more than one:: choose on basis of relative rates
00037         double  x = RandFlat::shoot(mr), y = 0;
00038         std::vector<EventSource*>::iterator  now = m_sourceList.begin();
00039         std::vector<EventSource*>::iterator  it = now;
00040         
00041         double intrval=0.,intrmin=100000.;
00042         
00043         for ( int q=0; now != m_sourceList.end(); ++now) {
00044             (*now)->event(time); // to initialize particles, so that the real interval for the particle is gotten.
00045             intrval=(*now)->interval(EventSource::time());
00046             
00047             if(intrval < intrmin){
00048                 it=now;
00049                 intrmin=intrval;
00050                 m_numofiters=q;
00051             }
00052             
00053             m_recent = (*it);
00054             q++;
00055         }
00056         //so now m_recent is the "soonest" source, and intrmin is the "soonest": time.
00057         // but, what if the "leftover" flux sends a source even faster?
00058         intrval=remainingFluxInterval();
00059         if(intrval < intrmin){
00060             
00061             addNewSource();
00062             intrmin=intrval;
00063             //++now;
00064             //m_recent = *(m_sourceList.end());
00065             it = m_sourceList.end();
00066             --it;
00067             m_recent = (*it);
00068         }
00069         //set the interval that won out after everything.
00070         setInterval(intrmin);
00071     }
00072     //update the time
00073     //m_time += interval(m_time);
00074     // now ask the chosen one to generate the event, if there is a rate
00075     return (FluxSource*)m_recent;//->event(time);
00076 }
00077 
00078 
00079 void CompositeDiffuse::addNewSource(){
00080     //here, set the flux in a random fashion, determined by the log N/ log S characteristic graph
00081     double flux=1.0;
00082     flux = getRandomFlux();
00083     //Set up the spectrum with the appropriate power spectrum
00084     Spectrum * spec=new SimpleSpectrum("gamma", 100.0);
00085     
00086     // Now make the random vector correesponding to random galactic direction
00087     double  costh = -RandFlat::shoot(-1.,1./*_minCos, _maxCos*/);
00088     double  sinth = sqrt(1.-costh*costh);
00089     double  l = RandFlat::shoot(-180, 180);       
00090     double b = (acos(costh)*180/M_PI)-90.;
00091     EventSource* aSource=new FluxSource(flux,spec,l,b);
00092     PointSourceData thissource; 
00093     thissource.flux = flux;
00094     thissource.l = l;
00095     thissource.b = b;
00096     //thissource.energyIndex = spec;
00097     m_listOfDiffuseSources.push_back(thissource);
00098     
00099     FluxSource* abc = (FluxSource*)aSource;
00100     //then add it into the list of sources..
00101     addSource(aSource);
00102     //..and subtract the total flux from what remains...
00103     m_unclaimedFlux -= flux;
00104 }
00105 
00106 
00107 double CompositeDiffuse::remainingFluxInterval(){
00108     //std::cout << "unclaimed flux is " << m_unclaimedFlux << std::endl;
00109     
00110     double  r = (solidAngle()*(m_unclaimedFlux)*6.);
00111     
00112     if (r <= 0){ return 1E20;
00113     }else{  
00114         double p = RandFlat::shoot(1.);
00115         return (-1.)*(log(1.-p))/r;
00116     }
00117     
00118 }
00119 
00120 long double CompositeDiffuse::logNlogS(long double flux){
00121     //READ MY LIPS - THIS NEEDS TO DO A PROPER INTERPOLATION!!!
00122     //Purpose:  this is designed to interpolate over the logN/logS characteristic.
00123     //Input:  the flux (in linear units)
00124     //Output:  the number of sources per 1/5 decade, at the input flux.
00125     //Caveats: the vector should be sorted - right now the file needs to be in order of ascending flux
00126     int i = 0;
00127     double logHighFlux,logLowFlux;
00128     i++; //there needs to be at least a space of 1 data point for measurement.
00129     while( (log10(flux) - m_logNLogS[i].first >= 0) && (m_logNLogS[i].first!=m_maxFlux) ){
00130         i++;
00131     }
00132     logHighFlux = m_logNLogS[i].first;
00133     double logHighSources = m_logNLogS[i].second;
00134     logLowFlux = m_logNLogS[i-1].first;
00135     double logLowSources = m_logNLogS[i-1].second;
00136     
00137     double logNumSources = logLowSources + ((logHighSources-logLowSources)*(log10(flux)-logLowFlux));
00138     //std::cout << "loglowsources = " << logLowSources << std::endl;
00139     
00140     return pow(10,logNumSources);
00141 }
00142 
00143 double sizeOfFifthDecade(double currentFlux){
00144     return currentFlux*(pow(10,0.2)-1.);
00145 }
00146 
00147 double CompositeDiffuse::getRandomFlux(){
00148     //NEED TO SET TOTAL INTEGRATED FLUX!!!!
00149     long double prob=RandFlat::shoot(m_totalIntegratedFlux);
00150     //long double dx=0.0000000000001;
00151     long double dx=1E-4;
00152     std::cout << "prob=" << prob << std::endl;
00153     
00154     double currentFlux = m_minFlux;
00155     while(prob > 0 && currentFlux<m_maxFlux){
00156         //dx=0.01*pow(10.0,log10(i));
00157         double sourcesPerFlux = logNlogS(currentFlux)/sizeOfFifthDecade(currentFlux);
00158         //std::cout << "currentFlux= " << currentFlux << ", logNlogS(currentFlux) = " << logNlogS(currentFlux) << std::endl;
00159         prob-=(dx)* sourcesPerFlux * currentFlux;
00160         currentFlux+=(dx) * currentFlux;
00161         //std::cout << currentFlux << std::endl;
00162         //      printf("\nin the findandaddnew loop; i=%12.10e, prob=%12.10e, dx=%12.10e , logi=%lf\n",i,prob,dx,log10(i));
00163     }
00164     std::cout << "New Source created in CompositeDiffuse, with flux = " << currentFlux << std::endl;
00165     return currentFlux;
00166 }
00167 
00168 void CompositeDiffuse::setFileFlux(){
00169     double  currentFlux = m_minFlux ;
00170     m_totalIntegratedFlux = 0.;  //to initialize
00171     //long double dx=0.0000000000001; 
00172     long double dx=1E-4;
00173     while(currentFlux < m_maxFlux){
00174         double sourcesPerFlux = logNlogS(currentFlux)/sizeOfFifthDecade(currentFlux);
00175         m_totalIntegratedFlux+=(dx)* sourcesPerFlux * currentFlux;
00176         currentFlux+=(dx) * currentFlux;
00177         //std::cout << "m_currentFlux = " << currentFlux << std::endl;
00178         
00179     }
00180     std::cout << "m_integratedFlux = " << m_totalIntegratedFlux << std::endl;
00181     
00182 }
00183 
00184 std::string CompositeDiffuse::writeXmlFile(const std::vector<std::string>& fileList) {
00198     std::strstream fileString;
00199     // Unique tag to add to ENTITY elements in the DTD.
00200     char libchar = 'a';
00201     std::string inFileName;
00202     
00203     std::vector<std::string>::const_iterator iter = fileList.begin();
00204     
00205     //the default DTD file
00206     inFileName=m_dtd;
00207     //replace $(FLUXROOT) by its system variable
00208     xml::IFile::extractEnvVar(&inFileName);
00209     
00210     //this stuff goes in the beginnning of the XML file to be read into the parser
00211     fileString << "<?xml version='1.0' ?>" << std::endl << "<!DOCTYPE data_library" 
00212         << " SYSTEM " << '"' << inFileName << '"' << " [" << std::endl;
00213     
00214     //as long as there are files in the file list...
00215     for (;iter != fileList.end(); iter++) {
00216         
00217         // get the file name, and evaluate any system variables in it
00218         inFileName=(*iter).c_str();
00219         xml::IFile::extractEnvVar(&inFileName);
00220         
00221         //then make an ENTITY entry specifying where the file is
00222         fileString << "<!ENTITY " << "library" << libchar << " SYSTEM " << '"' 
00223             << inFileName << "\" >" << std::endl;      
00224         libchar++;
00225     }
00226     
00227     fileString << "]>" << std::endl << "<data_library>" << std::endl;
00228     iter = fileList.begin();
00229     libchar = 'a';
00230     
00231     //as long as there are files in the file list...
00232     for (;iter != fileList.end(); iter++) {
00233         // add a reference to the file name
00234         fileString << "&library" << libchar << ";" << std::endl;       
00235         libchar++;
00236     }
00237     
00238     fileString << "</data_library>" << '\0';
00239     return fileString.str();
00240     
00241 }
00242 
00243 void CompositeDiffuse::fillTable(){
00244     
00245     m_dtd = "$(FLUXSVCROOT)/xml/FluxSvcParams.dtd";
00246     std::string xmlFile = "$(FLUXSVCROOT)/xml/FluxSvcParams.xml";
00247     
00248     xml::XmlParser parser;
00249     
00250     //prepare the XML file
00251     std::vector<std::string> fileList;
00252     fileList.push_back(xmlFile);
00253     
00254     //then create the parser input.
00255     std::string xmlFileIn = writeXmlFile( fileList);
00256     
00257     // a quick way of displaying what goes to the parser
00258     //std::cout << xmlFileIn <<std::endl;
00259     
00260     DOM_Document m_library_doc = parser.parse(xmlFileIn);
00261     
00262     if (m_library_doc == DOM_Document()) {
00263         std::cout << "Parse error: processing the document" << std::endl
00264             << xmlFileIn << std::endl;
00265         return;
00266     }
00267     
00268     // Root element is of type data_library.  Content is
00269     // one or more datatable elements.
00270     
00271     DOM_Element s_library = m_library_doc.getDocumentElement();
00272     
00273     // loop through the data elements to create a map of names, DOM_Elements
00274     if (s_library != DOM_Element()) {
00275         
00276         DOM_Element child = xml::Dom::getFirstChildElement(s_library);
00277         DOM_Element toplevel = xml::Dom::getFirstChildElement(s_library);
00278         
00279         while (child != DOM_Element()) {
00280             while (child.getAttribute("name") == DOMString()) {
00281                 s_library = child;
00282                 child = xml::Dom::getFirstChildElement(s_library);
00283             }
00284             
00285             while (child != DOM_Element()) {
00286                 std::string name = xml::Dom::transToChar(child.getAttribute("name"));
00287                 m_sources[name]=child;
00288                 child = xml::Dom::getSiblingElement(child);
00289             }
00290             
00291             child = xml::Dom::getSiblingElement(toplevel);
00292             toplevel=child;
00293         }
00294         
00295     }
00296     
00297     //now get the desired data table:
00298     DOM_Element characteristic = m_sources["logNlogScharacteristic"];
00299     
00300     
00301     DOM_Element sname = xml::Dom::getFirstChildElement(characteristic);
00302     if (sname == DOM_Element() ) {
00303         std::cout << "Improperly formed XML event source" << std::endl;
00304         return;
00305     }
00306     
00307     DOM_Element toplevel=sname;
00308     // If we got here, should have legit child element
00309     while (/*(sname.getTagName()).equals("logNlogSdata")*/sname != DOM_Element()) {
00310         double logflux = atof(xml::Dom::transToChar(sname.getAttribute("logflux")));
00311         double lognumsources = atof(xml::Dom::transToChar(sname.getAttribute("lognumsources")));
00312         m_logNLogS.push_back(std::make_pair<double,double>(logflux, lognumsources));
00313         
00314         //std::cout << logflux << " , " << lognumsources << std::endl;
00315         sname = xml::Dom::getSiblingElement(toplevel);
00316         toplevel=sname;
00317     }
00318     //now figure out the maximum and minimum fluxes.
00319     m_minFlux = pow(10,(*m_logNLogS.begin()).first);
00320     m_maxFlux = pow(10,(m_logNLogS.back()).first);
00321     //std::cout << m_minFlux << "   " << m_maxFlux<<std::endl;
00322     return;          
00323 }
00324 
00325 
00328 char* CompositeDiffuse::writeLogHistogram(){
00329     
00330     std::vector<std::pair<double,double> > currentHistPoints;
00331     //the histogram starts at minFlux, ends at maxFlux, and holds number of events.
00332     for(double curFlux = m_minFlux ; curFlux*(1.+sizeOfFifthDecade(curFlux)) <=m_maxFlux ; curFlux+=/*curFlux**/sizeOfFifthDecade(curFlux) ){
00333         currentHistPoints.push_back(std::make_pair<double,double>(curFlux,0.));  
00334     }
00335     
00336     std::vector<PointSourceData>::iterator now= m_listOfDiffuseSources.begin();
00337     for ( ; now != m_listOfDiffuseSources.end(); now++) {
00338         //std::vector<std::pair<double,double> >::iterator iter;
00339         for(int i=0 ; i <= currentHistPoints.size() ; i++){
00340             if(currentHistPoints[i].first<=(*now).flux && currentHistPoints[i+1].first>=(*now).flux) currentHistPoints[i].second++;
00341         }
00342     }
00343     //then we want to change the histogram bins to be centered in their ranges, and log everything
00344     std::vector<std::pair<double,double> >::iterator iter;
00345     for(iter=currentHistPoints.begin() ; iter!=currentHistPoints.end() ; iter++){
00346         (*iter).first = log10((*iter).first);
00347         (*iter).second = log10((*iter).second);
00348         (*iter).first += 1/10.;
00349     }
00350     //now, the output:
00351     std::strstream out2;// = new std::strstream;
00352     for(iter=currentHistPoints.begin() ; iter!=currentHistPoints.end() ; iter++){
00353         out2 << (*iter).first << '\t' << (*iter).second << std::endl;
00354     }
00355     std::cout << out2.str(); //WHY IS THERE JUNK ON THE END OF IT?
00356     return out2.str();
00357     
00358 }
00359 
00360 
00362 void CompositeDiffuse::writeSourceCharacteristic(std::ostream& out){
00363     out << fullTitle() << std::endl;
00364     out << "Diffuse Added Point Sources:" << std::endl;
00365     out << "l" << '\t' << "b" <<'\t' << "flux" << '\t'<< "energyIndex" << std::endl << std::endl;
00366     
00367     std::vector<PointSourceData>::iterator now= m_listOfDiffuseSources.begin();
00368     for ( ; now != m_listOfDiffuseSources.end(); now++) {
00369         out << (*now).l << '\t' <<(*now).b << '\t' << (*now).flux << '\t' << (*now).energyIndex << std::endl;
00370     }
00371     out << "histogram of reconstructed logN/logS:" << std::endl;
00372     out << "flux(integrated over 1/5 decade)" << '\t' << "number of sources" << std::endl << std::endl;
00373     out << writeLogHistogram() << std::endl;
00374     
00375 }

Generated on Wed Oct 16 14:01:29 2002 by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001