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

AcdReconDigiAlg.cxx

Go to the documentation of this file.
00001 #include "AcdReconDigiAlg.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 
00013 #include "GlastEvent/TopLevel/EventModel.h"
00014 #include "GlastEvent/TopLevel/Event.h"
00015 
00017 #include "TkrRecon/SiRecObjs.h"
00018 #include "TkrRecon/GFparticle.h"
00019 #include "TkrRecon/GFdata.h"
00020 #include "TkrRecon/GFgamma.h"
00021 
00022 #include "geometry/Point.h"
00023 #include "geometry/Vector.h"
00024 
00025 #include "idents/AcdId.h"
00026 #include "xml/IFile.h"
00027 
00028 #include <fstream>
00029 #include <algorithm>
00030 #include <cstdio>
00031 #include <stdlib.h>
00032 
00033 static float maxDOCA = 200.0;
00034 
00036 static const AlgFactory<AcdReconDigiAlg>  Factory;
00037 const IAlgFactory& AcdReconDigiAlgFactory = Factory;
00038 
00041 AcdReconDigiAlg::AcdReconDigiAlg(const std::string& name, ISvcLocator* pSvcLocator) :
00042 Algorithm(name, pSvcLocator) {
00043 
00045     declareProperty("tupleName",  m_tupleName="");
00046     declareProperty("xmlFile", m_xmlFileStr="");
00047     declareProperty("vetoThreshFile", m_vetoThreshFileStr="");
00048 
00049 }
00050 
00051 //------------------------------------------------------------------------------
00056 StatusCode AcdReconDigiAlg::initialize ( )
00057 {
00058 
00059     StatusCode sc = StatusCode::SUCCESS;
00060 
00061     MsgStream log(msgSvc(), name());
00062     log << MSG::INFO << "initialize" << endreq;
00063     
00064     // Use the Job options service to set the Algorithm's parameters
00066     setProperties();
00067 
00068     sc = serviceLocator()->getService("GlastDetSvc",
00069         IID_IGlastDetSvc, reinterpret_cast<IInterface*&>( m_glastDetSvc));
00070 
00071     if( sc.isFailure() ) {
00072         log << MSG::ERROR << "AcdReconDigiAlg failed to get the GlastDetSvc" << endreq;
00073         return sc;
00074     }
00075 
00076     getParameters();
00077 
00078     readThresholds();
00079 
00080     // get a pointer to our ntupleWriterSvc
00081     sc = serviceLocator()->getService("ntupleWriterSvc", 
00082         IID_INTupleWriterSvc, reinterpret_cast<IInterface*&>( ntupleWriteSvc));
00083 
00084     if( sc.isFailure() ) {
00085         log << MSG::ERROR << "AcdReconDigiAlg failed to get the ntupleWriterSvc" << endreq;
00086         return sc;
00087     }
00088 
00089     return sc;
00090 }
00091 
00092 
00093 
00094 //------------------------------------------------------------------------------
00097 StatusCode AcdReconDigiAlg::execute() {
00098     
00099     StatusCode  sc = StatusCode::SUCCESS;
00100     MsgStream   log( msgSvc(), name() );
00101     log << MSG::DEBUG << "execute" << endreq;
00102 
00110     DataObject *tempObj;
00111     sc = eventSvc()->retrieveObject("/Event/Digi/AcdDigis", tempObj);
00112     if (sc.isFailure()) {
00113         log << MSG::DEBUG << "No ACD Data available" << endreq;
00114         return StatusCode::SUCCESS;
00115     }
00116 
00117     m_AcdData = dynamic_cast<AcdDigiVector*>(tempObj);
00118     
00119     if (m_AcdData == 0) {
00120         log << MSG::DEBUG << "No ACD Data available " << endreq;
00121         return StatusCode::SUCCESS;
00122     }
00123 
00124     // run the reconstruction
00125     reconstruct(m_AcdData);
00126 
00130 
00131     log << MSG::DEBUG << "exiting ACD Recon " << endreq;
00132 
00133     return sc;
00134 }
00135 
00136 
00137 //------------------------------------------------------------------------------
00138 /*
00139 Finalize is called once at the end of event processing.
00140 Any cleanup to occur - will occur here.
00141 */
00142 StatusCode AcdReconDigiAlg::finalize() {
00143     
00144     MsgStream log(msgSvc(), name());
00145     log << MSG::INFO << "finalize" << endreq;
00146     
00147     return StatusCode::SUCCESS;
00148 }
00149 
00150 
00152 void AcdReconDigiAlg::getParameters ()
00153 {
00154 
00155     MsgStream   log( msgSvc(), name() );
00156 
00158     xml::IFile *m_ifile = new xml::IFile(m_xmlFileStr.c_str()); 
00159 
00160     std::vector<int> topIds = m_ifile->getIntVector("acdTop", "ids");
00161     std::vector<double> topX = m_ifile->getDoubleVector("acdTop", "x_center");
00162     std::vector<double> topY = m_ifile->getDoubleVector("acdTop", "y_center");
00163     std::vector<double> topZ = m_ifile->getDoubleVector("acdTop", "z_center");
00164     std::vector<double> topXlen = m_ifile->getDoubleVector("acdTop", "xlen");
00165     std::vector<double> topYlen = m_ifile->getDoubleVector("acdTop", "ylen");
00166     std::vector<double> topZlen = m_ifile->getDoubleVector("acdTop", "zlen");
00167 
00168     // Load the ids, centers and dimensions for the top tiles
00169     for (int i=0; i < topIds.size(); i++)  { 
00170         m_tileCenters[topIds[i]] = Point(topX[i], topY[i], topZ[i]);
00171         m_tileDims[topIds[i]] = Vector(topXlen[i], topYlen[i], topZlen[i]);
00172     }
00173 
00174     // Load the id and center of the bigtile
00175     int id = m_ifile->getInt("bigtile", "id");
00176     double bigX = m_ifile->getDouble("bigtile", "x_center");
00177     double bigY = m_ifile->getDouble("bigtile", "y_center");
00178     double bigZ = m_ifile->getDouble("bigtile", "z_center");
00179     double bigXlen = m_ifile->getDouble("bigtile", "xlen");
00180     double bigYlen = m_ifile->getDouble("bigtile", "ylen");
00181     double bigZlen = m_ifile->getDouble("bigtile", "zlen");
00182 
00183     m_tileCenters[id] = Point(bigX, bigY, bigZ);
00184     m_tileDims[id] = Vector(bigXlen, bigYlen, bigZlen);
00185 
00186     // Load the ids and centers for the side tiles
00187     std::vector<int> sideIds = m_ifile->getIntVector("acdSide", "ids");
00188     std::vector<double> sideX = m_ifile->getDoubleVector("acdSide", "x_center");
00189     std::vector<double> sideY = m_ifile->getDoubleVector("acdSide", "y_center");
00190     std::vector<double> sideZ = m_ifile->getDoubleVector("acdSide", "z_center");
00191     std::vector<double> sideXlen = m_ifile->getDoubleVector("acdSide", "xlen");
00192     std::vector<double> sideYlen = m_ifile->getDoubleVector("acdSide", "ylen");
00193     std::vector<double> sideZlen = m_ifile->getDoubleVector("acdSide", "zlen");
00194 
00195     for (int j=0; j < sideIds.size(); j++) {
00196         m_tileCenters[sideIds[j]] = Point(sideX[j], sideY[j], sideZ[j]);
00197         m_tileDims[sideIds[j]] = Vector(sideXlen[j], sideYlen[j], sideZlen[j]);
00198     }
00199 
00200     std::vector<int> xgtIds = m_ifile->getIntVector("xgt", "ids");
00201     std::vector<double> xgtX = m_ifile->getDoubleVector("xgt", "x_center");
00202     std::vector<double> xgtY = m_ifile->getDoubleVector("xgt", "y_center");
00203     std::vector<double> xgtZ = m_ifile->getDoubleVector("xgt", "z_center");
00204 
00205     for (int k = 0; k < xgtIds.size(); k++) 
00206         m_tileCenters[xgtIds[k]] = Point(xgtX[k], xgtY[k], xgtZ[k]);
00207 
00209     for( std::map<int,Point>::const_iterator it= m_tileCenters.begin(); it != m_tileCenters.end(); ++it) {
00210         Point cen = (*it).second;
00211         log << MSG::DEBUG << "id = " << (*it).first << " center = (" << cen.x() << "," << cen.y() << "," << cen.z() << ")" << endreq; 
00212     }
00213 
00214     m_numSideRows = m_ifile->getInt("acd", "num_side_tiles");
00215 
00216     log << MSG::DEBUG << "number of ACD rows = " << m_numSideRows << endreq;
00217 
00218 
00219 }
00220 
00221 void AcdReconDigiAlg::readThresholds() {
00222 
00223     xml::IFile::extractEnvVar(&m_vetoThreshFileStr);
00224     std::ifstream threshFile( m_vetoThreshFileStr.c_str() );
00225     
00226     if (threshFile.eof() || !threshFile.good()) return;
00227     int id = 0;
00228     double thresh = 0.0;
00229 
00230     threshFile >> id >> thresh;
00231 
00232     while ( ( !threshFile.eof() ) && ( id >= 0 )) {
00233         m_vetoThresh[id] = thresh;
00234         threshFile >> id >> thresh;
00235     }
00236 
00237     threshFile.close();
00238 }
00239 
00240 
00241 void AcdReconDigiAlg::clear() {
00242     m_totEnergy = 0.0;
00243     m_tileCount = 0.0;
00244     m_gammaDOCA = maxDOCA;
00245     m_DOCA = maxDOCA;
00246     m_rowDOCA_vec.clear();
00247     m_rowDOCA_vec.resize(m_numSideRows+1, maxDOCA);  // one for each side, plus one for the top
00248     m_act_dist = -200.0;
00249 
00250 }
00251 
00252 StatusCode AcdReconDigiAlg::reconstruct (const AcdDigiVector* v)
00253 {
00254 
00255     StatusCode sc = StatusCode::SUCCESS;
00256 
00257     MsgStream   log( msgSvc(), name() );
00258 
00259     // reset all member variables to their defaults
00260     clear();
00261 
00262     // iterate through all hit ACD tiles
00263     for( AcdDigiVector::const_iterator it= v->begin(); it != v->end(); ++it) {
00264         
00265 
00266         idents::AcdId id = (*it)->ID();
00267         
00268         //if ((*it)->Veto() == false) continue; // toss out hits below veto threshold
00269         // Use the pulse height and the veto thresholds to determine whether to continue
00270         if ((*it)->PulseHeight() < m_vetoThresh[id.id()]) continue;
00271         
00272         m_tileCount++;
00273 
00274     }
00275 
00276     log << MSG::DEBUG << "num Tiles = " << m_tileCount << endreq;
00277 
00278     acdTileDOCA();
00279 
00280     sc = writeNTuple();
00281 
00282     return sc;
00283 }
00284 
00285 
00286 StatusCode AcdReconDigiAlg::acdTileDOCA() {
00287 
00288     StatusCode sc = StatusCode::SUCCESS;
00289 
00290     MsgStream   log( msgSvc(), name() );
00291 
00292     SmartDataPtr<SiRecObjs> tkrRecData(eventSvc(),"/Event/TkrRecon/SiRecObjs");
00293     if (tkrRecData == 0) {
00294         log << MSG::DEBUG << "No TKR Reconstruction available " << endreq;
00295         return sc;
00296     }
00297 
00298     std::vector<const GFtrack*> xtracks;
00299     std::vector<const GFtrack*> ytracks;
00300 
00301     int nparticles = tkrRecData->numParticles();
00302     if (nparticles > 0) {
00303 
00304         log << MSG::DEBUG << "Number of particles " << nparticles << endreq;
00305 
00306         unsigned int iParticle;
00307         for (iParticle = 0; iParticle < nparticles; iParticle++) {
00308             GFparticle *particle = tkrRecData->Particle(iParticle);
00309             xtracks.push_back(particle->getXGFtrack());
00310             ytracks.push_back(particle->getYGFtrack());
00311         }
00312     } else {
00313         log << MSG::DEBUG << "No reconstructed particles " << endreq;
00314     }
00315 
00316     int ngammas = tkrRecData->numGammas();
00317     log << MSG::DEBUG << "number of gammas = " << ngammas << endreq;
00318 
00319     if (ngammas > 0) {
00320         unsigned int iGamma;
00321         // Create a temporary vector to store the DOCA's for the 
00322         // top and side tiles - we don't want to use the reconstructed
00323         // gamma direction & vector for these DOCAs...
00324         std::vector<double> temprowDOCA_vec;
00325         temprowDOCA_vec.resize(m_numSideRows+1, maxDOCA); 
00326         for (iGamma = 0; iGamma < ngammas; iGamma++) {
00327             GFgamma *gamma = tkrRecData->Gamma(iGamma);
00328             Point gammaVertex = gamma->vertex();
00329             Vector gammaDirection = gamma->direction();
00330             double tempDOCA = DOCA(gammaVertex, gammaDirection, m_rowDOCA_vec);
00331             if (tempDOCA < m_gammaDOCA) m_gammaDOCA = tempDOCA;
00332             // Store the tracks associated with the gamma
00333             xtracks.push_back(gamma->getPair(SiCluster::X));
00334             xtracks.push_back(gamma->getBest(SiCluster::X));
00335             ytracks.push_back(gamma->getPair(SiCluster::Y));            
00336             ytracks.push_back(gamma->getBest(SiCluster::Y));
00337         }
00338     } else {
00339         log << MSG::DEBUG << "No reconstructed gammas " << endreq;
00340     }
00341 
00342     // Now we should have a list of x and y tracks
00343     // iterate through the list of tracks, and combine to create all possible
00344     // pairings of X and Y tracks.  The min DOCA is then reported as ACD_DOCA in
00345     // the ntuple
00346     for (std::vector<const GFtrack*>::const_iterator xtrk = xtracks.begin(); xtrk != xtracks.end(); xtrk++) {
00347         for(std::vector<const GFtrack*>::const_iterator ytrk = ytracks.begin(); ytrk != ytracks.end(); ytrk++) {
00348             Vector dir = Vector((*xtrk)->slope(), (*ytrk)->slope(), 1.).unit();
00349             Point x0((*xtrk)->positionAtZ(0), (*ytrk)->positionAtZ(0), 0.);
00350  
00351             float testDOCA = DOCA(x0, dir, m_rowDOCA_vec);
00352             if(testDOCA < m_DOCA) m_DOCA = testDOCA;
00353 
00354             float test_dist= hitTileDist(x0, dir);
00355             if(test_dist > m_act_dist) m_act_dist = test_dist;
00356         }
00357     }
00358    
00359     log << MSG::DEBUG << "ACD_DOCA = " << m_DOCA << endreq;
00360 
00361     return sc;
00362 
00363 }
00364 
00365 // Distance of Closest Approach (DOCA)
00366 double AcdReconDigiAlg::DOCA (const Point &x0, const Vector &t0, std::vector<double> &doca_values)
00367 {
00368     // This section looks for close-by hits to the ACD tiles
00369 
00370     float minDOCA = maxDOCA;
00371     float dist;
00372 
00373     // iterate over all of the tiles
00374     for( AcdDigiVector::const_iterator it= m_AcdData->begin(); it != m_AcdData->end(); ++it) {
00375 
00376         idents::AcdId type = (*it)->ID();
00377 
00378         //      if((*it)->Veto() == false) continue;
00379         // Use the pulse height and the veto thresholds to determine whether to continue
00380         if ((*it)->PulseHeight() < m_vetoThresh[type.id()]) continue;
00381 
00382         // Need to grab the center position of this tile
00383         Point tileCenter = m_tileCenters[type.id()];
00384         Vector dX = tileCenter - x0;
00385 
00386         float prod = dX * t0;
00387         dist = sqrt(dX.mag2() - prod*prod);
00388         if(dist < minDOCA){
00389             minDOCA = dist;
00390         }
00391         
00392 
00393         // Pick up the min. distance from each type of tile
00394         // i.e. top, and each type of side row tile
00395         if (type.top() && dist < doca_values[0]) doca_values[0] = dist;
00396         if (type.side()) {
00397             if (dist < doca_values[type.row()+1]) doca_values[type.row()+1] = dist;
00398         }
00399     }
00400 
00401     return minDOCA;
00402 }
00403 
00404 // Bill Atwood's new edge DOCA algorithm
00405 double AcdReconDigiAlg::hitTileDist(const Point &x0, const Vector &t0)
00406 {
00407     double return_dist = -200.;
00408     
00409     if(!m_AcdData) return return_dist;
00410     
00411     // iterate over all of the tiles
00412     for( AcdDigiVector::const_iterator it= m_AcdData->begin(); it != m_AcdData->end(); ++it) {
00413 
00414 
00415         idents::AcdId type = (*it)->ID();
00416         // Use the pulse height and the veto thresholds to determine whether to continue
00417         if ((*it)->PulseHeight() < m_vetoThresh[type.id()]) continue;
00418         //if((*it)->Veto() == false) continue;
00419 
00420         // skip XGTs for now
00421         if (type.layer() > 1) continue;
00422 
00423         int iFace = type.face();
00424 
00425         // Need to grab the center position of this tile
00426         Point xT = m_tileCenters[type.id()];
00427         
00428         float dX = m_tileDims[type.id()].x();
00429         float dY = m_tileDims[type.id()].y();
00430         float dZ = m_tileDims[type.id()].z();
00431         
00432         // Figure out where in the plane of this face the trajectory hits
00433         double arc_dist = -1.; 
00434         if(iFace == 0) {// Top Tile. 
00435             arc_dist = (xT.z()-x0.z())/t0.z();                  
00436         }
00437         else if(iFace == 1 || iFace == 3) {// X Side Tile 
00438             arc_dist = (xT.x()-x0.x())/t0.x();
00439         }
00440         else if(iFace == 2 || iFace == 4) {// Y Side Tile
00441             arc_dist = (xT.y()-x0.y())/t0.y();
00442         }
00443         // If arc_dist is negative... had to go backwards to hit plane... 
00444         if(arc_dist < 0.) continue;
00445         
00446         Point x_isec = x0 + arc_dist*t0;
00447         
00448         Vector local_x0 = xT - x_isec; 
00449         if(iFace == 0) {// Top Tile
00450             double dist_x = dX/2. - fabs(local_x0.x());
00451             double dist_y = dY/2. - fabs(local_x0.y());                 
00452             double test_dist = (dist_x < dist_y) ? dist_x : dist_y;
00453             if(test_dist > return_dist) return_dist = test_dist;
00454         }
00455         else if(iFace == 1 || iFace == 3) {// X Side Tile
00456             double dist_z = dZ/2. - fabs(local_x0.z());
00457             double dist_y = dY/2. - fabs(local_x0.y());                 
00458             double test_dist = (dist_z < dist_y) ? dist_z : dist_y;
00459             if(test_dist > return_dist) return_dist = test_dist;
00460         }
00461         else if(iFace == 2 || iFace == 4) {// Y Side Tile
00462             double dist_z = dZ/2. - fabs(local_x0.z());
00463             double dist_x = dY/2. - fabs(local_x0.x());                 
00464             double test_dist = (dist_z < dist_x) ? dist_z : dist_x;
00465             if(test_dist > return_dist) return_dist = test_dist;
00466         }
00467     }
00468     return return_dist;
00469 }
00470 
00471 
00472 
00473 StatusCode AcdReconDigiAlg::writeNTuple() {
00474 
00475     StatusCode sc = StatusCode::SUCCESS;
00476     MsgStream   log( msgSvc(), name() );
00477 
00479     //sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_TotEnergy", m_totEnergy);
00480     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_TileCount", m_tileCount);
00481     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_DOCA", m_DOCA);
00482     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_GammaDOCA", m_gammaDOCA);
00483     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_TopDOCA", m_rowDOCA_vec[0]);
00484     sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), "ACD_Act_Dist", m_act_dist);
00485 
00486     // loop over all DOCA values for the sides
00487     unsigned int iDOCA;
00488     for (iDOCA = 1; iDOCA <= m_numSideRows; iDOCA++) {
00489         std::string label("ACD_S");
00490         char num[5];
00491         _itoa((iDOCA-1), num, 10);
00492         label += num;
00493         label += "DOCA";
00494         sc = ntupleWriteSvc->addItem(m_tupleName.c_str(), label.c_str(), m_rowDOCA_vec[iDOCA]);
00495     }
00496 
00497     return sc;
00498 }
00499 

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