43 LogDebug(
"HLTInclusiveVBFSource") <<
"constructor....";
50 triggerSummaryToken = consumes<trigger::TriggerEvent>(triggerSummaryLabel_);
52 triggerSummaryFUToken = consumes<trigger::TriggerEvent>(
54 triggerResultsFUToken = consumes<edm::TriggerResults>(
74 check_mjj650_Pt35_DEta3p5 =
false;
75 check_mjj700_Pt35_DEta3p5 =
false;
76 check_mjj750_Pt35_DEta3p5 =
false;
77 check_mjj800_Pt35_DEta3p5 =
false;
78 check_mjj650_Pt40_DEta3p5 =
false;
79 check_mjj700_Pt40_DEta3p5 =
false;
80 check_mjj750_Pt40_DEta3p5 =
false;
81 check_mjj800_Pt40_DEta3p5 =
false;
97 cout <<
"DEBUG-0: Start to analyze" << endl;
108 edm::LogInfo(
"HLTInclusiveVBFSource") <<
"TriggerResults not found, " 118 iEvent.getByToken(triggerSummaryToken, triggerObj_);
119 if (!triggerObj_.isValid()) {
120 iEvent.getByToken(triggerSummaryFUToken, triggerObj_);
121 if (!triggerObj_.isValid()) {
122 edm::LogInfo(
"HLTInclusiveVBFSource") <<
"TriggerEvent not found, " 129 cout <<
"DEBUG-1: Trigger information" << endl;
157 cout <<
"DEBUG-2: AOD Information" << endl;
164 filtername =
"dummy";
207 checkOffline =
false;
209 checkHLTIndex =
false;
218 checkdR_sameOrder =
false;
219 checkdR_crossOrder =
false;
222 reco_deltaetajet = 0.;
223 reco_deltaphijet = 0.;
224 reco_invmassjet = 0.;
225 hlt_deltaetajet = 0.;
226 hlt_deltaphijet = 0.;
233 checkOffline =
false;
234 for (
unsigned int ijet1 = 0; ijet1 <
jets.size(); ijet1++) {
237 if (
jets[ijet1].neutralEmEnergyFraction() > 0.99)
239 for (
unsigned int ijet2 = ijet1 + 1; ijet2 <
jets.size(); ijet2++) {
242 if (
jets[ijet2].neutralEmEnergyFraction() > 0.99)
245 reco_ejet1 =
jets[ijet1].energy();
247 reco_pxjet1 =
jets[ijet1].momentum().X();
248 reco_pyjet1 =
jets[ijet1].momentum().Y();
249 reco_pzjet1 =
jets[ijet1].momentum().Z();
250 reco_ptjet1 =
jets[ijet1].pt();
251 reco_etajet1 =
jets[ijet1].eta();
252 reco_phijet1 =
jets[ijet1].phi();
254 reco_ejet2 =
jets[ijet2].energy();
256 reco_pxjet2 =
jets[ijet2].momentum().X();
257 reco_pyjet2 =
jets[ijet2].momentum().Y();
258 reco_pzjet2 =
jets[ijet2].momentum().Z();
259 reco_ptjet2 =
jets[ijet2].pt();
260 reco_etajet2 =
jets[ijet2].eta();
261 reco_phijet2 =
jets[ijet2].phi();
263 reco_deltaetajet = reco_etajet1 - reco_etajet2;
265 reco_invmassjet =
sqrt((reco_ejet1 + reco_ejet2) * (reco_ejet1 + reco_ejet2) -
266 (reco_pxjet1 + reco_pxjet2) * (reco_pxjet1 + reco_pxjet2) -
267 (reco_pyjet1 + reco_pyjet2) * (reco_pyjet1 + reco_pyjet2) -
268 (reco_pzjet1 + reco_pzjet2) * (reco_pzjet1 + reco_pzjet2));
271 if (reco_ptjet1 < minPtHigh_)
273 if (reco_ptjet2 < minPtLow_)
275 if (etaOpposite_ ==
true && reco_etajet1 * reco_etajet2 > 0)
277 if (
std::abs(reco_deltaetajet) < minDeltaEta_)
279 if (
std::abs(reco_invmassjet) < minInvMass_)
284 cout <<
"DEBUG-3" << endl;
288 if (checkOffline ==
true)
291 if (checkOffline ==
false)
299 for (
auto&
v : hltPathsAll_) {
301 checkHLTIndex =
false;
304 v.getMEhisto_RECO_deltaEta_DiJet()->Fill(reco_deltaetajet);
305 v.getMEhisto_RECO_deltaPhi_DiJet()->Fill(reco_deltaphijet);
306 v.getMEhisto_RECO_invMass_DiJet()->Fill(reco_invmassjet);
310 cout <<
"DEBUG-4-0: Path loops" << endl;
313 if (isHLTPathAccepted(
v.getPath()) ==
false)
319 cout <<
"DEBUG-4-1: Path is accepted. Now we are looking for " <<
v.getLabel() <<
" module." << endl;
323 const int hltIndex = triggerObj_->filterIndex(
hltTag);
324 if (hltIndex >= triggerObj_->sizeFilters())
328 cout <<
"DEBUG-4-2: HLT module " <<
v.getLabel() <<
" exists" << endl;
329 const trigger::Keys& khlt = triggerObj_->filterKeys(hltIndex);
330 auto kj = khlt.begin();
331 for (; kj != khlt.end(); kj += 2) {
333 cout <<
"DEBUG-5" << endl;
334 checkdR_sameOrder =
false;
335 checkdR_crossOrder =
false;
336 hlt_ejet1 = toc[*kj].energy();
338 hlt_pxjet1 = toc[*kj].px();
339 hlt_pyjet1 = toc[*kj].py();
340 hlt_pzjet1 = toc[*kj].pz();
341 hlt_ptjet1 = toc[*kj].pt();
342 hlt_etajet1 = toc[*kj].eta();
343 hlt_phijet1 = toc[*kj].phi();
345 hlt_ejet2 = toc[*(kj + 1)].
energy();
347 hlt_pxjet2 = toc[*(kj + 1)].
px();
348 hlt_pyjet2 = toc[*(kj + 1)].
py();
349 hlt_pzjet2 = toc[*(kj + 1)].pz();
350 hlt_ptjet2 = toc[*(kj + 1)].
pt();
351 hlt_etajet2 = toc[*(kj + 1)].
eta();
352 hlt_phijet2 = toc[*(kj + 1)].phi();
354 dR_HLT_RECO_11 =
reco::deltaR(hlt_etajet1, hlt_phijet1, reco_etajet1, reco_phijet1);
355 dR_HLT_RECO_22 =
reco::deltaR(hlt_etajet2, hlt_phijet2, reco_etajet2, reco_phijet2);
356 dR_HLT_RECO_12 =
reco::deltaR(hlt_etajet1, hlt_phijet1, reco_etajet2, reco_phijet2);
357 dR_HLT_RECO_21 =
reco::deltaR(hlt_etajet2, hlt_phijet2, reco_etajet1, reco_phijet1);
358 if (dR_HLT_RECO_11 < deltaRMatch_ && dR_HLT_RECO_22 < deltaRMatch_)
359 checkdR_sameOrder =
true;
360 if (dR_HLT_RECO_12 < deltaRMatch_ && dR_HLT_RECO_21 < deltaRMatch_)
361 checkdR_crossOrder =
true;
362 if (checkdR_sameOrder ==
false && checkdR_crossOrder ==
false)
364 checkHLTIndex =
true;
367 cout <<
"DEBUG-6: Match" << endl;
368 hlt_deltaetajet = hlt_etajet1 - hlt_etajet2;
370 if (checkdR_crossOrder) {
371 hlt_deltaetajet = (-1) * hlt_deltaetajet;
374 hlt_invmassjet =
sqrt((hlt_ejet1 + hlt_ejet2) * (hlt_ejet1 + hlt_ejet2) -
375 (hlt_pxjet1 + hlt_pxjet2) * (hlt_pxjet1 + hlt_pxjet2) -
376 (hlt_pyjet1 + hlt_pyjet2) * (hlt_pyjet1 + hlt_pyjet2) -
377 (hlt_pzjet1 + hlt_pzjet2) * (hlt_pzjet1 + hlt_pzjet2));
378 v.getMEhisto_HLT_deltaEta_DiJet()->Fill(hlt_deltaetajet);
379 v.getMEhisto_HLT_deltaPhi_DiJet()->Fill(hlt_deltaphijet);
380 v.getMEhisto_HLT_invMass_DiJet()->Fill(hlt_invmassjet);
382 v.getMEhisto_RECO_deltaEta_DiJet_Match()->Fill(reco_deltaetajet);
383 v.getMEhisto_RECO_deltaPhi_DiJet_Match()->Fill(reco_deltaphijet);
384 v.getMEhisto_RECO_invMass_DiJet_Match()->Fill(reco_invmassjet);
386 v.getMEhisto_RECOHLT_deltaEta()->Fill(reco_deltaetajet, hlt_deltaetajet);
387 v.getMEhisto_RECOHLT_deltaPhi()->Fill(reco_deltaphijet, hlt_deltaphijet);
388 v.getMEhisto_RECOHLT_invMass()->Fill(reco_invmassjet, hlt_invmassjet);
390 if (checkHLTIndex ==
true)
397 if (checkHLT ==
true && checkHLTIndex ==
true) {
399 cout <<
"DEBUG-7: Match" << endl;
400 v.getMEhisto_NumberOfMatches()->Fill(1);
403 cout <<
"DEBUG-8: Not match" << endl;
404 v.getMEhisto_NumberOfMatches()->Fill(0);
411 for (
auto&
v : hltPathsAll_) {
412 if (isHLTPathAccepted(
v.getPath()) ==
false)
415 cout <<
"DEBUG-9: Loop for rate approximation: " <<
v.getPath() << endl;
416 check_mjj650_Pt35_DEta3p5 =
false;
417 check_mjj700_Pt35_DEta3p5 =
false;
418 check_mjj750_Pt35_DEta3p5 =
false;
419 check_mjj800_Pt35_DEta3p5 =
false;
420 check_mjj650_Pt40_DEta3p5 =
false;
421 check_mjj700_Pt40_DEta3p5 =
false;
422 check_mjj750_Pt40_DEta3p5 =
false;
423 check_mjj800_Pt40_DEta3p5 =
false;
425 const int hltIndex = triggerObj_->filterIndex(
hltTag);
426 if (hltIndex >= triggerObj_->sizeFilters())
428 const trigger::Keys& khlt = triggerObj_->filterKeys(hltIndex);
429 auto kj = khlt.begin();
430 for (; kj != khlt.end(); kj += 2) {
431 checkdR_sameOrder =
false;
432 checkdR_crossOrder =
false;
434 hlt_ejet1 = toc[*kj].energy();
436 hlt_pxjet1 = toc[*kj].px();
437 hlt_pyjet1 = toc[*kj].py();
438 hlt_pzjet1 = toc[*kj].pz();
439 hlt_ptjet1 = toc[*kj].pt();
440 hlt_etajet1 = toc[*kj].eta();
441 hlt_phijet1 = toc[*kj].phi();
443 hlt_ejet2 = toc[*(kj + 1)].
energy();
445 hlt_pxjet2 = toc[*(kj + 1)].
px();
446 hlt_pyjet2 = toc[*(kj + 1)].
py();
447 hlt_pzjet2 = toc[*(kj + 1)].pz();
448 hlt_ptjet2 = toc[*(kj + 1)].
pt();
449 hlt_etajet2 = toc[*(kj + 1)].
eta();
450 hlt_phijet2 = toc[*(kj + 1)].phi();
452 hlt_deltaetajet = hlt_etajet1 - hlt_etajet2;
454 hlt_invmassjet =
sqrt((hlt_ejet1 + hlt_ejet2) * (hlt_ejet1 + hlt_ejet2) -
455 (hlt_pxjet1 + hlt_pxjet2) * (hlt_pxjet1 + hlt_pxjet2) -
456 (hlt_pyjet1 + hlt_pyjet2) * (hlt_pyjet1 + hlt_pyjet2) -
457 (hlt_pzjet1 + hlt_pzjet2) * (hlt_pzjet1 + hlt_pzjet2));
459 if (check_mjj650_Pt35_DEta3p5 ==
false && hlt_ptjet1 > 35. && hlt_ptjet2 >= 35. && hlt_invmassjet > 650 &&
461 check_mjj650_Pt35_DEta3p5 =
true;
463 if (check_mjj700_Pt35_DEta3p5 ==
false && hlt_ptjet1 > 35. && hlt_ptjet2 >= 35. && hlt_invmassjet > 700 &&
465 check_mjj700_Pt35_DEta3p5 =
true;
467 if (check_mjj750_Pt35_DEta3p5 ==
false && hlt_ptjet1 > 35. && hlt_ptjet2 >= 35. && hlt_invmassjet > 750 &&
469 check_mjj750_Pt35_DEta3p5 =
true;
471 if (check_mjj800_Pt35_DEta3p5 ==
false && hlt_ptjet1 > 35. && hlt_ptjet2 >= 35. && hlt_invmassjet > 800 &&
473 check_mjj800_Pt35_DEta3p5 =
true;
475 if (check_mjj650_Pt40_DEta3p5 ==
false && hlt_ptjet1 > 40. && hlt_ptjet2 >= 40. && hlt_invmassjet > 650 &&
477 check_mjj650_Pt40_DEta3p5 =
true;
479 if (check_mjj700_Pt40_DEta3p5 ==
false && hlt_ptjet1 > 40. && hlt_ptjet2 >= 40. && hlt_invmassjet > 700 &&
481 check_mjj700_Pt40_DEta3p5 =
true;
483 if (check_mjj750_Pt40_DEta3p5 ==
false && hlt_ptjet1 > 40. && hlt_ptjet2 >= 40. && hlt_invmassjet > 750 &&
485 check_mjj750_Pt40_DEta3p5 =
true;
487 if (check_mjj800_Pt40_DEta3p5 ==
false && hlt_ptjet1 > 40. && hlt_ptjet2 >= 40. && hlt_invmassjet > 800 &&
489 check_mjj800_Pt40_DEta3p5 =
true;
492 if (check_mjj650_Pt35_DEta3p5 ==
true)
493 v.getMEhisto_NumberOfEvents()->Fill(0);
494 if (check_mjj700_Pt35_DEta3p5 ==
true)
495 v.getMEhisto_NumberOfEvents()->Fill(1);
496 if (check_mjj750_Pt35_DEta3p5 ==
true)
497 v.getMEhisto_NumberOfEvents()->Fill(2);
498 if (check_mjj800_Pt35_DEta3p5 ==
true)
499 v.getMEhisto_NumberOfEvents()->Fill(3);
500 if (check_mjj650_Pt40_DEta3p5 ==
true)
501 v.getMEhisto_NumberOfEvents()->Fill(4);
502 if (check_mjj700_Pt40_DEta3p5 ==
true)
503 v.getMEhisto_NumberOfEvents()->Fill(5);
504 if (check_mjj750_Pt40_DEta3p5 ==
true)
505 v.getMEhisto_NumberOfEvents()->Fill(6);
506 if (check_mjj800_Pt40_DEta3p5 ==
true)
507 v.getMEhisto_NumberOfEvents()->Fill(7);
517 if (!hltConfig_.init(
run,
c, processname_, changed)) {
518 LogDebug(
"HLTInclusiveVBFSource") <<
"HLTConfigProvider failed to initialize.";
521 const unsigned int numberOfPaths(hltConfig_.size());
522 for (
unsigned int i = 0;
i != numberOfPaths; ++
i) {
523 bool numFound =
false;
525 filtername =
"dummy";
526 unsigned int usedPrescale = 1;
527 unsigned int objectType = 0;
530 if (
pathname.find(
"HLT_Di") == std::string::npos)
532 if (
pathname.find(
"Jet") == std::string::npos)
534 if (
pathname.find(
"MJJ") == std::string::npos)
536 if (
pathname.find(
"VBF_v") == std::string::npos)
548 for (
unsigned int i = 0;
i != numberOfPaths; ++
i) {
554 if (numFound ==
false)
556 std::vector<std::string> numpathmodules = hltConfig_.moduleLabels(
pathname);
557 auto numpathmodule = numpathmodules.begin();
558 for (; numpathmodule != numpathmodules.end(); ++numpathmodule) {
560 if (hltConfig_.moduleType(*numpathmodule) ==
"HLTCaloJetVBFFilter" ||
561 hltConfig_.moduleType(*numpathmodule) ==
"HLTPFJetVBFFilter") {
562 filtername = *numpathmodule;
564 cout <<
" - Startup:Module = " << hltConfig_.moduleType(*numpathmodule) <<
", FilterName = " << filtername
569 cout <<
" - Startup:Final filter = " << filtername << endl;
571 if (objectType == 0 || numFound ==
false)
584 for (
auto&
v : hltPathsAll_) {
586 cout <<
"Storing: " <<
v.getPath() <<
", Prescale = " <<
v.getprescaleUsed() << endl;
609 RECO_deltaEta_DiJet = iBooker.
bookFloat(
"RECO_deltaEta_DiJet");
610 RECO_deltaPhi_DiJet = iBooker.
bookFloat(
"RECO_deltaPhi_DiJet");
611 RECO_invMass_DiJet = iBooker.
bookFloat(
"RECO_invMass_DiJet");
612 HLT_deltaEta_DiJet = iBooker.
bookFloat(
"HLT_deltaEta_DiJet");
613 HLT_deltaPhi_DiJet = iBooker.
bookFloat(
"HLT_deltaPhi_DiJet ");
614 HLT_invMass_DiJet = iBooker.
bookFloat(
"HLT_invMass_DiJet");
615 RECO_deltaEta_DiJet_Match = iBooker.
bookFloat(
"RECO_deltaEta_DiJet_Match");
616 RECO_deltaPhi_DiJet_Match = iBooker.
bookFloat(
"RECO_deltaPhi_DiJet_Match");
617 RECO_invMass_DiJet_Match = iBooker.
bookFloat(
"RECO_invMass_DiJet_Match");
618 RECOHLT_deltaEta = iBooker.
bookFloat(
"RECOHLT_deltaEta");
619 RECOHLT_deltaPhi = iBooker.
bookFloat(
"RECOHLT_deltaPhi ");
620 RECOHLT_invMass = iBooker.
bookFloat(
"RECOHLT_invMass");
621 NumberOfMatches = iBooker.
bookFloat(
"NumberOfMatches");
622 NumberOfEvents = iBooker.
bookFloat(
"NumberOfEvents");
629 histoname = labelname +
"_RECO_deltaEta_DiJet";
630 title = labelname +
"_RECO_deltaEta_DiJet " + trigPath;
631 RECO_deltaEta_DiJet = iBooker.
book1D(histoname.c_str(),
title.c_str(), 50, -10., 10.);
632 RECO_deltaEta_DiJet->
getTH1F();
635 histoname = labelname +
"_RECO_deltaPhi_DiJet";
636 title = labelname +
"_RECO_deltaPhi_DiJet " + trigPath;
637 RECO_deltaPhi_DiJet = iBooker.
book1D(histoname.c_str(),
title.c_str(), 35, -3.5, 3.5);
638 RECO_deltaPhi_DiJet->
getTH1F();
641 histoname = labelname +
"_RECO_invMass_DiJet";
642 title = labelname +
"_RECO_invMass_DiJet " + trigPath;
643 RECO_invMass_DiJet = iBooker.
book1D(histoname.c_str(),
title.c_str(), 100, 500., 2000.);
647 histoname = labelname +
"_HLT_deltaEta_DiJet";
648 title = labelname +
"_HLT_deltaEta_DiJet " + trigPath;
649 HLT_deltaEta_DiJet = iBooker.
book1D(histoname.c_str(),
title.c_str(), 50, -10., 10.);
653 histoname = labelname +
"_HLT_deltaPhi_DiJet";
654 title = labelname +
"_HLT_deltaPhi_DiJet " + trigPath;
655 HLT_deltaPhi_DiJet = iBooker.
book1D(histoname.c_str(),
title.c_str(), 35, -3.5, 3.5);
659 histoname = labelname +
"_HLT_invMass_DiJet";
660 title = labelname +
"_HLT_invMass_DiJet " + trigPath;
661 HLT_invMass_DiJet = iBooker.
book1D(histoname.c_str(),
title.c_str(), 100, 500., 2000.);
665 histoname = labelname +
"_RECO_deltaEta_DiJet_Match";
666 title = labelname +
"_RECO_deltaEta_DiJet_Match " + trigPath;
667 RECO_deltaEta_DiJet_Match = iBooker.
book1D(histoname.c_str(),
title.c_str(), 50, -10., 10.);
668 RECO_deltaEta_DiJet_Match->
getTH1F();
671 histoname = labelname +
"_RECO_deltaPhi_DiJet_Match";
672 title = labelname +
"_RECO_deltaPhi_DiJet_Match " + trigPath;
673 RECO_deltaPhi_DiJet_Match = iBooker.
book1D(histoname.c_str(),
title.c_str(), 35, -3.5, 3.5);
674 RECO_deltaPhi_DiJet_Match->
getTH1F();
677 histoname = labelname +
"_RECO_invMass_DiJet_Match";
678 title = labelname +
"_RECO_invMass_DiJet_Match " + trigPath;
679 RECO_invMass_DiJet_Match = iBooker.
book1D(histoname.c_str(),
title.c_str(), 100, 500., 2000.);
680 RECO_invMass_DiJet_Match->
getTH1F();
683 histoname = labelname +
"_RECOHLT_deltaEta";
684 title = labelname +
"_RECOHLT_deltaEta " + trigPath;
685 RECOHLT_deltaEta = iBooker.
book2D(histoname.c_str(),
title.c_str(), 50, -10., 10., 50, -10., 10.);
689 histoname = labelname +
"_RECOHLT_deltaPhi";
690 title = labelname +
"_RECOHLT_deltaPhi " + trigPath;
691 RECOHLT_deltaPhi = iBooker.
book2D(histoname.c_str(),
title.c_str(), 35, -3.5, 3.5, 35, -3.5, 3.5);
695 histoname = labelname +
"_RECOHLT_invMass";
696 title = labelname +
"_RECOHLT_invMass " + trigPath;
697 RECOHLT_invMass = iBooker.
book2D(histoname.c_str(),
title.c_str(), 100, 500., 2000., 100, 500., 2000.);
701 histoname = labelname +
"_NumberOfMatches ";
702 title = labelname +
"_NumberOfMatches " + trigPath;
703 NumberOfMatches = iBooker.
book1D(histoname.c_str(),
title.c_str(), 2, 0., 2.);
707 histoname = labelname +
"_NumberOfEvents";
708 title = labelname +
"_NumberOfEvents " + trigPath;
709 NumberOfEvents = iBooker.
book1D(histoname.c_str(),
title.c_str(), 10, 0., 10.);
713 v.setHistos(RECO_deltaEta_DiJet,
719 RECO_deltaEta_DiJet_Match,
720 RECO_deltaPhi_DiJet_Match,
721 RECO_invMass_DiJet_Match,
733 if (fabs(
eta) <= 1.3)
740 if (fabs(
eta) <= 3.0 && fabs(
eta) > 1.3)
755 for (
unsigned int j = 0;
j != hltConfig_.size(); ++
j) {
756 if (hltConfig_.triggerName(
j) ==
pathname)
777 const int index = triggerObj_->filterIndex(testTag);
778 if (
index >= triggerObj_->sizeFilters()) {
779 edm::LogInfo(
"HLTInclusiveVBFSource") <<
"no index " <<
index <<
" of that name ";
constexpr double deltaPhi(double phi1, double phi2)
T getParameter(std::string const &) const
MonitorElement * bookFloat(TString const &name, FUNC onbooking=NOOP())
virtual void setCurrentFolder(std::string const &fullpath)
virtual bool isForward(double eta)
virtual bool isBarrel(double eta)
virtual bool validPathHLT(std::string path)
~HLTInclusiveVBFSource() override
T getUntrackedParameter(std::string const &, T const &) const
void analyze(const edm::Event &, const edm::EventSetup &) override
HLTInclusiveVBFSource(const edm::ParameterSet &)
Abs< T >::type abs(const T &t)
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
std::vector< TriggerObject > TriggerObjectCollection
collection of trigger physics objects (e.g., all isolated muons)
Log< level::Info, false > LogInfo
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
std::vector< size_type > Keys
MonitorElement * book2D(TString const &name, TString const &title, int nchX, double lowX, double highX, int nchY, double lowY, double highY, FUNC onbooking=NOOP())
virtual bool isTriggerObjectFound(std::string objectName)
virtual bool isHLTPathAccepted(std::string pathName)
MonitorElement * book1D(TString const &name, TString const &title, int const nchX, double const lowX, double const highX, FUNC onbooking=NOOP())
virtual bool isEndCap(double eta)