CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/Fireworks/ParticleFlow/plugins/FWPFCandidateWithHitsProxyBuilder.cc

Go to the documentation of this file.
00001 
00002 #define protected public
00003 #include "TEveBoxSet.h"
00004 #undef protected
00005 #include "TEveTrack.h"
00006 #include "TEveTrackPropagator.h"
00007 #include "TEveCompound.h"
00008 #include "TEveStraightLineSet.h"
00009 #include "TEveProjectionBases.h"
00010 
00011 #include "Fireworks/ParticleFlow/plugins/FWPFCandidateWithHitsProxyBuilder.h"
00012 #include "Fireworks/Core/interface/FWEventItem.h"
00013 #include "Fireworks/Core/interface/FWGeometry.h"
00014 #include "Fireworks/Core/interface/BuilderUtils.h"
00015 #include "Fireworks/Core/interface/fwLog.h"
00016 #include "Fireworks/Core/interface/FWViewEnergyScale.h"
00017 #include "Fireworks/Core/interface/FWProxyBuilderConfiguration.h"
00018 #include "Fireworks/ParticleFlow/interface/setTrackTypePF.h"
00019 
00020 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
00021 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00022 #include "DataFormats/ParticleFlowReco/interface/PFBlock.h"
00023 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00024 
00025 #include "DataFormats/FWLite/interface/Handle.h"
00026 
00027 namespace
00028 {
00029 static std::string kRecHitCollectionName = "RecHitCollection";
00030 void  addLineToLineSet(TEveStraightLineSet* ls, const float* p, int i1, int i2)
00031 {
00032    i1 *= 3;
00033    i2 *= 3;
00034    ls->AddLine(p[i1], p[i1+1], p[i1+2], p[i2], p[i2+1], p[i2+2]);
00035 }
00036 
00037 
00038 void addBoxAsLines(TEveStraightLineSet* lineset, const float* p)
00039 {
00040    for (int l = 0; l < 5; l+=4)
00041    {
00042       addLineToLineSet(lineset, p, 0+l, 1+l);
00043       addLineToLineSet(lineset, p, 1+l, 2+l);
00044       addLineToLineSet(lineset, p, 2+l, 3+l);
00045       addLineToLineSet(lineset, p, 3+l, 0+l);
00046    }
00047    for (int l = 0; l < 4; ++l)
00048       addLineToLineSet(lineset, p, 0+l, 4+l);
00049 }
00050 
00051 void  editLineInLineSet(TEveChunkManager::iterator& li, const float* p, int i1, int i2)
00052 {
00053    TEveStraightLineSet::Line_t& line = * (TEveStraightLineSet::Line_t*) li();
00054    i1 *= 3;
00055    i2 *= 3;
00056    for (int i = 0; i < 3 ; ++i) {
00057       line.fV1[0+i] = p[i1+i];
00058       line.fV2[0+i] = p[i2+i];
00059    }
00060 
00061    li.next();
00062 }
00063 
00064 void editBoxInLineSet(TEveChunkManager::iterator& li, const float* p)
00065 {
00066     
00067    for (int i = 0; i < 5; i+=4)
00068    {
00069       editLineInLineSet(li, p, 0+i, 1+i);
00070 
00071       editLineInLineSet(li, p, 1+i, 2+i);
00072       editLineInLineSet(li, p, 2+i, 3+i);
00073       editLineInLineSet(li, p, 3+i, 0+i);
00074    }
00075    for (int i = 0; i < 4; ++i)
00076       editLineInLineSet(li, p, 0+i, 4+i);
00077 }
00078 }
00079 
00080  //______________________________________________________________________________
00081 
00082 void FWPFCandidateWithHitsProxyBuilder::setItem(const FWEventItem* iItem)
00083 {
00084 
00085    FWProxyBuilderBase::setItem(iItem);
00086    if (iItem) {
00087       std::string defn =  "particleFlowRecHitHCAL";
00088       iItem->getConfig()->assertParam(kRecHitCollectionName, defn);
00089    }
00090 }
00091 
00092 //______________________________________________________________________________
00093 void 
00094 FWPFCandidateWithHitsProxyBuilder::build(const FWEventItem* iItem, TEveElementList* product, const FWViewContext* vc)
00095 {
00096    // init PFCandiate collection
00097    reco::PFCandidateCollection const * candidates = 0;
00098    iItem->get( candidates );
00099    if( candidates == 0 ) return;
00100 
00101    Int_t idx = 0;
00102    initPFRecHitsCollections();
00103    for( reco::PFCandidateCollection::const_iterator it = candidates->begin(), itEnd = candidates->end(); it != itEnd; ++it, ++idx)
00104    {  
00105       TEveCompound* comp = createCompound();
00106       setupAddElement( comp, product );
00107       // printf("products size %d/%d \n", (int)iItem->size(), product->NumChildren());
00108 
00109       const reco::PFCandidate& cand = *it;
00110       
00111       // track
00112       {
00113          TEveRecTrack t;
00114          t.fBeta = 1.;
00115          t.fP = TEveVector( cand.px(), cand.py(), cand.pz() );
00116          t.fV = TEveVector( cand.vertex().x(), cand.vertex().y(), cand.vertex().z() );
00117          t.fSign = cand.charge();
00118          TEveTrack* trk = new TEveTrack(&t, context().getTrackPropagator() );
00119          trk->MakeTrack();
00120          fireworks::setTrackTypePF( cand, trk );
00121          setupAddElement( trk, comp);
00122       }
00123       // hits
00124       {
00125          comp->SetMainColor(iItem->defaultDisplayProperties().color());
00126          addHitsForCandidate(cand, comp, vc);
00127       }
00128 
00129    }
00130 }
00131 
00132 //______________________________________________________________________________
00133 void FWPFCandidateWithHitsProxyBuilder::initPFRecHitsCollections()
00134 {  
00135    // ref hcal collections
00136    edm::Handle<reco::PFRecHitCollection> handle_hits;
00137 
00138 
00139    m_collectionHCAL =0;
00140    try
00141    {
00142       std::string scc = item()->getConfig()->value<std::string>(kRecHitCollectionName);
00143       edm::InputTag tag(scc);
00144       item()->getEvent()->getByLabel(tag, handle_hits);
00145       if (handle_hits.isValid())
00146       {
00147          m_collectionHCAL = &*handle_hits;
00148          fwLog(fwlog::kInfo) <<"FWPFCandidateWithHitsProxyBuilder, item " << item()->name() <<": Accessed collection with name " << scc << "." << std::endl;
00149       }
00150       else
00151       {
00152          fwLog(fwlog::kError) <<"FWPFCandidateWithHitsProxyBuilder, item " << item()->name() <<": Failed to access collection with name " << scc << "." << std::endl;
00153       }
00154    }
00155    catch (...)
00156    {
00157       fwLog(fwlog::kError) <<"FWPFCandidateWithHitsProxyBuilder, item " << item()->name() <<": Failed to access rechit collection \n";
00158    }
00159 }
00160 
00161 //______________________________________________________________________________
00162 void FWPFCandidateWithHitsProxyBuilder::viewContextBoxScale( const float* corners, float scale, bool plotEt, std::vector<float>& scaledCorners, const reco::PFRecHit*)
00163 {
00164    static TEveVector vtmp;
00165    vtmp.Set(0.f, 0.f, 0.f);
00166    for( unsigned int i = 0; i < 24; i += 3 )
00167    {     
00168       vtmp[0] += corners[i];
00169       vtmp[1] += corners[i + 1];
00170       vtmp[2] += corners[i + 2];
00171    }
00172    vtmp *= 1.f/8.f;
00173 
00174    if (plotEt)
00175    {
00176       scale *= vtmp.Perp()/vtmp.Mag();
00177    }
00178 
00179    // Coordinates for a scaled version of the original box
00180    for( unsigned int i = 0; i < 24; i += 3 )
00181    {    
00182       scaledCorners[i] = vtmp[0] + ( corners[i] - vtmp[0] ) * scale;
00183       scaledCorners[i + 1] = vtmp[1] + ( corners[i + 1] - vtmp[1] ) * scale;
00184       scaledCorners[i + 2] = vtmp[2] + ( corners[i + 2] - vtmp[2] ) * scale;
00185    }
00186 }
00187 
00188 //______________________________________________________________________________
00189 const reco::PFRecHit* FWPFCandidateWithHitsProxyBuilder::getHitForDetId(unsigned candIdx)
00190 {
00191 
00192    for (reco::PFRecHitCollection::const_iterator it = m_collectionHCAL->begin(); it != m_collectionHCAL->end(); ++it)
00193    {
00194 
00195       if ( it->detId() == candIdx)
00196       {
00197          return  &(*it);
00198       }
00199    }
00200    return 0;
00201 }
00202 
00203 //______________________________________________________________________________
00204 void FWPFCandidateWithHitsProxyBuilder::scaleProduct(TEveElementList* parent, FWViewType::EType type, const FWViewContext* vc)
00205 {
00206    std::vector<float> scaledCorners(24);
00207 
00208    float scale = vc->getEnergyScale()->getScaleFactor3D()/50;
00209    for (TEveElement::List_i i=parent->BeginChildren(); i!=parent->EndChildren(); ++i)
00210    {
00211       if ((*i)->NumChildren() > 1)
00212       {
00213          TEveElement::List_i xx =  (*i)->BeginChildren(); ++xx;
00214          TEveBoxSet* boxset = dynamic_cast<TEveBoxSet*>(*xx);
00215          ++xx;
00216          TEveStraightLineSet* lineset = dynamic_cast<TEveStraightLineSet*>(*xx);
00217          TEveChunkManager::iterator li(lineset->GetLinePlex());
00218          li.next();
00219 
00220 
00221          TEveChunkManager* plex = boxset->GetPlex();
00222          if (plex->N())
00223          {
00224             for (int atomIdx=0; atomIdx < plex->Size(); ++atomIdx)
00225             {
00226               
00227                TEveBoxSet::BFreeBox_t* atom = (TEveBoxSet::BFreeBox_t*)boxset->GetPlex()->Atom(atomIdx);
00228                reco::PFRecHit* hit = (reco::PFRecHit*)boxset->GetUserData(atomIdx);
00229                const float* corners = item()->getGeom()->getCorners(hit->detId());
00230                viewContextBoxScale(corners, hit->energy()*scale, vc->getEnergyScale()->getPlotEt(), scaledCorners, hit);
00231                memcpy(atom->fVertices, &scaledCorners[0], sizeof(atom->fVertices));
00232 
00233                editBoxInLineSet(li, &scaledCorners[0]);
00234             }
00235 
00236             for (TEveProjectable::ProjList_i p = lineset->BeginProjecteds(); p != lineset->EndProjecteds(); ++p)
00237             {
00238                TEveStraightLineSetProjected* projLineSet = (TEveStraightLineSetProjected*)(*p);
00239                projLineSet->UpdateProjection();
00240             }
00241          }
00242       }
00243    }
00244 }  
00245 //______________________________________________________________________________
00246 namespace {
00247 TString boxset_tooltip_callback(TEveDigitSet* ds, Int_t idx)
00248 {
00249    void* ud = ds->GetUserData(idx);
00250    if (ud);
00251    {
00252       reco::PFRecHit* hit = (reco::PFRecHit*) ud;
00253       // printf("idx %d %p hit data %p\n", idx, (void*)hit, ud);
00254       if (hit)
00255          return TString::Format("RecHit %d energy '%f'", idx,  hit->energy());
00256       else
00257          return "ERROR";
00258    }
00259 }
00260 }
00261 //______________________________________________________________________________
00262 void FWPFCandidateWithHitsProxyBuilder::addHitsForCandidate(const reco::PFCandidate& cand, TEveElement* holder, const FWViewContext* vc)
00263 { 
00264    reco::PFCandidate::ElementsInBlocks eleInBlocks = cand.elementsInBlocks();
00265 
00266    TEveBoxSet* boxset = 0;
00267    TEveStraightLineSet* lineset = 0;
00268 
00269    for(unsigned elIdx=0; elIdx<eleInBlocks.size(); elIdx++)
00270    {
00271       // unsigned ieTrack = 0;
00272       // unsigned ieECAL = 0;
00273       unsigned ieHCAL = 0;
00274 
00275       reco::PFBlockRef blockRef = eleInBlocks[elIdx].first;
00276       unsigned indexInBlock = eleInBlocks[elIdx].second;
00277       edm::Ptr<reco::PFBlock> myBlock(blockRef.id(),blockRef.get(), blockRef.key());
00278       /*
00279         if (myBlock->elements()[indexInBlock].type() == 1)
00280         ieTrack = indexInBlock;
00281         if (myBlock->elements()[indexInBlock].type() == 4)
00282         ieECAL = indexInBlock;
00283       */
00284       if (myBlock->elements()[indexInBlock].type() == 5)
00285          ieHCAL = indexInBlock;
00286    
00287  
00288       std::vector<float> scaledCorners(24);
00289       float scale = vc->getEnergyScale()->getScaleFactor3D()/50;
00290       if (ieHCAL &&  m_collectionHCAL) {
00291          reco::PFClusterRef hcalclusterRef=myBlock->elements()[ieHCAL].clusterRef();
00292          edm::Ptr<reco::PFCluster> myCluster(hcalclusterRef.id(),hcalclusterRef.get(), hcalclusterRef.key());
00293          if (myCluster.get())
00294          {
00295             const std::vector< std::pair<DetId, float> > & hitsandfracs = myCluster->hitsAndFractions();
00296 
00297             if (!boxset)
00298             {
00299                boxset = new TEveBoxSet();
00300                boxset->Reset(TEveBoxSet::kBT_FreeBox, true, hitsandfracs.size());
00301                boxset->SetAntiFlick(true);
00302                boxset->SetAlwaysSecSelect(1);
00303                boxset->SetPickable(1);
00304                boxset->SetTooltipCBFoo(boxset_tooltip_callback);
00305             }
00306 
00307             if (!lineset)
00308             {
00309                lineset = new TEveStraightLineSet();
00310             }
00311 
00312             bool hitsFound = false;
00313             for ( int ihandf=0, lastIdx=(int)(hitsandfracs.size()); ihandf<lastIdx; ihandf++) 
00314             {
00315                unsigned int hitDetId = hitsandfracs[ihandf].first;
00316                const float* corners = context().getGeom()->getCorners(hitDetId);
00317                const reco::PFRecHit* hit = getHitForDetId(hitDetId);
00318                if (hit)
00319                {
00320                   viewContextBoxScale( corners, hit->energy()*scale, vc->getEnergyScale()->getPlotEt(), scaledCorners, hit);
00321                   boxset->AddBox( &scaledCorners[0]);
00322                   // setup last box
00323                   boxset->DigitColor(holder->GetMainColor());
00324                   boxset->DigitUserData((void*)hit);
00325                   addBoxAsLines(lineset, &scaledCorners[0]);
00326                   hitsFound = true;
00327                }
00328                /*
00329                // AMT: don't add lines if hit is not found becuse of unconsistency of scaling.
00330                else
00331                {
00332                   addBoxAsLines(lineset, corners);
00333                }
00334                */
00335             }
00336             if (!hitsFound)
00337                fwLog(fwlog::kWarning) << Form("Can't find matching hits with for HCAL block %d in RecHit collection. Number of hits %d.\n", elIdx, (int)hitsandfracs.size());
00338 
00339 
00340          }
00341          else
00342          {
00343             fwLog(fwlog::kInfo) << "empty cluster \n";
00344          }
00345       }
00346    } // endloop cand.elementsInBlocks();
00347 
00348 
00349    if (boxset) {
00350       boxset->RefitPlex();
00351       setupAddElement(boxset, holder);
00352    }
00353 
00354    if (lineset) {
00355       setupAddElement(lineset, holder);
00356    }
00357 }
00358 
00359 REGISTER_FWPROXYBUILDER(FWPFCandidateWithHitsProxyBuilder, reco::PFCandidateCollection,"PF CandidatesWithHits", FWViewType::kAll3DBits | FWViewType::kAllRPZBits );