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
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
00097
00098 const reco::PFCandidate& cand = *it;
00099
00100
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
00113 {
00114 comp->SetMainColor(iItem->defaultDisplayProperties().color());
00115 addHitsForCandidate(cand, comp, vc);
00116 }
00117
00118 }
00119 }
00120
00121
00122 void FWPFCandidateWithHitsProxyBuilder::initPFRecHitsCollections()
00123 {
00124
00125 edm::Handle<reco::PFRecHitCollection> handle_hits;
00126
00127
00128 m_collectionHCAL =0;
00129 try
00130 {
00131
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
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
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
00260
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
00268
00269
00270
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
00311 boxset->DigitColor(holder->GetMainColor());
00312 boxset->DigitUserData((void*)hit);
00313 addBoxAsLines(lineset, &scaledCorners[0]);
00314 hitsFound = true;
00315 }
00316
00317
00318
00319
00320
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 }
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 );