ClusterConeStrategy.cxx

Go to the documentation of this file.
00001 // ================================================
00002 //        ClusterConeStrategy class Implementation
00003 //
00004 //  + PreCluster helper class
00005 //
00006 // ================================================
00007 //
00008 // Namespace Atlfast
00009 //
00010 #include "AtlfastAlgs/ClusterConeStrategy.h"
00011 
00012 #include "AtlfastEvent/IKinematic.h"
00013 #include "AtlfastEvent/Cluster.h"
00014 #include "AtlfastEvent/CollectionDefs.h"
00015 
00016 #include "AtlfastUtils/FunctionObjects.h"
00017 
00018 #include <cmath> 
00019 #include <algorithm>
00020 #include <vector>
00021 
00022 // Gaudi includes
00023 #include "GaudiKernel/MsgStream.h"
00024 
00025 //Other
00026 #include "CLHEP/Vector/LorentzVector.h"
00027 
00028 
00029 namespace Atlfast {
00030   using std::sort;
00031   using std::partition;
00032 
00033   void 
00034   ClusterConeStrategy::makeClusters( 
00035                                     MsgStream& log, 
00036                                     const std::vector<IKinematic*>&storedCells,
00037                                     IKinematicVector& unusedCells,
00038                                     IClusterCollection* clusters) const {
00039     log << MSG::DEBUG << storedCells.size() << "cells to start with"<<endreq;
00040     // The cell collection suppplied is not mutable as it contains items
00041     // (or pointers to items) in the TES. 
00042     // Therefore we copy pointers to two local mutable collections  as we want 
00043     // to manipulate them as part of the clustering strategy
00044     
00045     // This is to hold cells remaining available for cluster formation. 
00046     localCellCollection availableCells(storedCells.begin(), 
00047                                        storedCells.end() );
00048     localCellIterator firstAvailableCell = availableCells.begin() ;
00049     localCellIterator lastAvailableCell  = availableCells.end() ;
00050     
00051     // This is to keep remaining candidate initiators.
00052     localCellCollection availableInitiators( storedCells.begin(), 
00053                                              storedCells.end() ) ;
00054     localCellIterator firstAvailableInitiator  = availableInitiators.begin() ;
00055     localCellIterator lastAvailableInitiator   = availableInitiators.end() ;
00056 
00057     // Partition the inititator candidates to retain only those above threshold
00058     lastAvailableInitiator 
00059       = partition( firstAvailableInitiator, 
00060                    lastAvailableInitiator,
00061                    PartitionCondition::AboveThresholdET( m_minInitiatorET )
00062                    );
00063     
00064     // Sort the remaining initiator candidates into descending order of eT
00065     // This means the first available initiator will always be the highest eT
00066     sort( firstAvailableInitiator, 
00067           lastAvailableInitiator, 
00068           SortAttribute::DescendingET() 
00069           );
00070     
00071     
00072     // Iterate over all initiator candidates
00073     
00074     while( firstAvailableInitiator != lastAvailableInitiator  ) {
00075       
00076       // Partition the cells to find those within the required R-cone
00077       
00078       //substitute an rCone with no args to stop the compiler wingeing
00079       // about unused parameters
00080       // double rCone = this->rCone( *firstAvailableInitiator ) ;
00081       double rCone = this->rCone( ) ;
00082       
00083       localCellIterator endCellInCone = partition
00084         ( 
00085          firstAvailableCell, 
00086          lastAvailableCell, 
00087          PartitionCondition::BelowThresholdDeltaR( *firstAvailableInitiator, 
00088                                                    rCone )
00089          );
00090       
00091       // Accumulate all cells in cone to get weighted kinematic centre
00092       // We use a PreCluster helper object for this
00093       PreCluster preclus( firstAvailableCell, endCellInCone, m_masslessJets);
00094       
00095       // Test if sum eT is above minumum. 
00096       if( preclus.eT() > m_minClusterET ){
00097         // Make a cluster and add to the collection
00098         HepLorentzVector temp=preclus;
00099         ICluster* newclus =  
00100           new Cluster( temp, firstAvailableCell, endCellInCone ) ;
00101         //      Cluster* newclus =  
00102         //        new Cluster( preclus, firstAvailableCell, endCellInCone ) ;
00103         clusters->push_back( newclus ) ;
00104         
00105         //log << MSG::DEBUG << "New Cluster created " << newclus << endreq ;
00106         
00107         // Remove all used cells from the available initiator range
00108         localCellIterator cell= firstAvailableCell; 
00109         for(; cell != endCellInCone; ++cell ){ 
00110           lastAvailableInitiator =
00111             std::remove( firstAvailableInitiator, 
00112                          lastAvailableInitiator, *cell );
00113         }
00114         
00115         // Remove all used cells from the available cell range
00116         firstAvailableCell = endCellInCone ;
00117         
00118       }else{
00119         //log << MSG::DEBUG << "Failed to form new cluster" 
00120         //    << *firstAvailableInitiator << endreq ;
00121         
00122         // This initiator didnt lead to a good cluster.
00123         // Remove it from the available initiator  range
00124         ++firstAvailableInitiator ;
00125       }
00126       
00127     }
00128 
00129     localCellIterator cellIter = firstAvailableCell;
00130     for(; cellIter!=lastAvailableCell; ++cellIter){
00131       //      unusedCells.push_back(new Cell(**cellIter));
00132       //PS 24/01/03
00133       //the next line replaces the previous line
00134       // but why was it there in the first place?
00135       //      unusedCells.push_back( (*cellIter)->clone() );
00136       unusedCells.push_back(*cellIter);
00137     }
00138     return;
00139   }
00140   
00141   //-------------------------------------------// private: rcone
00142   //------------------------------------------
00143   
00144   // looks up R-cone size according to position of initiator
00145   
00146   //double ClusterConeStrategy::rCone( Cell* initiator )
00147   double ClusterConeStrategy::rCone() const {
00148     // Temporary: return barrel always as we dont have mechanism
00149     // to determine calorimeter geometry yet.
00150     return m_rConeBarrel ;
00151   }
00152   
00153   
00154   
00155   
00156   //-------------------------------------
00157   // PreClusterHelper class
00158   //-------------------------------------
00159   
00160   // Constructor
00161   ClusterConeStrategy::PreCluster::PreCluster( 
00162                                               localCellIterator start, 
00163                                               localCellIterator end,
00164                                               bool masslessJets) : 
00165     m_eT_total(0),
00166     m_eta_weighted(0),
00167     m_masslessJets(masslessJets),
00168     m_momentum_sum( 0, 0, 0, 0 ){ 
00169     
00170     for( localCellIterator cell = start; cell != end; ++cell ){
00171       // Construct sum kinematic quantities weighted by eT
00172       // These are done EXACTLY as per the old ATLFAST++
00173       m_eT_total     += (*cell)->eT() ;
00174       m_eta_weighted += (*cell)->eta() * (*cell)->eT() ;
00175       
00176       // This next code for phi DOES NOT do things in exactly the same
00177       // way as old ATLFAST++
00178       // In particular the simple weighted phi which was implemented
00179       // would seem to have a problem at the cyclic boundary 
00180       // (unless I misunderstood, if it averaged pi-epsilon and -pi+epsilon
00181       // it would get 0 instead of pi
00182       // What is implemented here is a more generic solution which
00183       // is currently only used for phi, but could be used for eT
00184       // and eta also later
00185       
00186       m_momentum_sum += (*cell)->momentum() ;
00187       
00188     } 
00189   }       
00190   
00191   // queries
00192   
00193   double ClusterConeStrategy::PreCluster::eT()  { return m_eT_total ; }
00194   
00195   double ClusterConeStrategy::PreCluster::eta() { 
00196     // Implemented exactly as per the old ATLFAST++
00197     if( m_eT_total > 0 ) return m_eta_weighted / m_eT_total ;
00198     else return 0. ;
00199   }
00200   
00201   double ClusterConeStrategy::PreCluster::phi() { 
00202     // Implemented differently to the old ATLFAST++
00203     return m_momentum_sum.phi() ; 
00204   }
00205   
00206   
00207   // Conversion of eT, eta, phi to HepLorentzVector
00208   ClusterConeStrategy::PreCluster::operator HepLorentzVector () {
00209     
00210     // Note:  there is a good reason this doesnt use the member
00211     // 4-vector. It is trying to mimic as far as possible the old
00212     // ATLFAST++. 
00213     // This may be changed in the future.
00214     
00215     double theta = atan( exp( - this->eta() ) ) * 2.0 ;
00216     
00217     double x=0.,y=0.,z=0.,t=0. ;
00218     
00219     if( (0. < theta) && ( theta < M_PI ) )
00220       {           
00221         if(m_masslessJets){
00222           t = this->eT() / sin( theta ) ;
00223           x = this->eT() * cos( this->phi() ) ;
00224           y = this->eT() * sin( this->phi() ) ;
00225           z = t * cos( theta ) ;
00226         }else{
00227           t = m_momentum_sum.e();
00228           x = m_momentum_sum.px();
00229           y = m_momentum_sum.py();
00230           z = m_momentum_sum.pz();
00231         }
00232       }
00233     
00234     return HepLorentzVector( x, y, z, t ) ; 
00235   }
00236 } // end of namespace bracket
00237 
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 

Generated on Mon Sep 24 14:19:12 2007 for AtlfastAlgs by  doxygen 1.5.1