CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes
L1ExtraParticlesProd Class Reference

#include <L1ExtraParticlesProd.h>

Inheritance diagram for L1ExtraParticlesProd:
edm::EDProducer edm::ProducerBase edm::EDConsumerBase edm::ProductRegistryHelper

Public Member Functions

 L1ExtraParticlesProd (const edm::ParameterSet &)
 
 ~L1ExtraParticlesProd ()
 
- Public Member Functions inherited from edm::EDProducer
 EDProducer ()
 
ModuleDescription const & moduleDescription () const
 
virtual ~EDProducer ()
 
- Public Member Functions inherited from edm::ProducerBase
 ProducerBase ()
 
void registerProducts (ProducerBase *, ProductRegistry *, ModuleDescription const &)
 
std::function< void(BranchDescription
const &)> 
registrationCallback () const
 used by the fwk to register list of products More...
 
virtual ~ProducerBase ()
 
- Public Member Functions inherited from edm::EDConsumerBase
 EDConsumerBase ()
 
ProductHolderIndexAndSkipBit indexFrom (EDGetToken, BranchType, TypeID const &) const
 
void itemsMayGet (BranchType, std::vector< ProductHolderIndexAndSkipBit > &) const
 
void itemsToGet (BranchType, std::vector< ProductHolderIndexAndSkipBit > &) const
 
std::vector
< ProductHolderIndexAndSkipBit >
const & 
itemsToGetFromEvent () const
 
void labelsForToken (EDGetToken iToken, Labels &oLabels) const
 
bool registeredToConsume (ProductHolderIndex, bool, BranchType) const
 
bool registeredToConsumeMany (TypeID const &, BranchType) const
 
void updateLookup (BranchType iBranchType, ProductHolderIndexHelper const &)
 
virtual ~EDConsumerBase ()
 

Private Member Functions

virtual void beginJob ()
 
virtual void endJob ()
 
math::PtEtaPhiMLorentzVector gctLorentzVector (const double &et, const L1GctCand &cand, const L1CaloGeometry *geom, bool central)
 
virtual void produce (edm::Event &, const edm::EventSetup &)
 

Private Attributes

edm::InputTag cenJetSource_
 
bool centralBxOnly_
 
edm::InputTag etHadSource_
 
edm::InputTag etMissSource_
 
edm::InputTag etTotSource_
 
edm::InputTag forJetSource_
 
edm::InputTag hfRingBitCountsSource_
 
edm::InputTag hfRingEtSumsSource_
 
edm::InputTag htMissSource_
 
bool ignoreHtMiss_
 
edm::InputTag isoEmSource_
 
edm::InputTag muonSource_
 
edm::InputTag nonIsoEmSource_
 
bool produceCaloParticles_
 
bool produceMuonParticles_
 
edm::InputTag tauJetSource_
 

Static Private Attributes

static const double muonMassGeV_ = 0.105658369
 

Additional Inherited Members

- Public Types inherited from edm::EDProducer
typedef EDProducer ModuleType
 
- Public Types inherited from edm::ProducerBase
typedef
ProductRegistryHelper::TypeLabelList 
TypeLabelList
 
- Static Public Member Functions inherited from edm::EDProducer
static const std::string & baseType ()
 
static void fillDescriptions (ConfigurationDescriptions &descriptions)
 
static void prevalidate (ConfigurationDescriptions &descriptions)
 
- Protected Member Functions inherited from edm::ProducerBase
void callWhenNewProductsRegistered (std::function< void(BranchDescription const &)> const &func)
 
- Protected Member Functions inherited from edm::EDConsumerBase
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > consumes (edm::InputTag const &tag)
 
EDGetToken consumes (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken consumes (TypeToGet const &id, edm::InputTag const &tag)
 
ConsumesCollector consumesCollector ()
 Use a ConsumesCollector to gather consumes information from helper functions. More...
 
template<typename ProductType , BranchType B = InEvent>
void consumesMany ()
 
void consumesMany (const TypeToGet &id)
 
template<BranchType B>
void consumesMany (const TypeToGet &id)
 
template<typename ProductType , BranchType B = InEvent>
EDGetTokenT< ProductType > mayConsume (edm::InputTag const &tag)
 
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 
template<BranchType B>
EDGetToken mayConsume (const TypeToGet &id, edm::InputTag const &tag)
 

Detailed Description

L1Trigger/L1ExtraFromDigis/interface/L1ExtraParticlesProd.h

Author
Werner Sun

Description: producer of L1Extra particle objects from Level-1 hardware objects.

src/L1ExtraParticlesProd/src/L1ExtraParticlesProd.cc

Definition at line 41 of file L1ExtraParticlesProd.h.

Constructor & Destructor Documentation

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

Definition at line 67 of file L1ExtraParticlesProd.cc.

68  : produceMuonParticles_( iConfig.getParameter< bool >(
69  "produceMuonParticles" ) ),
71  "muonSource" ) ),
72  produceCaloParticles_( iConfig.getParameter< bool >(
73  "produceCaloParticles" ) ),
75  "isolatedEmSource" ) ),
77  "nonIsolatedEmSource" ) ),
79  "centralJetSource" ) ),
81  "forwardJetSource" ) ),
83  "tauJetSource" ) ),
85  "etTotalSource" ) ),
87  "etHadSource" ) ),
89  "etMissSource" ) ),
91  "htMissSource" ) ),
93  "hfRingEtSumsSource" ) ),
95  "hfRingBitCountsSource" ) ),
96  centralBxOnly_( iConfig.getParameter< bool >( "centralBxOnly" ) ),
97  ignoreHtMiss_( iConfig.getParameter< bool >( "ignoreHtMiss" ) )
98 {
99  using namespace l1extra ;
100 
101  //register your products
102  produces< L1EmParticleCollection >( "Isolated" ) ;
103  produces< L1EmParticleCollection >( "NonIsolated" ) ;
104  produces< L1JetParticleCollection >( "Central" ) ;
105  produces< L1JetParticleCollection >( "Forward" ) ;
106  produces< L1JetParticleCollection >( "Tau" ) ;
107  produces< L1MuonParticleCollection >() ;
108  produces< L1EtMissParticleCollection >( "MET" ) ;
109  produces< L1EtMissParticleCollection >( "MHT" ) ;
110  produces< L1HFRingsCollection >() ;
111 
112  //now do what ever other initialization is needed
113 }
T getParameter(std::string const &) const
edm::InputTag hfRingEtSumsSource_
edm::InputTag hfRingBitCountsSource_
L1ExtraParticlesProd::~L1ExtraParticlesProd ( )

Definition at line 116 of file L1ExtraParticlesProd.cc.

117 {
118 
119  // do anything here that needs to be done at desctruction time
120  // (e.g. close files, deallocate resources etc.)
121 
122 }

Member Function Documentation

void L1ExtraParticlesProd::beginJob ( void  )
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 1091 of file L1ExtraParticlesProd.cc.

1092 {
1093 }
void L1ExtraParticlesProd::endJob ( void  )
privatevirtual

Reimplemented from edm::EDProducer.

Definition at line 1097 of file L1ExtraParticlesProd.cc.

1097  {
1098 }
math::PtEtaPhiMLorentzVector L1ExtraParticlesProd::gctLorentzVector ( const double &  et,
const L1GctCand cand,
const L1CaloGeometry geom,
bool  central 
)
private

Definition at line 1063 of file L1ExtraParticlesProd.cc.

References L1CaloGeometry::emJetPhiBinCenter(), eta(), L1CaloGeometry::etaBinCenter(), L1GctCand::etaIndex(), phi, and L1GctCand::phiIndex().

Referenced by produce().

1067 {
1068  // To keep x and y components non-zero.
1069  double etCorr = et + 1.e-6 ; // protect against roundoff, not only for et=0
1070 
1071  double eta = geom->etaBinCenter( cand.etaIndex(), central ) ;
1072 
1073 // double tanThOver2 = exp( -eta ) ;
1074 // double ez = etCorr * ( 1. - tanThOver2 * tanThOver2 ) / ( 2. * tanThOver2 );
1075 // double e = etCorr * ( 1. + tanThOver2 * tanThOver2 ) / ( 2. * tanThOver2 );
1076 
1077  double phi = geom->emJetPhiBinCenter( cand.phiIndex() ) ;
1078 
1079 // return math::XYZTLorentzVector( etCorr * cos( phi ),
1080 // etCorr * sin( phi ),
1081 // ez,
1082 // e ) ;
1083  return math::PtEtaPhiMLorentzVector( etCorr,
1084  eta,
1085  phi,
1086  0. ) ;
1087 }
T eta() const
double etaBinCenter(unsigned int etaIndex, bool central=true) const
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:25
virtual unsigned etaIndex() const =0
get eta index (bit 3 is sign, 1 for -ve Z, 0 for +ve Z)
virtual unsigned phiIndex() const =0
get phi index (0-17)
double emJetPhiBinCenter(unsigned int phiIndex) const
Definition: DDAxes.h:10
void L1ExtraParticlesProd::produce ( edm::Event iEvent,
const edm::EventSetup iSetup 
)
privatevirtual

Implements edm::EDProducer.

Definition at line 131 of file L1ExtraParticlesProd.cc.

References cenJetSource_, centralBxOnly_, alignCSCRings::e, eta(), etHadSource_, etMissSource_, L1CaloGeometry::etSumPhiBinCenter(), etTotSource_, forJetSource_, gctLorentzVector(), edm::EventSetup::get(), edm::Event::getByLabel(), hfRingBitCountsSource_, hfRingEtSumsSource_, htMissSource_, L1CaloGeometry::htSumPhiBinCenter(), i, ignoreHtMiss_, isoEmSource_, edm::HandleBase::isValid(), L1GctEtHad::kEtHadMaxValue, L1GctEtMiss::kEtMissMaxValue, L1GctEtTotal::kEtTotalMaxValue, LogDebug, muonMassGeV_, muonSource_, nonIsoEmSource_, p4, phi, produceCaloParticles_, produceMuonParticles_, RecoTauCleanerPlugins::pt, edm::Event::put(), tauJetSource_, and funct::true.

133 {
134  using namespace edm ;
135  using namespace l1extra ;
136  using namespace std ;
137 
138  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139  // ~~~~~~~~~~~~~~~~~~~~ Muons ~~~~~~~~~~~~~~~~~~~~
140  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141 
142  auto_ptr< L1MuonParticleCollection > muColl(
144 
146  {
148  iSetup.get< L1MuTriggerScalesRcd >().get( muScales ) ;
149 
151  iSetup.get< L1MuTriggerPtScaleRcd >().get( muPtScale ) ;
152 
153  Handle< L1MuGMTReadoutCollection > hwMuCollection ;
154  iEvent.getByLabel( muonSource_, hwMuCollection ) ;
155 
156  vector< L1MuGMTExtendedCand > hwMuCands ;
157 
158  if( !hwMuCollection.isValid() )
159  {
160  LogDebug("L1ExtraParticlesProd")
161  << "\nWarning: L1MuGMTReadoutCollection with " << muonSource_
162  << "\nrequested in configuration, but not found in the event."
163  << std::endl;
164  }
165  else
166  {
167  if( centralBxOnly_ )
168  {
169  // Get GMT candidates from central bunch crossing only
170  hwMuCands = hwMuCollection->getRecord().getGMTCands() ;
171  }
172  else
173  {
174  // Get GMT candidates from all bunch crossings
175  vector< L1MuGMTReadoutRecord > records = hwMuCollection->getRecords();
176  vector< L1MuGMTReadoutRecord >::const_iterator rItr = records.begin();
177  vector< L1MuGMTReadoutRecord >::const_iterator rEnd = records.end();
178 
179  for( ; rItr != rEnd ; ++rItr )
180  {
181  vector< L1MuGMTExtendedCand > tmpCands = rItr->getGMTCands() ;
182 
183  hwMuCands.insert( hwMuCands.end(),
184  tmpCands.begin(),
185  tmpCands.end() ) ;
186  }
187  }
188 
189 // cout << "HW muons" << endl ;
190  vector< L1MuGMTExtendedCand >::const_iterator muItr = hwMuCands.begin() ;
191  vector< L1MuGMTExtendedCand >::const_iterator muEnd = hwMuCands.end() ;
192  for( int i = 0 ; muItr != muEnd ; ++muItr, ++i )
193  {
194 // cout << "#" << i
195 // << " name " << muItr->name()
196 // << " empty " << muItr->empty()
197 // << " pt " << muItr->ptIndex()
198 // << " eta " << muItr->etaIndex()
199 // << " phi " << muItr->phiIndex()
200 // << " iso " << muItr->isol()
201 // << " mip " << muItr->mip()
202 // << " bx " << muItr->bx()
203 // << endl ;
204 
205  if( !muItr->empty() )
206  {
207  // keep x and y components non-zero and protect against roundoff.
208  double pt =
209  muPtScale->getPtScale()->getLowEdge( muItr->ptIndex() ) + 1.e-6 ;
210 
211 // cout << "L1Extra pt " << pt << endl ;
212 
213  double eta =
214  muScales->getGMTEtaScale()->getCenter( muItr->etaIndex() ) ;
215 
216  double phi =
217  muScales->getPhiScale()->getLowEdge( muItr->phiIndex() ) ;
218 
220  eta,
221  phi,
222  muonMassGeV_ ) ;
223 
224  muColl->push_back(
225  L1MuonParticle( muItr->charge(),
226  p4,
227  *muItr,
228  muItr->bx() )
229  ) ;
230  }
231  }
232  }
233  }
234 
236  iEvent.put( muColl );
237 
238 
239  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
240  // ~~~~~~~~~~~~~~~~~~~~ Calorimeter ~~~~~~~~~~~~~~~~~~~~
241  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
242 
243  auto_ptr< L1EmParticleCollection > isoEmColl(
245 
246  auto_ptr< L1EmParticleCollection > nonIsoEmColl(
248 
249  auto_ptr< L1JetParticleCollection > cenJetColl(
251 
252  auto_ptr< L1JetParticleCollection > forJetColl(
254 
255  auto_ptr< L1JetParticleCollection > tauJetColl(
257 
258  auto_ptr< L1EtMissParticleCollection > etMissColl(
260 
261  auto_ptr< L1EtMissParticleCollection > htMissColl(
263 
264  auto_ptr< L1HFRingsCollection > hfRingsColl( new L1HFRingsCollection );
265 
267  {
268  // ~~~~~~~~~~~~~~~~~~~~ Geometry ~~~~~~~~~~~~~~~~~~~~
269 
270  ESHandle< L1CaloGeometry > caloGeomESH ;
271  iSetup.get< L1CaloGeometryRecord >().get( caloGeomESH ) ;
272  const L1CaloGeometry* caloGeom = &( *caloGeomESH ) ;
273 
274  // ~~~~~~~~~~~~~~~~~~~~ EM ~~~~~~~~~~~~~~~~~~~~
275 
276  ESHandle< L1CaloEtScale > emScale ;
277  iSetup.get< L1EmEtScaleRcd >().get( emScale ) ;
278 
279  // Isolated EM
280  Handle< L1GctEmCandCollection > hwIsoEmCands ;
281  iEvent.getByLabel( isoEmSource_, hwIsoEmCands ) ;
282 
283  if( !hwIsoEmCands.isValid() )
284  {
285  LogDebug("L1ExtraParticlesProd")
286  << "\nWarning: L1GctEmCandCollection with " << isoEmSource_
287  << "\nrequested in configuration, but not found in the event."
288  << std::endl;
289  }
290  else
291  {
292 // cout << "HW iso EM" << endl ;
293 
294  L1GctEmCandCollection::const_iterator emItr = hwIsoEmCands->begin() ;
295  L1GctEmCandCollection::const_iterator emEnd = hwIsoEmCands->end() ;
296  for( int i = 0 ; emItr != emEnd ; ++emItr, ++i )
297  {
298 // cout << "#" << i
299 // << " name " << emItr->name()
300 // << " empty " << emItr->empty()
301 // << " rank " << emItr->rank()
302 // << " eta " << emItr->etaIndex()
303 // << " sign " << emItr->etaSign()
304 // << " phi " << emItr->phiIndex()
305 // << " iso " << emItr->isolated()
306 // << " bx " << emItr->bx()
307 // << endl ;
308 
309  if( !emItr->empty() &&
310  ( !centralBxOnly_ || emItr->bx() == 0 ) )
311  {
312  double et = emScale->et( emItr->rank() ) ;
313 
314 // cout << "L1Extra et " << et << endl ;
315 
316  isoEmColl->push_back(
317  L1EmParticle( gctLorentzVector( et, *emItr, caloGeom, true ),
318  Ref< L1GctEmCandCollection >( hwIsoEmCands,
319  i ),
320  emItr->bx() ) ) ;
321  }
322  }
323  }
324 
325 
326  // Non-isolated EM
327  Handle< L1GctEmCandCollection > hwNonIsoEmCands ;
328  iEvent.getByLabel( nonIsoEmSource_, hwNonIsoEmCands ) ;
329 
330  if( !hwNonIsoEmCands.isValid() )
331  {
332  LogDebug("L1ExtraParticlesProd")
333  << "\nWarning: L1GctEmCandCollection with " << nonIsoEmSource_
334  << "\nrequested in configuration, but not found in the event."
335  << std::endl;
336  }
337  else
338  {
339 // cout << "HW non-iso EM" << endl ;
340  L1GctEmCandCollection::const_iterator emItr = hwNonIsoEmCands->begin() ;
341  L1GctEmCandCollection::const_iterator emEnd = hwNonIsoEmCands->end() ;
342  for( int i = 0 ; emItr != emEnd ; ++emItr, ++i )
343  {
344 // cout << "#" << i
345 // << " name " << emItr->name()
346 // << " empty " << emItr->empty()
347 // << " rank " << emItr->rank()
348 // << " eta " << emItr->etaIndex()
349 // << " sign " << emItr->etaSign()
350 // << " phi " << emItr->phiIndex()
351 // << " iso " << emItr->isolated()
352 // << " bx " << emItr->bx()
353 // << endl ;
354 
355  if( !emItr->empty() &&
356  ( !centralBxOnly_ || emItr->bx() == 0 ) )
357  {
358  double et = emScale->et( emItr->rank() ) ;
359 
360 // cout << "L1Extra et " << et << endl ;
361 
362  nonIsoEmColl->push_back(
363  L1EmParticle( gctLorentzVector( et, *emItr, caloGeom, true ),
364  Ref< L1GctEmCandCollection >( hwNonIsoEmCands,
365  i ),
366  emItr->bx() ) );
367  }
368  }
369  }
370 
371 
372  // ~~~~~~~~~~~~~~~~~~~~ Jets ~~~~~~~~~~~~~~~~~~~~
373 
374  ESHandle< L1CaloEtScale > jetScale ;
375  iSetup.get< L1JetEtScaleRcd >().get( jetScale ) ;
376 
377  // Central jets.
378  Handle< L1GctJetCandCollection > hwCenJetCands ;
379  iEvent.getByLabel( cenJetSource_, hwCenJetCands ) ;
380 
381  if( !hwCenJetCands.isValid() )
382  {
383  LogDebug("L1ExtraParticlesProd")
384  << "\nWarning: L1GctJetCandCollection with " << cenJetSource_
385  << "\nrequested in configuration, but not found in the event."
386  << std::endl;
387  }
388  else
389  {
390 // cout << "HW central jets" << endl ;
391  L1GctJetCandCollection::const_iterator jetItr = hwCenJetCands->begin() ;
392  L1GctJetCandCollection::const_iterator jetEnd = hwCenJetCands->end() ;
393  for( int i = 0 ; jetItr != jetEnd ; ++jetItr, ++i )
394  {
395 // cout << "#" << i
396 // << " name " << jetItr->name()
397 // << " empty " << jetItr->empty()
398 // << " rank " << jetItr->rank()
399 // << " eta " << jetItr->etaIndex()
400 // << " sign " << jetItr->etaSign()
401 // << " phi " << jetItr->phiIndex()
402 // << " cen " << jetItr->isCentral()
403 // << " for " << jetItr->isForward()
404 // << " tau " << jetItr->isTau()
405 // << " bx " << jetItr->bx()
406 // << endl ;
407 
408  if( !jetItr->empty() &&
409  ( !centralBxOnly_ || jetItr->bx() == 0 ) )
410  {
411  double et = jetScale->et( jetItr->rank() ) ;
412 
413 // cout << "L1Extra et " << et << endl ;
414 
415  cenJetColl->push_back(
416  L1JetParticle( gctLorentzVector( et, *jetItr, caloGeom, true ),
417  Ref< L1GctJetCandCollection >( hwCenJetCands,
418  i ),
419  jetItr->bx() ) ) ;
420  }
421  }
422  }
423 
424 
425  // Forward jets.
426  Handle< L1GctJetCandCollection > hwForJetCands ;
427  iEvent.getByLabel( forJetSource_, hwForJetCands ) ;
428 
429  if( !hwForJetCands.isValid() )
430  {
431  LogDebug("L1ExtraParticlesProd")
432  << "\nWarning: L1GctEmCandCollection with " << forJetSource_
433  << "\nrequested in configuration, but not found in the event."
434  << std::endl;
435  }
436  else
437  {
438 // cout << "HW forward jets" << endl ;
439  L1GctJetCandCollection::const_iterator jetItr = hwForJetCands->begin() ;
440  L1GctJetCandCollection::const_iterator jetEnd = hwForJetCands->end() ;
441  for( int i = 0 ; jetItr != jetEnd ; ++jetItr, ++i )
442  {
443 // cout << "#" << i
444 // << " name " << jetItr->name()
445 // << " empty " << jetItr->empty()
446 // << " rank " << jetItr->rank()
447 // << " eta " << jetItr->etaIndex()
448 // << " sign " << jetItr->etaSign()
449 // << " phi " << jetItr->phiIndex()
450 // << " cen " << jetItr->isCentral()
451 // << " for " << jetItr->isForward()
452 // << " tau " << jetItr->isTau()
453 // << " bx " << jetItr->bx()
454 // << endl ;
455 
456  if( !jetItr->empty() &&
457  ( !centralBxOnly_ || jetItr->bx() == 0 ) )
458  {
459  double et = jetScale->et( jetItr->rank() ) ;
460 
461 // cout << "L1Extra et " << et << endl ;
462 
463  forJetColl->push_back(
464  L1JetParticle( gctLorentzVector( et, *jetItr, caloGeom, false ),
465  Ref< L1GctJetCandCollection >( hwForJetCands,
466  i ),
467  jetItr->bx() ) ) ;
468  }
469  }
470  }
471 
472 
473  // Tau jets.
474 // cout << "HW tau jets" << endl ;
475  Handle< L1GctJetCandCollection > hwTauJetCands ;
476  iEvent.getByLabel( tauJetSource_, hwTauJetCands ) ;
477 
478  if( !hwTauJetCands.isValid() )
479  {
480  LogDebug("L1ExtraParticlesProd")
481  << "\nWarning: L1GctJetCandCollection with " << tauJetSource_
482  << "\nrequested in configuration, but not found in the event."
483  << std::endl;
484  }
485  else
486  {
487  L1GctJetCandCollection::const_iterator jetItr = hwTauJetCands->begin() ;
488  L1GctJetCandCollection::const_iterator jetEnd = hwTauJetCands->end() ;
489  for( int i = 0 ; jetItr != jetEnd ; ++jetItr, ++i )
490  {
491 // cout << "#" << i
492 // << " name " << jetItr->name()
493 // << " empty " << jetItr->empty()
494 // << " rank " << jetItr->rank()
495 // << " eta " << jetItr->etaIndex()
496 // << " sign " << jetItr->etaSign()
497 // << " phi " << jetItr->phiIndex()
498 // << " cen " << jetItr->isCentral()
499 // << " for " << jetItr->isForward()
500 // << " tau " << jetItr->isTau()
501 // << " bx " << jetItr->bx()
502 // << endl ;
503 
504  if( !jetItr->empty() &&
505  ( !centralBxOnly_ || jetItr->bx() == 0 ) )
506  {
507  double et = jetScale->et( jetItr->rank() ) ;
508 
509 // cout << "L1Extra et " << et << endl ;
510 
511  tauJetColl->push_back(
512  L1JetParticle( gctLorentzVector( et, *jetItr, caloGeom, true ),
513  Ref< L1GctJetCandCollection >( hwTauJetCands,
514  i ),
515  jetItr->bx() ) ) ;
516  }
517  }
518  }
519 
520  // ~~~~~~~~~~~~~~~~~~~~ ET Sums ~~~~~~~~~~~~~~~~~~~~
521 
522  double etSumLSB = jetScale->linearLsb() ;
523 
525  iEvent.getByLabel( etTotSource_, hwEtTotColl ) ;
526 
527  Handle< L1GctEtMissCollection > hwEtMissColl ;
528  iEvent.getByLabel( etMissSource_, hwEtMissColl ) ;
529 
530  if( !hwEtTotColl.isValid() )
531  {
532  LogDebug("L1ExtraParticlesProd")
533  << "\nWarning: L1GctEtTotalCollection with " << etTotSource_
534  << "\nrequested in configuration, but not found in the event."
535  << std::endl;
536  }
537  else if( !hwEtMissColl.isValid() )
538  {
539  LogDebug("L1ExtraParticlesProd")
540  << "\nWarning: L1GctEtMissCollection with " << etMissSource_
541  << "\nrequested in configuration, but not found in the event."
542  << std::endl;
543  }
544  else
545  {
546  // Make a L1EtMissParticle even if either L1GctEtTotal or L1GctEtMiss
547  // is missing for a given bx. Keep track of which L1GctEtMiss objects
548  // have a corresponding L1GctEtTotal object.
549  std::vector< bool > etMissMatched ;
550 
551  L1GctEtMissCollection::const_iterator hwEtMissItr =
552  hwEtMissColl->begin() ;
553  L1GctEtMissCollection::const_iterator hwEtMissEnd =
554  hwEtMissColl->end() ;
555  for( ; hwEtMissItr != hwEtMissEnd ; ++hwEtMissItr )
556  {
557  etMissMatched.push_back( false ) ;
558  }
559 
560  // Collate energy sums by bx
561  L1GctEtTotalCollection::const_iterator hwEtTotItr =
562  hwEtTotColl->begin() ;
563  L1GctEtTotalCollection::const_iterator hwEtTotEnd =
564  hwEtTotColl->end() ;
565 
566  int iTot = 0 ;
567  for( ; hwEtTotItr != hwEtTotEnd ; ++hwEtTotItr, ++iTot )
568  {
569  int bx = hwEtTotItr->bx() ;
570 
571  if( !centralBxOnly_ || bx == 0 )
572  {
573  // ET bin low edge
574  double etTot =
575  ( hwEtTotItr->overFlow() ?
576  ( double ) L1GctEtTotal::kEtTotalMaxValue :
577  ( double ) hwEtTotItr->et() ) * etSumLSB + 1.e-6 ;
578 
579  int iMiss = 0 ;
580  hwEtMissItr = hwEtMissColl->begin() ;
581  hwEtMissEnd = hwEtMissColl->end() ;
582  for( ; hwEtMissItr != hwEtMissEnd ; ++hwEtMissItr, ++iMiss )
583  {
584  if( hwEtMissItr->bx() == bx )
585  {
586  etMissMatched[ iMiss ] = true ;
587  break ;
588  }
589  }
590 
591  double etMiss = 0. ;
592  double phi = 0. ;
595 
596  // If a L1GctEtMiss with the right bx is not found, itr == end.
597  if( hwEtMissItr != hwEtMissEnd )
598  {
599  // ET bin low edge
600  etMiss =
601  ( hwEtMissItr->overFlow() ?
602  ( double ) L1GctEtMiss::kEtMissMaxValue :
603  ( double ) hwEtMissItr->et() ) * etSumLSB + 1.e-6 ;
604  // keep x and y components non-zero and
605  // protect against roundoff.
606 
607  phi = caloGeom->etSumPhiBinCenter( hwEtMissItr->phi() ) ;
608 
609  p4 = math::PtEtaPhiMLorentzVector( etMiss,
610  0.,
611  phi,
612  0. ) ;
613 
614  metRef = Ref< L1GctEtMissCollection >( hwEtMissColl, iMiss ) ;
615 
616 // cout << "HW ET Sums " << endl
617 // << "MET: phi " << hwEtMissItr->phi() << " = " << phi
618 // << " et " << hwEtMissItr->et() << " = " << etMiss
619 // << " EtTot " << hwEtTotItr->et() << " = " << etTot
620 // << " bx " << bx
621 // << endl ;
622  }
623 // else
624 // {
625 // cout << "HW ET Sums " << endl
626 // << "MET: phi " << phi
627 // << " et "<< etMiss
628 // << " EtTot " << hwEtTotItr->et() << " = " << etTot
629 // << " bx " << bx
630 // << endl ;
631 // }
632 
633  etMissColl->push_back(
635  p4,
636  L1EtMissParticle::kMET,
637  etTot,
638  metRef,
639  Ref< L1GctEtTotalCollection >( hwEtTotColl, iTot ),
642  bx
643  ) ) ;
644  }
645  }
646 
647  if( !centralBxOnly_ )
648  {
649  // Make L1EtMissParticles for those L1GctEtMiss objects without
650  // a matched L1GctEtTotal object.
651 
652  double etTot = 0. ;
653 
654  hwEtMissItr = hwEtMissColl->begin() ;
655  hwEtMissEnd = hwEtMissColl->end() ;
656  int iMiss = 0 ;
657  for( ; hwEtMissItr != hwEtMissEnd ; ++hwEtMissItr, ++iMiss )
658  {
659  if( !etMissMatched[ iMiss ] )
660  {
661  int bx = hwEtMissItr->bx() ;
662 
663  // ET bin low edge
664  double etMiss =
665  ( hwEtMissItr->overFlow() ?
666  ( double ) L1GctEtMiss::kEtMissMaxValue :
667  ( double ) hwEtMissItr->et() ) * etSumLSB + 1.e-6 ;
668  // keep x and y components non-zero and
669  // protect against roundoff.
670 
671  double phi =
672  caloGeom->etSumPhiBinCenter( hwEtMissItr->phi() ) ;
673 
675  0.,
676  phi,
677  0. ) ;
678 
679 // cout << "HW ET Sums " << endl
680 // << "MET: phi " << hwEtMissItr->phi() << " = " << phi
681 // << " et " << hwEtMissItr->et() << " = " << etMiss
682 // << " EtTot " << etTot
683 // << " bx " << bx
684 // << endl ;
685 
686  etMissColl->push_back(
688  p4,
689  L1EtMissParticle::kMET,
690  etTot,
691  Ref< L1GctEtMissCollection >( hwEtMissColl, iMiss ),
695  bx
696  ) ) ;
697  }
698  }
699  }
700  }
701 
702  // ~~~~~~~~~~~~~~~~~~~~ HT Sums ~~~~~~~~~~~~~~~~~~~~
703 
704  Handle< L1GctEtHadCollection > hwEtHadColl ;
705  iEvent.getByLabel( etHadSource_, hwEtHadColl ) ;
706 
707  Handle< L1GctHtMissCollection > hwHtMissColl ;
708  if( !ignoreHtMiss_ )
709  {
710  iEvent.getByLabel( htMissSource_, hwHtMissColl ) ;
711  }
712 
713  ESHandle< L1GctJetFinderParams > jetFinderParams ;
714  iSetup.get< L1GctJetFinderParamsRcd >().get( jetFinderParams ) ;
715  double htSumLSB = jetFinderParams->getHtLsbGeV();
716 
717  ESHandle< L1CaloEtScale > htMissScale ;
718  std::vector< bool > htMissMatched ;
719  if( !ignoreHtMiss_ )
720  {
721  iSetup.get< L1HtMissScaleRcd >().get( htMissScale ) ;
722 
723  if( !hwEtHadColl.isValid() )
724  {
725  LogDebug("L1ExtraParticlesProd")
726  << "\nWarning: L1GctEtHadCollection with " << etHadSource_
727  << "\nrequested in configuration, but not found in the event."
728  << std::endl;
729  }
730  else if( !hwHtMissColl.isValid() )
731  {
732  LogDebug("L1ExtraParticlesProd")
733  << "\nWarning: L1GctHtMissCollection with " << htMissSource_
734  << "\nrequested in configuration, but not found in the event."
735  << std::endl;
736  }
737  else
738  {
739  // Make a L1EtMissParticle even if either L1GctEtHad or L1GctHtMiss
740  // is missing for a given bx. Keep track of which L1GctHtMiss objects
741  // have a corresponding L1GctHtTotal object.
742  L1GctHtMissCollection::const_iterator hwHtMissItr =
743  hwHtMissColl->begin() ;
744  L1GctHtMissCollection::const_iterator hwHtMissEnd =
745  hwHtMissColl->end() ;
746  for( ; hwHtMissItr != hwHtMissEnd ; ++hwHtMissItr )
747  {
748  htMissMatched.push_back( false ) ;
749  }
750  }
751  }
752 
753  if( !hwEtHadColl.isValid() )
754  {
755  LogDebug("L1ExtraParticlesProd")
756  << "\nWarning: L1GctEtHadCollection with " << etHadSource_
757  << "\nrequested in configuration, but not found in the event."
758  << std::endl;
759  }
760  else if( !hwHtMissColl.isValid() )
761  {
762  LogDebug("L1ExtraParticlesProd")
763  << "\nWarning: L1GctHtMissCollection with " << htMissSource_
764  << "\nrequested in configuration, but not found in the event."
765  << std::endl;
766  }
767  else
768  {
769  L1GctEtHadCollection::const_iterator hwEtHadItr =
770  hwEtHadColl->begin() ;
771  L1GctEtHadCollection::const_iterator hwEtHadEnd =
772  hwEtHadColl->end() ;
773 
774  int iHad = 0 ;
775  for( ; hwEtHadItr != hwEtHadEnd ; ++hwEtHadItr, ++iHad )
776  {
777  int bx = hwEtHadItr->bx() ;
778 
779  if( !centralBxOnly_ || bx == 0 )
780  {
781  // HT bin low edge
782  double htTot =
783  ( hwEtHadItr->overFlow() ?
784  ( double ) L1GctEtHad::kEtHadMaxValue :
785  ( double ) hwEtHadItr->et() ) * htSumLSB + 1.e-6 ;
786 
787  double htMiss = 0. ;
788  double phi = 0. ;
791 
792  if( !ignoreHtMiss_ )
793  {
794  L1GctHtMissCollection::const_iterator hwHtMissItr =
795  hwHtMissColl->begin() ;
796  L1GctHtMissCollection::const_iterator hwHtMissEnd =
797  hwHtMissColl->end() ;
798 
799  int iMiss = 0 ;
800  for( ; hwHtMissItr != hwHtMissEnd ; ++hwHtMissItr, ++iMiss )
801  {
802  if( hwHtMissItr->bx() == bx )
803  {
804  htMissMatched[ iMiss ] = true ;
805  break ;
806  }
807  }
808 
809  // If a L1GctHtMiss with the right bx is not found, itr == end.
810  if( hwHtMissItr != hwHtMissEnd )
811  {
812  // HT bin low edge
813  htMiss =
814  htMissScale->et( hwHtMissItr->overFlow() ?
815  htMissScale->rankScaleMax() :
816  hwHtMissItr->et() ) + 1.e-6 ;
817  // keep x and y components non-zero and
818  // protect against roundoff.
819 
820  phi =
821  caloGeom->htSumPhiBinCenter( hwHtMissItr->phi() ) ;
822 
823  p4 = math::PtEtaPhiMLorentzVector( htMiss,
824  0.,
825  phi,
826  0. ) ;
827 
828  mhtRef=Ref< L1GctHtMissCollection >( hwHtMissColl, iMiss );
829 
830 // cout << "HW HT Sums " << endl
831 // << "MHT: phi " << hwHtMissItr->phi() << " = " << phi
832 // << " ht " << hwHtMissItr->et() << " = " << htMiss
833 // << " HtTot " << hwEtHadItr->et() << " = " << htTot
834 // << " bx " << bx
835 // << endl ;
836  }
837 // else
838 // {
839 // cout << "HW HT Sums " << endl
840 // << "MHT: phi " << phi
841 // << " ht " << htMiss
842 // << " HtTot " << hwEtHadItr->et() << " = " << htTot
843 // << " bx " << bx
844 // << endl ;
845 // }
846  }
847 
848  htMissColl->push_back(
850  p4,
851  L1EtMissParticle::kMHT,
852  htTot,
855  mhtRef,
856  Ref< L1GctEtHadCollection >( hwEtHadColl, iHad ),
857  bx
858  ) ) ;
859  }
860  }
861 
862  if( !centralBxOnly_ && !ignoreHtMiss_ )
863  {
864  // Make L1EtMissParticles for those L1GctHtMiss objects without
865  // a matched L1GctHtTotal object.
866  double htTot = 0. ;
867 
868  L1GctHtMissCollection::const_iterator hwHtMissItr =
869  hwHtMissColl->begin() ;
870  L1GctHtMissCollection::const_iterator hwHtMissEnd =
871  hwHtMissColl->end() ;
872 
873  int iMiss = 0 ;
874  for( ; hwHtMissItr != hwHtMissEnd ; ++hwHtMissItr, ++iMiss )
875  {
876  if( !htMissMatched[ iMiss ] )
877  {
878  int bx = hwHtMissItr->bx() ;
879 
880  // HT bin low edge
881  double htMiss =
882  htMissScale->et( hwHtMissItr->overFlow() ?
883  htMissScale->rankScaleMax() :
884  hwHtMissItr->et() ) + 1.e-6 ;
885  // keep x and y components non-zero and
886  // protect against roundoff.
887 
888  double phi =
889  caloGeom->htSumPhiBinCenter( hwHtMissItr->phi() ) ;
890 
892  0.,
893  phi,
894  0. ) ;
895 
896 // cout << "HW HT Sums " << endl
897 // << "MHT: phi " << hwHtMissItr->phi() << " = " << phi
898 // << " ht " << hwHtMissItr->et() << " = " << htMiss
899 // << " HtTot " << htTot
900 // << " bx " << bx
901 // << endl ;
902 
903  htMissColl->push_back(
905  p4,
906  L1EtMissParticle::kMHT,
907  htTot,
910  Ref< L1GctHtMissCollection >( hwHtMissColl, iMiss ),
912  bx
913  ) ) ;
914  }
915  }
916  }
917  }
918 
919  // ~~~~~~~~~~~~~~~~~~~~ HF Rings ~~~~~~~~~~~~~~~~~~~~
920 
922  iEvent.getByLabel( hfRingEtSumsSource_, hwHFEtSumsColl ) ;
923 
924  Handle< L1GctHFBitCountsCollection > hwHFBitCountsColl ;
925  iEvent.getByLabel( hfRingBitCountsSource_, hwHFBitCountsColl ) ;
926 
927  ESHandle< L1CaloEtScale > hfRingEtScale ;
928  iSetup.get< L1HfRingEtScaleRcd >().get( hfRingEtScale ) ;
929 
930  if( !hwHFEtSumsColl.isValid() )
931  {
932  LogDebug("L1ExtraParticlesProd")
933  << "\nWarning: L1GctHFRingEtSumsCollection with " << hfRingEtSumsSource_
934  << "\nrequested in configuration, but not found in the event."
935  << std::endl;
936  }
937  else if( !hwHFBitCountsColl.isValid() )
938  {
939  LogDebug("L1ExtraParticlesProd")
940  << "\nWarning: L1GctHFBitCountsCollection with " << hfRingBitCountsSource_
941  << "\nrequested in configuration, but not found in the event."
942  << std::endl;
943  }
944  else
945  {
946  L1GctHFRingEtSumsCollection::const_iterator hwHFEtSumsItr =
947  hwHFEtSumsColl->begin() ;
948  L1GctHFRingEtSumsCollection::const_iterator hwHFEtSumsEnd =
949  hwHFEtSumsColl->end() ;
950 
951  int iEtSums = 0 ;
952  for( ; hwHFEtSumsItr != hwHFEtSumsEnd ; ++hwHFEtSumsItr, ++iEtSums )
953  {
954  int bx = hwHFEtSumsItr->bx() ;
955 
956  if( !centralBxOnly_ || bx == 0 )
957  {
958  L1GctHFBitCountsCollection::const_iterator hwHFBitCountsItr =
959  hwHFBitCountsColl->begin() ;
960  L1GctHFBitCountsCollection::const_iterator hwHFBitCountsEnd =
961  hwHFBitCountsColl->end() ;
962 
963  int iBitCounts = 0 ;
964  for( ; hwHFBitCountsItr != hwHFBitCountsEnd ;
965  ++hwHFBitCountsItr, ++iBitCounts )
966  {
967  if( hwHFBitCountsItr->bx() == bx )
968  {
969  break ;
970  }
971  }
972 
973  // If a L1GctHFBitCounts with the right bx is not found, itr == end.
974  if( hwHFBitCountsItr != hwHFBitCountsEnd )
975  {
976  // Construct L1HFRings only if both HW objects are present.
977 
978  // cout << "HF Rings " << endl
979 
980  // HF Et sums
981  double etSums[ L1HFRings::kNumRings ] ;
982  etSums[ L1HFRings::kRing1PosEta ] =
983  hfRingEtScale->et( hwHFEtSumsItr->etSum( 0 ) ) + 1.e-6 ;
984  etSums[ L1HFRings::kRing1NegEta ] =
985  hfRingEtScale->et( hwHFEtSumsItr->etSum( 1 ) ) + 1.e-6 ;
986  etSums[ L1HFRings::kRing2PosEta ] =
987  hfRingEtScale->et( hwHFEtSumsItr->etSum( 2 ) ) + 1.e-6 ;
988  etSums[ L1HFRings::kRing2NegEta ] =
989  hfRingEtScale->et( hwHFEtSumsItr->etSum( 3 ) ) + 1.e-6 ;
990  // protect against roundoff.
991 
992 // cout << "HF Et Sums "
993 // << hwHFEtSumsItr->etSum( 0 ) << " = "
994 // << etSums[ L1HFRings::kRing1PosEta ] << " "
995 // << hwHFEtSumsItr->etSum( 1 ) << " = "
996 // << etSums[ L1HFRings::kRing1NegEta ] << " "
997 // << hwHFEtSumsItr->etSum( 2 ) << " = "
998 // << etSums[ L1HFRings::kRing2PosEta ] << " "
999 // << hwHFEtSumsItr->etSum( 3 ) << " = "
1000 // << etSums[ L1HFRings::kRing2NegEta ]
1001 // << endl ;
1002 
1003  // HF bit counts
1004  int bitCounts[ L1HFRings::kNumRings ] ;
1005  bitCounts[ L1HFRings::kRing1PosEta ] =
1006  hwHFBitCountsItr->bitCount( 0 ) ;
1007  bitCounts[ L1HFRings::kRing1NegEta ] =
1008  hwHFBitCountsItr->bitCount( 1 ) ;
1009  bitCounts[ L1HFRings::kRing2PosEta ] =
1010  hwHFBitCountsItr->bitCount( 2 ) ;
1011  bitCounts[ L1HFRings::kRing2NegEta ] =
1012  hwHFBitCountsItr->bitCount( 3 ) ;
1013 
1014 // cout << "HF bit counts "
1015 // << hwHFBitCountsItr->bitCount( 0 ) << " "
1016 // << hwHFBitCountsItr->bitCount( 1 ) << " "
1017 // << hwHFBitCountsItr->bitCount( 2 ) << " "
1018 // << hwHFBitCountsItr->bitCount( 3 ) << " "
1019 // << endl ;
1020 
1021  hfRingsColl->push_back(
1022  L1HFRings( etSums,
1023  bitCounts,
1024  Ref< L1GctHFRingEtSumsCollection >( hwHFEtSumsColl,
1025  iEtSums ),
1026  Ref< L1GctHFBitCountsCollection >( hwHFBitCountsColl,
1027  iBitCounts ),
1028  bx
1029  ) ) ;
1030  }
1031  }
1032  }
1033  }
1034  }
1035 
1037  iEvent.put( isoEmColl, "Isolated" ) ;
1038 
1040  iEvent.put( nonIsoEmColl, "NonIsolated" ) ;
1041 
1043  iEvent.put( cenJetColl, "Central" ) ;
1044 
1046  iEvent.put( forJetColl, "Forward" ) ;
1047 
1049  iEvent.put( tauJetColl, "Tau" ) ;
1050 
1052  iEvent.put( etMissColl, "MET" ) ;
1053 
1055  iEvent.put( htMissColl, "MHT" ) ;
1056 
1057  OrphanHandle< L1HFRingsCollection > hfRingsCollHandle =
1058  iEvent.put( hfRingsColl ) ;
1059 }
#define LogDebug(id)
int i
Definition: DBlmapReader.cc:9
math::PtEtaPhiMLorentzVector gctLorentzVector(const double &et, const L1GctCand &cand, const L1CaloGeometry *geom, bool central)
T eta() const
static const double muonMassGeV_
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:25
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:116
double p4[4]
Definition: TauolaWrapper.h:92
double htSumPhiBinCenter(unsigned int phiIndex) const
edm::InputTag hfRingEtSumsSource_
edm::InputTag hfRingBitCountsSource_
bool isValid() const
Definition: HandleBase.h:76
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:390
const T & get() const
Definition: EventSetup.h:55
std::vector< L1EtMissParticle > L1EtMissParticleCollection
double etSumPhiBinCenter(unsigned int phiIndex) const
Definition: DDAxes.h:10

Member Data Documentation

edm::InputTag L1ExtraParticlesProd::cenJetSource_
private

Definition at line 64 of file L1ExtraParticlesProd.h.

Referenced by produce().

bool L1ExtraParticlesProd::centralBxOnly_
private

Definition at line 76 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::etHadSource_
private

Definition at line 68 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::etMissSource_
private

Definition at line 69 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::etTotSource_
private

Definition at line 67 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::forJetSource_
private

Definition at line 65 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::hfRingBitCountsSource_
private

Definition at line 72 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::hfRingEtSumsSource_
private

Definition at line 71 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::htMissSource_
private

Definition at line 70 of file L1ExtraParticlesProd.h.

Referenced by produce().

bool L1ExtraParticlesProd::ignoreHtMiss_
private

Definition at line 80 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::isoEmSource_
private

Definition at line 62 of file L1ExtraParticlesProd.h.

Referenced by produce().

double const L1ExtraParticlesProd::muonMassGeV_ = 0.105658369
staticprivate

Definition at line 74 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::muonSource_
private

Definition at line 59 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::nonIsoEmSource_
private

Definition at line 63 of file L1ExtraParticlesProd.h.

Referenced by produce().

bool L1ExtraParticlesProd::produceCaloParticles_
private

Definition at line 61 of file L1ExtraParticlesProd.h.

Referenced by produce().

bool L1ExtraParticlesProd::produceMuonParticles_
private

Definition at line 58 of file L1ExtraParticlesProd.h.

Referenced by produce().

edm::InputTag L1ExtraParticlesProd::tauJetSource_
private

Definition at line 66 of file L1ExtraParticlesProd.h.

Referenced by produce().