CMS 3D CMS Logo

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