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

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

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