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

Isolator.cxx

Go to the documentation of this file.
00001 // ================================================
00002 // Isolator class Implementation
00003 // ================================================
00004 //
00005 // THIS TEXT TO BE REPLACED BY ATLAS STANDARD FORMAT
00006 //
00007 // Namespace ATLFast
00008 //
00009 
00010 #include "AtlfastAlgs/Isolator.h"
00011 #include "AtlfastAlgs/ClusterIsAssoc.h"
00012 #include "AtlfastAlgs/GlobalEventData.h"
00013 
00014 #include "AtlfastEvent/Phi.h"
00015 #include "AtlfastEvent/Cluster.h"
00016 
00017 #include "AtlfastUtils/FunctionObjects.h"
00018 #include "AtlfastUtils/HeaderPrinter.h"
00019 #include "AtlfastUtils/HepMC_helper/IMCselector.h"
00020 
00021 #include <cmath> 
00022 #include <algorithm>
00023 
00024 // Gaudi includes
00025 #include "GaudiKernel/DataSvc.h"
00026 #include "StoreGate/DataHandle.h"
00027 #include "AtlfastEvent/MsgStreamDefs.h"
00028 
00029 namespace Atlfast {
00030   using std::partial_sort;
00031 
00032 
00033   //--------------------------------
00034   // Constructors and destructors
00035   //--------------------------------
00036   
00037   Isolator::Isolator 
00038   ( const std::string& name, ISvcLocator* pSvcLocator ) 
00039     : Algorithm( name, pSvcLocator ){
00040     
00041     // Setting the parameter defaults.
00042     m_rClusterMatch      = 0.150;
00043     m_rClusterIsolation  = 0.400;
00044     m_eClusterIsolation  = 0.0;
00045     m_rCellIsolation     = 0.200;
00046     m_eCellIsolation     = 10.0;
00047     
00048     // Default paths for entities in the TES
00049     m_inputLocation                 = "Unknown";
00050     m_cellLocation                  = "/Event/AtlfastCell";
00051     m_clusterLocation               = "/Event/AtlfastCluster";
00052     m_isolatedOutputLocation        = "Unknown";
00053     m_nonIsolatedOutputLocation     = "Unknown";
00054     
00055     // This is how you declare the paramemters to Gaudi so that
00056     // they can be over-written via the job options file
00057     
00058     declareProperty( "RClusterMatch",             m_rClusterMatch ) ;
00059     declareProperty( "RClusterIsolation",         m_rClusterIsolation ) ;
00060     declareProperty( "EClusterIsolation",         m_eClusterIsolation ) ;
00061     declareProperty( "RCellIsolation",            m_rCellIsolation ) ;
00062     declareProperty( "ECellIsolation",            m_eCellIsolation ) ;
00063     
00064     declareProperty( "InputLocation",             m_inputLocation ) ;
00065     declareProperty( "CellLocation",              m_cellLocation ) ;
00066     declareProperty( "ClusterLocation",           m_clusterLocation ) ;
00067     declareProperty( "IsolatedOutputLocation",    m_isolatedOutputLocation ) ;
00068     declareProperty( "NonIsolatedOutputLocation", m_nonIsolatedOutputLocation ) ;
00069     
00070   }
00071   
00072   // Destructor
00073   Isolator::~Isolator() {
00074     MsgStream log( messageService(), name() ) ;
00075     log << MSG::INFO << "destructor" << endreq;
00076     if (m_tesIO) {
00077       delete m_tesIO;
00078     }
00079   } 
00080   
00081   
00082   //---------------------------------
00083   // initialise() 
00084   //---------------------------------
00085   
00086   StatusCode Isolator::initialize(){
00087     MsgStream log( messageService(), name() ) ;
00088     log << MSG::DEBUG << "Initialising" << endreq;
00089     
00090     
00091     //    m_tesIO = new TesIO(eventDataService());
00092     m_tesIO = new TesIO();
00093     //get the Global Event Data using singleton pattern
00094     GlobalEventData* ged = GlobalEventData::Instance();
00095     m_visibleToCal   = ged -> visibleToCal();
00096     
00097     HeaderPrinter hp("Atlfast Isolator:", log);
00098     
00099     hp.add("TES Locations:             ");
00100     hp.add(" Particles from            ", m_inputLocation); 
00101     hp.add(" Cells from                ", m_cellLocation);    
00102     hp.add(" Clusters from             ", m_clusterLocation); 
00103     hp.add(" Isolated Particles to     ", m_isolatedOutputLocation);
00104     hp.add(" Non-Isolated Particles to ", m_nonIsolatedOutputLocation);
00105     hp.add("Cluster match DeltaR       ", m_rClusterMatch);
00106     hp.add("Cluster isolation DeltaR   ", m_rClusterIsolation);
00107     hp.add("Cluster isolation E thresh ", m_eClusterIsolation);
00108     hp.add("Cell isolation DeltaR      ", m_rCellIsolation);
00109     hp.add("Cell isolation E thresh    ", m_eCellIsolation);
00110     hp.print();
00111     
00112     
00113     return StatusCode::SUCCESS ;
00114   }
00115   
00116   //---------------------------------
00117   // finalise() 
00118   //---------------------------------
00119   
00120   StatusCode Isolator::finalize(){
00121     MsgStream log( messageService(), name() ) ;
00122     log << MSG::INFO << "finalizing" << endreq;
00123     return StatusCode::SUCCESS ;
00124   }
00125   
00126   
00127   //----------------------------------------------
00128   // execute() method called once per event
00129   //----------------------------------------------
00130   //
00131   //  This algorithm creates isolated electrons. 
00132   //  It scans the list of MC electrons. If an electron is found it creates 
00133   //  a candidate Electron object with a smeared energy.  Different 
00134   //  energy-smearing for low luminosity and high luminosity can be invoked.
00135   //  It then checks several isolation criteria with respect to calorimeter
00136   //  clusters and cells.
00137   //  Only if the isolation is satisfied is the Electron kept.
00138   //  Finally all successful ELectrons are added to the event store.
00139   
00140   
00141   StatusCode Isolator::execute( ){
00142     
00143     //................................
00144     // make a message logging stream
00145     
00146     MsgStream log( messageService(), name() ) ;
00147     std::string mess;
00148     //...............................
00149     // Extract the input particles which are to be tested for isolation.
00150     
00151     //std::vector<ReconstructedParticle*> particles;
00152     const DataHandle<ReconstructedParticleCollection> particles;
00153     if(!m_tesIO->getDH(particles, m_inputLocation)){
00154       log << MSG::DEBUG 
00155           << "No reconstructed particles in TES to treat" 
00156           << endreq ;
00157       return StatusCode::SUCCESS ;
00158     }
00159     
00160     log << MSG::DEBUG 
00161         << "Found " 
00162         << particles->size() 
00163         << " particles in TES "
00164         << endreq ;
00165     
00166     
00167     //.........................................................
00168     // Extract the (pointers to) cells and clusters from the TES into 
00169     // locally defined arrays.
00170     
00171     
00172     std::vector<ITwoCptCell*> cells;
00173     if(!m_tesIO->copy<ITwoCptCellCollection> (cells, m_cellLocation)){
00174       
00175       log << MSG::DEBUG 
00176           << "No Cells found in TES at " 
00177           << m_cellLocation 
00178           << endreq ;
00179     }
00180     
00181     
00182     std::vector<Cluster*> clusters;
00183     if(!m_tesIO->copy<ClusterCollection>(clusters, m_clusterLocation)){
00184       log << MSG::DEBUG 
00185           << "No Clusters found in TES at " 
00186           << m_clusterLocation 
00187           << endreq ;
00188     }
00189     
00190     
00191     // ......................
00192     // Make an empty container object which will store (pointers to) all 
00193     // sucessfully isolated and non isolated electrons.  
00194     
00195     ReconstructedParticleCollection* isolatedParticles = 
00196       new ReconstructedParticleCollection ;
00197     
00198     ReconstructedParticleCollection* nonIsolatedParticles = 
00199       new ReconstructedParticleCollection ;
00200     
00201     
00202     //.........................................................
00203     // For each particle in the input list test if it is isolated.
00204     // If so copy it into the output collection.
00205     
00206     ReconstructedParticleCollection::iterator particle ;
00207     
00208     for( particle = particles->begin(); 
00209          particle != particles->end(); 
00210          ++particle)
00211       {       
00212         if( this->isIsolated( log, particle, cells, clusters ) )     
00213           isolatedParticles->push_back
00214             ( new ReconstructedParticle( *particle ) ); 
00215         else
00216           nonIsolatedParticles->push_back
00217             ( new ReconstructedParticle( *particle ) );         
00218       }
00219     
00220     
00221     //......................................
00222     // Register particles in the transient event store. 
00223     
00224     TesIoStat sc;
00225     sc = m_tesIO->store(isolatedParticles, m_isolatedOutputLocation );  
00226     
00227     if( !sc ) {
00228       log << MSG::ERROR << "Failed to register output in TES at " 
00229           << m_isolatedOutputLocation <<  endreq ;
00230       return sc;
00231     } else{
00232       log << MSG::DEBUG << "Written " << isolatedParticles->size() 
00233           << " isolated particles to TES " << endreq;
00234     }
00235     
00236     sc = m_tesIO->store(nonIsolatedParticles, m_nonIsolatedOutputLocation );
00237     
00238     if( !sc ) {
00239       log << MSG::ERROR << "Failed to register output in TES at " 
00240           << m_nonIsolatedOutputLocation <<  endreq ;
00241     }
00242     else {
00243       log << MSG::DEBUG << "Written " << nonIsolatedParticles->size() 
00244           << " NON-isolated particles to TES " << endreq;
00245     }
00246     
00247     return sc ;
00248     
00249   }
00250   
00251   
00252   //-------------------------------------------
00253   // private: isIsolated
00254   //------------------------------------------
00255   
00256   // Checks whether a candidate electron is isolated from clusters
00257   // and cells
00258   
00259   bool Isolator::isIsolated
00260   ( MsgStream& log, 
00261     ReconstructedParticleCollection::iterator particle,
00262     std::vector<ITwoCptCell*>& storedCells,
00263     std::vector<Cluster*>& storedClusters
00264     
00265     ){
00266     
00267     log << MSG::DEBUG << "\n\t Treating particle: " << *particle ;
00268     
00269     // Things we need to remember until the end of the method
00270     // If, during processing of Clusters, we identify an "associated cluster"
00271     // we remember it for use if the particle is finally judged to be isolated
00272     bool associated = false ;
00273     Cluster* associatedCluster = NULL ;
00274     
00275     
00276     
00277     //....................................
00278     // Cluster isolation
00279     
00280     if( storedClusters.begin() ) {
00281       
00282       if( storedClusters.size() > 0 ) {
00283         
00284         // Make a local copy as we want to mutate the list of pointers
00285         std::vector<Cluster*>  clusters( 
00286                                         storedClusters.begin(), 
00287                                         storedClusters.end() 
00288                                         );
00289         
00290         //Only use clusters not already claimed by ReconstructedParticles
00291         std::vector<Cluster*>::iterator firstNonAssociatedCluster ;
00292         firstNonAssociatedCluster = std::partition(
00293                                                    clusters.begin(),
00294                                                    clusters.end(),
00295                                                    ClusterIsAssoc()
00296                                                    );
00297         if(firstNonAssociatedCluster != clusters.begin()){
00298           log<<MSG::DEBUG<<"First "
00299              <<firstNonAssociatedCluster-clusters.begin()
00300              <<" clusters are associated to ReconstructedParticles "
00301              <<clusters.end()-firstNonAssociatedCluster
00302              <<" cluster(s) remain"
00303              <<endreq;
00304         }else{
00305           log<<MSG::DEBUG
00306              <<"No clusters are associated to ReconstructedParticles"
00307              <<endreq;
00308         }
00309         if(clusters.end()!=firstNonAssociatedCluster){
00310           // .....................
00311           // Associate unclaimed clusters with current particle. 
00312           // This looks at the nearest cluster only, and decides whether
00313           // it is within an "association" cone
00314           
00315           partial_sort(
00316                        firstNonAssociatedCluster,
00317                        firstNonAssociatedCluster+1,
00318                        clusters.end(), 
00319                        SortAttribute::DeltaR( *particle )
00320                        );
00321           
00322           log<<MSG::DEBUG<<"Sorted clusters "<<endreq;
00323           
00324           associated =
00325             (m_kinehelp.deltaR(*particle, *firstNonAssociatedCluster) <  
00326              m_rClusterMatch);
00327           
00328           if( associated ) 
00329             {
00330               log << "\n\t -->Found associated cluster: "  
00331                   << *clusters.begin() ;
00332               
00333               // Remember the relevant cluster until the end of this method
00334               associatedCluster = *firstNonAssociatedCluster ;
00335               
00336               // Set the first nonassociated cluster
00337               ++firstNonAssociatedCluster;
00338               
00339             }
00340           
00341           
00342           //............................................
00343           // Now we can check Cluster Isolation 
00344           // (if there is at least one more cluster to check)
00345           
00346           // Use kinematic helper to do all work
00347           double eClusterSum = m_kinehelp.sumETInCone( 
00348                                                       firstNonAssociatedCluster, 
00349                                                       clusters.end(), 
00350                                                       *particle,
00351                                                       m_rClusterIsolation
00352                                                       );
00353           
00354           // Apply the cut criteria
00355           
00356           if( eClusterSum  > m_eClusterIsolation ) 
00357             log  << "\n\t -->Excess Cluster energy in cone = " << eClusterSum 
00358                  << "   => NOT-ISOLATED " << endreq;       
00359           else
00360             log  << "\n\t -->Excess Cluster energy in cone = " << eClusterSum 
00361                  << "   => ISOLATED "  ;
00362           
00363           if( eClusterSum  > m_eClusterIsolation )  return false ;
00364           
00365         }
00366         
00367       }
00368     }
00369     
00370     
00371     //............................................
00372     // Cell Isolation: 
00373     
00374     if( storedCells.begin() ) {
00375       
00376       // Test on isolation in respect of the total transverese energy of all 
00377       // Cells within a given r-cone
00378       
00379       // Use kinematic helper to do all work
00380       double eCellSum = m_kinehelp.sumETInCone( 
00381                                                storedCells.begin(), 
00382                                                storedCells.end(), 
00383                                                *particle,
00384                                                m_rCellIsolation
00385                                                );
00386       
00387       
00388       // Subtract the energy associated with particle under test
00389       // as the cells summed will have included its deposit
00390       //    CalSelect depositsInCal;
00391       //    if(depositsInCal( *particle) ) eCellSum -= (*particle)->eT() ;
00392       bool itDeposits = m_visibleToCal->operator()( (*particle)->truth() );
00393       
00394       if(itDeposits) eCellSum -= (*particle)->eT() ;
00395       
00396       
00397       // Apply isolation criteria
00398       
00399       if( eCellSum  > m_eCellIsolation ) 
00400         log  
00401           << "\n\t -->Excess Cell energy in cone = " << eCellSum 
00402           << "   => NOT-ISOLATED " << endreq ;    
00403       else
00404         log   
00405           << "\n\t -->Excess Cell energy in cone = " << eCellSum 
00406           << "   => ISOLATED " ;
00407       
00408       if( eCellSum  > m_eCellIsolation ) return false ;
00409       
00410     }
00411     
00412     //..........................................
00413     // If we get here then the candidate was judged to be isolated
00414     
00415     // It is only now that we wish to set associations between isolated
00416     // particles and clusters. I.e we dont want to flag associations for 
00417     // non-isolated particles
00418     
00419     if( associated ) {
00420       
00421       // Set the association from Particle -> Cluster
00422       IAssociationManager* iamp = *particle;
00423       iamp->associate( associatedCluster ) ;
00424       
00425       // Set the association from Cluster -> Particle
00426       IAssociationManager* iamc = associatedCluster;
00427       iamc->associate( *particle ) ;
00428       
00429     }
00430     
00431     log << endreq ;
00432     
00433     return true ;
00434   }
00435   
00436 } // end of namespace bracket

Generated on Tue Mar 18 11:18:23 2003 for AtlfastAlgs by doxygen1.3-rc1