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_isolatedOutputLocation);
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     ReconstructedParticleCollection particles;
00153     if(!m_tesIO->
00154        copy<ReconstructedParticleCollection >(particles, m_inputLocation)){
00155       log << MSG::DEBUG 
00156           << "No reconstructed particles in TES to treat" 
00157           << endreq ;
00158       return StatusCode::SUCCESS ;
00159     }
00160     
00161     log << MSG::DEBUG 
00162         << "Found " 
00163         << particles.size() 
00164         << " particles in TES "
00165         << endreq ;
00166     
00167     
00168     //.........................................................
00169     // Extract the (pointers to) cells and clusters from the TES into 
00170     // locally defined arrays.
00171     
00172     
00173     std::vector<Cell*> cells;
00174     if(!m_tesIO->copy<CellCollection> (cells, m_cellLocation)){
00175       
00176       log << MSG::DEBUG 
00177           << "No Cells found in TES at " 
00178           << m_cellLocation 
00179           << endreq ;
00180     }
00181     
00182     
00183     std::vector<Cluster*> clusters;
00184     if(!m_tesIO->copy<ClusterCollection>(clusters, m_clusterLocation)){
00185       log << MSG::DEBUG 
00186           << "No Clusters found in TES at " 
00187           << m_clusterLocation 
00188           << endreq ;
00189     }
00190     
00191     
00192     // ......................
00193     // Make an empty container object which will store (pointers to) all 
00194     // sucessfully isolated and non isolated electrons.  
00195     
00196     ReconstructedParticleCollection* isolatedParticles = 
00197       new ReconstructedParticleCollection ;
00198     
00199     ReconstructedParticleCollection* nonIsolatedParticles = 
00200       new ReconstructedParticleCollection ;
00201     
00202     
00203     //.........................................................
00204     // For each particle in the input list test if it is isolated.
00205     // If so copy it into the output collection.
00206     
00207     ReconstructedParticleCollection::iterator particle ;
00208     
00209     for( particle = particles.begin(); 
00210          particle != particles.end(); 
00211          ++particle)
00212       {       
00213         if( this->isIsolated( log, particle, cells, clusters ) )     
00214           isolatedParticles->push_back
00215             ( new ReconstructedParticle( *particle ) ); 
00216         else
00217           nonIsolatedParticles->push_back
00218             ( new ReconstructedParticle( *particle ) );         
00219       }
00220     
00221     
00222     //......................................
00223     // Register particles in the transient event store. 
00224     
00225     TesIoStat sc;
00226     sc = m_tesIO->store(isolatedParticles, m_isolatedOutputLocation );  
00227     
00228     if( !sc ) {
00229       log << MSG::ERROR << "Failed to register output in TES at " 
00230           << m_isolatedOutputLocation <<  endreq ;
00231       return sc;
00232     } else{
00233       log << MSG::DEBUG << "Written " << isolatedParticles->size() 
00234           << " isolated particles to TES " << endreq;
00235     }
00236     
00237     sc = m_tesIO->store(nonIsolatedParticles, m_nonIsolatedOutputLocation );
00238     
00239     if( !sc ) {
00240       log << MSG::ERROR << "Failed to register output in TES at " 
00241           << m_nonIsolatedOutputLocation <<  endreq ;
00242     }
00243     else {
00244       log << MSG::DEBUG << "Written " << nonIsolatedParticles->size() 
00245           << " NON-isolated particles to TES " << endreq;
00246     }
00247     
00248     return sc ;
00249     
00250   }
00251   
00252   
00253   //-------------------------------------------
00254   // private: isIsolated
00255   //------------------------------------------
00256   
00257   // Checks whether a candidate electron is isolated from clusters
00258   // and cells
00259   
00260   bool Isolator::isIsolated
00261   ( MsgStream& log, 
00262     ReconstructedParticleCollection::iterator particle,
00263     std::vector<Cell*>& storedCells,
00264     std::vector<Cluster*>& storedClusters
00265     
00266     ){
00267     
00268     log << MSG::DEBUG << "\n\t Treating particle: " << *particle ;
00269     
00270     // Things we need to remember until the end of the method
00271     // If, during processing of Clusters, we identify an "associated cluster"
00272     // we remember it for use if the particle is finally judged to be isolated
00273     bool associated = false ;
00274     Cluster* associatedCluster = NULL ;
00275     
00276     
00277     
00278     //....................................
00279     // Cluster isolation
00280     
00281     if( storedClusters.begin() ) {
00282       
00283       if( storedClusters.size() > 0 ) {
00284         
00285         // Make a local copy as we want to mutate the list of pointers
00286         std::vector<Cluster*>  clusters( 
00287                                         storedClusters.begin(), 
00288                                         storedClusters.end() 
00289                                         );
00290         
00291         //Only use clusters not already claimed by ReconstructedParticles
00292         std::vector<Cluster*>::iterator firstNonAssociatedCluster ;
00293         firstNonAssociatedCluster = std::partition(
00294                                                    clusters.begin(),
00295                                                    clusters.end(),
00296                                                    ClusterIsAssoc()
00297                                                    );
00298         if(firstNonAssociatedCluster != clusters.begin()){
00299           log<<MSG::DEBUG<<"First "
00300              <<firstNonAssociatedCluster-clusters.begin()
00301              <<" clusters are associated to ReconstructedParticles "
00302              <<clusters.end()-firstNonAssociatedCluster
00303              <<" cluster(s) remain"
00304              <<endreq;
00305         }else{
00306           log<<MSG::DEBUG
00307              <<"No clusters are associated to ReconstructedParticles"
00308              <<endreq;
00309         }
00310         if(clusters.end()!=firstNonAssociatedCluster){
00311           // .....................
00312           // Associate unclaimed clusters with current particle. 
00313           // This looks at the nearest cluster only, and decides whether
00314           // it is within an "association" cone
00315           
00316           partial_sort(
00317                        firstNonAssociatedCluster,
00318                        firstNonAssociatedCluster+1,
00319                        clusters.end(), 
00320                        SortAttribute::DeltaR( *particle )
00321                        );
00322           
00323           log<<MSG::DEBUG<<"Sorted clusters "<<endreq;
00324           
00325           associated =
00326             (m_kinehelp.deltaR(*particle, *firstNonAssociatedCluster) <  
00327              m_rClusterMatch);
00328           
00329           if( associated ) 
00330             {
00331               log << "\n\t -->Found associated cluster: "  
00332                   << *clusters.begin() ;
00333               
00334               // Remember the relevant cluster until the end of this method
00335               associatedCluster = *firstNonAssociatedCluster ;
00336               
00337               // Set the first nonassociated cluster
00338               ++firstNonAssociatedCluster;
00339               
00340             }
00341           
00342           
00343           //............................................
00344           // Now we can check Cluster Isolation 
00345           // (if there is at least one more cluster to check)
00346           
00347           // Use kinematic helper to do all work
00348           double eClusterSum = m_kinehelp.sumETInCone( 
00349                                                       firstNonAssociatedCluster, 
00350                                                       clusters.end(), 
00351                                                       *particle,
00352                                                       m_rClusterIsolation
00353                                                       );
00354           
00355           // Apply the cut criteria
00356           
00357           if( eClusterSum  > m_eClusterIsolation ) 
00358             log  << "\n\t -->Excess Cluster energy in cone = " << eClusterSum 
00359                  << "   => NOT-ISOLATED " << endreq;       
00360           else
00361             log  << "\n\t -->Excess Cluster energy in cone = " << eClusterSum 
00362                  << "   => ISOLATED "  ;
00363           
00364           if( eClusterSum  > m_eClusterIsolation )  return false ;
00365           
00366         }
00367         
00368       }
00369     }
00370     
00371     
00372     //............................................
00373     // Cell Isolation: 
00374     
00375     if( storedCells.begin() ) {
00376       
00377       // Test on isolation in respect of the total transverese energy of all 
00378       // Cells within a given r-cone
00379       
00380       // Use kinematic helper to do all work
00381       double eCellSum = m_kinehelp.sumETInCone( 
00382                                                storedCells.begin(), 
00383                                                storedCells.end(), 
00384                                                *particle,
00385                                                m_rCellIsolation
00386                                                );
00387       
00388       
00389       // Subtract the energy associated with particle under test
00390       // as the cells summed will have included its deposit
00391       //    CalSelect depositsInCal;
00392       //    if(depositsInCal( *particle) ) eCellSum -= (*particle)->eT() ;
00393       bool itDeposits = m_visibleToCal->operator()( (*particle)->truth() );
00394       
00395       if(itDeposits) eCellSum -= (*particle)->eT() ;
00396       
00397       
00398       // Apply isolation criteria
00399       
00400       if( eCellSum  > m_eCellIsolation ) 
00401         log  
00402           << "\n\t -->Excess Cell energy in cone = " << eCellSum 
00403           << "   => NOT-ISOLATED " << endreq ;    
00404       else
00405         log   
00406           << "\n\t -->Excess Cell energy in cone = " << eCellSum 
00407           << "   => ISOLATED " ;
00408       
00409       if( eCellSum  > m_eCellIsolation ) return false ;
00410       
00411     }
00412     
00413     //..........................................
00414     // If we get here then the candidate was judged to be isolated
00415     
00416     // It is only now that we wish to set associations between isolated
00417     // particles and clusters. I.e we dont want to flag associations for 
00418     // non-isolated particles
00419     
00420     if( associated ) {
00421       
00422       // Set the association from Particle -> Cluster
00423       IAssociationManager* iamp = *particle;
00424       iamp->associate( associatedCluster ) ;
00425       
00426       // Set the association from Cluster -> Particle
00427       IAssociationManager* iamc = associatedCluster;
00428       iamc->associate( *particle ) ;
00429       
00430     }
00431     
00432     log << endreq ;
00433     
00434     return true ;
00435   }
00436   
00437 } // end of namespace bracket

Generated on Tue Jan 28 09:57:13 2003 for AtlfastAlgs by doxygen1.3-rc1