ATLAS Offline Software
Loading...
Searching...
No Matches
MissingEtHandle.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
5
7// //
8// Implementation of class MissingEtHandle //
9// //
10// //
12
13// Local
14#include "MissingEtHandle.h"
15#include "AODSysCommonData.h"
16
17//VP1
18#include "VP1Base/VP1Msg.h"
19
20//SoCoin
21#include <Inventor/C/errors/debugerror.h>
22#include <Inventor/nodes/SoLineSet.h>
23#include <Inventor/nodes/SoPointSet.h>
24#include <Inventor/nodes/SoVertexProperty.h>
25#include <Inventor/nodes/SoMaterial.h>
26#include <Inventor/nodes/SoCone.h>
27#include <Inventor/nodes/SoSeparator.h>
28#include <Inventor/nodes/SoTranslation.h>
29#include <Inventor/nodes/SoRotationXYZ.h>
30#include <Inventor/nodes/SoScale.h>
31#include <Inventor/nodes/SoDrawStyle.h>
32#include <Inventor/nodes/SoCoordinate3.h>
33#include <Inventor/nodes/SoGroup.h>
34
35#include <Inventor/SoPath.h>
36
37#include <SoDebug.h> // it's stored at /afs/cern.ch/sw/lcg/external/coin3d/3.1.3p2/x86_64-slc6-gcc47-opt/include/SoDebug.h
39#include "MissingEtCollHandle.h"
40
41// System of units
42#ifdef BUILDVP1LIGHT
43 #include "GeoModelKernel/Units.h"
44 #define SYSTEM_OF_UNITS GeoModelKernelUnits // --> 'GeoModelKernelUnits::cm'
45#else
46 #include "GaudiKernel/SystemOfUnits.h"
47 #define SYSTEM_OF_UNITS Gaudi::Units // --> 'Gaudi::Units::cm'
48#endif
49
50//double MissingEtHandle::thickness = 1.0;
51//double MissingEtHandle::scale = 1.0;
52//bool MissingEtHandle::shape = true;
53
54
55//____________________________________________________________________
57public:
58 // constructor and default values
59 //Imp () : theclass(0), controller(0), scale(1.0), bTaggingTagger("MV1"),bTaggingCut(0.98),randomColours(false),bTaggingSwitch(0),bTaggingTexture(0), bTaggingMaterial(0) {} // NOTE: parameters from the old JetCollection
60 //Imp () : theclass(0), scale(1.0) {} // TODO: implement the parameters above, from the old JetCollection
61
62 MissingEtHandle * theclass = nullptr; // the Jet class
63 const MissingEtCollHandle* theCollHandle = nullptr; // the CollHandle instance
65
66 const xAOD::MissingET * m_met = nullptr; // the met object
67
68 SoSeparator * sep = nullptr; // everything hangs from this.
69 SoGroup * base = nullptr ;//This gathers the whole dashed line visualizing MissingEt.
70 SoCone * cone = nullptr ;//This gathers the whole dashed line visualizing MissingEt.
71 // SoMaterial * m_randomMat; // random material for jets
72
73
74 //QList<std::pair<xAOD::ParameterPosition, Amg::Vector3D> > parametersAndPositions; // cache // TODO: see if useful for jets
75
76 //Settings:
77 // bool considerTransverseEnergies = true; // TODO: update with button connection "E/Et" (see VP1JetCollection.cxx)
78 // double coneRPar = -1; // FIXME: add calculation of coneRPar, like in the old VP1 Jet
79 double scale = 10.0; // default
80 double length = 1.0; // default
81 double thickness = 1.0; // default
82 bool shape = true; // default
83 double maxR = 0.0;
84
85
86 // SoLineSet * line;//This represents the line(s) representing the trackparticle. Can be interpolated.
87 // SoPointSet * points;//This represents the points(s) representing the trackparticle's parameters.
88
89
90 // Getters
91 QString name() const { return QString::fromStdString( m_met->name() ); }
92 double mpx() const { return m_met->mpx(); }
93 double mpy() const { return m_met->mpy(); }
94 double met() const { return m_met->met(); }
95 double phi() const { /*VP1Msg::messageVerbose("phi: " + QString::number(m_met->phi()) );*/ return m_met->phi(); }
96 double sumet() const { return m_met->sumet(); }
97
98
99 // double eta() const { /*VP1Msg::messageVerbose("eta: " + QString::number(m_met->eta()) );*/ return m_met->eta(); }
100 // double energyForLengthAndCuts() const { return considerTransverseEnergies ? transverseEnergy() : energy(); }
101
102 //Create/manipulate 3D objects:
103 // void createShapeFromJetParameters(const MissingEtCollHandle* collHandleJet, const double& coneR, const double& eta, const double& phi, const double& energy, const SbVec3f& origin);
105
106 void updateConeHeightParameters(SoCone*, SoTranslation*, const double& energy) const;
107 void updateConeHeightParameters() const;
108
109 // Update random material
110 // void rerandomiseMaterial();
111
112
113};
114
115//____________________________________________________________________
117 : AODHandleBase(ch), m_d(new Imp)
118{
119 VP1Msg::messageVerbose("MissingEtHandle::MissingEtHandle() - constructor");
120 m_d->theclass = this;
121 m_d->m_met = met;
122
123 m_d->sep = 0;
124 m_d->cone = 0;
125 // m_d->m_randomMat = 0;
126
127 // m_d->theCollHandle = dynamic_cast<const MissingEtCollHandle*>(collHandle());
128 m_d->theCollHandle = 0;
129}
130
131//____________________________________________________________________
133{
134 // VP1Msg::messageVerbose("MissingEtHandle::~MissingEtHandle() - destructor");
135 // if (m_d->m_randomMat) m_d->m_randomMat->unref();
136 if (m_d->cone) m_d->cone->unref();
137 if (m_d->base) m_d->base->unref();
138 if (m_d->sep) m_d->sep->unref();
139 delete m_d;
140}
141
142//____________________________________________________________________
144 // By default we use the collection material.
145 // std::cout<<"VertexHandle::determineMaterial() - collHandle()->material()"<<collHandle()->material()<<std::endl;
146 return collHandle()->material();
147}
148
149// Setter
150//____________________________________________________________________
151void MissingEtHandle::setScale( const double& sc) { m_d->scale = sc; }
152
154//void MissingEtHandle::rerandomiseMaterial() {m_d->rerandomiseMaterial(); }
155
156//____________________________________________________________________
158{
159 // VP1Msg::messageVerbose("MissingEtHandle::has3DObjects()");
160 return 0 != m_d->sep;
161}
162
163
164//____________________________________________________________________
166 // VP1Msg::messageVerbose("MissingEtHandle::clear3DObjects()");
167
168 // if (m_d->m_randomMat) {
169 // m_d->m_randomMat->unref();
170 // m_d->m_randomMat = 0;
171 // }
172 if (m_d->cone) {
173 m_d->cone->unref();
174 m_d->cone = 0;
175 }
176 if (m_d->sep) {
177 m_d->sep->unref();
178 m_d->sep = 0;
179 }
180
181}
182
183
184
185/*
186* This is the method which makes the 3D objects from the measurements
187*/
188//____________________________________________________________________
190
191 VP1Msg::messageVerbose("MissingEtHandle::nodes()");
192
193 if (m_d->sep) {
194 VP1Msg::messageVerbose("d->sep already defined (" + VP1Msg::str(m_d->sep) + "). Returning d->sep.");
195 return m_d->sep; // FIXME - do we need to check if anything need to be redrawn?
196 }
197 if (!m_d->sep) {
198 VP1Msg::messageVerbose("d->sep not defined. Creating shapes and a new d->sep.");
199 m_d->sep = new SoSeparator();
200 m_d->sep->ref();
201 }
202
203 m_d->theCollHandle = dynamic_cast<const MissingEtCollHandle*>(collHandle());
204 m_d->theCollSettingsButton = &(m_d->theCollHandle->collSettingsButton());
205
206
207// SbVec3f origin(0.,0.,0.);
208 /* TODO: ask if origin info is present in xAOD, like in the old Jet class
209 if ( m_d->m_met->origin() ) {
210 origin.setValue(m_d->m_met->origin()->position().x(),
211 m_d->m_met->origin()->position().y(),
212 m_d->m_met->origin()->position().z());
213 }
214 */
215
216 VP1Msg::messageVerbose("creating the shapes");
217
218
219 /*
220 * Here the 3D shapes are created
221 */
222 m_d->createShapeFromJetParameters();
223
224 return m_d->sep;
225}
226
227//____________________________________________________________________
229 m_d->updateConeHeightParameters();
230}
231
232
233//____________________________________________________________________
234//void MissingEtHandle::Imp::createShapeFromJetParameters(const MissingEtCollHandle* collHandleJet, const double& inputconeR, const double& eta,
235// const double& phi, const double& energy, const SbVec3f& origin)
237{
238 VP1Msg::messageVerbose("MissingEtHandle::Imp::createShapeFromJetParameters()");
239
240 //double length = m_met->met() * (200.0 * SYSTEM_OF_UNITS::cm /(100.0 * SYSTEM_OF_UNITS::GeV ));//Fixme: Make scale factor (and thickness) adjustable.
241
242 // Set length of MET: 200 cm for 100 GeV
243 double length = m_met->met() * (200.0 * SYSTEM_OF_UNITS::cm /(100.0 * SYSTEM_OF_UNITS::GeV ));
244 this->length = length;
245
246 // Set scale factor for MET length, from user's settings in the GUI
247 this->scale = theCollSettingsButton->metLength();
248
249 // Set thickness for MET line, from user's settings in the GUI
250 this->thickness = theCollSettingsButton->metThickness();
251
252
253 sep = new SoSeparator();
254 sep->ref();
255
256 //Dash line
257 SoGroup * dash = new SoGroup();
258
259 SoRotationXYZ *r = new SoRotationXYZ();
260 r->axis=SoRotationXYZ::Z;
261 r->angle=-M_PI/2+ m_met->phi();
262 dash->addChild(r);
263
264 SoTranslation *t= new SoTranslation();
265 t->translation.setValue(0, 0, 0);
266 dash->addChild(t);
267
268 //Define line width
269 SoDrawStyle *drawStyle = new SoDrawStyle;
270 drawStyle->style.setValue(SoDrawStyle::LINES);
271 drawStyle->lineWidth.setValue(1. * thickness);
272 drawStyle->linePattern.setValue(0xFF00); // 16-bits pattern for dashed line
273 dash->addChild(drawStyle);
274
275 //Define line connection
276 SoCoordinate3 *coords = new SoCoordinate3;
277 SbVec3f* vert = new SbVec3f[2];
278 vert[0] = SbVec3f(0.0, 0.0, 0.0);
279 vert[1] = SbVec3f(0.0, length * scale, 0.0);
280 coords->point.setValues(0, 2, vert);
281 delete [] vert;
282 dash->addChild(coords);
283
284 SoLineSet *lineSet = new SoLineSet ;
285 lineSet->numVertices.set1Value(0, 2) ;
286 dash->addChild(lineSet);
287
288 dash->ref();
289
290 base = new SoGroup();
291 base->addChild(dash);
292 base->ref();
293
294
295 sep->addChild(base); // starts along y-axis // DO NOT MOVE THIS: ITS POSITION IS USED BY "updateConeHeightParameters(SoSeparator* sep,const double& energy)"
296
297 //return sep;
298}
299
300//_____________________________________________________________________________________
301void MissingEtHandle::Imp::updateConeHeightParameters(SoCone*cone, SoTranslation* trans, const double& energy) const
302{
303 VP1Msg::messageVerbose("MissingEtHandle::Imp::updateConeHeightParameters()");
304
305 // double h(scale * energy);
306 double h(scale);
307
308 if (maxR > 0.0001) { // maxR > 0. is not univocally defined, because maxR is a floating point number
309 VP1Msg::messageVerbose("maxR > 0.0001 ==> setting h = min(h,maxR)");
310 h = std::min(h,maxR);
311 }
312
313 //h = 1500.0; // only for debug
314
315 cone->height = h;
316 cone->bottomRadius = 50.; //tan(coneR()) * h;
317 trans->translation = SbVec3f(0,-0.5*h,0);
318
319 //debug
320 SbString strHeight, strRadius;
321 (cone->height).get(strHeight);
322 (cone->bottomRadius).get(strRadius);
323 std::cout << "input - energy: " << energy << " - scale: " << scale << " - maxR: " << maxR << " - h: " << h << " --- updated cone - height: " << strHeight.getString() << " - bottom radius: " << strRadius.getString() << std::endl;
324
325 // you can also use the 'writeField()' method, direct to std output
326 //SoDebug::writeField(&(cone->height));
327
328 // QString text = "updated cone - height: " + QString::number(cone->height) + " - bottom radius: " + QString::number(cone->bottomRadius) " - translation: " + trans->translation;
329 // VP1Msg::messageVerbose(text);
330}
331
332
333//_____________________________________________________________________________________
335
336
337 if (!sep) {
338 VP1Msg::messageVerbose("sep not defined. Returning.");
339 return;
340 }
341
342 //NB: The translation is the SIXTH child and the cone is the LAST child.
343 if (sep->getNumChildren()<6) {
344 VP1Msg::messageVerbose("getNumChildren() < 6!!!");
345 return;
346 }
347
348 // const double energyJet = energyForLengthAndCuts();
349 //
350 // SoNode * sixthChild = sep->getChild(5);
351 // if (sixthChild->getTypeId()!=SoTranslation::getClassTypeId()) {
352 // return;
353 // }
354 // SoNode * lastChild = sep->getChild(sep->getNumChildren()-1);
355 // if (lastChild->getTypeId()!=SoCone::getClassTypeId()) {
356 // return;
357 // }
358 // updateConeHeightParameters(static_cast<SoCone*>(lastChild),static_cast<SoTranslation*>(sixthChild), energyJet);
359}
360
361
365//____________________________________________________________________
366QStringList MissingEtHandle::clicked() const
367{
368 VP1Msg::messageDebug("MissingEtHandle::clicked()");
369
370 QStringList l;
371 l << "--MissingEt: ";
372 //l << AODHandleBase::baseInfo();
373
374 // info and parameters,
375 // they go in the "Information" column in the Browser window
376 // see: http://acode-browser.usatlas.bnl.gov/lxr/source/atlas/Event/xAOD/xAODMissingET/xAODMissingET/versions/MissingET_v1.h
377 //
378 l +=" - Name: " + m_d->name();
379 l +=" - MissingEt: " + QString::number(m_d->met() / SYSTEM_OF_UNITS::GeV) +" [GeV]";
380 l +=" - Phi: " + QString::number(m_d->phi());
381 l +=" - SumEt: " + QString::number(m_d->sumet() / SYSTEM_OF_UNITS::GeV) +" [GeV]";
382 l +=" - mpx: " + QString::number(m_d->mpx() / SYSTEM_OF_UNITS::GeV) +" [GeV]" ;
383 l +=" - mpy: " + QString::number(m_d->mpy() / SYSTEM_OF_UNITS::GeV) +" [GeV]";
384
385 return l;
386}
387
388/*
389//____________________________________________________________________
390Amg::Vector3D MissingEtHandle::momentum() const
391{
392const Trk::Perigee& p = m_d->trackparticle->perigeeParameters();
393return p.momentum();
394}
395*/
396
398//const xAOD::IParticle& MissingEtHandle::iParticle() const
399//{
400// return *(m_d->m_met);
401//}
402
403
405//double MissingEtHandle::charge() const
406//{
407// //return m_d->trackparticle->charge(); // TODO: check in Jet interface if a "charge" is defined
408// return 0; // FIXME: dummy value now
409//}
410
411
412
413/*
414* TODO: If Jet class has something like SummaryType like TrackParticle has, implement this method. Otherwise, remove it!
415*
416*/
417/*
418//____________________________________________________________________
419unsigned MissingEtHandle::summaryValue(xAOD::SummaryType type) const
420{
421uint8_t num = 0;
422if (m_d->trackparticle->summaryValue(num,type)){
423return num;
424}
425// else...
426VP1Msg::message("MissingEtHandle::getSummaryValue - unable to retrieve the requested enum: "+VP1Msg::str(type));
427return 999999;
428}
429*/
430
431
435//____________________________________________________________________
437{
438 VP1Msg::messageDebug("MissingEtHandle::shortInfo()");
439
440 QString l;
441
442 l += m_d->name();
443 l += ", met: " + QString::number(m_d->met() / SYSTEM_OF_UNITS::GeV) +" [GeV]";
444 l += ", phi: " + QString::number(m_d->phi());
445
446 return l;
447}
448
449
453//____________________________________________________________________
454void MissingEtHandle::fillObjectBrowser( QList<QTreeWidgetItem *>& listOfItems)
455{
456 AODHandleBase::fillObjectBrowser(listOfItems); // Obligatory!
457
458 QTreeWidgetItem* TSOSitem = new QTreeWidgetItem(browserTreeItem());
459
460 // Jet "Object" title, in the Browser window
461 TSOSitem->setText(0, QString("Info: " ) );
462
463 QString dParameters("(");
464
465 // info and parameters,
466 // they go in the "Information" column in the Browser window
467 dParameters+="name: ";
468 dParameters+=m_d->name();
469 dParameters+=", met: ";
470 dParameters+=QString::number(m_d->met());
471 dParameters+=", phi: ";
472 dParameters+=QString::number(m_d->phi());
473 dParameters+=", sumet: ";
474 dParameters+=QString::number(m_d->sumet());
475
476 dParameters+="";
477
478 dParameters+=")";
479
480 dParameters += " [more info in the main Message Box]";
481
482 TSOSitem->setText(1, dParameters );
483
484 /*
485 * TODO: check jets parameters
486 */
487 /*
488 for (unsigned int i=0; i<m_d->trackparticle->numberOfParameters() ; ++i){
489
490 QTreeWidgetItem* TSOSitem = new QTreeWidgetItem(browserTreeItem());
491 TSOSitem->setText(0, QString("Parameter "+QString::number( i+1 ) ) );
492 QString pos(", Position = (");
493 pos+=QString::number(m_d->trackparticle->parameterX(i));
494 pos+=", ";
495 pos+=QString::number(m_d->trackparticle->parameterY(i));
496 pos+=", ";
497 pos+=QString::number(m_d->trackparticle->parameterZ(i));
498 pos+=")";
499
500 switch (m_d->trackparticle->parameterPosition(i)){
501 case xAOD::BeamLine:
502 TSOSitem->setText(1, QString("BeamLine" )+pos );
503 break;
504 case xAOD::FirstMeasurement:
505 TSOSitem->setText(1, QString("FirstMeasurement")+pos );
506 break;
507 case xAOD::LastMeasurement:
508 TSOSitem->setText(1, QString("LastMeasurement" )+pos );
509 break;
510 case xAOD::CalorimeterEntrance:
511 TSOSitem->setText(1, QString("CalorimeterEntrance")+pos );
512 break;
513 case xAOD::CalorimeterExit:
514 TSOSitem->setText(1, QString("CalorimeterExit" )+pos );
515 break;
516 case xAOD::MuonSpectrometerEntrance:
517 TSOSitem->setText(1, QString("MuonSpectrometerEntrance")+pos );
518 break;
519 default:
520 TSOSitem->setText(1, QString("Undefined")+pos );
521 }
522 }
523 */
524
525
526 // TODO - add more.
527}
528
529
530
531
532//____________________________________________________________________
533double MissingEtHandle::phi() const {
534 /*VP1Msg::messageVerbose("phi: " + QString::number(m_met->phi()) );*/
535 return m_d->phi();
536}
537
538
539//____________________________________________________________________
540double MissingEtHandle::met() const {
541 /*VP1Msg::messageVerbose("eta: " + QString::number(m_met->eta()) );*/
542 return m_d->met();
543}
544
545
547//double MissingEtHandle::energy() const { return m_d->energy(); }
548//
549//
551//double MissingEtHandle::energyForCuts() const { return m_d->energyForLengthAndCuts(); }
552//
553//
555//double MissingEtHandle::transverseEnergy() const { return m_d->transverseEnergy(); } //sin(2*atan(exp(-fabs(eta()))))*energy();
556
557
559//void MissingEtHandle::Imp::rerandomiseMaterial()
560//{
561// VP1Msg::messageVerbose("MissingEtHandle::Imp::rerandomiseMaterial()");
562//
563// //Fixme: share this code with other systems!!
564// if ( !m_randomMat ) { //We will anyway rerandomize it when we need it
565// VP1Msg::messageVerbose("'m_randomMat not set. Returning.");
566// return;
567// }
568//
569// double r2 = 0.3*0.3;
570// unsigned i(0);
571// double r,g,b;
572// bool ok;
573// while (true) {
574// r = (rand() / static_cast<double>(RAND_MAX));
575// g = (rand() / static_cast<double>(RAND_MAX));
576// b = (rand() / static_cast<double>(RAND_MAX));
577// ok = true;
578// //For now we make sure that we avoid black and red. This should be updated from bgd and highlight col automatically! (fixme).
579// // -> and we should probably also make sure that tracks close in (eta,phi) are well separated in colour-space.
580// if ( (r-1.0)*(r-1.0)+g*g+b*b < r2*0.5 )//avoid red (distance)
581// ok = false;
582// else if ( r*r/(r*r+g*g+b*b) > 0.8 )//avoid red (angle)
583// ok = false;
584// else if ( r*r+g*g+b*b < r2*2.0 )//avoid black
585// ok = false;
586// if (ok)
587// break;
588// ++i;
589// if (i>50 ) {
590// r2 *= 0.99;//To avoid problem in case we add too many forbidden spheres.
591// if (i>1000) {
592// //Just a safety
593// VP1Msg::messageVerbose("MissingEtHandle::Imp::rerandomiseMaterial() - Warning: Random colour could"
594// " not be selected such as to satisfy all separation criterias");
595// break;
596// }
597// }
598// }
599//
600// VP1MaterialButton::setMaterialParameters(m_randomMat,r, g, b, 0.1, 0.5 );
601//}
602
603/*
604//____________________________________________________________________
605//void MissingEtHandle::Imp::updateMaterial()
606void MissingEtHandle::updateMaterial(bool isRandomColors)
607{
608 VP1Msg::messageVerbose("MissingEtHandle::Imp::updateMaterial()");
609
610 // check if we have 3D objects; if not, return
611 if ( m_d->sep == 0 )
612 return;
613
614 // if (!isRandomColors && !m_d->m_randomMat)
615 // return;//m_randomMat can never have been attached
616 //
617 // if (isRandomColors && !m_d->m_randomMat) {
618 // m_d->m_randomMat = new SoMaterial;
619 // m_d->m_randomMat->ref();
620 // rerandomiseMaterial();
621 // }
622
623
624 // int i = m_d->sep->findChild(m_d->m_randomMat);
625 //
626 // if ( (i>=0) == isRandomColors ) {
627 // VP1Msg::messageVerbose("(i>=0)==isRandomColors. Returning.");
628 // return;
629 // }
630 //
631 // if (!isRandomColors )
632 // m_d->sep->removeChild(m_d->m_randomMat);
633 // else
634 // m_d->sep->insertChild(m_d->m_randomMat, m_d->sep->getNumChildren()-1);
635}
636*/
#define M_PI
static Double_t sc
Base class for all AOD object collections This class primarily handles setting up the interface,...
const AODCollHandleBase * collHandle() const
QTreeWidgetItem * browserTreeItem() const
Return the QTreeWidgetItem;.
virtual void fillObjectBrowser(QList< QTreeWidgetItem * > &list)
Create and fill the object browser QTreeWidgetItem.
AODHandleBase(AODCollHandleBase *)
Header file for AthHistogramAlgorithm.
const MissingEtCollectionSettingsButton * theCollSettingsButton
MissingEtHandle * theclass
const MissingEtCollHandle * theCollHandle
const xAOD::MissingET * m_met
void updateConeHeightParameters() const
double met() const
virtual SoMaterial * determineMaterial()
Should be implemented by children, in order to change the material depending on the interface etc.
virtual bool has3DObjects()
Returns true if the 3D objects have been created.
void setScale(const double &sc)
void fillObjectBrowser(QList< QTreeWidgetItem * > &listOfItems)
This gives the list of object's properties, shown in the 'Information' field in the Browser,...
virtual void clear3DObjects()
Delete objects.
virtual SoNode * nodes()
Returns the 3Dobjects.
double phi() const
virtual QStringList clicked() const
This gives the complete information about the object, shown in the main Message Box.
QString shortInfo() const
This returns the information shown about the object in the object browser.
MissingEtHandle(AODCollHandleBase *, const xAOD::MissingET *)
static void messageVerbose(const QString &)
Definition VP1Msg.cxx:84
static void messageDebug(const QString &)
Definition VP1Msg.cxx:39
SoMaterial * material() const
static QString str(const QString &s)
Definition VP1String.h:49
int r
Definition globals.cxx:22
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
MissingET_v1 MissingET
Version control by type defintion.