CMS 3D CMS Logo

PFRecoTauChargedHadronFromPFCandidatePlugin.cc
Go to the documentation of this file.
1 /*
2  * PFRecoTauChargedHadronFromPFCandidatePlugin
3  *
4  * Build PFRecoTauChargedHadron objects
5  * using charged PFCandidates and/or PFNeutralHadrons as input
6  *
7  * Author: Christian Veelken, LLR
8  *
9  */
10 
12 
27 
32 
37 
38 #include <memory>
39 
40 namespace reco {
41 
42  namespace tau {
43 
45  public:
48  // Return type is unique_ptr<ChargedHadronVector>
49  return_type operator()(const reco::Jet&) const override;
50  // Hook to update PV information
51  void beginEvent() override;
52 
53  private:
54  typedef std::vector<reco::CandidatePtr> CandPtrs;
55 
57 
59 
60  std::vector<int> inputParticleIds_; // type of candidates to clusterize
61 
77 
78  double bField_;
79 
81  };
82 
86  vertexAssociator_(pset.getParameter<edm::ParameterSet>("qualityCuts"), std::move(iC)),
87  qcuts_(nullptr) {
88  edm::ParameterSet qcuts_pset = pset.getParameterSet("qualityCuts").getParameterSet("signalQualityCuts");
89  qcuts_ = new RecoTauQualityCuts(qcuts_pset);
90 
91  inputParticleIds_ = pset.getParameter<std::vector<int> >("chargedHadronCandidatesParticleIds");
92 
93  dRmergeNeutralHadronWrtChargedHadron_ = pset.getParameter<double>("dRmergeNeutralHadronWrtChargedHadron");
94  dRmergeNeutralHadronWrtNeutralHadron_ = pset.getParameter<double>("dRmergeNeutralHadronWrtNeutralHadron");
95  dRmergeNeutralHadronWrtElectron_ = pset.getParameter<double>("dRmergeNeutralHadronWrtElectron");
96  dRmergeNeutralHadronWrtOther_ = pset.getParameter<double>("dRmergeNeutralHadronWrtOther");
97  minBlockElementMatchesNeutralHadron_ = pset.getParameter<int>("minBlockElementMatchesNeutralHadron");
98  maxUnmatchedBlockElementsNeutralHadron_ = pset.getParameter<int>("maxUnmatchedBlockElementsNeutralHadron");
99  dRmergePhotonWrtChargedHadron_ = pset.getParameter<double>("dRmergePhotonWrtChargedHadron");
100  dRmergePhotonWrtNeutralHadron_ = pset.getParameter<double>("dRmergePhotonWrtNeutralHadron");
101  dRmergePhotonWrtElectron_ = pset.getParameter<double>("dRmergePhotonWrtElectron");
102  dRmergePhotonWrtOther_ = pset.getParameter<double>("dRmergePhotonWrtOther");
103  minBlockElementMatchesPhoton_ = pset.getParameter<int>("minBlockElementMatchesPhoton");
104  maxUnmatchedBlockElementsPhoton_ = pset.getParameter<int>("maxUnmatchedBlockElementsPhoton");
105  minMergeNeutralHadronEt_ = pset.getParameter<double>("minMergeNeutralHadronEt");
106  minMergeGammaEt_ = pset.getParameter<double>("minMergeGammaEt");
107  minMergeChargedHadronPt_ = pset.getParameter<double>("minMergeChargedHadronPt");
108 
109  verbosity_ = pset.getParameter<int>("verbosity");
110  }
111 
113 
114  // Update the primary vertex
117 
120  bField_ = pSetup->inTesla(GlobalPoint(0, 0, 0)).z();
121  }
122 
123  namespace {
124  bool isMatchedByBlockElement(const reco::PFCandidate& pfCandidate1,
125  const reco::PFCandidate& pfCandidate2,
126  int minMatches1,
127  int minMatches2,
128  int maxUnmatchedBlockElements1plus2) {
129  reco::PFCandidate::ElementsInBlocks blockElements1 = pfCandidate1.elementsInBlocks();
130  int numBlocks1 = blockElements1.size();
131  reco::PFCandidate::ElementsInBlocks blockElements2 = pfCandidate2.elementsInBlocks();
132  int numBlocks2 = blockElements2.size();
133  int numBlocks_matched = 0;
134  for (reco::PFCandidate::ElementsInBlocks::const_iterator blockElement1 = blockElements1.begin();
135  blockElement1 != blockElements1.end();
136  ++blockElement1) {
137  bool isMatched = false;
138  for (reco::PFCandidate::ElementsInBlocks::const_iterator blockElement2 = blockElements2.begin();
139  blockElement2 != blockElements2.end();
140  ++blockElement2) {
141  if (blockElement1->first.id() == blockElement2->first.id() &&
142  blockElement1->first.key() == blockElement2->first.key() &&
143  blockElement1->second == blockElement2->second) {
144  isMatched = true;
145  }
146  }
147  if (isMatched)
148  ++numBlocks_matched;
149  }
150  assert(numBlocks_matched <= numBlocks1);
151  assert(numBlocks_matched <= numBlocks2);
152  if (numBlocks_matched >= minMatches1 && numBlocks_matched >= minMatches2 &&
153  ((numBlocks1 - numBlocks_matched) + (numBlocks2 - numBlocks_matched)) <= maxUnmatchedBlockElements1plus2) {
154  return true;
155  } else {
156  return false;
157  }
158  }
159  } // namespace
160 
162  const reco::Jet& jet) const {
163  if (verbosity_) {
164  edm::LogPrint("TauChHadronFromPF") << "<PFRecoTauChargedHadronFromPFCandidatePlugin::operator()>:";
165  edm::LogPrint("TauChHadronFromPF") << " pluginName = " << name();
166  }
167 
169 
170  // Get the candidates passing our quality cuts
173 
174  for (CandPtrs::iterator cand = candsVector.begin(); cand != candsVector.end(); ++cand) {
175  if (verbosity_) {
176  edm::LogPrint("TauChHadronFromPF")
177  << "processing PFCandidate: Pt = " << (*cand)->pt() << ", eta = " << (*cand)->eta()
178  << ", phi = " << (*cand)->phi() << " (pdgId = " << (*cand)->pdgId() << ", charge = " << (*cand)->charge()
179  << ")";
180  }
181 
183  if (std::abs((*cand)->charge()) > 0.5)
185  else
187  std::unique_ptr<PFRecoTauChargedHadron> chargedHadron(new PFRecoTauChargedHadron(**cand, algo));
188 
189  const reco::PFCandidate* pfCand = dynamic_cast<const reco::PFCandidate*>(&**cand);
190  if (pfCand) {
191  if (pfCand->trackRef().isNonnull())
192  chargedHadron->track_ = edm::refToPtr(pfCand->trackRef());
193  else if (pfCand->muonRef().isNonnull() && pfCand->muonRef()->innerTrack().isNonnull())
194  chargedHadron->track_ = edm::refToPtr(pfCand->muonRef()->innerTrack());
195  else if (pfCand->muonRef().isNonnull() && pfCand->muonRef()->globalTrack().isNonnull())
196  chargedHadron->track_ = edm::refToPtr(pfCand->muonRef()->globalTrack());
197  else if (pfCand->muonRef().isNonnull() && pfCand->muonRef()->outerTrack().isNonnull())
198  chargedHadron->track_ = edm::refToPtr(pfCand->muonRef()->outerTrack());
199  else if (pfCand->gsfTrackRef().isNonnull())
200  chargedHadron->track_ = edm::refToPtr(pfCand->gsfTrackRef());
201  } // TauReco@MiniAOD: Tracks only available dynamically, so no possiblity to save ref here; checked by code downstream
202 
203  chargedHadron->positionAtECALEntrance_ = atECALEntrance(&**cand, bField_);
204  chargedHadron->chargedPFCandidate_ = (*cand);
205  chargedHadron->addDaughter(*cand);
206 
207  int pdgId = std::abs(chargedHadron->chargedPFCandidate_->pdgId());
208 
210  for (const auto& jetConstituent : jet.daughterPtrVector()) {
211  // CV: take care of not double-counting energy in case "charged" PFCandidate is in fact a PFNeutralHadron
212  if (jetConstituent == chargedHadron->chargedPFCandidate_)
213  continue;
214 
215  int jetConstituentPdgId = std::abs(jetConstituent->pdgId());
216  if (!(jetConstituentPdgId == 130 || jetConstituentPdgId == 22))
217  continue;
218 
219  double dR = deltaR(atECALEntrance(jetConstituent.get(), bField_),
220  atECALEntrance(chargedHadron->chargedPFCandidate_.get(), bField_));
221  double dRmerge = -1.;
222  int minBlockElementMatches = 1000;
223  int maxUnmatchedBlockElements = 0;
224  double minMergeEt = 1.e+6;
225  if (jetConstituentPdgId == 130) {
226  if (pdgId == 211)
228  else if (pdgId == 130)
230  else if (pdgId == 11)
232  else
234  minBlockElementMatches = minBlockElementMatchesNeutralHadron_;
235  maxUnmatchedBlockElements = maxUnmatchedBlockElementsNeutralHadron_;
236  minMergeEt = minMergeNeutralHadronEt_;
237  } else if (jetConstituentPdgId == 22) {
238  if (pdgId == 211)
240  else if (pdgId == 130)
242  else if (pdgId == 11)
243  dRmerge = dRmergePhotonWrtElectron_;
244  else
245  dRmerge = dRmergePhotonWrtOther_;
246  minBlockElementMatches = minBlockElementMatchesPhoton_;
247  maxUnmatchedBlockElements = maxUnmatchedBlockElementsPhoton_;
248  minMergeEt = minMergeGammaEt_;
249  }
250 
251  if (jetConstituent->et() > minMergeEt) {
252  if (dR < dRmerge) {
253  chargedHadron->neutralPFCandidates_.push_back(jetConstituent);
254  chargedHadron->addDaughter(jetConstituent);
255  } else {
256  // TauReco@MiniAOD: No access to PF blocks at MiniAOD level, but the code below seems to have very minor impact
257  const reco::PFCandidate* pfJetConstituent =
258  dynamic_cast<const reco::PFCandidate*>(jetConstituent.get());
259  if (pfCand != nullptr && pfJetConstituent != nullptr) {
260  if (isMatchedByBlockElement(*pfJetConstituent,
261  *pfCand,
262  minBlockElementMatches,
263  minBlockElementMatches,
264  maxUnmatchedBlockElements)) {
265  chargedHadron->neutralPFCandidates_.push_back(jetConstituent);
266  chargedHadron->addDaughter(jetConstituent);
267  }
268  }
269  }
270  }
271  }
272  }
273 
275 
276  if (verbosity_) {
277  edm::LogPrint("TauChHadronFromPF") << *chargedHadron;
278  }
279  // Update the vertex
280  if (chargedHadron->daughterPtr(0).isNonnull())
281  chargedHadron->setVertex(chargedHadron->daughterPtr(0)->vertex());
282  output.push_back(std::move(chargedHadron));
283  }
284 
285  return output.release();
286  }
287 
288  } // namespace tau
289 } // namespace reco
290 
292 
295  "PFRecoTauChargedHadronFromPFCandidatePlugin");
reco::PFCandidate::trackRef
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:408
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::minMergeChargedHadronPt_
double minMergeChargedHadronPt_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:76
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::dRmergeNeutralHadronWrtNeutralHadron_
double dRmergeNeutralHadronWrtNeutralHadron_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:63
reco::tau::RecoTauEventHolderPlugin::evt
const edm::Event * evt() const
Definition: RecoTauPluginsCommon.cc:16
MagneticField::inTesla
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
reco::tau::PFRecoTauChargedHadronBuilderPlugin
Definition: PFRecoTauChargedHadronPlugins.h:35
reco::Jet
Base class for all types of Jets.
Definition: Jet.h:20
Muon.h
MessageLogger.h
PFRecoTauChargedHadronPlugins.h
reco::tau::RecoTauQualityCuts
Definition: RecoTauQualityCuts.h:35
ESHandle.h
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::dRmergePhotonWrtChargedHadron_
double dRmergePhotonWrtChargedHadron_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:68
reco::tau::RecoTauNamedPlugin::name
const std::string & name() const
Definition: RecoTauPluginsCommon.cc:10
metsig::tau
Definition: SignAlgoResolutions.h:49
PFCandidate.h
convertSQLitetoXML_cfg.output
output
Definition: convertSQLitetoXML_cfg.py:72
muons2muons_cfi.chargedHadron
chargedHadron
Definition: muons2muons_cfi.py:26
edm
HLT enums.
Definition: AlignableModifier.h:19
edm::LogPrint
Log< level::Warning, true > LogPrint
Definition: MessageLogger.h:130
reco::tau::atECALEntrance
math::XYZPointF atECALEntrance(const reco::Candidate *part, double bField)
Definition: RecoTauCommonUtilities.cc:109
reco::PFRecoTauChargedHadron::kUndefined
Definition: PFRecoTauChargedHadron.h:29
cms::cuda::assert
assert(be >=bs)
Jet.h
reco
fixed size matrix
Definition: AlignmentAlgorithmBase.h:45
reco::PFCandidate::elementsInBlocks
const ElementsInBlocks & elementsInBlocks() const
Definition: PFCandidate.cc:636
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::minMergeGammaEt_
double minMergeGammaEt_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:75
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::minMergeNeutralHadronEt_
double minMergeNeutralHadronEt_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:74
RecoTauVertexAssociator.h
reco::PFRecoTauChargedHadron
Definition: PFRecoTauChargedHadron.h:23
PV3DBase::z
T z() const
Definition: PV3DBase.h:61
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::CandPtrs
std::vector< reco::CandidatePtr > CandPtrs
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:54
edm::refToPtr
Ptr< typename C::value_type > refToPtr(Ref< C, typename C::value_type, refhelper::FindUsingAdvance< C, typename C::value_type > > const &ref)
Definition: RefToPtr.h:18
IdealMagneticFieldRecord
Definition: IdealMagneticFieldRecord.h:11
cmsdt::algo
algo
Definition: constants.h:165
MakerMacros.h
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::bField_
double bField_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:78
reco::PFCandidate::muonRef
reco::MuonRef muonRef() const
Definition: PFCandidate.cc:421
reco::tau::setChargedHadronP4
void setChargedHadronP4(reco::PFRecoTauChargedHadron &chargedHadron, double scaleFactor_neutralPFCands=1.0)
Definition: pfRecoTauChargedHadronAuxFunctions.cc:31
reco::tau::RecoTauVertexAssociator
Definition: RecoTauVertexAssociator.h:50
Track.h
edm::EventSetup::get
T get() const
Definition: EventSetup.h:87
TrackFwd.h
MuonFwd.h
IdealMagneticFieldRecord.h
edm::ESHandle< MagneticField >
reco::tau::RecoTauQualityCuts::setPV
void setPV(const reco::VertexRef &vtx)
Update the primary vertex.
Definition: RecoTauQualityCuts.h:47
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::qcuts_
RecoTauQualityCuts * qcuts_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:58
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::PFRecoTauChargedHadronFromPFCandidatePlugin
PFRecoTauChargedHadronFromPFCandidatePlugin(const edm::ParameterSet &, edm::ConsumesCollector &&iC)
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:83
RecoTauCommonUtilities.h
GlobalPoint
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
DEFINE_EDM_PLUGIN
#define DEFINE_EDM_PLUGIN(factory, type, name)
Definition: PluginFactory.h:124
reco::tau::PFRecoTauChargedHadronBuilderPlugin::ChargedHadronVector
boost::ptr_vector< PFRecoTauChargedHadron > ChargedHadronVector
Definition: PFRecoTauChargedHadronPlugins.h:38
reco::tau::PFRecoTauChargedHadronBuilderPlugin::return_type
std::unique_ptr< ChargedHadronVector > return_type
Definition: PFRecoTauChargedHadronPlugins.h:41
reco::PFCandidate::ElementsInBlocks
std::vector< ElementInBlock > ElementsInBlocks
Definition: PFCandidate.h:379
Vertex.h
RecoTauQualityCuts.h
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::dRmergeNeutralHadronWrtOther_
double dRmergeNeutralHadronWrtOther_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:65
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::dRmergeNeutralHadronWrtElectron_
double dRmergeNeutralHadronWrtElectron_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:64
trackerHitRTTI::isMatched
bool isMatched(TrackingRecHit const &hit)
Definition: trackerHitRTTI.h:33
reco::tau::RecoTauQualityCuts::filterCandRefs
Coll filterCandRefs(const Coll &refcoll, bool invert=false) const
Filter a ref vector of Candidates.
Definition: RecoTauQualityCuts.h:86
reco::tau::RecoTauVertexAssociator::associatedVertex
reco::VertexRef associatedVertex(const Jet &jet) const
Definition: RecoTauVertexAssociator.cc:378
reco::PFRecoTauChargedHadron::PFRecoTauChargedHadronAlgorithm
PFRecoTauChargedHadronAlgorithm
Definition: PFRecoTauChargedHadron.h:27
edm::ParameterSet
Definition: ParameterSet.h:47
reco::PFCandidate::gsfTrackRef
reco::GsfTrackRef gsfTrackRef() const
Definition: PFCandidate.cc:440
ParameterSet
Definition: Functions.h:16
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::dRmergePhotonWrtOther_
double dRmergePhotonWrtOther_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:71
deltaR.h
edmplugin::PluginFactory
Definition: PluginFactory.h:34
edm::Ref::isNonnull
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::beginEvent
void beginEvent() override
Hook called at the beginning of the event.
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:115
reco::PFRecoTauChargedHadron::kChargedPFCandidate
Definition: PFRecoTauChargedHadron.h:30
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::dRmergePhotonWrtNeutralHadron_
double dRmergePhotonWrtNeutralHadron_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:69
cand
Definition: decayParser.h:32
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::minBlockElementMatchesNeutralHadron_
int minBlockElementMatchesNeutralHadron_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:66
RefToPtr.h
GsfTrack.h
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::maxUnmatchedBlockElementsNeutralHadron_
int maxUnmatchedBlockElementsNeutralHadron_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:67
EgammaValidation_cff.pdgId
pdgId
Definition: EgammaValidation_cff.py:118
MagneticField.h
reco::tau::RecoTauVertexAssociator::setEvent
void setEvent(const edm::Event &evt)
Load the vertices from the event.
Definition: RecoTauVertexAssociator.cc:242
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::vertexAssociator_
RecoTauVertexAssociator vertexAssociator_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:56
reco::get
T get(const Candidate &c)
Definition: component.h:60
VertexFwd.h
eostools.move
def move(src, dest)
Definition: eostools.py:511
std
Definition: JetResolutionObject.h:76
GsfTrackFwd.h
reco::PFRecoTauChargedHadron::kPFNeutralHadron
Definition: PFRecoTauChargedHadron.h:32
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::operator()
return_type operator()(const reco::Jet &) const override
Build a collection of chargedHadrons from objects in the input jet.
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:161
metsig::jet
Definition: SignAlgoResolutions.h:47
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::minBlockElementMatchesPhoton_
int minBlockElementMatchesPhoton_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:72
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::dRmergePhotonWrtElectron_
double dRmergePhotonWrtElectron_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:70
reco::deltaR
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:30
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::inputParticleIds_
std::vector< int > inputParticleIds_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:60
pfRecoTauChargedHadronAuxFunctions.h
PFRecoTauChargedHadron.h
reco::PFCandidate
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::verbosity_
int verbosity_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:80
HGC3DClusterGenMatchSelector_cfi.dR
dR
Definition: HGC3DClusterGenMatchSelector_cfi.py:7
reco::tau::pfCandidates
std::vector< CandidatePtr > pfCandidates(const Jet &jet, int particleId, bool sort=true)
Definition: RecoTauCommonUtilities.cc:59
reco::tau::RecoTauEventHolderPlugin::evtSetup
const edm::EventSetup * evtSetup() const
Definition: RecoTauPluginsCommon.cc:18
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::dRmergeNeutralHadronWrtChargedHadron_
double dRmergeNeutralHadronWrtChargedHadron_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:62
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::~PFRecoTauChargedHadronFromPFCandidatePlugin
~PFRecoTauChargedHadronFromPFCandidatePlugin() override
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:112
edm::ConsumesCollector
Definition: ConsumesCollector.h:45
muonDTDigis_cfi.pset
pset
Definition: muonDTDigis_cfi.py:27
PFCandidateFwd.h
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:44
reco::tau::PFRecoTauChargedHadronFromPFCandidatePlugin::maxUnmatchedBlockElementsPhoton_
int maxUnmatchedBlockElementsPhoton_
Definition: PFRecoTauChargedHadronFromPFCandidatePlugin.cc:73