CMS 3D CMS Logo

List of all members | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
PFLinker Class Reference
Inheritance diagram for PFLinker:
edm::stream::EDProducer<>

Public Member Functions

 PFLinker (const edm::ParameterSet &)
 
void produce (edm::Event &, const edm::EventSetup &) override
 
 ~PFLinker () override
 
- Public Member Functions inherited from edm::stream::EDProducer<>
 EDProducer ()=default
 
 EDProducer (const EDProducer &)=delete
 
bool hasAbilityToProduceInBeginLumis () const final
 
bool hasAbilityToProduceInBeginProcessBlocks () const final
 
bool hasAbilityToProduceInBeginRuns () const final
 
bool hasAbilityToProduceInEndLumis () const final
 
bool hasAbilityToProduceInEndProcessBlocks () const final
 
bool hasAbilityToProduceInEndRuns () const final
 
const EDProduceroperator= (const EDProducer &)=delete
 

Static Public Member Functions

static void fillDescriptions (edm::ConfigurationDescriptions &descriptions)
 

Private Member Functions

template<typename TYPE >
edm::ValueMap< reco::PFCandidatePtrfillValueMap (edm::Event &event, std::string label, edm::Handle< TYPE > &inputObjCollection, const std::map< edm::Ref< TYPE >, reco::PFCandidatePtr > &mapToTheCandidate, const edm::OrphanHandle< reco::PFCandidateCollection > &newPFCandColl) const
 

Private Attributes

bool fillMuonRefs_
 Set muon refs and produce the value map? More...
 
bool forceElectronsInHGCAL_
 Put Electrons within HGCAL coming from SimPFProducer. More...
 
edm::EDGetTokenT< reco::GsfElectronCollectioninputTagGsfElectrons_
 Input GsfElectrons. More...
 
edm::EDGetTokenT< reco::MuonToMuonMapinputTagMuonMap_
 
edm::EDGetTokenT< reco::MuonCollectioninputTagMuons_
 
std::vector< edm::EDGetTokenT< reco::PFCandidateCollection > > inputTagPFCandidates_
 Input PFCandidates. More...
 
edm::EDGetTokenT< reco::PhotonCollectioninputTagPhotons_
 Input Photons. More...
 
edm::InputTag muonTag_
 Input Muons. More...
 
std::string nameOutputElectronsPF_
 name of output ValueMap electrons More...
 
std::string nameOutputMergedPF_
 name of output merged ValueMap More...
 
std::string nameOutputPF_
 name of output collection of PFCandidate More...
 
std::string nameOutputPhotonsPF_
 name of output ValueMap photons More...
 
bool producePFCandidates_
 Flags - if true: References will be towards new collection ; if false to the original one. More...
 

Additional Inherited Members

- Public Types inherited from edm::stream::EDProducer<>
using CacheTypes = CacheContexts< T... >
 
using GlobalCache = typename CacheTypes::GlobalCache
 
using HasAbility = AbilityChecker< T... >
 
using InputProcessBlockCache = typename CacheTypes::InputProcessBlockCache
 
using LuminosityBlockCache = typename CacheTypes::LuminosityBlockCache
 
using LuminosityBlockContext = LuminosityBlockContextT< LuminosityBlockCache, RunCache, GlobalCache >
 
using LuminosityBlockSummaryCache = typename CacheTypes::LuminosityBlockSummaryCache
 
using RunCache = typename CacheTypes::RunCache
 
using RunContext = RunContextT< RunCache, GlobalCache >
 
using RunSummaryCache = typename CacheTypes::RunSummaryCache
 

Detailed Description

Producer meant for the Post PF reconstruction.

Fills the GsfElectron, Photon and Muon Ref into the PFCandidate Produces the ValueMap between GsfElectronRef/Photon/Mupns with PFCandidateRef

Author
R. Bellan - UCSB ricca.nosp@m.rdo..nosp@m.bella.nosp@m.n@ce.nosp@m.rn.ch, F. Beaudette - CERN Flori.nosp@m.an.B.nosp@m.eaude.nosp@m.tte@.nosp@m.cern..nosp@m.ch

Definition at line 25 of file PFLinker.cc.

Constructor & Destructor Documentation

◆ PFLinker()

PFLinker::PFLinker ( const edm::ParameterSet iConfig)
explicit

Definition at line 97 of file PFLinker.cc.

References cms::cuda::assert(), fillMuonRefs_, forceElectronsInHGCAL_, edm::ParameterSet::getParameter(), mps_fire::i, ProducerED_cfi::InputTag, inputTagGsfElectrons_, inputTagMuonMap_, inputTagMuons_, inputTagPFCandidates_, inputTagPhotons_, edm::InputTag::label(), muonTag_, nameOutputElectronsPF_, nameOutputMergedPF_, nameOutputPF_, nameOutputPhotonsPF_, producePFCandidates_, AlCaHLTBitMon_QueryRunRegistry::string, and getPayloadData::tags.

97  {
98  // vector of InputTag; more than 1 is not for RECO, it is for analysis
99 
100  std::vector<edm::InputTag> tags = iConfig.getParameter<std::vector<edm::InputTag>>("PFCandidate");
101  for (unsigned int i = 0; i < tags.size(); ++i)
102  inputTagPFCandidates_.push_back(consumes<reco::PFCandidateCollection>(tags[i]));
103 
104  inputTagGsfElectrons_ = consumes<reco::GsfElectronCollection>(iConfig.getParameter<edm::InputTag>("GsfElectrons"));
105 
106  inputTagPhotons_ = consumes<reco::PhotonCollection>(iConfig.getParameter<edm::InputTag>("Photons"));
107 
108  muonTag_ = iConfig.getParameter<edm::InputTag>("Muons");
109  inputTagMuons_ = consumes<reco::MuonCollection>(edm::InputTag(muonTag_.label()));
110  inputTagMuonMap_ = consumes<reco::MuonToMuonMap>(muonTag_);
111 
112  nameOutputPF_ = iConfig.getParameter<std::string>("OutputPF");
113 
114  nameOutputElectronsPF_ = iConfig.getParameter<std::string>("ValueMapElectrons");
115 
116  nameOutputPhotonsPF_ = iConfig.getParameter<std::string>("ValueMapPhotons");
117 
118  producePFCandidates_ = iConfig.getParameter<bool>("ProducePFCandidates");
119 
120  nameOutputMergedPF_ = iConfig.getParameter<std::string>("ValueMapMerged");
121 
122  fillMuonRefs_ = iConfig.getParameter<bool>("FillMuonRefs");
123 
124  forceElectronsInHGCAL_ = iConfig.getParameter<bool>("forceElectronsInHGCAL");
125 
126  // should not produce PFCandidates and read seve
127  if (producePFCandidates_ && inputTagPFCandidates_.size() > 1) {
128  edm::LogError("PFLinker")
129  << " cannot read several collections of PFCandidates and produce a new collection at the same time. "
130  << std::endl;
131  assert(false);
132  }
133  if (producePFCandidates_) {
134  produces<reco::PFCandidateCollection>(nameOutputPF_);
135  }
136  produces<edm::ValueMap<reco::PFCandidatePtr>>(nameOutputElectronsPF_);
137  produces<edm::ValueMap<reco::PFCandidatePtr>>(nameOutputPhotonsPF_);
138  produces<edm::ValueMap<reco::PFCandidatePtr>>(nameOutputMergedPF_);
139  if (fillMuonRefs_)
140  produces<edm::ValueMap<reco::PFCandidatePtr>>(muonTag_.label());
141 }
edm::InputTag muonTag_
Input Muons.
Definition: PFLinker.cc:54
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
edm::EDGetTokenT< reco::MuonCollection > inputTagMuons_
Definition: PFLinker.cc:55
bool producePFCandidates_
Flags - if true: References will be towards new collection ; if false to the original one...
Definition: PFLinker.cc:70
std::string const & label() const
Definition: InputTag.h:36
Log< level::Error, false > LogError
edm::EDGetTokenT< reco::PhotonCollection > inputTagPhotons_
Input Photons.
Definition: PFLinker.cc:51
assert(be >=bs)
edm::EDGetTokenT< reco::MuonToMuonMap > inputTagMuonMap_
Definition: PFLinker.cc:56
std::string nameOutputElectronsPF_
name of output ValueMap electrons
Definition: PFLinker.cc:61
std::string nameOutputPhotonsPF_
name of output ValueMap photons
Definition: PFLinker.cc:64
std::string nameOutputPF_
name of output collection of PFCandidate
Definition: PFLinker.cc:58
bool fillMuonRefs_
Set muon refs and produce the value map?
Definition: PFLinker.cc:73
bool forceElectronsInHGCAL_
Put Electrons within HGCAL coming from SimPFProducer.
Definition: PFLinker.cc:76
edm::EDGetTokenT< reco::GsfElectronCollection > inputTagGsfElectrons_
Input GsfElectrons.
Definition: PFLinker.cc:48
std::vector< edm::EDGetTokenT< reco::PFCandidateCollection > > inputTagPFCandidates_
Input PFCandidates.
Definition: PFLinker.cc:45
std::string nameOutputMergedPF_
name of output merged ValueMap
Definition: PFLinker.cc:67

◆ ~PFLinker()

PFLinker::~PFLinker ( )
override

Definition at line 143 of file PFLinker.cc.

143 { ; }

Member Function Documentation

◆ fillDescriptions()

void PFLinker::fillDescriptions ( edm::ConfigurationDescriptions descriptions)
static

Definition at line 81 of file PFLinker.cc.

References edm::ConfigurationDescriptions::addWithDefaultLabel(), submitPVResolutionJobs::desc, ProducerED_cfi::InputTag, and AlCaHLTBitMon_QueryRunRegistry::string.

81  {
83  desc.add<std::vector<edm::InputTag>>("PFCandidate", {edm::InputTag("particleFlow")});
84  desc.add<edm::InputTag>("GsfElectrons", {"gedGsfElectrons"});
85  desc.add<edm::InputTag>("Photons", {"gedPhotons"});
86  desc.add<edm::InputTag>("Muons", {"muons", "muons1stStep2muonsMap"});
87  desc.add<bool>("ProducePFCandidates", true);
88  desc.add<bool>("FillMuonRefs", true);
89  desc.add<std::string>("OutputPF", "");
90  desc.add<std::string>("ValueMapElectrons", "electrons");
91  desc.add<std::string>("ValueMapPhotons", "photons");
92  desc.add<std::string>("ValueMapMerged", "all");
93  desc.add<bool>("forceElectronsInHGCAL", false);
94  descriptions.addWithDefaultLabel(desc);
95 }
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)

◆ fillValueMap()

template<typename TYPE >
edm::ValueMap< reco::PFCandidatePtr > PFLinker::fillValueMap ( edm::Event event,
std::string  label,
edm::Handle< TYPE > &  inputObjCollection,
const std::map< edm::Ref< TYPE >, reco::PFCandidatePtr > &  mapToTheCandidate,
const edm::OrphanHandle< reco::PFCandidateCollection > &  newPFCandColl 
) const
private

Definition at line 273 of file PFLinker.cc.

References trigObjTnPSource_cfi::filler, label, eostools::move(), producePFCandidates_, and contentValuesCheck::values.

278  {
279  auto pfMap_p = std::make_unique<edm::ValueMap<reco::PFCandidatePtr>>();
281 
282  typedef typename std::map<edm::Ref<TYPE>, reco::PFCandidatePtr>::const_iterator MapTYPE_it;
283 
284  unsigned nObj = inputObjCollection->size();
285  std::vector<reco::PFCandidatePtr> values(nObj);
286 
287  for (unsigned iobj = 0; iobj < nObj; ++iobj) {
288  edm::Ref<TYPE> objRef(inputObjCollection, iobj);
289  MapTYPE_it itcheck = mapToTheCandidate.find(objRef);
290 
291  reco::PFCandidatePtr candPtr;
292 
293  if (itcheck != mapToTheCandidate.end())
294  candPtr = producePFCandidates_ ? reco::PFCandidatePtr(newPFCandColl, itcheck->second.key()) : itcheck->second;
295 
296  values[iobj] = candPtr;
297  }
298 
299  filler.insert(inputObjCollection, values.begin(), values.end());
300  filler.fill();
301  edm::ValueMap<reco::PFCandidatePtr> returnValue = *pfMap_p;
302  event.put(std::move(pfMap_p), label);
303  return returnValue;
304 }
bool producePFCandidates_
Flags - if true: References will be towards new collection ; if false to the original one...
Definition: PFLinker.cc:70
char const * label
def move(src, dest)
Definition: eostools.py:511

◆ produce()

void PFLinker::produce ( edm::Event iEvent,
const edm::EventSetup iSetup 
)
override

Definition at line 145 of file PFLinker.cc.

References reco::PFCandidate::e, submitPVResolutionJobs::err, fillMuonRefs_, forceElectronsInHGCAL_, reco::PFCandidate::gamma, electronIsolatorFromEffectiveArea_cfi::gsfElectrons, mps_fire::i, iEvent, inputTagGsfElectrons_, inputTagMuonMap_, inputTagMuons_, inputTagPFCandidates_, inputTagPhotons_, edm::InputTag::label(), LogDebug, eostools::move(), DiMuonV_cfg::muons, muonTag_, nameOutputElectronsPF_, nameOutputMergedPF_, nameOutputPF_, nameOutputPhotonsPF_, reco::GsfElectron::P4_COMBINATION, zmumugammaAnalyzer_cfi::pfCandidates, displacedMuons_cfi::photon, BPHMonitor_cfi::photons, producePFCandidates_, and reco::Photon::regression2.

145  {
146  auto pfCandidates_p = std::make_unique<reco::PFCandidateCollection>();
147 
148  auto gsfElectrons = iEvent.getHandle(inputTagGsfElectrons_);
149 
150  std::map<reco::GsfElectronRef, reco::PFCandidatePtr> electronCandidateMap;
151 
152  auto photons = iEvent.getHandle(inputTagPhotons_);
153  std::map<reco::PhotonRef, reco::PFCandidatePtr> photonCandidateMap;
154 
156  if (fillMuonRefs_)
157  muonMap = iEvent.getHandle(inputTagMuonMap_);
158  std::map<reco::MuonRef, reco::PFCandidatePtr> muonCandidateMap;
159 
160  unsigned nColPF = inputTagPFCandidates_.size();
161 
162  for (unsigned icol = 0; icol < nColPF; ++icol) {
163  auto pfCandidates = iEvent.getHandle(inputTagPFCandidates_[icol]);
164  unsigned ncand = pfCandidates->size();
165 
166  for (unsigned i = 0; i < ncand; ++i) {
168  reco::PFCandidate cand(candPtr);
169 
170  bool isphoton = cand.particleId() == reco::PFCandidate::gamma && cand.mva_nothing_gamma() > 0.;
171  bool iselectron = cand.particleId() == reco::PFCandidate::e;
172  // PFCandidates may have a valid MuonRef though they are not muons.
173  bool hasNonNullMuonRef = cand.muonRef().isNonnull() && fillMuonRefs_;
174 
175  // if not an electron or a photon or a muon just fill the PFCandidate collection
176  if (!(isphoton || iselectron || hasNonNullMuonRef)) {
177  pfCandidates_p->push_back(cand);
178  continue;
179  }
180 
181  if (hasNonNullMuonRef) {
182  reco::MuonRef muRef = (*muonMap)[cand.muonRef()];
183  cand.setMuonRef(muRef);
184  muonCandidateMap[muRef] = candPtr;
185  }
186 
187  // if it is an electron. Find the GsfElectron with the same GsfTrack
188  if (iselectron) {
189  const reco::GsfTrackRef& gsfTrackRef(cand.gsfTrackRef());
190  auto itcheck = find_if(gsfElectrons->begin(), gsfElectrons->end(), [&gsfTrackRef](const auto& ele) {
191  return (ele.gsfTrack() == gsfTrackRef);
192  });
193  if (itcheck == gsfElectrons->end()) {
194  if (!forceElectronsInHGCAL_) {
195  std::ostringstream err;
196  err << " Problem in PFLinker: no GsfElectron " << std::endl;
197  edm::LogError("PFLinker") << err.str();
198  } else {
199  LogDebug("PFLinker") << "Forcing an electron pfCandidate at: " << cand.eta() << " in HGCAL" << std::endl;
200  pfCandidates_p->push_back(cand);
201  }
202  continue; // Watch out ! Continue
203  }
204  reco::GsfElectronRef electronRef(gsfElectrons, itcheck - gsfElectrons->begin());
205  cand.setGsfElectronRef(electronRef);
206  cand.setSuperClusterRef(electronRef->superCluster());
207  // update energy information since now it is done post-particleFlowTmp
208  cand.setEcalEnergy(electronRef->superCluster()->rawEnergy(), electronRef->ecalEnergy());
209  cand.setDeltaP(electronRef->p4Error(reco::GsfElectron::P4_COMBINATION));
210  cand.setP4(electronRef->p4(reco::GsfElectron::P4_COMBINATION));
211  electronCandidateMap[electronRef] = candPtr;
212  }
213 
214  // if it is a photon, find the one with the same PF super-cluster
215  if (isphoton) {
216  const reco::SuperClusterRef& scRef(cand.superClusterRef());
217  auto itcheck = find_if(
218  photons->begin(), photons->end(), [&scRef](const auto& photon) { return photon.superCluster() == scRef; });
219  if (itcheck == photons->end()) {
220  std::ostringstream err;
221  err << " Problem in PFLinker: no Photon " << std::endl;
222  edm::LogError("PFLinker") << err.str();
223  continue; // Watch out ! Continue
224  }
225  reco::PhotonRef photonRef(photons, itcheck - photons->begin());
226  cand.setPhotonRef(photonRef);
227  cand.setSuperClusterRef(photonRef->superCluster());
228  // update energy information since now it is done post-particleFlowTmp
229  cand.setEcalEnergy(photonRef->superCluster()->rawEnergy(),
230  photonRef->getCorrectedEnergy(reco::Photon::regression2));
231  cand.setDeltaP(photonRef->getCorrectedEnergyError(reco::Photon::regression2));
232  cand.setP4(photonRef->p4(reco::Photon::regression2));
233  photonCandidateMap[photonRef] = candPtr;
234  }
235 
236  pfCandidates_p->push_back(cand);
237  }
238  // save the PFCandidates and get a valid handle
239  }
240  const edm::OrphanHandle<reco::PFCandidateCollection> pfCandidateRefProd =
241  (producePFCandidates_) ? iEvent.put(std::move(pfCandidates_p), nameOutputPF_)
243 
244  // now make the valuemaps
245 
246  edm::ValueMap<reco::PFCandidatePtr> pfMapGsfElectrons = fillValueMap<reco::GsfElectronCollection>(
247  iEvent, nameOutputElectronsPF_, gsfElectrons, electronCandidateMap, pfCandidateRefProd);
248 
249  edm::ValueMap<reco::PFCandidatePtr> pfMapPhotons = fillValueMap<reco::PhotonCollection>(
250  iEvent, nameOutputPhotonsPF_, photons, photonCandidateMap, pfCandidateRefProd);
251 
253 
254  if (fillMuonRefs_) {
255  auto muons = iEvent.getHandle(inputTagMuons_);
256 
257  pfMapMuons =
258  fillValueMap<reco::MuonCollection>(iEvent, muonTag_.label(), muons, muonCandidateMap, pfCandidateRefProd);
259  }
260 
261  auto pfMapMerged = std::make_unique<edm::ValueMap<reco::PFCandidatePtr>>();
262  edm::ValueMap<reco::PFCandidatePtr>::Filler pfMapMergedFiller(*pfMapMerged);
263 
264  *pfMapMerged += pfMapGsfElectrons;
265  *pfMapMerged += pfMapPhotons;
266  if (fillMuonRefs_)
267  *pfMapMerged += pfMapMuons;
268 
269  iEvent.put(std::move(pfMapMerged), nameOutputMergedPF_);
270 }
edm::InputTag muonTag_
Input Muons.
Definition: PFLinker.cc:54
edm::EDGetTokenT< reco::MuonCollection > inputTagMuons_
Definition: PFLinker.cc:55
bool producePFCandidates_
Flags - if true: References will be towards new collection ; if false to the original one...
Definition: PFLinker.cc:70
std::string const & label() const
Definition: InputTag.h:36
Log< level::Error, false > LogError
edm::EDGetTokenT< reco::PhotonCollection > inputTagPhotons_
Input Photons.
Definition: PFLinker.cc:51
muons
the two sets of parameters below are mutually exclusive, depending if RECO or ALCARECO is used the us...
Definition: DiMuonV_cfg.py:214
edm::EDGetTokenT< reco::MuonToMuonMap > inputTagMuonMap_
Definition: PFLinker.cc:56
int iEvent
Definition: GenABIO.cc:224
std::string nameOutputElectronsPF_
name of output ValueMap electrons
Definition: PFLinker.cc:61
std::string nameOutputPhotonsPF_
name of output ValueMap photons
Definition: PFLinker.cc:64
std::string nameOutputPF_
name of output collection of PFCandidate
Definition: PFLinker.cc:58
bool fillMuonRefs_
Set muon refs and produce the value map?
Definition: PFLinker.cc:73
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
bool forceElectronsInHGCAL_
Put Electrons within HGCAL coming from SimPFProducer.
Definition: PFLinker.cc:76
edm::EDGetTokenT< reco::GsfElectronCollection > inputTagGsfElectrons_
Input GsfElectrons.
Definition: PFLinker.cc:48
def move(src, dest)
Definition: eostools.py:511
std::vector< edm::EDGetTokenT< reco::PFCandidateCollection > > inputTagPFCandidates_
Input PFCandidates.
Definition: PFLinker.cc:45
std::string nameOutputMergedPF_
name of output merged ValueMap
Definition: PFLinker.cc:67
#define LogDebug(id)

Member Data Documentation

◆ fillMuonRefs_

bool PFLinker::fillMuonRefs_
private

Set muon refs and produce the value map?

Definition at line 73 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ forceElectronsInHGCAL_

bool PFLinker::forceElectronsInHGCAL_
private

Put Electrons within HGCAL coming from SimPFProducer.

Definition at line 76 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ inputTagGsfElectrons_

edm::EDGetTokenT<reco::GsfElectronCollection> PFLinker::inputTagGsfElectrons_
private

Input GsfElectrons.

Definition at line 48 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ inputTagMuonMap_

edm::EDGetTokenT<reco::MuonToMuonMap> PFLinker::inputTagMuonMap_
private

Definition at line 56 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ inputTagMuons_

edm::EDGetTokenT<reco::MuonCollection> PFLinker::inputTagMuons_
private

Definition at line 55 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ inputTagPFCandidates_

std::vector<edm::EDGetTokenT<reco::PFCandidateCollection> > PFLinker::inputTagPFCandidates_
private

Input PFCandidates.

Definition at line 45 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ inputTagPhotons_

edm::EDGetTokenT<reco::PhotonCollection> PFLinker::inputTagPhotons_
private

Input Photons.

Definition at line 51 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ muonTag_

edm::InputTag PFLinker::muonTag_
private

Input Muons.

Definition at line 54 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ nameOutputElectronsPF_

std::string PFLinker::nameOutputElectronsPF_
private

name of output ValueMap electrons

Definition at line 61 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ nameOutputMergedPF_

std::string PFLinker::nameOutputMergedPF_
private

name of output merged ValueMap

Definition at line 67 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ nameOutputPF_

std::string PFLinker::nameOutputPF_
private

name of output collection of PFCandidate

Definition at line 58 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ nameOutputPhotonsPF_

std::string PFLinker::nameOutputPhotonsPF_
private

name of output ValueMap photons

Definition at line 64 of file PFLinker.cc.

Referenced by PFLinker(), and produce().

◆ producePFCandidates_

bool PFLinker::producePFCandidates_
private

Flags - if true: References will be towards new collection ; if false to the original one.

Definition at line 70 of file PFLinker.cc.

Referenced by fillValueMap(), PFLinker(), and produce().