| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

DrawHistoryAlg.cc

Go to the documentation of this file.
00001 #include "DrawHistoryAlg.h"
00002 #include "Event/SimHeader.h"
00003 #include "Event/SimParticleHistory.h"
00004 #include "Event/SimTrack.h"
00005 #include "Event/SimVertex.h"
00006 #include "Event/SimHit.h"
00007 #include "Event/SimHitHeader.h"
00008 #include "Event/SimHitCollection.h"
00009 #include "Event/SimPmtHit.h"
00010 #include "Event/SimRpcHit.h"
00011 
00012 #include "DetDesc/IDetectorElement.h"
00013 #include "DetDesc/GeometryInfoPlus.h"
00014 #include "DetDesc/IPVolume.h"
00015 #include "GaudiKernel/DeclareFactoryEntries.h"
00016 #include "GaudiKernel/ParticleProperty.h"
00017 #include "GaudiKernel/IParticlePropertySvc.h"
00018 
00019 #include "CLHEP/Units/SystemOfUnits.h"
00020 #include "HepMC/GenParticle.h"
00021 #include "HepMC/GenEvent.h"
00022 #include "HepMC/GenVertex.h"
00023 
00024 #include <fstream>
00025 #include <sstream>
00026 #include <string>
00027 
00028 DECLARE_ALGORITHM_FACTORY(DrawHistoryAlg);
00029 
00030 using namespace DayaBay;
00031 
00032 DrawHistoryAlg::DrawHistoryAlg(const std::string& name, ISvcLocator* pSvcLocator)
00033     : GaudiAlgorithm(name,pSvcLocator)
00034 {
00035     declareProperty("Location",m_location= DayaBay::SimHeaderLocation::Default,
00036                      "Location in the TES to get Event data");
00037     declareProperty("track_filename",m_track_filename = "tracks_%d.dot",
00038                     "Filename to write track structure. Use '\%d' to indicate event number.");
00039     declareProperty("trackandvertex_filename",m_trackandvertex_filename = "tracks_and_vertices_%d.dot",
00040                     "Filename to write track structure. Use '\%d' to indicate event number.");
00041     declareProperty("do_hits",m_do_hits = true,
00042                     "1 to make hits in track plot, 0 to ignore them.");
00043     declareProperty("Geometry",m_topGeoPath = "/dd/Structure/DayaBay",
00044                     "Top level geometry structure element.");
00045 }
00046 
00047 DrawHistoryAlg::~DrawHistoryAlg()
00048 {
00049 }
00050 
00051 StatusCode DrawHistoryAlg::initialize()
00052 {
00053  // service retrieval
00054   m_ppSvc =0;
00055   StatusCode sc = service("ParticlePropertySvc",m_ppSvc,true);
00056   if(sc.isFailure()){
00057     err() << "Cant' get a ParticlePropertySvc pointer." << endreq;
00058     return StatusCode::FAILURE;
00059   }  
00060 
00061   return StatusCode::SUCCESS;
00062 }
00063 
00064 StatusCode DrawHistoryAlg::finalize()
00065 {
00066   return StatusCode::SUCCESS;
00067 }
00068 
00069 std::string DrawHistoryAlg::particleName(int pdg)
00070 {
00071   ParticleProperty* p = m_ppSvc->findByStdHepID(pdg);
00072   if(p) return p->particle();
00073   std::ostringstream oss;
00074   oss << "[" << pdg << "]";
00075   return oss.str();
00076 }
00077 
00078 bool DrawHistoryAlg::volumeInfo(SimVertex& v, std::string& name, std::string& material)
00079 {
00080     static IDetectorElement* topDet = getDet<IDetectorElement>(m_topGeoPath);
00081     static IDetectorElement* lastDet = 0;
00082 
00083     // Perfer lastDet to topDet
00084     IDetectorElement* start = lastDet ? lastDet : topDet;
00085     std::string child_de_path = start->geometry()->belongsToPath(v.position(),-1);
00086     // If failed with lastDet, try again with topDet
00087     if ("" == child_de_path && lastDet) {
00088         child_de_path = topDet->geometry()->belongsToPath(v.position(),-1);
00089     }
00090     IDetectorElement* child = getDet<IDetectorElement>(child_de_path);
00091 
00092 
00093     // If still failed then game over
00094     if (!child) return false;
00095 
00096     // Optimizing cache, next vertex likely in this same DE
00097     lastDet = child;
00098 
00099     name = child->name();
00100     material = child->geometry()->lvolume()->materialName();
00101     return true;
00102 }
00103 
00104 StatusCode DrawHistoryAlg::execute()
00105 {
00106   using std::endl;
00107   
00108   DayaBay::SimHeader* header = 0;
00109   if (exist<DayaBay::SimHeader>(evtSvc(),m_location)) {
00110      header = get<DayaBay::SimHeader>(m_location);
00111   }
00112   if(!header) {
00113     warning() << "No SimHeader found." <<endreq;
00114     return StatusCode::SUCCESS;
00115   }
00116 
00117   const SimParticleHistory* h = header->particleHistory();
00118   if(!h) {
00119     warning() << "No SimParticleHistory found!" << endreq;
00120     return StatusCode::SUCCESS;
00121   }
00122 
00123   
00125   // Dot file of vertex and tracks.
00126 
00127   // sort filename
00128   std::string filename = m_trackandvertex_filename;
00129   {
00130     std::string::size_type dpos = filename.find("%d");
00131     if(dpos!=std::string::npos) {
00132       std::ostringstream oss; 
00133       oss << header->execNumber();
00134       filename.replace(dpos,2,oss.str());
00135     }
00136   }
00137   
00138   std::ofstream dot(filename.c_str());
00139   dot << "digraph G {" << endl;
00140   const std::list<SimTrack*>& tracks = h->tracks();
00141   std::list<SimTrack*>::const_iterator tit;
00142   for(tit = tracks.begin();tit!= tracks.end(); ++tit) {
00143     const SimTrack* t= *tit;
00144     const std::vector<SimVertex*>& vertices = t->vertices();
00145     dot << "// SimTrack id " << t->trackId() << endl;
00146     // Name the first vertex.
00147     dot << "v" << (long)(vertices[0]) 
00148                << " [label=\""
00149                << "SimTrack Start " << t->trackId()
00150                <<"\"]" << endl;
00151 
00152     // point back to parent vertex.
00153     // SimVertex* parent = t->parentVertex().vertex();
00154     // if(parent)  {
00155     //   dot << "v" << (int)(parent) <<" -> v" << (int)(vertices[0]);
00156     //   if(t->parentVertex().isDirect()) dot << " [ style = bold] ";
00157     //   else                             dot << " [ style = dotted ]";
00158     //   dot << ";" << endl;
00159     // }
00160     
00161     // Now the track chain.
00162     dot << "subgraph cluster" << t->trackId() <<" {" << endl;
00163     dot << "  label = \"SimTrack " << t->trackId()
00164         << "\\n" << particleName(t->particle())
00165         << "\\nparent=" << t->parentParticle()
00166         << "\\n" << "KE=" << t->vertices()[0]->kineticEnergy()/CLHEP::MeV << " MeV";
00167       for(SimTrack::descendants_map::const_iterator udit = t->unrecordedDescendants().begin();
00168           udit != t->unrecordedDescendants().end();
00169           ++udit) {
00170           dot << "\\n" << udit->second << " skipped of type " << particleName(udit->first);
00171       }
00172       dot << "\";" << endl;
00173     
00174     assert(vertices.size()>0);
00175          
00176     // The chain of vertices along the track.
00177     for(unsigned int iv = 1; iv<vertices.size(); iv++) {
00178       dot << "  v" << long(vertices[iv-1]) << "  -> v" << long(vertices[iv]);
00179       // Compute distance, dE,dx.
00180       double dx = (vertices[iv]->position()-vertices[iv-1]->position()).R();
00181       double dE = (vertices[iv]->totalEnergy()-vertices[iv-1]->totalEnergy());
00182       dot << "[label=\""
00183           << "dx=" << dx/CLHEP::cm << " cm"
00184           << "\\ndE=" << dE/CLHEP::MeV << " MeV"
00185           << "\"]";
00186       dot << ";" << endl;
00187     }
00188 
00189     dot << "}" << endl;
00190     // Do secondaries.
00191     for(unsigned int iv = 0; iv<vertices.size(); iv++) {
00192       const SimVertex* v = vertices[iv];
00193       const std::vector<SimTrackReference>& secs = v->secondaries();
00194       for(unsigned int isec = 0; isec < secs.size(); ++ isec){
00195         const SimTrack*  trk = secs[isec].track();
00196         if(trk) {
00197           dot << "v" << (long)v << " -> v" << (long)(trk->vertices()[0]);
00198           if(secs[isec].isIndirect())
00199             dot << "[ style = dotted ]";
00200           dot << ";" << endl;
00201         }
00202       }
00203     }    
00204   }
00205   
00206   // Just declare each vertex, see if there are wierd ones around.
00207   const std::list<SimVertex*>& verts = h->vertices();
00208   dot << endl << "// Dump of all " << verts.size() << " vertices" << endl;
00209   std::list<SimVertex*>::const_iterator vit;
00210   for(vit = verts.begin(); vit!= verts.end(); ++vit) {
00211     SimVertex* v = *vit;
00212     dot << "v" << (long)(v);  
00213     dot << " [label=\""; 
00214     dot << v->kineticEnergy()/CLHEP::MeV << " MeV";
00215 
00216     std::string name, material;
00217     if (volumeInfo(*v,name,material)) {
00218         dot << "\\n" << name;
00219         dot << "\\n" << material;
00220     }
00221     dot << "\"]" << endl;
00222     dot << ";" << endl;
00223   }
00224   dot << "}" << endl;
00225   dot.close();
00226   
00228   // Dot file of tracks, hits, and primaries.
00229   
00230   // sort filename
00231   filename = m_track_filename;
00232   {
00233     std::string::size_type dpos = filename.find("%d");
00234     if(dpos!=std::string::npos) {
00235       std::ostringstream oss;
00236       oss << header->execNumber();
00237       filename.replace(dpos,2,oss.str());
00238     }
00239   }
00240   
00241   dot.open(filename.c_str());
00242   dot << "digraph G {" << endl;
00243 
00244   // Create hooks from primary particles to first tracks.
00245   std::set<const HepMC::GenEvent*> primaryEvents;
00246   const std::list<const SimTrack*>& primaries = h->primaryTracks();
00247   std::list<const SimTrack*>::const_iterator it;
00248   for(it = primaries.begin();it!= primaries.end(); ++it) {
00249     // Get the primary.
00250     const HepMC::GenParticle* primaryParticle =  (*it)->primaryParticle();
00251     const HepMC::GenEvent* gev = primaryParticle->parent_event();
00252     primaryEvents.insert(gev);
00253     dot << "  primaryEvent" << (long)(gev) << ":genpar" << (long)(primaryParticle);
00254     dot << " -> track" << (long)(*it) << endl; 
00255   }
00256   
00257   // create record-like nodes for the primary events.
00258   std::set<const HepMC::GenEvent*>::iterator gevit;
00259   for(gevit = primaryEvents.begin() ; gevit != primaryEvents.end(); gevit++){
00260     const HepMC::GenEvent* gev = *gevit;
00261     dot << "  primaryEvent" << (long)(gev) << " [shape=record,rank=source,label=\"{";
00262     dot << "event " << gev->event_number() <<"\\nprocess_id=" << gev->signal_process_id() << "| {";
00263     
00264     HepMC::GenEvent::particle_const_iterator parit = gev->particles_begin();
00265     while(parit != gev->particles_end()) {
00266       const HepMC::GenParticle* gpar = *parit;
00267       HepMC::FourVector momentum(gpar->momentum());
00268       double pmag = HepMC::ThreeVector(momentum).mag();
00269       double ke = momentum.e() - sqrt(momentum.e()*momentum.e() - pmag*pmag);
00270       dot << "<" << "genpar" << (long)(gpar) << "> ";
00271       dot << particleName(gpar->pdg_id())
00272           << "\\n KE=" << ke/CLHEP::MeV << " MeV";
00273       parit++;
00274       if(parit != gev->particles_end()) dot << " | ";
00275     }
00276     
00277     dot << "} }\"];" << endl;    
00278   }
00279    
00280 
00281   // Now the actual tracks.
00282   dot << "subgraph cluster_of_the_tracks {" << endl;
00283   for(tit = tracks.begin();tit!= tracks.end(); ++tit) {
00284     const SimTrack* t= *tit;
00285     dot << "track" << (long)(t)
00286         << "[label=\""
00287         << "SimTrack " << t->trackId()
00288         << "\\n" << particleName(t->particle())
00289         //<< "\\nparent=" << t->parentParticle()
00290         << "\\n" << t->vertices()[0]->process().type() << " " <<  t->vertices()[0]->process().name()
00291         << "\\n" << "KE=" << t->vertices()[0]->kineticEnergy()/CLHEP::MeV << " MeV"
00292         << "\\n" << "with " << t->vertices().size() << " vertices";
00293       for(SimTrack::descendants_map::const_iterator udit = t->unrecordedDescendants().begin();
00294           udit != t->unrecordedDescendants().end();
00295           ++udit) {
00296           dot << "\\n" << udit->second << " skipped of type " << particleName(udit->first);
00297        }        
00298     dot << "\"];" << endl;
00299 
00300     if(t->ancestorTrack().track()) {
00301       dot << "track" << (long)(t->ancestorTrack().track()) << " -> track" <<  (long)(t);
00302       if(! t->ancestorTrack().isDirect())
00303         dot << " [ style = dotted label=\"" << t->ancestorTrack().indirection() << "\"]";
00304       dot << ";" << endl;
00305     }
00306   }
00307   dot << "}" << endl; // end subgraph
00308   
00309   
00310   // Now the hits that resulted from the tracks.
00311   if(m_do_hits) {
00312     SimHitHeader::hc_map::const_iterator hcit = header->hits()->hitCollection().begin();
00313     for( ; hcit != header->hits()->hitCollection().end(); hcit ++){
00314       const SimHitCollection* hc = hcit->second;
00315       for(unsigned int ihit = 0; ihit<hc->collection().size(); ihit++) {
00316         const SimHit* simhit = hc->collection()[ihit];
00317         // the simhit description.
00318       
00319         dot << "simhit" << (long)(simhit) << "[shape=triangle,rank=sink,label=\"";
00320         if(dynamic_cast<const SimPmtHit*>(simhit))       dot << "Pmt";
00321         else if(dynamic_cast<const SimRpcHit*>(simhit))  dot << "Rpc";
00322         else                                             dot << "Hit";      
00323         dot << "\\nID=" 
00324             << ((simhit->sensDetId()&(0xFF000000))>>24) << "."
00325             << ((simhit->sensDetId()&(0xFF0000))>>16) <<  "."
00326             << ((simhit->sensDetId()&(0xFF00))>>8) << "."
00327             << ((simhit->sensDetId()&(0xFF)))
00328             <<"\"];" << endl;
00329       
00330         // connect track to hit.
00331         dot << " track" << (long)(simhit->ancestor().track()) << " -> simhit" << (long)(simhit);
00332         if(! simhit->ancestor().isDirect())
00333            dot << " [ headport = n, style = dotted, label=\"" << simhit->ancestor().indirection() << "\"]";
00334         dot << ";" << endl;
00335       }
00336     }
00337   }
00338 
00339   dot << "}" << endl;
00340   dot.close();
00341   
00342   return StatusCode::SUCCESS;
00343 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:54:53 2011 for Historian by doxygen 1.4.7