Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

acdReconAlg.cxx

Go to the documentation of this file.
00001 #include "acdReconAlg.h"
00002 
00004 #include "GaudiKernel/MsgStream.h"
00005 #include "GaudiKernel/AlgFactory.h"
00006 #include "GaudiKernel/IDataProviderSvc.h"
00007 #include "GaudiKernel/SmartDataPtr.h"
00008 
00009 #include "GaudiKernel/SmartDataPtr.h"
00010 #include "GaudiKernel/StatusCode.h"
00011 
00012 
00014 #include "GlastEvent/TopLevel/EventModel.h"
00015 #include "GlastEvent/TopLevel/Event.h"
00016 #include "GaudiKernel/ObjectVector.h"
00017 #include "GlastEvent/data/TdGlastData.h"
00018 
00020 #include "TkrRecon/SiRecObjs.h"
00021 #include "TkrRecon/GFparticle.h"
00022 #include "TkrRecon/GFdata.h"
00023 #include "TkrRecon/GFgamma.h"
00024 
00025 #include "geometry/Point.h"
00026 #include "geometry/Vector.h"
00027 #include "geometry/Box.h"
00028 
00029 #include "xml/IFile.h"
00030 
00031 #include "idents/AcdId.h"
00032 
00033 
00034 #include <algorithm>
00035 #include <cstdio>
00036 #include <stdlib.h>
00037 
00038 double acdReconAlg::threshold_energy;
00039 
00040 int acdReconAlg::xNumTowers;
00041 int acdReconAlg::yNumTowers;
00042 int acdReconAlg::xNumTopTiles;
00043 int acdReconAlg::yNumTopTiles;
00044 int acdReconAlg::numSideRows;
00045 
00046 
00047 static float maxDOCA = 200.0;
00048 
00050 static const AlgFactory<acdReconAlg>  Factory;
00051 const IAlgFactory& acdReconAlgFactory = Factory;
00052 
00055 acdReconAlg::acdReconAlg(const std::string& name, ISvcLocator* pSvcLocator) :
00056 Algorithm(name, pSvcLocator) {
00057 
00059     declareProperty("tupleName",  m_tupleName="");
00060 
00061 }
00062 
00063 //------------------------------------------------------------------------------
00068 StatusCode acdReconAlg::initialize ( )
00069 {
00070 
00071     StatusCode sc = StatusCode::SUCCESS;
00072 
00073     MsgStream log(msgSvc(), name());
00074     log << MSG::INFO << "initialize" << endreq;
00075     
00076     // Use the Job options service to set the Algorithm's parameters
00078     setProperties();
00079 
00080     sc = serviceLocator()->getService("GlastDetSvc",
00081         IID_IGlastDetSvc, reinterpret_cast<IInterface*&>( m_glastDetSvc));
00082 
00083     if( sc.isFailure() ) {
00084         log << MSG::ERROR << "acdReconAlg failed to get the GlastDetSvc" << endreq;
00085         return sc;
00086     }
00087 
00088     m_tileParams = new TileParams;
00089 
00090     getParameters();
00091 
00092     // get a pointer to our ntupleWriterSvc
00093     sc = serviceLocator()->getService("ntupleWriterSvc", 
00094         IID_INTupleWriterSvc, reinterpret_cast<IInterface*&>( ntupleWriteSvc));
00095 
00096     if( sc.isFailure() ) {
00097         log << MSG::ERROR << "acdReconAlg failed to get the ntupleWriterSvc" << endreq;
00098         return sc;
00099     }
00100 
00101     /*
00102     if( service("GismoSvc", m_gismoSvc).isFailure()) {
00103         log << MSG::ERROR << "failed to find the GismoSvc" << endreq;
00104         return StatusCode::FAILURE;
00105     }*/
00106 
00107 
00108     return sc;
00109 }
00110 
00111 
00112 
00113 //------------------------------------------------------------------------------
00116 StatusCode acdReconAlg::execute() {
00117     
00118     StatusCode  sc = StatusCode::SUCCESS;
00119     MsgStream   log( msgSvc(), name() );
00120     log << MSG::DEBUG << "execute" << endreq;
00121 
00129     SmartDataPtr<TdGlastData> glastData(eventSvc(),"/Event/TdGlastData");
00130 
00131     if (glastData == 0) {
00132         log << MSG::DEBUG  << "No simulation detector data available " << endreq;
00133         return sc;
00134     }
00135 
00136     // retrieve the ACD data pointer
00137     m_AcdData = glastData->getVetoData();
00138     
00139     if (m_AcdData == 0) {
00140         log << MSG::DEBUG << "No ACD Data available " << endreq;
00141         return sc;
00142     }
00143 
00144     // run the reconstruction
00145     reconstruct(m_AcdData);
00146 
00150 
00151     log << MSG::DEBUG << "exiting ACD Recon " << endreq;
00152 
00153     return sc;
00154 }
00155 
00156 
00157 //------------------------------------------------------------------------------
00158 /*
00159 Finalize is called once at the end of event processing.
00160 Any cleanup to occur - will occur here.
00161 */
00162 StatusCode acdReconAlg::finalize() {
00163     
00164     MsgStream log(msgSvc(), name());
00165     log << MSG::INFO << "finalize" << endreq;
00166     
00167     return StatusCode::SUCCESS;
00168 }
00169 
00170 
00172 void acdReconAlg::getParameters ()
00173 {
00174 
00175     MsgStream   log( msgSvc(), name() );
00176 
00178     xml::IFile *m_ifile = const_cast<xml::IFile*>(m_glastDetSvc->iniFile()); //OOPS!
00179 
00180     threshold_energy = m_ifile->getDouble("veto", "threshold");
00181 
00182     yNumTowers = m_ifile->getInt("glast", "yNum");
00183     xNumTowers = m_ifile->getInt("glast", "xNum");
00184 
00185     xNumTopTiles = m_ifile->getInt("veto", "numXtiles");
00186     yNumTopTiles = m_ifile->getInt("veto", "numYtiles");
00187 
00188     numSideRows = m_ifile->getInt("veto", "num_side_tiles");
00189         
00190 }
00191 
00192 void acdReconAlg::clear() {
00193     m_totEnergy = 0.0;
00194     m_tileCount = 0.0;
00195     m_gammaDOCA = maxDOCA;
00196     m_DOCA = maxDOCA;
00197     m_rowDOCA_vec.clear();
00198     m_rowDOCA_vec.resize(numSideRows+1, maxDOCA);  // one for each side, plus one for the top
00199     m_act_dist = -200.0;
00200 }
00201 
00202 StatusCode acdReconAlg::reconstruct (const IVetoData* v)
00203 {
00204 
00205     StatusCode sc = StatusCode::SUCCESS;
00206 
00207     MsgStream   log( msgSvc(), name() );
00208 
00209     // reset all member variables to their defaults
00210     clear();
00211 
00212     // iterate through all hit ACD tiles
00213     for( IVetoData::const_iterator it= v->begin(); it != v->end(); ++it) {
00214         
00215         if ((*it).energy() < threshold_energy) continue; // toss out hits below threshold
00216 
00217         m_tileCount++;
00218         double tileEnergy = (*it).energy();
00219         m_totEnergy += tileEnergy;
00220         idents::AcdId id = (*it).type();
00221     }
00222 
00223     log << MSG::DEBUG << "num Tiles = " << m_tileCount << endreq;
00224     log << MSG::DEBUG << "total energy = " << m_totEnergy << endreq;
00225 
00226     m_glastDetSvc->accept(*m_tileParams);
00227 
00228     acdTileDOCA();
00229 
00230     sc = writeNTuple();
00231 
00232     return sc;
00233 }
00234 
00235 
00236 StatusCode acdReconAlg::acdTileDOCA() {
00237 
00238     StatusCode sc = StatusCode::SUCCESS;
00239 
00240     MsgStream   log( msgSvc(), name() );
00241 
00242     // Retrieve the TKR Reconstruction data
00243     SmartDataPtr<SiRecObjs> tkrRecData(eventSvc(),"/Event/TkrRecon/SiRecObjs");
00244     if (tkrRecData == 0) {
00245         log << MSG::DEBUG << "No TKR Reconstruction available " << endreq;
00246         return sc;
00247     }
00248 
00249     std::vector<const GFtrack*> xtracks;
00250     std::vector<const GFtrack*> ytracks;
00251 
00252     // Now retrieve all of the tracks
00253 
00254     int nparticles = tkrRecData->numParticles();
00255     if (nparticles > 0) {
00256 
00257         log << MSG::DEBUG << "Number of particles " << nparticles << endreq;
00258 
00259         unsigned int iParticle;
00260         for (iParticle = 0; iParticle < nparticles; iParticle++) {
00261             GFparticle *particle = tkrRecData->Particle(iParticle);
00262             xtracks.push_back(particle->getXGFtrack());
00263             ytracks.push_back(particle->getYGFtrack());
00264         }
00265     } else {
00266         log << MSG::DEBUG << "No reconstructed particles " << endreq;
00267     }
00268 
00269     int ngammas = tkrRecData->numGammas();
00270     log << MSG::DEBUG << "number of gammas = " << ngammas << endreq;
00271 
00272     if (ngammas > 0) {
00273         unsigned int iGamma;
00274         // Create a temporary vector to store the DOCA's for the 
00275         // top and side tiles - we don't want to use the reconstructed
00276         // gamma direction & vector for these DOCAs...
00277         std::vector<double> temprowDOCA_vec;
00278         temprowDOCA_vec.resize(numSideRows+1, maxDOCA); 
00279         for (iGamma = 0; iGamma < ngammas; iGamma++) {
00280             GFgamma *gamma = tkrRecData->Gamma(iGamma);
00281             Point gammaVertex = gamma->vertex();
00282             Vector gammaDirection = gamma->direction();
00283             double tempDOCA = DOCA(gammaVertex, gammaDirection, m_rowDOCA_vec);
00284             if (tempDOCA < m_gammaDOCA) m_gammaDOCA = tempDOCA;
00285             
00286             // Store the tracks associated with the gamma
00287             if (!gamma->getPair(SiCluster::X)->empty()) 
00288                 xtracks.push_back(gamma->getPair(SiCluster::X));
00289             if (!gamma->getBest(SiCluster::X)->empty()) 
00290                 xtracks.push_back(gamma->getBest(SiCluster::X));
00291             if (!gamma->getPair(SiCluster::Y)->empty())
00292                 ytracks.push_back(gamma->getPair(SiCluster::Y)); 
00293             if (!gamma->getBest(SiCluster::X)->empty())
00294                 ytracks.push_back(gamma->getBest(SiCluster::Y));
00295         }
00296     } else {
00297         log << MSG::DEBUG << "No reconstructed gammas " << endreq;
00298     }
00299 
00300     // Now we should have a list of x and y tracks
00301     // iterate through the list of tracks, and combine to create all possible
00302     // pairings of X and Y tracks.  The min DOCA is then reported as ACD_DOCA in
00303     // the ntuple
00304 
00305     for (std::vector<const GFtrack*>::const_iterator xtrk = xtracks.begin(); xtrk != xtracks.end(); xtrk++) {
00306         for(std::vector<const GFtrack*>::const_iterator ytrk = ytracks.begin(); ytrk != ytracks.end(); ytrk++) {
00307             Vector dir = Vector((*xtrk)->slope(), (*ytrk)->slope(), 1.).unit();
00308             Point x0((*xtrk)->positionAtZ(0), (*ytrk)->positionAtZ(0), 0.);
00309 
00310             float testDOCA = DOCA(x0, dir, m_rowDOCA_vec);
00311             if(testDOCA < m_DOCA) m_DOCA = testDOCA;
00312             
00313             float test_dist= hitTileDist(x0, dir);
00314             if(test_dist > m_act_dist) m_act_dist = test_dist;
00315 
00316         }
00317     }
00318    
00319     log << MSG::DEBUG << "ACD_DOCA = " << m_DOCA << endreq;
00320     log << MSG::DEBUG << "ACD_Act_dist = " << m_act_dist << endreq;
00321 
00322     return sc;
00323 
00324 }
00325 
00326 // Distance of Closest Approach (DOCA)
00327 double acdReconAlg::DOCA (const Point &x0, const Vector &t0, std::vector<double> &doca_values)
00328 {
00329     // This section looks for close-by hits to the ACD tiles
00330 
00331     float minDOCA = maxDOCA;
00332     float dist;
00333 
00334     // iterate over all tiles
00335     for( IVetoData::const_iterator it= m_AcdData->begin(); it != m_AcdData->end(); ++it) {
00336 
00337         float tile_energy = (*it).energy();
00338         if(tile_energy < threshold_energy) continue;
00339 
00340         Vector dX = (*it).position() - x0;
00341 
00342         float prod = dX * t0;
00343         dist = sqrt(dX.mag2() - prod*prod);
00344         if(dist < minDOCA){
00345             minDOCA = dist;
00346             m_hit_tile = *it;
00347         }
00348         
00349         idents::AcdId type = (*it).type();
00350 
00351         // Pick up the min. distance from each type of tile
00352         // i.e. top, and each type of side row tile
00353         if (type.top() && dist < doca_values[0]) doca_values[0] = dist;
00354         if (type.side()) {
00355             if (dist < doca_values[type.row()+1]) doca_values[type.row()+1] = dist;
00356         }
00357     }
00358 
00359     return minDOCA;
00360 }
00361 
00362 // Bill Atwood's new edge DOCA algorithm
00363 double acdReconAlg::hitTileDist(const Point &x0, const Vector &t0)
00364 {
00365     double return_dist = -200.;
00366     
00367     if(!m_AcdData) return return_dist;
00368     
00369     // iterate over all tiles
00370     for( IVetoData::const_iterator it= m_AcdData->begin(); it != m_AcdData->end(); ++it) {
00371         
00372         float eT = (*it).energy();
00373         if(eT < threshold_energy) continue;
00374         
00375         Point xT = (*it).position();
00376         idents::AcdId tileType((*it).type());
00377         int iFace = tileType.face();
00378 
00379         float dX = m_tileParams->length((*it).type());
00380         float dY = m_tileParams->width((*it).type());
00381         float dZ = m_tileParams->height((*it).type());
00382         
00383         // Figure out where in the plane of this face the trajectory hits
00384         double arc_dist = -1.; 
00385         if(iFace == 0) {// Top Tile. 
00386             arc_dist = (xT.z()-x0.z())/t0.z();                  
00387         }
00388         else if(iFace == 1 || iFace == 3) {// X Side Tile 
00389             arc_dist = (xT.x()-x0.x())/t0.x();
00390         }
00391         else if(iFace == 2 || iFace == 4) {// Y Side Tile
00392             arc_dist = (xT.y()-x0.y())/t0.y();
00393         }
00394         // If arc_dist is negative... had to go backwards to hit plane... 
00395         if(arc_dist < 0.) continue;
00396         
00397         Point x_isec = x0 + arc_dist*t0;
00398         
00399         Vector local_x0 = xT - x_isec; 
00400         if(iFace == 0) {// Top Tile
00401             double dist_x = dX/2. - fabs(local_x0.x());
00402             double dist_y = dY/2. - fabs(local_x0.y());                 
00403             double test_dist = (dist_x < dist_y) ? dist_x : dist_y;
00404             if(test_dist > return_dist) return_dist = test_dist;
00405         }
00406         else if(iFace == 1 || iFace == 3) {// X Side Tile
00407             double dist_z = dZ/2. - fabs(local_x0.z());
00408             double dist_y = dY/2. - fabs(local_x0.y());                 
00409             double test_dist = (dist_z < dist_y) ? dist_z : dist_y;
00410             if(test_dist > return_dist) return_dist = test_dist;
00411         }
00412         else if(iFace == 2 || iFace == 4) {// Y Side Tile
00413             double dist_z = dZ/2. - fabs(local_x0.z());
00414             double dist_x = dY/2. - fabs(local_x0.x());                 
00415             double test_dist = (dist_z < dist_x) ? dist_z : dist_x;
00416             if(test_dist > return_dist) return_dist = test_dist;
00417         }
00418     }
00419     return return_dist;
00420 }
00421 
00422 
00423 StatusCode acdReconAlg::writeNTuple() {
00424 
00425     StatusCode sc = StatusCode::SUCCESS;
00426     MsgStream   log( msgSvc(), name() );
00427 
00429     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_TotEnergy", m_totEnergy);
00430     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_TileCount", m_tileCount);
00431     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_DOCA", m_DOCA);
00432     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_GammaDOCA", m_gammaDOCA);
00433     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_TopDOCA", m_rowDOCA_vec[0]);
00434     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_Act_Dist", m_act_dist);
00435 
00436 
00437     // loop over all DOCA values for the sides
00438     unsigned int iDOCA;
00439     for (iDOCA = 1; iDOCA <= numSideRows; iDOCA++) {
00440         std::string label("ACD_S");
00441         char num[5];
00442         _itoa((iDOCA-1), num, 10);
00443         label += num;
00444         label += "DOCA";
00445         sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), label.c_str(), m_rowDOCA_vec[iDOCA]);
00446     }
00447 
00448     return sc;
00449 }
00450 

Generated at Wed Nov 21 12:22:56 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000