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
00078
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
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
00103
00104
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
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
00145 reconstruct(m_AcdData);
00146
00150
00151 log << MSG::DEBUG << "exiting ACD Recon " << endreq;
00152
00153 return sc;
00154 }
00155
00156
00157
00158
00159
00160
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());
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);
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
00210 clear();
00211
00212
00213 for( IVetoData::const_iterator it= v->begin(); it != v->end(); ++it) {
00214
00215 if ((*it).energy() < threshold_energy) continue;
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
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
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
00275
00276
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
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
00301
00302
00303
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
00327 double acdReconAlg::DOCA (const Point &x0, const Vector &t0, std::vector<double> &doca_values)
00328 {
00329
00330
00331 float minDOCA = maxDOCA;
00332 float dist;
00333
00334
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
00352
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
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
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
00384 double arc_dist = -1.;
00385 if(iFace == 0) {
00386 arc_dist = (xT.z()-x0.z())/t0.z();
00387 }
00388 else if(iFace == 1 || iFace == 3) {
00389 arc_dist = (xT.x()-x0.x())/t0.x();
00390 }
00391 else if(iFace == 2 || iFace == 4) {
00392 arc_dist = (xT.y()-x0.y())/t0.y();
00393 }
00394
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) {
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) {
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) {
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
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