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
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
00108
00109 const reco::PFCandidate& cand = *it;
00110
00111
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
00124 {
00125 comp->SetMainColor(iItem->defaultDisplayProperties().color());
00126 addHitsForCandidate(cand, comp, vc);
00127 }
00128
00129 }
00130 }
00131
00132
00133 void FWPFCandidateWithHitsProxyBuilder::initPFRecHitsCollections()
00134 {
00135
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
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
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
00272
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
00280
00281
00282
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
00323 boxset->DigitColor(holder->GetMainColor());
00324 boxset->DigitUserData((void*)hit);
00325 addBoxAsLines(lineset, &scaledCorners[0]);
00326 hitsFound = true;
00327 }
00328
00329
00330
00331
00332
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 }
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 );