00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "AtlfastAlgs/KIsolator.h"
00011
00012 #include "AtlfastUtils/IsAssociated.h"
00013 #include "AtlfastAlgs/GlobalEventData.h"
00014
00015 #include "AtlfastEvent/Phi.h"
00016 #include "AtlfastEvent/ICluster.h"
00017
00018 #include "AtlfastUtils/FunctionObjects.h"
00019 #include "AtlfastUtils/HeaderPrinter.h"
00020 #include "AtlfastUtils/HepMC_helper/IMCselector.h"
00021
00022 #include <cmath>
00023 #include <algorithm>
00024 #include <assert.h>
00025
00026
00027 #include "GaudiKernel/DataSvc.h"
00028 #include "AtlfastEvent/MsgStreamDefs.h"
00029
00030 #include "CLHEP/Units/SystemOfUnits.h"
00031
00032 namespace Atlfast {
00033 using std::partial_sort;
00034
00035
00036
00037
00038
00039
00040 KIsolator::KIsolator
00041 ( const std::string& name, ISvcLocator* pSvcLocator )
00042 : Algorithm( name, pSvcLocator ),
00043 m_tesIO(0) {
00044
00045
00046 m_rClusterMatch = 0.150;
00047 m_rClusterIsolation = 0.400;
00048 m_eClusterIsolation = 0.0*GeV;
00049 m_rCellIsolation = 0.200;
00050 m_eCellIsolation = 10.0*GeV;
00051
00052
00053 m_inputLocation = "/Event/AtlfastElectrons";
00054 m_cellLocation = "/Event/AtlfastCells";
00055 m_clusterLocation = "/Event/AtlfastClusters";
00056 m_isolatedOutputLocation = "/Event/AtlfastIsolatedElectrons";
00057 m_nonIsolatedOutputLocation = "/Event/AtlfastNonIsolatedElectrons";
00058
00059
00060
00061
00062 declareProperty( "RClusterMatch", m_rClusterMatch ) ;
00063 declareProperty( "RClusterIsolation", m_rClusterIsolation ) ;
00064 declareProperty( "EClusterIsolation", m_eClusterIsolation ) ;
00065 declareProperty( "RCellIsolation", m_rCellIsolation ) ;
00066 declareProperty( "ECellIsolation", m_eCellIsolation ) ;
00067
00068 declareProperty( "InputLocation", m_inputLocation ) ;
00069 declareProperty( "CellLocation", m_cellLocation ) ;
00070 declareProperty( "ClusterLocation", m_clusterLocation ) ;
00071 declareProperty( "IsolatedOutputLocation", m_isolatedOutputLocation ) ;
00072 declareProperty( "NonIsolatedOutputLocation", m_nonIsolatedOutputLocation ) ;
00073
00074 }
00075
00076
00077 KIsolator::~KIsolator() {
00078 MsgStream log( messageService(), name() ) ;
00079 log << MSG::INFO << "destructor" << endreq;
00080 if (m_tesIO) delete m_tesIO;
00081 }
00082
00083
00084
00085
00086
00087
00088 StatusCode KIsolator::initialize(){
00089 MsgStream log( messageService(), name() ) ;
00090 log << MSG::DEBUG << "Initialising" << endreq;
00091
00092
00093
00094 GlobalEventData* ged = GlobalEventData::Instance();
00095 m_visibleToCal = ged -> visibleToCal();
00096 m_mcLocation = ged -> mcLocation();
00097
00098 m_tesIO = new TesIO(m_mcLocation, ged->justHardScatter());
00099
00100
00101 HeaderPrinter hp("Atlfast KIsolator:", log);
00102
00103 hp.add("TES Locations: ");
00104 hp.add(" Particles from ", m_inputLocation);
00105 hp.add(" Cells from ", m_cellLocation);
00106 hp.add(" Clusters from ", m_clusterLocation);
00107 hp.add(" Isolated Particles to ", m_isolatedOutputLocation);
00108 hp.add(" Non-Isolated Particles to ", m_nonIsolatedOutputLocation);
00109 hp.add("Cluster match DeltaR ", m_rClusterMatch);
00110 hp.add("Cluster isolation DeltaR ", m_rClusterIsolation);
00111 hp.add("Cluster isolation E thresh ", m_eClusterIsolation);
00112 hp.add("Cell isolation DeltaR ", m_rCellIsolation);
00113 hp.add("Cell isolation E thresh ", m_eCellIsolation);
00114 hp.print();
00115
00116
00117 return StatusCode::SUCCESS ;
00118 }
00119
00120
00121
00122
00123
00124 StatusCode KIsolator::finalize(){
00125 MsgStream log( messageService(), name() ) ;
00126 log << MSG::INFO << "finalizing" << endreq;
00127 return StatusCode::SUCCESS ;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 StatusCode KIsolator::execute( ){
00146
00147
00148
00149
00150 MsgStream log( messageService(), name() ) ;
00151 std::string mess;
00152
00153
00154
00155
00156 const ReconstructedParticleCollection* particles(0);
00157 if(!m_tesIO->getDH(particles, m_inputLocation)){
00158 log << MSG::DEBUG
00159 << "No reconstructed particles in TES to treat"
00160 << endreq ;
00161 return StatusCode::SUCCESS ;
00162 }
00163
00164 log << MSG::DEBUG
00165 << "Found "
00166 << particles->size()
00167 << " particles in TES "
00168 << endreq ;
00169
00170
00171
00172
00173
00174
00175
00176 std::vector<ITwoCptCell*> cells;
00177 if(!m_tesIO->copy<ITwoCptCellCollection> (cells, m_cellLocation)){
00178
00179 log << MSG::DEBUG
00180 << "No Cells found in TES at "
00181 << m_cellLocation
00182 << endreq ;
00183 }
00184
00185
00186 std::vector<ICluster*> clusters;
00187 if(!m_tesIO->copy<IClusterCollection>(clusters, m_clusterLocation)){
00188 log << MSG::DEBUG
00189 << "No Clusters found in TES at "
00190 << m_clusterLocation
00191 << endreq ;
00192 }
00193
00194
00195
00196
00197
00198
00199 ReconstructedParticleCollection* isolatedParticles =
00200 new ReconstructedParticleCollection ;
00201
00202 ReconstructedParticleCollection* nonIsolatedParticles =
00203 new ReconstructedParticleCollection ;
00204
00205
00206
00207
00208
00209
00210 ReconstructedParticleCollection::const_iterator particle ;
00211
00212 for( particle = particles->begin();
00213 particle != particles->end();
00214 ++particle)
00215 {
00216 if( this->isIsolated( log, particle, cells, clusters ) )
00217 isolatedParticles->push_back
00218 ( new ReconstructedParticle( *particle ) );
00219 else
00220 nonIsolatedParticles->push_back
00221 ( new ReconstructedParticle( *particle ) );
00222 }
00223
00224
00225
00226
00227
00228 TesIoStat tis;
00229 tis = m_tesIO->store(isolatedParticles, m_isolatedOutputLocation );
00230 if( tis.isNotValid() ) {
00231 log << MSG::ERROR << "Failed to register output in TES at "
00232 << m_isolatedOutputLocation << endreq ;
00233 return tis;
00234 } else{
00235 log << MSG::DEBUG << "Written " << isolatedParticles->size()
00236 << " isolated particles to TES " << endreq;
00237 }
00238
00239 tis = m_tesIO->store(nonIsolatedParticles, m_nonIsolatedOutputLocation );
00240 if( tis.isNotValid() ) {
00241 log << MSG::ERROR << "Failed to register output in TES at "
00242 << m_nonIsolatedOutputLocation << endreq ;
00243 } else {
00244 log << MSG::DEBUG << "Written " << nonIsolatedParticles->size()
00245 << " NON-isolated particles to TES " << endreq;
00246 }
00247
00248 return tis;
00249
00250 }
00251
00252
00253
00254
00255
00256 double KIsolator::gapResponse(double eta){
00257 double aEta = std::abs(eta);
00258 double p1 = 1.1095;
00259 double p2 = -7.494*std::pow((aEta - p1),2);
00260 double p3 = -25.275*std::pow((aEta - p1),2);
00261 double p4 = 14.52;
00262 return ((aEta>1.3)&&(aEta<1.9))?
00263 1.0 - std::exp(p2 - p4*std::exp(p3)) : 1.0;
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274 bool KIsolator::isIsolated
00275 ( MsgStream& log,
00276 ReconstructedParticleCollection::const_iterator particle,
00277 std::vector<ITwoCptCell*>& storedCells,
00278 std::vector<ICluster*>& storedClusters
00279
00280 ){
00281
00282 log << MSG::DEBUG << "\n\t Treating particle: " << *particle ;
00283
00284
00285
00286
00287 bool associated = false ;
00288 ICluster* associatedCluster = NULL ;
00289
00290
00291
00292
00293
00294
00295
00296 if( !storedClusters.empty() ) {
00297
00298
00299 std::vector<ICluster*> clusters(
00300 storedClusters.begin(),
00301 storedClusters.end()
00302 );
00303
00304
00305 std::vector<ICluster*>::iterator it;
00306 for (it=clusters.begin(); it!=clusters.end(); ++it) {
00307 double dR = m_kinehelp.deltaR(*particle,*it);
00308 if (dR>m_rClusterMatch) continue;
00309 log << "\n\t --> cluster: " << *it ;
00310 log << "\n\t --> DeltaR: " << dR;
00311 log << "\n\t --> EtC-EtP: "
00312 << (*it)->eT() -
00313 (*particle)->eT()*gapResponse((*particle)->eta());
00314 log << "\n\t ---------------------------------------- " <<endreq;
00315 }
00316
00317
00318
00319 std::vector<ICluster*>::iterator firstNonAssociatedCluster ;
00320 firstNonAssociatedCluster =
00321 std::partition(
00322 clusters.begin(),
00323 clusters.end(),
00324 IsAssociated<ReconstructedParticle>
00325 );
00326 if(firstNonAssociatedCluster != clusters.begin()){
00327 log<<MSG::DEBUG<<"First "
00328 <<firstNonAssociatedCluster-clusters.begin()
00329 <<" clusters are associated to ReconstructedParticles "
00330 <<clusters.end()-firstNonAssociatedCluster
00331 <<" cluster(s) remain"
00332 <<endreq;
00333 }else{
00334 log<<MSG::DEBUG
00335 <<"No clusters are associated to ReconstructedParticles"
00336 <<endreq;
00337 }
00338 if(clusters.end()!=firstNonAssociatedCluster){
00339
00340
00341
00342
00343
00344 partial_sort(
00345 firstNonAssociatedCluster,
00346 firstNonAssociatedCluster+1,
00347 clusters.end(),
00348 SortAttribute::DeltaR( *particle )
00349 );
00350
00351 log<<MSG::DEBUG<<"Sorted clusters "<<endreq;
00352
00353 associated =
00354 (m_kinehelp.deltaR(*particle, *firstNonAssociatedCluster) <
00355 m_rClusterMatch);
00356
00357 if( associated )
00358 {
00359 log << "\n\t -->Found associated cluster: "
00360 << *clusters.begin() ;
00361
00362
00363 associatedCluster = *firstNonAssociatedCluster ;
00364
00365
00366 ++firstNonAssociatedCluster;
00367
00368 }
00369
00370
00371
00372
00373
00374
00375
00376 double eClusterSum = m_kinehelp.sumETInCone(
00377 firstNonAssociatedCluster,
00378 clusters.end(),
00379 *particle,
00380 m_rClusterIsolation
00381 );
00382
00383
00384
00385 if( eClusterSum > m_eClusterIsolation )
00386 log << "\n\t -->Excess Cluster energy in cone = " << eClusterSum
00387 << " => NOT-ISOLATED " << endreq;
00388 else
00389 log << "\n\t -->Excess Cluster energy in cone = " << eClusterSum
00390 << " => ISOLATED " ;
00391
00392 if( eClusterSum > m_eClusterIsolation ) return false ;
00393
00394 }
00395
00396 }
00397
00398
00399
00400
00401 if( !storedCells.empty() ) {
00402
00403
00404
00405
00406
00407
00408
00409 ReconstructedParticle* rp =
00410 new ReconstructedParticle(
00411 (*particle)->pdg_id(),
00412 (*particle)->momentum(),
00413 (*particle)->truth()
00414 );
00415
00416
00417
00418 double eCoreSum = m_kinehelp.sumETInCone(
00419 storedCells.begin(),
00420 storedCells.end(),
00421 rp,
00422 m_rCellIsolation
00423 );
00424
00425
00426
00427 delete rp;
00428
00429
00430
00431
00432
00433
00434 bool itDeposits = m_visibleToCal->operator()( (*particle)->truth() );
00435
00436
00437
00438 log << "\n\t -->Applying gap correction factor: "
00439 << gapResponse((*particle)->eta()) << endreq ;
00440
00441 double eCoreIsolation = eCoreSum;
00442 if(itDeposits) eCoreIsolation -=
00443 ((*particle)->eT())*gapResponse((*particle)->eta());
00444
00445
00446
00447
00448 if( eCoreIsolation > m_eCellIsolation )
00449 log
00450 << "\n\t -->Excess energy in core (R<0.2) = " << eCoreIsolation
00451 << " => NOT-ISOLATED " << endreq ;
00452 else
00453 log
00454 << "\n\t -->Excess energy in core (R<0.2) = " << eCoreIsolation
00455 << " => ISOLATED " << endreq ;
00456
00457 if( eCoreIsolation > m_eCellIsolation )return false;
00458
00459 }
00460
00461
00462
00463
00464
00465
00466
00467
00468 if( associated ) {
00469
00470
00471 IAOO* iamp = *particle;
00472 iamp->associate( associatedCluster ) ;
00473
00474 log << MSG::DEBUG
00475 << "Particle of type "<< (*particle)->pdg_id()<<" associated to Cluster"
00476 << endreq;
00477
00478
00479
00480 IAOO* iamc = associatedCluster;
00481 iamc->associate( *particle ) ;
00482
00483 log << MSG::DEBUG
00484 << "Cluster associated to Particle of type "<< (*particle)->pdg_id()
00485 << endreq;
00486
00487
00488 }
00489
00490 log << endreq ;
00491
00492 return true ;
00493 }
00494
00495 }