CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/DataFormats/ParticleFlowReco/src/PFBlock.cc

Go to the documentation of this file.
00001 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00002 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00003 #include "DataFormats/ParticleFlowReco/interface/PFLayer.h"
00004 
00005 #include <iomanip>
00006 #include <sstream>
00007 
00008 using namespace std;
00009 using namespace reco;
00010 
00011 
00012 void PFBlock::addElement(  PFBlockElement* element ) {
00013   element->setIndex( elements_.size() );
00014   element->lock();
00015   elements_.push_back( element->clone() ); 
00016 
00017 }
00018 
00019 
00020 void PFBlock::bookLinkData() {
00021 
00022 }
00023 
00024 
00025 
00026 void PFBlock::setLink(unsigned i1, 
00027                       unsigned i2, 
00028                       double Dist,
00029                       LinkData& linkData, 
00030                       LinkTest test) const {
00031   
00032   assert( test<LINKTEST_ALL );
00033   
00034   unsigned index = 0;
00035   bool ok =  matrix2vector(i1,i2, index);
00036 
00037   if(ok) {
00038     //ignore the  -1, -1 pair
00039     if ( Dist > -0.5 ) {
00040       Link & l = linkData[index];
00041       l.distance=Dist;
00042       l.test |= (1 << test);
00043     }     else  //delete if existing
00044       {
00045         LinkData::iterator it = linkData.find(index);
00046         if(it!=linkData.end()) linkData.erase(it);
00047       }
00048 
00049   } else {
00050     assert(0);
00051   }
00052   
00053 }
00054 
00055 
00056 // void PFBlock::lock(unsigned i, LinkData& linkData ) const {
00057   
00058 //   assert( linkData.size() == linkDataSize() );
00059   
00060 //   for(unsigned j=0; j<elements_.size(); j++) {
00061     
00062 //     if(i==j) continue;
00063     
00064 //     unsigned index = 0;
00065 //     bool ok =  matrix2vector(i,j, index);
00066 //     if(ok)
00067 //       linkData[index] = -1;
00068 //     else 
00069 //       assert(0);
00070 //   }
00071 // }
00072 
00073 
00074 
00075 void PFBlock::associatedElements( unsigned i, 
00076                                   const LinkData& linkData, 
00077                                   multimap<double, unsigned>& sortedAssociates,
00078                                   PFBlockElement::Type type,
00079                                   LinkTest test ) const {
00080 
00081   sortedAssociates.clear();
00082   
00083   // i is too large
00084   if( i > elements_.size() ) return;
00085   // assert(i>=0); i >= 0, since i is unsigned
00086   
00087   for(unsigned ie=0; ie<elements_.size(); ie++) {
00088     
00089     // considered element itself
00090     if( ie == i ) {
00091       continue;
00092     }
00093     // not the right type
00094     if(type !=  PFBlockElement::NONE && 
00095        elements_[ie].type() != type ) {
00096       continue;
00097     }
00098 
00099     // Order the elements by increasing distance !
00100 
00101     unsigned index = 0;
00102     if( !matrix2vector(i, ie, index) ) continue;
00103 
00104     double c2=-1;
00105     LinkData::const_iterator it =  linkData.find(index);
00106     if ( it!=linkData.end() && 
00107          ( ( (1 << test ) & it->second.test) !=0 || (test == LINKTEST_ALL) ) ) 
00108       c2= it->second.distance;
00109 
00110     // not associated
00111     if( c2 < 0 ) { 
00112       continue;
00113     }
00114 
00115     sortedAssociates.insert( pair<double,unsigned>(c2, ie) );
00116   }
00117 } 
00118 
00119 bool PFBlock::matrix2vector( unsigned iindex, 
00120                              unsigned jindex, 
00121                              unsigned& index ) const {
00122 
00123   unsigned size = elements_.size();
00124   if( iindex == jindex || 
00125       iindex >=  size ||
00126       jindex >=  size ) {
00127     return false;
00128   }
00129   
00130   if( iindex > jindex ) 
00131     std::swap( iindex, jindex);
00132 
00133   
00134   index = jindex-iindex-1;
00135 
00136   if(iindex>0) {
00137     index += iindex*size;
00138     unsigned missing = iindex*(iindex+1)/2;
00139     index -= missing;
00140   }
00141   
00142   return true;
00143 }
00144 
00145 
00146 double PFBlock::dist( unsigned ie1, unsigned ie2,
00147                       const LinkData& linkData) const {
00148 
00149   double Dist = -1;
00150 
00151   unsigned index = 0;
00152   if( !matrix2vector(ie1, ie2, index) ) return Dist;
00153   LinkData::const_iterator it =  linkData.find(index);
00154   if( it!=linkData.end() ) Dist= it->second.distance;
00155 
00156   return Dist;
00157 
00158 }
00159 
00160 
00161 ostream& reco::operator<<(  ostream& out, 
00162                             const reco::PFBlock& block ) {
00163 
00164   if(! out) return out;
00165   const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
00166   out<<"\t--- PFBlock ---  "<<endl;
00167   out<<"\tnumber of elements: "<<elements.size()<<endl;
00168   
00169   // Build element label (string) : elid from type, layer and occurence number
00170   // use stringstream instead of sprintf to concatenate string and integer into string
00171  
00172   vector <string> elid;
00173   string s;
00174   stringstream ss;
00175   int iel = 0;
00176   int iTK =0;
00177   int iGSF =0;
00178   int iBREM=0;
00179   int iPS1 = 0;
00180   int iPS2 = 0;
00181   int iEE = 0;
00182   int iEB = 0;
00183   int iHE = 0;
00184   int iHB = 0;
00185   int iHFEM = 0;
00186   int iHFHAD = 0;
00187   int iSC = 0;
00188   int iHO = 0;
00189 
00190   // for each element in turn
00191   std::vector<bool> toPrint(elements.size(),static_cast<bool>(true));
00192   for(unsigned ie=0; ie<elements.size(); ie++) {
00193     
00194     PFBlockElement::Type type = elements[ie].type();
00195     std::multimap<double, unsigned> ecalElems;
00196     switch(type){
00197     case PFBlockElement::TRACK:
00198       iTK++;
00199       ss << "TK" << iTK;
00200       break;
00201     case PFBlockElement::GSF:
00202       iGSF++;
00203       ss << "GSF" << iGSF;
00204       break;
00205     case PFBlockElement::BREM:
00206       block.associatedElements( ie,  block.linkData(),
00207                                 ecalElems ,
00208                                 reco::PFBlockElement::ECAL,
00209                                 reco::PFBlock::LINKTEST_ALL );
00210       iBREM++;
00211       if ( ecalElems.size() ) { 
00212         ss << "BR" << iBREM;
00213       } else {
00214         toPrint[ie] = false;
00215       }
00216       break;    
00217     case PFBlockElement::SC:
00218       iSC++;
00219       ss << "SC" << iSC;
00220       break;
00221     default:{
00222       PFClusterRef clusterref = elements[ie].clusterRef();
00223       int layer = clusterref->layer();
00224       switch (layer){
00225       case PFLayer::PS1:
00226         iPS1++;
00227         ss << "PV" << iPS1;
00228         break;
00229       case PFLayer::PS2:
00230         iPS2++;
00231         ss << "PH" << iPS2;
00232         break;
00233       case PFLayer::ECAL_ENDCAP:
00234         iEE++;
00235         ss << "EE" << iEE;
00236         break;
00237       case PFLayer::ECAL_BARREL:
00238         iEB++;
00239         ss << "EB" << iEB;
00240         break;
00241       case PFLayer::HCAL_ENDCAP:
00242         iHE++;
00243         ss << "HE" << iHE;
00244         break;
00245       case PFLayer::HCAL_BARREL1:
00246         iHB++;
00247         ss << "HB" << iHB;
00248         break;
00249       case PFLayer::HCAL_BARREL2:
00250         iHO++;
00251         ss << "HO" << iHO;
00252         break;
00253       case PFLayer::HF_EM:
00254         iHFEM++;
00255         ss << "FE" << iHFEM;
00256         break;
00257       case PFLayer::HF_HAD:
00258         iHFHAD++;
00259         ss << "FH" << iHFHAD;
00260         break;
00261       default:
00262         iel++;   
00263         ss << "??" << iel;
00264         break;
00265       }
00266       break;
00267     }
00268     }
00269     s = ss.str();
00270     elid.push_back( s );
00271     // clear stringstream
00272     ss.str("");
00273 
00274     if ( toPrint[ie] ) out<<"\t"<< s <<" "<<elements[ie] <<endl;
00275   }
00276   
00277   out<<endl;
00278 
00279   int width = 6;
00280   if( !block.linkData().empty() ) {
00281     out<<endl<<"\tlink data (distance x 1000): "<<endl;
00282     out<<setiosflags(ios::right);
00283     out<<"\t" << setw(width) << " ";
00284     for(unsigned ie=0; ie<elid.size(); ie++) 
00285       if ( toPrint[ie] ) out <<setw(width)<< elid[ie];
00286     out<<endl;  
00287     out<<setiosflags(ios::fixed);
00288     out<<setprecision(1);      
00289   
00290     for(unsigned i=0; i<block.elements_.size(); i++) {
00291       if ( !toPrint[i] ) continue;
00292       out<<"\t";
00293       out <<setw(width) << elid[i];
00294       for(unsigned j=0; j<block.elements_.size(); j++) {
00295         if ( !toPrint[j] ) continue;
00296         double Dist = block.dist(i,j, block.linkData());//,PFBlock::LINKTEST_ALL);
00297 
00298         // out<<setw(width)<< Dist*1000.;
00299         if (Dist > -0.5) out<<setw(width)<< Dist*1000.; 
00300         else  out <<setw(width)<< " ";
00301       }
00302       out<<endl;
00303     }
00304 
00305         
00306     out<<endl<<"\tlink data (distance x 1000) for tracking links : "<<endl;
00307     out<<setiosflags(ios::right);
00308     out<<"\t" << setw(width) << " ";
00309     for(unsigned ie=0; ie<elid.size(); ie++) 
00310       if ( toPrint[ie] && 
00311            ( block.elements_[ie].type() == PFBlockElement::TRACK ||
00312              block.elements_[ie].type() == PFBlockElement::GSF )) 
00313         out <<setw(width)<< elid[ie];
00314     out<<endl;  
00315     out<<setiosflags(ios::fixed);
00316     out<<setprecision(1);      
00317   
00318     for(unsigned i=0; i<block.elements_.size(); i++) {
00319       if ( !toPrint[i] || 
00320            (block.elements_[i].type() != PFBlockElement::TRACK &&
00321             block.elements_[i].type() != PFBlockElement::GSF )) continue;
00322       out<<"\t";
00323       out <<setw(width) << elid[i];
00324       for(unsigned j=0; j<block.elements_.size(); j++) {
00325         if ( !toPrint[j] || 
00326              (block.elements_[j].type() != PFBlockElement::TRACK &&
00327               block.elements_[j].type() != PFBlockElement::GSF )) continue;
00328         double Dist = block.dist(i,j, block.linkData());//,PFBlock::LINKTEST_ALL);
00329 
00330         // out<<setw(width)<< Dist*1000.;
00331         if (Dist > -0.5) out<<setw(width)<< Dist*1000.; 
00332         else  out <<setw(width)<< " ";
00333       }
00334       out<<endl;
00335     }
00336     
00337     out<<setprecision(3);  
00338     out<<resetiosflags(ios::right|ios::fixed);
00339 
00340   }
00341   else {
00342     out<<"\tno links."<<endl;
00343   }
00344   
00345   return out;
00346 }
00347  
00348  
00349 unsigned PFBlock::linkDataSize() const {
00350   unsigned n = elements_.size();
00351   
00352   // number of possible undirected links between n elements.
00353   // reflective links impossible.
00354  
00355   return n*(n-1)/2; 
00356 }