CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/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 
00189   // for each element in turn
00190   std::vector<bool> toPrint(elements.size(),static_cast<bool>(true));
00191   for(unsigned ie=0; ie<elements.size(); ie++) {
00192     
00193     PFBlockElement::Type type = elements[ie].type();
00194     std::multimap<double, unsigned> ecalElems;
00195     switch(type){
00196     case PFBlockElement::TRACK:
00197       iTK++;
00198       ss << "TK" << iTK;
00199       break;
00200     case PFBlockElement::GSF:
00201       iGSF++;
00202       ss << "GSF" << iGSF;
00203       break;
00204     case PFBlockElement::BREM:
00205       block.associatedElements( ie,  block.linkData(),
00206                                 ecalElems ,
00207                                 reco::PFBlockElement::ECAL,
00208                                 reco::PFBlock::LINKTEST_ALL );
00209       iBREM++;
00210       if ( ecalElems.size() ) { 
00211         ss << "BR" << iBREM;
00212       } else {
00213         toPrint[ie] = false;
00214       }
00215       break;    
00216     case PFBlockElement::SC:
00217       iSC++;
00218       ss << "SC" << iSC;
00219       break;
00220     default:{
00221       PFClusterRef clusterref = elements[ie].clusterRef();
00222       int layer = clusterref->layer();
00223       switch (layer){
00224       case PFLayer::PS1:
00225         iPS1++;
00226         ss << "PV" << iPS1;
00227         break;
00228       case PFLayer::PS2:
00229         iPS2++;
00230         ss << "PH" << iPS2;
00231         break;
00232       case PFLayer::ECAL_ENDCAP:
00233         iEE++;
00234         ss << "EE" << iEE;
00235         break;
00236       case PFLayer::ECAL_BARREL:
00237         iEB++;
00238         ss << "EB" << iEB;
00239         break;
00240       case PFLayer::HCAL_ENDCAP:
00241         iHE++;
00242         ss << "HE" << iHE;
00243         break;
00244       case PFLayer::HCAL_BARREL1:
00245         iHB++;
00246         ss << "HB" << iHB;
00247         break;
00248       case PFLayer::HF_EM:
00249         iHFEM++;
00250         ss << "FE" << iHFEM;
00251         break;
00252       case PFLayer::HF_HAD:
00253         iHFHAD++;
00254         ss << "FH" << iHFHAD;
00255         break;
00256       default:
00257         iel++;   
00258         ss << "??" << iel;
00259         break;
00260       }
00261       break;
00262     }
00263     }
00264     s = ss.str();
00265     elid.push_back( s );
00266     // clear stringstream
00267     ss.str("");
00268 
00269     if ( toPrint[ie] ) out<<"\t"<< s <<" "<<elements[ie] <<endl;
00270   }
00271   
00272   out<<endl;
00273 
00274   int width = 6;
00275   if( !block.linkData().empty() ) {
00276     out<<endl<<"\tlink data (distance x 1000): "<<endl;
00277     out<<setiosflags(ios::right);
00278     out<<"\t" << setw(width) << " ";
00279     for(unsigned ie=0; ie<elid.size(); ie++) 
00280       if ( toPrint[ie] ) out <<setw(width)<< elid[ie];
00281     out<<endl;  
00282     out<<setiosflags(ios::fixed);
00283     out<<setprecision(1);      
00284   
00285     for(unsigned i=0; i<block.elements_.size(); i++) {
00286       if ( !toPrint[i] ) continue;
00287       out<<"\t";
00288       out <<setw(width) << elid[i];
00289       for(unsigned j=0; j<block.elements_.size(); j++) {
00290         if ( !toPrint[j] ) continue;
00291         double Dist = block.dist(i,j, block.linkData());//,PFBlock::LINKTEST_ALL);
00292 
00293         // out<<setw(width)<< Dist*1000.;
00294         if (Dist > -0.5) out<<setw(width)<< Dist*1000.; 
00295         else  out <<setw(width)<< " ";
00296       }
00297       out<<endl;
00298     }
00299 
00300         
00301     out<<endl<<"\tlink data (distance x 1000) for tracking links : "<<endl;
00302     out<<setiosflags(ios::right);
00303     out<<"\t" << setw(width) << " ";
00304     for(unsigned ie=0; ie<elid.size(); ie++) 
00305       if ( toPrint[ie] && 
00306            ( block.elements_[ie].type() == PFBlockElement::TRACK ||
00307              block.elements_[ie].type() == PFBlockElement::GSF )) 
00308         out <<setw(width)<< elid[ie];
00309     out<<endl;  
00310     out<<setiosflags(ios::fixed);
00311     out<<setprecision(1);      
00312   
00313     for(unsigned i=0; i<block.elements_.size(); i++) {
00314       if ( !toPrint[i] || 
00315            (block.elements_[i].type() != PFBlockElement::TRACK &&
00316             block.elements_[i].type() != PFBlockElement::GSF )) continue;
00317       out<<"\t";
00318       out <<setw(width) << elid[i];
00319       for(unsigned j=0; j<block.elements_.size(); j++) {
00320         if ( !toPrint[j] || 
00321              (block.elements_[j].type() != PFBlockElement::TRACK &&
00322               block.elements_[j].type() != PFBlockElement::GSF )) continue;
00323         double Dist = block.dist(i,j, block.linkData());//,PFBlock::LINKTEST_ALL);
00324 
00325         // out<<setw(width)<< Dist*1000.;
00326         if (Dist > -0.5) out<<setw(width)<< Dist*1000.; 
00327         else  out <<setw(width)<< " ";
00328       }
00329       out<<endl;
00330     }
00331     
00332     out<<setprecision(3);  
00333     out<<resetiosflags(ios::right|ios::fixed);
00334 
00335   }
00336   else {
00337     out<<"\tno links."<<endl;
00338   }
00339   
00340   return out;
00341 }
00342  
00343  
00344 unsigned PFBlock::linkDataSize() const {
00345   unsigned n = elements_.size();
00346   
00347   // number of possible undirected links between n elements.
00348   // reflective links impossible.
00349  
00350   return n*(n-1)/2; 
00351 }