diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 000000000..22cc467a6 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. +config: d3cbb2c7c5ccfcda1afc552489b48f84 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/_images/columnar.png b/_images/columnar.png new file mode 100644 index 000000000..8ae9bdf6d Binary files /dev/null and b/_images/columnar.png differ diff --git a/_images/inheritance-27a321d9ec45cb2cd5502218088ee320767b27eb.png b/_images/inheritance-27a321d9ec45cb2cd5502218088ee320767b27eb.png new file mode 100644 index 000000000..6b8a4d684 Binary files /dev/null and b/_images/inheritance-27a321d9ec45cb2cd5502218088ee320767b27eb.png differ diff --git a/_images/inheritance-27a321d9ec45cb2cd5502218088ee320767b27eb.png.map b/_images/inheritance-27a321d9ec45cb2cd5502218088ee320767b27eb.png.map new file mode 100644 index 000000000..ef5493b1f --- /dev/null +++ b/_images/inheritance-27a321d9ec45cb2cd5502218088ee320767b27eb.png.map @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/_images/inheritance-31f0ad7408c4235c3cce168531a47585d9ca3f39.png b/_images/inheritance-31f0ad7408c4235c3cce168531a47585d9ca3f39.png new file mode 100644 index 000000000..8e1dcc37d Binary files /dev/null and b/_images/inheritance-31f0ad7408c4235c3cce168531a47585d9ca3f39.png differ diff --git a/_images/inheritance-31f0ad7408c4235c3cce168531a47585d9ca3f39.png.map b/_images/inheritance-31f0ad7408c4235c3cce168531a47585d9ca3f39.png.map new file mode 100644 index 000000000..c11d114a5 --- /dev/null +++ b/_images/inheritance-31f0ad7408c4235c3cce168531a47585d9ca3f39.png.map @@ -0,0 +1,6 @@ + + + + + + diff --git a/_images/inheritance-97a302fc26484a4a5046b140ffdfc0b0e88ac28f.png b/_images/inheritance-97a302fc26484a4a5046b140ffdfc0b0e88ac28f.png new file mode 100644 index 000000000..20b744b22 Binary files /dev/null and b/_images/inheritance-97a302fc26484a4a5046b140ffdfc0b0e88ac28f.png differ diff --git a/_images/inheritance-97a302fc26484a4a5046b140ffdfc0b0e88ac28f.png.map b/_images/inheritance-97a302fc26484a4a5046b140ffdfc0b0e88ac28f.png.map new file mode 100644 index 000000000..1218ee138 --- /dev/null +++ b/_images/inheritance-97a302fc26484a4a5046b140ffdfc0b0e88ac28f.png.map @@ -0,0 +1,5 @@ + + + + + diff --git a/_images/inheritance-b11f2d842e78e1a425057c04c4153a33e0521e85.png b/_images/inheritance-b11f2d842e78e1a425057c04c4153a33e0521e85.png new file mode 100644 index 000000000..cfd049d29 Binary files /dev/null and b/_images/inheritance-b11f2d842e78e1a425057c04c4153a33e0521e85.png differ diff --git a/_images/inheritance-b11f2d842e78e1a425057c04c4153a33e0521e85.png.map b/_images/inheritance-b11f2d842e78e1a425057c04c4153a33e0521e85.png.map new file mode 100644 index 000000000..2cb1bec65 --- /dev/null +++ b/_images/inheritance-b11f2d842e78e1a425057c04c4153a33e0521e85.png.map @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_images/inheritance-b34d504ec1bfe5214eb49828384d48289e8767fb.png b/_images/inheritance-b34d504ec1bfe5214eb49828384d48289e8767fb.png new file mode 100644 index 000000000..61f1b7067 Binary files /dev/null and b/_images/inheritance-b34d504ec1bfe5214eb49828384d48289e8767fb.png differ diff --git a/_images/inheritance-b34d504ec1bfe5214eb49828384d48289e8767fb.png.map b/_images/inheritance-b34d504ec1bfe5214eb49828384d48289e8767fb.png.map new file mode 100644 index 000000000..8b675c502 --- /dev/null +++ b/_images/inheritance-b34d504ec1bfe5214eb49828384d48289e8767fb.png.map @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_images/inheritance-b611f7d0e8cf385772cce3c879cd8b34a2da237c.png b/_images/inheritance-b611f7d0e8cf385772cce3c879cd8b34a2da237c.png new file mode 100644 index 000000000..766401a50 Binary files /dev/null and b/_images/inheritance-b611f7d0e8cf385772cce3c879cd8b34a2da237c.png differ diff --git a/_images/inheritance-b611f7d0e8cf385772cce3c879cd8b34a2da237c.png.map b/_images/inheritance-b611f7d0e8cf385772cce3c879cd8b34a2da237c.png.map new file mode 100644 index 000000000..16a484408 --- /dev/null +++ b/_images/inheritance-b611f7d0e8cf385772cce3c879cd8b34a2da237c.png.map @@ -0,0 +1,3 @@ + + + diff --git a/_images/inheritance-bfb9f3967431307b1219409b5a30467913b8873c.png b/_images/inheritance-bfb9f3967431307b1219409b5a30467913b8873c.png new file mode 100644 index 000000000..acd26efe7 Binary files /dev/null and b/_images/inheritance-bfb9f3967431307b1219409b5a30467913b8873c.png differ diff --git a/_images/inheritance-bfb9f3967431307b1219409b5a30467913b8873c.png.map b/_images/inheritance-bfb9f3967431307b1219409b5a30467913b8873c.png.map new file mode 100644 index 000000000..8f21f511b --- /dev/null +++ b/_images/inheritance-bfb9f3967431307b1219409b5a30467913b8873c.png.map @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/_images/inheritance-c1b1209f713b12400c7e24960dc64eaf8ae1042d.png b/_images/inheritance-c1b1209f713b12400c7e24960dc64eaf8ae1042d.png new file mode 100644 index 000000000..5038725d4 Binary files /dev/null and b/_images/inheritance-c1b1209f713b12400c7e24960dc64eaf8ae1042d.png differ diff --git a/_images/inheritance-c1b1209f713b12400c7e24960dc64eaf8ae1042d.png.map b/_images/inheritance-c1b1209f713b12400c7e24960dc64eaf8ae1042d.png.map new file mode 100644 index 000000000..0fea6b74c --- /dev/null +++ b/_images/inheritance-c1b1209f713b12400c7e24960dc64eaf8ae1042d.png.map @@ -0,0 +1,5 @@ + + + + + diff --git a/_images/inheritance-c5e0346a2520e8da3bf58b73c77163bfcd1f7912.png b/_images/inheritance-c5e0346a2520e8da3bf58b73c77163bfcd1f7912.png new file mode 100644 index 000000000..c53c64be9 Binary files /dev/null and b/_images/inheritance-c5e0346a2520e8da3bf58b73c77163bfcd1f7912.png differ diff --git a/_images/inheritance-c5e0346a2520e8da3bf58b73c77163bfcd1f7912.png.map b/_images/inheritance-c5e0346a2520e8da3bf58b73c77163bfcd1f7912.png.map new file mode 100644 index 000000000..ce407ac43 --- /dev/null +++ b/_images/inheritance-c5e0346a2520e8da3bf58b73c77163bfcd1f7912.png.map @@ -0,0 +1,5 @@ + + + + + diff --git a/_images/inheritance-c61e61501491f3fdbe125b3ba746ad47d3158fc3.png b/_images/inheritance-c61e61501491f3fdbe125b3ba746ad47d3158fc3.png new file mode 100644 index 000000000..198b61a91 Binary files /dev/null and b/_images/inheritance-c61e61501491f3fdbe125b3ba746ad47d3158fc3.png differ diff --git a/_images/inheritance-c61e61501491f3fdbe125b3ba746ad47d3158fc3.png.map b/_images/inheritance-c61e61501491f3fdbe125b3ba746ad47d3158fc3.png.map new file mode 100644 index 000000000..2cd1f33a3 --- /dev/null +++ b/_images/inheritance-c61e61501491f3fdbe125b3ba746ad47d3158fc3.png.map @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/_images/inheritance-d1d8fa6b162e090f70a24f933b189942f2e2e5db.png b/_images/inheritance-d1d8fa6b162e090f70a24f933b189942f2e2e5db.png new file mode 100644 index 000000000..77882998c Binary files /dev/null and b/_images/inheritance-d1d8fa6b162e090f70a24f933b189942f2e2e5db.png differ diff --git a/_images/inheritance-d1d8fa6b162e090f70a24f933b189942f2e2e5db.png.map b/_images/inheritance-d1d8fa6b162e090f70a24f933b189942f2e2e5db.png.map new file mode 100644 index 000000000..8490bc779 --- /dev/null +++ b/_images/inheritance-d1d8fa6b162e090f70a24f933b189942f2e2e5db.png.map @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/_images/inheritance-d39ddcacd300a77f4f00b38b3706b454f2bb2405.png b/_images/inheritance-d39ddcacd300a77f4f00b38b3706b454f2bb2405.png new file mode 100644 index 000000000..60c93d5b3 Binary files /dev/null and b/_images/inheritance-d39ddcacd300a77f4f00b38b3706b454f2bb2405.png differ diff --git a/_images/inheritance-d39ddcacd300a77f4f00b38b3706b454f2bb2405.png.map b/_images/inheritance-d39ddcacd300a77f4f00b38b3706b454f2bb2405.png.map new file mode 100644 index 000000000..9e1899296 --- /dev/null +++ b/_images/inheritance-d39ddcacd300a77f4f00b38b3706b454f2bb2405.png.map @@ -0,0 +1,4 @@ + + + + diff --git a/_images/inheritance-da164d4690f7ca5c8a2fcc89976648efc000c84c.png b/_images/inheritance-da164d4690f7ca5c8a2fcc89976648efc000c84c.png new file mode 100644 index 000000000..6ed16e135 Binary files /dev/null and b/_images/inheritance-da164d4690f7ca5c8a2fcc89976648efc000c84c.png differ diff --git a/_images/inheritance-da164d4690f7ca5c8a2fcc89976648efc000c84c.png.map b/_images/inheritance-da164d4690f7ca5c8a2fcc89976648efc000c84c.png.map new file mode 100644 index 000000000..2286328f3 --- /dev/null +++ b/_images/inheritance-da164d4690f7ca5c8a2fcc89976648efc000c84c.png.map @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/_images/notebooks_applying_corrections_10_1.png b/_images/notebooks_applying_corrections_10_1.png new file mode 100644 index 000000000..372b154a2 Binary files /dev/null and b/_images/notebooks_applying_corrections_10_1.png differ diff --git a/_images/notebooks_applying_corrections_12_2.png b/_images/notebooks_applying_corrections_12_2.png new file mode 100644 index 000000000..225e446da Binary files /dev/null and b/_images/notebooks_applying_corrections_12_2.png differ diff --git a/_images/notebooks_applying_corrections_14_1.png b/_images/notebooks_applying_corrections_14_1.png new file mode 100644 index 000000000..17991b7e2 Binary files /dev/null and b/_images/notebooks_applying_corrections_14_1.png differ diff --git a/_images/notebooks_histograms_29_0.png b/_images/notebooks_histograms_29_0.png new file mode 100644 index 000000000..89390c92c Binary files /dev/null and b/_images/notebooks_histograms_29_0.png differ diff --git a/_images/notebooks_histograms_31_0.png b/_images/notebooks_histograms_31_0.png new file mode 100644 index 000000000..fb39a3f56 Binary files /dev/null and b/_images/notebooks_histograms_31_0.png differ diff --git a/_images/notebooks_histograms_33_0.png b/_images/notebooks_histograms_33_0.png new file mode 100644 index 000000000..84454634f Binary files /dev/null and b/_images/notebooks_histograms_33_0.png differ diff --git a/_images/notebooks_histograms_34_0.png b/_images/notebooks_histograms_34_0.png new file mode 100644 index 000000000..9696e0720 Binary files /dev/null and b/_images/notebooks_histograms_34_0.png differ diff --git a/_images/notebooks_histograms_35_0.png b/_images/notebooks_histograms_35_0.png new file mode 100644 index 000000000..7cbafff14 Binary files /dev/null and b/_images/notebooks_histograms_35_0.png differ diff --git a/_images/notebooks_histograms_36_0.png b/_images/notebooks_histograms_36_0.png new file mode 100644 index 000000000..b7441b040 Binary files /dev/null and b/_images/notebooks_histograms_36_0.png differ diff --git a/_images/notebooks_histograms_37_2.png b/_images/notebooks_histograms_37_2.png new file mode 100644 index 000000000..3ed80416f Binary files /dev/null and b/_images/notebooks_histograms_37_2.png differ diff --git a/_images/notebooks_histograms_42_0.png b/_images/notebooks_histograms_42_0.png new file mode 100644 index 000000000..1edcb0d02 Binary files /dev/null and b/_images/notebooks_histograms_42_0.png differ diff --git a/_images/notebooks_histograms_43_0.png b/_images/notebooks_histograms_43_0.png new file mode 100644 index 000000000..fc8eeedbc Binary files /dev/null and b/_images/notebooks_histograms_43_0.png differ diff --git a/_images/notebooks_histograms_44_0.png b/_images/notebooks_histograms_44_0.png new file mode 100644 index 000000000..43eb7653c Binary files /dev/null and b/_images/notebooks_histograms_44_0.png differ diff --git a/_images/notebooks_histograms_46_0.png b/_images/notebooks_histograms_46_0.png new file mode 100644 index 000000000..a9e724780 Binary files /dev/null and b/_images/notebooks_histograms_46_0.png differ diff --git a/_images/notebooks_histograms_48_0.png b/_images/notebooks_histograms_48_0.png new file mode 100644 index 000000000..aedf95a3c Binary files /dev/null and b/_images/notebooks_histograms_48_0.png differ diff --git a/_images/notebooks_processor_10_1.png b/_images/notebooks_processor_10_1.png new file mode 100644 index 000000000..867b988e8 Binary files /dev/null and b/_images/notebooks_processor_10_1.png differ diff --git a/_images/notebooks_processor_17_1.png b/_images/notebooks_processor_17_1.png new file mode 100644 index 000000000..645261064 Binary files /dev/null and b/_images/notebooks_processor_17_1.png differ diff --git a/_images/notebooks_processor_18_0.png b/_images/notebooks_processor_18_0.png new file mode 100644 index 000000000..92c817554 Binary files /dev/null and b/_images/notebooks_processor_18_0.png differ diff --git a/_images/notebooks_processor_19_0.png b/_images/notebooks_processor_19_0.png new file mode 100644 index 000000000..a00ebf246 Binary files /dev/null and b/_images/notebooks_processor_19_0.png differ diff --git a/_images/notebooks_processor_20_1.png b/_images/notebooks_processor_20_1.png new file mode 100644 index 000000000..54fb2b791 Binary files /dev/null and b/_images/notebooks_processor_20_1.png differ diff --git a/_images/notebooks_processor_21_0.png b/_images/notebooks_processor_21_0.png new file mode 100644 index 000000000..9cb782a70 Binary files /dev/null and b/_images/notebooks_processor_21_0.png differ diff --git a/_images/notebooks_processor_22_0.png b/_images/notebooks_processor_22_0.png new file mode 100644 index 000000000..a21bd0abf Binary files /dev/null and b/_images/notebooks_processor_22_0.png differ diff --git a/_images/notebooks_processor_4_1.png b/_images/notebooks_processor_4_1.png new file mode 100644 index 000000000..06b88e067 Binary files /dev/null and b/_images/notebooks_processor_4_1.png differ diff --git a/_sources/api/coffea.analysis_tools.PackedSelection.rst.txt b/_sources/api/coffea.analysis_tools.PackedSelection.rst.txt new file mode 100644 index 000000000..1fd12fbb3 --- /dev/null +++ b/_sources/api/coffea.analysis_tools.PackedSelection.rst.txt @@ -0,0 +1,35 @@ +PackedSelection +=============== + +.. currentmodule:: coffea.analysis_tools + +.. autoclass:: PackedSelection + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~PackedSelection.maxitems + ~PackedSelection.names + + .. rubric:: Methods Summary + + .. autosummary:: + + ~PackedSelection.add + ~PackedSelection.all + ~PackedSelection.any + ~PackedSelection.require + + .. rubric:: Attributes Documentation + + .. autoattribute:: maxitems + .. autoattribute:: names + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: all + .. automethod:: any + .. automethod:: require diff --git a/_sources/api/coffea.analysis_tools.WeightStatistics.rst.txt b/_sources/api/coffea.analysis_tools.WeightStatistics.rst.txt new file mode 100644 index 000000000..ff0f4fd13 --- /dev/null +++ b/_sources/api/coffea.analysis_tools.WeightStatistics.rst.txt @@ -0,0 +1,19 @@ +WeightStatistics +================ + +.. currentmodule:: coffea.analysis_tools + +.. autoclass:: WeightStatistics + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~WeightStatistics.add + ~WeightStatistics.identity + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: identity diff --git a/_sources/api/coffea.analysis_tools.Weights.rst.txt b/_sources/api/coffea.analysis_tools.Weights.rst.txt new file mode 100644 index 000000000..c79a6f44e --- /dev/null +++ b/_sources/api/coffea.analysis_tools.Weights.rst.txt @@ -0,0 +1,35 @@ +Weights +======= + +.. currentmodule:: coffea.analysis_tools + +.. autoclass:: Weights + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Weights.variations + ~Weights.weightStatistics + + .. rubric:: Methods Summary + + .. autosummary:: + + ~Weights.add + ~Weights.add_multivariation + ~Weights.partial_weight + ~Weights.weight + + .. rubric:: Attributes Documentation + + .. autoattribute:: variations + .. autoattribute:: weightStatistics + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: add_multivariation + .. automethod:: partial_weight + .. automethod:: weight diff --git a/_sources/api/coffea.btag_tools.BTagScaleFactor.rst.txt b/_sources/api/coffea.btag_tools.BTagScaleFactor.rst.txt new file mode 100644 index 000000000..1182cda65 --- /dev/null +++ b/_sources/api/coffea.btag_tools.BTagScaleFactor.rst.txt @@ -0,0 +1,43 @@ +BTagScaleFactor +=============== + +.. currentmodule:: coffea.btag_tools + +.. autoclass:: BTagScaleFactor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~BTagScaleFactor.FLAV_B + ~BTagScaleFactor.FLAV_C + ~BTagScaleFactor.FLAV_UDSG + ~BTagScaleFactor.LOOSE + ~BTagScaleFactor.MEDIUM + ~BTagScaleFactor.RESHAPE + ~BTagScaleFactor.TIGHT + + .. rubric:: Methods Summary + + .. autosummary:: + + ~BTagScaleFactor.__call__ + ~BTagScaleFactor.eval + ~BTagScaleFactor.readcsv + + .. rubric:: Attributes Documentation + + .. autoattribute:: FLAV_B + .. autoattribute:: FLAV_C + .. autoattribute:: FLAV_UDSG + .. autoattribute:: LOOSE + .. autoattribute:: MEDIUM + .. autoattribute:: RESHAPE + .. autoattribute:: TIGHT + + .. rubric:: Methods Documentation + + .. automethod:: __call__ + .. automethod:: eval + .. automethod:: readcsv diff --git a/_sources/api/coffea.hist.Bin.rst.txt b/_sources/api/coffea.hist.Bin.rst.txt new file mode 100644 index 000000000..ffbc24b26 --- /dev/null +++ b/_sources/api/coffea.hist.Bin.rst.txt @@ -0,0 +1,35 @@ +Bin +=== + +.. currentmodule:: coffea.hist + +.. autoclass:: Bin + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Bin.size + + .. rubric:: Methods Summary + + .. autosummary:: + + ~Bin.centers + ~Bin.edges + ~Bin.identifiers + ~Bin.index + ~Bin.reduced + + .. rubric:: Attributes Documentation + + .. autoattribute:: size + + .. rubric:: Methods Documentation + + .. automethod:: centers + .. automethod:: edges + .. automethod:: identifiers + .. automethod:: index + .. automethod:: reduced diff --git a/_sources/api/coffea.hist.Cat.rst.txt b/_sources/api/coffea.hist.Cat.rst.txt new file mode 100644 index 000000000..5fc63a496 --- /dev/null +++ b/_sources/api/coffea.hist.Cat.rst.txt @@ -0,0 +1,31 @@ +Cat +=== + +.. currentmodule:: coffea.hist + +.. autoclass:: Cat + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Cat.size + ~Cat.sorting + + .. rubric:: Methods Summary + + .. autosummary:: + + ~Cat.identifiers + ~Cat.index + + .. rubric:: Attributes Documentation + + .. autoattribute:: size + .. autoattribute:: sorting + + .. rubric:: Methods Documentation + + .. automethod:: identifiers + .. automethod:: index diff --git a/_sources/api/coffea.hist.Hist.rst.txt b/_sources/api/coffea.hist.Hist.rst.txt new file mode 100644 index 000000000..579f95348 --- /dev/null +++ b/_sources/api/coffea.hist.Hist.rst.txt @@ -0,0 +1,79 @@ +Hist +==== + +.. currentmodule:: coffea.hist + +.. autoclass:: Hist + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Hist.DEFAULT_DTYPE + ~Hist.fields + ~Hist.label + + .. rubric:: Methods Summary + + .. autosummary:: + + ~Hist.add + ~Hist.axes + ~Hist.axis + ~Hist.clear + ~Hist.compatible + ~Hist.copy + ~Hist.dense_axes + ~Hist.dense_dim + ~Hist.dim + ~Hist.fill + ~Hist.group + ~Hist.identifiers + ~Hist.identity + ~Hist.integrate + ~Hist.project + ~Hist.rebin + ~Hist.remove + ~Hist.scale + ~Hist.sparse_axes + ~Hist.sparse_dim + ~Hist.sparse_nbins + ~Hist.sum + ~Hist.to_boost + ~Hist.to_hist + ~Hist.values + + .. rubric:: Attributes Documentation + + .. autoattribute:: DEFAULT_DTYPE + .. autoattribute:: fields + .. autoattribute:: label + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: axes + .. automethod:: axis + .. automethod:: clear + .. automethod:: compatible + .. automethod:: copy + .. automethod:: dense_axes + .. automethod:: dense_dim + .. automethod:: dim + .. automethod:: fill + .. automethod:: group + .. automethod:: identifiers + .. automethod:: identity + .. automethod:: integrate + .. automethod:: project + .. automethod:: rebin + .. automethod:: remove + .. automethod:: scale + .. automethod:: sparse_axes + .. automethod:: sparse_dim + .. automethod:: sparse_nbins + .. automethod:: sum + .. automethod:: to_boost + .. automethod:: to_hist + .. automethod:: values diff --git a/_sources/api/coffea.hist.Interval.rst.txt b/_sources/api/coffea.hist.Interval.rst.txt new file mode 100644 index 000000000..406656cd0 --- /dev/null +++ b/_sources/api/coffea.hist.Interval.rst.txt @@ -0,0 +1,33 @@ +Interval +======== + +.. currentmodule:: coffea.hist + +.. autoclass:: Interval + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Interval.hi + ~Interval.label + ~Interval.lo + ~Interval.mid + + .. rubric:: Methods Summary + + .. autosummary:: + + ~Interval.nan + + .. rubric:: Attributes Documentation + + .. autoattribute:: hi + .. autoattribute:: label + .. autoattribute:: lo + .. autoattribute:: mid + + .. rubric:: Methods Documentation + + .. automethod:: nan diff --git a/_sources/api/coffea.hist.StringBin.rst.txt b/_sources/api/coffea.hist.StringBin.rst.txt new file mode 100644 index 000000000..f991e4262 --- /dev/null +++ b/_sources/api/coffea.hist.StringBin.rst.txt @@ -0,0 +1,19 @@ +StringBin +========= + +.. currentmodule:: coffea.hist + +.. autoclass:: StringBin + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~StringBin.label + ~StringBin.name + + .. rubric:: Attributes Documentation + + .. autoattribute:: label + .. autoattribute:: name diff --git a/_sources/api/coffea.hist.clopper_pearson_interval.rst.txt b/_sources/api/coffea.hist.clopper_pearson_interval.rst.txt new file mode 100644 index 000000000..6f88164d0 --- /dev/null +++ b/_sources/api/coffea.hist.clopper_pearson_interval.rst.txt @@ -0,0 +1,6 @@ +clopper_pearson_interval +======================== + +.. currentmodule:: coffea.hist + +.. autofunction:: clopper_pearson_interval diff --git a/_sources/api/coffea.hist.export1d.rst.txt b/_sources/api/coffea.hist.export1d.rst.txt new file mode 100644 index 000000000..c83849344 --- /dev/null +++ b/_sources/api/coffea.hist.export1d.rst.txt @@ -0,0 +1,6 @@ +export1d +======== + +.. currentmodule:: coffea.hist + +.. autofunction:: export1d diff --git a/_sources/api/coffea.hist.normal_interval.rst.txt b/_sources/api/coffea.hist.normal_interval.rst.txt new file mode 100644 index 000000000..718eaa02c --- /dev/null +++ b/_sources/api/coffea.hist.normal_interval.rst.txt @@ -0,0 +1,6 @@ +normal_interval +=============== + +.. currentmodule:: coffea.hist + +.. autofunction:: normal_interval diff --git a/_sources/api/coffea.hist.plot1d.rst.txt b/_sources/api/coffea.hist.plot1d.rst.txt new file mode 100644 index 000000000..5c6763902 --- /dev/null +++ b/_sources/api/coffea.hist.plot1d.rst.txt @@ -0,0 +1,6 @@ +plot1d +====== + +.. currentmodule:: coffea.hist + +.. autofunction:: plot1d diff --git a/_sources/api/coffea.hist.plot2d.rst.txt b/_sources/api/coffea.hist.plot2d.rst.txt new file mode 100644 index 000000000..12e4af6a6 --- /dev/null +++ b/_sources/api/coffea.hist.plot2d.rst.txt @@ -0,0 +1,6 @@ +plot2d +====== + +.. currentmodule:: coffea.hist + +.. autofunction:: plot2d diff --git a/_sources/api/coffea.hist.plotgrid.rst.txt b/_sources/api/coffea.hist.plotgrid.rst.txt new file mode 100644 index 000000000..3ce8f3a79 --- /dev/null +++ b/_sources/api/coffea.hist.plotgrid.rst.txt @@ -0,0 +1,6 @@ +plotgrid +======== + +.. currentmodule:: coffea.hist + +.. autofunction:: plotgrid diff --git a/_sources/api/coffea.hist.plotratio.rst.txt b/_sources/api/coffea.hist.plotratio.rst.txt new file mode 100644 index 000000000..a47e7e279 --- /dev/null +++ b/_sources/api/coffea.hist.plotratio.rst.txt @@ -0,0 +1,6 @@ +plotratio +========= + +.. currentmodule:: coffea.hist + +.. autofunction:: plotratio diff --git a/_sources/api/coffea.hist.poisson_interval.rst.txt b/_sources/api/coffea.hist.poisson_interval.rst.txt new file mode 100644 index 000000000..0fbfc1622 --- /dev/null +++ b/_sources/api/coffea.hist.poisson_interval.rst.txt @@ -0,0 +1,6 @@ +poisson_interval +================ + +.. currentmodule:: coffea.hist + +.. autofunction:: poisson_interval diff --git a/_sources/api/coffea.jetmet_tools.CorrectedJetsFactory.rst.txt b/_sources/api/coffea.jetmet_tools.CorrectedJetsFactory.rst.txt new file mode 100644 index 000000000..d6436eb59 --- /dev/null +++ b/_sources/api/coffea.jetmet_tools.CorrectedJetsFactory.rst.txt @@ -0,0 +1,19 @@ +CorrectedJetsFactory +==================== + +.. currentmodule:: coffea.jetmet_tools + +.. autoclass:: CorrectedJetsFactory + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~CorrectedJetsFactory.build + ~CorrectedJetsFactory.uncertainties + + .. rubric:: Methods Documentation + + .. automethod:: build + .. automethod:: uncertainties diff --git a/_sources/api/coffea.jetmet_tools.CorrectedMETFactory.rst.txt b/_sources/api/coffea.jetmet_tools.CorrectedMETFactory.rst.txt new file mode 100644 index 000000000..bf78a2807 --- /dev/null +++ b/_sources/api/coffea.jetmet_tools.CorrectedMETFactory.rst.txt @@ -0,0 +1,19 @@ +CorrectedMETFactory +=================== + +.. currentmodule:: coffea.jetmet_tools + +.. autoclass:: CorrectedMETFactory + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~CorrectedMETFactory.build + ~CorrectedMETFactory.uncertainties + + .. rubric:: Methods Documentation + + .. automethod:: build + .. automethod:: uncertainties diff --git a/_sources/api/coffea.jetmet_tools.FactorizedJetCorrector.rst.txt b/_sources/api/coffea.jetmet_tools.FactorizedJetCorrector.rst.txt new file mode 100644 index 000000000..24779e3a1 --- /dev/null +++ b/_sources/api/coffea.jetmet_tools.FactorizedJetCorrector.rst.txt @@ -0,0 +1,29 @@ +FactorizedJetCorrector +====================== + +.. currentmodule:: coffea.jetmet_tools + +.. autoclass:: FactorizedJetCorrector + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~FactorizedJetCorrector.signature + + .. rubric:: Methods Summary + + .. autosummary:: + + ~FactorizedJetCorrector.getCorrection + ~FactorizedJetCorrector.getSubCorrections + + .. rubric:: Attributes Documentation + + .. autoattribute:: signature + + .. rubric:: Methods Documentation + + .. automethod:: getCorrection + .. automethod:: getSubCorrections diff --git a/_sources/api/coffea.jetmet_tools.JECStack.rst.txt b/_sources/api/coffea.jetmet_tools.JECStack.rst.txt new file mode 100644 index 000000000..8752a81da --- /dev/null +++ b/_sources/api/coffea.jetmet_tools.JECStack.rst.txt @@ -0,0 +1,25 @@ +JECStack +======== + +.. currentmodule:: coffea.jetmet_tools + +.. autoclass:: JECStack + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~JECStack.blank_name_map + ~JECStack.jec + ~JECStack.jer + ~JECStack.jersf + ~JECStack.junc + + .. rubric:: Attributes Documentation + + .. autoattribute:: blank_name_map + .. autoattribute:: jec + .. autoattribute:: jer + .. autoattribute:: jersf + .. autoattribute:: junc diff --git a/_sources/api/coffea.jetmet_tools.JetCorrectionUncertainty.rst.txt b/_sources/api/coffea.jetmet_tools.JetCorrectionUncertainty.rst.txt new file mode 100644 index 000000000..118f5ffcc --- /dev/null +++ b/_sources/api/coffea.jetmet_tools.JetCorrectionUncertainty.rst.txt @@ -0,0 +1,29 @@ +JetCorrectionUncertainty +======================== + +.. currentmodule:: coffea.jetmet_tools + +.. autoclass:: JetCorrectionUncertainty + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~JetCorrectionUncertainty.levels + ~JetCorrectionUncertainty.signature + + .. rubric:: Methods Summary + + .. autosummary:: + + ~JetCorrectionUncertainty.getUncertainty + + .. rubric:: Attributes Documentation + + .. autoattribute:: levels + .. autoattribute:: signature + + .. rubric:: Methods Documentation + + .. automethod:: getUncertainty diff --git a/_sources/api/coffea.jetmet_tools.JetResolution.rst.txt b/_sources/api/coffea.jetmet_tools.JetResolution.rst.txt new file mode 100644 index 000000000..7c8cb1837 --- /dev/null +++ b/_sources/api/coffea.jetmet_tools.JetResolution.rst.txt @@ -0,0 +1,27 @@ +JetResolution +============= + +.. currentmodule:: coffea.jetmet_tools + +.. autoclass:: JetResolution + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~JetResolution.signature + + .. rubric:: Methods Summary + + .. autosummary:: + + ~JetResolution.getResolution + + .. rubric:: Attributes Documentation + + .. autoattribute:: signature + + .. rubric:: Methods Documentation + + .. automethod:: getResolution diff --git a/_sources/api/coffea.jetmet_tools.JetResolutionScaleFactor.rst.txt b/_sources/api/coffea.jetmet_tools.JetResolutionScaleFactor.rst.txt new file mode 100644 index 000000000..8fa56b265 --- /dev/null +++ b/_sources/api/coffea.jetmet_tools.JetResolutionScaleFactor.rst.txt @@ -0,0 +1,27 @@ +JetResolutionScaleFactor +======================== + +.. currentmodule:: coffea.jetmet_tools + +.. autoclass:: JetResolutionScaleFactor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~JetResolutionScaleFactor.signature + + .. rubric:: Methods Summary + + .. autosummary:: + + ~JetResolutionScaleFactor.getScaleFactor + + .. rubric:: Attributes Documentation + + .. autoattribute:: signature + + .. rubric:: Methods Documentation + + .. automethod:: getScaleFactor diff --git a/_sources/api/coffea.lookup_tools.evaluator.rst.txt b/_sources/api/coffea.lookup_tools.evaluator.rst.txt new file mode 100644 index 000000000..25defedb5 --- /dev/null +++ b/_sources/api/coffea.lookup_tools.evaluator.rst.txt @@ -0,0 +1,17 @@ +evaluator +========= + +.. currentmodule:: coffea.lookup_tools + +.. autoclass:: evaluator + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~evaluator.keys + + .. rubric:: Methods Documentation + + .. automethod:: keys diff --git a/_sources/api/coffea.lookup_tools.extractor.rst.txt b/_sources/api/coffea.lookup_tools.extractor.rst.txt new file mode 100644 index 000000000..289f65da1 --- /dev/null +++ b/_sources/api/coffea.lookup_tools.extractor.rst.txt @@ -0,0 +1,27 @@ +extractor +========= + +.. currentmodule:: coffea.lookup_tools + +.. autoclass:: extractor + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~extractor.add_weight_set + ~extractor.add_weight_sets + ~extractor.extract_from_file + ~extractor.finalize + ~extractor.import_file + ~extractor.make_evaluator + + .. rubric:: Methods Documentation + + .. automethod:: add_weight_set + .. automethod:: add_weight_sets + .. automethod:: extract_from_file + .. automethod:: finalize + .. automethod:: import_file + .. automethod:: make_evaluator diff --git a/_sources/api/coffea.lumi_tools.LumiData.rst.txt b/_sources/api/coffea.lumi_tools.LumiData.rst.txt new file mode 100644 index 000000000..697532577 --- /dev/null +++ b/_sources/api/coffea.lumi_tools.LumiData.rst.txt @@ -0,0 +1,17 @@ +LumiData +======== + +.. currentmodule:: coffea.lumi_tools + +.. autoclass:: LumiData + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~LumiData.get_lumi + + .. rubric:: Methods Documentation + + .. automethod:: get_lumi diff --git a/_sources/api/coffea.lumi_tools.LumiList.rst.txt b/_sources/api/coffea.lumi_tools.LumiList.rst.txt new file mode 100644 index 000000000..a46d5904e --- /dev/null +++ b/_sources/api/coffea.lumi_tools.LumiList.rst.txt @@ -0,0 +1,17 @@ +LumiList +======== + +.. currentmodule:: coffea.lumi_tools + +.. autoclass:: LumiList + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~LumiList.clear + + .. rubric:: Methods Documentation + + .. automethod:: clear diff --git a/_sources/api/coffea.lumi_tools.LumiMask.rst.txt b/_sources/api/coffea.lumi_tools.LumiMask.rst.txt new file mode 100644 index 000000000..246cd5670 --- /dev/null +++ b/_sources/api/coffea.lumi_tools.LumiMask.rst.txt @@ -0,0 +1,17 @@ +LumiMask +======== + +.. currentmodule:: coffea.lumi_tools + +.. autoclass:: LumiMask + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~LumiMask.__call__ + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.nanoevents.BaseSchema.rst.txt b/_sources/api/coffea.nanoevents.BaseSchema.rst.txt new file mode 100644 index 000000000..9e4b13e54 --- /dev/null +++ b/_sources/api/coffea.nanoevents.BaseSchema.rst.txt @@ -0,0 +1,19 @@ +BaseSchema +========== + +.. currentmodule:: coffea.nanoevents + +.. autoclass:: BaseSchema + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~BaseSchema.behavior + ~BaseSchema.form + + .. rubric:: Attributes Documentation + + .. autoattribute:: behavior + .. autoattribute:: form diff --git a/_sources/api/coffea.nanoevents.DelphesSchema.rst.txt b/_sources/api/coffea.nanoevents.DelphesSchema.rst.txt new file mode 100644 index 000000000..53468899f --- /dev/null +++ b/_sources/api/coffea.nanoevents.DelphesSchema.rst.txt @@ -0,0 +1,35 @@ +DelphesSchema +============= + +.. currentmodule:: coffea.nanoevents + +.. autoclass:: DelphesSchema + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~DelphesSchema.behavior + ~DelphesSchema.docstrings + ~DelphesSchema.mixins + ~DelphesSchema.singletons + ~DelphesSchema.warn_missing_crossrefs + + .. rubric:: Methods Summary + + .. autosummary:: + + ~DelphesSchema.v1 + + .. rubric:: Attributes Documentation + + .. autoattribute:: behavior + .. autoattribute:: docstrings + .. autoattribute:: mixins + .. autoattribute:: singletons + .. autoattribute:: warn_missing_crossrefs + + .. rubric:: Methods Documentation + + .. automethod:: v1 diff --git a/_sources/api/coffea.nanoevents.NanoAODSchema.rst.txt b/_sources/api/coffea.nanoevents.NanoAODSchema.rst.txt new file mode 100644 index 000000000..90dd1e04e --- /dev/null +++ b/_sources/api/coffea.nanoevents.NanoAODSchema.rst.txt @@ -0,0 +1,43 @@ +NanoAODSchema +============= + +.. currentmodule:: coffea.nanoevents + +.. autoclass:: NanoAODSchema + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~NanoAODSchema.all_cross_references + ~NanoAODSchema.behavior + ~NanoAODSchema.mixins + ~NanoAODSchema.nested_index_items + ~NanoAODSchema.nested_items + ~NanoAODSchema.special_items + ~NanoAODSchema.warn_missing_crossrefs + + .. rubric:: Methods Summary + + .. autosummary:: + + ~NanoAODSchema.v5 + ~NanoAODSchema.v6 + ~NanoAODSchema.v7 + + .. rubric:: Attributes Documentation + + .. autoattribute:: all_cross_references + .. autoattribute:: behavior + .. autoattribute:: mixins + .. autoattribute:: nested_index_items + .. autoattribute:: nested_items + .. autoattribute:: special_items + .. autoattribute:: warn_missing_crossrefs + + .. rubric:: Methods Documentation + + .. automethod:: v5 + .. automethod:: v6 + .. automethod:: v7 diff --git a/_sources/api/coffea.nanoevents.NanoEventsFactory.rst.txt b/_sources/api/coffea.nanoevents.NanoEventsFactory.rst.txt new file mode 100644 index 000000000..988689343 --- /dev/null +++ b/_sources/api/coffea.nanoevents.NanoEventsFactory.rst.txt @@ -0,0 +1,23 @@ +NanoEventsFactory +================= + +.. currentmodule:: coffea.nanoevents + +.. autoclass:: NanoEventsFactory + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~NanoEventsFactory.events + ~NanoEventsFactory.from_parquet + ~NanoEventsFactory.from_preloaded + ~NanoEventsFactory.from_root + + .. rubric:: Methods Documentation + + .. automethod:: events + .. automethod:: from_parquet + .. automethod:: from_preloaded + .. automethod:: from_root diff --git a/_sources/api/coffea.nanoevents.PDUNESchema.rst.txt b/_sources/api/coffea.nanoevents.PDUNESchema.rst.txt new file mode 100644 index 000000000..8adb4e3ab --- /dev/null +++ b/_sources/api/coffea.nanoevents.PDUNESchema.rst.txt @@ -0,0 +1,21 @@ +PDUNESchema +=========== + +.. currentmodule:: coffea.nanoevents + +.. autoclass:: PDUNESchema + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~PDUNESchema.behavior + ~PDUNESchema.mixins + ~PDUNESchema.top_objects + + .. rubric:: Attributes Documentation + + .. autoattribute:: behavior + .. autoattribute:: mixins + .. autoattribute:: top_objects diff --git a/_sources/api/coffea.nanoevents.PFNanoAODSchema.rst.txt b/_sources/api/coffea.nanoevents.PFNanoAODSchema.rst.txt new file mode 100644 index 000000000..cc4613766 --- /dev/null +++ b/_sources/api/coffea.nanoevents.PFNanoAODSchema.rst.txt @@ -0,0 +1,19 @@ +PFNanoAODSchema +=============== + +.. currentmodule:: coffea.nanoevents + +.. autoclass:: PFNanoAODSchema + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~PFNanoAODSchema.all_cross_references + ~PFNanoAODSchema.mixins + + .. rubric:: Attributes Documentation + + .. autoattribute:: all_cross_references + .. autoattribute:: mixins diff --git a/_sources/api/coffea.nanoevents.PHYSLITESchema.rst.txt b/_sources/api/coffea.nanoevents.PHYSLITESchema.rst.txt new file mode 100644 index 000000000..15ac0c654 --- /dev/null +++ b/_sources/api/coffea.nanoevents.PHYSLITESchema.rst.txt @@ -0,0 +1,21 @@ +PHYSLITESchema +============== + +.. currentmodule:: coffea.nanoevents + +.. autoclass:: PHYSLITESchema + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~PHYSLITESchema.behavior + ~PHYSLITESchema.mixins + ~PHYSLITESchema.truth_collections + + .. rubric:: Attributes Documentation + + .. autoattribute:: behavior + .. autoattribute:: mixins + .. autoattribute:: truth_collections diff --git a/_sources/api/coffea.nanoevents.TreeMakerSchema.rst.txt b/_sources/api/coffea.nanoevents.TreeMakerSchema.rst.txt new file mode 100644 index 000000000..f6e9f529b --- /dev/null +++ b/_sources/api/coffea.nanoevents.TreeMakerSchema.rst.txt @@ -0,0 +1,27 @@ +TreeMakerSchema +=============== + +.. currentmodule:: coffea.nanoevents + +.. autoclass:: TreeMakerSchema + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~TreeMakerSchema.behavior + + .. rubric:: Methods Summary + + .. autosummary:: + + ~TreeMakerSchema.uproot_writeable + + .. rubric:: Attributes Documentation + + .. autoattribute:: behavior + + .. rubric:: Methods Documentation + + .. automethod:: uproot_writeable diff --git a/_sources/api/coffea.nanoevents.methods.base.NanoCollection.rst.txt b/_sources/api/coffea.nanoevents.methods.base.NanoCollection.rst.txt new file mode 100644 index 000000000..f24cc86cc --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.base.NanoCollection.rst.txt @@ -0,0 +1,7 @@ +NanoCollection +============== + +.. currentmodule:: coffea.nanoevents.methods.base + +.. autoclass:: NanoCollection + :show-inheritance: diff --git a/_sources/api/coffea.nanoevents.methods.base.NanoEvents.rst.txt b/_sources/api/coffea.nanoevents.methods.base.NanoEvents.rst.txt new file mode 100644 index 000000000..bb859f50e --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.base.NanoEvents.rst.txt @@ -0,0 +1,17 @@ +NanoEvents +========== + +.. currentmodule:: coffea.nanoevents.methods.base + +.. autoclass:: NanoEvents + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~NanoEvents.metadata + + .. rubric:: Attributes Documentation + + .. autoattribute:: metadata diff --git a/_sources/api/coffea.nanoevents.methods.base.Systematic.rst.txt b/_sources/api/coffea.nanoevents.methods.base.Systematic.rst.txt new file mode 100644 index 000000000..089bdbbc3 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.base.Systematic.rst.txt @@ -0,0 +1,33 @@ +Systematic +========== + +.. currentmodule:: coffea.nanoevents.methods.base + +.. autoclass:: Systematic + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Systematic.systematics + + .. rubric:: Methods Summary + + .. autosummary:: + + ~Systematic.add_kind + ~Systematic.add_systematic + ~Systematic.describe_variations + ~Systematic.explodes_how + + .. rubric:: Attributes Documentation + + .. autoattribute:: systematics + + .. rubric:: Methods Documentation + + .. automethod:: add_kind + .. automethod:: add_systematic + .. automethod:: describe_variations + .. automethod:: explodes_how diff --git a/_sources/api/coffea.nanoevents.methods.candidate.Candidate.rst.txt b/_sources/api/coffea.nanoevents.methods.candidate.Candidate.rst.txt new file mode 100644 index 000000000..82a9e07ac --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.candidate.Candidate.rst.txt @@ -0,0 +1,19 @@ +Candidate +========= + +.. currentmodule:: coffea.nanoevents.methods.candidate + +.. autoclass:: Candidate + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~Candidate.add + ~Candidate.sum + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: sum diff --git a/_sources/api/coffea.nanoevents.methods.candidate.PtEtaPhiECandidate.rst.txt b/_sources/api/coffea.nanoevents.methods.candidate.PtEtaPhiECandidate.rst.txt new file mode 100644 index 000000000..ea68e773d --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.candidate.PtEtaPhiECandidate.rst.txt @@ -0,0 +1,7 @@ +PtEtaPhiECandidate +================== + +.. currentmodule:: coffea.nanoevents.methods.candidate + +.. autoclass:: PtEtaPhiECandidate + :show-inheritance: diff --git a/_sources/api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate.rst.txt b/_sources/api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate.rst.txt new file mode 100644 index 000000000..a8a8683f0 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate.rst.txt @@ -0,0 +1,7 @@ +PtEtaPhiMCandidate +================== + +.. currentmodule:: coffea.nanoevents.methods.candidate + +.. autoclass:: PtEtaPhiMCandidate + :show-inheritance: diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.AssociatedPFCand.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.AssociatedPFCand.rst.txt new file mode 100644 index 000000000..011725bae --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.AssociatedPFCand.rst.txt @@ -0,0 +1,21 @@ +AssociatedPFCand +================ + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: AssociatedPFCand + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~AssociatedPFCand.collection_map + ~AssociatedPFCand.jet + ~AssociatedPFCand.pf + + .. rubric:: Attributes Documentation + + .. autoattribute:: collection_map + .. autoattribute:: jet + .. autoattribute:: pf diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.AssociatedSV.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.AssociatedSV.rst.txt new file mode 100644 index 000000000..8fd1e8d8a --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.AssociatedSV.rst.txt @@ -0,0 +1,21 @@ +AssociatedSV +============ + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: AssociatedSV + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~AssociatedSV.collection_map + ~AssociatedSV.jet + ~AssociatedSV.sv + + .. rubric:: Attributes Documentation + + .. autoattribute:: collection_map + .. autoattribute:: jet + .. autoattribute:: sv diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.Electron.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.Electron.rst.txt new file mode 100644 index 000000000..82548e4ab --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.Electron.rst.txt @@ -0,0 +1,39 @@ +Electron +======== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: Electron + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Electron.FAIL + ~Electron.LOOSE + ~Electron.MEDIUM + ~Electron.TIGHT + ~Electron.VETO + ~Electron.isLoose + ~Electron.isMedium + ~Electron.isTight + ~Electron.isVeto + ~Electron.matched_gen + ~Electron.matched_jet + ~Electron.matched_photon + + .. rubric:: Attributes Documentation + + .. autoattribute:: FAIL + .. autoattribute:: LOOSE + .. autoattribute:: MEDIUM + .. autoattribute:: TIGHT + .. autoattribute:: VETO + .. autoattribute:: isLoose + .. autoattribute:: isMedium + .. autoattribute:: isTight + .. autoattribute:: isVeto + .. autoattribute:: matched_gen + .. autoattribute:: matched_jet + .. autoattribute:: matched_photon diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.FatJet.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.FatJet.rst.txt new file mode 100644 index 000000000..45a96c668 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.FatJet.rst.txt @@ -0,0 +1,33 @@ +FatJet +====== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: FatJet + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~FatJet.LOOSE + ~FatJet.TIGHT + ~FatJet.TIGHTLEPVETO + ~FatJet.constituents + ~FatJet.isLoose + ~FatJet.isTight + ~FatJet.isTightLeptonVeto + ~FatJet.matched_gen + ~FatJet.subjets + + .. rubric:: Attributes Documentation + + .. autoattribute:: LOOSE + .. autoattribute:: TIGHT + .. autoattribute:: TIGHTLEPVETO + .. autoattribute:: constituents + .. autoattribute:: isLoose + .. autoattribute:: isTight + .. autoattribute:: isTightLeptonVeto + .. autoattribute:: matched_gen + .. autoattribute:: subjets diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.FsrPhoton.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.FsrPhoton.rst.txt new file mode 100644 index 000000000..38897283c --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.FsrPhoton.rst.txt @@ -0,0 +1,17 @@ +FsrPhoton +========= + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: FsrPhoton + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~FsrPhoton.matched_muon + + .. rubric:: Attributes Documentation + + .. autoattribute:: matched_muon diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.GenParticle.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.GenParticle.rst.txt new file mode 100644 index 000000000..62d969dd1 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.GenParticle.rst.txt @@ -0,0 +1,37 @@ +GenParticle +=========== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: GenParticle + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~GenParticle.FLAGS + ~GenParticle.children + ~GenParticle.distinctChildren + ~GenParticle.distinctChildrenDeep + ~GenParticle.distinctParent + ~GenParticle.parent + + .. rubric:: Methods Summary + + .. autosummary:: + + ~GenParticle.hasFlags + + .. rubric:: Attributes Documentation + + .. autoattribute:: FLAGS + .. autoattribute:: children + .. autoattribute:: distinctChildren + .. autoattribute:: distinctChildrenDeep + .. autoattribute:: distinctParent + .. autoattribute:: parent + + .. rubric:: Methods Documentation + + .. automethod:: hasFlags diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.GenVisTau.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.GenVisTau.rst.txt new file mode 100644 index 000000000..eee00f588 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.GenVisTau.rst.txt @@ -0,0 +1,17 @@ +GenVisTau +========= + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: GenVisTau + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~GenVisTau.parent + + .. rubric:: Attributes Documentation + + .. autoattribute:: parent diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.Jet.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.Jet.rst.txt new file mode 100644 index 000000000..cf8d132cd --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.Jet.rst.txt @@ -0,0 +1,35 @@ +Jet +=== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: Jet + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Jet.LOOSE + ~Jet.TIGHT + ~Jet.TIGHTLEPVETO + ~Jet.constituents + ~Jet.isLoose + ~Jet.isTight + ~Jet.isTightLeptonVeto + ~Jet.matched_electrons + ~Jet.matched_gen + ~Jet.matched_muons + + .. rubric:: Attributes Documentation + + .. autoattribute:: LOOSE + .. autoattribute:: TIGHT + .. autoattribute:: TIGHTLEPVETO + .. autoattribute:: constituents + .. autoattribute:: isLoose + .. autoattribute:: isTight + .. autoattribute:: isTightLeptonVeto + .. autoattribute:: matched_electrons + .. autoattribute:: matched_gen + .. autoattribute:: matched_muons diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.LowPtElectron.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.LowPtElectron.rst.txt new file mode 100644 index 000000000..43e656399 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.LowPtElectron.rst.txt @@ -0,0 +1,21 @@ +LowPtElectron +============= + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: LowPtElectron + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~LowPtElectron.matched_electron + ~LowPtElectron.matched_gen + ~LowPtElectron.matched_photon + + .. rubric:: Attributes Documentation + + .. autoattribute:: matched_electron + .. autoattribute:: matched_gen + .. autoattribute:: matched_photon diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.MissingET.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.MissingET.rst.txt new file mode 100644 index 000000000..1ea3476de --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.MissingET.rst.txt @@ -0,0 +1,17 @@ +MissingET +========= + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: MissingET + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~MissingET.r + + .. rubric:: Attributes Documentation + + .. autoattribute:: r diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.Muon.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.Muon.rst.txt new file mode 100644 index 000000000..66819f046 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.Muon.rst.txt @@ -0,0 +1,21 @@ +Muon +==== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: Muon + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Muon.matched_fsrPhoton + ~Muon.matched_gen + ~Muon.matched_jet + + .. rubric:: Attributes Documentation + + .. autoattribute:: matched_fsrPhoton + .. autoattribute:: matched_gen + .. autoattribute:: matched_jet diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.PFCand.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.PFCand.rst.txt new file mode 100644 index 000000000..101175d7b --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.PFCand.rst.txt @@ -0,0 +1,7 @@ +PFCand +====== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: PFCand + :show-inheritance: diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.Photon.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.Photon.rst.txt new file mode 100644 index 000000000..27d739414 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.Photon.rst.txt @@ -0,0 +1,39 @@ +Photon +====== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: Photon + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Photon.FAIL + ~Photon.LOOSE + ~Photon.MEDIUM + ~Photon.TIGHT + ~Photon.charge + ~Photon.isLoose + ~Photon.isMedium + ~Photon.isTight + ~Photon.mass + ~Photon.matched_electron + ~Photon.matched_gen + ~Photon.matched_jet + + .. rubric:: Attributes Documentation + + .. autoattribute:: FAIL + .. autoattribute:: LOOSE + .. autoattribute:: MEDIUM + .. autoattribute:: TIGHT + .. autoattribute:: charge + .. autoattribute:: isLoose + .. autoattribute:: isMedium + .. autoattribute:: isTight + .. autoattribute:: mass + .. autoattribute:: matched_electron + .. autoattribute:: matched_gen + .. autoattribute:: matched_jet diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection.rst.txt new file mode 100644 index 000000000..b01255ed6 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection.rst.txt @@ -0,0 +1,7 @@ +PtEtaPhiMCollection +=================== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: PtEtaPhiMCollection + :show-inheritance: diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.SecondaryVertex.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.SecondaryVertex.rst.txt new file mode 100644 index 000000000..c1736b7b8 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.SecondaryVertex.rst.txt @@ -0,0 +1,17 @@ +SecondaryVertex +=============== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: SecondaryVertex + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~SecondaryVertex.p4 + + .. rubric:: Attributes Documentation + + .. autoattribute:: p4 diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.Tau.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.Tau.rst.txt new file mode 100644 index 000000000..de413892f --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.Tau.rst.txt @@ -0,0 +1,19 @@ +Tau +=== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: Tau + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Tau.matched_gen + ~Tau.matched_jet + + .. rubric:: Attributes Documentation + + .. autoattribute:: matched_gen + .. autoattribute:: matched_jet diff --git a/_sources/api/coffea.nanoevents.methods.nanoaod.Vertex.rst.txt b/_sources/api/coffea.nanoevents.methods.nanoaod.Vertex.rst.txt new file mode 100644 index 000000000..45e3845db --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.nanoaod.Vertex.rst.txt @@ -0,0 +1,17 @@ +Vertex +====== + +.. currentmodule:: coffea.nanoevents.methods.nanoaod + +.. autoclass:: Vertex + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Vertex.pos + + .. rubric:: Attributes Documentation + + .. autoattribute:: pos diff --git a/_sources/api/coffea.nanoevents.methods.vector.LorentzVector.rst.txt b/_sources/api/coffea.nanoevents.methods.vector.LorentzVector.rst.txt new file mode 100644 index 000000000..5dd7f447d --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.vector.LorentzVector.rst.txt @@ -0,0 +1,57 @@ +LorentzVector +============= + +.. currentmodule:: coffea.nanoevents.methods.vector + +.. autoclass:: LorentzVector + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~LorentzVector.boostvec + ~LorentzVector.energy + ~LorentzVector.eta + ~LorentzVector.mass + ~LorentzVector.mass2 + ~LorentzVector.pvec + + .. rubric:: Methods Summary + + .. autosummary:: + + ~LorentzVector.absolute + ~LorentzVector.add + ~LorentzVector.boost + ~LorentzVector.delta_r + ~LorentzVector.delta_r2 + ~LorentzVector.metric_table + ~LorentzVector.multiply + ~LorentzVector.nearest + ~LorentzVector.negative + ~LorentzVector.subtract + ~LorentzVector.sum + + .. rubric:: Attributes Documentation + + .. autoattribute:: boostvec + .. autoattribute:: energy + .. autoattribute:: eta + .. autoattribute:: mass + .. autoattribute:: mass2 + .. autoattribute:: pvec + + .. rubric:: Methods Documentation + + .. automethod:: absolute + .. automethod:: add + .. automethod:: boost + .. automethod:: delta_r + .. automethod:: delta_r2 + .. automethod:: metric_table + .. automethod:: multiply + .. automethod:: nearest + .. automethod:: negative + .. automethod:: subtract + .. automethod:: sum diff --git a/_sources/api/coffea.nanoevents.methods.vector.PolarTwoVector.rst.txt b/_sources/api/coffea.nanoevents.methods.vector.PolarTwoVector.rst.txt new file mode 100644 index 000000000..9379108ce --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.vector.PolarTwoVector.rst.txt @@ -0,0 +1,37 @@ +PolarTwoVector +============== + +.. currentmodule:: coffea.nanoevents.methods.vector + +.. autoclass:: PolarTwoVector + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~PolarTwoVector.phi + ~PolarTwoVector.r + ~PolarTwoVector.r2 + ~PolarTwoVector.x + ~PolarTwoVector.y + + .. rubric:: Methods Summary + + .. autosummary:: + + ~PolarTwoVector.multiply + ~PolarTwoVector.negative + + .. rubric:: Attributes Documentation + + .. autoattribute:: phi + .. autoattribute:: r + .. autoattribute:: r2 + .. autoattribute:: x + .. autoattribute:: y + + .. rubric:: Methods Documentation + + .. automethod:: multiply + .. automethod:: negative diff --git a/_sources/api/coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.rst.txt b/_sources/api/coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.rst.txt new file mode 100644 index 000000000..700fe8fc3 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.rst.txt @@ -0,0 +1,49 @@ +PtEtaPhiELorentzVector +====================== + +.. currentmodule:: coffea.nanoevents.methods.vector + +.. autoclass:: PtEtaPhiELorentzVector + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~PtEtaPhiELorentzVector.E + ~PtEtaPhiELorentzVector.energy + ~PtEtaPhiELorentzVector.eta + ~PtEtaPhiELorentzVector.phi + ~PtEtaPhiELorentzVector.pt + ~PtEtaPhiELorentzVector.r + ~PtEtaPhiELorentzVector.rho + ~PtEtaPhiELorentzVector.rho2 + ~PtEtaPhiELorentzVector.t + ~PtEtaPhiELorentzVector.theta + ~PtEtaPhiELorentzVector.z + + .. rubric:: Methods Summary + + .. autosummary:: + + ~PtEtaPhiELorentzVector.multiply + ~PtEtaPhiELorentzVector.negative + + .. rubric:: Attributes Documentation + + .. autoattribute:: E + .. autoattribute:: energy + .. autoattribute:: eta + .. autoattribute:: phi + .. autoattribute:: pt + .. autoattribute:: r + .. autoattribute:: rho + .. autoattribute:: rho2 + .. autoattribute:: t + .. autoattribute:: theta + .. autoattribute:: z + + .. rubric:: Methods Documentation + + .. automethod:: multiply + .. automethod:: negative diff --git a/_sources/api/coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.rst.txt b/_sources/api/coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.rst.txt new file mode 100644 index 000000000..324235765 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.rst.txt @@ -0,0 +1,51 @@ +PtEtaPhiMLorentzVector +====================== + +.. currentmodule:: coffea.nanoevents.methods.vector + +.. autoclass:: PtEtaPhiMLorentzVector + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~PtEtaPhiMLorentzVector.E + ~PtEtaPhiMLorentzVector.eta + ~PtEtaPhiMLorentzVector.mass + ~PtEtaPhiMLorentzVector.mass2 + ~PtEtaPhiMLorentzVector.phi + ~PtEtaPhiMLorentzVector.pt + ~PtEtaPhiMLorentzVector.r + ~PtEtaPhiMLorentzVector.rho + ~PtEtaPhiMLorentzVector.rho2 + ~PtEtaPhiMLorentzVector.t + ~PtEtaPhiMLorentzVector.theta + ~PtEtaPhiMLorentzVector.z + + .. rubric:: Methods Summary + + .. autosummary:: + + ~PtEtaPhiMLorentzVector.multiply + ~PtEtaPhiMLorentzVector.negative + + .. rubric:: Attributes Documentation + + .. autoattribute:: E + .. autoattribute:: eta + .. autoattribute:: mass + .. autoattribute:: mass2 + .. autoattribute:: phi + .. autoattribute:: pt + .. autoattribute:: r + .. autoattribute:: rho + .. autoattribute:: rho2 + .. autoattribute:: t + .. autoattribute:: theta + .. autoattribute:: z + + .. rubric:: Methods Documentation + + .. automethod:: multiply + .. automethod:: negative diff --git a/_sources/api/coffea.nanoevents.methods.vector.SphericalThreeVector.rst.txt b/_sources/api/coffea.nanoevents.methods.vector.SphericalThreeVector.rst.txt new file mode 100644 index 000000000..692cb9db2 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.vector.SphericalThreeVector.rst.txt @@ -0,0 +1,39 @@ +SphericalThreeVector +==================== + +.. currentmodule:: coffea.nanoevents.methods.vector + +.. autoclass:: SphericalThreeVector + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~SphericalThreeVector.p + ~SphericalThreeVector.p2 + ~SphericalThreeVector.r + ~SphericalThreeVector.rho + ~SphericalThreeVector.theta + ~SphericalThreeVector.z + + .. rubric:: Methods Summary + + .. autosummary:: + + ~SphericalThreeVector.multiply + ~SphericalThreeVector.negative + + .. rubric:: Attributes Documentation + + .. autoattribute:: p + .. autoattribute:: p2 + .. autoattribute:: r + .. autoattribute:: rho + .. autoattribute:: theta + .. autoattribute:: z + + .. rubric:: Methods Documentation + + .. automethod:: multiply + .. automethod:: negative diff --git a/_sources/api/coffea.nanoevents.methods.vector.ThreeVector.rst.txt b/_sources/api/coffea.nanoevents.methods.vector.ThreeVector.rst.txt new file mode 100644 index 000000000..e68d16e66 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.vector.ThreeVector.rst.txt @@ -0,0 +1,53 @@ +ThreeVector +=========== + +.. currentmodule:: coffea.nanoevents.methods.vector + +.. autoclass:: ThreeVector + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~ThreeVector.p + ~ThreeVector.p2 + ~ThreeVector.pz + ~ThreeVector.rho + ~ThreeVector.rho2 + ~ThreeVector.theta + ~ThreeVector.unit + + .. rubric:: Methods Summary + + .. autosummary:: + + ~ThreeVector.absolute + ~ThreeVector.add + ~ThreeVector.cross + ~ThreeVector.dot + ~ThreeVector.multiply + ~ThreeVector.negative + ~ThreeVector.subtract + ~ThreeVector.sum + + .. rubric:: Attributes Documentation + + .. autoattribute:: p + .. autoattribute:: p2 + .. autoattribute:: pz + .. autoattribute:: rho + .. autoattribute:: rho2 + .. autoattribute:: theta + .. autoattribute:: unit + + .. rubric:: Methods Documentation + + .. automethod:: absolute + .. automethod:: add + .. automethod:: cross + .. automethod:: dot + .. automethod:: multiply + .. automethod:: negative + .. automethod:: subtract + .. automethod:: sum diff --git a/_sources/api/coffea.nanoevents.methods.vector.TwoVector.rst.txt b/_sources/api/coffea.nanoevents.methods.vector.TwoVector.rst.txt new file mode 100644 index 000000000..8db4ed315 --- /dev/null +++ b/_sources/api/coffea.nanoevents.methods.vector.TwoVector.rst.txt @@ -0,0 +1,57 @@ +TwoVector +========= + +.. currentmodule:: coffea.nanoevents.methods.vector + +.. autoclass:: TwoVector + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~TwoVector.phi + ~TwoVector.pt + ~TwoVector.pt2 + ~TwoVector.px + ~TwoVector.py + ~TwoVector.r + ~TwoVector.r2 + ~TwoVector.unit + + .. rubric:: Methods Summary + + .. autosummary:: + + ~TwoVector.absolute + ~TwoVector.add + ~TwoVector.delta_phi + ~TwoVector.divide + ~TwoVector.dot + ~TwoVector.multiply + ~TwoVector.negative + ~TwoVector.subtract + ~TwoVector.sum + + .. rubric:: Attributes Documentation + + .. autoattribute:: phi + .. autoattribute:: pt + .. autoattribute:: pt2 + .. autoattribute:: px + .. autoattribute:: py + .. autoattribute:: r + .. autoattribute:: r2 + .. autoattribute:: unit + + .. rubric:: Methods Documentation + + .. automethod:: absolute + .. automethod:: add + .. automethod:: delta_phi + .. automethod:: divide + .. automethod:: dot + .. automethod:: multiply + .. automethod:: negative + .. automethod:: subtract + .. automethod:: sum diff --git a/_sources/api/coffea.processor.AccumulatorABC.rst.txt b/_sources/api/coffea.processor.AccumulatorABC.rst.txt new file mode 100644 index 000000000..71c12b1f0 --- /dev/null +++ b/_sources/api/coffea.processor.AccumulatorABC.rst.txt @@ -0,0 +1,19 @@ +AccumulatorABC +============== + +.. currentmodule:: coffea.processor + +.. autoclass:: AccumulatorABC + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~AccumulatorABC.add + ~AccumulatorABC.identity + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: identity diff --git a/_sources/api/coffea.processor.DaskExecutor.rst.txt b/_sources/api/coffea.processor.DaskExecutor.rst.txt new file mode 100644 index 000000000..ba71e25e3 --- /dev/null +++ b/_sources/api/coffea.processor.DaskExecutor.rst.txt @@ -0,0 +1,39 @@ +DaskExecutor +============ + +.. currentmodule:: coffea.processor + +.. autoclass:: DaskExecutor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~DaskExecutor.client + ~DaskExecutor.heavy_input + ~DaskExecutor.priority + ~DaskExecutor.retries + ~DaskExecutor.treereduction + ~DaskExecutor.use_dataframes + ~DaskExecutor.worker_affinity + + .. rubric:: Methods Summary + + .. autosummary:: + + ~DaskExecutor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: client + .. autoattribute:: heavy_input + .. autoattribute:: priority + .. autoattribute:: retries + .. autoattribute:: treereduction + .. autoattribute:: use_dataframes + .. autoattribute:: worker_affinity + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.processor.FuturesExecutor.rst.txt b/_sources/api/coffea.processor.FuturesExecutor.rst.txt new file mode 100644 index 000000000..e4696c1bc --- /dev/null +++ b/_sources/api/coffea.processor.FuturesExecutor.rst.txt @@ -0,0 +1,35 @@ +FuturesExecutor +=============== + +.. currentmodule:: coffea.processor + +.. autoclass:: FuturesExecutor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~FuturesExecutor.mergepool + ~FuturesExecutor.merging + ~FuturesExecutor.recoverable + ~FuturesExecutor.tailtimeout + ~FuturesExecutor.workers + + .. rubric:: Methods Summary + + .. autosummary:: + + ~FuturesExecutor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: mergepool + .. autoattribute:: merging + .. autoattribute:: recoverable + .. autoattribute:: tailtimeout + .. autoattribute:: workers + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.processor.IterativeExecutor.rst.txt b/_sources/api/coffea.processor.IterativeExecutor.rst.txt new file mode 100644 index 000000000..e6683ee50 --- /dev/null +++ b/_sources/api/coffea.processor.IterativeExecutor.rst.txt @@ -0,0 +1,27 @@ +IterativeExecutor +================= + +.. currentmodule:: coffea.processor + +.. autoclass:: IterativeExecutor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~IterativeExecutor.workers + + .. rubric:: Methods Summary + + .. autosummary:: + + ~IterativeExecutor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: workers + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.processor.LazyDataFrame.rst.txt b/_sources/api/coffea.processor.LazyDataFrame.rst.txt new file mode 100644 index 000000000..0f739cbc2 --- /dev/null +++ b/_sources/api/coffea.processor.LazyDataFrame.rst.txt @@ -0,0 +1,35 @@ +LazyDataFrame +============= + +.. currentmodule:: coffea.processor + +.. autoclass:: LazyDataFrame + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~LazyDataFrame.available + ~LazyDataFrame.columns + ~LazyDataFrame.materialized + ~LazyDataFrame.metadata + ~LazyDataFrame.size + + .. rubric:: Methods Summary + + .. autosummary:: + + ~LazyDataFrame.preload + + .. rubric:: Attributes Documentation + + .. autoattribute:: available + .. autoattribute:: columns + .. autoattribute:: materialized + .. autoattribute:: metadata + .. autoattribute:: size + + .. rubric:: Methods Documentation + + .. automethod:: preload diff --git a/_sources/api/coffea.processor.NanoAODSchema.rst.txt b/_sources/api/coffea.processor.NanoAODSchema.rst.txt new file mode 100644 index 000000000..35bb1045f --- /dev/null +++ b/_sources/api/coffea.processor.NanoAODSchema.rst.txt @@ -0,0 +1,43 @@ +NanoAODSchema +============= + +.. currentmodule:: coffea.processor + +.. autoclass:: NanoAODSchema + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~NanoAODSchema.all_cross_references + ~NanoAODSchema.behavior + ~NanoAODSchema.mixins + ~NanoAODSchema.nested_index_items + ~NanoAODSchema.nested_items + ~NanoAODSchema.special_items + ~NanoAODSchema.warn_missing_crossrefs + + .. rubric:: Methods Summary + + .. autosummary:: + + ~NanoAODSchema.v5 + ~NanoAODSchema.v6 + ~NanoAODSchema.v7 + + .. rubric:: Attributes Documentation + + .. autoattribute:: all_cross_references + .. autoattribute:: behavior + .. autoattribute:: mixins + .. autoattribute:: nested_index_items + .. autoattribute:: nested_items + .. autoattribute:: special_items + .. autoattribute:: warn_missing_crossrefs + + .. rubric:: Methods Documentation + + .. automethod:: v5 + .. automethod:: v6 + .. automethod:: v7 diff --git a/_sources/api/coffea.processor.PackedSelection.rst.txt b/_sources/api/coffea.processor.PackedSelection.rst.txt new file mode 100644 index 000000000..4fa2e4d06 --- /dev/null +++ b/_sources/api/coffea.processor.PackedSelection.rst.txt @@ -0,0 +1,31 @@ +PackedSelection +=============== + +.. currentmodule:: coffea.processor + +.. autoclass:: PackedSelection + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~PackedSelection.names + + .. rubric:: Methods Summary + + .. autosummary:: + + ~PackedSelection.add + ~PackedSelection.all + ~PackedSelection.require + + .. rubric:: Attributes Documentation + + .. autoattribute:: names + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: all + .. automethod:: require diff --git a/_sources/api/coffea.processor.ParslExecutor.rst.txt b/_sources/api/coffea.processor.ParslExecutor.rst.txt new file mode 100644 index 000000000..c0f66b9df --- /dev/null +++ b/_sources/api/coffea.processor.ParslExecutor.rst.txt @@ -0,0 +1,37 @@ +ParslExecutor +============= + +.. currentmodule:: coffea.processor + +.. autoclass:: ParslExecutor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~ParslExecutor.config + ~ParslExecutor.jobs_executors + ~ParslExecutor.merges_executors + ~ParslExecutor.merging + ~ParslExecutor.recoverable + ~ParslExecutor.tailtimeout + + .. rubric:: Methods Summary + + .. autosummary:: + + ~ParslExecutor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: config + .. autoattribute:: jobs_executors + .. autoattribute:: merges_executors + .. autoattribute:: merging + .. autoattribute:: recoverable + .. autoattribute:: tailtimeout + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.processor.ProcessorABC.rst.txt b/_sources/api/coffea.processor.ProcessorABC.rst.txt new file mode 100644 index 000000000..7e81f0574 --- /dev/null +++ b/_sources/api/coffea.processor.ProcessorABC.rst.txt @@ -0,0 +1,19 @@ +ProcessorABC +============ + +.. currentmodule:: coffea.processor + +.. autoclass:: ProcessorABC + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~ProcessorABC.postprocess + ~ProcessorABC.process + + .. rubric:: Methods Documentation + + .. automethod:: postprocess + .. automethod:: process diff --git a/_sources/api/coffea.processor.Runner.rst.txt b/_sources/api/coffea.processor.Runner.rst.txt new file mode 100644 index 000000000..86f726891 --- /dev/null +++ b/_sources/api/coffea.processor.Runner.rst.txt @@ -0,0 +1,69 @@ +Runner +====== + +.. currentmodule:: coffea.processor + +.. autoclass:: Runner + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Runner.align_clusters + ~Runner.cachestrategy + ~Runner.chunksize + ~Runner.dynamic_chunksize + ~Runner.format + ~Runner.maxchunks + ~Runner.metadata_cache + ~Runner.mmap + ~Runner.pre_executor + ~Runner.processor_compression + ~Runner.retries + ~Runner.savemetrics + ~Runner.skipbadfiles + ~Runner.use_dataframes + ~Runner.use_skyhook + ~Runner.xrootdtimeout + + .. rubric:: Methods Summary + + .. autosummary:: + + ~Runner.__call__ + ~Runner.automatic_retries + ~Runner.get_cache + ~Runner.metadata_fetcher + ~Runner.preprocess + ~Runner.read_coffea_config + ~Runner.run + + .. rubric:: Attributes Documentation + + .. autoattribute:: align_clusters + .. autoattribute:: cachestrategy + .. autoattribute:: chunksize + .. autoattribute:: dynamic_chunksize + .. autoattribute:: format + .. autoattribute:: maxchunks + .. autoattribute:: metadata_cache + .. autoattribute:: mmap + .. autoattribute:: pre_executor + .. autoattribute:: processor_compression + .. autoattribute:: retries + .. autoattribute:: savemetrics + .. autoattribute:: skipbadfiles + .. autoattribute:: use_dataframes + .. autoattribute:: use_skyhook + .. autoattribute:: xrootdtimeout + + .. rubric:: Methods Documentation + + .. automethod:: __call__ + .. automethod:: automatic_retries + .. automethod:: get_cache + .. automethod:: metadata_fetcher + .. automethod:: preprocess + .. automethod:: read_coffea_config + .. automethod:: run diff --git a/_sources/api/coffea.processor.TreeMakerSchema.rst.txt b/_sources/api/coffea.processor.TreeMakerSchema.rst.txt new file mode 100644 index 000000000..267f1b8bb --- /dev/null +++ b/_sources/api/coffea.processor.TreeMakerSchema.rst.txt @@ -0,0 +1,27 @@ +TreeMakerSchema +=============== + +.. currentmodule:: coffea.processor + +.. autoclass:: TreeMakerSchema + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~TreeMakerSchema.behavior + + .. rubric:: Methods Summary + + .. autosummary:: + + ~TreeMakerSchema.uproot_writeable + + .. rubric:: Attributes Documentation + + .. autoattribute:: behavior + + .. rubric:: Methods Documentation + + .. automethod:: uproot_writeable diff --git a/_sources/api/coffea.processor.Weights.rst.txt b/_sources/api/coffea.processor.Weights.rst.txt new file mode 100644 index 000000000..947b59e2f --- /dev/null +++ b/_sources/api/coffea.processor.Weights.rst.txt @@ -0,0 +1,31 @@ +Weights +======= + +.. currentmodule:: coffea.processor + +.. autoclass:: Weights + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~Weights.variations + + .. rubric:: Methods Summary + + .. autosummary:: + + ~Weights.add + ~Weights.partial_weight + ~Weights.weight + + .. rubric:: Attributes Documentation + + .. autoattribute:: variations + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: partial_weight + .. automethod:: weight diff --git a/_sources/api/coffea.processor.WorkQueueExecutor.rst.txt b/_sources/api/coffea.processor.WorkQueueExecutor.rst.txt new file mode 100644 index 000000000..6d0ace24c --- /dev/null +++ b/_sources/api/coffea.processor.WorkQueueExecutor.rst.txt @@ -0,0 +1,93 @@ +WorkQueueExecutor +================= + +.. currentmodule:: coffea.processor + +.. autoclass:: WorkQueueExecutor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~WorkQueueExecutor.bar_format + ~WorkQueueExecutor.chunks_accum_in_mem + ~WorkQueueExecutor.chunks_per_accum + ~WorkQueueExecutor.chunksize + ~WorkQueueExecutor.compression + ~WorkQueueExecutor.cores + ~WorkQueueExecutor.custom_init + ~WorkQueueExecutor.debug_log + ~WorkQueueExecutor.disk + ~WorkQueueExecutor.dynamic_chunksize + ~WorkQueueExecutor.environment_file + ~WorkQueueExecutor.events_total + ~WorkQueueExecutor.fast_terminate_workers + ~WorkQueueExecutor.filepath + ~WorkQueueExecutor.gpus + ~WorkQueueExecutor.manager_name + ~WorkQueueExecutor.master_name + ~WorkQueueExecutor.memory + ~WorkQueueExecutor.password_file + ~WorkQueueExecutor.port + ~WorkQueueExecutor.print_stdout + ~WorkQueueExecutor.resource_monitor + ~WorkQueueExecutor.resources_mode + ~WorkQueueExecutor.retries + ~WorkQueueExecutor.split_on_exhaustion + ~WorkQueueExecutor.ssl + ~WorkQueueExecutor.stats_log + ~WorkQueueExecutor.status_display_interval + ~WorkQueueExecutor.tasks_accum_log + ~WorkQueueExecutor.transactions_log + ~WorkQueueExecutor.treereduction + ~WorkQueueExecutor.verbose + ~WorkQueueExecutor.wrapper + ~WorkQueueExecutor.x509_proxy + + .. rubric:: Methods Summary + + .. autosummary:: + + ~WorkQueueExecutor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: bar_format + .. autoattribute:: chunks_accum_in_mem + .. autoattribute:: chunks_per_accum + .. autoattribute:: chunksize + .. autoattribute:: compression + .. autoattribute:: cores + .. autoattribute:: custom_init + .. autoattribute:: debug_log + .. autoattribute:: disk + .. autoattribute:: dynamic_chunksize + .. autoattribute:: environment_file + .. autoattribute:: events_total + .. autoattribute:: fast_terminate_workers + .. autoattribute:: filepath + .. autoattribute:: gpus + .. autoattribute:: manager_name + .. autoattribute:: master_name + .. autoattribute:: memory + .. autoattribute:: password_file + .. autoattribute:: port + .. autoattribute:: print_stdout + .. autoattribute:: resource_monitor + .. autoattribute:: resources_mode + .. autoattribute:: retries + .. autoattribute:: split_on_exhaustion + .. autoattribute:: ssl + .. autoattribute:: stats_log + .. autoattribute:: status_display_interval + .. autoattribute:: tasks_accum_log + .. autoattribute:: transactions_log + .. autoattribute:: treereduction + .. autoattribute:: verbose + .. autoattribute:: wrapper + .. autoattribute:: x509_proxy + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.processor.accumulate.rst.txt b/_sources/api/coffea.processor.accumulate.rst.txt new file mode 100644 index 000000000..8e3f2ecf9 --- /dev/null +++ b/_sources/api/coffea.processor.accumulate.rst.txt @@ -0,0 +1,6 @@ +accumulate +========== + +.. currentmodule:: coffea.processor + +.. autofunction:: accumulate diff --git a/_sources/api/coffea.processor.column_accumulator.rst.txt b/_sources/api/coffea.processor.column_accumulator.rst.txt new file mode 100644 index 000000000..e90d42201 --- /dev/null +++ b/_sources/api/coffea.processor.column_accumulator.rst.txt @@ -0,0 +1,29 @@ +column_accumulator +================== + +.. currentmodule:: coffea.processor + +.. autoclass:: column_accumulator + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~column_accumulator.value + + .. rubric:: Methods Summary + + .. autosummary:: + + ~column_accumulator.add + ~column_accumulator.identity + + .. rubric:: Attributes Documentation + + .. autoattribute:: value + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: identity diff --git a/_sources/api/coffea.processor.dask_executor.rst.txt b/_sources/api/coffea.processor.dask_executor.rst.txt new file mode 100644 index 000000000..0afc56e2f --- /dev/null +++ b/_sources/api/coffea.processor.dask_executor.rst.txt @@ -0,0 +1,39 @@ +dask_executor +============= + +.. currentmodule:: coffea.processor + +.. autoclass:: dask_executor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~dask_executor.client + ~dask_executor.heavy_input + ~dask_executor.priority + ~dask_executor.retries + ~dask_executor.treereduction + ~dask_executor.use_dataframes + ~dask_executor.worker_affinity + + .. rubric:: Methods Summary + + .. autosummary:: + + ~dask_executor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: client + .. autoattribute:: heavy_input + .. autoattribute:: priority + .. autoattribute:: retries + .. autoattribute:: treereduction + .. autoattribute:: use_dataframes + .. autoattribute:: worker_affinity + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.processor.defaultdict_accumulator.rst.txt b/_sources/api/coffea.processor.defaultdict_accumulator.rst.txt new file mode 100644 index 000000000..bbade65e3 --- /dev/null +++ b/_sources/api/coffea.processor.defaultdict_accumulator.rst.txt @@ -0,0 +1,19 @@ +defaultdict_accumulator +======================= + +.. currentmodule:: coffea.processor + +.. autoclass:: defaultdict_accumulator + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~defaultdict_accumulator.add + ~defaultdict_accumulator.identity + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: identity diff --git a/_sources/api/coffea.processor.dict_accumulator.rst.txt b/_sources/api/coffea.processor.dict_accumulator.rst.txt new file mode 100644 index 000000000..35882d480 --- /dev/null +++ b/_sources/api/coffea.processor.dict_accumulator.rst.txt @@ -0,0 +1,19 @@ +dict_accumulator +================ + +.. currentmodule:: coffea.processor + +.. autoclass:: dict_accumulator + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~dict_accumulator.add + ~dict_accumulator.identity + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: identity diff --git a/_sources/api/coffea.processor.futures_executor.rst.txt b/_sources/api/coffea.processor.futures_executor.rst.txt new file mode 100644 index 000000000..637155eb6 --- /dev/null +++ b/_sources/api/coffea.processor.futures_executor.rst.txt @@ -0,0 +1,35 @@ +futures_executor +================ + +.. currentmodule:: coffea.processor + +.. autoclass:: futures_executor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~futures_executor.mergepool + ~futures_executor.merging + ~futures_executor.recoverable + ~futures_executor.tailtimeout + ~futures_executor.workers + + .. rubric:: Methods Summary + + .. autosummary:: + + ~futures_executor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: mergepool + .. autoattribute:: merging + .. autoattribute:: recoverable + .. autoattribute:: tailtimeout + .. autoattribute:: workers + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.processor.iterative_executor.rst.txt b/_sources/api/coffea.processor.iterative_executor.rst.txt new file mode 100644 index 000000000..7f323c243 --- /dev/null +++ b/_sources/api/coffea.processor.iterative_executor.rst.txt @@ -0,0 +1,27 @@ +iterative_executor +================== + +.. currentmodule:: coffea.processor + +.. autoclass:: iterative_executor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~iterative_executor.workers + + .. rubric:: Methods Summary + + .. autosummary:: + + ~iterative_executor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: workers + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.processor.list_accumulator.rst.txt b/_sources/api/coffea.processor.list_accumulator.rst.txt new file mode 100644 index 000000000..b4b66bdf8 --- /dev/null +++ b/_sources/api/coffea.processor.list_accumulator.rst.txt @@ -0,0 +1,19 @@ +list_accumulator +================ + +.. currentmodule:: coffea.processor + +.. autoclass:: list_accumulator + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~list_accumulator.add + ~list_accumulator.identity + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: identity diff --git a/_sources/api/coffea.processor.parsl_executor.rst.txt b/_sources/api/coffea.processor.parsl_executor.rst.txt new file mode 100644 index 000000000..04994bfa1 --- /dev/null +++ b/_sources/api/coffea.processor.parsl_executor.rst.txt @@ -0,0 +1,37 @@ +parsl_executor +============== + +.. currentmodule:: coffea.processor + +.. autoclass:: parsl_executor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~parsl_executor.config + ~parsl_executor.jobs_executors + ~parsl_executor.merges_executors + ~parsl_executor.merging + ~parsl_executor.recoverable + ~parsl_executor.tailtimeout + + .. rubric:: Methods Summary + + .. autosummary:: + + ~parsl_executor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: config + .. autoattribute:: jobs_executors + .. autoattribute:: merges_executors + .. autoattribute:: merging + .. autoattribute:: recoverable + .. autoattribute:: tailtimeout + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.processor.run_spark_job.rst.txt b/_sources/api/coffea.processor.run_spark_job.rst.txt new file mode 100644 index 000000000..45b8eff7f --- /dev/null +++ b/_sources/api/coffea.processor.run_spark_job.rst.txt @@ -0,0 +1,6 @@ +run_spark_job +============= + +.. currentmodule:: coffea.processor + +.. autofunction:: run_spark_job diff --git a/_sources/api/coffea.processor.set_accumulator.rst.txt b/_sources/api/coffea.processor.set_accumulator.rst.txt new file mode 100644 index 000000000..233d2bfef --- /dev/null +++ b/_sources/api/coffea.processor.set_accumulator.rst.txt @@ -0,0 +1,19 @@ +set_accumulator +=============== + +.. currentmodule:: coffea.processor + +.. autoclass:: set_accumulator + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~set_accumulator.add + ~set_accumulator.identity + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: identity diff --git a/_sources/api/coffea.processor.value_accumulator.rst.txt b/_sources/api/coffea.processor.value_accumulator.rst.txt new file mode 100644 index 000000000..b24170068 --- /dev/null +++ b/_sources/api/coffea.processor.value_accumulator.rst.txt @@ -0,0 +1,19 @@ +value_accumulator +================= + +.. currentmodule:: coffea.processor + +.. autoclass:: value_accumulator + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~value_accumulator.add + ~value_accumulator.identity + + .. rubric:: Methods Documentation + + .. automethod:: add + .. automethod:: identity diff --git a/_sources/api/coffea.processor.work_queue_executor.rst.txt b/_sources/api/coffea.processor.work_queue_executor.rst.txt new file mode 100644 index 000000000..479e02e40 --- /dev/null +++ b/_sources/api/coffea.processor.work_queue_executor.rst.txt @@ -0,0 +1,93 @@ +work_queue_executor +=================== + +.. currentmodule:: coffea.processor + +.. autoclass:: work_queue_executor + :show-inheritance: + + .. rubric:: Attributes Summary + + .. autosummary:: + + ~work_queue_executor.bar_format + ~work_queue_executor.chunks_accum_in_mem + ~work_queue_executor.chunks_per_accum + ~work_queue_executor.chunksize + ~work_queue_executor.compression + ~work_queue_executor.cores + ~work_queue_executor.custom_init + ~work_queue_executor.debug_log + ~work_queue_executor.disk + ~work_queue_executor.dynamic_chunksize + ~work_queue_executor.environment_file + ~work_queue_executor.events_total + ~work_queue_executor.fast_terminate_workers + ~work_queue_executor.filepath + ~work_queue_executor.gpus + ~work_queue_executor.manager_name + ~work_queue_executor.master_name + ~work_queue_executor.memory + ~work_queue_executor.password_file + ~work_queue_executor.port + ~work_queue_executor.print_stdout + ~work_queue_executor.resource_monitor + ~work_queue_executor.resources_mode + ~work_queue_executor.retries + ~work_queue_executor.split_on_exhaustion + ~work_queue_executor.ssl + ~work_queue_executor.stats_log + ~work_queue_executor.status_display_interval + ~work_queue_executor.tasks_accum_log + ~work_queue_executor.transactions_log + ~work_queue_executor.treereduction + ~work_queue_executor.verbose + ~work_queue_executor.wrapper + ~work_queue_executor.x509_proxy + + .. rubric:: Methods Summary + + .. autosummary:: + + ~work_queue_executor.__call__ + + .. rubric:: Attributes Documentation + + .. autoattribute:: bar_format + .. autoattribute:: chunks_accum_in_mem + .. autoattribute:: chunks_per_accum + .. autoattribute:: chunksize + .. autoattribute:: compression + .. autoattribute:: cores + .. autoattribute:: custom_init + .. autoattribute:: debug_log + .. autoattribute:: disk + .. autoattribute:: dynamic_chunksize + .. autoattribute:: environment_file + .. autoattribute:: events_total + .. autoattribute:: fast_terminate_workers + .. autoattribute:: filepath + .. autoattribute:: gpus + .. autoattribute:: manager_name + .. autoattribute:: master_name + .. autoattribute:: memory + .. autoattribute:: password_file + .. autoattribute:: port + .. autoattribute:: print_stdout + .. autoattribute:: resource_monitor + .. autoattribute:: resources_mode + .. autoattribute:: retries + .. autoattribute:: split_on_exhaustion + .. autoattribute:: ssl + .. autoattribute:: stats_log + .. autoattribute:: status_display_interval + .. autoattribute:: tasks_accum_log + .. autoattribute:: transactions_log + .. autoattribute:: treereduction + .. autoattribute:: verbose + .. autoattribute:: wrapper + .. autoattribute:: x509_proxy + + .. rubric:: Methods Documentation + + .. automethod:: __call__ diff --git a/_sources/api/coffea.util.SpeedColumn.rst.txt b/_sources/api/coffea.util.SpeedColumn.rst.txt new file mode 100644 index 000000000..31d6100dc --- /dev/null +++ b/_sources/api/coffea.util.SpeedColumn.rst.txt @@ -0,0 +1,17 @@ +SpeedColumn +=========== + +.. currentmodule:: coffea.util + +.. autoclass:: SpeedColumn + :show-inheritance: + + .. rubric:: Methods Summary + + .. autosummary:: + + ~SpeedColumn.render + + .. rubric:: Methods Documentation + + .. automethod:: render diff --git a/_sources/api/coffea.util.awkward_rewrap.rst.txt b/_sources/api/coffea.util.awkward_rewrap.rst.txt new file mode 100644 index 000000000..118b2bfd4 --- /dev/null +++ b/_sources/api/coffea.util.awkward_rewrap.rst.txt @@ -0,0 +1,6 @@ +awkward_rewrap +============== + +.. currentmodule:: coffea.util + +.. autofunction:: awkward_rewrap diff --git a/_sources/api/coffea.util.deprecate.rst.txt b/_sources/api/coffea.util.deprecate.rst.txt new file mode 100644 index 000000000..efcde2076 --- /dev/null +++ b/_sources/api/coffea.util.deprecate.rst.txt @@ -0,0 +1,6 @@ +deprecate +========= + +.. currentmodule:: coffea.util + +.. autofunction:: deprecate diff --git a/_sources/api/coffea.util.load.rst.txt b/_sources/api/coffea.util.load.rst.txt new file mode 100644 index 000000000..fd16129da --- /dev/null +++ b/_sources/api/coffea.util.load.rst.txt @@ -0,0 +1,6 @@ +load +==== + +.. currentmodule:: coffea.util + +.. autofunction:: load diff --git a/_sources/api/coffea.util.rewrap_recordarray.rst.txt b/_sources/api/coffea.util.rewrap_recordarray.rst.txt new file mode 100644 index 000000000..48f56c5b2 --- /dev/null +++ b/_sources/api/coffea.util.rewrap_recordarray.rst.txt @@ -0,0 +1,6 @@ +rewrap_recordarray +================== + +.. currentmodule:: coffea.util + +.. autofunction:: rewrap_recordarray diff --git a/_sources/api/coffea.util.rich_bar.rst.txt b/_sources/api/coffea.util.rich_bar.rst.txt new file mode 100644 index 000000000..2c9de600a --- /dev/null +++ b/_sources/api/coffea.util.rich_bar.rst.txt @@ -0,0 +1,6 @@ +rich_bar +======== + +.. currentmodule:: coffea.util + +.. autofunction:: rich_bar diff --git a/_sources/api/coffea.util.save.rst.txt b/_sources/api/coffea.util.save.rst.txt new file mode 100644 index 000000000..a16d5856e --- /dev/null +++ b/_sources/api/coffea.util.save.rst.txt @@ -0,0 +1,6 @@ +save +==== + +.. currentmodule:: coffea.util + +.. autofunction:: save diff --git a/_sources/concepts.rst.txt b/_sources/concepts.rst.txt new file mode 100644 index 000000000..aaaed2e5d --- /dev/null +++ b/_sources/concepts.rst.txt @@ -0,0 +1,70 @@ +Coffea concepts +=============== + +This page explains concepts and terminology used within the coffea package. +It is intended to provide a high-level overview, while details can be found in other sections of the documentation. + +.. _def-columnar-analysis: + +Columnar analysis +----------------- +Columnar analysis is a paradigm that describes the way the user writes the analysis application that is best described +in contrast to the the traditional paradigm in high-energy particle physics (HEP) of using an event loop. In an event loop, the analysis operates row-wise +on the input data (in HEP, one row usually corresponds to one reconstructed particle collision event.) Each row +is a structure containing several fields, such as the properties of the visible outgoing particles +that were reconstructed in a collision event. The analysis code manipulates this structure to either output derived +quantities or summary statistics in the form of histograms. In contrast, columnar analysis operates on individual +columns of data spanning a *chunk* (partition, batch) of rows using `array programming `_ +primitives in turn, to compute derived quantities and summary statistics. Array programming is widely used within +the `scientific python ecosystem `_, supported by the `numpy `_ library. +However, although the existing scientific python stack is fully capable of analyzing rectangular arrays (i.e. +no variable-length array dimensions), HEP data is very irregular, and manipulating it can become awkward without +first generalizing array structure a bit. The `awkward `_ package does this, +extending array programming capabilities to the complexity of HEP data. + +.. image:: images/columnar.png + :width: 70 % + :align: center + +.. _def-processor: + +Coffea processor +---------------- +In almost all HEP analyses, each row corresponds to an independent event, and it is exceptionally rare +to need to compute inter-row derived quantites. Due to this, horizontal scale-out is almost trivial: +each chunk of rows can be operated on independently. Further, if the output of an analysis is restricted +to reducible accumulators such as histograms (abstracted by `AccumulatorABC`), then outputs can even be merged via tree reduction. +The `ProcessorABC` class is an abstraction to encapsulate analysis code so that it can be easily scaled out, leaving +the delivery of input columns and reduction of output accumulators to the coffea framework. + +.. _def-scale-out: + +Scale-out +--------- +Often, the computation requirements of a HEP data analysis exceed the resources of a single thread of execution. +To facilitate parallelization and allow the user to access more compute resources, coffea employs various *executors* +to ease the transition between a local analysis on a small set of test data to a full-scale analysis. +The executors roughly fall into two categories: local and distributed. + +.. _def-local-executors: + +Local executors +^^^^^^^^^^^^^^^ +Currently, two local executors exist: `iterative_executor` and `futures_executor`. +The iterative executor simply processes each chunk of an input dataset in turn, using the current +python thread. The futures executor employs python `multiprocessing` to spawn multiple python processes +that process chunks in parallel on the machine. Processes are used rather than threads to avoid +performance limitations due to the CPython `global interpreter lock `_. + +.. _def-distributed-executors: + +Distributed executors +^^^^^^^^^^^^^^^^^^^^^ +Currently, coffea supports four types of distributed executors: + + - the `parsl `_ distributed executor, accessed via `parsl_executor`, + - the `dask `_ distributed executor, accessed via `dask_executor`, + - the Apache `Spark `_ distributed executor, accessed via `run_spark_job`, + - and the :ref:`intro-coffea-wq` distributed executor, accessed via `work_queue_executor`. + +These executors use their respective underlying libraries to distribute processing tasks over multiple machines. diff --git a/_sources/examples.rst.txt b/_sources/examples.rst.txt new file mode 100644 index 000000000..b168a91df --- /dev/null +++ b/_sources/examples.rst.txt @@ -0,0 +1,18 @@ +Coffea by Example +================= + +The following pages are rendered jupyter notebooks that provide an overview and example usage of Coffea features. +Each notebook builds on the previous one so it is recommended to go through them in order. + +.. toctree:: + + notebooks/nanoevents.ipynb + notebooks/applying_corrections.ipynb + notebooks/accumulators.ipynb + notebooks/processor.ipynb + +A few coffea features are now deprecated in favor of dedicated libraries: + +.. toctree:: + + notebooks/histograms.ipynb diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 000000000..711c356c1 --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,20 @@ +.. coffea documentation master file, created by + sphinx-quickstart on Fri Jun 7 09:23:02 2019. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +.. include:: ../../README.rst + +.. toctree:: + installation + examples + concepts + reference +.. + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/_sources/installation.rst.txt b/_sources/installation.rst.txt new file mode 100644 index 000000000..eb44c6725 --- /dev/null +++ b/_sources/installation.rst.txt @@ -0,0 +1,221 @@ +.. _installing-coffea: + +Installing coffea +================= + +Quick start +----------- +To try coffea now, without installing anything, you can experiment with our +`hosted tutorial notebooks `_. + +Platform support +---------------- +Coffea is a python package distributed via `PyPI `_. A python installation is required to use coffea. +Python version 3.6 or newer is required. + +All functional features in each supported python version are routinely tested. +You can see the python version you have installed by typing the following at the command prompt: + +>>> python --version + +or, in some cases, if both python 2 and 3 are available, you can find the python 3 version via: + +>>> python3 --version + +coffea core functionality is routinely tested on Windows, Linux and MacOS. +All :ref:`def-local-executors` are tested against all three platforms, +however the :ref:`def-distributed-executors` are not routinely tested on Windows. + +Coffea starts from v0.5.0 in the PyPI repository since before v0.5.0 it was hosted as `fnal-column-analysis-tools `_. If you are still using fnal-column-analysis-tools, please move to `coffea `_! + +Install coffea +-------------- +To install coffea, there are several mostly-equivalent options: + + - install coffea system-wide using ``pip install coffea``; + - if you do not have administrator permissions, install as local user with ``pip install --user coffea``; + - if you prefer to not place coffea in your global environment, you can set up a `Virtual environment`_; + - if you use `Conda `_, simply ``conda install coffea``; + - or, if you like to use containers, see `Pre-built images`_ below. + +To update a previously installed coffea to a newer version, use: ``pip install --upgrade coffea`` +Although not required, it is recommended to also `install Jupyter `_, as it provides a more interactive development environment. +The installation procedure is essentially identical as above: ``pip install jupyter``. (If you use conda, ``conda install jupyter`` is a better option.) + +In rare cases, you may find that the ``pip`` executable in your path does not correspond to the same python installation as the ``python`` executable. This is a sign of a broken python environment. However, this can be bypassed by using the syntax ``python -m pip ...`` in place of ``pip ...``. + +Install optional dependencies +----------------------------- +Coffea supports several optional components that require additional package installations. +In particular, all of the :ref:`def-distributed-executors` require additional packages. +The necessary dependencies can be installed easily via ``pip`` using the setuptools `extras `_ facility: + + - Apache `Spark `_ distributed executor: ``pip install coffea[spark]`` + - `parsl `_ distributed executor: ``pip install coffea[parsl]`` + - `dask `_ distributed executor: ``pip install coffea[dask]`` + - `Work Queue `_ distributed executor: see :ref:`intro-coffea-wq` for installation instructions + +Multiple extras can be installed together via, e.g. ``pip install coffea[dask,spark]`` + +Virtual environment +------------------- +Virtual environments are a good way to isolate python environments, and ensure no hidden dependencies. +You can find more information at https://docs.python.org/3/library/venv.html + +.. code-block:: bash + + python -m venv my_env + source my_env/bin/activate + pip install coffea + +Pre-built images +---------------- +A complete coffea + scientific python environment is available as a docker image: + +.. code-block:: bash + + docker run -it --name docker-coffea-base coffeateam/coffea-base + +More information is available at https://github.com/CoffeaTeam/docker-coffea-base#readme +Additionally there is an image with dask dependencies (including dask-jobqueue): + +.. code-block:: bash + + docker run -it --name docker-coffea-dask coffeateam/coffea-dask + +With corresponding repo at https://github.com/CoffeaTeam/docker-coffea-dask#readme + +If you use singularity, there are preconverted images available via the unpacked.cern.ch service. For example, you can start a shell with: + +.. code-block:: bash + + singularity shell -B ${PWD}:/work /cvmfs/unpacked.cern.ch/registry.hub.docker.com/coffeateam/coffea-dask:latest + +Install via cvmfs +----------------- +Although the local installation can work anywhere, if the base environment does not already have most of the coffea dependencies, then the user-local package directory can become quite bloated. +An option to avoid this bloat is to use a base python environment provided via `CERN LCG `_, which is available on any system that has the `cvmfs `_ directory ``/cvmfs/sft.cern.ch/`` mounted. +Simply source a LCG release (shown here: 98python3) and install: + +.. code-block:: bash + + # check your platform: CC7 shown below, for SL6 it would be "x86_64-slc6-gcc8-opt" + source /cvmfs/sft.cern.ch/lcg/views/LCG_98python3/x86_64-centos7-gcc9-opt/setup.sh # or .csh, etc. + pip install --user coffea + +This method can be fragile, since the LCG-distributed packages may conflict with the coffea dependencies. In general it is better to define your own environment or use an image. + +Creating a portable virtual environment +--------------------------------------- +In some instances, it may be useful to have a self-contained environment that can be relocated. +One use case is for users of coffea that do not have access to a distributed compute cluster that is compatible with +one of the coffea distributed executors. Here, a fallback solution can be found by creating traditional batch jobs (e.g. condor) +which then use coffea local executors, possibly multi-threaded. In this case, often the user-local python package directory +is not available from batch workers, so a portable python enviroment needs to be created. +Annoyingly, python virtual environments are not portable by default due to several hardcoded paths in specific locations, however +there are two workarounds presented below. In both cases, we make a virtual environment that starts from a non-system base +python environment to lower the amount of needed installations in the virtual environment. One can always start a venv from scratch, +but the number of coffea dependencies makes the installation rather large, up to a few hundred MB. + + +Container-based +~~~~~~~~~~~~~~~ +If we start from one of the singularity containers from the `Pre-built images`_ section, we don't have to install nearly as much +software in our virtual environment, letting the container image take care of the majority of the codebase. For example, the following +code starts from the ``coffea-dask`` image and adds a special python module that is not included in the base image: + +.. code-block:: bash + + singularity shell -B ${PWD}:/srv /cvmfs/unpacked.cern.ch/registry.hub.docker.com/coffeateam/coffea-dask:latest + cd /srv + python -m venv --without-pip --system-site-packages myenv + source myenv/bin/activate + python -m pip install --ignore-installed h5py + +This creates a virtual environmennt ``myenv`` and a directory with the same name where the extra python module ``h5py`` will be +installed. At this point, the terminal prompt will look like ``(myenv) Singularity>``, indicating you are inside a singularity +image and have ``myenv`` activated. Next time you log in, only lines 1, 2, and 4 need to be re-executed. + +If using HTCondor for job submission, you can create a tarball of the virtual environment directory and then submit condor +jobs using the ``+SingularityImage`` `HTCondor option `_. +Note that this option is not enabled by default in HTCondor installations, so you may need to talk to your site administrator to be +able to use this option. You will also need to create a small wrapper script to re-source the environment to have the job use the +same environment as your interactive container. +A complete example that runs at FNAL LPC is shown `in this gist `_. + + +LCG-based +~~~~~~~~~ +There are not many locations to edit to make a venv portable, and some sed hacks can save the day. +Here is an example of a bash script that installs coffea on top of the LCG 98python3 software stack inside a portable virtual environment, +with the caveat that cvmfs must be visible from batch workers: + +.. code-block:: bash + + #!/usr/bin/env bash + NAME=coffeaenv + LCG=/cvmfs/sft.cern.ch/lcg/views/LCG_98python3/x86_64-centos7-gcc9-opt + + source $LCG/setup.sh + # following https://aarongorka.com/blog/portable-virtualenv/, an alternative is https://github.com/pantsbuild/pex + python -m venv --copies $NAME + source $NAME/bin/activate + LOCALPATH=$NAME$(python -c 'import sys; print(f"/lib/python{sys.version_info.major}.{sys.version_info.minor}/site-packages")') + export PYTHONPATH=${LOCALPATH}:$PYTHONPATH + python -m pip install setuptools pip wheel --upgrade + python -m pip install coffea + sed -i '1s/#!.*python$/#!\/usr\/bin\/env python/' $NAME/bin/* + sed -i '40s/.*/VIRTUAL_ENV="$(cd "$(dirname "$(dirname "${BASH_SOURCE[0]}" )")" \&\& pwd)"/' $NAME/bin/activate + sed -i "2a source ${LCG}/setup.sh" $NAME/bin/activate + sed -i "3a export PYTHONPATH=${LOCALPATH}:\$PYTHONPATH" $NAME/bin/activate + tar -zcf ${NAME}.tar.gz ${NAME} + +The resulting tarball size is about 60 MB. +An example batch job wrapper script is: + +.. code-block:: bash + + #!/usr/bin/env bash + tar -zxf coffeaenv.tar.gz + source coffeaenv/bin/activate + + echo "Running command:" $@ + time $@ || exit $? + +Note that this environment only functions from the working directory of the wrapper script due to having relative paths. +Unless you install jupyter into this environment (which may bloat the tarball--LCG98 jupyter is reasonably recent), it is not visible inside the LCG jupyter server. From a shell with the virtual environment activated, you can execute:: + + python -m ipykernel install --user --name=coffeaenv + +to make a new kernel available that uses this environment. + +For Developers +-------------- + +1. Download source: + + .. code-block:: bash + + git clone https://github.com/CoffeaTeam/coffea + +2. Install with development dependencies: + + .. code-block:: bash + + cd coffea + pip install --editable .[dev] + // or if you need to work on the executors, e.g. dask, + pip install --editable .[dev,dask] + +3. Develop a cool new feature or fix some bugs + +4. Lint source, run tests, and build documentation: + + .. code-block:: bash + + flake8 coffea tests setup.py + black coffea tests setup.py + pytest tests + pushd docs && make html && popd + +5. Make a pull request! diff --git a/_sources/modules/coffea.analysis_tools.rst.txt b/_sources/modules/coffea.analysis_tools.rst.txt new file mode 100644 index 000000000..b4386d871 --- /dev/null +++ b/_sources/modules/coffea.analysis_tools.rst.txt @@ -0,0 +1,5 @@ +coffea.analysis_tools +===================== + +.. automodapi:: coffea.analysis_tools + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.btag_tools.rst.txt b/_sources/modules/coffea.btag_tools.rst.txt new file mode 100644 index 000000000..da6214151 --- /dev/null +++ b/_sources/modules/coffea.btag_tools.rst.txt @@ -0,0 +1,5 @@ +coffea.btag_tools +================= + +.. automodapi:: coffea.btag_tools + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.hist.rst.txt b/_sources/modules/coffea.hist.rst.txt new file mode 100644 index 000000000..ca6a0e8da --- /dev/null +++ b/_sources/modules/coffea.hist.rst.txt @@ -0,0 +1,5 @@ +coffea.hist +=========== + +.. automodapi:: coffea.hist + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.jetmet_tools.rst.txt b/_sources/modules/coffea.jetmet_tools.rst.txt new file mode 100644 index 000000000..6721a2e7c --- /dev/null +++ b/_sources/modules/coffea.jetmet_tools.rst.txt @@ -0,0 +1,5 @@ +coffea.jetmet_tools +=================== + +.. automodapi:: coffea.jetmet_tools + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.lookup_tools.rst.txt b/_sources/modules/coffea.lookup_tools.rst.txt new file mode 100644 index 000000000..8129232e6 --- /dev/null +++ b/_sources/modules/coffea.lookup_tools.rst.txt @@ -0,0 +1,5 @@ +coffea.lookup_tools +=================== + +.. automodapi:: coffea.lookup_tools + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.lumi_tools.rst.txt b/_sources/modules/coffea.lumi_tools.rst.txt new file mode 100644 index 000000000..3d796e005 --- /dev/null +++ b/_sources/modules/coffea.lumi_tools.rst.txt @@ -0,0 +1,5 @@ +coffea.lumi_tools +================= + +.. automodapi:: coffea.lumi_tools + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.nanoevents.methods.base.rst.txt b/_sources/modules/coffea.nanoevents.methods.base.rst.txt new file mode 100644 index 000000000..ade6106f0 --- /dev/null +++ b/_sources/modules/coffea.nanoevents.methods.base.rst.txt @@ -0,0 +1,5 @@ +coffea.nanoevents.methods.base +============================== + +.. automodapi:: coffea.nanoevents.methods.base + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.nanoevents.methods.candidate.rst.txt b/_sources/modules/coffea.nanoevents.methods.candidate.rst.txt new file mode 100644 index 000000000..8b2d80c0f --- /dev/null +++ b/_sources/modules/coffea.nanoevents.methods.candidate.rst.txt @@ -0,0 +1,5 @@ +coffea.nanoevents.methods.candidate +=================================== + +.. automodapi:: coffea.nanoevents.methods.candidate + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.nanoevents.methods.nanoaod.rst.txt b/_sources/modules/coffea.nanoevents.methods.nanoaod.rst.txt new file mode 100644 index 000000000..3e0bb090d --- /dev/null +++ b/_sources/modules/coffea.nanoevents.methods.nanoaod.rst.txt @@ -0,0 +1,5 @@ +coffea.nanoevents.methods.nanoaod +================================= + +.. automodapi:: coffea.nanoevents.methods.nanoaod + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.nanoevents.methods.vector.rst.txt b/_sources/modules/coffea.nanoevents.methods.vector.rst.txt new file mode 100644 index 000000000..5e9540860 --- /dev/null +++ b/_sources/modules/coffea.nanoevents.methods.vector.rst.txt @@ -0,0 +1,5 @@ +coffea.nanoevents.methods.vector +================================ + +.. automodapi:: coffea.nanoevents.methods.vector + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.nanoevents.rst.txt b/_sources/modules/coffea.nanoevents.rst.txt new file mode 100644 index 000000000..581391beb --- /dev/null +++ b/_sources/modules/coffea.nanoevents.rst.txt @@ -0,0 +1,5 @@ +coffea.nanoevents +================= + +.. automodapi:: coffea.nanoevents + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.processor.rst.txt b/_sources/modules/coffea.processor.rst.txt new file mode 100644 index 000000000..064f506f5 --- /dev/null +++ b/_sources/modules/coffea.processor.rst.txt @@ -0,0 +1,5 @@ +coffea.processor +================ + +.. automodapi:: coffea.processor + :no-heading: \ No newline at end of file diff --git a/_sources/modules/coffea.util.rst.txt b/_sources/modules/coffea.util.rst.txt new file mode 100644 index 000000000..7fe6d6037 --- /dev/null +++ b/_sources/modules/coffea.util.rst.txt @@ -0,0 +1,5 @@ +coffea.util +=========== + +.. automodapi:: coffea.util + :no-heading: \ No newline at end of file diff --git a/_sources/notebooks/accumulators.ipynb.txt b/_sources/notebooks/accumulators.ipynb.txt new file mode 100644 index 000000000..a5ae2c31f --- /dev/null +++ b/_sources/notebooks/accumulators.ipynb.txt @@ -0,0 +1,693 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Analysis tools and accumulators\n", + "\n", + "This is a rendered copy of [accumulators.ipynb](https://github.com/CoffeaTeam/coffea/blob/master/binder/accumulators.ipynb). You can optionally run it interactively on [binder at this link](https://mybinder.org/v2/gh/coffeateam/coffea/master?filepath=binder%2Faccumulators.ipynb)\n", + "\n", + "Now that we know how to access data with NanoEvents and apply corrections, let's go through some useful columnar analysis tools and idioms for building _accumulators_, namely, the eventual output of a coffea processor that has natural \"merge\" semantics. The most familiar type of accumulator is the histogram, but other types are useful in certain contexts.\n", + "\n", + "We'll use our small sample file to demonstrate the utilities, although it won't be very interesting to analyze" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import awkward as ak\n", + "from coffea.nanoevents import NanoEventsFactory, NanoAODSchema\n", + "\n", + "fname = \"https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/nano_dy.root\"\n", + "events = NanoEventsFactory.from_root(\n", + " fname,\n", + " schemaclass=NanoAODSchema.v6,\n", + " metadata={\"dataset\": \"DYJets\"},\n", + ").events()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To generate some mock systematics, we'll use one of the scale factors from the applying_corrections notebook (note you will have to at least execute the cell that downloads test data in that notebook for this to work)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['scalefactors_Tight_Electron', 'scalefactors_Tight_Electron_error'])" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from coffea.lookup_tools import extractor\n", + "\n", + "ext = extractor()\n", + "ext.add_weight_sets([\"* * data/testSF2d.histo.root\"])\n", + "ext.finalize()\n", + "evaluator = ext.make_evaluator()\n", + "evaluator.keys()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Weights\n", + "\n", + "This is a container for event weights and associated systematic shifts, which helps track the product of the weights (i.e. the total event weight to be used for filling histograms) as well as systematic variations to that product. Here we demo its use by constructing an event weight consisting of the generator weight, the $\\alpha_s$ uncertainty variation, and the electron ID scale factor with its associated systematic." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from coffea.analysis_tools import Weights\n", + "\n", + "weights = Weights(len(events))\n", + "\n", + "weights.add(\"genWeight\", events.genWeight)\n", + "\n", + "weights.add(\n", + " \"alphaS\",\n", + " # in NanoAOD, the generator weights are already stored with respect to nominal\n", + " weight=np.ones(len(events)),\n", + " # 31 => alphas(MZ)=0.1165 central value; 32 => alphas(MZ)=0.1195\n", + " # per https://lhapdfsets.web.cern.ch/current/PDF4LHC15_nnlo_30_pdfas/PDF4LHC15_nnlo_30_pdfas.info\n", + " # which was found by looking up the LHA ID in events.LHEPdfWeight.__doc__\n", + " weightUp=events.LHEPdfWeight[:, 32],\n", + " weightDown=events.LHEPdfWeight[:, 31],\n", + ")\n", + "\n", + "eleSF = evaluator[\"scalefactors_Tight_Electron\"](events.Electron.eta, events.Electron.pt)\n", + "eleSFerror = evaluator[\"scalefactors_Tight_Electron_error\"](events.Electron.eta, events.Electron.pt)\n", + "weights.add(\n", + " \"eleSF\",\n", + " # the event weight is the product of the per-electron weights\n", + " # note, in a real analysis we would first have to select electrons of interest\n", + " weight=ak.prod(eleSF, axis=1),\n", + " weightUp=ak.prod(eleSF + eleSFerror, axis=1),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A [WeightStatistics](https://coffeateam.github.io/coffea/api/coffea.analysis_tools.WeightStatistics.html) object tracks the smallest and largest weights seen per type, as well as some other summary statistics. It is kept internally and can be accessed via `weights.weightStatistics`. This object is addable, so it can be used in an accumulator." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'genWeight': WeightStatistics(sumw=578762.4375, sumw2=27678371840.0, minw=-26331.201171875, maxw=26331.201171875, n=40),\n", + " 'alphaS': WeightStatistics(sumw=40.0, sumw2=40.0, minw=1.0, maxw=1.0, n=40),\n", + " 'eleSF': WeightStatistics(sumw=38.26972579956055, sumw2=36.81547546386719, minw=0.6674144268035889, maxw=1.0077519416809082, n=40)}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights.weightStatistics" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then the total event weight is available via" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 26331.20117188, 23933.4196682 , 24385.06528643, 17224.10489525,\n", + " 26331.20117188, 26535.31910775, -23236.21447283, 26067.890625 ,\n", + " 26331.20117188, 25105.68057538, 26331.20117188, 26061.82814944,\n", + " 26061.82814944, -26331.20117188, 26331.20117188, 24421.85661211,\n", + " -24854.62516629, 26331.20117188, -19978.69273076, 26331.20117188,\n", + " 22168.68846612, -25134.17258657, 26331.20117188, 26331.20117188,\n", + " 26331.20117188, 24770.33051391, 26331.20117188, 22732.29949574,\n", + " 26331.20117188, 24421.85661211, 26331.20117188, 25857.1530546 ,\n", + " 26331.20117188, -23903.50101615, 26331.20117188, -24770.33051391,\n", + " 26331.20117188, -24906.05914783, 26331.20117188, -26331.20117188])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights.weight()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the total event weight with a given variation is available via" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 26331.20117188, 24397.53583916, 25294.0252539 , 17997.89462374,\n", + " 26331.20117188, 27253.27428405, -23502.68164558, 26067.890625 ,\n", + " 26331.20117188, 25230.22218679, 26331.20117188, 26779.78332574,\n", + " 26779.78332574, -26331.20117188, 26331.20117188, 24885.97278307,\n", + " -24977.92136851, 26331.20117188, -20983.93483174, 26331.20117188,\n", + " 22734.27398292, -25869.18763094, 26331.20117188, 26331.20117188,\n", + " 26331.20117188, 25448.12088952, 26331.20117188, 22998.76666849,\n", + " 26331.20117188, 24885.97278307, 26331.20117188, 26254.27086417,\n", + " 26331.20117188, -24141.51091823, 26331.20117188, -25448.12088952,\n", + " 26331.20117188, -25583.84952343, 26331.20117188, -26331.20117188])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights.weight(\"eleSFUp\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "all variations tracked by the `weights` object are available via" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'alphaSDown', 'alphaSUp', 'eleSFDown', 'eleSFUp'}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights.variations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## PackedSelection\n", + "\n", + "This class can store several boolean arrays in a memory-efficient mannner and evaluate arbitrary combinations of boolean requirements in an CPU-efficient way. Supported inputs include 1D numpy or awkward arrays. This makes it a good tool to form analysis signal and control regions, and to implement cutflow or \"N-1\" plots.\n", + "\n", + "Below we create a packed selection with some typical selections for a Z+jets study, to be used later to form same-sign and opposite-sign $ee$ and $\\mu\\mu$ event categories/regions." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['twoElectron', 'eleOppSign', 'noElectron', 'twoMuon', 'muOppSign', 'noMuon', 'leadPt20']\n" + ] + } + ], + "source": [ + "from coffea.analysis_tools import PackedSelection\n", + "\n", + "selection = PackedSelection()\n", + "\n", + "selection.add(\"twoElectron\", ak.num(events.Electron) == 2)\n", + "selection.add(\"eleOppSign\", ak.sum(events.Electron.charge, axis=1) == 0)\n", + "selection.add(\"noElectron\", ak.num(events.Electron) == 0)\n", + "\n", + "selection.add(\"twoMuon\", ak.num(events.Muon) == 2)\n", + "selection.add(\"muOppSign\", ak.sum(events.Muon.charge, axis=1) == 0)\n", + "selection.add(\"noMuon\", ak.num(events.Muon) == 0)\n", + "\n", + "\n", + "selection.add(\n", + " \"leadPt20\",\n", + " # assuming one of `twoElectron` or `twoMuon` is imposed, this implies at least one is above threshold\n", + " ak.any(events.Electron.pt >= 20.0, axis=1) | ak.any(events.Muon.pt >= 20.0, axis=1)\n", + ")\n", + "\n", + "print(selection.names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To evaluate a boolean mask (e.g. to filter events) we can use the `selection.all(*names)` function, which will compute the AND of all listed boolean selections" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False])" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "selection.all(\"twoElectron\", \"noMuon\", \"leadPt20\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also be more specific and require that a specific set of selections have a given value (with the unspecified ones allowed to be either true or false) using `selection.require`" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "selection.require(twoElectron=True, noMuon=True, eleOppSign=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the python syntax for passing an arguments variable, we can easily implement a \"N-1\" style selection" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Events passing all cuts, ignoring noMuon: 3\n", + "Events passing all cuts, ignoring twoElectron: 10\n", + "Events passing all cuts, ignoring leadPt20: 5\n", + "Events passing all cuts: 3\n" + ] + } + ], + "source": [ + "allCuts = {\"twoElectron\", \"noMuon\", \"leadPt20\"}\n", + "for cut in allCuts:\n", + " nev = selection.all(*(allCuts - {cut})).sum()\n", + " print(f\"Events passing all cuts, ignoring {cut}: {nev}\")\n", + "\n", + "nev = selection.all(*allCuts).sum()\n", + "print(f\"Events passing all cuts: {nev}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Accumulator semantics\n", + "\n", + "Prior to coffea 0.7.2, accumulators were more explicit in that they inherited from [AccumulatorABC](https://coffeateam.github.io/coffea/api/coffea.processor.AccumulatorABC.html). Such accumulators are still supported, but now the requirements for an acuumulator output of a processor have been relaxed to the protocol:\n", + "```python\n", + "class Addable(Protocol):\n", + " def __add__(self: T, other: T) -> T:\n", + " ...\n", + "\n", + "\n", + "Accumulatable = Union[Addable, MutableSet, MutableMapping]\n", + "```\n", + "\n", + "Essentially, any item that can be added, any set, or any dictionary of the above, can be used as an accumulator:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'num': 4, 'val': 11.1, 'thing': {'a', 'b', 'c'}}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from coffea.processor import accumulate\n", + "\n", + "accumulate([\n", + " {\"num\": 0, \"val\": 3.1},\n", + " {\"num\": 2, \"val\": 4.0, \"thing\": {\"a\", \"b\"}},\n", + " {\"num\": 2, \"val\": 4.0, \"thing\": {\"a\", \"c\"}},\n", + "])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since `hist` histograms are addable, they can be used as well:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0. 3. 0. 2. 0. 1. 0. 0. 0. 0.]\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "Axis 0\n", + "\n", + "\n", + "\n", + "
\n", + "
\n", + "Regular(10, 0, 1, label='Axis 0')
\n", + "
\n", + "Double() Σ=6.0\n", + "\n", + "
\n", + "
\n", + "" + ], + "text/plain": [ + "Hist(Regular(10, 0, 1, label='Axis 0'), storage=Double()) # Sum: 6.0" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import hist\n", + "\n", + "def makehist():\n", + " return hist.Hist.new.Reg(10, 0, 1).Double()\n", + "\n", + "h = accumulate([\n", + " makehist().fill([0.1, 0.1, 0.3]),\n", + " makehist().fill([0.1, 0.3, 0.5]),\n", + "])\n", + "print(h.values())\n", + "h" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bringing it together\n", + "\n", + "Let's build an output accumulator that stores, per dataset:\n", + " - the sum of weights for the events processed, to use for later luminosity-normalizing the yields;\n", + " - a histogram of the dilepton invariant mass, with category axes for various selection regions of interest and systematics; and\n", + " - the weight statistics, for debugging purposes\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'DYJets': {'sumw': 578762.44,\n", + " 'mass': Hist(\n", + " StrCategory(['ee', 'eeSS', 'mm', 'mmSS'], name='region', label='region'),\n", + " StrCategory(['nominal', 'alphaSUp', 'eleSFUp', 'alphaSDown', 'eleSFDown'], name='systematic', label='systematic'),\n", + " Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=621215, variance=2.20829e+10),\n", + " 'weightStats': {'genWeight': WeightStatistics(sumw=578762.4375, sumw2=27678371840.0, minw=-26331.201171875, maxw=26331.201171875, n=40),\n", + " 'alphaS': WeightStatistics(sumw=40.0, sumw2=40.0, minw=1.0, maxw=1.0, n=40),\n", + " 'eleSF': WeightStatistics(sumw=38.26972579956055, sumw2=36.81547546386719, minw=0.6674144268035889, maxw=1.0077519416809082, n=40)}}}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "regions = {\n", + " \"ee\": {\"twoElectron\": True, \"noMuon\": True, \"leadPt20\": True, \"eleOppSign\": True},\n", + " \"eeSS\": {\"twoElectron\": True, \"noMuon\": True, \"leadPt20\": True, \"eleOppSign\": False},\n", + " \"mm\": {\"twoMuon\": True, \"noElectron\": True, \"leadPt20\": True, \"muOppSign\": True},\n", + " \"mmSS\": {\"twoMuon\": True, \"noElectron\": True, \"leadPt20\": True, \"muOppSign\": False},\n", + "}\n", + "\n", + "masshist = (\n", + " hist.Hist.new\n", + " .StrCat(regions.keys(), name=\"region\")\n", + " .StrCat([\"nominal\"] + list(weights.variations), name=\"systematic\")\n", + " .Reg(60, 60, 120, name=\"mass\", label=\"$m_{ll}$ [GeV]\")\n", + " .Weight()\n", + ")\n", + "\n", + "for region, cuts in regions.items():\n", + " goodevent = selection.require(**cuts)\n", + "\n", + " if region.startswith(\"ee\"):\n", + " mass = events.Electron[goodevent].sum().mass\n", + " elif region.startswith(\"mm\"):\n", + " mass = events.Muon[goodevent].sum().mass\n", + "\n", + " masshist.fill(\n", + " region=region,\n", + " systematic=\"nominal\",\n", + " mass=mass,\n", + " weight=weights.weight()[goodevent],\n", + " )\n", + " for syst in weights.variations:\n", + " masshist.fill(\n", + " region=region,\n", + " systematic=syst,\n", + " mass=mass,\n", + " weight=weights.weight(syst)[goodevent],\n", + " )\n", + "\n", + "out = {\n", + " events.metadata[\"dataset\"]: {\n", + " \"sumw\": ak.sum(events.genWeight),\n", + " \"mass\": masshist,\n", + " \"weightStats\": weights.weightStatistics,\n", + " }\n", + "}\n", + "\n", + "out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The cell below demonstrates that indeed this output is accumulatable. So if we were to return such a result from a coffea processor, we would be all ready to process thousands of files!" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'DYJets': {'mass': Hist(\n", + " StrCategory(['ee', 'eeSS', 'mm', 'mmSS'], name='region', label='region'),\n", + " StrCategory(['nominal', 'alphaSUp', 'eleSFUp', 'alphaSDown', 'eleSFDown'], name='systematic', label='systematic'),\n", + " Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=1.24243e+06, variance=4.41659e+10),\n", + " 'weightStats': {'genWeight': WeightStatistics(sumw=1157524.875, sumw2=55356743680.0, minw=-26331.201171875, maxw=26331.201171875, n=80),\n", + " 'alphaS': WeightStatistics(sumw=80.0, sumw2=80.0, minw=1.0, maxw=1.0, n=80),\n", + " 'eleSF': WeightStatistics(sumw=76.5394515991211, sumw2=73.63095092773438, minw=0.6674144268035889, maxw=1.0077519416809082, n=80)},\n", + " 'sumw': 1157524.9}}" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "accumulate([out, out])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The mass histogram itself is not very interesting with only 40 input events, however" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + "\n", + "60\n", + "\n", + "\n", + "120\n", + "\n", + "\n", + "$m_{ll}$ [GeV]\n", + "\n", + "\n", + "\n", + "
\n", + "
\n", + "Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]')
\n", + "
\n", + "Weight() Σ=WeightedSum(value=126744, variance=4.49114e+09)\n", + "\n", + "
\n", + "
\n", + "" + ], + "text/plain": [ + "Hist(Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]'), storage=Weight()) # Sum: WeightedSum(value=126744, variance=4.49114e+09)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "out[\"DYJets\"][\"mass\"][sum, \"nominal\", :]" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/_sources/notebooks/applying_corrections.ipynb.txt b/_sources/notebooks/applying_corrections.ipynb.txt new file mode 100644 index 000000000..7620b05a8 --- /dev/null +++ b/_sources/notebooks/applying_corrections.ipynb.txt @@ -0,0 +1,679 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Applying corrections to columnar data\n", + "\n", + "Here we will show how to apply corrections to columnar data using:\n", + "\n", + "- the `coffea.lookup_tools` package, which is designed to read in ROOT histograms and a variety of data file formats popular within CMS into a standardized lookup table format;\n", + "- CMS-specific extensions to the above, for jet corrections (`coffea.jetmet_tools`) and b-tagging efficiencies/uncertainties (`coffea.btag_tools`);\n", + "- the [correctionlib](https://cms-nanoaod.github.io/correctionlib/) package, which provides a experiment-agnostic serializable data format for common correction functions." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Test data**:\n", + "We'll use NanoEvents to construct some test data." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import awkward as ak\n", + "from coffea.nanoevents import NanoEventsFactory, NanoAODSchema\n", + "\n", + "fname = \"https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/nano_dy.root\"\n", + "events = NanoEventsFactory.from_root(\n", + " fname,\n", + " schemaclass=NanoAODSchema.v6,\n", + " metadata={\"dataset\": \"DYJets\"},\n", + ").events()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Coffea lookup_tools\n", + "\n", + "The entrypoint for `coffea.lookup_tools` is the [extractor class](https://coffeateam.github.io/coffea/api/coffea.lookup_tools.extractor.html#coffea.lookup_tools.extractor)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from coffea.lookup_tools import extractor" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "~/src/coffea/binder/data ~/src/coffea/binder\n", + "~/src/coffea/binder\n" + ] + } + ], + "source": [ + "%%bash\n", + "# download some sample correction sources\n", + "mkdir -p data\n", + "pushd data\n", + "PREFIX=https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples\n", + "curl -Os $PREFIX/testSF2d.histo.root\n", + "curl -Os $PREFIX/Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi.jec.txt\n", + "curl -Os $PREFIX/Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi.junc.txt\n", + "curl -Os $PREFIX/DeepCSV_102XSF_V1.btag.csv.gz\n", + "popd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Opening a root file and using it as a lookup table\n", + "\n", + "In [tests/samples](https://github.com/CoffeaTeam/coffea/tree/master/tests/samples), there is an example file with a `TH2F` histogram named `scalefactors_Tight_Electron`. The following code reads that histogram into an [evaluator](https://coffeateam.github.io/coffea/api/coffea.lookup_tools.evaluator.html#coffea.lookup_tools.evaluator) instance, under the key `testSF2d` and applies it to some electrons." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "available evaluator keys:\n", + "\t testSF2d\n", + "testSF2d: 2 dimensional histogram with axes:\n", + "\t1: [-2.5 -2. -1.566 -1.444 -0.8 0. 0.8 1.444 1.566 2.\n", + " 2.5 ]\n", + "\t2: [ 10. 20. 35. 50. 90. 150. 500.]\n", + "\n", + "type of testSF2d: \n" + ] + } + ], + "source": [ + "ext = extractor()\n", + "# several histograms can be imported at once using wildcards (*)\n", + "ext.add_weight_sets([\"testSF2d scalefactors_Tight_Electron data/testSF2d.histo.root\"])\n", + "ext.finalize()\n", + "\n", + "evaluator = ext.make_evaluator()\n", + "\n", + "print(\"available evaluator keys:\")\n", + "for key in evaluator.keys():\n", + " print(\"\\t\", key)\n", + "print(\"testSF2d:\", evaluator['testSF2d'])\n", + "print(\"type of testSF2d:\", type(evaluator['testSF2d']))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Electron eta: [[], [1.83], [-0.293, -0.904], [-2.19, 1.65], ... [-0.0595], [], [0.381], [], []]\n", + "Electron pt: [[], [29.6], [60.1, 51.7], [10.7, 8.6], [], ... [], [15.6], [], [7.68], [], []]\n", + "Scale factor: [[], [0.909], [0.953, 0.972], [0.807, 0.827], ... [0.941], [], [0.946], [], []]\n" + ] + } + ], + "source": [ + "print(\"Electron eta:\", events.Electron.eta)\n", + "print(\"Electron pt:\", events.Electron.pt)\n", + "print(\"Scale factor:\", evaluator[\"testSF2d\"](events.Electron.eta, events.Electron.pt))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Building and using your own correction from a histogram\n", + "\n", + "To use a histogram or ratio of histograms to build your own correction, you can use `lookup_tools` to simplify the implementation. Here we create some mock data for two slightly different pt and eta spectra (say, from two different generators) and derive a correction to reweight one sample to the other." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAEGCAYAAACJnEVTAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAhDUlEQVR4nO3de3RV1bn38e8jghQKIhgViBrgDdpwiySIQmBYPS0oClIvwDkq0A5jR3XY9m05Vduhtgz61krre+w5LxerghUVxVPEG9Zae8AbGixyiVgIYgkGjdgSlINcfN4/9krOFvbOTvY12ev3GWOPrDXXbS4W49lzzznXnObuiIhIOByT6wyIiEj2KOiLiISIgr6ISIgo6IuIhIiCvohIiByb6wwkcuKJJ3pRUVGusyEi0m6sXbv2I3cviLWtzQf9oqIiqqqqcp0NEZF2w8zei7dN1TsiIiGioC8iEiIK+iIiIdLm6/RFJDwOHjxIbW0t+/fvz3VW2oXOnTtTWFhIx44dW3yMgr6ItBm1tbV069aNoqIizCzX2WnT3J3du3dTW1tLv379WnycqndEpM3Yv38/vXr1UsBvATOjV69erf5VpKAvIm2KAn7LJfNvpaAvIhIiCvoiEhq33347c+fOjbt9+fLlVFdXp/Wa27dv56GHHkrrOVOhoJ9lUxa8ypQFr+Y6GyISg4K+iEg7N2fOHAYOHEhFRQXvvPMOAPfccw8jRoxg2LBhXHbZZezbt49XXnmFFStWMGvWLEpLS6mpqYm5H8Bjjz3G4MGDGTZsGGPHjgXg8OHDzJo1ixEjRjB06FAWLFgAwE033cTq1aspLS3lrrvuys0/QjR3b9OfsrIyzydXzn/Fr5z/Sq6zIdImVVdXp/V8VVVVPnjwYP/00099z549PmDAAL/zzjv9o48+atrnxz/+sd99993u7j59+nR/7LHHmrbF22/w4MFeW1vr7u5///vf3d19wYIFPnv2bHd3379/v5eVlfm2bdv8xRdf9AkTJqT1vqLF+jcDqjxOTFU//TT76ZObqH6/Ie726rrItnhVPCV9unPbJYMykjeRsFm9ejWTJ0+mS5cuAEycOBGAjRs38pOf/IR//OMffPLJJ4wbNy7m8fH2Gz16NDNmzODKK6/kG9/4BgB/+MMfWL9+PcuWLQNgz549bNmyhU6dOmX6NltFQT/Nqt9voLqugZLe3Vt/bF38LwsRSZ8ZM2awfPlyhg0bxqJFi/jzn//cqv3mz5/PmjVrePrppykrK2Pt2rW4O7/5zW+O+gKJd+5cUdDPgJLe3Vl63bkxtzWW8GNtVwOvSHqNHTuWGTNmcPPNN3Po0CGefPJJrrvuOvbu3Uvv3r05ePAgS5YsoW/fvgB069aNvXv3Nh0fb7+amhpGjhzJyJEjefbZZ9mxYwfjxo1j3rx5nH/++XTs2JG//vWv9O3b96hz5pqCvojkreHDhzNlyhSGDRvGSSedxIgRIwCYPXs2I0eOpKCggJEjRzYF5alTp3Lttddy9913s2zZsrj7zZo1iy1btuDuXHDBBQwbNoyhQ4eyfft2hg8fjrtTUFDA8uXLGTp0KB06dGDYsGHMmDGD73//+zn79wCwSJ1/21VeXu7taRKV5kryibYnOlYk37399tt85StfyXU22pVY/2Zmttbdy2Ptry6bSVBfexFpr1S9k2UqxYtILiUs6ZvZfWb2oZltjEpbambrgs92M1sXpBeZ2X9HbZsfdUyZmW0ws61mdrdpVCURkaxrSUl/EfDvwAONCe4+pXHZzH4F7Inav8bdS2OcZx5wLbAGeAYYDzzb6hyLiEjSEgZ9d19lZkWxtgWl9SuB85s7h5n1Brq7+2vB+gPApbTRoJ/KC1bJ9tEXEcmGVBtyxwAfuPuWqLR+ZvYXM/svMxsTpPUFaqP2qQ3SYjKzSjOrMrOq+vr6FLPYeo0vWCWjpHd3Svoo6ItkizpWtE6qDbnTgIej1uuA09x9t5mVAcvNrNVjCrj7QmAhRLpsppjHpCT7gpWICMD48eN57bXXqKio4Kmnnsp1dpokXdI3s2OBbwBLG9Pc/TN33x0srwVqgIHATqAw6vDCIE1EJC/NmjWL3/3ud7nOxlFSqd75J2CzuzdV25hZgZl1CJb7A8XANnevAxrM7JygHeAa4IkUri0ikhGzZ8/mjDPOoKKigmnTpjF37lxqamoYP348ZWVljBkzhs2bNwORsXluvPFGRo0aRf/+/ZsGWwO44IIL6NatW65uI66E1Ttm9jBwHnCimdUCt7n7vcBUvli1AzAW+JmZHQQ+B77t7h8H275DpCfQl4g04LbJRtyWULWOSObF61BxZHvbvs8OATDk9ue+kB6rQ0WiUWzfeOMNHn/8cd566y0OHjzI8OHDKSsro7Kykvnz51NcXMyaNWv4zne+w5/+9CcA6urqeOmll9i8eTMTJ07k8ssvb/W9ZlNLeu9Mi5M+I0ba48DjcfavAga3Mn8iIlnz8ssvM2nSJDp37kznzp255JJL2L9/P6+88gpXXHFF036fffZZ0/Kll17KMcccQ0lJCR988EEust0qeiNXRNqkls4rkemOFZ9//jk9evRg3bp1Mbcfd9xxTcttfSwz0Ng7IiJNRo8ezZNPPsn+/fv55JNPeOqpp+jSpQv9+vXjscceAyKB/a233spxTpOnoC8iEhgxYgQTJ05k6NChXHjhhQwZMoTjjz+eJUuWcO+99zJs2DAGDRrEE08k7ocyZswYrrjiCl544QUKCwt57rnnEh6TDareERGJ8sMf/pDbb7+dffv2MXbsWMrKyujXrx8rV648at9FixZ9Yf2TTz5pWl69enWms5oUBX0RadfSXZdfWVlJdXU1+/fvZ/r06QwfPjyt5881BX0RkSgPPfRQrrOQUarTFxEJEQV9EZEQUdAXEQkRBX0Rad/unxD5SIso6IuIpNm6des499xzGTRoEEOHDmXp0qWJD8oS9d4REUmzLl268MADD1BcXMz7779PWVkZ48aNo0ePHrnOmoK+iEi02bNn8+CDD1JQUMCpp55KWVkZkydP5vrrr6e+vp4uXbpwzz33cOaZZzJjxgy6d+9OVVUVu3bt4pe//CWXX345AwcObDpfnz59OOmkk6ivr1fQFxGJ69mbYNeGo9N3rf/i+oFPI3//z6lfTD9l6NHHnjIELvxF3EtmYmjl119/nQMHDjBgwICEt5wNCvoiIoF0D61cV1fH1VdfzeLFiznmmLbRhKqg345obl4JlWZK5F/Q2HNn5tMZyUayQys3NDQwYcIE5syZwznnnJORvCWjbXz1iIi0AekaWvnAgQNMnjyZa665ps3NpKWgLyISSNfQyo8++iirVq1i0aJFlJaWUlpaGveXQrapeqeNqa5raKrGibUNiLsdEs8BKiLNS8fQyldddRVXXXVVNrLbaglL+mZ2n5l9aGYbo9JuN7OdZrYu+FwUte1mM9tqZu+Y2bio9PFB2lYzuyn9t9L+lfTpHnMy55aqrmuIOZG0SF6b+XRa6/MrKyspLS1l+PDhXHbZZaEcWnkR8O/AA0ek3+Xuc6MTzKwEmAoMAvoAfzSzxg6r/wF8DagF3jCzFe5enULe806iEnqihtzmfgGISMvk+9DKCYO+u68ys6IWnm8S8Ii7fwa8a2ZbgbODbVvdfRuAmT0S7KugLyKSRak05N5gZuuD6p8TgrS+wI6ofWqDtHjpMZlZpZlVmVlVfX19ClkUEZFoyQb9ecAAoBSoA36VrgwBuPtCdy939/KCgoJ0nrpdW3rdueqjLyIpSar3jrs3vXZmZvcATwWrO4Hod6ELgzSaSQ+XDL9IIhI2M1fOBOD+8ffnOCftQ1IlfTPrHbU6GWjs2bMCmGpmx5lZP6AYeB14Ayg2s35m1olIY++K5LMtItJ2pXNo5eXLl1Ndnb7mz4QlfTN7GDgPONHMaoHbgPPMrBRwYDtwHYC7bzKzR4k00B4Crnf3w8F5bgCeAzoA97n7prTdhYhIG9LSoZUPHz5Mhw4dmj3X8uXLufjiiykpKUlL3hKW9N19mrv3dveO7l7o7ve6+9XuPsTdh7r7RHevi9p/jrsPcPcz3P3ZqPRn3H1gsG1OWnIvIpJms2fP5owzzqCiooJp06Yxd+5campqGD9+PGVlZYwZM4bNmzcDMGPGDG688UZGjRpF//79WbZsGQADBw6kuLgY+OLQygBFRUX86Ec/Yvjw4SxZsoSysjIA3nrrLcyMv/3tbwAMGDCAV155hRUrVjBr1ixKS0upqalJ+f70Rm66xRsOtlHjsLDxpndLMPSrSFjc8fodbP5481HpR6btO7QPgHMf+mInhzN7nnnUsWf2PJMfnf2juNfM1tDKvXr14s0334zc5x130NDQwOrVqykvL2f16tVUVFRw0kknMWrUKCZOnMjFF1+ctjF8FPTTbdeGyOeUIckdKyI5k62hladMmdK0PGrUKF5++WVWrVrFLbfcwsqVK3F3xowZk5F7VNDPhFOGxO+d01zvHU3uLNKkuRJ5tEz33snE0Mpdu3ZtWh47diyrV6/mvffeY9KkSdxxxx2YGRMmZCYeaJRNEZFALoZWHjNmDA8++CDFxcUcc8wx9OzZk2eeeYaKigoAunXrxt69e9Nzgyjoi4g0ycXQykVFRbg7Y8eOBaCiooIePXpwwgmRgQ6mTp3KnXfeyVlnnaWG3HZJL2WJtGmZHlp5+/btR6Xt2PE/o9Tccsst3HLLLU3ro0ePzm4/fRGRtizddfmVlZVUV1ezf/9+pk+fHsqhlUVEQiPfh1ZWnX57cv8E9fCRvBfdA0aal8y/lYK+iLQZnTt3Zvfu3Qr8LeDu7N69m86dO7fqOFXviEibUVhYSG1tLZpHo2U6d+5MYWFhq45R0E9GJodH3rUhfhVOgiEcbt29h/eOHQBozH1pnzp27Ei/fv1ynY28pqDfliQzdEOUooPb0pQREclXCvptSaKB1hL8wtj+84o0Z0hE8o2CfgzT98zn9EM1cP/xsXdorpol2cHWRESyQL13Yjj9UE3yVSWnDFHQF5E2SyX9OLZ37M+gZEbKzCQN4SAiKVJJX0QkRBT0RURCJGHQN7P7zOxDM9sYlXanmW02s/Vm9nsz6xGkF5nZf5vZuuAzP+qYMjPbYGZbzexuM7OM3FE2zHxaVS0i0i61pKS/CBh/RNrzwGB3Hwr8Fbg5aluNu5cGn29Hpc8DrgWKg8+R5xQRkQxLGPTdfRXw8RFpf3D3Q8Hqa0Cz7wGbWW+gu7u/5pFBNR4ALk0qxyIikrR01Ol/E3g2ar2fmf3FzP7LzBpn9u0L1EbtUxukxWRmlWZWZWZVGoNDRCR9Ugr6ZvZj4BCwJEiqA05z97OA/w08ZGbdW3ted1/o7uXuXl5QUJBKFkVEJErS/fTNbAZwMXBBUGWDu38GfBYsrzWzGmAgsJMvVgEVBmkiIpJFSZX0zWw88K/ARHffF5VeYGYdguX+RBpst7l7HdBgZucEvXauAZqfWVhERNIuYUnfzB4GzgNONLNa4DYivXWOA54Pel6+FvTUGQv8zMwOAp8D33b3xkbg7xDpCfQlIm0A0e0Akmm5eotYRNqUhEHf3afFSL43zr6PA4/H2VYFDG5V7kREJK30Rq6ISIhowLU8U3RwW5whn5ufdQuIjA6aaEx/EWnXFPTzSGSqRBiUzMG7NqQ1LyLSNino55HFx0dGvVg6M8YcuYkacpv7BSAieUN1+iIiIaKgLyISIqreCQv1zxcRVNIXEQkVBX0RkRBR0A+JKQteZcqCV3OdDRHJMQV9EZEQUUNunqmua4hZoq+uawCIW9q/dfceunY6lqJMZk5Eck5BP4+U9Gn1fDVN9h04nMaciEhbpaCfR267JP4ADI0l/KXXxXhbF9j08w4ZyZOItC2q0xcRCREFfRGREFH1TkjEq9YRkXBRSV9EJERaFPTN7D4z+9DMNkal9TSz581sS/D3hCDdzOxuM9tqZuvNbHjUMdOD/beY2fT0346IiDSnpSX9RcD4I9JuAl5w92LghWAd4EKgOPhUAvMg8iVBZFL1kcDZwG2NXxQiIpIdLQr67r4K+PiI5EnA4mB5MXBpVPoDHvEa0MPMegPjgOfd/WN3/zvwPEd/kYiISAalUqd/srvXBcu7gJOD5b7Ajqj9aoO0eOlHMbNKM6sys6r6+voUsigiItHS0pDr7g54Os4VnG+hu5e7e3lBQUG6TisiEnqpBP0Pgmobgr8fBuk7gVOj9isM0uKlS1t3/wTNoSuSJ1IJ+iuAxh4404EnotKvCXrxnAPsCaqBngO+bmYnBA24Xw/SREQkS1r0cpaZPQycB5xoZrVEeuH8AnjUzL4FvAdcGez+DHARsBXYB8wEcPePzWw28Eaw38/c/cjGYcmhooPbYpfod62P/G2utH/KELjwF5nJmIikTYuCvrtPi7Ppghj7OnB9nPPcB9zX4txJ1rx37AAA4g/Z1oxdG9KaFxHJHA3DIAAsPv7bACydGWO4hsYSfrzJ1VXfL9JuaBgGEZEQUdAXEQkRVe9IYvGqdUSk3QllSX/KglfjzhUrIpLPQhn0RUTCKm+rd3765Caq32+Iua26LpIer7T/wwOH6dJJc8aKSP7J25J+9fsNTcG9tbp06kDXTnn7fdhqqg4TyR95HdlKenePOU1gYwCLO4Xg/cdnMlsiIjmT10FfWqe6riFmiT5Rdditu/fQtdOxFGUycyKSFqEM+pok/Gglfbonfey+A4fTmBMRyaRQBn052m2XxB91J1F12Kafq9FbpL3I24ZcERE5mkr6klDK1WGJBmwTkaxRSV9EJERU0pe0iDsBCySehEUTsIhkjYK+pEwTsIi0Hwr6krJmJ2CB5uv0NQGLSFapTl9EJESSLumb2RnA0qik/sCtQA/gWqA+SL/F3Z8JjrkZ+BZwGLjR3Z9L9vrSjqjXjkibkXTQd/d3gFIAM+sA7AR+D8wE7nL3udH7m1kJMJVI1W8f4I9mNtDd9TqniEiWpKt65wKgxt3fa2afScAj7v6Zu78LbAXOTtP1RUSkBdIV9KcCD0et32Bm683sPjM7IUjrC+yI2qc2SDuKmVWaWZWZVdXX18faRUREkpBy0DezTsBE4LEgaR4wgEjVTx3wq9ae090Xunu5u5cXFBSkmkUREQmko6R/IfCmu38A4O4fuPthd/8cuIf/qcLZCZwadVxhkCYiIlmSjqA/jaiqHTPrHbVtMrAxWF4BTDWz48ysH1AMvJ6G64uISAul9HKWmXUFvgZcF5X8SzMrBRzY3rjN3TeZ2aNANXAIuF49d0REsiuloO/unwK9jki7upn95wBzUrmmiIgkT2/kioiEiIK+ZNyUBa/GnV9XRLJLQV9EJETCOcqmZnJKu+q6hril+eq6BoCY22/dvYeunY6lKJOZE5Em4Qz6klYlfbonfey+A+rAJZJNeRv0p++Zz+mHauD+44/emGgmp10bIrM5SYvcdknz06c0lvBjzbW76ecdMpInEYktb+v0Tz9UE5nCLxmnDFHQbyvun6CJVkTSKG9L+gDbO/ZnUHOzNalOPytilfBFJDfyOujHpWDfpqQ0qTpoYnWRVghn0Jc2I6VJ1UETq4u0koK+5FRKk6pHbxeRFsnbhlwRETmaSvrStqn9RSStVNIXEQkRBX0RkRBR0BcRCREFfRGREFHQFxEJkZSDvpltN7MNZrbOzKqCtJ5m9ryZbQn+nhCkm5ndbWZbzWy9mQ1P9foiItJy6Srpf9XdS929PFi/CXjB3YuBF4J1gAuB4uBTCcxL0/VFRKQFMlW9MwlYHCwvBi6NSn/AI14DephZ7wzlQUREjpCOoO/AH8xsrZlVBmknu3tdsLwLODlY7gvsiDq2NkgTEZEsSMcbuRXuvtPMTgKeN7PN0Rvd3c3MW3PC4MujEuC0005LQxYllDSEtshRUi7pu/vO4O+HwO+Bs4EPGqttgr8fBrvvBE6NOrwwSDvynAvdvdzdywsKClLNooiIBFIq6ZtZV+AYd98bLH8d+BmwApgO/CL4+0RwyArgBjN7BBgJ7ImqBhJJzq4NsUfb1Fj8IkdJtXrnZOD3ZtZ4rofcfaWZvQE8ambfAt4Drgz2fwa4CNgK7ANmpnh9CbtUprXUWPwSQikFfXffBgyLkb4buCBGugPXp3JNkS9orpSusfhFjqKhlaVNm7LgVSDJeXbVgCtyFAV9ybnquoam4B5rGxB3O0BJn+7cdknSEy6KhIqCvuRUSZ/uKR3f+KUgIi2joC85laiEnqh6p7lfACJyNAV9adOSqssXkbg0tLKISIgo6IuIhIiCvohIiCjoi4iEiIK+iEiIKOhL3pqy4FV16RQ5grpsSrsX743eRG/z3rp7D107HUtRrI0ai1/ylIK+tGupvNG778Bhig5u07DMEioK+tKuNfdGb6K3eZ/55UC2H+pAUqP2aFhmaacU9CVvJXqbd/Hx347sNzPGfhqWWfKUgr5ILKrLlzyl3jsiIiGioC8iEiIK+iIiIZJ00DezU83sRTOrNrNNZvbdIP12M9tpZuuCz0VRx9xsZlvN7B0zG5eOGxARkZZLpSH3EPADd3/TzLoBa83s+WDbXe4+N3pnMysBpgKDgD7AH81soLsfTiEPIiLSCkmX9N29zt3fDJb3Am8DfZs5ZBLwiLt/5u7vAluBs5O9voiItF5a6vTNrAg4C1gTJN1gZuvN7D4zOyFI6wvsiDqsljhfEmZWaWZVZlZVX1+fjiyKZNf9E9SXX9qklPvpm9mXgceB77l7g5nNA2YDHvz9FfDN1pzT3RcCCwHKy8s91TyKZMSuDfEDe6JhHDSEg+RISkHfzDoSCfhL3P0/Adz9g6jt9wBPBas7gVOjDi8M0kTan1OGJH+shnCQHEo66JuZAfcCb7v7r6PSe7t7XbA6GdgYLK8AHjKzXxNpyC0GXk/2+iI5lUopXdU+kkOplPRHA1cDG8xsXZB2CzDNzEqJVO9sB64DcPdNZvYoUE2k58/16rkjbVWiwdpE2qukg767vwRYjE3PNHPMHGBOstcUSbdkx+KHyLDOzY3y2ayWtAecMjT2drUHSAo04JqEVipj8Td+KSRF7QGSQwr6ElqpjMWf0jSMiUrpzQ3rrPYASZGCvkgMOa3L17DOkkEacE1EJERU0hdpb1JpBAY1BIecgr5Ie5JKIzCoIVgU9EWSFa+7Z+M2gJLesXsIJd3dM9USuhqCQ09BXyQJOevuKZIiBX2RJCT9UhYpdvcUSZF674iIhIhK+iI5kJP2ABEU9EWyLuftAfG6fKq7Zygo6ItkWU7bAzTuT+gp6Iu0M6lUDcEkSvpcndwXj7p75gUFfZF2JJWqIUhD9ZCqhto9BX2RdiTVBtyUqodSqRp676XIJ14VkeYQyBoFfZGQSTRxTEaqhp69Kfk2AbUlpJWCvkiIpFI9tObdj1nz7sdUv59MFVGKbQnNDTLXEvql0ERBXyREUqke+umTm+IG/ES/EjI601iiqqFEVUvJaqftGFkP+mY2Hvg3oAPwW3dvW/8iIhJTql1Nk+91lMKvBGi+aqklgTtZqX7ZZOgLI6tB38w6AP8BfA2oBd4wsxXuXp3NfIhIdiWqVorfjpC4WqklbRGRTww9g78Hms1e7Ot+Flz3QOzrTu8yn5Jj3qMo3gma+8LJYDtGtkv6ZwNb3X0bgJk9QuRpZCTo//TET+i6cmYmTi0irdERupye3KH9vvwp+w4cZnuc7Y3njbe9OR//7UIAep72bKuPTXTdH3z5INCd7nSMvcMpZ8c99+m9evJoq3PUMtkO+n2BHVHrtcDII3cys0qgMlj9xMzeSfJ6J8JbHyV5bHt1IqB7zm9hu1/I2D3/Z/pPmQavA8ZbJ/JNS/ae437FtsmGXHdfCCxM9TxmVuXu5WnIUruhe85/Ybtf0D2nU7aHVt4JnBq1XhikiYhIFmQ76L8BFJtZPzPrBEwFVmQ5DyIioZXV6h13P2RmNwDPEemyeZ+7b8rgJVOuImqHdM/5L2z3C7rntDF3z8R5RUSkDdJ0iSIiIaKgLyISInkZ9M1svJm9Y2ZbzeymXOcnE8zsVDN70cyqzWyTmX03SO9pZs+b2Zbg7wm5zmu6mVkHM/uLmT0VrPczszXB814adBLIG2bWw8yWmdlmM3vbzM7N9+dsZt8P/l9vNLOHzaxzvj1nM7vPzD40s41RaTGfq0XcHdz7ejMbnux18y7oRw31cCFQAkwzs5Lc5iojDgE/cPcS4Bzg+uA+bwJecPdi4IVgPd98F3g7av0O4C53/1/A34Fv5SRXmfNvwEp3PxMYRuTe8/Y5m1lf4Eag3N0HE+n0MZX8e86LgPFHpMV7rhcCxcGnEpiX7EXzLugTNdSDux8AGod6yCvuXufubwbLe4kEgr5E7nVxsNti4NKcZDBDzKwQmAD8Nlg34HxgWbBLXt2zmR0PjAXuBXD3A+7+D/L8ORPpWfglMzsW6ALUkWfP2d1XAR8fkRzvuU4CHvCI14AeZtY7mevmY9CPNdRD3xzlJSvMrAg4C1gDnOzudcGmXcDJucpXhvxf4F+Bz4P1XsA/3P1QsJ5vz7sfUA/cH1Rp/dbMupLHz9nddwJzgb8RCfZ7gLXk93NuFO+5pi2u5WPQDxUz+zLwOPA9d//CMIQe6Y+bN31yzexi4EN3X5vrvGTRscBwYJ67nwV8yhFVOXn4nE8gUrLtB/QBunJ0NUjey9RzzcegH5qhHsysI5GAv8TdG0eO+qDxZ1/w98Nc5S8DRgMTzWw7kWq784nUd/cIqgEg/553LVDr7muC9WVEvgTy+Tn/E/Cuu9e7+0Eio6KNJr+fc6N4zzVtcS0fg34ohnoI6rLvBd52919HbVoBTA+WpwNPZDtvmeLuN7t7obsXEXmuf3L3fwFeBC4Pdsu3e94F7DCzM4KkC4gMRZ63z5lItc45ZtYl+H/eeM95+5yjxHuuK4Brgl485wB7oqqBWsfd8+4DXAT8FagBfpzr/GToHiuI/PRbD6wLPhcRqeN+AdgC/BHomeu8Zuj+zwOeCpb7ExmNdivwGHBcrvOX5nstBaqCZ70cOCHfnzPwU2AzsBH4HXBcvj1n4GEibRYHifyi+1a85woYkV6JNcAGIj2bkrquhmEQEQmRfKzeERGROBT0RURCREFfRCREFPRFREJEQV9EJEQU9EVSZGbfM7Muuc6HSEuoy6ZIioI3hMvd/aNc50UkkazOkSvSngUD260kMvjXcGATsIrI+DAvmtlH7v7V3OVQJDFV74i0zhnA/3P3rwANQCfgfeCrCvjSHijoi7TODnd/OVh+kMhwGCLthoK+SOsc2QimRjFpVxT0RVrnNDM7N1j+Z+AlYC/QLXdZEmk5BX2R1nmHyHzEbxMZ7XIesBBYaWYv5jRnIi2gLpsiLRT03nnKI5N1i7RLKumLiISISvoiIiGikr6ISIgo6IuIhIiCvohIiCjoi4iEiIK+iEiI/H+aryEGV8/c/AAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import numpy as np\n", + "import hist\n", + "import matplotlib.pyplot as plt\n", + "\n", + "dists = (\n", + " hist.Hist.new\n", + " .StrCat([\"gen1\", \"gen2\", \"gen2rwt\"], name=\"dataset\")\n", + " .Reg(20, 0, 100, name=\"pt\")\n", + " .Reg(4, -3, 3, name=\"eta\")\n", + " .Weight()\n", + " .fill(\n", + " dataset=\"gen1\",\n", + " pt=np.random.exponential(scale=10.0, size=10000) + np.random.exponential(scale=10.0, size=10000),\n", + " eta=np.random.normal(scale=1, size=10000)\n", + " )\n", + " .fill(\n", + " dataset=\"gen2\",\n", + " pt=np.random.exponential(scale=10.0, size=10000) + np.random.exponential(scale=15.0, size=10000),\n", + " eta=np.random.normal(scale=1.1, size=10000)\n", + " )\n", + ")\n", + "\n", + "fig, ax = plt.subplots()\n", + "dists[:, :, sum].plot1d(ax=ax)\n", + "ax.legend(title=\"dataset\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we derive a correction as a function of $p_T$ and $\\eta$ to `gen2` such that it agrees with `gen1`. We'll set it to 1 anywhere we run out of statistics for the correction, to avoid divide by zero issues" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2 dimensional histogram with axes:\n", + "\t1: [ 0. 5. 10. 15. 20. 25. 30. 35. 40. 45. 50. 55. 60. 65.\n", + " 70. 75. 80. 85. 90. 95. 100.]\n", + "\t2: [-3. -1.5 0. 1.5 3. ]\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "ColormeshArtists(pcolormesh=, cbar=, text=[])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "from coffea.lookup_tools.dense_lookup import dense_lookup\n", + "\n", + "num = dists[\"gen1\", :, :].values()\n", + "den = dists[\"gen2\", :, :].values()\n", + "sf = np.where(\n", + " (num > 0) & (den > 0),\n", + " num / np.maximum(den, 1) * den.sum() / num.sum(),\n", + " 1.0,\n", + ")\n", + "\n", + "corr = dense_lookup(sf, [ax.edges for ax in dists.axes[1:]])\n", + "print(corr)\n", + "\n", + "# a quick way to plot the scale factor is to steal the axis definitions from the input histograms:\n", + "sfhist = hist.Hist(*dists.axes[1:], data=sf)\n", + "sfhist.plot2d()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we generate some new mock data as if it was drawn from `gen2` and reweight it with our `corr` to match `gen1`" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "ptvals = np.random.exponential(scale=10.0, size=10000) + np.random.exponential(scale=15.0, size=10000)\n", + "etavals = np.random.normal(scale=1.1, size=10000)\n", + "\n", + "dists.fill(\n", + " dataset=\"gen2rwt\",\n", + " pt=ptvals,\n", + " eta=etavals,\n", + " weight=corr(ptvals, etavals)\n", + ")\n", + "\n", + "fig, ax = plt.subplots()\n", + "dists[:, :, sum].plot1d(ax=ax)\n", + "ax.legend(title=\"dataset\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that `corr()` can accept also jagged arrays if need be." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## CMS high-level tools\n", + "\n", + "### Applying energy scale transformations with jetmet_tools\n", + "\n", + "The `coffea.jetmet_tools` package provides a convenience class [JetTransformer](https://coffeateam.github.io/coffea/api/coffea.jetmet_tools.JetTransformer.html#coffea.jetmet_tools.JetTransformer) which applies specified corrections and computes uncertainties in one call. First we build the desired jet correction stack to apply. This will usually be some set of the various JEC and JER correction text files that depends on the jet cone size (AK4, AK8) and the pileup mitigation algorithm, as well as the data-taking year they are associated with." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi', 'Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi']\n" + ] + } + ], + "source": [ + "from coffea.jetmet_tools import FactorizedJetCorrector, JetCorrectionUncertainty\n", + "from coffea.jetmet_tools import JECStack, CorrectedJetsFactory\n", + "import awkward as ak\n", + "import numpy as np\n", + "\n", + "ext = extractor()\n", + "ext.add_weight_sets([\n", + " \"* * data/Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi.jec.txt\",\n", + " \"* * data/Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi.junc.txt\",\n", + "])\n", + "ext.finalize()\n", + "\n", + "jec_stack_names = [\n", + " \"Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi\",\n", + " \"Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi\"\n", + "]\n", + "\n", + "evaluator = ext.make_evaluator()\n", + "\n", + "jec_inputs = {name: evaluator[name] for name in jec_stack_names}\n", + "jec_stack = JECStack(jec_inputs)\n", + "### more possibilities are available if you send in more pieces of the JEC stack\n", + "# mc2016_ak8_jxform = JECStack([\"more\", \"names\", \"of\", \"JEC parts\"])\n", + "\n", + "print(dir(evaluator))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we prepare some auxilary variables that are used to parameterize the jet energy corrections, such as jet area, mass, and event $\\rho$ (mean pileup energy density), and pass all of these into the `CorrectedJetsFactory`:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "starting columns: {'btagCSVV2', 'electronIdx1', 'electronIdx2', 'eta', 'muonSubtrFactor', 'btagCMVA', 'bRegCorr', 'btagDeepFlavB', 'jercCHPUF', 'chEmEF', 'pt_raw', 'muonIdx2', 'nMuons', 'cleanmask', 'muonIdx1G', 'genJetIdxG', 'puId', 'muEF', 'mass', 'genJetIdx', 'muonIdx1', 'area', 'hadronFlavour', 'btagDeepC', 'qgl', 'rawFactor', 'mass_raw', 'partonFlavour', 'phi', 'btagDeepFlavC', 'nElectrons', 'electronIdx2G', 'rho', 'btagDeepB', 'neHEF', 'pt_gen', 'muonIdx2G', 'neEmEF', 'electronIdx1G', 'jercCHF', 'muonIdxG', 'jetId', 'nConstituents', 'electronIdxG', 'bRegRes', 'pt', 'chHEF'}\n", + "new columns: {'jet_energy_correction', 'mass_orig', 'pt_orig', 'pt_jec', 'JES_jes', 'mass_jec', 'jet_energy_uncertainty_jes'}\n" + ] + } + ], + "source": [ + "name_map = jec_stack.blank_name_map\n", + "name_map['JetPt'] = 'pt'\n", + "name_map['JetMass'] = 'mass'\n", + "name_map['JetEta'] = 'eta'\n", + "name_map['JetA'] = 'area'\n", + "\n", + "jets = events.Jet\n", + " \n", + "jets['pt_raw'] = (1 - jets['rawFactor']) * jets['pt']\n", + "jets['mass_raw'] = (1 - jets['rawFactor']) * jets['mass']\n", + "jets['pt_gen'] = ak.values_astype(ak.fill_none(jets.matched_gen.pt, 0), np.float32)\n", + "jets['rho'] = ak.broadcast_arrays(events.fixedGridRhoFastjetAll, jets.pt)[0]\n", + "name_map['ptGenJet'] = 'pt_gen'\n", + "name_map['ptRaw'] = 'pt_raw'\n", + "name_map['massRaw'] = 'mass_raw'\n", + "name_map['Rho'] = 'rho'\n", + " \n", + "events_cache = events.caches[0]\n", + "corrector = FactorizedJetCorrector(\n", + " Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi=evaluator['Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi'],\n", + ")\n", + "uncertainties = JetCorrectionUncertainty(\n", + " Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi=evaluator['Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi']\n", + ")\n", + "\n", + "jet_factory = CorrectedJetsFactory(name_map, jec_stack)\n", + "corrected_jets = jet_factory.build(jets, lazy_cache=events_cache)\n", + "\n", + "print('starting columns:', set(ak.fields(jets)))\n", + "print('new columns:', set(ak.fields(corrected_jets)) - set(ak.fields(jets)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below we show that the corrected jets indeed have a different $p_T$ and mass than we started with" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "untransformed pt ratios [[1.12, 1.09, 1.2, 1.35, 1.27], [1.03, ... 1.28, 1.1, 1.13, 0.989], [1.13, 0.978]]\n", + "untransformed mass ratios [[1.12, 1.09, 1.2, 1.35, 1.27], [1.03, ... 1.28, 1.1, 1.13, 0.989], [1.13, 0.978]]\n", + "transformed pt ratios [[1.2, 1.3, 1.46, 2.09, 2.1], [1.09, 1.29, ... 1.84, 1.47, 1.36, 1.16], [1.37, 1.15]]\n", + "transformed mass ratios [[1.2, 1.3, 1.46, 2.09, 2.1], [1.09, 1.29, ... 1.84, 1.47, 1.36, 1.16], [1.37, 1.15]]\n", + "JES UP pt ratio [[1.22, 1.35, 1.56, 2.34, 2.37], [1.1, ... 2.07, 1.52, 1.41, 1.2], [1.41, 1.17]]\n", + "JES DOWN pt ratio [[1.19, 1.25, 1.35, 1.83, 1.83], [1.08, ... 1.6, 1.41, 1.32, 1.13], [1.33, 1.12]]\n" + ] + } + ], + "source": [ + "print('untransformed pt ratios', jets.pt/jets.pt_raw)\n", + "print('untransformed mass ratios', jets.mass/jets.mass_raw)\n", + "\n", + "print('transformed pt ratios', corrected_jets.pt/corrected_jets.pt_raw)\n", + "print('transformed mass ratios', corrected_jets.mass/corrected_jets.mass_raw)\n", + "\n", + "print('JES UP pt ratio', corrected_jets.JES_jes.up.pt/corrected_jets.pt_raw)\n", + "print('JES DOWN pt ratio', corrected_jets.JES_jes.down.pt/corrected_jets.pt_raw)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Applying CMS b-tagging corrections with btag_tools\n", + "The `coffea.btag_tools` module provides the high-level utility [BTagScaleFactor](https://coffeateam.github.io/coffea/api/coffea.btag_tools.BTagScaleFactor.html#coffea.btag_tools.BTagScaleFactor) which calculates per-jet weights for b-tagging as well as light flavor mis-tagging efficiencies. Uncertainties can be calculated as well." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SF: [[1.52, 1.56, 1.59, 1.6, 1.6], [0.969, 1.57, ... 1.59, 1.6, 1.6, 1.6], [1.6, 1.6]]\n", + "systematic +: [[1.72, 1.77, 1.79, 1.8, 1.8], [1.01, 1.78, ... 1.8, 1.8, 1.8, 1.8], [1.8, 1.8]]\n", + "systematic -: [[1.31, 1.36, 1.38, 1.4, 1.4], [0.925, 1.37, ... 1.39, 1.4, 1.4, 1.4], [1.4, 1.4]]\n" + ] + } + ], + "source": [ + "from coffea.btag_tools import BTagScaleFactor\n", + "\n", + "btag_sf = BTagScaleFactor(\"data/DeepCSV_102XSF_V1.btag.csv.gz\", \"medium\")\n", + "\n", + "print(\"SF:\", btag_sf.eval(\"central\", events.Jet.hadronFlavour, abs(events.Jet.eta), events.Jet.pt))\n", + "print(\"systematic +:\", btag_sf.eval(\"up\", events.Jet.hadronFlavour, abs(events.Jet.eta), events.Jet.pt))\n", + "print(\"systematic -:\", btag_sf.eval(\"down\", events.Jet.hadronFlavour, abs(events.Jet.eta), events.Jet.pt))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using correctionlib\n", + "\n", + "For the most part, using correctionlib is straightforward. We'll show here how to convert the custom correction we derived earlier (`corr`) into a correctionlib object, and save it in the json format:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
CorrectionSet (schema v2)                                                                    \n",
+       "my custom corrections                                                                        \n",
+       "📂                                                                                           \n",
+       "└── 📈 gen2_to_gen1 (v0)                                                                     \n",
+       "    Reweights gen2 to agree with gen1                                                        \n",
+       "    Node counts: MultiBinning: 1                                                             \n",
+       "    ╭──────────── ▶ input ─────────────╮ ╭──────────── ▶ input ────────────╮                 \n",
+       "    │ pt (real)                        │ │ eta (real)                      │                 \n",
+       "    │ pt                               │ │ eta                             │                 \n",
+       "    │ Range: [0.0, 100.0), overflow ok │ │ Range: [-3.0, 3.0), overflow ok │                 \n",
+       "    ╰──────────────────────────────────╯ ╰─────────────────────────────────╯                 \n",
+       "    ╭─── ◀ output ───╮                                                                       \n",
+       "    │ out (real)     │                                                                       \n",
+       "    │ No description │                                                                       \n",
+       "    ╰────────────────╯                                                                       \n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1mCorrectionSet\u001b[0m (\u001b[3mschema v2\u001b[0m) \n", + "my custom corrections \n", + "📂 \n", + "└── 📈 \u001b[1mgen2_to_gen1\u001b[0m (v0) \n", + " Reweights gen2 to agree with gen1 \n", + " Node counts: \u001b[1mMultiBinning\u001b[0m: 1 \n", + " ╭──────────── ▶ input ─────────────╮ ╭──────────── ▶ input ────────────╮ \n", + " │ \u001b[1mpt\u001b[0m (real) │ │ \u001b[1meta\u001b[0m (real) │ \n", + " │ pt │ │ eta │ \n", + " │ Range: [0.0, 100.0), overflow ok │ │ Range: [-3.0, 3.0), overflow ok │ \n", + " ╰──────────────────────────────────╯ ╰─────────────────────────────────╯ \n", + " ╭─── ◀ output ───╮ \n", + " │ \u001b[1mout\u001b[0m (real) │ \n", + " │ \u001b[3mNo description\u001b[0m │ \n", + " ╰────────────────╯ \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import correctionlib, rich\n", + "import correctionlib.convert\n", + "\n", + "# without a name, the resulting object will fail validation\n", + "sfhist.name = \"gen2_to_gen1\"\n", + "sfhist.label = \"out\"\n", + "clibcorr = correctionlib.convert.from_histogram(sfhist)\n", + "clibcorr.description = \"Reweights gen2 to agree with gen1\"\n", + "# set overflow bins behavior (default is to raise an error when out of bounds)\n", + "clibcorr.data.flow = \"clamp\"\n", + "\n", + "cset = correctionlib.schemav2.CorrectionSet(\n", + " schema_version=2,\n", + " description=\"my custom corrections\",\n", + " corrections=[clibcorr],\n", + ")\n", + "rich.print(cset)\n", + "\n", + "with open(\"data/mycorrections.json\", \"w\") as fout:\n", + " fout.write(cset.json(exclude_unset=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now use this new correction in a similar way to the original `corr()` object:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1.55691586, 1.36319225, 1.36319225, ..., 1.55691586, 0.64304079,\n", + " 1.02863368])" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ceval = cset.to_evaluator()\n", + "\n", + "ceval[\"gen2_to_gen1\"].evaluate(ptvals, etavals)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At the time of writing, correctionlib does not support jagged arrays. But we can work around this using awkward utilities `flatten` and `unflatten`, as shown below" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def myJetSF(jets):\n", + " j, nj = ak.flatten(jets), ak.num(jets)\n", + " sf = ceval[\"gen2_to_gen1\"].evaluate(np.array(j.pt), np.array(j.eta))\n", + " return ak.unflatten(sf, nj)\n", + "\n", + "myJetSF(events.Jet)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/_sources/notebooks/histograms.ipynb.txt b/_sources/notebooks/histograms.ipynb.txt new file mode 100644 index 000000000..d14ddbe6d --- /dev/null +++ b/_sources/notebooks/histograms.ipynb.txt @@ -0,0 +1,1190 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Coffea Histograms (deprecated)\n", + "\n", + "_This feature is deprecated in favor of [hist](https://hist.readthedocs.io/en/latest/) and [mplhep](https://mplhep.readthedocs.io/en/latest/). A migration guide can be found in discussion [CoffeaTeam/coffea#705](https://github.com/CoffeaTeam/coffea/discussions/705)_\n", + "\n", + "This is a rendered copy of [histograms.ipynb](https://github.com/CoffeaTeam/coffea/blob/master/binder/histograms.ipynb). You can optionally run it interactively on [binder at this link](https://mybinder.org/v2/gh/coffeateam/coffea/master?filepath=binder%2Fhistograms.ipynb)\n", + "\n", + "In scientific python, histograms seem to be considered as a plot style, on equal footing with, e.g. scatter plots.\n", + "It may well be that HEP is the only place where users need to plot *pre-binned* data, and thus must use histograms as persistent objects representing reduced data. In Coffea, the [hist](https://coffeateam.github.io/coffea/modules/coffea.hist.html) subpackage provides a persistable mergable histogram object. This notebook will discuss a few ways that such objects can be manipulated.\n", + "\n", + "A histogram object roughly goes through three stages in its life:\n", + "\n", + " - Filling\n", + " - Transformation (projection, rebinning, integrating)\n", + " - Plotting\n", + "\n", + "We'll go over examples of each stage in this notebook, and conclude with some styling examples." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Filling\n", + "Let's start with filling. We'll use a random distribution [near and dear](https://en.wikipedia.org/wiki/ARGUS_distribution) to of b and c factory physicists, and have the numpy builtin [histogram function](https://numpy.org/doc/stable/reference/generated/numpy.histogram.html) do the work for us:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(array([ 16, 47, 66, 95, 125, 113, 137, 167, 143, 91]), array([0.002894 , 0.10257766, 0.20226132, 0.30194498, 0.40162865,\n", + " 0.50131231, 0.60099597, 0.70067963, 0.80036329, 0.90004695,\n", + " 0.99973061]))\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from scipy.stats import argus\n", + "\n", + "vals = argus(chi=.5).rvs(size=1000)\n", + "\n", + "hist = np.histogram(vals)\n", + "print(hist)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So we're done, right?\n", + "Probably not: we have more than 1000 events, and probably need to use some map-reduce paradigm to fill the histogram because we can't keep all 1 billion `vals` in memory. So we need two things: a binning, so that all histograms that were independently created can be added, and the ability to add two histograms." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "binning = np.linspace(0, 1, 50)\n", + "\n", + "def add_histos(h1, h2):\n", + " h1sumw, h1binning = h1\n", + " h2sumw, h2binning = h2\n", + " if h1binning.shape == h2binning.shape and np.all(h1binning==h2binning):\n", + " return h1sumw+h2sumw, h1binning\n", + " else:\n", + " raise ValueError(\"The histograms have inconsistent binning\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(array([ 2, 6, 6, 6, 12, 18, 20, 16, 14, 28, 22, 26, 28, 42, 18, 34, 28,\n", + " 48, 40, 42, 42, 60, 46, 62, 46, 52, 46, 38, 52, 54, 50, 58, 72, 54,\n", + " 50, 74, 80, 58, 70, 70, 42, 64, 68, 52, 60, 32, 44, 30, 18]), array([0. , 0.02040816, 0.04081633, 0.06122449, 0.08163265,\n", + " 0.10204082, 0.12244898, 0.14285714, 0.16326531, 0.18367347,\n", + " 0.20408163, 0.2244898 , 0.24489796, 0.26530612, 0.28571429,\n", + " 0.30612245, 0.32653061, 0.34693878, 0.36734694, 0.3877551 ,\n", + " 0.40816327, 0.42857143, 0.44897959, 0.46938776, 0.48979592,\n", + " 0.51020408, 0.53061224, 0.55102041, 0.57142857, 0.59183673,\n", + " 0.6122449 , 0.63265306, 0.65306122, 0.67346939, 0.69387755,\n", + " 0.71428571, 0.73469388, 0.75510204, 0.7755102 , 0.79591837,\n", + " 0.81632653, 0.83673469, 0.85714286, 0.87755102, 0.89795918,\n", + " 0.91836735, 0.93877551, 0.95918367, 0.97959184, 1. ]))\n" + ] + } + ], + "source": [ + "vals2 = argus(chi=.5).rvs(size=1000)\n", + "\n", + "hist1 = np.histogram(vals, bins=binning)\n", + "hist2 = np.histogram(vals, bins=binning)\n", + "\n", + "hist = add_histos(hist1, hist2)\n", + "print(hist)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So now we have everything we need to make our own equivalent to ROOT TH1, from a filling perspective:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "class myTH1:\n", + " def __init__(self, binning):\n", + " self._binning = binning\n", + " self._sumw = np.zeros(binning.size - 1)\n", + " \n", + " def fill(self, values, weights=None):\n", + " sumw, _ = np.histogram(values, bins=self._binning, weights=weights)\n", + " self._sumw += sumw\n", + " \n", + " def __add__(self, other):\n", + " if not isinstance(other, myTH1):\n", + " raise ValueError\n", + " if not np.array_equal(other._binning, self._binning):\n", + " raise ValueError(\"The histograms have inconsistent binning\")\n", + " out = myTH1(self._binning)\n", + " out._sumw = self._sumw + other._sumw\n", + " return out" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 3. 3. 7. 5. 9. 18. 16. 17. 15. 24. 26. 27. 34. 37. 23. 38. 29. 46.\n", + " 40. 40. 36. 50. 47. 49. 57. 49. 50. 44. 59. 69. 55. 52. 68. 54. 48. 72.\n", + " 72. 64. 55. 74. 57. 64. 63. 55. 49. 39. 39. 31. 22.]\n" + ] + } + ], + "source": [ + "binning = np.linspace(0, 1, 50)\n", + "\n", + "h1 = myTH1(binning)\n", + "h1.fill(vals)\n", + "\n", + "h2 = myTH1(binning)\n", + "h2.fill(vals2)\n", + "\n", + "h = h1 + h2\n", + "print(h._sumw)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Homework: add `sumw2` support.\n", + "\n", + "Of course, we might want multidimensional histograms. There is `np.histogramdd`:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "xyz = np.random.multivariate_normal(mean=[1, 3, 7], cov=np.eye(3), size=10000)\n", + "\n", + "xbins = np.linspace(-10, 10, 20)\n", + "ybins = np.linspace(-10, 10, 20)\n", + "zbins = np.linspace(-10, 10, 20)\n", + "hnumpy = np.histogramdd(xyz, bins=(xbins, ybins, zbins))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "but we are becoming challenged by book-keeping of the variables.\n", + "The [histogram class](https://coffeateam.github.io/coffea/api/coffea.hist.Hist.html#coffea.hist.Hist) in Coffea is designed to simplify this operation, and the eventual successor (for filling purposes) [boost-histogram](https://github.com/scikit-hep/boost-histogram#usage) has similar syntax.\n", + "\n", + "In the constructor you specify each axis, either as a numeric `Bin` axis or a categorical `Cat` axis. Each axis constructor takes arguments similar to ROOT TH1 constructors. One can pass an array to the `Bin` axis for non-uniform binning. Then the fill call is as simple as passing the respective arrays to `histo.fill`." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "import coffea.hist as hist\n", + "\n", + "histo = hist.Hist(\"Counts\",\n", + " hist.Cat(\"sample\", \"sample name\"),\n", + " hist.Bin(\"x\", \"x value\", 20, -10, 10),\n", + " hist.Bin(\"y\", \"y value\", 20, -10, 10),\n", + " hist.Bin(\"z\", \"z value\", 20, -10, 10),\n", + " )\n", + "\n", + "histo.fill(sample=\"sample 1\", x=xyz[:,0], y=xyz[:,1], z=xyz[:,2])\n", + "\n", + "# suppose we have another sample of xyz values\n", + "xyz_sample2 = np.random.multivariate_normal(mean=[1, 3, 7], cov=np.eye(3), size=10000)\n", + "\n", + "# additionally, lets assume entries in sample 2 have some non-uniform weight equal to atan(distance from origin)\n", + "weight = np.arctan(np.sqrt(np.power(xyz_sample2, 2).sum(axis=1)))\n", + "\n", + "# weight is a reserved keyword in Hist, and can be added to any fill() call\n", + "histo.fill(sample=\"sample 2\", x=xyz_sample2[:,0], y=xyz_sample2[:,1], z=xyz_sample2[:,2], weight=weight)\n", + "\n", + "print(histo)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# For more details, look at:\n", + "# help(hist.Hist)\n", + "# help(hist.Bin)\n", + "# help(hist.Cat)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Transformation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are a few examples of transformations on multidimensional histograms in Coffea. For each, the docstring (`help(function)` or shift+tab in Jupyter) provides useful info." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# sum all x bins within nominal range (-10, 10)\n", + "histo.sum(\"x\", overflow='none')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is some analog to fancy array slicing for histogram objects, which is supported (with reasonable consistency) in Coffea, where the slice boundaries are physical axis values, rather than bin indices. All values outside the slice range are merged into overflow bins.\n", + "\n", + "For a lengthy discussion on possible slicing syntax for the future, see [boost-histogram#35](https://github.com/scikit-hep/boost-histogram/issues/35)." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sliced = histo[:,0:,4:,0:]\n", + "display(sliced)\n", + "display(sliced.identifiers(\"y\", overflow='all'))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# integrate y bins from -2 to +10\n", + "histo.integrate(\"y\", slice(0, 10))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# rebin z axis by providing a new axis definition\n", + "histo.rebin(\"z\", hist.Bin(\"znew\", \"rebinned z value\", [-10, -6, 6, 10]))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# merge categorical axes\n", + "mapping = {\n", + " 'all samples': ['sample 1', 'sample 2'],\n", + " 'just sample 1': ['sample 1'],\n", + "}\n", + "histo.group(\"sample\", hist.Cat(\"cat\", \"new category\"), mapping)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# scale entire histogram by 3 (in-place)\n", + "histo.scale(3.)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# scale samples by different values (also in-place)\n", + "scales = {\n", + " 'sample 1': 1.2,\n", + " 'sample 2': 0.2,\n", + "}\n", + "histo.scale(scales, axis='sample')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# useful debugging tool: print bins, aka 'identifiers'\n", + "display(histo.identifiers('sample'))\n", + "display(histo.identifiers('x'))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{('sample 1',): array([0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00,\n", + " 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00,\n", + " 0.00000e+00, 0.00000e+00, 3.60000e+00, 5.40000e+01, 7.23600e+02,\n", + " 4.83120e+03, 1.24164e+04, 1.24344e+04, 4.68720e+03, 8.13600e+02]),\n", + " ('sample 2',): array([0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 7.67352230e-01, 1.23975181e+01, 1.91084135e+02, 1.16950599e+03,\n", + " 3.00209800e+03, 2.88614286e+03, 1.20687727e+03, 1.68492970e+02])}" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# bin contents are accessed using values\n", + "histo.sum('x', 'y').values(sumw2=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/lagray/miniconda3/envs/coffea-work/lib/python3.7/site-packages/uproot3/__init__.py:138: FutureWarning: Consider switching from 'uproot3' to 'uproot', since the new interface became the default in 2020.\n", + "\n", + " pip install -U uproot\n", + "\n", + "In Python:\n", + "\n", + " >>> import uproot\n", + " >>> with uproot.open(...) as file:\n", + " ...\n", + "\n", + " FutureWarning\n" + ] + } + ], + "source": [ + "# data can be exported to ROOT via uproot3 (soon uproot v4 as well), but only 1D\n", + "import uproot3\n", + "import os\n", + "\n", + "if os.path.exists(\"output.root\"):\n", + " os.remove(\"output.root\")\n", + "\n", + "outputfile = uproot3.create(\"output.root\")\n", + "h = histo.sum('x', 'y')\n", + "for sample in h.identifiers('sample'):\n", + " outputfile[sample.name] = hist.export1d(h.integrate('sample', sample))\n", + "outputfile.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plotting\n", + "The most integrated plotting utility in the scientific python ecosystem, by far, is [matplotlib](https://matplotlib.org/). However, as we will see, it is not tailored to HEP needs.\n", + "\n", + "Let's start by looking at basic mpl histogramming." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD4CAYAAAAXUaZHAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAPo0lEQVR4nO3dfayed13H8feH1YFDoIMeltlOT5GC1qlhORkjJIiU4BhkXSJZuogUbGyAiSgkUCBxRkOyRQUhIlrZXGdwbE50jQN1li2LhBbPHtgjD2XsobVbD+7BByJQ+frHfUGO3enOfe7H7bf3Kzk51/W7nr6/3qefc53ffV3XnapCktSWp027AEnS6BnuktQgw12SGmS4S1KDDHdJatCqaRcAsGbNmpqdnZ12GZL0pHLjjTd+s6pmllr2hAj32dlZ5ufnp12GJD2pJLn3WMsclpGkBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1yHCXpAY9Ie5QlfRYszuumcpx77nwdVM5rkbLcJf0/0zrlwr4i2WUlh2WSXJJksNJbl9i2buTVJI13XySfDTJ/iS3JjltHEVLkh5fP2fulwJ/DFy2uDHJKcBrgPsWNb8W2NB9vRT4ePddkpblUNToLHvmXlU3AA8tsejDwHuAxZ+wvRm4rHr2AquTnDySSiVJfRvoapkkm4GDVfWloxatBe5fNH+ga1tqH9uTzCeZX1hYGKQMSdIxrDjck5wAvB/47WEOXFU7q2ququZmZpZ81rwkaUCDXC3zE8B64EtJANYBNyU5HTgInLJo3XVdmyRpglZ85l5Vt1XV86tqtqpm6Q29nFZVDwC7gTd1V82cATxaVYdGW7IkaTn9XAp5OfAF4MVJDiTZ9jirfwa4G9gP/Dnw9pFUKUlakWWHZarqvGWWzy6aLuD84cuSJA3DZ8tIUoMMd0lqkOEuSQ0y3CWpQYa7JDXIcJekBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGDPM9dmrhpfbYmtPn5mmqfZ+6S1CDDXZIa5LCMtIxpDglJg/LMXZIaZLhLUoMMd0lqkOEuSQ1aNtyTXJLkcJLbF7X9fpIvJ7k1yd8mWb1o2fuS7E/ylSS/OKa6JUmPo58z90uBM49quxY4tap+Fvgq8D6AJBuBLcBPd9v8SZLjRlatJKkvy4Z7Vd0APHRU2z9V1ZFudi+wrpveDHyqqr5dVd8A9gOnj7BeSVIfRjHm/qvAZ7vptcD9i5Yd6NoeI8n2JPNJ5hcWFkZQhiTp+4YK9yQfAI4An1zptlW1s6rmqmpuZmZmmDIkSUcZ+A7VJG8GXg9sqqrqmg8CpyxabV3XJkmaoIHO3JOcCbwHOLuqvrVo0W5gS5KnJ1kPbAC+OHyZkqSVWPbMPcnlwCuBNUkOABfQuzrm6cC1SQD2VtVbq+qOJFcCd9Ibrjm/qv53XMVLkpa2bLhX1XlLNF/8OOt/EPjgMEVJkobjHaqS1CDDXZIaZLhLUoMMd0lqkOEuSQ0y3CWpQYa7JDXIcJekBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1yHCXpAYZ7pLUIMNdkhpkuEtSgwx3SWrQsh+QneQS4PXA4ao6tWt7LnAFMAvcA5xbVQ8nCfAR4CzgW8Cbq+qm8ZSuaZjdcc20S5DUh37O3C8FzjyqbQewp6o2AHu6eYDXAhu6r+3Ax0dTpiRpJZYN96q6AXjoqObNwK5uehdwzqL2y6pnL7A6yckjqlWS1KdBx9xPqqpD3fQDwEnd9Frg/kXrHejaHiPJ9iTzSeYXFhYGLEOStJRlx9yXU1WVpAbYbiewE2Bubm7F20vSqEzzvaR7LnzdWPY76Jn7g98fbum+H+7aDwKnLFpvXdcmSZqgQcN9N7C1m94KXL2o/U3pOQN4dNHwjSRpQvq5FPJy4JXAmiQHgAuAC4Erk2wD7gXO7Vb/DL3LIPfTuxTyLWOoWZK0jGXDvarOO8aiTUusW8D5wxYlSRqOd6hKUoMMd0lqkOEuSQ0y3CWpQYa7JDXIcJekBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1yHCXpAYZ7pLUIMNdkhpkuEtSgwx3SWqQ4S5JDTLcJalBQ4V7kt9KckeS25NcnuQZSdYn2Zdkf5Irkhw/qmIlSf0ZONyTrAV+A5irqlOB44AtwEXAh6vqhcDDwLZRFCpJ6t+wwzKrgB9Osgo4ATgEvAq4qlu+CzhnyGNIklZo4HCvqoPAHwD30Qv1R4EbgUeq6ki32gFg7VLbJ9meZD7J/MLCwqBlSJKWMMywzInAZmA98KPAM4Ez+92+qnZW1VxVzc3MzAxahiRpCcMMy7wa+EZVLVTVd4FPAy8HVnfDNADrgIND1ihJWqFhwv0+4IwkJyQJsAm4E7gOeEO3zlbg6uFKlCSt1DBj7vvovXF6E3Bbt6+dwHuBdyXZDzwPuHgEdUqSVmDV8qscW1VdAFxwVPPdwOnD7FeSNBzvUJWkBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1yHCXpAYZ7pLUIMNdkhpkuEtSgwx3SWqQ4S5JDTLcJalBhrskNchwl6QGGe6S1CDDXZIaNFS4J1md5KokX05yV5KXJXlukmuTfK37fuKoipUk9WfYM/ePAP9QVT8J/BxwF7AD2FNVG4A93bwkaYIGDvckzwFeAVwMUFXfqapHgM3Arm61XcA5w5UoSVqpYc7c1wMLwF8kuTnJJ5I8Ezipqg516zwAnDRskZKklRkm3FcBpwEfr6qXAP/NUUMwVVVALbVxku1J5pPMLywsDFGGJOlow4T7AeBAVe3r5q+iF/YPJjkZoPt+eKmNq2pnVc1V1dzMzMwQZUiSjjZwuFfVA8D9SV7cNW0C7gR2A1u7tq3A1UNVKElasVVDbv8O4JNJjgfuBt5C7xfGlUm2AfcC5w55DEnSCg0V7lV1CzC3xKJNw+xXkjQc71CVpAYZ7pLUoGHH3DUFszuumXYJkp7gPHOXpAYZ7pLUIMNdkhpkuEtSgwx3SWqQ4S5JDTLcJalBhrskNchwl6QGGe6S1CDDXZIaZLhLUoMMd0lqkOEuSQ0y3CWpQYa7JDXID+sYgh+aIemJaugz9yTHJbk5yd938+uT7EuyP8kVSY4fvkxJ0kqMYljmncBdi+YvAj5cVS8EHga2jeAYkqQVGCrck6wDXgd8opsP8Crgqm6VXcA5wxxDkrRyw565/xHwHuB73fzzgEeq6kg3fwBYu9SGSbYnmU8yv7CwMGQZkqTFBg73JK8HDlfVjYNsX1U7q2ququZmZmYGLUOStIRhrpZ5OXB2krOAZwDPBj4CrE6yqjt7XwccHL5MSdJKDHzmXlXvq6p1VTULbAE+V1W/DFwHvKFbbStw9dBVSpJWZBw3Mb0XeFeS/fTG4C8ewzEkSY9jJDcxVdX1wPXd9N3A6aPYryRpMD5+QJIaZLhLUoMMd0lqkOEuSQ0y3CWpQYa7JDXIcJekBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1yHCXpAYZ7pLUIMNdkhpkuEtSgwx3SWqQ4S5JDRo43JOckuS6JHcmuSPJO7v25ya5NsnXuu8njq5cSVI/hjlzPwK8u6o2AmcA5yfZCOwA9lTVBmBPNy9JmqCBw72qDlXVTd30fwJ3AWuBzcCubrVdwDlD1ihJWqGRjLknmQVeAuwDTqqqQ92iB4CTjrHN9iTzSeYXFhZGUYYkqTN0uCf5EeBvgN+sqv9YvKyqCqiltquqnVU1V1VzMzMzw5YhSVpkqHBP8kP0gv2TVfXprvnBJCd3y08GDg9XoiRppVYNumGSABcDd1XVhxYt2g1sBS7svl89VIXLmN1xzTh3L0lPSgOHO/By4FeA25Lc0rW9n16oX5lkG3AvcO5QFUqSVmzgcK+qfwFyjMWbBt2vJGl43qEqSQ0y3CWpQYa7JDXIcJekBhnuktQgw12SGmS4S1KDDHdJapDhLkkNMtwlqUGGuyQ1yHCXpAYZ7pLUIMNdkhpkuEtSgwx3SWqQ4S5JDTLcJalBhrskNchwl6QGjS3ck5yZ5CtJ9ifZMa7jSJIeayzhnuQ44GPAa4GNwHlJNo7jWJKkxxrXmfvpwP6quruqvgN8Ctg8pmNJko6yakz7XQvcv2j+APDSxSsk2Q5s72b/K8lXgDXAN8dU05OB/bf/9v8pJhf9YHKQ/v/4sRaMK9yXVVU7gZ2L25LMV9XclEqaOvtv/+2//R/V/sY1LHMQOGXR/LquTZI0AeMK938FNiRZn+R4YAuwe0zHkiQdZSzDMlV1JMmvA/8IHAdcUlV39LHpzuVXaZr9f2qz/09tI+1/qmqU+5MkPQF4h6okNchwl6QGTSXcl3s0QZKnJ7miW74vyewUyhybPvr/riR3Jrk1yZ4kx7yW9cmo30dTJPmlJJWkqcvj+ul/knO7n4E7kvzVpGscpz5+/n8syXVJbu7+D5w1jTrHIcklSQ4nuf0Yy5Pko92/za1JThv4YFU10S96b7B+HXgBcDzwJWDjUeu8HfjTbnoLcMWk65xy/38BOKGbfttTrf/des8CbgD2AnPTrnvCr/8G4GbgxG7++dOue8L93wm8rZveCNwz7bpH2P9XAKcBtx9j+VnAZ4EAZwD7Bj3WNM7c+3k0wWZgVzd9FbApSSZY4zgt2/+quq6qvtXN7qV3n0Ar+n00xe8BFwH/M8niJqCf/v8a8LGqehigqg5PuMZx6qf/BTy7m34O8G8TrG+squoG4KHHWWUzcFn17AVWJzl5kGNNI9yXejTB2mOtU1VHgEeB502kuvHrp/+LbaP3m7wVy/a/+1P0lKq6ZpKFTUg/r/+LgBcl+XySvUnOnFh149dP/38HeGOSA8BngHdMprQnhJXmwzFN7fEDWl6SNwJzwM9Pu5ZJSfI04EPAm6dcyjStojc080p6f7XdkORnquqRaRY1QecBl1bVHyZ5GfCXSU6tqu9Nu7Ank2mcuffzaIIfrJNkFb0/zf59ItWNX1+PZkjyauADwNlV9e0J1TYJy/X/WcCpwPVJ7qE37ri7oTdV+3n9DwC7q+q7VfUN4Kv0wr4F/fR/G3AlQFV9AXgGvYdqPRWM7NEt0wj3fh5NsBvY2k2/Afhcde82NGDZ/id5CfBn9IK9pfFWWKb/VfVoVa2pqtmqmqX3nsPZVTU/nXJHrp+f/7+jd9ZOkjX0hmnunmCN49RP/+8DNgEk+Sl64b4w0SqnZzfwpu6qmTOAR6vq0EB7mtI7xmfROxv5OvCBru136f0nht6L+dfAfuCLwAum/S73hPv/z8CDwC3d1+5p1zzJ/h+17vU0dLVMn69/6A1N3QncBmyZds0T7v9G4PP0rqS5BXjNtGseYd8vBw4B36X3F9o24K3AWxe99h/r/m1uG+Zn38cPSFKDvENVkhpkuEtSgwx3SWqQ4S5JDTLcJalBhrskNchwl6QG/R+P5l+Y85xrwgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "vals = argus(chi=.5).rvs(size=1000)\n", + "\n", + "# notice the semicolon, which prevents display of the return values\n", + "plt.hist(vals);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Suppose we want to plot pre-binned data, for example from our earlier `np.histogram` usage. Here we start running into the edge of typical mpl usage. As mentioned before, apparently HEP is the only regular user of pre-binned histograms." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "binning = np.linspace(0, 1, 50)\n", + "\n", + "h1vals, h1bins = np.histogram(vals, bins=binning)\n", + "plt.step(x=h1bins[:-1], y=h1vals, where='post');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To facilitate these operations, there is a package called [mplhep](https://github.com/scikit-hep/mplhep). This package is available standlaone, but it is also used internally by the `coffea.hist` subpackage to provide several convenience functions to aid in plotting `Hist` objects:\n", + "\n", + " * [plot1d](https://coffeateam.github.io/coffea/api/coffea.hist.plot1d.html#coffea.hist.plot1d): Create a 1D plot from a 1D or 2D Hist object\n", + "\n", + " * [plotratio](https://coffeateam.github.io/coffea/api/coffea.hist.plotratio.html#coffea.hist.plotratio): Create a ratio plot, dividing two compatible histograms\n", + "\n", + " * [plot2d](https://coffeateam.github.io/coffea/api/coffea.hist.plot2d.html#coffea.hist.plot2d): Create a 2D plot from a 2D Hist object\n", + "\n", + " * [plotgrid](https://coffeateam.github.io/coffea/api/coffea.hist.plotgrid.html#coffea.hist.plotgrid): Create a grid of plots, enumerating identifiers on up to 3 axes\n", + " \n", + "Below are some simple examples of using each function on our `histo` object." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZwAAAEGCAYAAABRvCMcAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAh6ElEQVR4nO3de3xU1b338c+Pa+oFAUkBCR5AQQkXKYZb0VNOqYCiYi3eqpWiFVultbYi+OjLW/Vp9ZxHqz5V5CiKfXlBqT5QpSIottYCGiyCXCxRUYOgFBSKHEH09/yxV+IQZpJJMrNnknzfr9e8smfttff+zc5kfll7r1nL3B0REZFsa5brAEREpGlQwhERkVgo4YiISCyUcEREJBZKOCIiEosWuQ4gbh06dPBu3brlOgwRkQZl+fLl/3T3wvrso8klnG7dulFaWprrMEREGhQze7e++9AlNRERiYUSjoiIxEIJR0REYtHk7uEk8/nnn1NeXs5nn32W61AapIKCAoqKimjZsmWuQxGRPKaEA5SXl3PwwQfTrVs3zCzX4TQo7s7WrVspLy+ne/fuuQ5HRPKYLqkBn332GYceeqiSTR2YGYceeqhahyJSIyWcQMmm7nTuRCQdSjgiIhILJZw8M2LECH0xVUQaJSUcEZE6OOveJZx175Kc76MhUcKpwaeffsrYsWM55phj6Nu3L7NnzwbgxhtvZNCgQfTt25dJkyZRMXPqiBEjuPzyyykpKaF37968+uqrnH766fTs2ZNrrrkGgA0bNnD00Udz7rnn0rt3b8aPH8+uXbv2O/Zzzz3HsGHDGDhwIGeccQY7d+7cr86IESOYOnUqgwcPplevXrz00kuVxzj++OMZOHAgAwcO5G9/+xsAL774It/61rcYN24cPXr0YNq0aTz88MMMHjyYfv368dZbbwGwZcsWvve97zFo0CAGDRrEyy+/nPmTKyJNirpF1+DZZ5/lsMMO45lnngFg+/btAEyePJlrr70WgB/84Ac8/fTTnHLKKQC0atWK0tJS7rjjDsaNG8fy5ctp3749RxxxBJdffjkAb775Jvfffz/Dhw/nggsu4O677+aKK66oPO4///lPbrrpJhYtWsSBBx7ILbfcwm233VZ5zER79+7llVdeYf78+dxwww0sWrSIr3/96yxcuJCCggLWr1/POeecU3mp7vXXX2ft2rW0b9+eHj168KMf/YhXXnmFO+64g7vuuovf/va3XHbZZVx++eUcd9xxvPfee4wePZq1a9dm70SLNDKPLHuPuSs2VltnzaYdANW2csYN6ML3hxye0dhyRQmnBv369eOXv/wlU6dO5eSTT+b4448HYPHixdx6663s2rWLbdu20adPn8qEc+qpp1Zu26dPHzp37gxAjx49eP/992nbti1du3Zl+PDhAJx33nnceeed+yScpUuXsmbNmso6e/bsYdiwYUljPP300wE49thj2bBhAxB9mXXy5MmsWLGC5s2b849//KOy/qBBgypjOuKIIxg1alRlvIsXLwZg0aJFrFmzpnKbHTt2sHPnTg466KC6nkqRBqWmhFFTslj2zjYAhnRvX+cYKo6hhNNE9OrVi9dee4358+dzzTXXMHLkSK688kouueQSSktL6dq1K9dff/0+30Np3bo1AM2aNatcrni+d+9eYP+uxFWfuzsnnHACjz76aI0xVhyjefPmlfu//fbb6dixI6+//jpffvklBQUF+9WvGmNifF9++SVLly7dZzuRpmTuio2s2bSD4s5t6rT9kO7ta2ydVCSr2Rcn/2eysd3fUcKpwQcffED79u0577zzaNu2Lffdd19lcunQoQM7d+5kzpw5jB8/vlb7fe+991iyZAnDhg3jkUce4bjjjttn/dChQ7n00kspKyvjyCOP5NNPP2Xjxo306tUrrf1v376doqIimjVrxqxZs/jiiy9qFd+oUaO46667mDJlCgArVqxgwIABtdqHSENX3LlNjckg1XrZnzoN1GDVqlUMHjyYAQMGcMMNN3DNNdfQtm1bLrroIvr27cvo0aMZNGhQrfd71FFH8bvf/Y7evXvz8ccf85Of/GSf9YWFhTz44IOcc8459O/fn2HDhrFu3bq093/JJZcwa9YsjjnmGNatW8eBBx5Yq/juvPNOSktL6d+/P8XFxUyfPr1W24uIVGUVvasyvmOzmcDJwEfu3jeU/SdwCrAHeAuY6O6fhHVXARcCXwA/c/cFoXwMcAfQHLjP3X8TyrsDjwGHAsuBH7j7npriKikp8arfc1m7di29e/eu70tO24YNGzj55JN54403YjtmtsV9DkWyLR9aMPkQQwUzW+7uJfXZRzZbOA8CY6qULQT6unt/4B/AVQBmVgycDfQJ29xtZs3NrDnwO+BEoBg4J9QFuAW43d2P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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "hist.plot1d(histo.sum(\"x\", \"y\"), overlay='sample');" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZwAAAEICAYAAABrtkJsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAkBElEQVR4nO3de5hWdbn/8fcHEMk8oDISAgYaHggP0YCYWhSKeAp3qWm6JU/8SjFrt1XMri2ZdrC2lpWyLUn0UvBESUoiIlqpKEiACCijog6pEAiGFIXevz/WF3wYnoEZ5nnWMzN8Xtc116x1r+9a615rHuZmrfWd71JEYGZmVm5tKp2AmZltG1xwzMwsFy44ZmaWCxccMzPLhQuOmZnlwgXHzMxyUbaCI2mMpKWS5tWJXyRpoaTnJV1bEL9cUo2kFyQdUxAfkmI1kkYWxHtKejrF75LUvlzHYmZmTady/R2OpE8Dq4HbIqJPin0WuAI4PiLWStojIpZK6g2MA/oDewKPAPumTb0IHA3UAjOA0yNivqS7gQkRMV7SaGBORNy0pbw6deoUPXr0KOmxmpm1ds8+++zfIqKqKdtoV6pk6oqIP0rqUSf8NeCHEbE2tVma4kOB8Sn+iqQasuIDUBMRLwNIGg8MlbQA+Bzw5dRmLDAK2GLB6dGjBzNnztzq4zIz2xZJerWp28j7Gc6+wJHpVtjjkvqleFfg9YJ2tSlWX3x3YGVErKsTNzOzZqpsVzib2d9uwACgH3C3pL3LvVNJw4HhAHvttVe5d2dmZkXkfYVTS/bcJSLiGeB9oBOwBOhe0K5bitUXXw50lNSuTryoiLg5Iqojorqqqkm3IM3MbCvlfYXzO+CzwDRJ+wLtgb8BE4E7JV1H1mmgF/AMIKCXpJ5kBeU04MsREZKmAScD44FhwP05H4uZNTP//ve/qa2t5Z///GelU2mxOnToQLdu3dhuu+1Kvu2yFRxJ44CBQCdJtcCVwBhgTOoq/S9gWGTd5J5Pvc7mA+uACyPivbSdEcBkoC0wJiKeT7u4DBgv6WrgL8At5ToWM2sZamtr2WmnnejRoweSKp1OixMRLF++nNraWnr27Fny7ZetW3RzVV1dHe6lZtY6LViwgP3339/FpgkigoULF3LAAQdsFJf0bERUN2XbHmnAzFoVF5umKef5c8ExM7NcuOCYmZXBwIED/UfmdeTdS83MrMWYW7tyq9d9d+26LTfaxvgKx8y2Ce+++y7HH388Bx98MH369OGuu+4C4KqrrqJfv3706dOH4cOHs74j1cCBA/nxqG9z+nGf5aTPHsq82bP45vn/yYlHfpJfXHs1AEtef42hA/tz+UXnc9JnD+Vb/28Y//jHmg37XPTW35lbu5LRd0zg4E/254ADD2bwCScx/YVa5tau3Oir32FHcPYFF9PnkE/y0b0/xq33TWJu7UoWL17MkUceSd++fenbty9PPvkkAI899hif+cxnGDp0KHvvvTcjR47kjjvuoH///hx44IG89NJLACxbtowvfvGL9OvXj379+vHEE0/kedo34oJjZtuEhx56iD333JM5c+Ywb948hgwZAsCIESOYMWMG8+bN4x//+AcPPPDAhnXatd+OcZOmccqZZ/ONc8/g21f/mPseeZL77xnHyrdXALD4pUWceta5/G7a03x4x524e+zGf6Hx9orl/OqGn/B/437LXX94nN4HHcJtv7qxaI7vrXuPOx+YyqWjvs/on2aD6e+xxx5MmTKFWbNmcdddd/H1r399Q/s5c+YwevRoFixYwO23386LL77IM888w3nnncfPf/5zAC6++GK++c1vMmPGDO677z7OO++80p3URvItNTPbJhx44IF861vf4rLLLuOEE07gyCOPBGDatGlce+21rFmzhhUrVvDxj3+cE088EYCBRx8LwMf2780+++1PVeePANBtr4/y5l+XsNPOu/CRPbvyiX4DADj+C6cybsz/MeyrF23Y79xZM3h50Qt85T+yAvfvf/+bg/r2o5hBx54AQO8DD+Gvr7+2of2IESOYPXs2bdu25cUXX9zQvl+/fnTp0gWAffbZh8GDB2841mnTpgHwyCOPMH/+/A3rvPPOO6xevZodd9xxq8/l1nLBMbNtwr777susWbOYNGkS3/nOdxg0aBCXXnopF1xwATNnzqR79+6MGjVqo1EK2rffHoA2bdqwXfsPXrnVpk0b3luXPaPZpBtxnfmIYMCRA/nRL7f8t+kb9te2Le+9l23/+uuvp3PnzsyZM4f333+fDh06bGi//fbbb5TT+vk2bdqwLuX3/vvvM3369I3WqxTfUjOzbcJf//pXdthhB84880wuueQSZs2ataG4dOrUidWrV3Pvvfc2ertvLKllzrPPAPCH39274WpnvYP69mP2zKd5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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "hist.plot1d(histo.sum(\"x\", \"y\"), overlay='sample', stack=True);" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "hist.plot2d(histo.sum('x', 'sample'), xaxis='y');" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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keeee67KchcsWEBZWRnDhw9n4MCBTJ8+nTVr1uTiLYuIFCzl7Nqpp1xE6q2m3pFEDXklf58+fVi8eDFz5sxhypQpjBo1iosvvpjJkydTWlpKjx49mDp1Kjt27KicpnXr1gA0a9as8nnF6507ox6hcMeoStVfuztHHXUU9957b73fg4hIHJSz85N6ykWkIG3YsIHddtuNiRMnctFFF7F48eLKZN6xY0fKy8uZNWtWxvN9++23mT8/2hHNmDGDESNGVBl/+OGH8/zzz7Nq1SogOk/ytddeq+e7ERFp3JSza6eiXEQK0tKlSxkyZAgDBw7kiiuuYMqUKbRv355zzjmH4uJijj76aAYPHpzxfA866CBuuukmioqK+PDDDzn33HOrjO/UqRPTpk3jlFNOYcCAAQwbNoyVK1fuMp+HHnqI7t27M3/+fMaMGcPRRx9d5/cqIlLolLNrZxVXuTYmJSUlrvsCS7bE9WMK+fYjDitWrKCoqCijafLtPVS3evVqxo4dy7Jly3K2zGTr0cwWuXtJzoLIA8rbItmlnN0wspmzdU65iORMviZ2ERHZlXJ2bun0FRGRoGfPnjntcRERkbprbDlbRbmIiIiISMxUlIuIiIiIxExFuYiIiIhIzFSUi0ju3DUmeoiISP5Tzs4pFeUiImkYOXIkmdyy76KLLuLggw9mwIABfP/73+ejjz7KXnAiIlJFIeZsFeUiIllw1FFHsWzZMl555RX69OnDf//3f8cdkoiIpJAPOVtFuYgUpG3btjFmzBgOOeQQiouLmTlzJgBXXnklgwcPpri4mEmTJlHxA2kjR47kggsuoKSkhKKiIhYuXMj48ePp3bs3U6ZMAaIfojj44IM57bTTKCoqYsKECWzfvn2XZT/xxBMMGzaMQYMGccIJJ1BeXr5Lm9GjR9OiRfRTEIcffjjr1q3L1qoQEcl7ytm1048HiUj9/f1SeGfprsPfeaXq68+2RX//u0fV4fsM2HXaffrDsdekXORjjz1G165defTRRwHYsmULAOeffz6XX345AKeffjqPPPIIxx13HACtWrWitLSUG264gXHjxrFo0SI6dOjAAQccwAUXXADAq6++yh133MHw4cM566yz+MMf/sCFF15YudwPPviAq666iieffJLdd9+da6+9luuvv75ymcnceeednHTSSSnHi4jklHJ2XuZs9ZSLSEHq378/c+fO5ZJLLuHZZ59lzz33BGDevHkMHTqU/v378/TTT7N8+fLKaY4//vjKafv160eXLl1o3bo1vXr1Yu3atQD06NGD4cOHAzBx4kSee+65KstdsGABZWVlDB8+nIEDBzJ9+nTWrFmTMs6rr76aFi1acNpppzXo+xcRKSTK2bVTT7mI1F8NvSNVVFzFf+aj9V5knz59WLx4MXPmzGHKlCmMGjWKiy++mMmTJ1NaWkqPHj2YOnUqO3bsqJymdevWADRr1qzyecXrnTt3AmBmVZZT/bW7c9RRR3HvvffWGuO0adN45JFHeOqpp3aZj4hIbJSzk4o7Z6unXEQK0oYNG9htt92YOHEiF110EYsXL65M5h07dqS8vJxZs2ZlPN+3336b+fPnAzBjxgxGjBhRZfzhhx/O888/z6pVq4DoPMnXXnttl/k89thjXHfddcyePZvddtst4zhERBoT5ezaqadcRArS0qVLueiii2jWrBktW7bk5ptvpn379pxzzjkUFxezzz77MHjw4Izne9BBB3HTTTdx1lln0bdvX84999wq4zt16sS0adM45ZRT+PTTTwG46qqr6NOnT5V2559/Pp9++ilHHXUUEO0Ybrnlljq+WxGRwqacXTuruMq1MSkpKfFM7k0pkomTbo2+kc/8ybAmsdxUVqxYQVFRUWYTNeCh0GxYvXo1Y8eOZdmyZTlbZrL1aGaL3L0kZ0HkAeVtkexSzm4Y2czZ6ikXkdzJ08QuIiJJKGfnlM4pFxEJevbsmdMeFxERqbvGlrNVlIuIiIiIxExFuYjUWWO8JiWXtP5EJJeUc+on2+sv60W5mTU3s3+Z2SPh9f5m9qKZrTKzmWbWKgxvHV6vCuN7JszjsjD8VTM7Otsxi0jt2rRpw6ZNm5Tk68jd2bRpE23atIk7FBFpApSz6ycXOTsXF3r+FFgBtAuvrwV+4+73mdktwNnAzeHvh+5+oJmdHNqdZGZ9gZOBfkBX4Ekz6+PuX+QgdhFJoXv37qxbt473338/7lAKVps2bejevXvcYYhIE6CcXX/ZztlZLcrNrDswBrga+LlFP4/0beDU0GQ6MJWoKB8XngPMAn4f2o8D7nP3T4G3zGwVMASYn83YRaRmLVu2ZP/99487DBERSYNydv7L9ukrvwUuBr4Mr/cGPnL3neH1OqBbeN4NWAsQxm8J7SuHJ5mmkplNMrNSMyvVt0ARkfynvC0i8pWsFeVmNhZ4z90XZWsZidz9NncvcfeSTp065WKRIiJSD8rbIiJfyebpK8OB483su0AbonPKbwDam1mL0BveHVgf2q8HegDrzKwFsCewKWF4hcRpREREREQKXtZ6yt39Mnfv7u49iS7UfNrdTwPmARNCszOAh8Pz2eE1YfzTHl0iPBs4OdydZX+gN/BStuIWEREREcm1XNx9pbpLgPvM7CrgX8AdYfgdwJ/ChZybiQp53H25md0PlAE7gfN05xURERERaUxyUpS7+zPAM+H5m0R3T6neZgdwQorprya6g4uIiIiISKOjX/QUEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmGVclJvZXmY2IBvBiIhI46J9hohIetIqys3sGTNrZ2YdgMXAH83s+uyGJiIihUj7DBGRzKXbU76nu28FxgN3u/tQ4DvZC0tERAqY9hkiIhlKtyhvYWZdgBOBR7IYj4iIFD7tM0REMpRuUX4F8Diwyt0Xmlkv4PWaJjCzNmb2kpm9bGbLzeyKMHx/M3vRzFaZ2UwzaxWGtw6vV4XxPRPmdVkY/qqZHV2ndyoiIrmS8T5DRKSpa5Fmu43uXnmhjru/mcb5gZ8C33b3cjNrCTxnZn8Hfg78xt3vM7NbgLOBm8PfD939QDM7GbgWOMnM+gInA/2ArsCTZtbH3b/I5I2KiEjO1GWfISLSpKXbU/67NIdV8kh5eNkyPBz4NjArDJ8OfC88HxdeE8aPMjMLw+9z90/d/S1gFTAkzbhFRCT3Mt5niIg0dTX2lJvZMOAbQCcz+3nCqHZA89pmbmbNgUXAgcBNwBvAR+6+MzRZB3QLz7sBawHcfaeZbQH2DsMXJMw2cRoREckT9d1niIg0ZbX1lLcC9iAq3tsmPLYCE2qbubt/4e4Dge5EvdsH1yfYmpjZJDMrNbPS999/P1uLERGR1DLaZyhvi4h8pcaecnf/B/APM5vm7mvquhB3/8jM5gHDgPZm1iL0lncH1odm64EewDozawHsCWxKGF4hcZrEZdwG3AZQUlLidY1VRETqJtN9hvK2iMhX0r3Qs7WZ3Qb0TJzG3b+dagIz6wR8HgryrwFHEV28OY+ox+Q+4Azg4TDJ7PB6fhj/tLu7mc0GZoSLhLoCvYGX0n6HIiKSaxnvM0REmrp0i/IHgFuA24F073rSBZgezitvBtzv7o+YWRlwn5ldBfwLuCO0vwP4k5mtAjYT3XEFd19uZvcDZcBO4DzdeUVEJK/VZZ8hItKkpVuU73T3mzOZsbu/AhyaZPibJLl7irvvAE5IMa+rgaszWb6IiMQm432GiEhTl+4tEf9mZpPNrIuZdah4ZDUyEREpVNpniIhkKN2e8jPC34sShjnQq2HDERGRRkD7DBGRDKVVlLv7/tkOREREGgftM0REMpdWUW5mP0w23N3vbthwRESk0GmfISKSuXRPXxmc8LwNMApYDCjBiohIddpniIhkKN3TV/498bWZtSe6z7iIiEgV2meIiGQu3buvVLcN0DmDIiKSDu0zRERqke455X8junIeoDlQBNyfraBERKRwaZ8hIpK5dM8p/9+E5zuBNe6+LgvxiIhI4dM+Q0QkQ2mdvuLu/wBWAm2BvYDPshmUiIgULu0zREQyl1ZRbmYnAi8BJwAnAi+a2YRsBiYiIoVJ+wwRkcyle/rKfwGD3f09ADPrBDwJzMpWYCIiUrC0zxARyVC6d19pVpFcg00ZTCsiIk2L9hkiIhlKt6f8MTN7HLg3vD4JmJOdkEREpMBpnyEikqEai3IzOxDo7O4Xmdl4YEQYNR+4J9vBiYhI4dA+Q0Sk7mrrKf8tcBmAuz8IPAhgZv3DuOOyGJuIiBSW36J9hohIndR2jl9nd19afWAY1jMrEYmISKHSPkNEpI5qK8rb1zDuaw0Yh4iIFL72NYzTPkNEpAa1FeWlZnZO9YFm9mNgUXZCEhGRAqV9hohIHdV2TvnPgIfM7DS+SqglQCvg+1mMS0RECs/P0D5DRKROaizK3f1d4Btm9i2gOAx+1N2fznpkIiJSULTPEBGpu7TuU+7u84B5WY5FREQaAe0zREQyp19YExERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiVnWinIz62Fm88yszMyWm9lPw/AOZjbXzF4Pf/cKw83MbjSzVWb2ipkNSpjXGaH962Z2RrZiFhERERGJQzZ7yncCv3D3vsDhwHlm1he4FHjK3XsDT4XXAMcCvcNjEnAzREU88EtgKDAE+GVFIS8iXznp1vmcdOv8uMMQERGROshaUe7uG919cXj+MbAC6AaMA6aHZtOB74Xn44C7PbIAaG9mXYCjgbnuvtndPwTmAsdkK24RFbciIiKSa2n9eFB9mVlP4FDgRaCzu28Mo94BOofn3YC1CZOtC8NSDa++jElEPezsu+++DRi9SP4o27g15ReGso1bAVKOHzewG6cO1WdD8ofytojIV7J+oaeZ7QH8BfiZu29NHOfuDnhDLMfdb3P3Encv6dSpU0PMUiSvjBvYjb5d2tVp2rKNW3l4yfoGjkikfpS3RUS+ktWecjNrSVSQ3+PuD4bB75pZF3ffGE5PeS8MXw/0SJi8exi2HhhZbfgz2YxbGrcZL75dY4FaW49z2catdS6O6+PUofvW2NNdEe/MnwxLOU5ERETyUzbvvmLAHcAKd78+YdRsoOIOKmcADycM/2G4C8vhwJZwmsvjwGgz2ytc4Dk6DBOpk4eXrK8svOuib5d2jBu4yxlUIiIiInWWzZ7y4cDpwFIzWxKG/SdwDXC/mZ0NrAFODOPmAN8FVgHbgTMB3H2zmf0KWBjaXenum7MYtzQBfbu0S9qjDDX3OOezQotXREREvpK1otzdnwMsxehRSdo7cF6Ked0J3Nlw0YmIiIiI5I+c3H1FpJCox1lERERyLet3XxERERERkZqpKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZi1iDsAkYJTehcsnZV83DuvRH/3GZB6+v4ToOTMho9LRERECpZ6ykUytXQWvLO0btO+szR1QS8iIiJNlnrKRepin/5w5qO7Dr9rTPQ32biK8e8s/apdIvWyi4iINFkqykUaUqpivEL/CXWfd0XvvIpyERGRRkdFuUgulZxZ96I6We+6iIiINAo6p1xEREREJGZZK8rN7E4ze8/MliUM62Bmc83s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yuV+8MEHXHXVVTz55JPsvvvuXHvttVx//fWVyxQRkV0pZ9dORblIhupTWL/4VnSN8tD9O2S83Ip552NRfsXfllO2YesuwytirrD9050A9J9a9QZKfbu022Xavl3b8cvj+qVcZv/+/fnFL37BJZdcwtixYzniiCMAmDdvHtdddx3bt29n8+bN9OvXrzLBH3/88ZXT9uvXjy5dugDQq1cv1q5dS/v27enRowfDhw8HYOLEidx4441VEvyCBQsoKyurbPPZZ58xbJguzhWRwqGcnZ85W0W5SIYeXrKeso1bkyal2gzdv0PK3u7a7r5SqBfbZEufPn1YvHgxc+bMYcqUKYwaNYqLL76YyZMnU1paSo8ePZg6dSo7duyonKZ169YANGvWrPJ5xeudO6OdT7hjVKXqr92do446invvvTdbb01EpNFRzq6dinKROujbpV3S4rmp3tawpt6RRA25fjZs2ECHDh2YOHEi7du35/bbb69M5h07dqS8vJxZs2YxYcKEjOb79ttvM3/+fIYNG8aMGTMYMWJElfGHH3445513HqtWreLAAw9k27ZtrF+/nj59+tT7PYmI5IJydn7mbF3oKSIFaenSpQwZMoSBAwdyxRVXMGXKFNq3b88555xDcXExRx99NIMHD854vgcddBA33XQTRUVFfPjhh5x77rlVxnfq1Ilp06ZxyimnMGDAAIYNG8bKlSt3mc9DDz1E9+7dmT9/PmPGjOHoo4+u83sVESl0ytm1s4qrXBuTkpIS132BJVtq6jnIZk95vvXCr1ixgqKiooymybf3UN3q1asZO3Ysy5Yty9kyk61HM1vk7iU5CyIPKG+LZJdydsPIZs5WT7mIiIiISMx0TrlIA8rX3oR8ke/rp2fPnjntcRERyWfK2bmlnnIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEcmdu8ZEjwI0cuRIMrll30UXXcTBBx/MgAED+P73v89HH32UveBERLJBOTunVJSLiGTBUUcdxbJly3jllVfo06cP//3f/x13SCIikkI+5GwV5SJSkLZt28aYMWM45JBDKC4uZubMmQBceeWVDB48mOLiYiZNmkTFD6SNHDmSCy64gJKSEoqKili4cCHjx4+nd+/eTJkyBYh+iOLggw/mtNNOo6ioiAkTJrB9+/Zdlv3EE08wbNgwBg0axAkn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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# make coarse binned hist and look at several distributions\n", + "hnew = (\n", + " histo\n", + " .rebin(\"y\", hist.Bin(\"ynew\", \"rebinned y value\", [0, 3, 5]))\n", + " .rebin(\"z\", hist.Bin(\"znew\", \"rebinned z value\", [5, 8, 10]))\n", + ")\n", + "\n", + "hist.plotgrid(hnew, row='ynew', col='znew', overlay='sample');" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/lagray/coffea/coffea/binder/coffea/hist/plot.py:357: RuntimeWarning: invalid value encountered in true_divide\n", + " rsumw = sumw_num / sumw_denom\n" + ] + }, + { + "data": { + "text/plain": [ + "(-10.0, 10.0)" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "numerator = histo.integrate('sample', 'sample 1').sum('y', 'z')\n", + "denominator = histo.sum('sample', 'y', 'z')\n", + "\n", + "numerator.label = r'$\\epsilon$'\n", + "ax = hist.plotratio(\n", + " num=numerator,\n", + " denom=denominator,\n", + " error_opts={'color': 'k', 'marker': '.'},\n", + " unc='clopper-pearson'\n", + ")\n", + "ax.set_ylim(0.6, 1.)\n", + "ax.set_xlim(-10, 10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Styling\n", + "\n", + "We've covered the basics of plotting, now let's go over some styling options. To make things more interesting, we'll load some electron and muon Lorentz vectors from simulated $H\\rightarrow ZZ^{*}$ events into awkward arrays and then plot some kinematic quantities for them, making liberal use of the matplotlib styling options which are exposed through the coffea plotting utilities." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " % Total % Received % Xferd Average Speed Time Time Time Current\r\n", + " Dload Upload Total Spent Left Speed\r\n", + "\r", + " 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r", + "100 212k 100 212k 0 0 7601k 0 --:--:-- --:--:-- --:--:-- 7601k\r\n" + ] + } + ], + "source": [ + "!curl -OL http://scikit-hep.org/uproot3/examples/HZZ.root" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Avg. electrons/event: 0.07063197026022305\n", + "Avg. muons/event: 1.579925650557621\n" + ] + } + ], + "source": [ + "import uproot\n", + "import awkward as ak\n", + "from coffea.nanoevents.methods import vector\n", + "ak.behavior.update(vector.behavior)\n", + "\n", + "fin = uproot.open(\"HZZ.root\")\n", + "tree = fin[\"events\"]\n", + "\n", + "# let's build the lepton arrays back into objects\n", + "# in the future, some of this verbosity can be reduced\n", + "arrays = {k.replace('Electron_', ''): v for k, v in tree.arrays(filter_name=\"Electron_*\", how=dict).items()}\n", + "electrons = ak.zip({'x': arrays.pop('Px'), \n", + " 'y': arrays.pop('Py'), \n", + " 'z': arrays.pop(\"Pz\"),\n", + " 't': arrays.pop(\"E\"),\n", + " },\n", + " with_name=\"LorentzVector\"\n", + ")\n", + "\n", + "\n", + "arrays = {k.replace('Muon_', ''): v for k,v in tree.arrays(filter_name=\"Muon_*\", how=dict).items()}\n", + "muons = ak.zip({'x': arrays.pop('Px'), \n", + " 'y': arrays.pop('Py'), \n", + " 'z': arrays.pop(\"Pz\"),\n", + " 't': arrays.pop(\"E\"),\n", + " },\n", + " with_name=\"LorentzVector\"\n", + ")\n", + "\n", + "print(\"Avg. electrons/event:\", ak.sum(ak.num(electrons))/tree.num_entries)\n", + "print(\"Avg. muons/event:\", ak.sum(ak.num(muons))/tree.num_entries)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "lepton_kinematics = hist.Hist(\n", + " \"Events\",\n", + " hist.Cat(\"flavor\", \"Lepton flavor\"),\n", + " hist.Bin(\"pt\", \"$p_{T}$\", 19, 10, 100),\n", + " hist.Bin(\"eta\", \"$\\eta$\", [-2.5, -1.4, 0, 1.4, 2.5]),\n", + ")\n", + "\n", + "# Pass keyword arguments to fill, all arrays must be flat numpy arrays\n", + "# User is responsible for ensuring all arrays have same jagged structure!\n", + "lepton_kinematics.fill(\n", + " flavor=\"electron\",\n", + " pt=ak.flatten(electrons.pt),\n", + " eta=ak.flatten(electrons.eta)\n", + ")\n", + "lepton_kinematics.fill(\n", + " flavor=\"muon\",\n", + " pt=ak.flatten(muons.pt),\n", + " eta=ak.flatten(muons.eta)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Now we can start to manipulate this single histogram to plot different views of the data\n", + "# here we look at lepton pt for all eta\n", + "lepton_pt = lepton_kinematics.integrate(\"eta\")\n", + "\n", + "ax = hist.plot1d(\n", + " lepton_pt,\n", + " overlay=\"flavor\",\n", + " stack=True,\n", + " fill_opts={'alpha': .5, 'edgecolor': (0,0,0,0.3)}\n", + ")\n", + "# all plot calls return the matplotlib axes object, from which\n", + "# you can edit features afterwards using matplotlib object-oriented syntax\n", + "# e.g. maybe you really miss '90s graphics...\n", + "ax.get_legend().shadow = True" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZgAAAEICAYAAABiXeIWAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAnXklEQVR4nO3de3hU9b3v8feXEO6iAl5oIjvhCCoQQIiAVarIEbFeUIpCtRapFT3qc7rrUTfd55gix21r20e7az1V3IiWeqHgVlJLvYC6Fa1IUCQSRBFjDYUKwQaVO3zPH2slHUKSmZBZM5PJ5/U882TNWr+15juTgW9+12XujoiISLK1S3cAIiKSnZRgREQkEkowIiISCSUYERGJhBKMiIhEon26A0iFXr16eUFBQbrDEBFpVVauXLnV3Y853PPbRIIpKCigrKws3WGIiLQqZvZJS85XE5mIiERCCUZERCKhBCMiIpFoE30wItK27N27l6qqKnbt2pXuUFqFTp06kZ+fT25ublKvqwQjIlmnqqqKI444goKCAsws3eFkNHenurqaqqoqCgsLk3ptNZGJSNbZtWsXPXv2VHJJgJnRs2fPSGp7SjAikpWUXBIX1WelBCMiIpFQghGRNqNbt24tvsaqVatYvHhxEqIJLFiwgFNOOYUxY8bwyiuvcOGFFybt2ummBCONmvzgn5n84J/THYZIRkl2gpkzZw4PPfQQL7/8ctKu2Zh9+/ZF/hqxlGBEpE376KOPGD9+PMOHD2f06NG8//77AFx99dVcf/31FBcX079/f5599ln27NlDSUkJ8+fPZ+jQocyfP59t27ZxySWXMHjwYEaNGsXq1asBmDlzJt/73vc4++yz6du3L7/61a8Oee1Zs2axbNkyrrnmGm699daDjr311lucfvrpnHrqqXz9619n3bp1AIwaNYo1a9bUlTv77LMpKytrMo6rrrqKM844g6uuuiqSz7BR7p71j+HDh7s03+UPvOGXP/BGusMQabaKiooG93ft2vWQfeecc45/8MEH7u7+5ptv+pgxY9zdferUqX7eeef5/v37/YMPPvC8vDzfuXOnz50712+88ca682+66SafOXOmu7svXbrUhwwZ4u7uP/7xj/3000/3Xbt2+ZYtW7xHjx6+Z8+eQ17/rLPO8hUrVri7+8svv+wXXHCBu7vX1NT43r173d39xRdf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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Clearly the yields are much different, are the shapes similar? We can check by setting `density=True`\n", + "lepton_pt.label = \"Density\"\n", + "ax = hist.plot1d(lepton_pt, overlay=\"flavor\", density=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Let's stack them, after defining some nice styling\n", + "stack_fill_opts = {\n", + " 'alpha': 0.8,\n", + " 'edgecolor':(0,0,0,.5)\n", + "}\n", + "stack_error_opts = {\n", + " 'label':'Stat. Unc.',\n", + " 'hatch':'///',\n", + " 'facecolor':'none',\n", + " 'edgecolor':(0,0,0,.5),\n", + " 'linewidth': 0\n", + "}\n", + "# maybe we want to compare different eta regions\n", + "# plotgrid accepts row and column axes, and creates a grid of 1d plots as appropriate\n", + "ax = hist.plotgrid(\n", + " lepton_kinematics,\n", + " row=\"eta\",\n", + " overlay=\"flavor\",\n", + " stack=True,\n", + " fill_opts=stack_fill_opts,\n", + " error_opts=stack_error_opts,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "# Here we create some pseudodata for the pt histogram so we can make a nice data/mc plot\n", + "pthist = lepton_kinematics.sum('eta')\n", + "bin_values = pthist.axis('pt').centers()\n", + "poisson_means = pthist.sum('flavor').values()[()]\n", + "values = np.repeat(bin_values, np.random.poisson(poisson_means))\n", + "pthist.fill(flavor='pseudodata', pt=values)\n", + "\n", + "# Set nicer labels, by accessing the string bins' label property\n", + "pthist.axis('flavor').index('electron').label = 'e Flavor'\n", + "pthist.axis('flavor').index('muon').label = r'$\\mu$ Flavor'\n", + "pthist.axis('flavor').index('pseudodata').label = r'Pseudodata from e/$\\mu$'\n", + "\n", + "# using regular expressions on flavor name to select just the data\n", + "# another method would be to fill a separate data histogram\n", + "import re\n", + "notdata = re.compile('(?!pseudodata)')" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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Q25uLqtXr/a3P/zww7Rv377KAB5jxozhjDPOAGDXrl1MnDiR9u3b06xZMwYNGsQ777zjf+wJJ5zA+PHjmTRpEu3ateOYY44J6echyUVhKiktmEO3wQatRFdhYSHdu3enZcuW/mUrV64kPT2d3r17R+Q5SkpKmDhxIsuWLeOtt94iKyuL4cOH+/cezznnHLZv387rr7/uX6e4uJiXX36Z888/H4Crr76a5557jscee4yVK1fSr18/hg4dysaN/zsn/fTTT+OcY8mSJTz55JMRqV0Sm8JUUlawh24b4jnURFRYWMiAAQMqLFu5ciW9e/emSZMmNa63cOFCMjMz/bfAS5wqGzlyJCNHjqR79+4cdthhPP7446xfv55ly5YBsM8++3DaaafxzDPP+NeZO3cujRs35owzzqCkpIQHHniA2267jdNPP51evXrx4IMP0r59e2bMmOFf5+CDD+bOO++kZ8+e9OrVK9QfiSQRdUCSlFSfQ7cK0sRQWFjI2WefXWHZihUr6uxINHjwYB5++GH//drGJl63bh3XX389BQUFbNmyhb1797J3716+/vpr/2POP/98LrzwQkpLS2nRogXPPPMMI0eOpFmzZqxatYrdu3dXOHSblpbG0UcfzWeffeZfdsQRRwT7siVFaM9UUlI4h24VpLG3d+9ePv744yp7psuXL68zTFu0aEG3bt38t06dOtX42GHDhrFlyxYeeughCgoKWLlyJY0bN67QSej000+ncePGvPzyy2zevJl///vf/kO8tQkcA7byCFuS+rRnKikp2EO3U6ZMqbVdYmPt2rWUlpay//77+5d9/PHHrF27NmKXuGzdupU1a9Zw//33c+KJJwKePd/KM4o0bdqUc845h2eeeYYffviBDh06cMIJJwDQtWtX0tPTeffdd+natSvgmYVo6dKljBkzJiJ1SnJSmEpKCvbQ7dSpU2ttl9jwTTJw3333ceWVV1JUVMTEiRMBT+/ZSNhnn31o27YtjzzyCJ07d2bDhg1Mnjy52p6/559/PkOGDGH9+vWMHj2aRo08B/EyMjIYP34811xzDW3btuXggw/m7rvvZtOmTVx++eURqVOSk8JUUtJxx5/ItoAJgcvKdrF92zayWrfmqWdnV3l8MO37tduPJYvfjGrd0dJp/44xG0jB93z1UVhYyCmnnMK3335L37596dGjBzfccAPj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gwbxt7/9rdb1ysvLueWWWzjssMPYd999yczM5MUXX+Trr2N/Tvqwww7z/3///T2To2/evBnwfGk99thj/UEqqUdh2gDU9kGXl5fHYYcd5v8jrzz8X13rQ/J3xmkIEjlIfZo1a8Ypp5zCDTfcwHvvvcfFF1/M1KlTKSsrq3GdO+64gzvvvJPJkyfzxhtvUFhYyIgRI2pdJ1itWrUCYLt3zOhA27ZtIysrq8KywDl3fed09+7dG3YdkhwUpimurg+6b775huHDh3P//fcDFYf/C2b9ZDjHKcH16k6EXr2BevfuzZ49e/znUdPT06ucY3znnXcYPnw4F1xwAdnZ2XTt2pW1a9dWeEx16wWje/fuNGrUiA8//LDC8i+//JLt27dz6KGHBr2t/v37884770Qk5CUxKUxTXLDzhV588cWAZ/i/WAepznFGXyIH6datWznppJN4+umnWbVqFevXr+f5559n+vTpDBkyxL+H2KVLF5YsWcKGDRv44YcfAM95xzfeeIN33nmHNWvWMGHCBNavX1/ltS9btoyioiJ++OEH/95iz549a732tGXLllxyySVMnjyZl19+mfXr1/P2228zduxYBg0axHHHHRf0a7z88sspLi7m3HPP5YMPPuCLL75g1qxZFBYWAvDSSy/Rs2dPNmzYUJ8fnSQQhWmKi9YHpQZ9T35dunTh6quvrjEIw20PVmZmJoMGDeKee+7h+OOPp0+fPvzlL39hzJgx/gkTAG688Ua++eYbunbtSrt27QC47rrrOOqoo8jLy2Pw4MFkZGQwduzYCtufNGkS6enp9O7dm3bt2vnPp37++ef+UK7JPffcw29/+1uuvfZa+vTpw4UXXki/fv2YP3++/1BuMDp16sTbb79NWVkZJ554Iv379+fee++lcWNPH9Dt27fz+eefs3v37qC3KYnFnHPxriFmcnJy3PLly+NdRtzVFJRmhnOuziA9tHefoKZBU5DWbtKoPD4uXBHRba5evZpevXpFdJsiya62vwsz+9A5lxPuc+jSmBQXOOk2RG7i7dquk6zrOsp4XmcpIhINCtMU55t0G+reI4z3xNsiIslK50wbiESfeFtEJJkpTBuA+lyeonOcIiL1p8O8KS7YQemPyzuDnTt31NquIBURqZ72TFNcsIPSd+h0YIXh/6prFxGR6ilMU1ywg9LXt11ERP5HYZrigh2U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lPg7Ofkek56ezrvvvutfVl5eztKlS+ndu3dQ29i6dStr1qzhL3/5CyeffDK9evXil19+Yc+ePRVqS09Pr/C7Dna9UNX12iIl2N/Xyy+/XKEX79q1ayktLWX//ff3L/v4449Zu3at9kxFGrraDt3m5+ezdOlSSktLAU8vUV9HIN+5y8rr19azsz7S0tL8zxHL86Q1Wb9+PQ899BBnnHEGnTp14ssvv2TVqlWMHz+eli1bMmnSJCZNmoRzjsGDB1NcXOzv+XnppZcCcNJJJzFx4kTmzZvHoYceykMPPcQ333zj/7lnZmZy8cUXc80119CuXTv2339/brzxxgqBlpGRwfjx47nmmmto27YtBx98MHfffTebNm3i8ssvD2ob++yzD23btuWRRx6hc+fObNiwgcmTJ/s72fh06dKFZcuWUVRURGZmJm3atAlqvVDV9doiJZjf15YtW3j//ff517/+5V+vsLAQgPvuu48rr7ySoqIi//Wnu3btilh9oVKYisRJWdmuWs+B/uc///EHqU9gR6BYdEZKFC1atGDt2rWcc845/PDDD7Rv356xY8dyzTXXAHDTTTfRvn177rjjDsaPH0+rVq3Izs7m6quv9m/jt7/9LatWreK3v/0tAFdccQVnnXUWP/zwg/8xd9xxByUlJZx11lm0aNGC//f//l+Vzli33XYbABdddBHbtm2jf//+LFy4kI4dOwa1jUaNGvHcc8/xhz/8gb59+9KtWzfuvPPOKp2LJk2axIUXXkjv3r3ZsWMH69evD2q9cNT12iKlrt/X/PnzOfLII2nfvr1/ncLCQk455RS+/fZb+vbtS48ePbjhhhsYP3489957L6eeempEa6wvq3wOIZXl5OS45cuXx7uMmOqXPYA7Zsf+kgap24UnDeD9996t8RzotGnTmDNnToVAzczMZNasWfTt27faIF29ejW9evWKWI1mVuU8o0i0nXnmmRxzzDEVvgwNHTqU/v37c+utt9Z7e7X9XZjZh865nJCL9dI5U5E4qes60+uuu46jjz6azMxMAH9HoF69esVsj3TKlClR3b5IdY455hj/oCE+hYWFFXoSJ5q4HuY1s6eBIUAG8D0w3Tn3qLdtCDADOBAoAMY5577ytjUFHgB+DZR617sr9q9AJHQtW+9Lv+yK18yVle1i+7ZtZLVuzVPPzsY5R5t2+1FcXEybdvvx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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# make a nice ratio plot, adjusting some font sizes\n", + "plt.rcParams.update({\n", + " 'font.size': 14,\n", + " 'axes.titlesize': 18,\n", + " 'axes.labelsize': 18,\n", + " 'xtick.labelsize': 12,\n", + " 'ytick.labelsize': 12\n", + "})\n", + "fig, (ax, rax) = plt.subplots(\n", + " nrows=2,\n", + " ncols=1,\n", + " figsize=(7,7),\n", + " gridspec_kw={\"height_ratios\": (3, 1)},\n", + " sharex=True\n", + ")\n", + "fig.subplots_adjust(hspace=.07)\n", + "\n", + "# Here is an example of setting up a color cycler to color the various fill patches\n", + "# We get the colors from this useful utility: http://colorbrewer2.org/#type=qualitative&scheme=Paired&n=6\n", + "from cycler import cycler\n", + "colors = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c']\n", + "ax.set_prop_cycle(cycler(color=colors))\n", + "\n", + "fill_opts = {\n", + " 'edgecolor': (0,0,0,0.3),\n", + " 'alpha': 0.8\n", + "}\n", + "error_opts = {\n", + " 'label': 'Stat. Unc.',\n", + " 'hatch': '///',\n", + " 'facecolor': 'none',\n", + " 'edgecolor': (0,0,0,.5),\n", + " 'linewidth': 0\n", + "}\n", + "data_err_opts = {\n", + " 'linestyle': 'none',\n", + " 'marker': '.',\n", + " 'markersize': 10.,\n", + " 'color': 'k',\n", + " 'elinewidth': 1,\n", + "}\n", + "\n", + "# plot the MC first\n", + "hist.plot1d(\n", + " pthist[notdata], \n", + " overlay=\"flavor\", \n", + " ax=ax,\n", + " clear=False,\n", + " stack=True, \n", + " line_opts=None,\n", + " fill_opts=fill_opts,\n", + " error_opts=error_opts\n", + ")\n", + "# now the pseudodata, setting clear=False to avoid overwriting the previous plot\n", + "hist.plot1d(\n", + " pthist['pseudodata'],\n", + " overlay=\"flavor\",\n", + " ax=ax,\n", + " clear=False,\n", + " error_opts=data_err_opts\n", + ")\n", + "\n", + "ax.autoscale(axis='x', tight=True)\n", + "ax.set_ylim(0, None)\n", + "ax.set_xlabel(None)\n", + "leg = ax.legend()\n", + "\n", + "# now we build the ratio plot\n", + "hist.plotratio(\n", + " num=pthist['pseudodata'].sum(\"flavor\"),\n", + " denom=pthist[notdata].sum(\"flavor\"), \n", + " ax=rax,\n", + " error_opts=data_err_opts, \n", + " denom_fill_opts={},\n", + " guide_opts={},\n", + " unc='num'\n", + ")\n", + "rax.set_ylabel('Ratio')\n", + "rax.set_ylim(0,2)\n", + "\n", + "# add some labels\n", + "coffee = plt.text(0., 1., u\"☕\",\n", + " fontsize=28, \n", + " horizontalalignment='left', \n", + " verticalalignment='bottom', \n", + " transform=ax.transAxes\n", + " )\n", + "lumi = plt.text(1., 1., r\"1 fb$^{-1}$ (?? TeV)\",\n", + " fontsize=16, \n", + " horizontalalignment='right', \n", + " verticalalignment='bottom', \n", + " transform=ax.transAxes\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Some further styling tools are available through the `mplhep` package. In particular, there are several stylesheets that update `plt.rcParams` to conform with experiment style recommendations regarding font face, font sizes, tick mark styles, and other such things. Below is an example application." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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OteppDQidomIn0bEIxGxc4v9/wn8GvhP4EJgfmmfJEnqpL/+9a9AliSVJwhtbMCAARx88MEArSYuARxzzDEMGjSoYt13vvOdQHY1dfHixZuM56GHHgKyBKutpyQNGzaMf//3fweomGABHHrooRX3b7nllpuMoSu8/vWv54QTTuAtb3nLBvvXrl3L7373O/7rv/6rYr3Bgwfzrne9C4D//d//3eDYz3/+c1JKjB07lokTJzbvL39mRxxxRMU/KgAOPvhgNt98c6DyZ7brrruy/fbbd/Dd1b+a1ymNiB2Ae4HtNtq/E/D50rd/BF4FDgC+GhH/l1K6r9Y+JUlSNkMdYOnSpR1a7ui5555rtW+PPfZos/wOO+zAlltuyapVq3j44YcZN25cu+2XE6xNPbazfLytpHT06PyfybN+/Xp++9vfcuONN/LAAw/w0EMPsWTJEl599dV2651wwgn84Ac/4KabbmLFihUMHz4cgNmzZwPwgQ98YIMR5I58ZuUVDh588MGKn9lOO+1U5burbzUnpcCngBHAE8AFwDOl/ccBmwP3pJT2B4iIRuA04KOlrSRJqtHatWurKl/psnely9MtbbZZliK89NJLm2w/u+1w08ptvvLKKxWPbyqm7vbUU0/xzne+s/nWiM0335x/+7d/4+1vfzsTJ05khx12YPLkyRXrHnbYYWy//fY8/fTTzJ07l/e973089thj3HbbbQwYMICTTjppg/Jd8ZkNGTKkmrdX9zpz+f5tZDe+npZSakopvVzaf0xp/w9alL2ktJ2IJEnqlL322guA173udR2aQFJOslp65JFH2mz/mWee4fnnn9+gr/bsueeeAM3rgralfCvA6173uk22mYcPfvCD3Hnnney5557ceOONvPDCC9xxxx1cdtllnHLKKbzhDW9os+5mm23G1KlTgX9dwr/mmmsAOProo9l55503KN+Rz6zl7RP1+pl1pc4kpeUx9lvLOyIblz649G3Lu5jLY867daI/SZLEvxLFhx9+mBdffLHNcn/7299YsGABTzzxRKtjN998c5ujdeVnxsO/kqf2jBkzBoAHH3ywzQXkywley/jryerVq/nVr34FwHe/+12OPvro5lHKsvIl97accMIJANxwww2sXr26+dJ9pYlM5c/spptuavPWgPnz57N69WqgPj+zrtaZpLR87aDlGdsX2BZYmlJq+SfYZhXKSpKkGowZM4a99tqL9evXt/mUokcffZR9992XN7/5zfz9739vdfzPf/4zP/vZz1rtX7FiBRdeeCEAU6ZMYauttmpVZuNk9uCDD2brrbdm3bp1zJw5s2Ky++Uvf5lnn32WAQMGcOSRR3bkbfaolrdElCcXtfTyyy/z9a9/vfn7Su/xkEMOYeedd2bNmjU0NjZy5513Mnz48OaJYy0dc8wxADzwwAP86Ec/anX8lVdeaV4F4XWve11zEtuXdSYpLU/HO6jFvhml7cZrPexb2j7Wif4kSeqzVqxYwZIlS9p9PfZY9t/ogAED+OIXvwjA17/+dU455RTuueceXnzxRZYvX861117LW97yFlavXs0BBxzQajZ52UknncRXvvIVHnroIZ555hmKxSL7778/ixcv3qCPjf3lL39h7dq1zYnZ1ltvzbnnngtkjyCdNm0ad955Jy+88AJ/+tOf+I//+A++8IUvAPDhD394kxOi8rDttts2T/76+Mc/zoIFC1izZg3Lli3jl7/8JW9961v59a9/3Vz+F7/4Rav7PAcMGMB73/tegObP44QTTqiY5B566KEcffTRQHbbwAUXXMCiRYt4/vnn+cMf/sCkSZOYN28eAF/4whc6NKGt16t1gVOyx4auJ7s0Pwk4FlhJNtv+2Bbldudfs/Bnd/fCq73hhYvnqwUXz5f6t/IC7x15bbzY+5e+9KV2y48bNy499dRTG9QpL+R+5plntvlITyBddtllrWL94Q9/uMHjNvfaa6/mY+vWrUunnnpqu/Ece+yxafXq1Ru02XLx/LaUF4t/61vfWtNn29HF8+fMmdNm7Jtttln61re+lcaMGdO8b8qUKa36nD9//gb17rjjjjbje+qpp9LEiRPb/cw+97nPddnnUasW56duF8+/GHga2AP4DTAH2Ar4EzAXICJOJxtRnVCq841O9CdJklr41Kc+xV133cWHPvQh9t9/f7bcckt23nln3vKWt9DU1MQ999zT5jqWEydOZOHChZx22mnsvPPODBkyhDe+8Y3MmDGDO++8kzPPPLNVnRNPPJHTTz+d7bbbjgEDBmywJNHAgQP5/ve/T7FY5KSTTuLf/u3f2GKLLXjDG97AtGnTuOqqq5gzZw5Dhw7tts+js975zndy6623cswxx7DrrrsyePDg5ocM3H///Zx11ln89Kc/ZezYsey4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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import mplhep\n", + "plt.style.use(mplhep.style.ROOT)\n", + "\n", + "# Compare this to the style of the plot drawn previously\n", + "ax = hist.plot1d(lepton_pt, overlay=\"flavor\", density=True)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/_sources/notebooks/nanoevents.ipynb.txt b/_sources/notebooks/nanoevents.ipynb.txt new file mode 100644 index 000000000..87bf187dc --- /dev/null +++ b/_sources/notebooks/nanoevents.ipynb.txt @@ -0,0 +1,639 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Reading data with coffea NanoEvents\n", + "\n", + "This is a rendered copy of [nanoevents.ipynb](https://github.com/CoffeaTeam/coffea/blob/master/binder/nanoevents.ipynb). You can optionally run it interactively on [binder at this link](https://mybinder.org/v2/gh/coffeateam/coffea/master?filepath=binder%2Fnanoevents.ipynb)\n", + "\n", + "NanoEvents is a Coffea utility to wrap flat nTuple structures (such as the CMS [NanoAOD](https://www.epj-conferences.org/articles/epjconf/pdf/2019/19/epjconf_chep2018_06021.pdf) format) into a single awkward array with appropriate object methods (such as Lorentz vector methods$^*$), cross references, and nested objects, all lazily accessed$^\\dagger$ from the source ROOT TTree via uproot. The interpretation of the TTree data is configurable via [schema objects](https://coffeateam.github.io/coffea/modules/coffea.nanoevents.html#classes), which are community-supplied for various source file types. These schema objects allow a richer interpretation of the file contents than the [uproot.lazy](https://uproot4.readthedocs.io/en/latest/uproot4.behaviors.TBranch.lazy.html) methods. Currently available schemas include:\n", + "\n", + " - `BaseSchema`, which provides a simple representation of the input TTree, where each branch is available verbatim as `events.branch_name`, effectively the same behavior as `uproot.lazy`. Any branches that uproot supports at \"full speed\" (i.e. that are fully split and either flat or single-jagged) can be read by this schema;\n", + " - `NanoAODSchema`, which is optimized to provide all methods and cross-references in CMS NanoAOD format;\n", + " - `PFNanoAODSchema`, which builds a double-jagged particle flow candidate colllection `events.jet.constituents` from compatible PFNanoAOD input files;\n", + " - `TreeMakerSchema` which is designed to read TTrees made by [TreeMaker](https://github.com/TreeMaker/TreeMaker), an alternative CMS nTuplization format;\n", + " - `PHYSLITESchema`, for the ATLAS DAOD_PHYSLITE derivation, a compact centrally-produced data format similar to CMS NanoAOD; and\n", + " - `DelphesSchema`, for reading Delphes fast simulation [nTuples](https://cp3.irmp.ucl.ac.be/projects/delphes/wiki/WorkBook/RootTreeDescription).\n", + "\n", + "We welcome contributions for new schemas, and can assist with the design of them.\n", + "\n", + "$^*$ Vector methods are currently made possible via the [coffea vector](https://coffeateam.github.io/coffea/modules/coffea.nanoevents.methods.vector.html) methods mixin class structure. In a future version of coffea, they will instead be provided by the dedicated scikit-hep [vector](https://vector.readthedocs.io/en/latest/) library, which provides a more rich feature set. The coffea vector methods predate the release of the vector library.\n", + "\n", + "$^\\dagger$ _Lazy_ access refers to only fetching the needed data from the (possibly remote) file when a sub-array is first accessed. The sub-array is then _materialized_ and subsequent access of the sub-array uses a cached value in memory. As such, fully materializing a `NanoEvents` object may require a significant amount of memory.\n", + "\n", + "\n", + "In this demo, we will use NanoEvents to read a small CMS NanoAOD sample. The events object can be instantiated as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import awkward as ak\n", + "from coffea.nanoevents import NanoEventsFactory, NanoAODSchema\n", + "\n", + "fname = \"https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/nano_dy.root\"\n", + "events = NanoEventsFactory.from_root(\n", + " fname,\n", + " schemaclass=NanoAODSchema.v6,\n", + " metadata={\"dataset\": \"DYJets\"},\n", + ").events()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the factory constructor, we also pass the desired schema version (the latest version of NanoAOD can be built with `schemaclass=NanoAODSchema`) for this file and some extra metadata that we can later access with `events.metadata`. In a later example, we will show how to set up this metadata in coffea processors where the `events` object is pre-created for you. Consider looking at the [from_root](https://coffeateam.github.io/coffea/api/coffea.nanoevents.NanoEventsFactory.html#coffea.nanoevents.NanoEventsFactory.from_root) class method to see all optional arguments.\n", + "\n", + "The `events` object is an awkward array, which at its top level is a record array with one record for each \"collection\", where a collection is a grouping of fields (TBranches) based on the naming conventions of [NanoAODSchema](https://coffeateam.github.io/coffea/api/coffea.nanoevents.NanoAODSchema.html). For example, in the file we opened, the branches:\n", + "```\n", + "Generator_binvar\n", + "Generator_scalePDF\n", + "Generator_weight\n", + "Generator_x1\n", + "Generator_x2\n", + "Generator_xpdf1\n", + "Generator_xpdf2\n", + "Generator_id1\n", + "Generator_id2\n", + "```\n", + "are grouped into one sub-record named `Generator` which can be accessed using either getitem or getattr syntax, i.e. `events[\"Generator\"]` or `events.Generator`. e.g." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.Generator.id1" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['binvar', 'scalePDF', 'weight', 'x1', 'x2', 'xpdf1', 'xpdf2', 'id1', 'id2']" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# all names can be listed with:\n", + "events.Generator.fields" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In CMS NanoAOD, each TBranch has a self-documenting help string embedded in the title field, which is carried into the NanoEvents, e.g. executing the following cell should produce a help pop-up:\n", + "```\n", + "Type: Array\n", + "String form: [1, -1, -1, 21, 21, 4, 2, -2, 2, 1, 3, 1, ... -1, -1, 1, -2, 2, 1, 2, -2, -1, 2, 1]\n", + "Length: 40\n", + "File: ~/src/awkward-1.0/awkward1/highlevel.py\n", + "Docstring: id of first parton\n", + "Class docstring: ...\n", + "```\n", + "where the `Docstring` shows information about the content of this array." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "events.Generator.id1?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Based on a collection's name or contents, some collections acquire additional _methods_, which are extra features exposed by the code in the mixin classes of the `coffea.nanoevents.methods` modules. For example, although `events.GenJet` has the fields:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['eta', 'mass', 'phi', 'pt', 'partonFlavour', 'hadronFlavour']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenJet.fields" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "we can access additional attributes associated to each generated jet by virtue of the fact that they can be interpreted as [Lorentz vectors](https://coffeateam.github.io/coffea/api/coffea.nanoevents.methods.vector.LorentzVector.html#coffea.nanoevents.methods.vector.LorentzVector):" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenJet.energy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can call more complex methods, like computing the distance $\\Delta R = \\sqrt{\\Delta \\eta^2 + \\Delta \\phi ^2}$ between two LorentzVector objects:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# find distance between leading jet and all electrons in each event\n", + "dr = events.Jet[:, 0].delta_r(events.Electron)\n", + "dr" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# find minimum distance\n", + "ak.min(dr, axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# a convenience method for this operation on all jets is available\n", + "events.Jet.nearest(events.Electron)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The assignment of methods classes to collections is done inside the schema object during the initial creation of the array, governed by the awkward array's `__record__` parameter and the associated behavior. See [ak.behavior](https://awkward-array.readthedocs.io/en/latest/ak.behavior.html) for a more detailed explanation of array behaviors.\n", + "\n", + "Additional methods provide convenience functions for interpreting some branches, e.g. CMS NanoAOD packs several jet identification flag bits into a single integer, `jetId`. By implementing the bit-twiddling in the [Jet mixin](https://github.com/CoffeaTeam/coffea/blob/7045c06b9448d2be4315e65d432e6d8bd117d6d7/coffea/nanoevents/methods/nanoaod.py#L279-L282), the analsyis code becomes more clear:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[6, 6, 6, 6, 6], [6, 2, 6, 6, 6, 6, 6, 0], ... 6], [6], [6, 6, 0, 6, 6, 6], [6, 6]]\n", + "[[True, True, True, True, True], [True, ... False, True, True, True], [True, True]]\n" + ] + } + ], + "source": [ + "print(events.Jet.jetId)\n", + "print(events.Jet.isTight)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also define convenience functions to unpack and apply some mask to a set of flags, e.g. for generated particles:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Raw status flags: [[10625, 27009, 4481, 22913, 257, 257, ... 13884, 13884, 12876, 12876, 12876, 12876]]\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(f\"Raw status flags: {events.GenPart.statusFlags}\")\n", + "events.GenPart.hasFlags(['isPrompt', 'isLastCopy'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "CMS NanoAOD also contains pre-computed cross-references for some types of collections. For example, there is a TBranch `Electron_genPartIdx` which indexes the `GenPart` collection per event to give the matched generated particle, and `-1` if no match is found. NanoEvents transforms these indices into an awkward _indexed array_ pointing to the collection, so that one can directly access the matched particle using getattr syntax:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.Electron.matched_gen.pdgId" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.Muon[ak.num(events.Muon)>0].matched_jet.pt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For generated particles, the parent index is similarly mapped:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenPart.parent.pdgId" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition, using the parent index, a helper method computes the inverse mapping, namely, `children`. As such, one can find particle siblings with:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenPart.parent.children.pdgId\n", + "# notice this is a doubly-jagged array" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since often one wants to shortcut repeated particles in a decay sequence, a helper method `distinctParent` is also available. Here we use it to find the parent particle ID for all prompt electrons:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenPart[\n", + " (abs(events.GenPart.pdgId) == 11)\n", + " & events.GenPart.hasFlags(['isPrompt', 'isLastCopy'])\n", + "].distinctParent.pdgId" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Events can be filtered like any other awkward array using boolean fancy-indexing" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mmevents = events[ak.num(events.Muon) == 2]\n", + "zmm = mmevents.Muon[:, 0] + mmevents.Muon[:, 1]\n", + "zmm.mass" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# a convenience method is available to sum vectors along an axis:\n", + "mmevents.Muon.sum(axis=1).mass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As expected for this sample, most of the dimuon events have a pair invariant mass close to that of a Z boson. But what about the last event? Let's take a look at the generator information:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-13, 13]\n", + "[False, False]\n" + ] + } + ], + "source": [ + "print(mmevents[-1].Muon.matched_gen.pdgId)\n", + "print(mmevents[-1].Muon.matched_gen.hasFlags([\"isPrompt\"]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So they are real generated muons, but they are not prompt (i.e. from the initial decay of a heavy resonance)\n", + "\n", + "Let's look at their parent particles:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mmevents[-1].Muon.matched_gen.parent.pdgId" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "aha! They are muons coming from tau lepton decays, and hence a fair amount of the Z mass is carried away by the neutrinos:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "31.265271292167853\n", + "91.68363205830444\n" + ] + } + ], + "source": [ + "print(mmevents[-1].Muon.matched_gen.sum().mass)\n", + "print(mmevents[-1].Muon.matched_gen.parent.sum().mass)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One can assign new variables to the arrays, with some caveats:\n", + "\n", + " * Assignment must use setitem (`events[\"path\", \"to\", \"name\"] = value`)\n", + " * Assignment to a sliced `events` won't be accessible from the original variable\n", + " * New variables are not visible from cross-references" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mmevents[\"Electron\", \"myvariable\"] = mmevents.Electron.pt + zmm.mass\n", + "mmevents.Electron.myvariable" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/_sources/notebooks/processor.ipynb.txt b/_sources/notebooks/processor.ipynb.txt new file mode 100644 index 000000000..92a2e0ce9 --- /dev/null +++ b/_sources/notebooks/processor.ipynb.txt @@ -0,0 +1,947 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Coffea Processors\n", + "This is a rendered copy of [processor.ipynb](https://github.com/CoffeaTeam/coffea/blob/master/binder/processor.ipynb). You can optionally run it interactively on [binder at this link](https://mybinder.org/v2/gh/coffeateam/coffea/master?filepath=binder%2Fprocessor.ipynb)\n", + "\n", + "Coffea relies mainly on [uproot](https://github.com/scikit-hep/uproot) to provide access to ROOT files for analysis.\n", + "As a usual analysis will involve processing tens to thousands of files, totalling gigabytes to terabytes of data, there is a certain amount of work to be done to build a parallelized framework to process the data in a reasonable amount of time. Of course, one can work directly within uproot to achieve this, as we'll show in the beginning, but coffea provides the `coffea.processor` module, which allows users to worry just about the actual analysis code and not about how to implement efficient parallelization, assuming that the parallization is a trivial map-reduce operation (e.g. filling histograms and adding them together). The module provides the following key features:\n", + "\n", + " * A `ProcessorABC` abstract base class that can be derived from to implement the analysis code;\n", + " * A [NanoEvents](https://coffeateam.github.io/coffea/notebooks/nanoevents.html) interface to the arrays being read from the TTree as inputs;\n", + " * A generic `accumulate()` utility to reduce the outputs to a single result, as showin in the accumulators notebook tutorial; and\n", + " * A set of parallel executors to access multicore processing or distributed computing systems such as [Dask](https://distributed.dask.org/en/latest/), [Parsl](http://parsl-project.org/), [Spark](https://spark.apache.org/), [WorkQueue](https://cctools.readthedocs.io/en/latest/work_queue/), and others.\n", + "\n", + "Let's start by writing a simple processor class that reads some CMS open data and plots a dimuon mass spectrum.\n", + "We'll start by copying the [ProcessorABC](https://coffeateam.github.io/coffea/api/coffea.processor.ProcessorABC.html#coffea.processor.ProcessorABC) skeleton and filling in some details:\n", + "\n", + " * Remove `flag`, as we won't use it\n", + " * Adding a new histogram for $m_{\\mu \\mu}$\n", + " * Building a [Candidate](https://coffeateam.github.io/coffea/api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate.html#coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate) record for muons, since we will read it with `BaseSchema` interpretation (the files used here could be read with `NanoAODSchema` but we want to show how to build vector objects from other TTree formats) \n", + " * Calculating the dimuon invariant mass" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import awkward as ak\n", + "from coffea import processor\n", + "from coffea.nanoevents.methods import candidate\n", + "import hist\n", + "\n", + "class MyProcessor(processor.ProcessorABC):\n", + " def __init__(self):\n", + " pass\n", + "\n", + " def process(self, events):\n", + " dataset = events.metadata['dataset']\n", + " muons = ak.zip(\n", + " {\n", + " \"pt\": events.Muon_pt,\n", + " \"eta\": events.Muon_eta,\n", + " \"phi\": events.Muon_phi,\n", + " \"mass\": events.Muon_mass,\n", + " \"charge\": events.Muon_charge,\n", + " },\n", + " with_name=\"PtEtaPhiMCandidate\",\n", + " behavior=candidate.behavior,\n", + " )\n", + "\n", + " h_mass = (\n", + " hist.Hist.new\n", + " .StrCat([\"opposite\", \"same\"], name=\"sign\")\n", + " .Log(1000, 0.2, 200., name=\"mass\", label=\"$m_{\\mu\\mu}$ [GeV]\")\n", + " .Int64()\n", + " )\n", + "\n", + " cut = (ak.num(muons) == 2) & (ak.sum(muons.charge, axis=1) == 0)\n", + " # add first and second muon in every event together\n", + " dimuon = muons[cut][:, 0] + muons[cut][:, 1]\n", + " h_mass.fill(sign=\"opposite\", mass=dimuon.mass)\n", + "\n", + " cut = (ak.num(muons) == 2) & (ak.sum(muons.charge, axis=1) != 0)\n", + " dimuon = muons[cut][:, 0] + muons[cut][:, 1]\n", + " h_mass.fill(sign=\"same\", mass=dimuon.mass)\n", + "\n", + " return {\n", + " dataset: {\n", + " \"entries\": len(events),\n", + " \"mass\": h_mass,\n", + " }\n", + " }\n", + "\n", + " def postprocess(self, accumulator):\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we were to just use bare uproot to execute this processor, we could do that with the following example, which:\n", + "\n", + " * Opens a CMS open data file\n", + " * Creates a NanoEvents object using `BaseSchema` (roughly equivalent to the output of `uproot.lazy`)\n", + " * Creates a `MyProcessor` instance\n", + " * Runs the `process()` function, which returns our accumulators\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'DoubleMuon': {'entries': 10000,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 4939.0 (4951.0 with flow)}}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import uproot\n", + "from coffea.nanoevents import NanoEventsFactory, BaseSchema\n", + "\n", + "filename = \"root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root\"\n", + "file = uproot.open(filename)\n", + "events = NanoEventsFactory.from_root(\n", + " file,\n", + " entry_stop=10000,\n", + " metadata={\"dataset\": \"DoubleMuon\"},\n", + " schemaclass=BaseSchema,\n", + ").events()\n", + "p = MyProcessor()\n", + "out = p.process(events)\n", + "out" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAEPCAYAAAC5sYRSAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAsDElEQVR4nO3de5hU5Znv/e/d1Seag8rJoBAaZxQFGohpQJQQdphtzKuJqImSiQ6eYsyWxODWiBkjnZgxvpm8OfDqRHGMshO3kHhITHR0J86QaIJIE4kKeIgIQkRogUBDH6vq3n/Uoau7q89dXV2rfp/r6qtrne+1Vvddz3rWs55l7o6IiARLQbYDEBGR/qfkLiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkCF2Q4AYPTo0V5eXp7tMEREcsqmTZved/cx6aYNiuReXl5OdXV1tsMQEckpZrazo2mqlhERCSAldxGRAFJyFxEJoC7r3M3sx8B5wD53nxYfNxJYC5QDO4CL3f1gfNotwFVABPiyuz/Tm8Cam5vZvXs3DQ0NvVlc2igtLWX8+PEUFRVlOxQRGQDduaH6IHAX8L9Sxi0HnnX3O81seXz4ZjObAiwGpgInAL81s1PcPdLTwHbv3s3w4cMpLy/HzHq6uKRwd/bv38/u3buZNGlStsMRkQHQZbWMu/8eONBm9PnA6vjn1cCilPFr3L3R3d8G/gLM7k1gDQ0NjBo1Som9H5gZo0aN0lWQSB7pbZ378e6+ByD+e2x8/InArpT5dsfH9YoSe//RsRTJL/19QzVdBknbYbyZXWNm1WZWXVNT062Vh0IhZs6cydSpU5kxYwbf+973iEajAFRXV/PlL3+514FnWlVVFd/97nezHYaI5InePsS018zGufseMxsH7IuP3w1MSJlvPPBuuhW4+ypgFUBlZWW33hgyZMgQNm/eDMC+ffv4x3/8Rw4dOsQ3vvENKisrqays7N3e5IBIJEIoFMp2GCKSI3pbcn8CWBL/vAT4Zcr4xWZWYmaTgJOBF/sWYnpjx45l1apV3HXXXbg769at47zzzgNipeQlS5Zw9tlnU15ezmOPPcZXv/pVKioqOOecc2hubgZiT8a+//77QKzkv2DBAgAOHDjAokWLmD59OmeccQYvv/xycr1XXnklCxYs4KSTTmLlypVpY3v66ac5/fTTmTFjBgsXLkyO37p1a9plFy1axIc//GGmTp3KqlWrkuOHDRvGbbfdxpw5c1i/fj33338/p5xyCgsWLODzn/88S5cuBaCmpoaLLrqIWbNmMWvWLP7whz/001EWCZ5L7l3PJfeuz3YYmefunf4ADwN7gGZiJfOrgFHAs8Cb8d8jU+b/Z+At4HXgE12t39358Ic/7G1t3bq13bihQ4e2G3fsscf6e++95//1X//l5557rru7r1ixws866yxvamryzZs3+5AhQ/ypp55yd/dFixb5448/7u7uEydO9JqaGnd337hxo3/0ox91d/elS5d6VVWVu7s/++yzPmPGjOR6586d6w0NDV5TU+MjR470pqamVvHs27fPx48f79u3b3d39/3793e5bGKeuro6nzp1qr///vvusYPpa9eudXf3v/71rz5x4kTfv3+/NzU1+bx58/y6665zd/fPfvaz/txzz7m7+86dO/3UU09td5w6OqYi+ebie/7oF9/zx2yH0S+Aau8gr3ZZLePun+1g0sJ0I939X4B/6f7XS994B++A/cQnPkFRUREVFRVEIhHOOeccACoqKtixY0en63z++ed59NFHAfjYxz7G/v37OXToEADnnnsuJSUllJSUMHbsWPbu3cv48eOTy77wwgvMnz8/2eRw5MiRyWkdLbty5Uoef/xxAHbt2sWbb77JqFGjCIVCXHTRRQC8+OKLfPSjH02u7zOf+QxvvPEGAL/97W/ZunVrcjuHDx+mtraW4cOHd+8gikjgDIqOw3pr+/bthEIhxo4dy7Zt21pNKykpAaCgoICioqJka5GCggLC4TAAhYWFyRuyqc0E031hJJZPrBdiN3gT60pdtqOWKemWXbduHb/97W9Zv349ZWVlLFiwIBlLaWlpsp69oy8xgGg0yvr16xkyZEiH84hIfsnZ7gdqamq49tprWbp0aa+b+ZWXl7Np0yaAZEkdYP78+Tz00EMArFu3jtGjRzNixIhurXPu3Ln87ne/4+233wZi9fedOXToEMcddxxlZWW89tprvPDCC2nnmz17Nr/73e84ePAg4XC4Vbxnn302d911V3I4cdNZRNrbuucwW/ccznYYGZdTJff6+npmzpxJc3MzhYWFXHbZZdxwww29Xt+KFSu46qqruOOOO5gzZ05yfFVVFVdccQXTp0+nrKyM1atXd7KW1saMGcOqVau48MILiUajjB07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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "fig, ax = plt.subplots()\n", + "out[\"DoubleMuon\"][\"mass\"].plot1d(ax=ax)\n", + "ax.set_xscale(\"log\")\n", + "ax.legend(title=\"Dimuon charge\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One could expand on this code to run over several chunks of the file, setting `entry_start` and `entry_stop` as appropriate. Then, several datasets could be processed by iterating over several files. However, the processor [Runner](https://coffeateam.github.io/coffea/api/coffea.processor.Runner.html) can help with this! One lists the datasets and corresponding files, the processor they want to run, and which executor they want to use. Available executors derive from `ExecutorBase` and are listed [here](https://coffeateam.github.io/coffea/modules/coffea.processor.html#classes). Since these files are very large, we limit to just reading the first few chunks of events from each dataset with `maxchunks`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e4fb80c50d72479a8b3906c885982cd4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n",
+       "
\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "17b53a251fbb4038896bcd937ea8a2dc", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
/opt/conda/lib/python3.8/site-packages/awkward/_connect/_numpy.py:195: RuntimeWarning: \n",
+       "invalid value encountered in sqrt\n",
+       "  result = getattr(ufunc, method)(\n",
+       "
\n" + ], + "text/plain": [ + "/opt/conda/lib/python3.8/site-packages/awkward/_connect/_numpy.py:195: RuntimeWarning: \n", + "invalid value encountered in sqrt\n", + " result = getattr(ufunc, method)(\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n",
+       "
\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "{'ZZ to 4mu': {'entries': 999380,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 192074.0 (192500.0 with flow)},\n", + " 'DoubleMuon': {'entries': 1000560,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 519403.0 (520002.0 with flow)}}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fileset = {\n", + " 'DoubleMuon': [\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root',\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012C_DoubleMuParked.root',\n", + " ],\n", + " 'ZZ to 4mu': [\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/ZZTo4mu.root'\n", + " ]\n", + "}\n", + "\n", + "iterative_run = processor.Runner(\n", + " executor = processor.IterativeExecutor(compression=None),\n", + " schema=BaseSchema,\n", + " maxchunks=10,\n", + ")\n", + "\n", + "out = iterative_run(\n", + " fileset,\n", + " treename=\"Events\",\n", + " processor_instance=MyProcessor(),\n", + ")\n", + "out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, if we want to use more than a single core on our machine, we simply change [IterativeExecutor](https://coffeateam.github.io/coffea/api/coffea.processor.IterativeExecutor.html) for [FuturesExecutor](https://coffeateam.github.io/coffea/api/coffea.processor.FuturesExecutor.html), which uses the python [concurrent.futures](https://docs.python.org/3/library/concurrent.futures.html) standard library. We can then set the most interesting argument to the `FuturesExecutor`: the number of cores to use (2):" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5448fcf953e3448e9fc80882b54a26aa", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n",
+       "
\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "{'ZZ to 4mu': {'entries': 999380,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 192074.0 (192500.0 with flow)},\n", + " 'DoubleMuon': {'entries': 1000560,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 519403.0 (520002.0 with flow)}}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "futures_run = processor.Runner(\n", + " executor = processor.FuturesExecutor(compression=None, workers=2),\n", + " schema=BaseSchema,\n", + " maxchunks=10,\n", + ")\n", + "\n", + "out = futures_run(\n", + " fileset,\n", + " \"Events\",\n", + " processor_instance=MyProcessor()\n", + ")\n", + "out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hopefully this ran faster than the previous cell, but that may depend on how many cores are available on the machine you are running this notebook and your connection to `eospublic.cern.ch`. At least the output will be prettier now:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlwAAAF7CAYAAAAHXVWjAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAABFZklEQVR4nO3deXxU1cH/8c/JvoeEJCwJEHbZUcIiIFBRoHXBvdaquFSrldra2qp9fNxauz2trfxcqK1b1borLrhUEBSVxYAssu9JCJCQkJ3s5/fHHUICSUhIbibJfN+vV16ZOXPunTPhMvOdc84911hrERERERH3+Hm7ASIiIiKdnQKXiIiIiMsUuERERERcpsAlIiIi4jIFLhERERGXBXi7AScTFxdnk5OTvd0MERERkZNavXr1IWtt/PHl7T5wJScnk5qa6u1miIiIiJyUMWZvfeUaUhQRERFxmQKXiIiIiMsUuERERERc1u7ncImIiEjLVVRUkJGRQWlpqbeb0imEhISQlJREYGBgk+orcImIiPiAjIwMIiMjSU5Oxhjj7eZ0aNZacnJyyMjIoG/fvk3aRkOKIiIiPqC0tJSuXbsqbLUCYwxdu3ZtVm+hApeIiIiPUNhqPc39WypwiYiIiLhMgUtERMRH+fv7M3r0aIYNG8aoUaN45JFHqK6uBiA1NZXbb7/dyy1s2AMPPMBf/vIXbzejyTRpXkRExEeFhoaydu1aALKysrjqqqvIz8/nwQcfJCUlhZSUFO820EVVVVX4+/u32fOph0tERERISEjgqaee4rHHHsNay9KlSzn//PMBpzdpzpw5zJgxg+TkZN566y1+/etfM2LECGbNmkVFRQXgXI7v0KFDgNNDNm3aNAByc3O56KKLGDlyJBMmTGD9+vU1+73hhhuYNm0a/fr1Y968efW27aOPPuKMM85g1KhRTJ8+vaZ806ZN9W570UUXMWbMGIYNG8ZTTz1VUx4REcF9993H+PHjWb58OU8//TSDBg1i2rRp3HTTTcydOxeA7OxsLr30UsaOHcvYsWP58ssvW/z3VQ+XiIiIANCvXz+qq6vJyso64bGdO3eyZMkSNm3axJlnnsmbb77Jn//8Zy6++GIWLlzIRRdd1OB+77//fk4//XQWLFjAp59+yrXXXlvTs7ZlyxaWLFlCYWEhgwcP5tZbb62ztlV2djY33XQTn3/+OX379iU3N7fmsYa2feaZZ4iNjeXIkSOMHTuWSy+9lK5du1JcXMzw4cN56KGHyMzM5Oqrr2bNmjVERkZy9tlnM2rUKAB+9rOfcccddzB58mTS0tKYOXMmmzdvbtHfVoFLREREalhr6y3/7ne/S2BgICNGjKCqqopZs2YBMGLECPbs2dPoPr/44gvefPNNAM4++2xycnLIz88H4LzzziM4OJjg4GASEhI4ePAgSUlJNduuWLGCKVOm1Kx3FRsbW/NYQ9vOmzePt99+G4D09HS2b99O165d8ff359JLLwVg1apVTJ06tWZ/l19+Odu2bQNg0aJFbNq0qeZ5CgoKKCwsJDIysml/xHoocIlIo37x2lp2ZRfzl8tHMSAhwtvNEREX7dq1C39/fxISEk7o0QkODgbAz8+PwMDAmmUR/Pz8qKysBCAgIKBm0n3tNarqC3FHtz+6X3Am8R/dV+1tG1qCob5tly5dyqJFi1i+fDlhYWFMmzatpi0hISE187YaCpYA1dXVLF++nNDQ0AbrNJfmcIlIo95as4+16XkcKa/ydlNExEXZ2dnccsstzJ0795TX60pOTmb16tUANT1aAFOmTOGll14CYOnSpcTFxREVFdWkfZ555pl89tln7N69G6DOkGJ98vPziYmJISwsjC1btrBixYp6640bN47PPvuMw4cPU1lZWae9M2bM4LHHHqu5f3T4syXUwyUiIuKjjhw5wujRo6moqCAgIIBrrrmGX/ziF6e8v/vvv58bb7yR3//+94wfP76m/IEHHuD6669n5MiRhIWF8fzzzzd5n/Hx8Tz11FNccsklVFdXk5CQwCeffNJg/VmzZjF//nxGjhzJ4MGDmTBhQr31EhMT+c1vfsP48ePp2bMnQ4cOJTo6GoB58+Zx2223MXLkSCorK5kyZQrz589vcpvrYxrrUmsPUlJSbGpqqrebIeKzku9eCMB7cyczIinay60RkVO1efNmhgwZ4u1mtCtFRUVERERQWVnJxRdfzA033MDFF1/c5O3r+5saY1Zba09YT0NDiiIiIuKTHnjgAUaPHs3w4cPp27dvo2datpSGFEVERMQnteVK9erhEhEREXGZApeIiIiIyxS4RERERFymwCUiIiLiMgUuERER8QmpqancfvvtgLMA61dffdVmz62zFEVERMQnpKSkkJLiLJG1dOlSIiIimDhxYps8t3q4RERExCseeeQRhg8fzvDhw/n73//Onj17OO2005gzZw4jR47ksssuo6SkBHAuG3TXXXcxbtw4xo0bx44dOwDYu3cv06dPZ+TIkUyfPp20tDQAXn/9dYYPH86oUaOYMmUK4ISs888/nz179jB//nz+9re/MXr0aJYtW0Z2djaXXnopY8eOZezYsXz55Zet+lrVwyUiIuLDHnxvI5syC1p1n0N7RnH/BcMarbN69WqeffZZVq5cibWW8ePHM3XqVLZu3crTTz/NpEmTuOGGG3jiiSe48847AYiKimLVqlX8+9//5uc//znvv/8+c+fO5dprr2XOnDk888wz3H777SxYsICHHnqIjz/+mMTERPLy8uo8d3JyMrfccgsRERE1+77qqqu44447mDx5MmlpacycOfOEC3i3hHq4REREpM198cUXXHzxxYSHhxMREcEll1zCsmXL6NWrF5MmTQLg6quv5osvvqjZ5gc/+EHN7+XLlwOwfPlyrrrqKgCuueaamvqTJk3iuuuu45///CdVVVUnbc+iRYuYO3cuo0eP5sILL6SgoIDCwsJWe73q4RIREfFhJ+uJcktD13I2xjR4v6Hb9dWfP38+K1euZOHChYwePZq1a9c22p7q6mqWL19OaGhoU5rfbOrhEhERkTY3ZcoUFixYQElJCcXFxbz99tucddZZpKWl1fRevfzyy0yePLlmm1dffbXm95lnngnAxIkTeeWVVwB46aWXaurv3LmT8ePH89BDDxEXF0d6enqd54+MjKzTgzVjxgwee+yxmvsnC2jNpcAlIiIibe6MM87guuuuY9y4cYwfP54f/ehHxMTEMGTIEJ5//nlGjhxJbm4ut956a802ZWVljB8/nkcffZS//e1vAMybN49nn32WkSNH8sILL/Doo48C8Ktf/YoRI0YwfPhwpkyZwqhRo+o8/wUXXMDbb79dM2l+3rx5pKamMnLkSIYOHcr8+fNb9fWahrr02ouUlBSbmprq7WaI+KzkuxcC8N7cyYxIivZya0TkVG3evJkhQ4Z4uxmN2rNnD+effz7ffvvtCY8lJyeTmppKXFycF1pWv/r+psaY1dbalOPrqodLRERExGWaNC8iIiLtQnJycr29W+D0fnVk6uESERERcZkCl4iIiIjLFLhEREREXKbAJSIiIuIyBS4RERERlylwiYiIiLhMgUtERETa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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "out[\"DoubleMuon\"][\"mass\"].plot1d(ax=ax)\n", + "ax.set_xscale(\"log\")\n", + "ax.legend(title=\"Dimuon charge\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting fancy\n", + "Let's flesh out this analysis into a 4-muon analysis, searching for diboson events:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "import numba\n", + "\n", + "\n", + "@numba.njit\n", + "def find_4lep(events_leptons, builder):\n", + " \"\"\"Search for valid 4-lepton combinations from an array of events * leptons {charge, ...}\n", + " \n", + " A valid candidate has two pairs of leptons that each have balanced charge\n", + " Outputs an array of events * candidates {indices 0..3} corresponding to all valid\n", + " permutations of all valid combinations of unique leptons in each event\n", + " (omitting permutations of the pairs)\n", + " \"\"\"\n", + " for leptons in events_leptons:\n", + " builder.begin_list()\n", + " nlep = len(leptons)\n", + " for i0 in range(nlep):\n", + " for i1 in range(i0 + 1, nlep):\n", + " if leptons[i0].charge + leptons[i1].charge != 0:\n", + " continue\n", + " for i2 in range(nlep):\n", + " for i3 in range(i2 + 1, nlep):\n", + " if len({i0, i1, i2, i3}) < 4:\n", + " continue\n", + " if leptons[i2].charge + leptons[i3].charge != 0:\n", + " continue\n", + " builder.begin_tuple(4)\n", + " builder.index(0).integer(i0)\n", + " builder.index(1).integer(i1)\n", + " builder.index(2).integer(i2)\n", + " builder.index(3).integer(i3)\n", + " builder.end_tuple()\n", + " builder.end_list()\n", + "\n", + " return builder\n", + "\n", + "\n", + "class FancyDimuonProcessor(processor.ProcessorABC):\n", + " def process(self, events):\n", + " dataset_axis = hist.axis.StrCategory([], growth=True, name=\"dataset\", label=\"Primary dataset\")\n", + " mass_axis = hist.axis.Regular(300, 0, 300, name=\"mass\", label=r\"$m_{\\mu\\mu}$ [GeV]\")\n", + " pt_axis = hist.axis.Regular(300, 0, 300, name=\"pt\", label=r\"$p_{T,\\mu}$ [GeV]\")\n", + " \n", + " h_nMuons = hist.Hist(\n", + " dataset_axis,\n", + " hist.axis.IntCategory(range(6), name=\"nMuons\", label=\"Number of good muons\"),\n", + " storage=\"weight\", label=\"Counts\",\n", + " )\n", + " h_m4mu = hist.Hist(dataset_axis, mass_axis, storage=\"weight\", label=\"Counts\")\n", + " h_mZ1 = hist.Hist(dataset_axis, mass_axis, storage=\"weight\", label=\"Counts\")\n", + " h_mZ2 = hist.Hist(dataset_axis, mass_axis, storage=\"weight\", label=\"Counts\")\n", + " h_ptZ1mu1 = hist.Hist(dataset_axis, pt_axis, storage=\"weight\", label=\"Counts\")\n", + " h_ptZ1mu2 = hist.Hist(dataset_axis, pt_axis, storage=\"weight\", label=\"Counts\")\n", + " \n", + " cutflow = defaultdict(int)\n", + " \n", + " dataset = events.metadata['dataset']\n", + " muons = ak.zip({\n", + " \"pt\": events.Muon_pt,\n", + " \"eta\": events.Muon_eta,\n", + " \"phi\": events.Muon_phi,\n", + " \"mass\": events.Muon_mass,\n", + " \"charge\": events.Muon_charge,\n", + " \"softId\": events.Muon_softId,\n", + " \"isolation\": events.Muon_pfRelIso03_all,\n", + " }, with_name=\"PtEtaPhiMCandidate\", behavior=candidate.behavior)\n", + " \n", + " # make sure they are sorted by transverse momentum\n", + " muons = muons[ak.argsort(muons.pt, axis=1)]\n", + " \n", + " cutflow['all events'] += len(muons)\n", + " \n", + " # impose some quality and minimum pt cuts on the muons\n", + " muons = muons[\n", + " muons.softId\n", + " & (muons.pt > 5)\n", + " & (muons.isolation < 0.2)\n", + " ]\n", + " cutflow['at least 4 good muons'] += ak.sum(ak.num(muons) >= 4)\n", + " h_nMuons.fill(dataset=dataset, nMuons=ak.num(muons))\n", + " \n", + " # reduce first axis: skip events without enough muons\n", + " muons = muons[ak.num(muons) >= 4]\n", + " \n", + " # find all candidates with helper function\n", + " fourmuon = find_4lep(muons, ak.ArrayBuilder()).snapshot()\n", + " if ak.all(ak.num(fourmuon) == 0):\n", + " # skip processing as it is an EmptyArray\n", + " return {\n", + " 'nMuons': h_nMuons,\n", + " 'cutflow': {dataset: cutflow},\n", + " }\n", + " fourmuon = [muons[fourmuon[idx]] for idx in \"0123\"]\n", + " fourmuon = ak.zip({\n", + " \"z1\": ak.zip({\n", + " \"lep1\": fourmuon[0],\n", + " \"lep2\": fourmuon[1],\n", + " \"p4\": fourmuon[0] + fourmuon[1],\n", + " }),\n", + " \"z2\": ak.zip({\n", + " \"lep1\": fourmuon[2],\n", + " \"lep2\": fourmuon[3],\n", + " \"p4\": fourmuon[2] + fourmuon[3],\n", + " }),\n", + " })\n", + " \n", + " cutflow['at least one candidate'] += ak.sum(ak.num(fourmuon) > 0)\n", + " \n", + " # require minimum dimuon mass\n", + " fourmuon = fourmuon[(fourmuon.z1.p4.mass > 60.) & (fourmuon.z2.p4.mass > 20.)]\n", + " cutflow['minimum dimuon mass'] += ak.sum(ak.num(fourmuon) > 0)\n", + " \n", + " # choose permutation with z1 mass closest to nominal Z boson mass\n", + " bestz1 = ak.singletons(ak.argmin(abs(fourmuon.z1.p4.mass - 91.1876), axis=1))\n", + " fourmuon = ak.flatten(fourmuon[bestz1])\n", + " \n", + " h_m4mu.fill(\n", + " dataset=dataset,\n", + " mass=(fourmuon.z1.p4 + fourmuon.z2.p4).mass,\n", + " )\n", + " h_mZ1.fill(\n", + " dataset=dataset, \n", + " mass=fourmuon.z1.p4.mass,\n", + " )\n", + " h_mZ2.fill(\n", + " dataset=dataset, \n", + " mass=fourmuon.z2.p4.mass,\n", + " )\n", + " h_ptZ1mu1.fill(\n", + " dataset=dataset,\n", + " pt=fourmuon.z1.lep1.pt,\n", + " )\n", + " h_ptZ1mu2.fill(\n", + " dataset=dataset,\n", + " pt=fourmuon.z1.lep2.pt,\n", + " )\n", + " return {\n", + " 'nMuons': h_nMuons,\n", + " 'mass': h_m4mu,\n", + " 'mass_z1': h_mZ1,\n", + " 'mass_z2': h_mZ2,\n", + " 'pt_z1_mu1': h_ptZ1mu1,\n", + " 'pt_z1_mu2': h_ptZ1mu2,\n", + " 'cutflow': {dataset: cutflow},\n", + " }\n", + "\n", + " def postprocess(self, accumulator):\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6f0938c279944980a1e4fd122f54d690", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n",
+       "
\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'nMuons': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " IntCategory([0, 1, 2, 3, 4, 5], name='nMuons', label='Number of good muons'),\n", + " storage=Weight()) # Sum: WeightedSum(value=6.76277e+07, variance=6.76277e+07) (WeightedSum(value=6.76279e+07, variance=6.76279e+07) with flow), 'mass': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=65472, variance=65472) (WeightedSum(value=82352, variance=82352) with flow), 'mass_z1': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=82303, variance=82303) (WeightedSum(value=82352, variance=82352) with flow), 'mass_z2': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=81873, variance=81873) (WeightedSum(value=82352, variance=82352) with flow), 'pt_z1_mu1': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='pt', label='$p_{T,\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=82351, variance=82351) (WeightedSum(value=82352, variance=82352) with flow), 'pt_z1_mu2': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='pt', label='$p_{T,\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=82170, variance=82170) (WeightedSum(value=82352, variance=82352) with flow), 'cutflow': {'ZZ to 4mu': defaultdict(, {'all events': 1499064, 'at least 4 good muons': 143618, 'at least one candidate': 143055, 'minimum dimuon mass': 81867}), 'DoubleMuon': defaultdict(, {'all events': 66128870, 'at least 4 good muons': 8289, 'at least one candidate': 3849, 'minimum dimuon mass': 485})}}\n" + ] + } + ], + "source": [ + "import time\n", + "\n", + "tstart = time.time() \n", + "\n", + "fileset = {\n", + " 'DoubleMuon': [\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root',\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012C_DoubleMuParked.root',\n", + " ],\n", + " 'ZZ to 4mu': [\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/ZZTo4mu.root'\n", + " ]\n", + "}\n", + "\n", + "\n", + "run = processor.Runner(\n", + " executor = processor.FuturesExecutor(compression=None, workers=4),\n", + " schema=BaseSchema,\n", + " chunksize=100_000,\n", + " # maxchunks=10, # total 676 chunks\n", + ")\n", + "\n", + "output = run(\n", + " fileset,\n", + " \"Events\",\n", + " processor_instance=FancyDimuonProcessor(),\n", + ")\n", + "\n", + "elapsed = time.time() - tstart\n", + "print(output)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Events/s: 153664.49672142894\n" + ] + } + ], + "source": [ + "nevt = output['cutflow']['ZZ to 4mu']['all events'] + output['cutflow']['DoubleMuon']['all events']\n", + "print(\"Events/s:\", nevt / elapsed)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What follows is just us looking at the output, you can execute it if you wish" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# scale ZZ simulation to expected yield\n", + "lumi = 11.6 # 1/fb\n", + "zzxs = 7200 * 0.0336**2 # approximate 8 TeV ZZ(4mu)\n", + "nzz = output['cutflow']['ZZ to 4mu']['all events']\n", + "\n", + "scaled = {}\n", + "for name, h in output.items():\n", + " if isinstance(h, hist.Hist):\n", + " scaled[name] = h.copy()\n", + " scaled[name].view()[0, :] *= lumi * zzxs / nzz" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1, 122819923.5463199)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "scaled['nMuons'].plot1d(ax=ax, overlay='dataset')\n", + "ax.set_yscale('log')\n", + "ax.set_ylim(1, None)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['mass'][:, ::hist.rebin(4)].plot1d(ax=ax, overlay='dataset');" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['mass_z1'].plot1d(ax=ax, overlay='dataset');" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2.0, 300.0)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['mass_z2'].plot1d(ax=ax, overlay='dataset')\n", + "ax.set_xlim(2, 300)\n", + "# ax.set_xscale('log')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAAELCAYAAADA/N09AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAVTUlEQVR4nO3db4xcV3nH8e/jdRynMWnjZhMbSHCMIkoAxwluoKLqP6B14koJKqggiiJDa1oRCaS2qlMQf/qGtCrwon8oRolrVTQUFWjSuilYKSiiigIOcTZxTBpwQgixY4NVJXGxt14/fXHvZDfrmZ3Z3ZmdOTPfjzSamXPvzDzXl/y4e++550RmIkkqz7J+FyBJWhgDXJIKZYBLUqEMcEkqlAEuSYUywCWpUMuX8scuuOCCXLdu3VL+pCQV77777vtRZo7Pbl/SAF+3bh179+5dyp+UpOJFxPebtXsKRZIKZYBLUqEMcEkqlAEuSYUywCWpUAa4JBXKAJekQhngklSo4QrwnVuqhySNgOEKcEkaIQa4JBXKAJekQrUN8IhYGRHfjIgHImJ/RHysbl8dEXsi4tH6+fzelytJaujkCPwk8GuZeQWwEdgcEa8HtgN3ZeZlwF31e0nSEmkb4Fl5rn57Vv1I4DpgV92+C7i+FwVKkprr6Bx4RIxFxD7gCLAnM+8FLsrMQwD184UtPrstIvZGxN6jR492qWxJUkcBnplTmbkReClwdUS8utMfyMwdmbkpMzeNj58xoYQkaYHm1QslM/8H+DqwGXg6ItYC1M9Hul2cJKm1TnqhjEfEz9SvzwHeBHwHuAO4oV7tBuD2HtUoSWqikzkx1wK7ImKMKvC/kJn/FhH3AF+IiPcATwBv62GdkqRZ2gZ4Zk4AVzZp/zHwxl4UJUlqzzsxJalQBrgkFWq4A9zhZSUNseEOcEkaYga4JBXKAJekQhngklQoA1ySCmWAS1KhhifAd26BwxNnth+esCuhpKE0PAEuSSPGAJekQhngklQoA1ySCmWAS1KhDHBJKpQBLkmFMsAlqVAGuCQVygCXpEIZ4JJUKANckgplgEtSoQxwSSpU2wCPiIsj4msRcSAi9kfE++v2j0bEDyNiX/24tvflNrFzC3z84uZDyUrSEFvewTqngD/MzG9HxIuA+yJiT73sU5n5l70rT5LUStsAz8xDwKH69bMRcQB4Sa8LkyTNbV7nwCNiHXAlcG/ddGNETETErRFxfreLm5dTJ2DyOBw72NcyJGmpdBzgEbEK+CLwgcx8Bvg08HJgI9UR+idafG5bROyNiL1Hjx5dfMWtnJ6CnILJ53r3G5I0QDoK8Ig4iyq8P5eZXwLIzKczcyozTwOfBa5u9tnM3JGZmzJz0/j4eLfqlqSR10kvlABuAQ5k5idntK+dsdpbgIe6X54kqZVOeqG8AXgX8GBE7Kvb/hR4R0RsBBJ4HHhvD+qTJLXQSS+UbwDRZNG/d7+cedq5xf7fkkaWd2JKUqEMcEkqlAEuSYUywCWpUAa4JBXKAJekQo1GgB+eqLocNrNzS+tlkjTAhjfA79xeBfepE/2uRJJ6opM7Mct0+EE4+QzEWL8rkaSeGN4jcEkacga4JBXKAJekQhngklSo4buIOXm8mqV+8ni/K5GknhqOI/BTJ6rp1JrJKbsSShpKwxHgp1uEd6fLJalAw3MKpVl/b/uASxpiw3EELkkjyACXpEIZ4JJUKANckgo1OgE+15CyklSg0QlwSRoyBrgkFaptgEfExRHxtYg4EBH7I+L9dfvqiNgTEY/Wz+f3vlxJUkMnR+CngD/MzFcCrwfeFxGXA9uBuzLzMuCu+r0kaYm0DfDMPJSZ365fPwscAF4CXAfsqlfbBVzfoxolSU3M6xx4RKwDrgTuBS7KzENQhTxwYdera+fYwWrUwVYDWUnSEOs4wCNiFfBF4AOZ+cw8PrctIvZGxN6jR48upMbWJp+rwjvGYNkYrDi3erRyeKIaatbuhJKGQEcBHhFnUYX35zLzS3Xz0xGxtl6+FjjS7LOZuSMzN2XmpvHx8W7UPKu4OriXr+z+d0vSAOukF0oAtwAHMvOTMxbdAdxQv74BuL375UmSWulkONk3AO8CHoyIfXXbnwI3A1+IiPcATwBv60mFkqSm2gZ4Zn4DiBaL39jdciRJnfJOTEkqVLkBfud2ONlxZxhJGjrlBvjhB6vnZU6bJmk0lT0n5tnn9bsCSeqbco/AJWnEGeCSVCgDXJIKNdwB3hgbJafg1Ikzl9+5vRof5fBE9VqSCjLcAQ6wYlX1fLrJiIWHH6xGM5w8Pt2rRZIKMfwBvnp9NeBVK+1GMJSkAVV2N8KFagwr20xjqNmtu5euHklagOE/ApekIWWAS1KhhifA12yoHrNt3e05bklDafjOgU8er56dJ1PSkBueI3CANa+ZPtqOsekuhJI0hIYrwK+5uTqN0ugauHp9vyuSpJ4ZrgCXpBFigDccnpjuAy5JBTDAJalQBrgkFWp0ArzViISSVKjRCPC5RiSUpEKNRoC3G5FQkgo0GgEuSUOobYBHxK0RcSQiHprR9tGI+GFE7Ksf1/a2zDms2QA3/cDhXyWNnE6OwP8e2Nyk/VOZubF+/Ht3y+qTxvRqUPUJt1+4pAHWNsAz827g2BLU0ns5VQ12ZW8USUNgMefAb4yIifoUy/mtVoqIbRGxNyL2Hj16dBE/t0jLxqoLmTllbxRJQ2GhAf5p4OXARuAQ8IlWK2bmjszclJmbxsfHF/hzXbB8ZTXAlb1RJA2JBQV4Zj6dmVOZeRr4LHB1d8uSJLWzoACPiLUz3r4FeKjVuj21ZoO9TySNrLYz8kTEbcCvABdExJPAR4BfiYiNQAKPA+/tXYmSpGbaBnhmvqNJ8y09qKV/GtOwNZs7c+eWqmuhR/uSBox3YkpSoQxwSSrUaAT41t3VKZBmGnNoSlJhRiPAJWkIGeCSVCgDXJIKZYBLUqHa9gMfSo1RCbPJoFanTsAT91SDXy1feebyxhCz9gmX1GfDF+DtgnXZGJymeXhDNVJhTlXrSNIAG71TKI5KKGlIjF6AS9KQMMAlqVAGuCQVygBvmKtniiQNoNEJ8LnGQ2kwvCUVZHQCXJKGjAEuSYUywCWpUAa4JBXKAJekQo1WgG/dDTf9oH1vFJjuVnjqRO/rkqQFGK0A78TMMVJyqhrcSpIGkAE+U4w50JWkYhjghyf6XYEkLUjbAI+IWyPiSEQ8NKNtdUTsiYhH6+fze1umJGm2To7A/x7YPKttO3BXZl4G3FW/lyQtobYBnpl3A8dmNV8H7Kpf7wKu725ZkqR2FnoO/KLMPARQP1/YvZIGTKM74eEJuNM/NCQNjp5fxIyIbRGxNyL2Hj16tNc/tzArVlU9T5a16H3yfIg/uLR1SdIcFhrgT0fEWoD6+UirFTNzR2ZuysxN4+PjC/y5Hlu9vuo+2GwWepjuXihJA2ShAX4HcEP9+gbg9u6UI0nqVCfdCG8D7gFeERFPRsR7gJuBN0fEo8Cb6/fl2LobLvmF5svWbPBoW1IRlrdbITPf0WLRG7tciyRpHrwTc76OHbRHiqSBYIA30+iVAmf2Tpl8Dk4+Y48USX3X9hTKSFq9vgpqSRpgHoFLUqE8Am/oZJIHSRogHoFLUqE8Au9UYzyUZnZueeH7rbun27bu7m1dkkaWR+CSVCgDXJIKZYBLUqEM8Jm27p4+Z71mgz1TJA00A1ySCmWAS1KhDHBJKpQBvlCt+oTPXmd2H3FJ6pLRDfA1r4Gzz6tGHpx58fKM9TbATT9wkgdJA2d078S85maHhJVUtNE9ApekwhngklQoA1ySCmWAS1KhRvci5lzmGgJ2zQb4/jeWrhZJasEAn4+ZY4JPHp/u4314wnFTJC05T6FIUqEWdQQeEY8DzwJTwKnM3NSNoiRJ7XXjFMqvZuaPuvA9kqR58BSKJBVqsUfgCXw1IhL4TGbu6EJNgyun4OQzZ7afOlFdyDz5TDW+yp3b4djB6kLnsYNLX6ekkbDYAH9DZj4VERcCeyLiO5l598wVImIbsA3gkksuWeTP9dGKVc3DG+D0jGA/+Uw1xsrkc1XgTz63dDVKGimLOoWSmU/Vz0eALwNXN1lnR2ZuysxN4+Pji/m5/lq9HmKs31VI0vMWfAQeEecCyzLz2fr1rwN/1rXKStBqTPCZ7ZPH4eMXV6/XbKhuEmr0H291w1C75ZLE4k6hXAR8OSIa3/OPmfkfXalKktTWggM8Mw8CV3SxlqXnEa6kgtmNUJIKZYAvVE5V3Qe7tZ4kzZMBvhinp7q7niTNgwG+EGef11mXwhiz66GknjHAJalQBrgkFcoJHXph8njrZTu3TE8A0bhhB144KUQnE0TM/Cyc2SVyEG4GalbDINQlDQkDfDFaDW4lSUvAUyjzsWysuoC5YlX1WpL6yCPwTs0cwwSqUQZPT1VH4WefV7XNPBpfcW693hynUyRpETwCl6RCGeCSVCgDXJIKZYBLUqEM8IXYunvuftqN7oVrNlQXM3Oquph5eKKaI7Mxh2az+TKdS1NSh+yFshjLxuA0VbfChtn9wlesmu6J0ng+PUf/cefSlNShcgK8cQdjw+Tx6a56/bJ8ZfW8ev0L25+4pwrhxrJGGE8ef2G3wsZReTMzp2LrRKt15/MdvdKshvnUNfMOVU3z3+VMg/pv0phOscs8hSJJhTLAJalQBvh8bN09/WdQ40Jmj/40kqR2DHBJKlQ5FzGHRU698PXk8eo5xqoLL52MnXLqxPQ4LDFW9YZpXFCduXx2+1JrVseg1CYNAY/Ae6ExauGa17RftxHojedOetY0wrvxudlzbjaW93suzmZ1DEpt0hAwwHth+crq3Pg1Nzdf3myuzBibPqfuPJqSOuAplMWYefGy2awzs9s/fnF1A0/jKLvVzTz97t8uqQiLOgKPiM0R8UhEfDcitnerKElSews+Ao+IMeBvgDcDTwLfiog7MvPhbhW3VD72r/t5+KnuTI12+YvP4yNd+SZJmttiTqFcDXw3Mw8CRMTngeuAngT48SfuZ2X+5Pn3yzjN/05O8e7P3LPo7773sWMAvO7S1Yv+nnsfO8bDl36oaphV262TU5wL7M+Xse7/DjLzRMn+sy7nzyarz304/5ifm9zf8neWcZqY8X4qE04+d8by2e39MAZkTnF6Rh3N2uZy4on7AV6w/+W/SzOD+m9y4on76cWJ0cjMhX0w4q3A5sz83fr9u4DXZeaNs9bbBmyr374CeGSBtV4A/GiBnx00bsvgGZbtALdlUC1mW16WmeOzGxdzBB5N2s74f4PM3AHsWMTvVD8WsTczNy32ewaB2zJ4hmU7wG0ZVL3YlsVcxHwSmDmk3EuBpxZXjiSpU4sJ8G8Bl0XEpRGxAng7cEd3ypIktbPgUyiZeSoibgS+QnVd6tbMbH3lbfEWfRpmgLgtg2dYtgPclkHV9W1Z8EVMSVJ/eSu9JBXKAJekQhUR4CXfsh8Rj0fEgxGxLyL21m2rI2JPRDxaP5/f7zqbiYhbI+JIRDw0o61l7RFxU72PHomI3+hP1c212JaPRsQP632zLyKunbFsILclIi6OiK9FxIGI2B8R76/bi9svc2xLiftlZUR8MyIeqLflY3V7b/dLZg70g+oC6feA9cAK4AHg8n7XNY/6HwcumNX2F8D2+vV24M/7XWeL2n8JuAp4qF3twOX1vjkbuLTeZ2P93oY22/JR4I+arDuw2wKsBa6qX78I+O+63uL2yxzbUuJ+CWBV/fos4F7g9b3eLyUcgT9/y35mTgKNW/ZLdh2wq369C7i+f6W0lpl3A8dmNbeq/Trg85l5MjMfA75Lte8GQottaWVgtyUzD2Xmt+vXzwIHgJdQ4H6ZY1taGeRtycxsjA1xVv1IerxfSgjwlwA/mPH+SebeyYMmga9GxH31sAIAF2XmIaj+Rwxc2Lfq5q9V7aXupxsjYqI+xdL487aIbYmIdcCVVEd7Re+XWdsCBe6XiBiLiH3AEWBPZvZ8v5QQ4B3dsj/A3pCZVwHXAO+LiF/qd0E9UuJ++jTwcmAjcAj4RN0+8NsSEauALwIfyMy5htIscVuK3C+ZOZWZG6nuSr86Il49x+pd2ZYSArzoW/Yz86n6+QjwZao/k56OiLUA9fOR/lU4b61qL24/ZebT9X90p4HPMv0n7EBvS0ScRRV4n8vML9XNRe6XZttS6n5pyMz/Ab4ObKbH+6WEAC/2lv2IODciXtR4Dfw68BBV/TfUq90A3N6fChekVe13AG+PiLMj4lLgMuCbfaivY43/sGpvodo3MMDbEhEB3AIcyMxPzlhU3H5ptS2F7pfxiPiZ+vU5wJuA79Dr/dLvq7cdXuG9luoK9feAD/a7nnnUvZ7qSvMDwP5G7cDPAncBj9bPq/tda4v6b6P6E/b/qI4Y3jNX7cAH6330CHBNv+vvYFv+AXgQmKj/g1o76NsC/CLVn9oTwL76cW2J+2WObSlxv2wA7q9rfgj4cN3e0/3irfSSVKgSTqFIkpowwCWpUAa4JBXKAJekQhngklQoA1ySCmWAa2RFxLqI+Ek9fkWj7aKI+MeIOFiPX3NPRLxlju/4+uyhQCPiAxHxtxFxTj0c6mREXNDDTdGIMsA16r6X1fgVjTsD/wW4OzPXZ+Zrqe78fekcn7+tXmemtwO3ZeZP6u8euNu9NRwMcBUhIj4fEf8UEfdGxPcjYksPfubXgMnM/LtGQ2Z+PzP/qq7hd+pB+/dFxGciYgz4Z+A3I+Lsep11wIuBb/SgPukFDHCV4grgYGa+Dngn8JEe/MargG83WxARrwR+m2p0yY3AFPDOzPwx1RgWm+tV3w78U3qLs5bA8n4XILVTDw50AfCxuulh4PyI2Aq8DvgN4CvA/Zn5mS7+7t9QjdcxSTUY/2uBb1VnWjiH6ZHlGqdRbq+f392tGqS5GOAqwauBRzPzRP3+KuCBzNwZEbcDyzPz92d/KCJeBfxmZv55RPw1cFNWM7+0sh/4rcabzHxfffFxL9X4zbsy86Ymn/sX4JMRcRVwTtazzEi95ikUleAK4JJ64thzqY7EP1Uvey0tTnsAm6hGggQ4r014A/wnsDIi/mBG20/Vz3cBb42IC+H5yWpfBpDVVFpfB26lOhqXloQBrhJcAXyOKiS/BXw6M/+rXvZa4L4Wn/t54OE69Nuqz1tfD/xyRDwWEd+kOnXyJ5n5MPAhqunxJoA9VJPyNtxW1/n5eWyXtCgOJ6uBFxF3A7+XmY80WXYb8O7M/ElEXER1yuSWetluqrG/nwFek5mbZ312HfBvmTnX1FfdqP9xYFNm/qiXv6PR4zlwleDlVAPinyEz3zHj7ZXAY/D8VF0/zsz3zvG9U8BPR8S+Rl/wbqovvt5DNUP56W5/v+QRuCQVynPgklQoA1ySCmWAS1KhDHBJKpQBLkmFMsAlqVAGuCQVygCXpEIZ4JJUqP8HbPacLOxSFOkAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['pt_z1_mu1'].plot1d(ax=ax, overlay='dataset');" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXAAAAEMCAYAAADd+e2FAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAaN0lEQVR4nO3df5Afd33f8ddLJ59ly3axqjMyWCCLIU75IcBcApSUtBAaGdOYTJipPSHjClq1mZBCp2kiDx0M/cdO2pB2SkJQgozbunIyDgESjRs8JK6Hjms427JkWXYMshECHTqjqYWEpUN37/6xu7691X6/3/3+0t3nvs/HzM33+9397Gffu6t7a2+/u++PI0IAgPSsWuoAAAC9IYEDQKJI4ACQKBI4ACSKBA4AiSKBA0CiOiZw27tsH7P9eGX6r9t+yvYB278zvBABAHVWN2jzeUmflvTfigm2/5GkGyRtiYgztq9osrL169fHpk2beggTAEbXww8//FxETFSnd0zgEfGA7U2Vyb8q6faIOJO3OdYkiE2bNmlqaqpJUwBAzva366b3eg38JyT9A9sP2f7ftn+qzYq3256yPTUzM9Pj6gAAVb0m8NWSLpf0Vkn/TtKf2nZdw4jYGRGTETE5MXHOXwAAgB71msCPSPpCZL4uaV7S+sGFBQDopNcE/kVJ75Qk2z8haVzScwOKCQDQQMcvMW3vlvQPJa23fUTSrZJ2SdqV31o4K+nmoKwhAJxXTe5CuanFrA8MOBYAQBd4EhMAEkUCB4BEkcA7ueP67Kfp9G76AIA+kMABIFEkcABIFAkcABJFAgeARJHAASBRJHAASBQJHAASRQIHgESRwAEgUSRwAEgUCRwAEkUCB4BEkcABIFEkcABIFAkcABLVMYHb3mX7WD7+ZXXeb9gO24xIPyzUEgfQQpMz8M9L2lqdaHujpHdLOjzgmAAADXRM4BHxgKTjNbN+T9JvSmI0egBYAj1dA7f9C5K+GxGPNWi73faU7amZmZleVgcAqNF1Ard9saSPSfp4k/YRsTMiJiNicmJiotvVAQBa6OUM/FWSrpb0mO1nJV0l6RHbGwYZGACgvdXdLhAR+yVdUXzOk/hkRDw3wLgAAB00uY1wt6QHJV1j+4jtDw0/LABAJx3PwCPipg7zNw0sGgBAYzyJCQCJIoEDQKJI4ACQKBI4ACSKBA4AiSKBA0Ciun6QZ0UryrZu29NfH9P7pA1bmvUziHUCGEmcgQNAokjgAJAoEjgAJIoEDgCJIoEDQKJI4ACQKBI4ACSKBA4AiSKBA0CiSOAAkCgSOAAkqsmYmLtsH7P9eGnaf7T9pO19tv/c9kuGGiUA4BxNzsA/L2lrZdp9kl4XEVsk/a2kWwYcFwCgg44JPCIekHS8Mu0rEXE2//h/JV01hNgAAG0M4hr4ByXd22qm7e22p2xPzczMDGB1AACpzwRu+2OSzkq6q1WbiNgZEZMRMTkxMdHP6oarqONdZ3rfQt3uTm2brqvcXyfT+6TbNi4sU7d8t30CSF7PAzrYvlnSeyW9KyJicCEBAJroKYHb3irptyT9bET8aLAhAQCaaHIb4W5JD0q6xvYR2x+S9GlJl0q6z/Ze23845DgBABUdz8Aj4qaayZ8bQiwAgC7wJCYAJIoEDgCJIoEDQKJI4ACQKBI4ACSKBA4AiSKBA0CiSOCdHD8kzZ7KXsvOns5qlNy7o1kfTdsCQEMk8E5mT0oxl72Wzc9JZ05I0/ub9dG0LQA0RAIHgESRwAEgUT2Xkx05s6eymtytNKnFffjBhT42bGnfz7Y93cUHYORwBg4AiSKBA0CiSOAAkCgSOAAkigQOAIkigQNAopqMibnL9jHbj5emrbN9n+2n89fLhxsmAKCqyRn45yVtrUzbIemrEfFqSV/NPwMAzqOOCTwiHpB0vDL5Bkl35u/vlPS+wYYFSVnxq+l9WeEsAKjo9Rr4SyPiqCTlr1e0amh7u+0p21MzMzM9rm5ETe/PimDNzy11JACWoaF/iRkROyNiMiImJyYmhr06ABgZvSbw79u+UpLy12ODCwkA0ESvCfzLkm7O398s6UuDCQcA0FST2wh3S3pQ0jW2j9j+kKTbJb3b9tOS3p1/BgCcRx3LyUbETS1mvWvAsQAAujCaT2Lecf1C3e3y+0Ga3jecfgEgN5oJHABWABI4ACSKBA4AiSKBA0CiSOAAkCgSOAAkigRedvZ0dvvfvX1Uxz1+SJo9lf0cP9Ssfb/rBDCSOj7IM1Lm57Lqf9P7e+9j9qQUcwvvm7Tvd50ARhIJfBg8ttQRABgBXEIBgESRwAEgUSRwAEgUCRwAEkUCB4BEkcABIFGjcxthuTb39D5pw5Zmy8yeataurs/ZU9JtG1v30an/6X3nfu6mxnjRdtue7uYBSAJn4ACQqL4SuO1/Y/uA7cdt77a9ZlCBAQDa6zmB2365pH8taTIiXidpTNKNgwoMANBev9fAV0u6yPaPJV0s6Xv9h7REjh9aqGFSJ+ayYler12Sv7dp2UhTNGr+kWfuYy66VrxrLi2WdXLzsvTu66w/AitDzGXhEfFfSf5J0WNJRSc9HxFeq7Wxvtz1le2pmZqb3SIetSeGp+bnFr70qimY1WaeU1VaJuWy5ovhVednp/d31B2BF6OcSyuWSbpB0taSXSVpr+wPVdhGxMyImI2JyYmKi90jPB49JF15WP71aoKpV22HENL6WAlkAztHPl5g/J+mZiJiJiB9L+oKkvz+YsAAAnfSTwA9Leqvti21b0rskHRxMWACATvq5Bv6QpHskPSJpf97XzgHFtXyMr81+6qY3eRioaAsAA9bXXSgRcaukWwcUCwCgCzyJCQCJIoEDQKJI4ACQKBI4ACSKBA4AiVr59cBb1c9uVVt79pR0+MGsjncT5Zrd0/ua1Q8ftGrd8Grt8/LndvW/qREOJGXlJ/BBKopK1RWyOns6q1USc60fe2+3vERRKgBdIYE3tWpMms/fe+zcJFsk73aKxF4Up6oqilIBQAMk8KZWV8aqWLe5u+XPR+ErACOFLzGXu24e2QcwUkjgAJAoEjgAJIoEDgCJIoEDQKJI4ACQKBI4ACSKBA4AiSKBA0Ci+krgtl9i+x7bT9o+aPttgwoMANBev4/S/xdJ/ysi3m97XNLFA4gJANBAzwnc9mWS3iHpn0lSRMxKmh1MWEN0/FBWEXDVWP7+ZDb9zImFeiX9loR9xduyqoJnTmRVCqt1VMrG11LACkBP+rmEslnSjKQ7bD9q+49tr602sr3d9pTtqZmZmT5WNyCzJ7NKgPNz2fvZU8Op4V1UK5zvUKEQAHrUTwJfLelaSZ+JiDdJOiVpR7VRROyMiMmImJyYmOhjdQNQHXCh38TdbgCHdZtb1wUv1l1ednrfwsAMs6daD0RRdsf1i9vNnsoGoqgO8FBeR6d+p/dlfRR9l9uXP1fnATjv+kngRyQdiYiH8s/3KEvoAIDzoOcEHhHTkr5j+5p80rskPTGQqAAAHfV7F8qvS7orvwPlkKRt/YcEAGiirwQeEXslTQ4mFABAN3gSEwASRQIHgESRwAEgUSRwAEgUCbys1ejvG7Ysnrdhi7RtT3/rGT/nodXWtu3JHs8vL1MXazd9AkgeCRwAEtXvfeBpKIpWdVs06uxpaa5Bfa6zp7P6KnViLnvEve7sOOZax3T80OICW1J38RfbfPb0ufPu3ZE9Ml/UawGQpNE4A+8leUsLhag2vL5Zu6pVY1k9lPG13SfLokpisVynGOqWP3OiPrbp/dm8Yh0AkjQaCbzMY+2LTFVdeJl03e299bt6TZa8N2zJilu16v+VP9N6XrHcdbcvPhsHMPJGL4EDwApBAgeARJHAASBRK+sulDuuz+6uaHU/93JVDAxRvlOl02AT5UEb6tpWB4uoW7YYOGLbnoV9V7dMMXBDMe22jQvzbtu4eH8X98cXy1Tvl687Rr3eU99qHedDu3UvZVzLCfth6DgDB4BEkcABIFEr6xLKMHX6M7C4/NHqfvPq8uXLEHV9DWOgZQArCmfgAJCovhO47THbj9r+y0EEBABoZhBn4B+RdHAA/QAAutBXArd9laTrJf3xYMIBADTV75eY/1nSb0q6tP9QhqBdFcKiemBdXZSigmCrCoN1/SyVaiXEs6ezAlbFtKLiocey4lqtHD+UbfOqsayGC4Blr+czcNvvlXQsIh7u0G677SnbUzMzM72urjetkne7RDZ+yUJS91jzKoLjl2Q/F17WfeXAflSrDZaTd1nMta6aKGX7qlMbAMtKP5dQ3i7pF2w/K+luSe+0/T+qjSJiZ0RMRsTkxMREH6sboNVrWlckXLc5L/+a/7SqIljmsazdus3ZE4ZNqhcOksfqKxV2W3kRQFJ6TuARcUtEXBURmyTdKOmvI+IDA4sMANAW94EDQKIG8iRmRNwv6f5B9AUAaGY0z8DLo8IX17oHbdue9KoiAkjKaCZwAFgBSOAAkCgSOAAkamWWky2POIPFitF/yp9v29h+X1VH9Gk3v93oPe2WKUYFkhaP6lOM3lMdNaj8/UKxXLnf6og/1ZGAqttUnl6sr67/cnztTO9b2K7qtrTqp8koP61i7LR8u3ZNRxdihJ1zLfE+4QwcABJFAgeARK3MSygpKopOSQuv7R6DLwpUxdxCu04FuGIuK3bVKY6iqJWU1UYpClwVhbLq5gE470brDLxcka8oWtVPEaqij3bFsTot27RYVp1ysh6/JLufvVPtk07Fqor/FObnFgpjFcuUP1fnATjvRieBeyxLcMXZYlG0qp8iVEUfvZyBltdfuPAy6RPP1xematJf8YBSXRJvUtiq2EcUwAKSMDoJfHxtluDqvr1vpWnbVu227ZFu+U7rPjr1P7528fxun+zs9JTpMJ5ABXDejE4CB4AVhgQOAIkigQNAokjgAJAoEjgAJIoEDgCJIoEDQKJ6TuC2N9r+G9sHbR+w/ZFBBgYAaK+fWihnJf3biHjE9qWSHrZ9X0Q8MaDYAABt9JzAI+KopKP5+x/aPijp5ZLSSODl+sbV6d0oP025VHWSiyc2i+0ZX7tQEGvDFunbX1t46rJd3e/iadXDDw43XgADMZBr4LY3SXqTpIcG0V9P7t2xMFjBmROdK/ONqphb2C9nTmQVBs+ePndfldsVlRLLn8vvy/v8+KFs+tnT2edq9cNiet0y3Th+KDvevSw7CMX6791RP6/X7VpJ2u0jDETfCdz2JZL+TNJHI+JEzfzttqdsT83MzPS7utam9y9O2ikl72plwlaVCje8fqHQVfFa166orjh+ycIyraoezpcqChZtVo21L35VnldUL5TyZH5yod+6aoXF9LplujF7Mv8PoIdlB6FY//T++nm9btdK0m4fYSD6qgdu+wJlyfuuiPhCXZuI2ClppyRNTk5GP+vraHxtmmfe6zZn/9iLyoTVz4Xrbl/8y1AMC1ZtV/5cXqZo7zHpFW9bPLyaxxaWq1ZXLPZpUa2wqtt9XiT/1I4TsMz0nMBtW9LnJB2MiE8NLqQWyuMh1mH8y+Vh9lTnMTTrlimPnVk3jmb1+BfHu9X6ytPK/bWKrTy9GCe0lfIYoocfPLdtObbqvFZxVfvvpBhzs9pn0+Xr2nXa5m77b7ePhqXVmKfD1mn7uqmC2oV+LqG8XdKvSHqn7b35z3sGFBcAoIN+7kL5miQPMBYAQBd4EhMAEkUCB4BEkcABIFF93UaYnOq3wP1+K9zP8tVlq0901j0lWlUdI7PcZ93yxVOZTeIqL188mVk8qTm9b+m+7QfwIs7AASBRJHAASBQJHAASNVrXwHGu4nH2VnVPeumvqIRYfC4/JVs8kl9dpih6NT+X1WJZvSabNj+XXWc/c2LxctViWtV+i8+rxhb6bbX+6vRi/dJCDOX+qqUG2u2Ls6cXb0s1tnJfRZu6dVTjkLJiUUX5g3bL1vVT3cft1lneh91s/0rXdJ8P0co7Ay8KMUkLr+2KOY2SorBV8QtZFM0qJ7o6xT5ttQ/L+7yqOr1YV3WZoqhWuQBW8bn4D6BVobLq9PJrud8my1cLcM3PndtfN6rb0q6vVgXA6uKoFstqt2y7dTRZZ92xwbLYJyvvDLz6P2H1To1RVhS2KhfBalIxr9in1aJZ1flS58JXddrVsSn6Kc7A2xUsaze/XECrGlvdGXy/6voaVBGvQcaJpK28M3AAGBEkcABI1Mq6hDK+VrrlO80egllO6h4IavWQUNOHh8rt2j00VJRprZa7rHsoqNW6Oz30U7fuumVSUh62rm6eRInjdvsIA8EZOAAkigQOAIkigQNAokjgAJAoEjgAJKqvBG57q+2nbH/T9o5BBQUA6KyfUenHJP2+pHdLOiLpG7a/HBFPDCq4ng1h9OemPvkXB/TE94Z/69RrXnaZbv0nr+1+wV5qondqU55/28bs1rFOo3BXl5k9de5tZ8WtiFJWx7x8m2hdXfO6+cWTmUVf5X4KRftWtz5W19FE0U9xK2G573a3HzaZ94q3tY6xaXzVdu2WK/ZhN/2PkiXcJ/3cB/7Tkr4ZEYckyfbdkm6QNJQEfurwo1oTL7Scv0rz+tHsnD742aW7p/iJoyf0w9NnJUlvuXrd0Nbz0DPH9dAzx3XPw0f0ozNndfGFq/WaKy8b2vq6sWt2TmslHTj6vP5Dw2Oxa3ZOF8ec5s+c1JikyN9L0pNHn5ckvVbSqfz4fvwHz6vuv666+XNnTr74b+PZo88v6qdQtD+Vt/nJUnmBVZpfNHL33JmFedVYy548+rw2/Xhhu8rTil/3umXb9Vk8QH8g72dNvKDT+e9FEedczXJl1XbtlivPa9p/XcyttmcYTh9+VJLa5opB6WafnD78qIaR5h0RvS1ov1/S1oj45/nnX5H0loj4cKXddknb84/XSHqqx1jXS3qux2WXG7Zl+Vkp2yGxLctVP9vyyoiYqE7s5wzcNdPO+d8gInZK2tnHerKV2VMRMdlvP8sB27L8rJTtkNiW5WoY29LPl5hHJG0sfb5K0vf6CwcA0FQ/Cfwbkl5t+2rb45JulPTlwYQFAOik50soEXHW9ocl/ZWy7yp2RcSBgUV2rr4vwywjbMvys1K2Q2JblquBb0vPX2ICAJYWT2ICQKJI4ACQqCQSeMqP7Nt+1vZ+23ttT+XT1tm+z/bT+evlSx1nHdu7bB+z/XhpWsvYbd+SH6OnbP/80kRdr8W2fML2d/Njs9f2e0rzluW22N5o+29sH7R9wPZH8unJHZc225LicVlj++u2H8u35ZP59OEel4hY1j/KviD9lqTNksYlPSbpNUsdVxfxPytpfWXa70jakb/fIem3lzrOFrG/Q9K1kh7vFLuk1+TH5kJJV+fHbGypt6HDtnxC0m/UtF222yLpSknX5u8vlfS3ebzJHZc225LicbGkS/L3F0h6SNJbh31cUjgDf/GR/YiYlVQ8sp+yGyTdmb+/U9L7li6U1iLiAUnHK5NbxX6DpLsj4kxEPCPpm8qO3bLQYltaWbbbEhFHI+KR/P0PJR2U9HIleFzabEsry3lbIiKKZ+ovyH9CQz4uKSTwl0sqVR7SEbU/yMtNSPqK7YfzsgKS9NKIOCpl/4glXbFk0XWvVeypHqcP296XX2Ip/rxNYltsb5L0JmVne0kfl8q2SAkeF9tjtvdKOibpvogY+nFJIYE3emR/GXt7RFwr6TpJv2b7HUsd0JCkeJw+I+lVkt4o6aik382nL/ttsX2JpD+T9NGIaFf+MsVtSfK4RMRcRLxR2VPpP237dW2aD2RbUkjgST+yHxHfy1+PSfpzZX8mfd/2lZKUvx5bugi71ir25I5TRHw//6Wbl/RHWvgTdllvi+0LlCW8uyLiC/nkJI9L3bakelwKEfH/JN0vaauGfFxSSODJPrJve63tS4v3kv6xpMeVxX9z3uxmSV9amgh70ir2L0u60faFtq+W9GpJX1+C+BorfrFyv6js2EjLeFtsW9LnJB2MiE+VZiV3XFptS6LHZcL2S/L3F0n6OUlPatjHZam/vW34De97lH1D/S1JH1vqeLqIe7Oyb5ofk3SgiF3S35X0VUlP56/rljrWFvHvVvYn7I+VnTF8qF3skj6WH6OnJF231PE32Jb/Lmm/pH35L9SVy31bJP2Msj+190nam/+8J8Xj0mZbUjwuWyQ9msf8uKSP59OHelx4lB4AEpXCJRQAQA0SOAAkigQOAIkigQNAokjgAJAoEjgAJIoEDgCJIoFjZNneZPuFvABRMe2ltv+n7UN5AbIHbf9imz7ur9Zytv1R239g+6K8nvWs7fVD3BSMKBI4Rt23IitAVDza/UVJD0TE5oh4s7LSDVe1WX533qbsRkm7I+KFvO9lV68DKwMJHEmwfbftP7H9kO1v275+CKt5p6TZiPjDYkJEfDsi/msewwfyUVf22v6s7TFJ90h6r+0L8zabJL1M0teGEB+wCAkcqXiDpEMR8RZJvyzp1iGs47WSHqmbYfvvSfqnysoDv1HSnKRfjogfKCtCtDVveqOkPwlqVOA8WL3UAQCd5NXd1kv6ZD7pCUmX294m6S2Sfl7SX0l6NCI+O8D1/r6ygkuzykZTebOkb2RXWnSRFkqDFpdRvpS/fnBQMQDtkMCRgtdJejoiTuefr5X0WETcYftLklZHxL+qLmT7tZLeGxG/bfvTkm6JbOiuVg5I+qXiQ0T8Wv7l45SyAvx3RsQtNct9UdKnbF8r6aLIhwkDho1LKEjBGyS9Ih/5e62yM/Hfy+e9WS0ue0iaVFbKV5Iu65C8JemvJa2x/aulaRfnr1+V9H7bV0gvjjb+SkmKbCzE+yXtUnY2DpwXJHCk4A2S7lKWJL8h6TMR8X/yeW+W9HCL5X5K0hN50u8ov279Pkk/a/sZ219XdunktyLiCUn/Xtn4pvsk3adsVPXC7jzOu7vYLqAv1APHsmf7AUn/IiKeqpm3W9IHI+IF2y9Vdsnkc/m8PcoGbzgh6fURsbWy7CZJfxkR7cYuHET8z0qajIjnhrkejB6ugSMFr1I2osk5IuKm0sc3SXpGenGsxR9ExL9s0++cpL9je29xL/gg5V++PijpAknzg+4f4AwcABLFNXAASBQJHAASRQIHgESRwAEgUSRwAEgUCRwAEkUCB4BEkcABIFH/HxmR9/GBvsb+AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['pt_z1_mu2'].plot1d(ax=ax, overlay='dataset');" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/_sources/reference.rst.txt b/_sources/reference.rst.txt new file mode 100644 index 000000000..64f1499f8 --- /dev/null +++ b/_sources/reference.rst.txt @@ -0,0 +1,29 @@ +API Reference Guide +******************* +Coffea: a column object framework for effective analysis. + +When executing + + >>> import coffea + +a subset of the full coffea package is imported into the python environment. +Some packages must be imported explicitly, so as to avoid importing unnecessary +and/or heavy dependencies. Below lists the packages available in the ``coffea`` namespace. + +.. autosummary:: + :toctree: modules + :template: automodapi_templ.rst + + coffea.analysis_tools + coffea.btag_tools + coffea.hist + coffea.jetmet_tools + coffea.lookup_tools + coffea.lumi_tools + coffea.nanoevents + coffea.nanoevents.methods.base + coffea.nanoevents.methods.candidate + coffea.nanoevents.methods.nanoaod + coffea.nanoevents.methods.vector + coffea.processor + coffea.util diff --git a/_sources/wq.rst.txt b/_sources/wq.rst.txt new file mode 100644 index 000000000..b0d1421b5 --- /dev/null +++ b/_sources/wq.rst.txt @@ -0,0 +1,101 @@ +.. _intro-coffea-wq: + +Work Queue Executor +=================== + +`Work Queue `_ is a +distributed computing framework used to build large scale manager-worker +applications, developed by the Cooperative Computing Lab +(CCL) at the University of Notre Dame. This executor functions as the +manager program which divides up a Coffea data analysis workload into +discrete tasks. A large number of worker processes running on +cluster or cloud systems will execute the tasks. + +To set up Coffea and Work Queue together, you may need to +create a Conda environment, install the software, and then +create a tarball containing the environment. The tarball is +sent to each worker in order to provide the same environment +as the manager machine. + +.. code-block:: bash + + # Create a new environment + conda create --yes --name coffea-env -c conda-forge python coffea xrootd ndcctools conda conda-pack + conda activate coffea-env + + # Pack the environment into a portable tarball. + conda-pack --output coffea-env.tar.gz + +To run an analysis, you must set up a work queue executor +with appropriate arguments. Here is a complete example: + +.. literalinclude:: wq-example.py + :language: Python + +When executing this example, +you should see that Coffea begins to run, and a progress bar +shows the creation of tasks. Workers are created locally using the factory +declared. + +You can also launch workers outside python. For testing purposes, you can start +a single worker on the same machine, and direct it to connect to your manager +process, like this: + +.. code-block:: + + work_queue_worker -P password.txt 9123 + +Or: + +.. code-block:: + + work_queue_worker -P password.txt -M coffea-wq-${USER} + +With a single worker, the process will be gradual as it completes +one task (or a few tasks) at a time. The output will be similar to this: + +.. code-block:: + + ------------------------------------------------ + Example Coffea Analysis with Work Queue Executor + ------------------------------------------------ + Manager Name: -M coffea-wq-btovar + ------------------------------------------------ + Listening for work queue workers on port 9123. + submitted preprocessing task id 1 item pre_0, with 1 file + submitted preprocessing task id 2 item pre_1, with 1 file + preprocessing task id 2 item pre_1 with 1 events on localhost. return code 0 (success) + allocated cores: 2.0, memory: 1000 MB, disk 2000 MB, gpus: 0.0 + measured cores: 0.3, memory: 120 MB, disk 6 MB, gpus: 0.0, runtime 3.1 s + preprocessing task id 1 item pre_0 with 1 events on localhost. return code 0 (success) + allocated cores: 2.0, memory: 1000 MB, disk 2000 MB, gpus: 0.0 + measured cores: 0.3, memory: 120 MB, disk 6 MB, gpus: 0.0, runtime 2.9 s + submitted processing task id 3 item p_2, with 100056 event + submitted processing task id 4 item p_3, with 100056 event + submitted processing task id 5 item p_4, with 100056 event + submitted processing task id 6 item p_5, with 100056 event + Preprocessing 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2/2 [ 0:00:06 < 0:00:00 | 0.3 file/s ] + Submitted 0% 0/400224 [ 0:00:00 < -:--:-- | ? event/s ] + Processed 0% 0/400224 [ 0:00:00 < -:--:-- | ? event/s ] + Accumulated 0% 0/1 [ 0:00:00 < -:--:-- | ? tasks/s ] + + +To run at larger scale, you will need to run a large number +of workers on a cluster or other infrastructure. For example, +to submit 32 workers to an HTCondor pool: + +.. code-block:: + + condor_submit_workers -M coffea-wq-${USER} -P password.txt 1 + + +Similarly, you can run the worker's factory outside the manager. In that way, +you can have the manager and the factory running on different machines: + +.. code-block:: + + work_queue_factory -T condor -M coffea-wq-${USER} -P password.txt --max-workers 10 --cores 8 --python-env=env.tar.gz + +For more information on starting and managing workers +on various batch systems and clusters, see the +`Work Queue `_ documentation diff --git a/_static/_sphinx_javascript_frameworks_compat.js b/_static/_sphinx_javascript_frameworks_compat.js new file mode 100644 index 000000000..81415803e --- /dev/null +++ b/_static/_sphinx_javascript_frameworks_compat.js @@ -0,0 +1,123 @@ +/* Compatability shim for jQuery and underscores.js. + * + * Copyright Sphinx contributors + * Released under the two clause BSD licence + */ + +/** + * small helper function to urldecode strings + * + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent#Decoding_query_parameters_from_a_URL + */ +jQuery.urldecode = function(x) { + if (!x) { + return x + } + return decodeURIComponent(x.replace(/\+/g, ' ')); +}; + +/** + * small helper function to urlencode strings + */ +jQuery.urlencode = encodeURIComponent; + +/** + * This function returns the parsed url parameters of the + * current request. Multiple values per key are supported, + * it will always return arrays of strings for the value parts. + */ +jQuery.getQueryParameters = function(s) { + if (typeof s === 'undefined') + s = document.location.search; + var parts = s.substr(s.indexOf('?') + 1).split('&'); + var result = {}; + for (var i = 0; i < parts.length; i++) { + var tmp = parts[i].split('=', 2); + var key = jQuery.urldecode(tmp[0]); + var value = jQuery.urldecode(tmp[1]); + if (key in result) + result[key].push(value); + else + result[key] = [value]; + } + return result; +}; + +/** + * highlight a given string on a jquery object by wrapping it in + * span elements with the given class name. + */ +jQuery.fn.highlightText = function(text, className) { + function highlight(node, addItems) { + if (node.nodeType === 3) { + var val = node.nodeValue; + var pos = val.toLowerCase().indexOf(text); + if (pos >= 0 && + !jQuery(node.parentNode).hasClass(className) && + !jQuery(node.parentNode).hasClass("nohighlight")) { + var span; + var isInSVG = jQuery(node).closest("body, svg, foreignObject").is("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.className = className; + } + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + node.parentNode.insertBefore(span, node.parentNode.insertBefore( + document.createTextNode(val.substr(pos + text.length)), + node.nextSibling)); + node.nodeValue = val.substr(0, pos); + if (isInSVG) { + var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); + var bbox = node.parentElement.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute('class', className); + addItems.push({ + "parent": node.parentNode, + "target": rect}); + } + } + } + else if (!jQuery(node).is("button, select, textarea")) { + jQuery.each(node.childNodes, function() { + highlight(this, addItems); + }); + } + } + var addItems = []; + var result = this.each(function() { + highlight(this, addItems); + }); + for (var i = 0; i < addItems.length; ++i) { + jQuery(addItems[i].parent).before(addItems[i].target); + } + return result; +}; + +/* + * backward compatibility for jQuery.browser + * This will be supported until firefox bug is fixed. + */ +if (!jQuery.browser) { + jQuery.uaMatch = function(ua) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || + /(webkit)[ \/]([\w.]+)/.exec(ua) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || + /(msie) ([\w.]+)/.exec(ua) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; + }; + jQuery.browser = {}; + jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; +} diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 000000000..7ebbd6d07 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,914 @@ +/* + * Sphinx stylesheet -- basic theme. + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin-top: 10px; +} + +ul.search li { + padding: 5px 0; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +ol.arabic { + list-style: decimal; +} + +ol.loweralpha { + list-style: lower-alpha; +} + +ol.upperalpha { + list-style: upper-alpha; +} + +ol.lowerroman { + list-style: lower-roman; +} + +ol.upperroman { + list-style: upper-roman; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + margin-left: 30px; +} + +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + +dl > dd:last-child, +dl > dd:last-child > :last-child { + margin-bottom: 0; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/check-solid.svg b/_static/check-solid.svg new file mode 100644 index 000000000..92fad4b5c --- /dev/null +++ b/_static/check-solid.svg @@ -0,0 +1,4 @@ + + + + diff --git a/_static/clipboard.min.js b/_static/clipboard.min.js new file mode 100644 index 000000000..54b3c4638 --- /dev/null +++ b/_static/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.8 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return n={686:function(t,e,n){"use strict";n.d(e,{default:function(){return o}});var e=n(279),i=n.n(e),e=n(370),u=n.n(e),e=n(817),c=n.n(e);function a(t){try{return document.execCommand(t)}catch(t){return}}var f=function(t){t=c()(t);return a("cut"),t};var l=function(t){var e,n,o,r=1 + + + + diff --git a/_static/copybutton.css b/_static/copybutton.css new file mode 100644 index 000000000..f1916ec7d --- /dev/null +++ b/_static/copybutton.css @@ -0,0 +1,94 @@ +/* Copy buttons */ +button.copybtn { + position: absolute; + display: flex; + top: .3em; + right: .3em; + width: 1.7em; + height: 1.7em; + opacity: 0; + transition: opacity 0.3s, border .3s, background-color .3s; + user-select: none; + padding: 0; + border: none; + outline: none; + border-radius: 0.4em; + /* The colors that GitHub uses */ + border: #1b1f2426 1px solid; + background-color: #f6f8fa; + color: #57606a; +} + +button.copybtn.success { + border-color: #22863a; + color: #22863a; +} + +button.copybtn svg { + stroke: currentColor; + width: 1.5em; + height: 1.5em; + padding: 0.1em; +} + +div.highlight { + position: relative; +} + +/* Show the copybutton */ +.highlight:hover button.copybtn, button.copybtn.success { + opacity: 1; +} + +.highlight button.copybtn:hover { + background-color: rgb(235, 235, 235); +} + +.highlight button.copybtn:active { + background-color: rgb(187, 187, 187); +} + +/** + * A minimal CSS-only tooltip copied from: + * https://codepen.io/mildrenben/pen/rVBrpK + * + * To use, write HTML like the following: + * + *

Short

+ */ + .o-tooltip--left { + position: relative; + } + + .o-tooltip--left:after { + opacity: 0; + visibility: hidden; + position: absolute; + content: attr(data-tooltip); + padding: .2em; + font-size: .8em; + left: -.2em; + background: grey; + color: white; + white-space: nowrap; + z-index: 2; + border-radius: 2px; + transform: translateX(-102%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); +} + +.o-tooltip--left:hover:after { + display: block; + opacity: 1; + visibility: visible; + transform: translateX(-100%) translateY(0); + transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); + transition-delay: .5s; +} + +/* By default the copy button shouldn't show up when printing a page */ +@media print { + button.copybtn { + display: none; + } +} diff --git a/_static/copybutton.js b/_static/copybutton.js new file mode 100644 index 000000000..1efcd51da --- /dev/null +++ b/_static/copybutton.js @@ -0,0 +1,248 @@ +// Localization support +const messages = { + 'en': { + 'copy': 'Copy', + 'copy_to_clipboard': 'Copy to clipboard', + 'copy_success': 'Copied!', + 'copy_failure': 'Failed to copy', + }, + 'es' : { + 'copy': 'Copiar', + 'copy_to_clipboard': 'Copiar al portapapeles', + 'copy_success': '¡Copiado!', + 'copy_failure': 'Error al copiar', + }, + 'de' : { + 'copy': 'Kopieren', + 'copy_to_clipboard': 'In die Zwischenablage kopieren', + 'copy_success': 'Kopiert!', + 'copy_failure': 'Fehler beim Kopieren', + }, + 'fr' : { + 'copy': 'Copier', + 'copy_to_clipboard': 'Copier dans le presse-papier', + 'copy_success': 'Copié !', + 'copy_failure': 'Échec de la copie', + }, + 'ru': { + 'copy': 'Скопировать', + 'copy_to_clipboard': 'Скопировать в буфер', + 'copy_success': 'Скопировано!', + 'copy_failure': 'Не удалось скопировать', + }, + 'zh-CN': { + 'copy': '复制', + 'copy_to_clipboard': '复制到剪贴板', + 'copy_success': '复制成功!', + 'copy_failure': '复制失败', + }, + 'it' : { + 'copy': 'Copiare', + 'copy_to_clipboard': 'Copiato negli appunti', + 'copy_success': 'Copiato!', + 'copy_failure': 'Errore durante la copia', + } +} + +let locale = 'en' +if( document.documentElement.lang !== undefined + && messages[document.documentElement.lang] !== undefined ) { + locale = document.documentElement.lang +} + +let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; +if (doc_url_root == '#') { + doc_url_root = ''; +} + +/** + * SVG files for our copy buttons + */ +let iconCheck = ` + ${messages[locale]['copy_success']} + + +` + +// If the user specified their own SVG use that, otherwise use the default +let iconCopy = ``; +if (!iconCopy) { + iconCopy = ` + ${messages[locale]['copy_to_clipboard']} + + + +` +} + +/** + * Set up copy/paste for code blocks + */ + +const runWhenDOMLoaded = cb => { + if (document.readyState != 'loading') { + cb() + } else if (document.addEventListener) { + document.addEventListener('DOMContentLoaded', cb) + } else { + document.attachEvent('onreadystatechange', function() { + if (document.readyState == 'complete') cb() + }) + } +} + +const codeCellId = index => `codecell${index}` + +// Clears selected text since ClipboardJS will select the text when copying +const clearSelection = () => { + if (window.getSelection) { + window.getSelection().removeAllRanges() + } else if (document.selection) { + document.selection.empty() + } +} + +// Changes tooltip text for a moment, then changes it back +// We want the timeout of our `success` class to be a bit shorter than the +// tooltip and icon change, so that we can hide the icon before changing back. +var timeoutIcon = 2000; +var timeoutSuccessClass = 1500; + +const temporarilyChangeTooltip = (el, oldText, newText) => { + el.setAttribute('data-tooltip', newText) + el.classList.add('success') + // Remove success a little bit sooner than we change the tooltip + // So that we can use CSS to hide the copybutton first + setTimeout(() => el.classList.remove('success'), timeoutSuccessClass) + setTimeout(() => el.setAttribute('data-tooltip', oldText), timeoutIcon) +} + +// Changes the copy button icon for two seconds, then changes it back +const temporarilyChangeIcon = (el) => { + el.innerHTML = iconCheck; + setTimeout(() => {el.innerHTML = iconCopy}, timeoutIcon) +} + +const addCopyButtonToCodeCells = () => { + // If ClipboardJS hasn't loaded, wait a bit and try again. This + // happens because we load ClipboardJS asynchronously. + if (window.ClipboardJS === undefined) { + setTimeout(addCopyButtonToCodeCells, 250) + return + } + + // Add copybuttons to all of our code cells + const COPYBUTTON_SELECTOR = 'div.highlight pre'; + const codeCells = document.querySelectorAll(COPYBUTTON_SELECTOR) + codeCells.forEach((codeCell, index) => { + const id = codeCellId(index) + codeCell.setAttribute('id', id) + + const clipboardButton = id => + `` + codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) + }) + +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} + + +var copyTargetText = (trigger) => { + var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); + + // get filtered text + let exclude = '.linenos'; + + let text = filterText(target, exclude); + return formatCopyText(text, '>>> |\\.\\.\\. |\\$ ', true, true, true, true, '', 'EOF') +} + + // Initialize with a callback so we can modify the text before copy + const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) + + // Update UI with error/success messages + clipboard.on('success', event => { + clearSelection() + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) + temporarilyChangeIcon(event.trigger) + }) + + clipboard.on('error', event => { + temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) + }) +} + +runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_static/copybutton_funcs.js b/_static/copybutton_funcs.js new file mode 100644 index 000000000..dbe1aaad7 --- /dev/null +++ b/_static/copybutton_funcs.js @@ -0,0 +1,73 @@ +function escapeRegExp(string) { + return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string +} + +/** + * Removes excluded text from a Node. + * + * @param {Node} target Node to filter. + * @param {string} exclude CSS selector of nodes to exclude. + * @returns {DOMString} Text from `target` with text removed. + */ +export function filterText(target, exclude) { + const clone = target.cloneNode(true); // clone as to not modify the live DOM + if (exclude) { + // remove excluded nodes + clone.querySelectorAll(exclude).forEach(node => node.remove()); + } + return clone.innerText; +} + +// Callback when a copy button is clicked. Will be passed the node that was clicked +// should then grab the text and replace pieces of text that shouldn't be used in output +export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { + var regexp; + var match; + + // Do we check for line continuation characters and "HERE-documents"? + var useLineCont = !!lineContinuationChar + var useHereDoc = !!hereDocDelim + + // create regexp to capture prompt and remaining line + if (isRegexp) { + regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') + } else { + regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') + } + + const outputLines = []; + var promptFound = false; + var gotLineCont = false; + var gotHereDoc = false; + const lineGotPrompt = []; + for (const line of textContent.split('\n')) { + match = line.match(regexp) + if (match || gotLineCont || gotHereDoc) { + promptFound = regexp.test(line) + lineGotPrompt.push(promptFound) + if (removePrompts && promptFound) { + outputLines.push(match[2]) + } else { + outputLines.push(line) + } + gotLineCont = line.endsWith(lineContinuationChar) & useLineCont + if (line.includes(hereDocDelim) & useHereDoc) + gotHereDoc = !gotHereDoc + } else if (!onlyCopyPromptLines) { + outputLines.push(line) + } else if (copyEmptyLines && line.trim() === '') { + outputLines.push(line) + } + } + + // If no lines with the prompt were found then just use original lines + if (lineGotPrompt.some(v => v === true)) { + textContent = outputLines.join('\n'); + } + + // Remove a trailing newline to avoid auto-running when pasting + if (textContent.endsWith("\n")) { + textContent = textContent.slice(0, -1) + } + return textContent +} diff --git a/_static/css/badge_only.css b/_static/css/badge_only.css new file mode 100644 index 000000000..88ba55b96 --- /dev/null +++ b/_static/css/badge_only.css @@ -0,0 +1 @@ +.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px} \ No newline at end of file diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff b/_static/css/fonts/Roboto-Slab-Bold.woff new file mode 100644 index 000000000..6cb600001 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Bold.woff2 b/_static/css/fonts/Roboto-Slab-Bold.woff2 new file mode 100644 index 000000000..7059e2314 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Bold.woff2 differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff b/_static/css/fonts/Roboto-Slab-Regular.woff new file mode 100644 index 000000000..f815f63f9 Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff differ diff --git a/_static/css/fonts/Roboto-Slab-Regular.woff2 b/_static/css/fonts/Roboto-Slab-Regular.woff2 new file mode 100644 index 000000000..f2c76e5bd Binary files /dev/null and b/_static/css/fonts/Roboto-Slab-Regular.woff2 differ diff --git a/_static/css/fonts/fontawesome-webfont.eot b/_static/css/fonts/fontawesome-webfont.eot new file mode 100644 index 000000000..e9f60ca95 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.eot differ diff --git a/_static/css/fonts/fontawesome-webfont.svg b/_static/css/fonts/fontawesome-webfont.svg new file mode 100644 index 000000000..855c845e5 --- /dev/null +++ b/_static/css/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/css/fonts/fontawesome-webfont.ttf b/_static/css/fonts/fontawesome-webfont.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.ttf differ diff --git a/_static/css/fonts/fontawesome-webfont.woff b/_static/css/fonts/fontawesome-webfont.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff differ diff --git a/_static/css/fonts/fontawesome-webfont.woff2 b/_static/css/fonts/fontawesome-webfont.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/_static/css/fonts/fontawesome-webfont.woff2 differ diff --git a/_static/css/fonts/lato-bold-italic.woff b/_static/css/fonts/lato-bold-italic.woff new file mode 100644 index 000000000..88ad05b9f Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff differ diff --git a/_static/css/fonts/lato-bold-italic.woff2 b/_static/css/fonts/lato-bold-italic.woff2 new file mode 100644 index 000000000..c4e3d804b Binary files /dev/null and b/_static/css/fonts/lato-bold-italic.woff2 differ diff --git a/_static/css/fonts/lato-bold.woff b/_static/css/fonts/lato-bold.woff new file mode 100644 index 000000000..c6dff51f0 Binary files /dev/null and b/_static/css/fonts/lato-bold.woff differ diff --git a/_static/css/fonts/lato-bold.woff2 b/_static/css/fonts/lato-bold.woff2 new file mode 100644 index 000000000..bb195043c Binary files /dev/null and b/_static/css/fonts/lato-bold.woff2 differ diff --git a/_static/css/fonts/lato-normal-italic.woff b/_static/css/fonts/lato-normal-italic.woff new file mode 100644 index 000000000..76114bc03 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff differ diff --git a/_static/css/fonts/lato-normal-italic.woff2 b/_static/css/fonts/lato-normal-italic.woff2 new file mode 100644 index 000000000..3404f37e2 Binary files /dev/null and b/_static/css/fonts/lato-normal-italic.woff2 differ diff --git a/_static/css/fonts/lato-normal.woff b/_static/css/fonts/lato-normal.woff new file mode 100644 index 000000000..ae1307ff5 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff differ diff --git a/_static/css/fonts/lato-normal.woff2 b/_static/css/fonts/lato-normal.woff2 new file mode 100644 index 000000000..3bf984332 Binary files /dev/null and b/_static/css/fonts/lato-normal.woff2 differ diff --git a/_static/css/theme.css b/_static/css/theme.css new file mode 100644 index 000000000..0f14f1064 --- /dev/null +++ b/_static/css/theme.css @@ -0,0 +1,4 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs>li{display:inline-block;padding-top:5px}.wy-breadcrumbs>li.wy-breadcrumbs-aside{float:right}.rst-content .wy-breadcrumbs>li code,.rst-content .wy-breadcrumbs>li tt,.wy-breadcrumbs>li .rst-content tt,.wy-breadcrumbs>li code{all:inherit;color:inherit}.breadcrumb-item:before{content:"/";color:#bbb;font-size:13px;padding:0 6px 0 3px}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search .wy-dropdown>aactive,.wy-side-nav-search .wy-dropdown>afocus,.wy-side-nav-search>a:hover,.wy-side-nav-search>aactive,.wy-side-nav-search>afocus{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon,.wy-side-nav-search>a.icon{display:block}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.switch-menus{position:relative;display:block;margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-side-nav-search>div.switch-menus>div.language-switch,.wy-side-nav-search>div.switch-menus>div.version-switch{display:inline-block;padding:.2em}.wy-side-nav-search>div.switch-menus>div.language-switch select,.wy-side-nav-search>div.switch-menus>div.version-switch select{display:inline-block;margin-right:-2rem;padding-right:2rem;max-width:240px;text-align-last:center;background:none;border:none;border-radius:0;box-shadow:none;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-size:1em;font-weight:400;color:hsla(0,0%,100%,.3);cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none}.wy-side-nav-search>div.switch-menus>div.language-switch select:active,.wy-side-nav-search>div.switch-menus>div.language-switch select:focus,.wy-side-nav-search>div.switch-menus>div.language-switch select:hover,.wy-side-nav-search>div.switch-menus>div.version-switch select:active,.wy-side-nav-search>div.switch-menus>div.version-switch select:focus,.wy-side-nav-search>div.switch-menus>div.version-switch select:hover{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.5)}.wy-side-nav-search>div.switch-menus>div.language-switch select option,.wy-side-nav-search>div.switch-menus>div.version-switch select option{color:#000}.wy-side-nav-search>div.switch-menus>div.language-switch:has(>select):after,.wy-side-nav-search>div.switch-menus>div.version-switch:has(>select):after{display:inline-block;width:1.5em;height:100%;padding:.1em;content:"\f0d7";font-size:1em;line-height:1.2em;font-family:FontAwesome;text-align:center;pointer-events:none;box-sizing:border-box}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions .rst-other-versions .rtd-current-item{font-weight:700}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}#flyout-search-form{padding:6px}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content p a{overflow-wrap:anywhere}.rst-content .wy-table td p,.rst-content .wy-table td ul,.rst-content .wy-table th p,.rst-content .wy-table th ul,.rst-content table.docutils td p,.rst-content table.docutils td ul,.rst-content table.docutils th p,.rst-content table.docutils th ul,.rst-content table.field-list td p,.rst-content table.field-list td ul,.rst-content table.field-list th p,.rst-content table.field-list th ul{font-size:inherit}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .citation-reference>span.fn-bracket,.rst-content .footnote-reference>span.fn-bracket{display:none}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:auto minmax(80%,95%)}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{display:inline-grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{display:grid;grid-template-columns:auto auto minmax(.65rem,auto) minmax(40%,95%)}html.writer-html5 .rst-content aside.citation>span.label,html.writer-html5 .rst-content aside.footnote>span.label,html.writer-html5 .rst-content div.citation>span.label{grid-column-start:1;grid-column-end:2}html.writer-html5 .rst-content aside.citation>span.backrefs,html.writer-html5 .rst-content aside.footnote>span.backrefs,html.writer-html5 .rst-content div.citation>span.backrefs{grid-column-start:2;grid-column-end:3;grid-row-start:1;grid-row-end:3}html.writer-html5 .rst-content aside.citation>p,html.writer-html5 .rst-content aside.footnote>p,html.writer-html5 .rst-content div.citation>p{grid-column-start:4;grid-column-end:5}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{margin-bottom:24px}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.citation>dt,html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.citation>dt>span.brackets:before,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.citation>dt>span.brackets:after,html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a{word-break:keep-all}html.writer-html5 .rst-content dl.citation>dt>span.fn-backref>a:not(:first-child):before,html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content dl.citation>dd,html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.citation>dd p,html.writer-html5 .rst-content dl.footnote>dd p{font-size:.9rem}html.writer-html5 .rst-content aside.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content div.citation{padding-left:1rem;padding-right:1rem;font-size:.9rem;line-height:1.2rem}html.writer-html5 .rst-content aside.citation p,html.writer-html5 .rst-content aside.footnote p,html.writer-html5 .rst-content div.citation p{font-size:.9rem;line-height:1.2rem;margin-bottom:12px}html.writer-html5 .rst-content aside.citation span.backrefs,html.writer-html5 .rst-content aside.footnote span.backrefs,html.writer-html5 .rst-content div.citation span.backrefs{text-align:left;font-style:italic;margin-left:.65rem;word-break:break-word;word-spacing:-.1rem;max-width:5rem}html.writer-html5 .rst-content aside.citation span.backrefs>a,html.writer-html5 .rst-content aside.footnote span.backrefs>a,html.writer-html5 .rst-content div.citation span.backrefs>a{word-break:keep-all}html.writer-html5 .rst-content aside.citation span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content aside.footnote span.backrefs>a:not(:first-child):before,html.writer-html5 .rst-content div.citation span.backrefs>a:not(:first-child):before{content:" "}html.writer-html5 .rst-content aside.citation span.label,html.writer-html5 .rst-content aside.footnote span.label,html.writer-html5 .rst-content div.citation span.label{line-height:1.2rem}html.writer-html5 .rst-content aside.citation-list,html.writer-html5 .rst-content aside.footnote-list,html.writer-html5 .rst-content div.citation-list{margin-bottom:24px}html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content aside.footnote,html.writer-html5 .rst-content aside.footnote-list aside.footnote,html.writer-html5 .rst-content div.citation-list>div.citation,html.writer-html5 .rst-content dl.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content aside.footnote-list aside.footnote code,html.writer-html5 .rst-content aside.footnote-list aside.footnote tt,html.writer-html5 .rst-content aside.footnote code,html.writer-html5 .rst-content aside.footnote tt,html.writer-html5 .rst-content div.citation-list>div.citation code,html.writer-html5 .rst-content div.citation-list>div.citation tt,html.writer-html5 .rst-content dl.citation code,html.writer-html5 .rst-content dl.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040;overflow-wrap:normal}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}.rst-content dl dd>ol:last-child,.rst-content dl dd>p:last-child,.rst-content dl dd>table:last-child,.rst-content dl dd>ul:last-child{margin-bottom:0}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) dl:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.citation):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel,.rst-content .menuselection{font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .guilabel,.rst-content .menuselection{border:1px solid #7fbbe3;background:#e7f2fa}.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>.kbd,.rst-content :not(dl.option-list)>:not(dt):not(kbd):not(.kbd)>kbd{color:inherit;font-size:80%;background-color:#fff;border:1px solid #a6a6a6;border-radius:4px;box-shadow:0 2px grey;padding:2.4px 6px;margin:auto 0}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 000000000..0398ebb9f --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,149 @@ +/* + * Base JavaScript utilities for all Sphinx HTML documentation. + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 000000000..4940b0c5d --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '0.7.23', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/_static/file.png differ diff --git a/_static/fonts/Lato/lato-bold.eot b/_static/fonts/Lato/lato-bold.eot new file mode 100644 index 000000000..3361183a4 Binary files /dev/null and b/_static/fonts/Lato/lato-bold.eot differ diff --git a/_static/fonts/Lato/lato-bold.ttf b/_static/fonts/Lato/lato-bold.ttf new file mode 100644 index 000000000..29f691d5e Binary files /dev/null and b/_static/fonts/Lato/lato-bold.ttf differ diff --git a/_static/fonts/Lato/lato-bold.woff b/_static/fonts/Lato/lato-bold.woff new file mode 100644 index 000000000..c6dff51f0 Binary files /dev/null and b/_static/fonts/Lato/lato-bold.woff differ diff --git a/_static/fonts/Lato/lato-bold.woff2 b/_static/fonts/Lato/lato-bold.woff2 new file mode 100644 index 000000000..bb195043c Binary files /dev/null and b/_static/fonts/Lato/lato-bold.woff2 differ diff --git a/_static/fonts/Lato/lato-bolditalic.eot b/_static/fonts/Lato/lato-bolditalic.eot new file mode 100644 index 000000000..3d4154936 Binary files /dev/null and b/_static/fonts/Lato/lato-bolditalic.eot differ diff --git a/_static/fonts/Lato/lato-bolditalic.ttf b/_static/fonts/Lato/lato-bolditalic.ttf new file mode 100644 index 000000000..f402040b3 Binary files /dev/null and b/_static/fonts/Lato/lato-bolditalic.ttf differ diff --git a/_static/fonts/Lato/lato-bolditalic.woff b/_static/fonts/Lato/lato-bolditalic.woff new file mode 100644 index 000000000..88ad05b9f Binary files /dev/null and b/_static/fonts/Lato/lato-bolditalic.woff differ diff --git a/_static/fonts/Lato/lato-bolditalic.woff2 b/_static/fonts/Lato/lato-bolditalic.woff2 new file mode 100644 index 000000000..c4e3d804b Binary files /dev/null and b/_static/fonts/Lato/lato-bolditalic.woff2 differ diff --git a/_static/fonts/Lato/lato-italic.eot b/_static/fonts/Lato/lato-italic.eot new file mode 100644 index 000000000..3f826421a Binary files /dev/null and b/_static/fonts/Lato/lato-italic.eot differ diff --git a/_static/fonts/Lato/lato-italic.ttf b/_static/fonts/Lato/lato-italic.ttf new file mode 100644 index 000000000..b4bfc9b24 Binary files /dev/null and b/_static/fonts/Lato/lato-italic.ttf differ diff --git a/_static/fonts/Lato/lato-italic.woff b/_static/fonts/Lato/lato-italic.woff new file mode 100644 index 000000000..76114bc03 Binary files /dev/null and b/_static/fonts/Lato/lato-italic.woff differ diff --git a/_static/fonts/Lato/lato-italic.woff2 b/_static/fonts/Lato/lato-italic.woff2 new file mode 100644 index 000000000..3404f37e2 Binary files /dev/null and b/_static/fonts/Lato/lato-italic.woff2 differ diff --git a/_static/fonts/Lato/lato-regular.eot b/_static/fonts/Lato/lato-regular.eot new file mode 100644 index 000000000..11e3f2a5f Binary files /dev/null and b/_static/fonts/Lato/lato-regular.eot differ diff --git a/_static/fonts/Lato/lato-regular.ttf b/_static/fonts/Lato/lato-regular.ttf new file mode 100644 index 000000000..74decd9eb Binary files /dev/null and b/_static/fonts/Lato/lato-regular.ttf differ diff --git a/_static/fonts/Lato/lato-regular.woff b/_static/fonts/Lato/lato-regular.woff new file mode 100644 index 000000000..ae1307ff5 Binary files /dev/null and b/_static/fonts/Lato/lato-regular.woff differ diff --git a/_static/fonts/Lato/lato-regular.woff2 b/_static/fonts/Lato/lato-regular.woff2 new file mode 100644 index 000000000..3bf984332 Binary files /dev/null and b/_static/fonts/Lato/lato-regular.woff2 differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot new file mode 100644 index 000000000..79dc8efed Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf new file mode 100644 index 000000000..df5d1df27 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff new file mode 100644 index 000000000..6cb600001 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 new file mode 100644 index 000000000..7059e2314 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot new file mode 100644 index 000000000..2f7ca78a1 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf new file mode 100644 index 000000000..eb52a7907 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff new file mode 100644 index 000000000..f815f63f9 Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff differ diff --git a/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 new file mode 100644 index 000000000..f2c76e5bd Binary files /dev/null and b/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 differ diff --git a/_static/graphviz.css b/_static/graphviz.css new file mode 100644 index 000000000..30f3837b6 --- /dev/null +++ b/_static/graphviz.css @@ -0,0 +1,12 @@ +/* + * Sphinx stylesheet -- graphviz extension. + */ + +img.graphviz { + border: 0; + max-width: 100%; +} + +object.graphviz { + max-width: 100%; +} diff --git a/_static/jquery.js b/_static/jquery.js new file mode 100644 index 000000000..c4c6022f2 --- /dev/null +++ b/_static/jquery.js @@ -0,0 +1,2 @@ +/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",y.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="
",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0"),n("table.docutils.footnote").wrap("
"),n("table.docutils.citation").wrap("
"),n(".wy-menu-vertical ul").not(".simple").siblings("a").each((function(){var t=n(this);expand=n(''),expand.on("click",(function(n){return e.toggleCurrent(t),n.stopPropagation(),!1})),t.prepend(expand)}))},reset:function(){var n=encodeURI(window.location.hash)||"#";try{var e=$(".wy-menu-vertical"),t=e.find('[href="'+n+'"]');if(0===t.length){var i=$('.document [id="'+n.substring(1)+'"]').closest("div.section");0===(t=e.find('[href="#'+i.attr("id")+'"]')).length&&(t=e.find('[href="#"]'))}if(t.length>0){$(".wy-menu-vertical .current").removeClass("current").attr("aria-expanded","false"),t.addClass("current").attr("aria-expanded","true"),t.closest("li.toctree-l1").parent().addClass("current").attr("aria-expanded","true");for(let n=1;n<=10;n++)t.closest("li.toctree-l"+n).addClass("current").attr("aria-expanded","true");t[0].scrollIntoView()}}catch(n){console.log("Error expanding nav for anchor",n)}},onScroll:function(){this.winScroll=!1;var n=this.win.scrollTop(),e=n+this.winHeight,t=this.navBar.scrollTop()+(n-this.winPosition);n<0||e>this.docHeight||(this.navBar.scrollTop(t),this.winPosition=n)},onResize:function(){this.winResize=!1,this.winHeight=this.win.height(),this.docHeight=$(document).height()},hashChange:function(){this.linkScroll=!0,this.win.one("hashchange",(function(){this.linkScroll=!1}))},toggleCurrent:function(n){var e=n.closest("li");e.siblings("li.current").removeClass("current").attr("aria-expanded","false"),e.siblings().find("li.current").removeClass("current").attr("aria-expanded","false");var t=e.find("> ul li");t.length&&(t.removeClass("current").attr("aria-expanded","false"),e.toggleClass("current").attr("aria-expanded",(function(n,e){return"true"==e?"false":"true"})))}},"undefined"!=typeof window&&(window.SphinxRtdTheme={Navigation:n.exports.ThemeNav,StickyNav:n.exports.ThemeNav}),function(){for(var n=0,e=["ms","moz","webkit","o"],t=0;t a.language.name.localeCompare(b.language.name)); + + const languagesHTML = ` +
+
Languages
+ ${languages + .map( + (translation) => ` +
+ ${translation.language.code} +
+ `, + ) + .join("\n")} +
+ `; + return languagesHTML; + } + + function renderVersions(config) { + if (!config.versions.active.length) { + return ""; + } + const versionsHTML = ` +
+
Versions
+ ${config.versions.active + .map( + (version) => ` +
+ ${version.slug} +
+ `, + ) + .join("\n")} +
+ `; + return versionsHTML; + } + + function renderDownloads(config) { + if (!Object.keys(config.versions.current.downloads).length) { + return ""; + } + const downloadsNameDisplay = { + pdf: "PDF", + epub: "Epub", + htmlzip: "HTML", + }; + + const downloadsHTML = ` +
+
Downloads
+ ${Object.entries(config.versions.current.downloads) + .map( + ([name, url]) => ` +
+ ${downloadsNameDisplay[name]} +
+ `, + ) + .join("\n")} +
+ `; + return downloadsHTML; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const flyout = ` +
+ + Read the Docs + v: ${config.versions.current.slug} + + +
+
+ ${renderLanguages(config)} + ${renderVersions(config)} + ${renderDownloads(config)} +
+
On Read the Docs
+
+ Project Home +
+
+ Builds +
+
+ Downloads +
+
+
+
Search
+
+
+ +
+
+
+
+ + Hosted by Read the Docs + +
+
+ `; + + // Inject the generated flyout into the body HTML element. + document.body.insertAdjacentHTML("beforeend", flyout); + + // Trigger the Read the Docs Addons Search modal when clicking on the "Search docs" input from inside the flyout. + document + .querySelector("#flyout-search-form") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); + }) +} + +if (themeLanguageSelector || themeVersionSelector) { + function onSelectorSwitch(event) { + const option = event.target.selectedIndex; + const item = event.target.options[option]; + window.location.href = item.dataset.url; + } + + document.addEventListener("readthedocs-addons-data-ready", function (event) { + const config = event.detail.data(); + + const versionSwitch = document.querySelector( + "div.switch-menus > div.version-switch", + ); + if (themeVersionSelector) { + let versions = config.versions.active; + if (config.versions.current.hidden || config.versions.current.type === "external") { + versions.unshift(config.versions.current); + } + const versionSelect = ` + + `; + + versionSwitch.innerHTML = versionSelect; + versionSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + + const languageSwitch = document.querySelector( + "div.switch-menus > div.language-switch", + ); + + if (themeLanguageSelector) { + if (config.projects.translations.length) { + // Add the current language to the options on the selector + let languages = config.projects.translations.concat( + config.projects.current, + ); + languages = languages.sort((a, b) => + a.language.name.localeCompare(b.language.name), + ); + + const languageSelect = ` + + `; + + languageSwitch.innerHTML = languageSelect; + languageSwitch.firstElementChild.addEventListener("change", onSelectorSwitch); + } + else { + languageSwitch.remove(); + } + } + }); +} + +document.addEventListener("readthedocs-addons-data-ready", function (event) { + // Trigger the Read the Docs Addons Search modal when clicking on "Search docs" input from the topnav. + document + .querySelector("[role='search'] input") + .addEventListener("focusin", () => { + const event = new CustomEvent("readthedocs-search-show"); + document.dispatchEvent(event); + }); +}); \ No newline at end of file diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 000000000..c7fe6c6fa --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,192 @@ +/* + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 000000000..d96755fda Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/nbsphinx-broken-thumbnail.svg b/_static/nbsphinx-broken-thumbnail.svg new file mode 100644 index 000000000..4919ca882 --- /dev/null +++ b/_static/nbsphinx-broken-thumbnail.svg @@ -0,0 +1,9 @@ + + + + diff --git a/_static/nbsphinx-code-cells.css b/_static/nbsphinx-code-cells.css new file mode 100644 index 000000000..a3fb27c30 --- /dev/null +++ b/_static/nbsphinx-code-cells.css @@ -0,0 +1,259 @@ +/* remove conflicting styling from Sphinx themes */ +div.nbinput.container div.prompt *, +div.nboutput.container div.prompt *, +div.nbinput.container div.input_area pre, +div.nboutput.container div.output_area pre, +div.nbinput.container div.input_area .highlight, +div.nboutput.container div.output_area .highlight { + border: none; + padding: 0; + margin: 0; + box-shadow: none; +} + +div.nbinput.container > div[class*=highlight], +div.nboutput.container > div[class*=highlight] { + margin: 0; +} + +div.nbinput.container div.prompt *, +div.nboutput.container div.prompt * { + background: none; +} + +div.nboutput.container div.output_area .highlight, +div.nboutput.container div.output_area pre { + background: unset; +} + +div.nboutput.container div.output_area div.highlight { + color: unset; /* override Pygments text color */ +} + +/* avoid gaps between output lines */ +div.nboutput.container div[class*=highlight] pre { + line-height: normal; +} + +/* input/output containers */ +div.nbinput.container, +div.nboutput.container { + display: -webkit-flex; + display: flex; + align-items: flex-start; + margin: 0; + width: 100%; +} +@media (max-width: 540px) { + div.nbinput.container, + div.nboutput.container { + flex-direction: column; + } +} + +/* input container */ +div.nbinput.container { + padding-top: 5px; +} + +/* last container */ +div.nblast.container { + padding-bottom: 5px; +} + +/* input prompt */ +div.nbinput.container div.prompt pre, +/* for sphinx_immaterial theme: */ +div.nbinput.container div.prompt pre > code { + color: #307FC1; +} + +/* output prompt */ +div.nboutput.container div.prompt pre, +/* for sphinx_immaterial theme: */ +div.nboutput.container div.prompt pre > code { + color: #BF5B3D; +} + +/* all prompts */ +div.nbinput.container div.prompt, +div.nboutput.container div.prompt { + width: 4.5ex; + padding-top: 5px; + position: relative; + user-select: none; +} + +div.nbinput.container div.prompt > div, +div.nboutput.container div.prompt > div { + position: absolute; + right: 0; + margin-right: 0.3ex; +} + +@media (max-width: 540px) { + div.nbinput.container div.prompt, + div.nboutput.container div.prompt { + width: unset; + text-align: left; + padding: 0.4em; + } + div.nboutput.container div.prompt.empty { + padding: 0; + } + + div.nbinput.container div.prompt > div, + div.nboutput.container div.prompt > div { + position: unset; + } +} + +/* disable scrollbars and line breaks on prompts */ +div.nbinput.container div.prompt pre, +div.nboutput.container div.prompt pre { + overflow: hidden; + white-space: pre; +} + +/* input/output area */ +div.nbinput.container div.input_area, +div.nboutput.container div.output_area { + -webkit-flex: 1; + flex: 1; + overflow: auto; +} +@media (max-width: 540px) { + div.nbinput.container div.input_area, + div.nboutput.container div.output_area { + width: 100%; + } +} + +/* input area */ +div.nbinput.container div.input_area { + border: 1px solid #e0e0e0; + border-radius: 2px; + /*background: #f5f5f5;*/ +} + +/* override MathJax center alignment in output cells */ +div.nboutput.container div[class*=MathJax] { + text-align: left !important; +} + +/* override sphinx.ext.imgmath center alignment in output cells */ +div.nboutput.container div.math p { + text-align: left; +} + +/* standard error */ +div.nboutput.container div.output_area.stderr { + background: #fdd; +} + +/* ANSI colors */ +.ansi-black-fg { color: #3E424D; } +.ansi-black-bg { background-color: #3E424D; } +.ansi-black-intense-fg { color: #282C36; } +.ansi-black-intense-bg { background-color: #282C36; } +.ansi-red-fg { color: #E75C58; } +.ansi-red-bg { background-color: #E75C58; } +.ansi-red-intense-fg { color: #B22B31; } +.ansi-red-intense-bg { background-color: #B22B31; } +.ansi-green-fg { color: #00A250; } +.ansi-green-bg { background-color: #00A250; } +.ansi-green-intense-fg { color: #007427; } +.ansi-green-intense-bg { background-color: #007427; } +.ansi-yellow-fg { color: #DDB62B; } +.ansi-yellow-bg { background-color: #DDB62B; } +.ansi-yellow-intense-fg { color: #B27D12; } +.ansi-yellow-intense-bg { background-color: #B27D12; } +.ansi-blue-fg { color: #208FFB; } +.ansi-blue-bg { background-color: #208FFB; } +.ansi-blue-intense-fg { color: #0065CA; } +.ansi-blue-intense-bg { background-color: #0065CA; } +.ansi-magenta-fg { color: #D160C4; } +.ansi-magenta-bg { background-color: #D160C4; } +.ansi-magenta-intense-fg { color: #A03196; } +.ansi-magenta-intense-bg { background-color: #A03196; } +.ansi-cyan-fg { color: #60C6C8; } +.ansi-cyan-bg { background-color: #60C6C8; } +.ansi-cyan-intense-fg { color: #258F8F; } +.ansi-cyan-intense-bg { background-color: #258F8F; } +.ansi-white-fg { color: #C5C1B4; } +.ansi-white-bg { background-color: #C5C1B4; } +.ansi-white-intense-fg { color: #A1A6B2; } +.ansi-white-intense-bg { background-color: #A1A6B2; } + +.ansi-default-inverse-fg { color: #FFFFFF; } +.ansi-default-inverse-bg { background-color: #000000; } + +.ansi-bold { font-weight: bold; } +.ansi-underline { text-decoration: underline; } + + +div.nbinput.container div.input_area div[class*=highlight] > pre, +div.nboutput.container div.output_area div[class*=highlight] > pre, +div.nboutput.container div.output_area div[class*=highlight].math, +div.nboutput.container div.output_area.rendered_html, +div.nboutput.container div.output_area > div.output_javascript, +div.nboutput.container div.output_area:not(.rendered_html) > img{ + padding: 5px; + margin: 0; +} + +/* fix copybtn overflow problem in chromium (needed for 'sphinx_copybutton') */ +div.nbinput.container div.input_area > div[class^='highlight'], +div.nboutput.container div.output_area > div[class^='highlight']{ + overflow-y: hidden; +} + +/* hide copy button on prompts for 'sphinx_copybutton' extension ... */ +.prompt .copybtn, +/* ... and 'sphinx_immaterial' theme */ +.prompt .md-clipboard.md-icon { + display: none; +} + +/* Some additional styling taken form the Jupyter notebook CSS */ +.jp-RenderedHTMLCommon table, +div.rendered_html table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 12px; + table-layout: fixed; +} +.jp-RenderedHTMLCommon thead, +div.rendered_html thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} +.jp-RenderedHTMLCommon tr, +.jp-RenderedHTMLCommon th, +.jp-RenderedHTMLCommon td, +div.rendered_html tr, +div.rendered_html th, +div.rendered_html td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} +.jp-RenderedHTMLCommon th, +div.rendered_html th { + font-weight: bold; +} +.jp-RenderedHTMLCommon tbody tr:nth-child(odd), +div.rendered_html tbody tr:nth-child(odd) { + background: #f5f5f5; +} +.jp-RenderedHTMLCommon tbody tr:hover, +div.rendered_html tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + diff --git a/_static/nbsphinx-gallery.css b/_static/nbsphinx-gallery.css new file mode 100644 index 000000000..365c27a96 --- /dev/null +++ b/_static/nbsphinx-gallery.css @@ -0,0 +1,31 @@ +.nbsphinx-gallery { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + gap: 5px; + margin-top: 1em; + margin-bottom: 1em; +} + +.nbsphinx-gallery > a { + padding: 5px; + border: 1px dotted currentColor; + border-radius: 2px; + text-align: center; +} + +.nbsphinx-gallery > a:hover { + border-style: solid; +} + +.nbsphinx-gallery img { + max-width: 100%; + max-height: 100%; +} + +.nbsphinx-gallery > a > div:first-child { + display: flex; + align-items: start; + justify-content: center; + height: 120px; + margin-bottom: 5px; +} diff --git a/_static/nbsphinx-no-thumbnail.svg b/_static/nbsphinx-no-thumbnail.svg new file mode 100644 index 000000000..9dca7588f --- /dev/null +++ b/_static/nbsphinx-no-thumbnail.svg @@ -0,0 +1,9 @@ + + + + diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 000000000..7107cec93 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 000000000..0d49244ed --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,75 @@ +pre { line-height: 125%; } +td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #eeffcc; } +.highlight .c { color: #408090; font-style: italic } /* Comment */ +.highlight .err { border: 1px solid #FF0000 } /* Error */ +.highlight .k { color: #007020; font-weight: bold } /* Keyword */ +.highlight .o { color: #666666 } /* Operator */ +.highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #007020 } /* Comment.Preproc */ +.highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */ +.highlight .gd { color: #A00000 } /* Generic.Deleted */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +.highlight .gr { color: #FF0000 } /* Generic.Error */ +.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +.highlight .gi { color: #00A000 } /* Generic.Inserted */ +.highlight .go { color: #333333 } /* Generic.Output */ +.highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #0044DD } /* Generic.Traceback */ +.highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #007020 } /* Keyword.Pseudo */ +.highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #902000 } /* Keyword.Type */ +.highlight .m { color: #208050 } /* Literal.Number */ +.highlight .s { color: #4070a0 } /* Literal.String */ +.highlight .na { color: #4070a0 } /* Name.Attribute */ +.highlight .nb { color: #007020 } /* Name.Builtin */ +.highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */ +.highlight .no { color: #60add5 } /* Name.Constant */ +.highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */ +.highlight .ne { color: #007020 } /* Name.Exception */ +.highlight .nf { color: #06287e } /* Name.Function */ +.highlight .nl { color: #002070; font-weight: bold } /* Name.Label */ +.highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */ +.highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #bb60d5 } /* Name.Variable */ +.highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mb { color: #208050 } /* Literal.Number.Bin */ +.highlight .mf { color: #208050 } /* Literal.Number.Float */ +.highlight .mh { color: #208050 } /* Literal.Number.Hex */ +.highlight .mi { color: #208050 } /* Literal.Number.Integer */ +.highlight .mo { color: #208050 } /* Literal.Number.Oct */ +.highlight .sa { color: #4070a0 } /* Literal.String.Affix */ +.highlight .sb { color: #4070a0 } /* Literal.String.Backtick */ +.highlight .sc { color: #4070a0 } /* Literal.String.Char */ +.highlight .dl { color: #4070a0 } /* Literal.String.Delimiter */ +.highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4070a0 } /* Literal.String.Double */ +.highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */ +.highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */ +.highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */ +.highlight .sx { color: #c65d09 } /* Literal.String.Other */ +.highlight .sr { color: #235388 } /* Literal.String.Regex */ +.highlight .s1 { color: #4070a0 } /* Literal.String.Single */ +.highlight .ss { color: #517918 } /* Literal.String.Symbol */ +.highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #06287e } /* Name.Function.Magic */ +.highlight .vc { color: #bb60d5 } /* Name.Variable.Class */ +.highlight .vg { color: #bb60d5 } /* Name.Variable.Global */ +.highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */ +.highlight .vm { color: #bb60d5 } /* Name.Variable.Magic */ +.highlight .il { color: #208050 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 000000000..2c774d17a --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,632 @@ +/* + * Sphinx JavaScript utilities for the full-text search. + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename, kind] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; + const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; + const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; + + const [docName, title, anchor, descr, score, _filename, kind] = item; + + let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + requestUrl = contentRoot + docName + docFileSuffix; + linkUrl = docName + docLinkSuffix; + } + let linkEl = listItem.appendChild(document.createElement("a")); + linkEl.href = linkUrl + anchor; + linkEl.dataset.score = score; + linkEl.innerHTML = title; + if (descr) { + listItem.appendChild(document.createElement("span")).innerHTML = + " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } + else if (showSearchSummary) + fetch(requestUrl) + .then((responseData) => responseData.text()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + }); + Search.output.appendChild(listItem); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + searchTerms, + highlightTerms, +) => { + // results left, load the summary and display it + // this is intended to be dynamic (don't sub resultsCount) + if (results.length) { + _displayItem(results.pop(), searchTerms, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + SearchResultKind.title, + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + SearchResultKind.object, + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + SearchResultKind.text, + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 000000000..8a96c69a1 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + rest, + node.nextSibling + ) + ); + node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); + + if (isInSVG) { + const rect = document.createElementNS( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/api/coffea.analysis_tools.PackedSelection.html b/api/coffea.analysis_tools.PackedSelection.html new file mode 100644 index 000000000..e5542642f --- /dev/null +++ b/api/coffea.analysis_tools.PackedSelection.html @@ -0,0 +1,276 @@ + + + + + + + + + PackedSelection — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

PackedSelection

+
+
+class coffea.analysis_tools.PackedSelection(dtype='uint32')[source]
+

Bases: object

+

Store several boolean arrays in a compact manner

+

This class can store several boolean arrays in a memory-efficient mannner +and evaluate arbitrary combinations of boolean requirements in an CPU-efficient way. +Supported inputs are 1D numpy or awkward arrays.

+
+
Parameters:
+

dtype (numpy.dtype or str) – internal bitwidth of the packed array, which governs the maximum +number of selections storable in this object. The default value +is uint32, which allows up to 32 booleans to be stored, but +if a smaller or larger number of selections needs to be stored, +one can choose uint16 or uint64 instead.

+
+
+

Attributes Summary

+ + + + + + + + + +

maxitems

names

Current list of mask names available

+

Methods Summary

+ + + + + + + + + + + + + + + +

add(name, selection[, fill_value])

Add a new boolean array

all(*names)

Shorthand for require, where all the values are True

any(*names)

Return a mask vector corresponding to an inclusive OR of requirements

require(**names)

Return a mask vector corresponding to specific requirements

+

Attributes Documentation

+
+
+maxitems
+
+ +
+
+names
+

Current list of mask names available

+
+ +

Methods Documentation

+
+
+add(name, selection, fill_value=False)[source]
+

Add a new boolean array

+
+
Parameters:
+
    +
  • name (str) – name of the selection

  • +
  • selection (numpy.ndarray or awkward.Array) – a flat array of type bool or ?bool. +If this is not the first selection added, it must also have +the same shape as previously added selections. If the array +is option-type, null entries will be filled with fill_value.

  • +
  • fill_value (bool, optional) – All masked entries will be filled as specified (default: False)

  • +
+
+
+
+ +
+
+all(*names)[source]
+

Shorthand for require, where all the values are True

+
+ +
+
+any(*names)[source]
+

Return a mask vector corresponding to an inclusive OR of requirements

+
+
Parameters:
+

*names (args) – The named selections to allow

+
+
+

Examples

+

If

+
>>> selection.names
+['cut1', 'cut2', 'cut3']
+
+
+

then

+
>>> selection.any("cut1", "cut2")
+array([True, False, True, ...])
+
+
+

returns a boolean array where an entry is True if the corresponding entries +cut1 == True or cut2 == False, and cut3 arbitrary.

+
+ +
+
+require(**names)[source]
+

Return a mask vector corresponding to specific requirements

+

Specify an exact requirement on an arbitrary subset of the masks

+
+
Parameters:
+

**names (kwargs) – Each argument to require specific value for, in form arg=True +or arg=False.

+
+
+

Examples

+

If

+
>>> selection.names
+['cut1', 'cut2', 'cut3']
+
+
+

then

+
>>> selection.require(cut1=True, cut2=False)
+array([True, False, True, ...])
+
+
+

returns a boolean array where an entry is True if the corresponding entries +cut1 == True, cut2 == False, and cut3 arbitrary.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.analysis_tools.WeightStatistics.html b/api/coffea.analysis_tools.WeightStatistics.html new file mode 100644 index 000000000..d641a0c99 --- /dev/null +++ b/api/coffea.analysis_tools.WeightStatistics.html @@ -0,0 +1,174 @@ + + + + + + + + + WeightStatistics — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

WeightStatistics

+
+
+class coffea.analysis_tools.WeightStatistics(sumw=0.0, sumw2=0.0, minw=inf, maxw=-inf, n=0)[source]
+

Bases: AccumulatorABC

+

Methods Summary

+ + + + + + + + + +

add(other)

Add another accumulator to this one in-place

identity()

Identity of the accumulator

+

Methods Documentation

+
+
+add(other)[source]
+

Add another accumulator to this one in-place

+
+ +
+
+identity()[source]
+

Identity of the accumulator

+

A value such that any other value added to it will return +the other value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.analysis_tools.Weights.html b/api/coffea.analysis_tools.Weights.html new file mode 100644 index 000000000..9315f0e08 --- /dev/null +++ b/api/coffea.analysis_tools.Weights.html @@ -0,0 +1,299 @@ + + + + + + + + + Weights — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Weights

+
+
+class coffea.analysis_tools.Weights(size, storeIndividual=False)[source]
+

Bases: object

+

Container for event weights and associated systematic shifts

+

This container keeps track of correction factors and systematic +effects that can be encoded as multiplicative modifiers to the event weight. +All weights are stored in vector form.

+
+
Parameters:
+
    +
  • size (int) – size of the weight arrays to be handled (i.e. the number of events / instances).

  • +
  • storeIndividual (bool, optional) – store not only the total weight + variations, but also each individual weight. +Default is false.

  • +
+
+
+

Attributes Summary

+ + + + + + + + + +

variations

List of available modifiers

weightStatistics

+

Methods Summary

+ + + + + + + + + + + + + + + +

add(name, weight[, weightUp, weightDown, shift])

Add a new weight

add_multivariation(name, weight, ...[, shift])

Add a new weight with multiple variations

partial_weight([include, exclude])

Partial event weight vector

weight([modifier])

Current event weight vector

+

Attributes Documentation

+
+
+variations
+

List of available modifiers

+
+ +
+
+weightStatistics
+
+ +

Methods Documentation

+
+
+add(name, weight, weightUp=None, weightDown=None, shift=False)[source]
+

Add a new weight

+

Adds a named correction to the event weight, and optionally also associated +systematic uncertainties.

+
+
Parameters:
+
    +
  • name (str) – name of correction

  • +
  • weight (numpy.ndarray) – the nominal event weight associated with the correction

  • +
  • weightUp (numpy.ndarray, optional) – weight with correction uncertainty shifted up (if available)

  • +
  • weightDown (numpy.ndarray, optional) – weight with correction uncertainty shifted down. If weightUp is supplied, and +the correction uncertainty is symmetric, this can be set to None to auto-calculate +the down shift as 1 / weightUp.

  • +
  • shift (bool, optional) – if True, interpret weightUp and weightDown as a realtive difference (additive) to the +nominal value

  • +
+
+
+
+

Note

+

weightUp and weightDown are assumed to be rvalue-like and may be modified in-place by this function

+
+
+ +
+
+add_multivariation(name, weight, modifierNames, weightsUp, weightsDown, shift=False)[source]
+

Add a new weight with multiple variations

+

Each variation of a single weight is given a different modifier name. +This is particularly useful e.g. for btag SF variations.

+
+
Parameters:
+
    +
  • name (str) – name of correction

  • +
  • weight (numpy.ndarray) – the nominal event weight associated with the correction

  • +
  • modifierNames (list of str) – list of modifiers for each set of weights variation

  • +
  • weightsUp (list of numpy.ndarray) – weight with correction uncertainty shifted up (if available)

  • +
  • weightsDown (list of numpy.ndarray) – weight with correction uncertainty shifted down. If weightUp is supplied, and +the correction uncertainty is symmetric, this can be set to None to auto-calculate +the down shift as 1 / weightUp.

  • +
  • shift (bool, optional) – if True, interpret weightUp and weightDown as a realtive difference (additive) to the +nominal value

  • +
+
+
+
+

Note

+

weightUp and weightDown are assumed to be rvalue-like and may be modified in-place by this function

+
+
+ +
+
+partial_weight(include=[], exclude=[])[source]
+

Partial event weight vector

+

Return a partial weight by multiplying a subset of all weights. +Can be operated either by specifying weights to include or +weights to exclude, but not both at the same time. The method +can only be used if the individual weights are stored via the +storeIndividual argument in the Weights initializer.

+
+
Parameters:
+
    +
  • include (list) – Weight names to include, defaults to []

  • +
  • exclude (list) – Weight names to exclude, defaults to []

  • +
+
+
Returns:
+

weight – The weight vector, corresponding to only the effect of the +corrections specified.

+
+
Return type:
+

numpy.ndarray

+
+
+
+ +
+
+weight(modifier=None)[source]
+

Current event weight vector

+
+
Parameters:
+

modifier (str, optional) – if supplied, provide event weight corresponding to a particular +systematic uncertainty shift, of form str(name + 'Up') or (Down)

+
+
Returns:
+

weight – The weight vector, possibly modified by the effect of a given systematic variation.

+
+
Return type:
+

numpy.ndarray

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.btag_tools.BTagScaleFactor.html b/api/coffea.btag_tools.BTagScaleFactor.html new file mode 100644 index 000000000..d130ea1a2 --- /dev/null +++ b/api/coffea.btag_tools.BTagScaleFactor.html @@ -0,0 +1,289 @@ + + + + + + + + + BTagScaleFactor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

BTagScaleFactor

+
+
+class coffea.btag_tools.BTagScaleFactor(filename, workingpoint, methods='comb,comb,incl', keep_df=False)[source]
+

Bases: object

+

A class holding one complete BTag scale factor for a given working point

+
+
Parameters:
+
    +
  • filename (str) – The BTag-formatted CSV file to read (accepts .csv, .csv.gz, etc.) +See pandas read_csv for all supported compressions.

  • +
  • workingpoint (str or int) – The working point, one of LOOSE, MEDIUM, TIGHT, or RESHAPE (0-3, respectively)

  • +
  • methods (str, optional) – The scale factor derivation method to use for each flavor, ‘b,c,light’ respectively. +Defaults to ‘comb,comb,incl’

  • +
  • keep_df (bool, optional) – If set true, keep the parsed dataframe as an attribute (.df) for later inspection

  • +
+
+
+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + +

FLAV_B

FLAV_C

FLAV_UDSG

LOOSE

MEDIUM

RESHAPE

TIGHT

+

Methods Summary

+ + + + + + + + + + + + +

__call__(systematic, flavor, eta, pt[, ...])

Call self as a function.

eval(systematic, flavor, eta, pt[, discr, ...])

Evaluate this scale factor as a function of jet properties

readcsv(filename)

Reads a BTag-formmated CSV file into a pandas dataframe

+

Attributes Documentation

+
+
+FLAV_B = 0
+
+ +
+
+FLAV_C = 1
+
+ +
+
+FLAV_UDSG = 2
+
+ +
+
+LOOSE = 0
+
+ +
+
+MEDIUM = 1
+
+ +
+
+RESHAPE = 3
+
+ +
+
+TIGHT = 2
+
+ +

Methods Documentation

+
+
+__call__(systematic, flavor, eta, pt, discr=None, ignore_missing=False)[source]
+

Call self as a function.

+
+ +
+
+eval(systematic, flavor, eta, pt, discr=None, ignore_missing=False)[source]
+

Evaluate this scale factor as a function of jet properties

+
+
Parameters:
+
    +
  • systematic (str) – Which systematic to evaluate. Nominal correction is ‘central’, the options depend +on the scale factor and method

  • +
  • flavor (numpy.ndarray or awkward.Array) – The generated jet hadron flavor, following the enumeration: +0: uds quark or gluon, 4: charm quark, 5: bottom quark

  • +
  • eta (numpy.ndarray or awkward.Array) – The jet pseudorapitiy

  • +
  • pt (numpy.ndarray or awkward.Array) – The jet transverse momentum

  • +
  • discr (numpy.ndarray or awkward.Array, optional) – The jet tagging discriminant value (default None), optional for all scale factors except +the reshaping scale factor

  • +
  • ignore_missing (bool, optional) – If set true, any values that have no correction will return 1. instead of throwing +an exception. Out-of-bounds values are always clipped to the nearest bin.

  • +
+
+
Returns:
+

out – An array with shape matching pt, containing the per-jet scale factor

+
+
Return type:
+

numpy.ndarray or awkward.Array

+
+
+
+ +
+
+classmethod readcsv(filename)[source]
+

Reads a BTag-formmated CSV file into a pandas dataframe

+

This function also merges the bin min and max into a tuple representing the bin

+
+
Parameters:
+

filename (str) – The file to open

+
+
Returns:
+

    +
  • df (pandas.DataFrame) – A dataframe containing all info in the file

  • +
  • discriminator (str) – The name of the discriminator the correction map is for

  • +
+

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.Bin.html b/api/coffea.hist.Bin.html new file mode 100644 index 000000000..84ff9b2b3 --- /dev/null +++ b/api/coffea.hist.Bin.html @@ -0,0 +1,261 @@ + + + + + + + + + Bin — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Bin

+
+
+class coffea.hist.Bin(name, label, n_or_arr, lo=None, hi=None)[source]
+

Bases: DenseAxis

+

A binned axis with name, label, and binning.

+
+
Parameters:
+
    +
  • name (str) – is used as a keyword in histogram filling, immutable

  • +
  • label (str) – describes the meaning of the axis, can be changed

  • +
  • n_or_arr (int or list or numpy.ndarray) – Integer number of bins, if uniform binning. Otherwise, a list or +numpy 1D array of bin boundaries.

  • +
  • lo (float, optional) – lower boundary of bin range, if uniform binning

  • +
  • hi (float, optional) – upper boundary of bin range, if uniform binning

  • +
+
+
+

This axis will generate frequencies for n+3 bins, special bin indices: +0 = underflow, n+1 = overflow, n+2 = nanflow +Bin boundaries are [lo, hi)

+

Attributes Summary

+ + + + + + +

size

Number of bins, including overflow (i.e. n + 3).

+

Methods Summary

+ + + + + + + + + + + + + + + + + + +

centers([overflow])

Bin centers

edges([overflow])

Bin boundaries

identifiers([overflow])

List of Interval identifiers

index(identifier)

Index of a identifer or label

reduced(islice)

Return a new axis with reduced binning

+

Attributes Documentation

+
+
+size
+

Number of bins, including overflow (i.e. n + 3)

+
+ +

Methods Documentation

+
+
+centers(overflow='none')[source]
+

Bin centers

+
+
Parameters:
+

overflow (str) – Create overflow and/or underflow bins by adding a bin of same width to each end. +See Hist.sum description for the allowed values.

+
+
+
+ +
+
+edges(overflow='none')[source]
+

Bin boundaries

+
+
Parameters:
+

overflow (str) – Create overflow and/or underflow bins by adding a bin of same width to each end. +See Hist.sum description for the allowed values.

+
+
+
+ +
+
+identifiers(overflow='none')[source]
+

List of Interval identifiers

+
+ +
+
+index(identifier)[source]
+

Index of a identifer or label

+
+
Parameters:
+

identifier (float or Interval or numpy.ndarray) – The identifier(s) to lookup. Supports vectorized +calls when a numpy 1D array of numbers is passed.

+
+
+

Returns an integer corresponding to the index in the axis where the histogram would be filled. +The integer range includes flow bins: 0 = underflow, n+1 = overflow, n+2 = nanflow

+
+ +
+
+reduced(islice)[source]
+

Return a new axis with reduced binning

+

The new binning corresponds to the slice made on this axis. +Overflow will be taken care of by Hist.__getitem__

+
+
Parameters:
+

islice (slice) – islice.start and islice.stop should be None or within [1, ax.size() - 1] +This slice is usually as returned from Bin._ireduce

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.Cat.html b/api/coffea.hist.Cat.html new file mode 100644 index 000000000..999a6952b --- /dev/null +++ b/api/coffea.hist.Cat.html @@ -0,0 +1,222 @@ + + + + + + + + + Cat — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Cat

+
+
+class coffea.hist.Cat(name, label, sorting='identifier')[source]
+

Bases: SparseAxis

+

A category axis with name and label

+
+
Parameters:
+
    +
  • name (str) – is used as a keyword in histogram filling, immutable

  • +
  • label (str) – describes the meaning of the axis, can be changed

  • +
  • sorting ({'identifier', 'placement', 'integral'}, optional) – Axis sorting when listing identifiers. Default ‘placement’ +Changing this setting can effect the order of stack plotting +in hist.plot1d.

  • +
+
+
+

The number of categories is arbitrary, and can be filled sparsely +Identifiers are strings

+

Attributes Summary

+ + + + + + + + + +

size

Number of bins

sorting

Sorting definition to adhere to

+

Methods Summary

+ + + + + + + + + +

identifiers()

List of StringBin identifiers

index(identifier)

Index of a identifer or label

+

Attributes Documentation

+
+
+size
+

Number of bins

+
+ +
+
+sorting
+

Sorting definition to adhere to

+

See Cat constructor for possible values

+
+ +

Methods Documentation

+
+
+identifiers()[source]
+

List of StringBin identifiers

+
+ +
+
+index(identifier)[source]
+

Index of a identifer or label

+
+
Parameters:
+

identifier (str or StringBin) – The identifier to lookup

+
+
+

Returns a StringBin corresponding to the given argument (trival in the case +where a StringBin was passed) and saves a reference internally in the case where +the identifier was not seen before by this axis.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.Hist.html b/api/coffea.hist.Hist.html new file mode 100644 index 000000000..5431ab6bc --- /dev/null +++ b/api/coffea.hist.Hist.html @@ -0,0 +1,594 @@ + + + + + + + + + Hist — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Hist

+
+
+class coffea.hist.Hist(label, *axes, **kwargs)[source]
+

Bases: AccumulatorABC

+

Specify a multidimensional histogram.

+
+
Parameters:
+
    +
  • label (str) – A description of the meaning of the sum of weights

  • +
  • *axes – positional list of Cat or Bin objects, denoting the axes of the histogram

  • +
  • axes (collections.abc.Sequence) – list of Cat or Bin objects, denoting the axes of the histogram (overridden by *axes)

  • +
  • dtype (str) – Underlying numpy dtype to use for storing sum of weights

  • +
+
+
+

Examples

+

Creating a histogram with a sparse axis, and two dense axes:

+
h = coffea.hist.Hist("Observed bird count",
+                     coffea.hist.Cat("species", "Bird species"),
+                     coffea.hist.Bin("x", "x coordinate [m]", 20, -5, 5),
+                     coffea.hist.Bin("y", "y coordinate [m]", 20, -5, 5),
+                     )
+
+# or
+
+h = coffea.hist.Hist(label="Observed bird count",
+                     axes=(coffea.hist.Cat("species", "Bird species"),
+                           coffea.hist.Bin("x", "x coordinate [m]", 20, -5, 5),
+                           coffea.hist.Bin("y", "y coordinate [m]", 20, -5, 5),
+                          )
+                     )
+
+# or
+
+h = coffea.hist.Hist(axes=[coffea.hist.Cat("species", "Bird species"),
+                           coffea.hist.Bin("x", "x coordinate [m]", 20, -5, 5),
+                           coffea.hist.Bin("y", "y coordinate [m]", 20, -5, 5),
+                          ],
+                     label="Observed bird count",
+                     )
+
+
+

which produces:

+
>>> h
+<Hist (species,x,y) instance at 0x10d84b550>
+
+
+

Attributes Summary

+ + + + + + + + + + + + +

DEFAULT_DTYPE

Default numpy dtype to store sum of weights

fields

This is a stub for histbook compatibility

label

A label describing the meaning of the sum of weights

+

Methods Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

add(other)

Add another histogram into this one, in-place

axes()

Get all axes in this histogram

axis(axis_name)

Get an Axis object

clear()

Clear all content in this histogram

compatible(other)

Checks if this histogram is compatible with another, i.e. they have identical binning.

copy([content])

Create a deep copy

dense_axes()

All dense axes

dense_dim()

Dense dimension of this histogram (number of non-sparse axes)

dim()

Dimension of this histogram (number of axes)

fill(**values)

Fill sum of weights from columns

group(old_axes, new_axis, mapping[, overflow])

Group a set of slices on old axes into a single new axis

identifiers(axis[, overflow])

Return a list of identifiers for an axis

identity()

The identity (zero value) of this accumulator

integrate(axis_name[, int_range, overflow])

Integrates current histogram along one dimension

project(*axes, **kwargs)

Project histogram onto a subset of its axes

rebin(old_axis, new_axis)

Rebin a dense axis

remove(bins, axis)

Remove bins from a sparse axis

scale(factor[, axis])

Scale histogram in-place by factor

sparse_axes()

All sparse axes

sparse_dim()

Sparse dimension of this histogram (number of sparse axes)

sparse_nbins()

Total number of sparse bins

sum(*axes, **kwargs)

Integrates out a set of axes, producing a new histogram

to_boost()

Convert this coffea Hist object to a boost_histogram obbject

to_hist()

Convert this coffea.hist histogram to a hist object

values([sumw2, overflow])

Extract the sum of weights arrays from this histogram

+

Attributes Documentation

+
+
+DEFAULT_DTYPE = 'd'
+

Default numpy dtype to store sum of weights

+
+ +
+
+fields
+

This is a stub for histbook compatibility

+
+ +
+
+label
+

A label describing the meaning of the sum of weights

+
+ +

Methods Documentation

+
+
+add(other)[source]
+

Add another histogram into this one, in-place

+
+ +
+
+axes()[source]
+

Get all axes in this histogram

+
+ +
+
+axis(axis_name)[source]
+

Get an Axis object

+
+ +
+
+clear()[source]
+

Clear all content in this histogram

+
+ +
+
+compatible(other)[source]
+

Checks if this histogram is compatible with another, i.e. they have identical binning

+
+ +
+
+copy(content=True)[source]
+

Create a deep copy

+
+
Parameters:
+

content (bool) – If set false, only the histogram definition is copied, resetting +the sum of weights to zero

+
+
+
+ +
+
+dense_axes()[source]
+

All dense axes

+
+ +
+
+dense_dim()[source]
+

Dense dimension of this histogram (number of non-sparse axes)

+
+ +
+
+dim()[source]
+

Dimension of this histogram (number of axes)

+
+ +
+
+fill(**values)[source]
+

Fill sum of weights from columns

+
+
Parameters:
+

**values – Keyword arguments, one for each axis name, of either flat numpy arrays +(for dense dimensions) or literals (for sparse dimensions) which will +be used to fill bins at the corresponding indices.

+
+
+
+

Note

+

The reserved keyword weight, if specified, will increment sum of weights +by the given column values, which must be broadcastable to the same dimension as all other +columns. Upon first use, this will trigger the storage of the sum of squared weights.

+
+

Examples

+

Filling the histogram from the Hist example:

+
>>> h.fill(species='ducks', x=numpy.random.normal(size=10), y=numpy.random.normal(size=10), weight=numpy.ones(size=10) * 3)
+
+
+
+ +
+
+group(old_axes, new_axis, mapping, overflow='none')[source]
+

Group a set of slices on old axes into a single new axis

+
+
Parameters:
+
    +
  • old_axes – Axis or tuple of axes which are being grouped

  • +
  • new_axis – A new sparse dimension definition, e.g. a Cat instance

  • +
  • mapping (dict) – A mapping {'new_bin': (slice, ...), ...} where each +slice is on the axes being re-binned. In the case of +a single axis for old_axes, {'new_bin': slice, ...} +is admissible.

  • +
  • overflow (str) – See sum description for meaning of allowed values +Default is to not include overflow bins

  • +
+
+
+

Returns a new histogram object

+
+ +
+
+identifiers(axis, overflow='none')[source]
+

Return a list of identifiers for an axis

+
+
Parameters:
+
    +
  • axis – Axis name or Axis object

  • +
  • overflow – See sum description for meaning of allowed values

  • +
+
+
+
+ +
+
+identity()[source]
+

The identity (zero value) of this accumulator

+
+ +
+
+integrate(axis_name, int_range=slice(None, None, None), overflow='none')[source]
+

Integrates current histogram along one dimension

+
+
Parameters:
+
    +
  • axis_name (str or Axis) – Which dimension to reduce on

  • +
  • int_range (slice) – Any slice, list, string, or other object that the axis will understand +Default is to integrate over the whole range

  • +
  • overflow (str) – See sum description for meaning of allowed values +Default is to not include overflow bins

  • +
+
+
+
+ +
+
+project(*axes, **kwargs)[source]
+

Project histogram onto a subset of its axes

+
+
Parameters:
+
    +
  • *axes (str or Axis) – Positional list of axes to project on to

  • +
  • overflow (str) – Controls behavior of integration over remaining axes. +See sum description for meaning of allowed values +Default is to not include overflow bins

  • +
+
+
+
+ +
+
+rebin(old_axis, new_axis)[source]
+

Rebin a dense axis

+

This function will construct the mapping from old to new axis, and +constructs a new histogram, rebinning the sum of weights along that dimension.

+
+

Note

+

No interpolation is performed, so the user must be sure the old +and new axes have compatible bin boundaries, e.g. that they evenly +divide each other.

+
+
+
Parameters:
+
    +
  • old_axis (str or Axis) – Axis to rebin

  • +
  • new_axis (str or Axis or int) – A DenseAxis object defining the new axis (e.g. a Bin instance). +If a number N is supplied, the old axis edges are downsampled by N, +resulting in a histogram with old_nbins // N bins.

  • +
+
+
+

Returns a new Hist object.

+
+ +
+
+remove(bins, axis)[source]
+

Remove bins from a sparse axis

+
+
Parameters:
+
    +
  • bins (iterable) – A list of bin identifiers to remove

  • +
  • axis (str or Axis) – Axis name or SparseAxis instance

  • +
+
+
+

Returns a copy of the histogram with specified bins removed, not an in-place operation

+
+ +
+
+scale(factor, axis=None)[source]
+

Scale histogram in-place by factor

+
+
Parameters:
+
    +
  • factor (float or dict) – A number or mapping of identifier to number

  • +
  • axis (optional) – Which (sparse) axis the dict applies to, may be a tuples of axes. +The dict keys must follow the same structure.

  • +
+
+
+

Examples

+

This function is useful to quickly reweight according to some +weight mapping along a sparse axis, such as the species axis +in the Hist example:

+
>>> h.scale({'ducks': 0.3, 'geese': 1.2}, axis='species')
+>>> h.scale({('ducks',): 0.5}, axis=('species',))
+>>> h.scale({('geese', 'honk'): 5.0}, axis=('species', 'vocalization'))
+
+
+
+ +
+
+sparse_axes()[source]
+

All sparse axes

+
+ +
+
+sparse_dim()[source]
+

Sparse dimension of this histogram (number of sparse axes)

+
+ +
+
+sparse_nbins()[source]
+

Total number of sparse bins

+
+ +
+
+sum(*axes, **kwargs)[source]
+

Integrates out a set of axes, producing a new histogram

+
+
Parameters:
+
    +
  • *axes – Positional list of axes to integrate out (either a string or an Axis object)

  • +
  • overflow ({'none', 'under', 'over', 'all', 'allnan'}, optional) – How to treat the overflow bins in the sum. Only applies to dense axes. +‘all’ includes both under- and over-flow but not nan-flow bins. +Default is ‘none’.

  • +
+
+
+
+ +
+
+to_boost()[source]
+

Convert this coffea Hist object to a boost_histogram obbject

+
+ +
+
+to_hist()[source]
+

Convert this coffea.hist histogram to a hist object

+
+ +
+
+values(sumw2=False, overflow='none')[source]
+

Extract the sum of weights arrays from this histogram

+
+
Parameters:
+
    +
  • sumw2 (bool) – If True, frequencies is a tuple of arrays (sum weights, sum squared weights)

  • +
  • overflow – See sum description for meaning of allowed values

  • +
+
+
+

Returns a mapping {(sparse identifier, ...): numpy.array(...), ...} +where each array has dimension dense_dim and shape matching +the number of bins per axis, plus 0-3 overflow bins depending +on the overflow argument.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.Interval.html b/api/coffea.hist.Interval.html new file mode 100644 index 000000000..ebc07c17e --- /dev/null +++ b/api/coffea.hist.Interval.html @@ -0,0 +1,219 @@ + + + + + + + + + Interval — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Interval

+
+
+class coffea.hist.Interval(lo, hi, label=None)[source]
+

Bases: object

+

Real number interval

+

Totally ordered, assuming no overlap in intervals. +A special nan interval can be constructed, which is defined +as greater than [*, inf)

+
+
Parameters:
+
    +
  • lo (float) – Bin lower bound, inclusive

  • +
  • hi (float) – Bin upper bound, exclusive

  • +
+
+
+

Attributes Summary

+ + + + + + + + + + + + + + + +

hi

Upper boundary of this bin, exclusive

label

Label of this bin, mutable

lo

Lower boundary of this bin, inclusive

mid

Midpoint of this bin

+

Methods Summary

+ + + + + + +

nan()

+

Attributes Documentation

+
+
+hi
+

Upper boundary of this bin, exclusive

+
+ +
+
+label
+

Label of this bin, mutable

+
+ +
+
+lo
+

Lower boundary of this bin, inclusive

+
+ +
+
+mid
+

Midpoint of this bin

+
+ +

Methods Documentation

+
+
+nan()[source]
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.StringBin.html b/api/coffea.hist.StringBin.html new file mode 100644 index 000000000..9355178c0 --- /dev/null +++ b/api/coffea.hist.StringBin.html @@ -0,0 +1,187 @@ + + + + + + + + + StringBin — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

StringBin

+
+
+class coffea.hist.StringBin(name, label=None)[source]
+

Bases: object

+

A string used to fill a sparse axis

+

Totally ordered, lexicographically by name.

+
+
Parameters:
+
    +
  • name (str) – Name of the bin, as used in Hist.fill calls

  • +
  • label (str) – The str representation of this bin can be overriden by +a custom label, which will be used preferentially in legends +produced by hist.plot1d, etc.

  • +
+
+
+

Attributes Summary

+ + + + + + + + + +

label

Label of this bin, mutable

name

Name of this bin, Immutable

+

Attributes Documentation

+
+
+label
+

Label of this bin, mutable

+
+ +
+
+name
+

Name of this bin, Immutable

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.clopper_pearson_interval.html b/api/coffea.hist.clopper_pearson_interval.html new file mode 100644 index 000000000..a30ce87a1 --- /dev/null +++ b/api/coffea.hist.clopper_pearson_interval.html @@ -0,0 +1,164 @@ + + + + + + + + + clopper_pearson_interval — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

clopper_pearson_interval

+
+
+coffea.hist.clopper_pearson_interval(num, denom, coverage=0.6826894921370859)[source]
+

Compute Clopper-Pearson coverage interval for a binomial distribution

+
+
Parameters:
+
    +
  • num (numpy.ndarray) – Numerator, or number of successes, vectorized

  • +
  • denom (numpy.ndarray) – Denominator or number of trials, vectorized

  • +
  • coverage (float, optional) – Central coverage interval, defaults to 68%

  • +
+
+
+

c.f. http://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.export1d.html b/api/coffea.hist.export1d.html new file mode 100644 index 000000000..526470e4a --- /dev/null +++ b/api/coffea.hist.export1d.html @@ -0,0 +1,176 @@ + + + + + + + + + export1d — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

export1d

+
+
+coffea.hist.export1d(hist)[source]
+

Export a 1-dimensional Hist object to uproot

+

This allows one to write a coffea histogram into a ROOT file, via uproot.

+
+
Parameters:
+

hist (Hist) – A 1-dimensional histogram object

+
+
Returns:
+

A uproot3_methods.classes.TH1 object

+
+
Return type:
+

out

+
+
+

Examples

+

Creating a coffea histogram, filling, and writing to a file:

+
import coffea, uproot3, numpy
+h = coffea.hist.Hist("Events", coffea.hist.Bin("var", "some variable", 20, 0, 1))
+h.fill(var=numpy.random.normal(size=100))
+fout = uproot3.create('output.root')
+fout['myhist'] = coffea.hist.export1d(h)
+fout.close()
+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.normal_interval.html b/api/coffea.hist.normal_interval.html new file mode 100644 index 000000000..fc07712a5 --- /dev/null +++ b/api/coffea.hist.normal_interval.html @@ -0,0 +1,166 @@ + + + + + + + + + normal_interval — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

normal_interval

+
+
+coffea.hist.normal_interval(pw, tw, pw2, tw2, coverage=0.6826894921370859)[source]
+

Compute errors based on the expansion of pass/(pass + fail), possibly weighted

+
+
Parameters:
+
    +
  • pw (numpy.ndarray) – Numerator, or number of (weighted) successes, vectorized

  • +
  • tw (numpy.ndarray) – Denominator or number of (weighted) trials, vectorized

  • +
  • pw2 (numpy.ndarray) – Numerator sum of weights squared, vectorized

  • +
  • tw2 (numpy.ndarray) – Denominator sum of weights squared, vectorized

  • +
  • coverage (float, optional) – Central coverage interval, defaults to 68%

  • +
  • https (c.f.)

  • +
+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.plot1d.html b/api/coffea.hist.plot1d.html new file mode 100644 index 000000000..372582f17 --- /dev/null +++ b/api/coffea.hist.plot1d.html @@ -0,0 +1,194 @@ + + + + + + + + + plot1d — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

plot1d

+
+
+coffea.hist.plot1d(hist, ax=None, clear=True, overlay=None, stack=False, overflow='none', line_opts=None, fill_opts=None, error_opts=None, legend_opts={}, overlay_overflow='none', density=False, binwnorm=None, order=None)[source]
+

Create a 1D plot from a 1D or 2D Hist object

+
+
Parameters:
+
    +
  • hist (Hist) – Histogram with maximum of two dimensions

  • +
  • ax (matplotlib.axes.Axes, optional) – Axes object (if None, one is created)

  • +
  • clear (bool, optional) – Whether to clear Axes before drawing (if passed); if False, this function will skip drawing the legend

  • +
  • overlay (str, optional) – In the case that hist is 2D, specify the axis of hist to overlay (remaining axis will be x axis)

  • +
  • stack (bool, optional) – Whether to stack or overlay non-axis dimension (if it exists)

  • +
  • order (list, optional) – How to order when stacking. Take a list of identifiers.

  • +
  • overflow (str, optional) – If overflow behavior is not ‘none’, extra bins will be drawn on either end of the nominal +axis range, to represent the contents of the overflow bins. See Hist.sum documentation +for a description of the options.

  • +
  • line_opts (dict, optional) – A dictionary of options to pass to the matplotlib +ax.step call +internal to this function. Leave blank for defaults.

  • +
  • fill_opts (dict, optional) – A dictionary of options to pass to the matplotlib +ax.fill_between call +internal to this function. Leave blank for defaults.

  • +
  • error_opts (dict, optional) – A dictionary of options to pass to the matplotlib +ax.errorbar call +internal to this function. Leave blank for defaults. Some special options are interpreted by +this function and not passed to matplotlib: ‘emarker’ (default: ‘’) specifies the marker type +to place at cap of the errorbar.

  • +
  • legend_opts (dict, optional) – A dictionary of options to pass to the matplotlib +ax.legend call +internal to this fuction. Leave blank for defaults.

  • +
  • overlay_overflow (str, optional) – If overflow behavior is not ‘none’, extra bins in the overlay axis will be overlayed or stacked, +to represent the contents of the overflow bins. See Hist.sum documentation for a description of the options.

  • +
  • density (bool, optional) – If true, convert sum weights to probability density (i.e. integrates to 1 over domain of axis) +(Note: this option conflicts with binwnorm)

  • +
  • binwnorm (float, optional) – If true, convert sum weights to bin-width-normalized, with unit equal to supplied value (usually you want to specify 1.)

  • +
+
+
Returns:
+

ax – A matplotlib Axes object

+
+
Return type:
+

matplotlib.axes.Axes

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.plot2d.html b/api/coffea.hist.plot2d.html new file mode 100644 index 000000000..1b0ab0b36 --- /dev/null +++ b/api/coffea.hist.plot2d.html @@ -0,0 +1,184 @@ + + + + + + + + + plot2d — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

plot2d

+
+
+coffea.hist.plot2d(hist, xaxis, ax=None, clear=True, xoverflow='none', yoverflow='none', patch_opts=None, text_opts=None, density=False, binwnorm=None)[source]
+

Create a 2D plot from a 2D Hist object

+
+
Parameters:
+
    +
  • hist (Hist) – Histogram with two dimensions

  • +
  • xaxis (str or Axis) – Which of the two dimensions to use as an x axis

  • +
  • ax (matplotlib.axes.Axes, optional) – Axes object (if None, one is created)

  • +
  • clear (bool, optional) – Whether to clear Axes before drawing (if passed); if False, this function will skip drawing the legend

  • +
  • xoverflow (str, optional) – If overflow behavior is not ‘none’, extra bins will be drawn on either end of the nominal x +axis range, to represent the contents of the overflow bins. See Hist.sum documentation +for a description of the options.

  • +
  • yoverflow (str, optional) – Similar to xoverflow

  • +
  • patch_opts (dict, optional) – Options passed to the matplotlib pcolormesh +call internal to this function, to plot a rectangular grid of patches colored according to the bin values. +Leave empty for defaults.

  • +
  • text_opts (dict, optional) – Options passed to the matplotlib text +call internal to this function, to place a text label at each bin center with the bin value. Special +options interpreted by this function and not passed to matplotlib: ‘format’: printf-style float format +, default ‘%.2g’.

  • +
  • density (bool, optional) – If true, convert sum weights to probability density (i.e. integrates to 1 over domain of axis) +(Note: this option conflicts with binwnorm)

  • +
  • binwnorm (float, optional) – If true, convert sum weights to bin-width-normalized, with unit equal to supplied value (usually you want to specify 1.)

  • +
+
+
Returns:
+

ax – A matplotlib Axes object

+
+
Return type:
+

matplotlib.axes.Axes

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.plotgrid.html b/api/coffea.hist.plotgrid.html new file mode 100644 index 000000000..ff8a88e77 --- /dev/null +++ b/api/coffea.hist.plotgrid.html @@ -0,0 +1,177 @@ + + + + + + + + + plotgrid — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

plotgrid

+
+
+coffea.hist.plotgrid(h, figure=None, row=None, col=None, overlay=None, row_overflow='none', col_overflow='none', **plot_opts)[source]
+

Create a grid of plots, enumerating identifiers on up to 3 axes

+
+
Parameters:
+
    +
  • h (Hist) – A histogram with up to 3 axes

  • +
  • figure (matplotlib.figure.Figure, optional) – If omitted, a new figure is created. Otherwise, the axes will be redrawn on this existing figure.

  • +
  • row (str) – Name of row axis

  • +
  • col (str) – Name of column axis

  • +
  • overlay (str) – name of overlay axis

  • +
  • row_overflow (str, optional) – If overflow behavior is not ‘none’, extra bins will be drawn on either end of the nominal x +axis range, to represent the contents of the overflow bins. See Hist.sum documentation +for a description of the options.

  • +
  • col_overflow (str, optional) – Similar to row_overflow

  • +
  • **plot_opts (kwargs) – The remaining axis of the histogram, after removing any of row,col,overlay specified, +will be the plot axis, with plot_opts passed to the plot1d call.

  • +
+
+
Returns:
+

axes – An array of matplotlib Axes objects

+
+
Return type:
+

numpy.ndarray

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.plotratio.html b/api/coffea.hist.plotratio.html new file mode 100644 index 000000000..baef4a418 --- /dev/null +++ b/api/coffea.hist.plotratio.html @@ -0,0 +1,189 @@ + + + + + + + + + plotratio — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

plotratio

+
+
+coffea.hist.plotratio(num, denom, ax=None, clear=True, overflow='none', xerr=False, error_opts=None, denom_fill_opts=None, guide_opts=None, unc='clopper-pearson', label=None)[source]
+

Create a ratio plot, dividing two compatible histograms

+
+
Parameters:
+
    +
  • num (Hist) – Numerator, a single-axis histogram

  • +
  • denom (Hist) – Denominator, a single-axis histogram

  • +
  • ax (matplotlib.axes.Axes, optional) – Axes object (if None, one is created)

  • +
  • clear (bool, optional) – Whether to clear Axes before drawing (if passed); if False, this function will skip drawing the legend

  • +
  • overflow (str, optional) – If overflow behavior is not ‘none’, extra bins will be drawn on either end of the nominal +axis range, to represent the contents of the overflow bins. See Hist.sum documentation +for a description of the options.

  • +
  • xerr (bool, optional) – If true, then error bars are drawn for x-axis to indicate the size of the bin.

  • +
  • error_opts (dict, optional) – A dictionary of options to pass to the matplotlib +ax.errorbar call +internal to this function. Leave blank for defaults. Some special options are interpreted by +this function and not passed to matplotlib: ‘emarker’ (default: ‘’) specifies the marker type +to place at cap of the errorbar.

  • +
  • denom_fill_opts (dict, optional) – A dictionary of options to pass to the matplotlib +ax.fill_between call +internal to this function, filling the denominator uncertainty band. Leave blank for defaults.

  • +
  • guide_opts (dict, optional) – A dictionary of options to pass to the matplotlib +ax.axhline call +internal to this function, to plot a horizontal guide line at ratio of 1. Leave blank for defaults.

  • +
  • unc (str, optional) – Uncertainty calculation option: ‘clopper-pearson’ interval for efficiencies; ‘poisson-ratio’ interval +for ratio of poisson distributions; ‘num’ poisson interval of numerator scaled by denominator value +(common for data/mc, for better or worse).

  • +
  • label (str, optional) – Associate a label to this entry (note: y axis label set by num.label)

  • +
+
+
Returns:
+

ax – A matplotlib Axes object

+
+
Return type:
+

matplotlib.axes.Axes

+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.hist.poisson_interval.html b/api/coffea.hist.poisson_interval.html new file mode 100644 index 000000000..199eba9f1 --- /dev/null +++ b/api/coffea.hist.poisson_interval.html @@ -0,0 +1,171 @@ + + + + + + + + + poisson_interval — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

poisson_interval

+
+
+coffea.hist.poisson_interval(sumw, sumw2, coverage=0.6826894921370859)[source]
+

Frequentist coverage interval for Poisson-distributed observations

+
+
Parameters:
+
    +
  • sumw (numpy.ndarray) – Sum of weights vector

  • +
  • sumw2 (numpy.ndarray) – Sum weights squared vector

  • +
  • coverage (float, optional) – Central coverage interval, defaults to 68%

  • +
+
+
+

Calculates the so-called ‘Garwood’ interval, +c.f. https://www.ine.pt/revstat/pdf/rs120203.pdf or +http://ms.mcmaster.ca/peter/s743/poissonalpha.html +For weighted data, this approximates the observed count by sumw**2/sumw2, which +effectively scales the unweighted poisson interval by the average weight. +This may not be the optimal solution: see https://arxiv.org/pdf/1309.1287.pdf for a proper treatment. +When a bin is zero, the scale of the nearest nonzero bin is substituted to scale the nominal upper bound. +If all bins zero, a warning is generated and interval is set to sumw.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.jetmet_tools.CorrectedJetsFactory.html b/api/coffea.jetmet_tools.CorrectedJetsFactory.html new file mode 100644 index 000000000..d48e534e6 --- /dev/null +++ b/api/coffea.jetmet_tools.CorrectedJetsFactory.html @@ -0,0 +1,174 @@ + + + + + + + + + CorrectedJetsFactory — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CorrectedJetsFactory

+
+
+class coffea.jetmet_tools.CorrectedJetsFactory(name_map, jec_stack)[source]
+

Bases: object

+

Methods Summary

+ + + + + + + + + +

build(jets, lazy_cache)

uncertainties()

+

Methods Documentation

+
+
+build(jets, lazy_cache)[source]
+
+ +
+
+uncertainties()[source]
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.jetmet_tools.CorrectedMETFactory.html b/api/coffea.jetmet_tools.CorrectedMETFactory.html new file mode 100644 index 000000000..bb26a6720 --- /dev/null +++ b/api/coffea.jetmet_tools.CorrectedMETFactory.html @@ -0,0 +1,174 @@ + + + + + + + + + CorrectedMETFactory — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

CorrectedMETFactory

+
+
+class coffea.jetmet_tools.CorrectedMETFactory(name_map)[source]
+

Bases: object

+

Methods Summary

+ + + + + + + + + +

build(MET, corrected_jets, lazy_cache)

uncertainties()

+

Methods Documentation

+
+
+build(MET, corrected_jets, lazy_cache)[source]
+
+ +
+
+uncertainties()[source]
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.jetmet_tools.FactorizedJetCorrector.html b/api/coffea.jetmet_tools.FactorizedJetCorrector.html new file mode 100644 index 000000000..6d884a716 --- /dev/null +++ b/api/coffea.jetmet_tools.FactorizedJetCorrector.html @@ -0,0 +1,209 @@ + + + + + + + + + FactorizedJetCorrector — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

FactorizedJetCorrector

+
+
+class coffea.jetmet_tools.FactorizedJetCorrector(**kwargs)[source]
+

Bases: object

+

This class is a columnar implementation of the FactorizedJetCorrector tool in +CMSSW and FWLite. It applies a series of JECs in ascending order as defined by +‘_level_order’, and checks for the consistency of input corrections.

+

It implements the jet energy correction definition specified in the JEC TWiki.

+

You can use this class as follows:

+
fjc = FactorizedJetCorrector(name1=corrL1,...)
+jetCorrs = fjc(JetParameter1=jet.parameter1,...)
+
+
+

Attributes Summary

+ + + + + + +

signature

list the necessary jet properties that must be input to this function

+

Methods Summary

+ + + + + + + + + +

getCorrection(**kwargs)

Returns the set of corrections for all input jets at the highest available level

getSubCorrections(**kwargs)

Returns the set of corrections for all input jets broken down by level

+

Attributes Documentation

+
+
+signature
+

list the necessary jet properties that must be input to this function

+
+ +

Methods Documentation

+
+
+getCorrection(**kwargs)[source]
+

Returns the set of corrections for all input jets at the highest available level

+

Use it like:

+
jecs = corrector.getCorrection(JetProperty1=jet.property1,...)
+
+
+
+ +
+
+getSubCorrections(**kwargs)[source]
+

Returns the set of corrections for all input jets broken down by level

+

Use it like:

+
jecs = corrector.getSubCorrections(JetProperty1=jet.property1,...)
+#'jecs' will be formatted like [[jec_jet1 jec_jet2 ...] ...]
+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.jetmet_tools.JECStack.html b/api/coffea.jetmet_tools.JECStack.html new file mode 100644 index 000000000..c08021bd9 --- /dev/null +++ b/api/coffea.jetmet_tools.JECStack.html @@ -0,0 +1,198 @@ + + + + + + + + + JECStack — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

JECStack

+
+
+class coffea.jetmet_tools.JECStack(corrections, jec=None, junc=None, jer=None, jersf=None)[source]
+

Bases: object

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + +

blank_name_map

jec

jer

jersf

junc

+

Attributes Documentation

+
+
+blank_name_map
+
+ +
+
+jec
+
+ +
+
+jer
+
+ +
+
+jersf
+
+ +
+
+junc
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.jetmet_tools.JetCorrectionUncertainty.html b/api/coffea.jetmet_tools.JetCorrectionUncertainty.html new file mode 100644 index 000000000..570586a29 --- /dev/null +++ b/api/coffea.jetmet_tools.JetCorrectionUncertainty.html @@ -0,0 +1,206 @@ + + + + + + + + + JetCorrectionUncertainty — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

JetCorrectionUncertainty

+
+
+class coffea.jetmet_tools.JetCorrectionUncertainty(**kwargs)[source]
+

Bases: object

+

This class is a columnar implementation of the JetCorrectionUncertainty tool in +CMSSW and FWLite. It calculates the jet energy scale uncertainty for a corrected jet +in a given binning.

+

It implements the jet energy correction definition specified in the JES Uncertainty TWiki.

+

You can use this class as follows:

+
jcu = JetCorrectionUncertainty(name1=corrL1,...)
+jetUncs = jcu(JetParameter1=jet.parameter1,...)
+
+
+

Attributes Summary

+ + + + + + + + + +

levels

list the different sources of uncertainty

signature

list the necessary jet properties that must be input to this function

+

Methods Summary

+ + + + + + +

getUncertainty(**kwargs)

Returns the set of uncertainties for all input jets for all the levels (== sources)

+

Attributes Documentation

+
+
+levels
+

list the different sources of uncertainty

+
+ +
+
+signature
+

list the necessary jet properties that must be input to this function

+
+ +

Methods Documentation

+
+
+getUncertainty(**kwargs)[source]
+

Returns the set of uncertainties for all input jets for all the levels (== sources)

+

Use it like:

+
juncs = uncertainty.getUncertainty(JetProperty1=jet.property1,...)
+#'juncs' will be formatted like [('SourceName', [[up_val down_val]_jet1 ... ]), ...]
+#in a zip iterator
+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.jetmet_tools.JetResolution.html b/api/coffea.jetmet_tools.JetResolution.html new file mode 100644 index 000000000..53b1c9873 --- /dev/null +++ b/api/coffea.jetmet_tools.JetResolution.html @@ -0,0 +1,195 @@ + + + + + + + + + JetResolution — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

JetResolution

+
+
+class coffea.jetmet_tools.JetResolution(**kwargs)[source]
+

Bases: object

+

This class is a columnar implementation of the JetResolution tool in +CMSSW and FWLite. It calculates the jet energy resolution for a corrected jet +in a given binning.

+

It implements the jet energy correction definition specified in the JER TWiki.

+

You can use this class as follows:

+
jr = JetResolution(name1=corrL1,...)
+jetRes = jr(JetParameter1=jet.parameter1,...)
+
+
+

Attributes Summary

+ + + + + + +

signature

list the necessary jet properties that must be input to this function

+

Methods Summary

+ + + + + + +

getResolution(**kwargs)

Returns the set of resolutions for all input jets at the highest available level

+

Attributes Documentation

+
+
+signature
+

list the necessary jet properties that must be input to this function

+
+ +

Methods Documentation

+
+
+getResolution(**kwargs)[source]
+

Returns the set of resolutions for all input jets at the highest available level

+

Use it like:

+
jrs = reso.getResolution(JetProperty1=jet.property1,...)
+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.jetmet_tools.JetResolutionScaleFactor.html b/api/coffea.jetmet_tools.JetResolutionScaleFactor.html new file mode 100644 index 000000000..6d1ad6d1c --- /dev/null +++ b/api/coffea.jetmet_tools.JetResolutionScaleFactor.html @@ -0,0 +1,195 @@ + + + + + + + + + JetResolutionScaleFactor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

JetResolutionScaleFactor

+
+
+class coffea.jetmet_tools.JetResolutionScaleFactor(**kwargs)[source]
+

Bases: object

+

This class is a columnar implementation of the JetResolutionScaleFactor tool in +CMSSW and FWLite. It calculates the jet energy resolution scale factor for a +corrected jet in a given binning.

+

It implements the jet energy scale factor definition specified in the JER TWiki.

+

You can use this class as follows:

+
jersf = JetResolutionScaleFactor(name1=corrL1,...)
+jetResSF = jersf(JetParameter1=jet.parameter1,...)
+
+
+

Attributes Summary

+ + + + + + +

signature

list the necessary jet properties that must be input to this function

+

Methods Summary

+ + + + + + +

getScaleFactor(**kwargs)

Returns the set of resolutions for all input jets at the highest available level

+

Attributes Documentation

+
+
+signature
+

list the necessary jet properties that must be input to this function

+
+ +

Methods Documentation

+
+
+getScaleFactor(**kwargs)[source]
+

Returns the set of resolutions for all input jets at the highest available level

+

Use it like:

+
jersfs = jersf.getScaleFactor(JetProperty1=jet.property1,...)
+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.lookup_tools.evaluator.html b/api/coffea.lookup_tools.evaluator.html new file mode 100644 index 000000000..83bfffa36 --- /dev/null +++ b/api/coffea.lookup_tools.evaluator.html @@ -0,0 +1,177 @@ + + + + + + + + + evaluator — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

evaluator

+
+
+class coffea.lookup_tools.evaluator(names, types, primitives)[source]
+

Bases: object

+

The evaluator class serves as a single point of extry for +looking up values of histograms and other functions read in +with the extractor class. Stored look ups can be indexed by +name and then called through an overloaded __call__ function.

+

Example:

+
#assuming 'eta' and 'pt' are array like objects
+wgts = "testSF2d scalefactors_Tight_Electron tests/samples/testSF2d.histo.root"
+extractor.add_weight_sets([wgts])
+extractor.finalize(reduce_list=['testSF2d'])
+evaluator = extractor.make_evaluator()
+out = evaluator["testSF2d"](eta, pt)
+
+
+

The returned value has the same shape as the input arguments.

+

lookup_types is a map of possible contructors for extracted data

+

Methods Summary

+ + + + + + +

keys()

returns the available functions

+

Methods Documentation

+
+
+keys()[source]
+

returns the available functions

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.lookup_tools.extractor.html b/api/coffea.lookup_tools.extractor.html new file mode 100644 index 000000000..524e24d03 --- /dev/null +++ b/api/coffea.lookup_tools.extractor.html @@ -0,0 +1,234 @@ + + + + + + + + + extractor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

extractor

+
+
+class coffea.lookup_tools.extractor[source]
+

Bases: object

+

This class defines a common entry point for defining functions that extract +the inputs to build lookup tables from various kinds of files.

+

The files that can be converted are presently defined in the “file_converters” dict.

+
+
The file names are used to determine the converter that is used, i.e.:

something.TYPE.FORMAT will apply the TYPE extractor to a file of given FORMAT

+
+
+

If there is no file type specifier the ‘default’ value is used.

+
+
The extractor class supports a number of useful file formats by default:
    +
  • .histo.root : 1,2, and 3 dimensional histograms in root files.

  • +
  • .histo.json : N-dimensional histograms stored in JSON format.

  • +
  • .btag.csv : CMS BTV b-tagging weights in csv files.

  • +
  • .ea.txt : CMS EGM effective area text files.

  • +
  • ‘.[jec, jersf, jr, junc].txt’ : CMS JME jet energy corrections and systematic error text files.

  • +
+
+
+

It is possible to extend the functionality of lookup_tools.extractor by editing coffea.lookup_tools.file_converters to add new types and formats.

+
+
You can add sets of lookup tables / weights by calling:

extractor.add_weight_set(<description>)

+
+
<description> is formatted like ‘<nickname> <name-in-file> <the file to extract>’

* can be used as a wildcard to import all available lookup tables in a file

+
+
+

Methods Summary

+ + + + + + + + + + + + + + + + + + + + + +

add_weight_set(local_name, thetype, weights)

adds one extracted weight to the extractor

add_weight_sets(weightsdescs)

expects a list of text lines to be formatted as '<local name> <name> <weights file>' allows * * <file> and <prefix> * <file> to do easy imports of whole file

extract_from_file(thefile, name)

import a file and then extract a lookup set

finalize([reduce_list])

stop any further imports and if provided pare down the stored histograms to those specified in reduce_list

import_file(thefile)

cache the whole contents of a file for later processing

make_evaluator()

produce an evaluator based on the finalized extractor

+

Methods Documentation

+
+
+add_weight_set(local_name, thetype, weights)[source]
+

adds one extracted weight to the extractor

+
+ +
+
+add_weight_sets(weightsdescs)[source]
+

expects a list of text lines to be formatted as ‘<local name> <name> <weights file>’ +allows * * <file> and <prefix> * <file> to do easy imports of whole file

+
+ +
+
+extract_from_file(thefile, name)[source]
+

import a file and then extract a lookup set

+
+ +
+
+finalize(reduce_list=None)[source]
+

stop any further imports and if provided pare down +the stored histograms to those specified in reduce_list

+
+ +
+
+import_file(thefile)[source]
+

cache the whole contents of a file for later processing

+
+ +
+
+make_evaluator()[source]
+

produce an evaluator based on the finalized extractor

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.lumi_tools.LumiData.html b/api/coffea.lumi_tools.LumiData.html new file mode 100644 index 000000000..fae71c29b --- /dev/null +++ b/api/coffea.lumi_tools.LumiData.html @@ -0,0 +1,181 @@ + + + + + + + + + LumiData — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

LumiData

+
+
+class coffea.lumi_tools.LumiData(lumi_csv)[source]
+

Bases: object

+

Holds per-lumiSection integrated lumi values

+
+
Parameters:
+

lumi_csv (str) – The path the the luminosity csv output file

+
+
+

The values are extracted from the csv output as returned by brilcalc, e.g. with a command such as:

+
brilcalc lumi -c /cvmfs/cms.cern.ch/SITECONF/local/JobConfig/site-local-config.xml \
+         -b "STABLE BEAMS" --normtag=/cvmfs/cms-bril.cern.ch/cms-lumi-pog/Normtags/normtag_PHYSICS.json \
+         -u /pb --byls --output-style csv -i Cert_294927-306462_13TeV_PromptReco_Collisions17_JSON.txt > lumi2017.csv
+
+
+

Methods Summary

+ + + + + + +

get_lumi(runlumis)

Calculate integrated lumi

+

Methods Documentation

+
+
+get_lumi(runlumis)[source]
+

Calculate integrated lumi

+
+
Parameters:
+

runlumis (numpy.ndarray or LumiList) – A 2d numpy array of [[run,lumi], [run,lumi], ...] or LumiList object +of the lumiSections to integrate over.

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.lumi_tools.LumiList.html b/api/coffea.lumi_tools.LumiList.html new file mode 100644 index 000000000..42919d14a --- /dev/null +++ b/api/coffea.lumi_tools.LumiList.html @@ -0,0 +1,173 @@ + + + + + + + + + LumiList — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

LumiList

+
+
+class coffea.lumi_tools.LumiList(runs=None, lumis=None)[source]
+

Bases: object

+

Mergeable list of unique (run, lumiSection) values

+

This list can be merged with another via +=.

+
+
Parameters:
+
+
+
+

Methods Summary

+ + + + + + +

clear()

Clear current lumi list

+

Methods Documentation

+
+
+clear()[source]
+

Clear current lumi list

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.lumi_tools.LumiMask.html b/api/coffea.lumi_tools.LumiMask.html new file mode 100644 index 000000000..7105733ca --- /dev/null +++ b/api/coffea.lumi_tools.LumiMask.html @@ -0,0 +1,185 @@ + + + + + + + + + LumiMask — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

LumiMask

+
+
+class coffea.lumi_tools.LumiMask(jsonfile)[source]
+

Bases: object

+

Holds a luminosity mask index, and provides vectorized lookup

+
+
Parameters:
+

jsonfile (str) – Path the the ‘golden json’ file or other valid lumiSection database in json format.

+
+
+

This class parses a CMS lumi json into an efficient valid lumiSection lookup table

+

Methods Summary

+ + + + + + +

__call__(runs, lumis)

Check if run and lumi are valid

+

Methods Documentation

+
+
+__call__(runs, lumis)[source]
+

Check if run and lumi are valid

+
+
Parameters:
+
+
+
Returns:
+

mask_out – An array of dtype bool where valid (run, lumi) tuples +will have their corresponding entry set True.

+
+
Return type:
+

numpy.ndarray

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.BaseSchema.html b/api/coffea.nanoevents.BaseSchema.html new file mode 100644 index 000000000..9953c4844 --- /dev/null +++ b/api/coffea.nanoevents.BaseSchema.html @@ -0,0 +1,181 @@ + + + + + + + + + BaseSchema — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

BaseSchema

+
+
+class coffea.nanoevents.BaseSchema(base_form)[source]
+

Bases: object

+

Base schema builder

+

The basic schema is essentially unchanged from the original ROOT file. +A top-level base.NanoEvents object is returned, where each original branch +form is accessible as a direct descendant.

+

Attributes Summary

+ + + + + + + + + +

behavior

Behaviors necessary to implement this schema

form

Awkward form of this schema

+

Attributes Documentation

+
+
+behavior
+

Behaviors necessary to implement this schema

+
+ +
+
+form
+

Awkward form of this schema

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.DelphesSchema.html b/api/coffea.nanoevents.DelphesSchema.html new file mode 100644 index 000000000..0fa58c6fa --- /dev/null +++ b/api/coffea.nanoevents.DelphesSchema.html @@ -0,0 +1,223 @@ + + + + + + + + + DelphesSchema — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

DelphesSchema

+
+
+class coffea.nanoevents.DelphesSchema(base_form, version='latest')[source]
+

Bases: BaseSchema

+

Delphes schema builder

+

The Delphes schema is built from all branches found in the supplied file, based on +the naming pattern of the branches. The following additional arrays are constructed:

+
    +
  • Any branches named {name}_size are assumed to be counts branches and converted to offsets o{name}

  • +
+

Attributes Summary

+ + + + + + + + + + + + + + + + + + +

behavior

Behaviors necessary to implement this schema

docstrings

mixins

singletons

warn_missing_crossrefs

+

Methods Summary

+ + + + + + +

v1(base_form)

Build the DelphesEvents

+

Attributes Documentation

+
+
+behavior
+

Behaviors necessary to implement this schema

+
+ +
+
+docstrings = {'AlphaQCD': 'value of the QCD coupling used in the event, see hep-ph/0109068', 'AlphaQED': 'value of the QED coupling used in the event, see hep-ph/0109068', 'Area': 'area', 'BTVSumPT2': 'sum pt^2 of tracks attached to the secondary vertex', 'BTag': '0 or 1 for a jet that has been tagged as containing a heavy quark', 'BTagAlgo': '0 or 1 for a jet that has been tagged as containing a heavy quark', 'BTagPhys': '0 or 1 for a jet that has been tagged as containing a heavy quark', 'Beta': '(sum pt of charged pile-up constituents)/(sum pt of charged constituents)', 'BetaStar': '(sum pt of charged constituents coming from hard interaction)/(sum pt of charged constituents)', 'Charge': 'charge', 'Constituents': 'references to constituents', 'CrossSection': 'cross-section in [pb]', 'CrossSectionError': 'cross-section error [pb]', 'CtgTheta': 'cotangent of theta', 'D0': 'transverse impact parameter', 'D1': 'particle first child', 'D2': 'particle last child', 'DZ': 'longitudinal impact parameter', 'E': 'energy [GeV]', 'ET': 'transverse energy [GeV]', 'Edges[2]': 'pseudorapidity range edges', 'Edges[4]': 'calorimeter tower edges', 'Eem': 'calorimeter tower electromagnetic energy', 'Ehad': 'calorimeter tower hadronic energy', 'EhadOverEem': 'ratio of the hadronic versus electromagnetic energy deposited in the calorimeter', 'ErrorCtgTheta': 'cotangent of theta error', 'ErrorD0': 'transverse impact parameter error', 'ErrorDZ': 'longitudinal impact parameter error', 'ErrorP': 'momentum error [GeV]', 'ErrorPT': 'transverse momentum error [GeV]', 'ErrorPhi': 'azimuthal angle error', 'ErrorT': 'vertex position error (t component)', 'ErrorX': 'vertex position error (x component)', 'ErrorY': 'vertex position error (y component)', 'ErrorZ': 'vertex position error (z component)', 'Eta': 'pseudorapidity', 'EtaOuter': 'pseudorapidity at the edge', 'Flavor': 'jet flavor', 'FlavorAlgo': 'jet flavor', 'FlavorPhys': 'jet flavor', 'FracPt[5]': '(sum pt of constituents within a ring 0.1*i < DeltaR < 0.1*(i+1))/(sum pt of constituents)', 'GenDeltaZ': 'distance in z to closest generated vertex', 'GenSumPT2': 'sum pt^2 of gen tracks attached to the vertex', 'HT': 'scalar sum of transverse momenta [GeV]', 'ID': 'ID', 'ID1': 'flavour code of first parton', 'ID2': 'flavour code of second parton', 'Index': 'index', 'IsPU': '0 or 1 for particles from pile-up interactions', 'IsolationVar': 'isolation variable', 'IsolationVarRhoCorr': 'isolation variable', 'L': 'path length', 'M1': 'particle first parent', 'M2': 'particle second parent', 'MET': 'missing transverse energy', 'MPI': 'number of multi parton interactions', 'Mass': 'invariant mass [GeV]', 'MeanSqDeltaR': 'average distance (squared) between constituent and particle weighted by pt (squared) of constituent', 'NCharged': 'number of charged constituents', 'NDF': 'number of degrees of freedom', 'NNeutrals': 'number of neutral constituents', 'NSubJetsPruned': 'number of subjets pruned', 'NSubJetsSoftDropped': 'number of subjets soft-dropped', 'NSubJetsTrimmed': 'number of subjets trimmed', 'NTimeHits': 'number of hits contributing to time measurement', 'Number': 'event number', 'P': 'momentum [GeV]', 'PDF1': 'PDF (id1, x1, Q)', 'PDF2': 'PDF (id2, x2, Q)', 'PID': 'HEP ID number', 'PT': 'transverse momentum [GeV]', 'PTD': 'average pt between constituent and jet weighted by pt of constituent', 'Particle': 'reference to generated particle', 'Particles': 'references to generated particles', 'Phi': 'azimuthal angle', 'PhiOuter': 'azimuthal angle at the edge', 'ProcTime': 'processing time', 'ProcessID': 'subprocess code for the event or signal process id', 'PrunedP4[5]': 'first entry (i = 0) is the total Pruned Jet 4-momenta and from i = 1 to 4 are the pruned subjets 4-momenta', 'Px': 'particle momentum vector (x component)', 'Py': 'particle momentum vector (y component)', 'Pz': 'particle momentum vector (z component)', 'Rapidity': 'particle rapidity', 'ReadTime': 'read time', 'Rho': 'rho energy density', 'S': 'distance to the interaction point [m]', 'Scale': 'energy scale, see hep-ph/0109068', 'ScalePDF': "Q-scale used in evaluation of PDF's [GeV]", 'Sigma': 'vertex position (z component) error', 'SoftDroppedP4[5]': 'first entry (i = 0) is the total SoftDropped Jet 4-momenta and from i = 1 to 4 are the pruned subjets 4-momenta', 'SoftDroppedSubJet1': 'leading soft-dropped subjet', 'SoftDroppedSubJet2': 'subleading soft-dropped subjet', 'Status': 'particle status', 'SumPT2': 'sum pt^2 of tracks attached to the vertex', 'SumPt': 'isolation variable', 'SumPtCharged': 'isolation variable', 'SumPtChargedPU': 'isolation variable', 'SumPtNeutral': 'isolation variable', 'TOuter': 'time position (t component) at the edge', 'TauTag': '0 or 1 for a particle that has been tagged as a tau', 'Tau[5]': 'N-subjettiness', 'Trigger': 'trigger word', 'TrimmedP4[5]': 'first entry (i = 0) is the total Trimmed Jet 4-momenta and from i = 1 to 4 are the trimmed subjets 4-momenta', 'Tx': 'angle of the momentum in the horizontal (x,z) plane [urad]', 'Ty': 'angle of the momentum in the verical (y,z) plane [urad]', 'VertexIndex': 'reference to vertex', 'Weight': 'weight for the event', 'X1': 'fraction of beam momentum carried by first parton ("beam side")', 'X2': 'fraction of beam momentum carried by second parton ("target side")', 'XOuter': 'position (x component) at the edge', 'Xd': 'X coordinate of point of closest approach to vertex', 'YOuter': 'position (y component) at the edge', 'Yd': 'Y coordinate of point of closest approach to vertex', 'ZOuter': 'position (z component) at the edge', 'Zd': 'Z coordinate of point of closest approach to vertex'}
+
+ +
+
+mixins = {'CaloJet02': 'Jet', 'CaloJet04': 'Jet', 'CaloJet08': 'Jet', 'CaloJet15': 'Jet', 'EFlowNeutralHadron': 'Tower', 'EFlowPhoton': 'Photon', 'EFlowTrack': 'Track', 'Electron': 'Electron', 'Event': 'Event', 'EventLHEF': 'EventLHEF', 'GenJet': 'Jet', 'GenJet02': 'Jet', 'GenJet04': 'Jet', 'GenJet08': 'Jet', 'GenJet15': 'Jet', 'GenMissingET': 'MissingET', 'HepMCEvent': 'HepMCEvent', 'Jet': 'Jet', 'LHCOEvent': 'LHCOEvent', 'MissingET': 'MissingET', 'Muon': 'Muon', 'Particle': 'Particle', 'ParticleFlowJet02': 'Jet', 'ParticleFlowJet04': 'Jet', 'ParticleFlowJet08': 'Jet', 'ParticleFlowJet15': 'Jet', 'Photon': 'Photon', 'Rho': 'Rho', 'ScalarHT': 'ScalarHT', 'Tower': 'Tower', 'Track': 'Track', 'TrackJet02': 'Jet', 'TrackJet04': 'Jet', 'TrackJet08': 'Jet', 'TrackJet15': 'Jet', 'Weight': 'Weight', 'WeightLHEF': 'WeightLHEF'}
+
+ +
+
+singletons = ['Event', 'EventLHEF', 'HepMCEvent', 'LHCOEvent', 'Rho', 'ScalarHT', 'MissingET']
+
+ +
+
+warn_missing_crossrefs = True
+
+ +

Methods Documentation

+
+
+classmethod v1(base_form)[source]
+

Build the DelphesEvents

+

For example, one can use NanoEventsFactory.from_root("file.root", schemaclass=DelphesSchema.v1) +to ensure NanoAODv7 compatibility.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.NanoAODSchema.html b/api/coffea.nanoevents.NanoAODSchema.html new file mode 100644 index 000000000..233bf16c6 --- /dev/null +++ b/api/coffea.nanoevents.NanoAODSchema.html @@ -0,0 +1,280 @@ + + + + + + + + + NanoAODSchema — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

NanoAODSchema

+
+
+class coffea.nanoevents.NanoAODSchema(base_form, version='latest')[source]
+

Bases: BaseSchema

+

NanoAOD schema builder

+

The NanoAOD schema is built from all branches found in the supplied file, based on +the naming pattern of the branches. The following additional arrays are constructed:

+
    +
  • Any branches named n{name} are assumed to be counts branches and converted to offsets o{name}

  • +
  • Any local index branches with names matching {source}_{target}Idx* are converted to global indexes for the event chunk (postfix G)

  • +
  • Any nested_items are constructed, if the necessary branches are available

  • +
  • Any special_items are constructed, if the necessary branches are available

  • +
+

From those arrays, NanoAOD collections are formed as collections of branches grouped by name, where:

+
    +
  • one branch exists named name and no branches start with name_, interpreted as a single flat array;

  • +
  • one branch exists named name, one named n{name}, and no branches start with name_, interpreted as a single jagged array;

  • +
  • no branch exists named {name} and many branches start with name_*, interpreted as a flat table; or

  • +
  • one branch exists named n{name} and many branches start with name_*, interpreted as a jagged table.

  • +
+

Collections are assigned mixin types according to the mixins mapping. +All collections are then zipped into one base.NanoEvents record and returned.

+

There is a class-level variable warn_missing_crossrefs which will alter the behavior of +NanoAODSchema. If warn_missing_crossrefs is true then when a missing global index cross-ref +target is encountered a warning will be issued. Regardless, the cross-reference is dropped.

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + +

all_cross_references

Cross-references, where an index is to be interpreted with respect to another collection

behavior

Behaviors necessary to implement this schema

mixins

Default configuration for mixin types, based on the collection name.

nested_index_items

Nested collections, where nesting is accomplished by assuming the target can be unflattened according to a source counts

nested_items

Nested collections, where nesting is accomplished by a fixed-length set of indexers

special_items

Special arrays, where the callable and input arrays are specified in the value

warn_missing_crossrefs

+

Methods Summary

+ + + + + + + + + + + + +

v5(base_form)

Build the NanoEvents assuming NanoAODv5

v6(base_form)

Build the NanoEvents assuming NanoAODv6

v7(base_form)

Build the NanoEvents assuming NanoAODv7

+

Attributes Documentation

+
+
+all_cross_references = {'Electron_genPartIdx': 'GenPart', 'Electron_jetIdx': 'Jet', 'Electron_photonIdx': 'Photon', 'FatJet_genJetAK8Idx': 'GenJetAK8', 'FatJet_subJetIdx1': 'SubJet', 'FatJet_subJetIdx2': 'SubJet', 'FsrPhoton_muonIdx': 'Muon', 'GenPart_genPartIdxMother': 'GenPart', 'GenVisTau_genPartIdxMother': 'GenPart', 'Jet_electronIdx1': 'Electron', 'Jet_electronIdx2': 'Electron', 'Jet_genJetIdx': 'GenJet', 'Jet_muonIdx1': 'Muon', 'Jet_muonIdx2': 'Muon', 'LowPtElectron_electronIdx': 'Electron', 'LowPtElectron_genPartIdx': 'GenPart', 'LowPtElectron_photonIdx': 'Photon', 'Muon_fsrPhotonIdx': 'FsrPhoton', 'Muon_genPartIdx': 'GenPart', 'Muon_jetIdx': 'Jet', 'Photon_electronIdx': 'Electron', 'Photon_genPartIdx': 'GenPart', 'Photon_jetIdx': 'Jet', 'Tau_genPartIdx': 'GenPart', 'Tau_jetIdx': 'Jet'}
+

Cross-references, where an index is to be interpreted with respect to another collection

+

Each such cross-reference will be converted to a global indexer, so that arbitrarily sliced events +can still resolve the indirection back the parent events

+
+ +
+
+behavior
+

Behaviors necessary to implement this schema

+
+ +
+
+mixins = {'CaloMET': 'MissingET', 'ChsMET': 'MissingET', 'Electron': 'Electron', 'FatJet': 'FatJet', 'FsrPhoton': 'FsrPhoton', 'GenDressedLepton': 'PtEtaPhiMCollection', 'GenIsolatedPhoton': 'PtEtaPhiMCollection', 'GenJet': 'PtEtaPhiMCollection', 'GenJetAK8': 'PtEtaPhiMCollection', 'GenMET': 'MissingET', 'GenPart': 'GenParticle', 'GenVisTau': 'GenVisTau', 'IsoTrack': 'PtEtaPhiMCollection', 'Jet': 'Jet', 'LHEPart': 'PtEtaPhiMCollection', 'LowPtElectron': 'LowPtElectron', 'MET': 'MissingET', 'METFixEE2017': 'MissingET', 'Muon': 'Muon', 'PV': 'Vertex', 'Photon': 'Photon', 'PuppiMET': 'MissingET', 'RawMET': 'MissingET', 'RawPuppiMET': 'MissingET', 'SV': 'SecondaryVertex', 'SoftActivityJet': 'PtEtaPhiMCollection', 'SubGenJetAK8': 'PtEtaPhiMCollection', 'SubJet': 'PtEtaPhiMCollection', 'Tau': 'Tau', 'TkMET': 'MissingET', 'TrigObj': 'PtEtaPhiMCollection'}
+

Default configuration for mixin types, based on the collection name.

+

The types are implemented in the coffea.nanoevents.methods.nanoaod module.

+
+ +
+
+nested_index_items = {'FatJet_pFCandsIdxG': ('FatJet_nConstituents', 'FatJetPFCands'), 'GenFatJet_pFCandsIdxG': ('GenJetAK8_nConstituents', 'GenFatJetCands'), 'GenJet_pFCandsIdxG': ('GenJet_nConstituents', 'GenJetCands'), 'Jet_pFCandsIdxG': ('Jet_nConstituents', 'JetPFCands')}
+

Nested collections, where nesting is accomplished by assuming the target can be unflattened according to a source counts

+
+ +
+
+nested_items = {'FatJet_subJetIdxG': ['FatJet_subJetIdx1G', 'FatJet_subJetIdx2G'], 'Jet_electronIdxG': ['Jet_electronIdx1G', 'Jet_electronIdx2G'], 'Jet_muonIdxG': ['Jet_muonIdx1G', 'Jet_muonIdx2G']}
+

Nested collections, where nesting is accomplished by a fixed-length set of indexers

+
+ +
+
+special_items = {'GenPart_childrenIdxG': (<function children_form>, ('oGenPart', 'GenPart_genPartIdxMotherG')), 'GenPart_distinctChildrenDeepIdxG': (<function distinctChildrenDeep_form>, ('oGenPart', 'GenPart_genPartIdxMotherG', 'GenPart_pdgId')), 'GenPart_distinctChildrenIdxG': (<function children_form>, ('oGenPart', 'GenPart_distinctParentIdxG')), 'GenPart_distinctParentIdxG': (<function distinctParent_form>, ('GenPart_genPartIdxMotherG', 'GenPart_pdgId'))}
+

Special arrays, where the callable and input arrays are specified in the value

+
+ +
+
+warn_missing_crossrefs = True
+
+ +

Methods Documentation

+
+
+classmethod v5(base_form)[source]
+

Build the NanoEvents assuming NanoAODv5

+
+ +
+
+classmethod v6(base_form)[source]
+

Build the NanoEvents assuming NanoAODv6

+
+ +
+
+classmethod v7(base_form)[source]
+

Build the NanoEvents assuming NanoAODv7

+

For example, one can use NanoEventsFactory.from_root("file.root", schemaclass=NanoAODSchema.v7) +to ensure NanoAODv7 compatibility.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.NanoEventsFactory.html b/api/coffea.nanoevents.NanoEventsFactory.html new file mode 100644 index 000000000..4882b7564 --- /dev/null +++ b/api/coffea.nanoevents.NanoEventsFactory.html @@ -0,0 +1,252 @@ + + + + + + + + + NanoEventsFactory — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

NanoEventsFactory

+
+
+class coffea.nanoevents.NanoEventsFactory(schema, mapping, partition_key, cache=None)[source]
+

Bases: object

+

A factory class to build NanoEvents objects

+

Methods Summary

+ + + + + + + + + + + + + + + +

events()

Build events

from_parquet(file[, treepath, entry_start, ...])

Quickly build NanoEvents from a parquet file

from_preloaded(array_source[, entry_start, ...])

Quickly build NanoEvents from a pre-loaded array source

from_root(file[, treepath, entry_start, ...])

Quickly build NanoEvents from a root file

+

Methods Documentation

+
+
+events()[source]
+

Build events

+
+ +
+
+classmethod from_parquet(file, treepath='/Events', entry_start=None, entry_stop=None, runtime_cache=None, persistent_cache=None, schemaclass=<class 'coffea.nanoevents.schemas.nanoaod.NanoAODSchema'>, metadata=None, parquet_options={}, skyhook_options={}, access_log=None)[source]
+

Quickly build NanoEvents from a parquet file

+
+
Parameters:
+
    +
  • file (str, pathlib.Path, pyarrow.NativeFile, or python file-like) – The filename or already opened file using e.g. uproot.open()

  • +
  • treepath (str, optional) – Name of the tree to read in the file

  • +
  • entry_start (int, optional) – Start at this entry offset in the tree (default 0)

  • +
  • entry_stop (int, optional) – Stop at this entry offset in the tree (default end of tree)

  • +
  • runtime_cache (dict, optional) – A dict-like interface to a cache object. This cache is expected to last the +duration of the program only, and will be used to hold references to materialized +awkward arrays, etc.

  • +
  • persistent_cache (dict, optional) – A dict-like interface to a cache object. Only bare numpy arrays will be placed in this cache, +using globally-unique keys.

  • +
  • schemaclass (BaseSchema) – A schema class deriving from BaseSchema and implementing the desired view of the file

  • +
  • metadata (dict, optional) – Arbitrary metadata to add to the base.NanoEvents object

  • +
  • parquet_options (dict, optional) – Any options to pass to pyarrow.parquet.ParquetFile

  • +
  • access_log (list, optional) – Pass a list instance to record which branches were lazily accessed by this instance

  • +
+
+
+
+ +
+
+classmethod from_preloaded(array_source, entry_start=None, entry_stop=None, runtime_cache=None, persistent_cache=None, schemaclass=<class 'coffea.nanoevents.schemas.nanoaod.NanoAODSchema'>, metadata=None, access_log=None)[source]
+

Quickly build NanoEvents from a pre-loaded array source

+
+
Parameters:
+
    +
  • array_source (Mapping[str, awkward.Array]) – A mapping of names to awkward arrays, it must have a metadata attribute with uuid, +num_rows, and path sub-items.

  • +
  • entry_start (int, optional) – Start at this entry offset in the tree (default 0)

  • +
  • entry_stop (int, optional) – Stop at this entry offset in the tree (default end of tree)

  • +
  • runtime_cache (dict, optional) – A dict-like interface to a cache object. This cache is expected to last the +duration of the program only, and will be used to hold references to materialized +awkward arrays, etc.

  • +
  • persistent_cache (dict, optional) – A dict-like interface to a cache object. Only bare numpy arrays will be placed in this cache, +using globally-unique keys.

  • +
  • schemaclass (BaseSchema) – A schema class deriving from BaseSchema and implementing the desired view of the file

  • +
  • metadata (dict, optional) – Arbitrary metadata to add to the base.NanoEvents object

  • +
  • access_log (list, optional) – Pass a list instance to record which branches were lazily accessed by this instance

  • +
+
+
+
+ +
+
+classmethod from_root(file, treepath='/Events', entry_start=None, entry_stop=None, runtime_cache=None, persistent_cache=None, schemaclass=<class 'coffea.nanoevents.schemas.nanoaod.NanoAODSchema'>, metadata=None, uproot_options={}, access_log=None, iteritems_options={})[source]
+

Quickly build NanoEvents from a root file

+
+
Parameters:
+
    +
  • file (str or uproot.reading.ReadOnlyDirectory) – The filename or already opened file using e.g. uproot.open()

  • +
  • treepath (str, optional) – Name of the tree to read in the file

  • +
  • entry_start (int, optional) – Start at this entry offset in the tree (default 0)

  • +
  • entry_stop (int, optional) – Stop at this entry offset in the tree (default end of tree)

  • +
  • runtime_cache (dict, optional) – A dict-like interface to a cache object. This cache is expected to last the +duration of the program only, and will be used to hold references to materialized +awkward arrays, etc.

  • +
  • persistent_cache (dict, optional) – A dict-like interface to a cache object. Only bare numpy arrays will be placed in this cache, +using globally-unique keys.

  • +
  • schemaclass (BaseSchema) – A schema class deriving from BaseSchema and implementing the desired view of the file

  • +
  • metadata (dict, optional) – Arbitrary metadata to add to the base.NanoEvents object

  • +
  • uproot_options (dict, optional) – Any options to pass to uproot.open

  • +
  • access_log (list, optional) – Pass a list instance to record which branches were lazily accessed by this instance

  • +
+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.PDUNESchema.html b/api/coffea.nanoevents.PDUNESchema.html new file mode 100644 index 000000000..88f64e95f --- /dev/null +++ b/api/coffea.nanoevents.PDUNESchema.html @@ -0,0 +1,184 @@ + + + + + + + + + PDUNESchema — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

PDUNESchema

+
+
+class coffea.nanoevents.PDUNESchema(base_form)[source]
+

Bases: BaseSchema

+

Attributes Summary

+ + + + + + + + + + + + +

behavior

Behaviors necessary to implement this schema

mixins

top_objects

+

Attributes Documentation

+
+
+behavior
+

Behaviors necessary to implement this schema

+
+ +
+
+mixins = {'RecoBeam': 'Beam', 'Showers': 'Showers', 'Tracks': 'Tracks', 'end3D': 'ThreeVector', 'end4D': 'LorentzVector', 'reco_beam': 'RecoBeam', 'reco_daughter_allShower': 'Showers', 'reco_daughter_allTrack': 'Tracks', 'start3D': 'ThreeVector', 'start4D': 'LorentzVector', 'vtx3D': 'ThreeVector'}
+
+ +
+
+top_objects = {'reco_beam': 'RecoBeam', 'reco_daughter_allShower': 'Showers', 'reco_daughter_allTrack': 'Tracks', 'true_beam': 'TrueBeam'}
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.PFNanoAODSchema.html b/api/coffea.nanoevents.PFNanoAODSchema.html new file mode 100644 index 000000000..253d1082f --- /dev/null +++ b/api/coffea.nanoevents.PFNanoAODSchema.html @@ -0,0 +1,183 @@ + + + + + + + + + PFNanoAODSchema — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

PFNanoAODSchema

+
+
+class coffea.nanoevents.PFNanoAODSchema(base_form, version='latest')[source]
+

Bases: NanoAODSchema

+

PFNano schema builder

+

PFNano is an extended NanoAOD format that includes PF candidates and secondary vertices +More info at https://github.com/cms-jet/PFNano

+

Attributes Summary

+ + + + + + + + + +

all_cross_references

Cross-references, where an index is to be interpreted with respect to another collection

mixins

Default configuration for mixin types, based on the collection name.

+

Attributes Documentation

+
+
+all_cross_references = {'Electron_genPartIdx': 'GenPart', 'Electron_jetIdx': 'Jet', 'Electron_photonIdx': 'Photon', 'FatJetPFCands_jetIdx': 'FatJet', 'FatJetPFCands_pFCandsIdx': 'PFCands', 'FatJetSVs_jetIdx': 'FatJet', 'FatJetSVs_sVIdx': 'SV', 'FatJet_electronIdx3SJ': 'Electron', 'FatJet_genJetAK8Idx': 'GenJetAK8', 'FatJet_muonIdx3SJ': 'Muon', 'FatJet_subJetIdx1': 'SubJet', 'FatJet_subJetIdx2': 'SubJet', 'FsrPhoton_muonIdx': 'Muon', 'GenFatJetCands_jetIdx': 'GenJetAK8', 'GenFatJetCands_pFCandsIdx': 'GenCands', 'GenFatJetSVs_jetIdx': 'GenJetAK8', 'GenFatJetSVs_sVIdx': 'SV', 'GenJetCands_jetIdx': 'GenJet', 'GenJetCands_pFCandsIdx': 'GenCands', 'GenJetSVs_jetIdx': 'GenJet', 'GenJetSVs_sVIdx': 'SV', 'GenPart_genPartIdxMother': 'GenPart', 'GenVisTau_genPartIdxMother': 'GenPart', 'JetPFCands_jetIdx': 'Jet', 'JetPFCands_pFCandsIdx': 'PFCands', 'JetSVs_jetIdx': 'Jet', 'JetSVs_sVIdx': 'SV', 'Jet_electronIdx1': 'Electron', 'Jet_electronIdx2': 'Electron', 'Jet_genJetIdx': 'GenJet', 'Jet_muonIdx1': 'Muon', 'Jet_muonIdx2': 'Muon', 'LowPtElectron_electronIdx': 'Electron', 'LowPtElectron_genPartIdx': 'GenPart', 'LowPtElectron_photonIdx': 'Photon', 'Muon_fsrPhotonIdx': 'FsrPhoton', 'Muon_genPartIdx': 'GenPart', 'Muon_jetIdx': 'Jet', 'Photon_electronIdx': 'Electron', 'Photon_genPartIdx': 'GenPart', 'Photon_jetIdx': 'Jet', 'SubJet_subGenJetAK8Idx': 'SubGenJetAK8', 'Tau_genPartIdx': 'GenPart', 'Tau_jetIdx': 'Jet'}
+

Cross-references, where an index is to be interpreted with respect to another collection

+

Each such cross-reference will be converted to a global indexer, so that arbitrarily sliced events +can still resolve the indirection back the parent events

+
+ +
+
+mixins = {'CaloMET': 'MissingET', 'ChsMET': 'MissingET', 'Electron': 'Electron', 'FatJet': 'FatJet', 'FatJetPFCands': 'AssociatedPFCand', 'FatJetSVs': 'AssociatedSV', 'FsrPhoton': 'FsrPhoton', 'GenCands': 'PFCand', 'GenDressedLepton': 'PtEtaPhiMCollection', 'GenFatJetCands': 'AssociatedPFCand', 'GenFatJetSVs': 'AssociatedSV', 'GenIsolatedPhoton': 'PtEtaPhiMCollection', 'GenJet': 'PtEtaPhiMCollection', 'GenJetAK8': 'PtEtaPhiMCollection', 'GenJetCands': 'AssociatedPFCand', 'GenJetSVs': 'AssociatedSV', 'GenMET': 'MissingET', 'GenPart': 'GenParticle', 'GenVisTau': 'GenVisTau', 'IsoTrack': 'PtEtaPhiMCollection', 'Jet': 'Jet', 'JetPFCands': 'AssociatedPFCand', 'JetSVs': 'AssociatedSV', 'LHEPart': 'PtEtaPhiMCollection', 'LowPtElectron': 'LowPtElectron', 'MET': 'MissingET', 'METFixEE2017': 'MissingET', 'Muon': 'Muon', 'PFCands': 'PFCand', 'PV': 'Vertex', 'Photon': 'Photon', 'PuppiMET': 'MissingET', 'RawMET': 'MissingET', 'RawPuppiMET': 'MissingET', 'SV': 'SecondaryVertex', 'SoftActivityJet': 'PtEtaPhiMCollection', 'SubGenJetAK8': 'PtEtaPhiMCollection', 'SubJet': 'PtEtaPhiMCollection', 'Tau': 'Tau', 'TkMET': 'MissingET', 'TrigObj': 'PtEtaPhiMCollection'}
+

Default configuration for mixin types, based on the collection name.

+

The types are implemented in the coffea.nanoevents.methods.nanoaod module.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.PHYSLITESchema.html b/api/coffea.nanoevents.PHYSLITESchema.html new file mode 100644 index 000000000..f57d726a3 --- /dev/null +++ b/api/coffea.nanoevents.PHYSLITESchema.html @@ -0,0 +1,201 @@ + + + + + + + + + PHYSLITESchema — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

PHYSLITESchema

+
+
+class coffea.nanoevents.PHYSLITESchema(base_form)[source]
+

Bases: BaseSchema

+

PHYSLITE schema builder - work in progress.

+

This is a schema for the ATLAS DAOD_PHYSLITE derivation. +Closely following schemas.nanoaod.NanoAODSchema, it is mainly build from +naming patterns where the “Analysis” prefix has been removed, so the +collections will be named Electrons, Muons, instead of AnalysisElectrons, +AnalysisMunos, etc. The collection fields correspond to the “Aux” and +“AuxDyn” columns.

+

Collections are assigned mixin types according to the mixins mapping. +All collections are then zipped into one base.NanoEvents record and returned.

+

Cross references are build from ElementLink columns. Global indices are +created dynamically, using an _eventindex field that is attached to +each collection.

+

Attributes Summary

+ + + + + + + + + + + + +

behavior

Behaviors necessary to implement this schema

mixins

Default configuration for mixin types, based on the collection name.

truth_collections

TRUTH3 collection names.

+

Attributes Documentation

+
+
+behavior
+

Behaviors necessary to implement this schema

+
+ +
+
+mixins = {'CombinedMuonTrackParticles': 'TrackParticle', 'Electrons': 'Electron', 'ExtrapolatedMuonTrackParticles': 'TrackParticle', 'GSFTrackParticles': 'TrackParticle', 'InDetTrackParticles': 'TrackParticle', 'Jets': 'Particle', 'MuonSpectrometerTrackParticles': 'TrackParticle', 'Muons': 'Muon', 'TauJets': 'Particle', 'TruthBoson': 'TruthParticle', 'TruthBottom': 'TruthParticle', 'TruthElectrons': 'TruthParticle', 'TruthMuons': 'TruthParticle', 'TruthNeutrinos': 'TruthParticle', 'TruthPhotons': 'TruthParticle', 'TruthTaus': 'TruthParticle', 'TruthTop': 'TruthParticle'}
+

Default configuration for mixin types, based on the collection name.

+

The types are implemented in the coffea.nanoevents.methods.physlite module.

+
+ +
+
+truth_collections = ['TruthPhotons', 'TruthMuons', 'TruthNeutrinos', 'TruthTaus', 'TruthElectrons', 'TruthBoson', 'TruthBottom', 'TruthTop']
+

TRUTH3 collection names.

+

TruthParticle behavior is assigned to all of them and global index forms +for parent/children relations are created for all combinations.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.TreeMakerSchema.html b/api/coffea.nanoevents.TreeMakerSchema.html new file mode 100644 index 000000000..c6009ea1e --- /dev/null +++ b/api/coffea.nanoevents.TreeMakerSchema.html @@ -0,0 +1,219 @@ + + + + + + + + + TreeMakerSchema — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

TreeMakerSchema

+
+
+class coffea.nanoevents.TreeMakerSchema(base_form)[source]
+

Bases: BaseSchema

+

TreeMaker schema builder

+

The TreeMaker schema is built from all branches found in the supplied file, +based on the naming pattern of the branches. There are two steps of to the +generation of array collections:

+
    +
  • Objects with vector-like quantities (momentum, coordinate points) in the +TreeMaker n-tuples are stored using ROOT PtEtaPhiEVectors and XYZPoint +classes with maximum TTree splitting. These variable branches are grouped +into a single collection with the original object name, with the +corresponding coordinate variables names mapped to the standard variable +names for coffea.nanoevents.methods.vector behaviors. For example: +- The “Jets” branch in a TreeMaker n-tuple branch stores ‘PtEtaPhiEVector’s

    +
    +

    corresponding to the momentum of AK4 jets. The resulting collection after +this first step would contain the vector variables in the form of +Jets.pt, Jets.eta, Jets.phi, Jets.energy, and addition vector quantities +(px) can be accessed via the usual vector behavior methods.

    +
    +
      +
    • The “PrimaryVertices” branch in a TreeMaker n-tuple branch stores +‘XYZPoint’s corresponding to the coordinates of the primary vertices, The +resulting collection after this first step wold contain the coordinate +variables in the form of PrimaryVertices.x, PrimaryVertices.y, +PrimaryVertices.z.

    • +
    +
  • +
  • Extended quantities of physic objects are stored in the format +<Object>_<variable>, such as “Jets_jecFactor”. Such variables will be +merged into the collection <Object>, so the branch “Jets_jetFactor” will be +access to in the array format as “Jets.jecFactor”. An exception to the

  • +
+

All collections are then zipped into one base.NanoEvents record and +returned.

+

Attributes Summary

+ + + + + + +

behavior

Behaviors necessary to implement this schema

+

Methods Summary

+ + + + + + +

uproot_writeable()

Converting a TreeMakerSchema event into something that is uproot writeable.

+

Attributes Documentation

+
+
+behavior
+

Behaviors necessary to implement this schema

+
+ +

Methods Documentation

+
+
+classmethod uproot_writeable()[source]
+

Converting a TreeMakerSchema event into something that is uproot +writeable. Based off the discussion thread here [1], but added specific +cased to handled the nested structures define for TreeMaker n-tuples. +[1] https://github.com/CoffeaTeam/coffea/discussions/735

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.base.NanoCollection.html b/api/coffea.nanoevents.methods.base.NanoCollection.html new file mode 100644 index 000000000..d27706a94 --- /dev/null +++ b/api/coffea.nanoevents.methods.base.NanoCollection.html @@ -0,0 +1,151 @@ + + + + + + + + + NanoCollection — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

NanoCollection

+
+
+class coffea.nanoevents.methods.base.NanoCollection[source]
+

Bases: object

+

A NanoEvents collection

+

This mixin provides some helper methods useful for creating cross-references +and other advanced mixin types.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.base.NanoEvents.html b/api/coffea.nanoevents.methods.base.NanoEvents.html new file mode 100644 index 000000000..0f239f6e8 --- /dev/null +++ b/api/coffea.nanoevents.methods.base.NanoEvents.html @@ -0,0 +1,165 @@ + + + + + + + + + NanoEvents — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

NanoEvents

+
+
+class coffea.nanoevents.methods.base.NanoEvents[source]
+

Bases: Systematic

+

NanoEvents mixin class

+

This mixin class is used as the top-level type for NanoEvents objects.

+

Attributes Summary

+ + + + + + +

metadata

Arbitrary metadata

+

Attributes Documentation

+
+
+metadata
+

Arbitrary metadata

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.base.Systematic.html b/api/coffea.nanoevents.methods.base.Systematic.html new file mode 100644 index 000000000..278d34a0f --- /dev/null +++ b/api/coffea.nanoevents.methods.base.Systematic.html @@ -0,0 +1,213 @@ + + + + + + + + + Systematic — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Systematic

+
+
+class coffea.nanoevents.methods.base.Systematic[source]
+

Bases: object

+

A base mixin class to describe and build variations on a feature of an nanoevents object.

+

Attributes Summary

+ + + + + + +

systematics

Return the list of all systematics attached to this object.

+

Methods Summary

+ + + + + + + + + + + + + + + +

add_kind(kind)

Register a type of systematic variation, it must fullfil the base class interface.

add_systematic(name, kind, what, ...)

name: str, name of the systematic variation / uncertainty source kind: str, the name of the kind of systematic variation what: Union[str, List[str], Tuple[str]], name what gets varied, this could be a list or tuple of column names varying_function: Union[function, bound method], a function that describes how 'what' is varied, it must close over all non-event-data arguments.

describe_variations()

returns a list of variation names

explodes_how()

This describes how a systematic uncertainty needs to be evaluated in the context of other systematic uncertainties.

+

Attributes Documentation

+
+
+systematics
+

Return the list of all systematics attached to this object.

+
+ +

Methods Documentation

+
+
+classmethod add_kind(kind: str)[source]
+

Register a type of systematic variation, it must fullfil the base class interface.

+
+ +
+
+add_systematic(name: str, kind: str, what: str | List[str] | Tuple[str], varying_function: Callable)[source]
+

name: str, name of the systematic variation / uncertainty source +kind: str, the name of the kind of systematic variation +what: Union[str, List[str], Tuple[str]], name what gets varied,

+
+

this could be a list or tuple of column names

+
+

varying_function: Union[function, bound method], a function that describes how ‘what’ is varied, it must close over all non-event-data arguments.

+
+ +
+
+abstract describe_variations()[source]
+

returns a list of variation names

+
+ +
+
+abstract explodes_how()[source]
+

This describes how a systematic uncertainty needs to be evaluated in the context of other systematic uncertainties. +i.e. Do you iterate over this keeping all others fixed or do you need to have correlations with other (subsets of) systematics.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.candidate.Candidate.html b/api/coffea.nanoevents.methods.candidate.Candidate.html new file mode 100644 index 000000000..5b333433f --- /dev/null +++ b/api/coffea.nanoevents.methods.candidate.Candidate.html @@ -0,0 +1,174 @@ + + + + + + + + + Candidate — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Candidate

+
+
+class coffea.nanoevents.methods.candidate.Candidate[source]
+

Bases: LorentzVector

+

A Lorentz vector with charge

+

This mixin class requires the parent class to provide items x, y, z, t, and charge.

+

Methods Summary

+ + + + + + + + + +

add(other)

Add two candidates together elementwise using x, y, z, t, and charge components

sum([axis])

Sum an array of vectors elementwise using x, y, z, t, and charge components

+

Methods Documentation

+
+
+add(other)[source]
+

Add two candidates together elementwise using x, y, z, t, and charge components

+
+ +
+
+sum(axis=-1)[source]
+

Sum an array of vectors elementwise using x, y, z, t, and charge components

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.candidate.PtEtaPhiECandidate.html b/api/coffea.nanoevents.methods.candidate.PtEtaPhiECandidate.html new file mode 100644 index 000000000..46d584c22 --- /dev/null +++ b/api/coffea.nanoevents.methods.candidate.PtEtaPhiECandidate.html @@ -0,0 +1,150 @@ + + + + + + + + + PtEtaPhiECandidate — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

PtEtaPhiECandidate

+
+
+class coffea.nanoevents.methods.candidate.PtEtaPhiECandidate[source]
+

Bases: Candidate, PtEtaPhiELorentzVector

+

A Lorentz vector in eta, energy coordinates with charge

+

This mixin class requires the parent class to provide items pt, eta, phi, energy, and charge.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate.html b/api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate.html new file mode 100644 index 000000000..596c03341 --- /dev/null +++ b/api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate.html @@ -0,0 +1,150 @@ + + + + + + + + + PtEtaPhiMCandidate — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

PtEtaPhiMCandidate

+
+
+class coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate[source]
+

Bases: Candidate, PtEtaPhiMLorentzVector

+

A Lorentz vector in eta, mass coordinates with charge

+

This mixin class requires the parent class to provide items pt, eta, phi, mass, and charge.

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.AssociatedPFCand.html b/api/coffea.nanoevents.methods.nanoaod.AssociatedPFCand.html new file mode 100644 index 000000000..789c578db --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.AssociatedPFCand.html @@ -0,0 +1,193 @@ + + + + + + + + + AssociatedPFCand — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

AssociatedPFCand

+
+
+class coffea.nanoevents.methods.nanoaod.AssociatedPFCand[source]
+

Bases: NanoCollection

+

PFNano PF candidate to jet association object

+

Attributes Summary

+ + + + + + + + + + + + +

collection_map

jet

pf

+

Attributes Documentation

+
+
+collection_map = {'FatJetPFCands': ('FatJet', 'PFCands'), 'GenFatJetCands': ('GenJetAK8', 'GenCands'), 'GenJetCands': ('GenJet', 'GenCands'), 'JetPFCands': ('Jet', 'PFCands')}
+
+ +
+
+jet
+
+ +
+
+pf
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.AssociatedSV.html b/api/coffea.nanoevents.methods.nanoaod.AssociatedSV.html new file mode 100644 index 000000000..eea81ae0b --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.AssociatedSV.html @@ -0,0 +1,193 @@ + + + + + + + + + AssociatedSV — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

AssociatedSV

+
+
+class coffea.nanoevents.methods.nanoaod.AssociatedSV[source]
+

Bases: NanoCollection

+

PFNano secondary vertex to jet association object

+

Attributes Summary

+ + + + + + + + + + + + +

collection_map

jet

sv

+

Attributes Documentation

+
+
+collection_map = {'FatJetSVs': ('FatJet', 'SV'), 'GenFatJetSVs': ('GenJetAK8', 'SV'), 'GenJetSVs': ('GenJet', 'SV'), 'JetSVs': ('Jet', 'SV')}
+
+ +
+
+jet
+
+ +
+
+sv
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.Electron.html b/api/coffea.nanoevents.methods.nanoaod.Electron.html new file mode 100644 index 000000000..7aad5e2f4 --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.Electron.html @@ -0,0 +1,274 @@ + + + + + + + + + Electron — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Electron

+
+
+class coffea.nanoevents.methods.nanoaod.Electron[source]
+

Bases: PtEtaPhiMCandidate, NanoCollection, Systematic

+

NanoAOD electron object

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

FAIL

cutBased selection minimum value

LOOSE

cutBased selection minimum value

MEDIUM

cutBased selection minimum value

TIGHT

cutBased selection minimum value

VETO

cutBased selection minimum value

isLoose

Returns a boolean array marking loose cut-based electrons

isMedium

Returns a boolean array marking medium cut-based electrons

isTight

Returns a boolean array marking tight cut-based electrons

isVeto

Returns a boolean array marking veto cut-based electrons

matched_gen

matched_jet

matched_photon

+

Attributes Documentation

+
+
+FAIL = 0
+

cutBased selection minimum value

+
+ +
+
+LOOSE = 2
+

cutBased selection minimum value

+
+ +
+
+MEDIUM = 3
+

cutBased selection minimum value

+
+ +
+
+TIGHT = 4
+

cutBased selection minimum value

+
+ +
+
+VETO = 1
+

cutBased selection minimum value

+
+ +
+
+isLoose
+

Returns a boolean array marking loose cut-based electrons

+
+ +
+
+isMedium
+

Returns a boolean array marking medium cut-based electrons

+
+ +
+
+isTight
+

Returns a boolean array marking tight cut-based electrons

+
+ +
+
+isVeto
+

Returns a boolean array marking veto cut-based electrons

+
+ +
+
+matched_gen
+
+ +
+
+matched_jet
+
+ +
+
+matched_photon
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.FatJet.html b/api/coffea.nanoevents.methods.nanoaod.FatJet.html new file mode 100644 index 000000000..a49f1749a --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.FatJet.html @@ -0,0 +1,247 @@ + + + + + + + + + FatJet — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

FatJet

+
+
+class coffea.nanoevents.methods.nanoaod.FatJet[source]
+

Bases: PtEtaPhiMLorentzVector, NanoCollection, Systematic

+

NanoAOD large radius jet object

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

LOOSE

jetId bit position

TIGHT

jetId bit position

TIGHTLEPVETO

jetId bit position

constituents

isLoose

Returns a boolean array marking loose jets according to jetId index

isTight

Returns a boolean array marking tight jets according to jetId index

isTightLeptonVeto

Returns a boolean array marking tight jets with explicit lepton veto according to jetId index

matched_gen

subjets

+

Attributes Documentation

+
+
+LOOSE = 0
+

jetId bit position

+
+ +
+
+TIGHT = 1
+

jetId bit position

+
+ +
+
+TIGHTLEPVETO = 2
+

jetId bit position

+
+ +
+
+constituents
+
+ +
+
+isLoose
+

Returns a boolean array marking loose jets according to jetId index

+
+ +
+
+isTight
+

Returns a boolean array marking tight jets according to jetId index

+
+ +
+
+isTightLeptonVeto
+

Returns a boolean array marking tight jets with explicit lepton veto according to jetId index

+
+ +
+
+matched_gen
+
+ +
+
+subjets
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.FsrPhoton.html b/api/coffea.nanoevents.methods.nanoaod.FsrPhoton.html new file mode 100644 index 000000000..74f3037e2 --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.FsrPhoton.html @@ -0,0 +1,177 @@ + + + + + + + + + FsrPhoton — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

FsrPhoton

+
+
+class coffea.nanoevents.methods.nanoaod.FsrPhoton[source]
+

Bases: PtEtaPhiMCandidate, NanoCollection

+

NanoAOD fsr photon object

+

Attributes Summary

+ + + + + + +

matched_muon

+

Attributes Documentation

+
+
+matched_muon
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.GenParticle.html b/api/coffea.nanoevents.methods.nanoaod.GenParticle.html new file mode 100644 index 000000000..ceff21f4b --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.GenParticle.html @@ -0,0 +1,248 @@ + + + + + + + + + GenParticle — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

GenParticle

+
+
+class coffea.nanoevents.methods.nanoaod.GenParticle[source]
+

Bases: PtEtaPhiMLorentzVector, NanoCollection

+

NanoAOD generator-level particle object, including parent and child self-references

+

Parent and child self-references are constructed from the genPartIdxMother column, where +for each entry, the mother entry index is recorded, or -1 if no mother exists.

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + +

FLAGS

bit-packed statusFlags interpretations.

children

Accessor to child particles.

distinctChildren

Accessor to distinct (different PDG id) child particles

distinctChildrenDeep

Accessor to distinct child particles with different PDG id, or last ones in the chain

distinctParent

Accessor to distinct (different PDG id) parent particle

parent

Accessor to the parent particle

+

Methods Summary

+ + + + + + +

hasFlags(*flags)

Check if one or more status flags are set

+

Attributes Documentation

+
+
+FLAGS = ['isPrompt', 'isDecayedLeptonHadron', 'isTauDecayProduct', 'isPromptTauDecayProduct', 'isDirectTauDecayProduct', 'isDirectPromptTauDecayProduct', 'isDirectHadronDecayProduct', 'isHardProcess', 'fromHardProcess', 'isHardProcessTauDecayProduct', 'isDirectHardProcessTauDecayProduct', 'fromHardProcessBeforeFSR', 'isFirstCopy', 'isLastCopy', 'isLastCopyBeforeFSR']
+

bit-packed statusFlags interpretations. Use GenParticle.hasFlags to query

+
+ +
+
+children
+

Accessor to child particles.

+
+ +
+
+distinctChildren
+

Accessor to distinct (different PDG id) child particles

+
+ +
+
+distinctChildrenDeep
+

Accessor to distinct child particles with different PDG id, or last ones in the chain

+
+ +
+
+distinctParent
+

Accessor to distinct (different PDG id) parent particle

+
+ +
+
+parent
+

Accessor to the parent particle

+
+ +

Methods Documentation

+
+
+hasFlags(*flags)[source]
+

Check if one or more status flags are set

+
+
Parameters:
+

flags (str or list) – A list of flags that are required to be set true. If the first argument +is a list, it is expanded and subsequent arguments ignored. +Possible flags are enumerated in the FLAGS attribute

+
+
+

Returns a boolean array

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.GenVisTau.html b/api/coffea.nanoevents.methods.nanoaod.GenVisTau.html new file mode 100644 index 000000000..f2774cb13 --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.GenVisTau.html @@ -0,0 +1,178 @@ + + + + + + + + + GenVisTau — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

GenVisTau

+
+
+class coffea.nanoevents.methods.nanoaod.GenVisTau[source]
+

Bases: PtEtaPhiMCandidate, NanoCollection

+

NanoAOD visible tau object

+

Attributes Summary

+ + + + + + +

parent

Accessor to the parent particle

+

Attributes Documentation

+
+
+parent
+

Accessor to the parent particle

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.Jet.html b/api/coffea.nanoevents.methods.nanoaod.Jet.html new file mode 100644 index 000000000..c5d84aa92 --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.Jet.html @@ -0,0 +1,255 @@ + + + + + + + + + Jet — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Jet

+
+
+class coffea.nanoevents.methods.nanoaod.Jet[source]
+

Bases: PtEtaPhiMLorentzVector, NanoCollection, Systematic

+

NanoAOD narrow radius jet object

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

LOOSE

jetId bit position

TIGHT

jetId bit position

TIGHTLEPVETO

jetId bit position

constituents

isLoose

Returns a boolean array marking loose jets according to jetId index

isTight

Returns a boolean array marking tight jets according to jetId index

isTightLeptonVeto

Returns a boolean array marking tight jets with explicit lepton veto according to jetId index

matched_electrons

matched_gen

matched_muons

+

Attributes Documentation

+
+
+LOOSE = 0
+

jetId bit position

+
+ +
+
+TIGHT = 1
+

jetId bit position

+
+ +
+
+TIGHTLEPVETO = 2
+

jetId bit position

+
+ +
+
+constituents
+
+ +
+
+isLoose
+

Returns a boolean array marking loose jets according to jetId index

+
+ +
+
+isTight
+

Returns a boolean array marking tight jets according to jetId index

+
+ +
+
+isTightLeptonVeto
+

Returns a boolean array marking tight jets with explicit lepton veto according to jetId index

+
+ +
+
+matched_electrons
+
+ +
+
+matched_gen
+
+ +
+
+matched_muons
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.LowPtElectron.html b/api/coffea.nanoevents.methods.nanoaod.LowPtElectron.html new file mode 100644 index 000000000..b4d0dc27c --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.LowPtElectron.html @@ -0,0 +1,193 @@ + + + + + + + + + LowPtElectron — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

LowPtElectron

+
+
+class coffea.nanoevents.methods.nanoaod.LowPtElectron[source]
+

Bases: PtEtaPhiMCandidate, NanoCollection, Systematic

+

NanoAOD low-pt electron object

+

Attributes Summary

+ + + + + + + + + + + + +

matched_electron

matched_gen

matched_photon

+

Attributes Documentation

+
+
+matched_electron
+
+ +
+
+matched_gen
+
+ +
+
+matched_photon
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.MissingET.html b/api/coffea.nanoevents.methods.nanoaod.MissingET.html new file mode 100644 index 000000000..0a6993292 --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.MissingET.html @@ -0,0 +1,177 @@ + + + + + + + + + MissingET — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

MissingET

+
+
+class coffea.nanoevents.methods.nanoaod.MissingET[source]
+

Bases: PolarTwoVector, NanoCollection, Systematic

+

NanoAOD Missing transverse energy object

+

Attributes Summary

+ + + + + + +

r

Distance from origin in XY plane

+

Attributes Documentation

+
+
+r
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.Muon.html b/api/coffea.nanoevents.methods.nanoaod.Muon.html new file mode 100644 index 000000000..10848f7d1 --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.Muon.html @@ -0,0 +1,193 @@ + + + + + + + + + Muon — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Muon

+
+
+class coffea.nanoevents.methods.nanoaod.Muon[source]
+

Bases: PtEtaPhiMCandidate, NanoCollection, Systematic

+

NanoAOD muon object

+

Attributes Summary

+ + + + + + + + + + + + +

matched_fsrPhoton

matched_gen

matched_jet

+

Attributes Documentation

+
+
+matched_fsrPhoton
+
+ +
+
+matched_gen
+
+ +
+
+matched_jet
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.PFCand.html b/api/coffea.nanoevents.methods.nanoaod.PFCand.html new file mode 100644 index 000000000..959ef5ebc --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.PFCand.html @@ -0,0 +1,163 @@ + + + + + + + + + PFCand — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.Photon.html b/api/coffea.nanoevents.methods.nanoaod.Photon.html new file mode 100644 index 000000000..85e69d246 --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.Photon.html @@ -0,0 +1,272 @@ + + + + + + + + + Photon — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Photon

+
+
+class coffea.nanoevents.methods.nanoaod.Photon[source]
+

Bases: PtEtaPhiMCandidate, NanoCollection, Systematic

+

NanoAOD photon object

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

FAIL

cutBased selection minimum value

LOOSE

cutBased selection minimum value

MEDIUM

cutBased selection minimum value

TIGHT

cutBased selection minimum value

charge

isLoose

Returns a boolean array marking loose cut-based photons

isMedium

Returns a boolean array marking medium cut-based photons

isTight

Returns a boolean array marking tight cut-based photons

mass

Invariant mass (+, -, -, -)

matched_electron

matched_gen

matched_jet

+

Attributes Documentation

+
+
+FAIL = 0
+

cutBased selection minimum value

+
+ +
+
+LOOSE = 1
+

cutBased selection minimum value

+
+ +
+
+MEDIUM = 2
+

cutBased selection minimum value

+
+ +
+
+TIGHT = 3
+

cutBased selection minimum value

+
+ +
+
+charge
+
+ +
+
+isLoose
+

Returns a boolean array marking loose cut-based photons

+
+ +
+
+isMedium
+

Returns a boolean array marking medium cut-based photons

+
+ +
+
+isTight
+

Returns a boolean array marking tight cut-based photons

+
+ +
+
+mass
+
+ +
+
+matched_electron
+
+ +
+
+matched_gen
+
+ +
+
+matched_jet
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection.html b/api/coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection.html new file mode 100644 index 000000000..044aa1867 --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection.html @@ -0,0 +1,163 @@ + + + + + + + + + PtEtaPhiMCollection — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

PtEtaPhiMCollection

+
+
+class coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection[source]
+

Bases: PtEtaPhiMLorentzVector, NanoCollection

+

Generic collection that has Lorentz vector properties

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.SecondaryVertex.html b/api/coffea.nanoevents.methods.nanoaod.SecondaryVertex.html new file mode 100644 index 000000000..33ebca182 --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.SecondaryVertex.html @@ -0,0 +1,178 @@ + + + + + + + + + SecondaryVertex — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

SecondaryVertex

+
+
+class coffea.nanoevents.methods.nanoaod.SecondaryVertex[source]
+

Bases: Vertex

+

NanoAOD secondary vertex object

+

Attributes Summary

+ + + + + + +

p4

4-momentum vector of tracks associated to this SV

+

Attributes Documentation

+
+
+p4
+

4-momentum vector of tracks associated to this SV

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.Tau.html b/api/coffea.nanoevents.methods.nanoaod.Tau.html new file mode 100644 index 000000000..b4b6fab1b --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.Tau.html @@ -0,0 +1,185 @@ + + + + + + + + + Tau — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Tau

+
+
+class coffea.nanoevents.methods.nanoaod.Tau[source]
+

Bases: PtEtaPhiMCandidate, NanoCollection, Systematic

+

NanoAOD tau object

+

Attributes Summary

+ + + + + + + + + +

matched_gen

matched_jet

+

Attributes Documentation

+
+
+matched_gen
+
+ +
+
+matched_jet
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.nanoaod.Vertex.html b/api/coffea.nanoevents.methods.nanoaod.Vertex.html new file mode 100644 index 000000000..df29638ef --- /dev/null +++ b/api/coffea.nanoevents.methods.nanoaod.Vertex.html @@ -0,0 +1,178 @@ + + + + + + + + + Vertex — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Vertex

+
+
+class coffea.nanoevents.methods.nanoaod.Vertex[source]
+

Bases: NanoCollection

+

NanoAOD vertex object

+

Attributes Summary

+ + + + + + +

pos

Vertex position as a three vector

+

Attributes Documentation

+
+
+pos
+

Vertex position as a three vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.vector.LorentzVector.html b/api/coffea.nanoevents.methods.vector.LorentzVector.html new file mode 100644 index 000000000..d76628d26 --- /dev/null +++ b/api/coffea.nanoevents.methods.vector.LorentzVector.html @@ -0,0 +1,362 @@ + + + + + + + + + LorentzVector — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

LorentzVector

+
+
+class coffea.nanoevents.methods.vector.LorentzVector[source]
+

Bases: ThreeVector

+

A cartesian Lorentz vector

+

A heavy emphasis towards a momentum vector interpretation is assumed. +(+, -, -, -) metric +This mixin class requires the parent class to provide items x, y, z, and t.

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + +

boostvec

The x, y and z compontents divided by t as a ThreeVector

energy

Alias for t

eta

Pseudorapidity

mass

Invariant mass (+, -, -, -)

mass2

Squared mass

pvec

The x, y and z compontents as a ThreeVector

+

Methods Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

absolute()

Magnitude of this Lorentz vector

add(other)

Add two vectors together elementwise using x, y, z, and t components

boost(other)

Apply a Lorentz boost given by the ThreeVector other and return it

delta_r(other)

Distance between two Lorentz vectors in (eta,phi) plane

delta_r2(other)

Squared delta_r

metric_table(other[, axis, metric, ...])

Return a list of a metric evaluated between this object and another.

multiply(other)

Multiply this vector by a scalar elementwise using x, y, z, and t components

nearest(other[, axis, metric, ...])

Return nearest object to this one

negative()

Returns the negative of the vector

subtract(other)

Subtract a vector from another elementwise using x, y, z, and t components

sum([axis])

Sum an array of vectors elementwise using x, y, z, and t components

+

Attributes Documentation

+
+
+boostvec
+

The x, y and z compontents divided by t as a ThreeVector

+

This can be used for boosting. For cases where |t| <= rho, this +returns the unit vector.

+
+ +
+
+energy
+

Alias for t

+
+ +
+
+eta
+

Pseudorapidity

+

\(-\ln[\tan(\theta/2)] = \text{arcsinh}(z/r)\)

+
+ +
+
+mass
+

Invariant mass (+, -, -, -)

+

\(\sqrt{t^2-x^2-y^2-z^2}\)

+
+ +
+
+mass2
+

Squared mass

+
+ +
+
+pvec
+

The x, y and z compontents as a ThreeVector

+
+ +

Methods Documentation

+
+
+absolute()[source]
+

Magnitude of this Lorentz vector

+

Alias for mass

+
+ +
+
+add(other)[source]
+

Add two vectors together elementwise using x, y, z, and t components

+
+ +
+
+boost(other)[source]
+

Apply a Lorentz boost given by the ThreeVector other and return it

+

Note that this follows the convention that, for example in order to boost +a vector into its own rest frame, one needs to use the negative of its boostvec

+
+ +
+
+delta_r(other)[source]
+

Distance between two Lorentz vectors in (eta,phi) plane

+

\(\sqrt{\Delta\eta^2 + \Delta\phi^2}\)

+
+ +
+
+delta_r2(other)[source]
+

Squared delta_r

+
+ +
+
+metric_table(other, axis=1, metric=<function LorentzVector.<lambda>>, return_combinations=False)[source]
+

Return a list of a metric evaluated between this object and another.

+

The two arrays should be broadcast-compatible on all axes other than the specified +axis, which will be used to form a cartesian product. If axis=None, broadcast arrays directly. +The return shape will be that of self with a new axis with shape of other appended +at the specified axis depths.

+
+
Parameters:
+
    +
  • other (awkward.Array) – Another array with same shape in all but axis

  • +
  • axis (int, optional) – The axis to form the cartesian product (default 1). If None, the metric +is directly evaluated on the input arrays (i.e. they should broadcast)

  • +
  • metric (callable) – A function of two arguments, returning a scalar. The default metric is delta_r.

  • +
  • return_combinations (bool) – If True return the combinations of inputs as well as an unzipped tuple

  • +
+
+
+
+ +
+
+multiply(other)[source]
+

Multiply this vector by a scalar elementwise using x, y, z, and t components

+
+ +
+
+nearest(other, axis=1, metric=<function LorentzVector.<lambda>>, return_metric=False, threshold=None)[source]
+

Return nearest object to this one

+

Finds item in other satisfying min(metric(self, other)). +The two arrays should be broadcast-compatible on all axes other than the specified +axis, which will be used to form a cartesian product. If axis=None, broadcast arrays directly. +The return shape will be that of self.

+
+
Parameters:
+
    +
  • other (awkward.Array) – Another array with same shape in all but axis

  • +
  • axis (int, optional) – The axis to form the cartesian product (default 1). If None, the metric +is directly evaluated on the input arrays (i.e. they should broadcast)

  • +
  • metric (callable) – A function of two arguments, returning a scalar. The default metric is delta_r.

  • +
  • return_metric (bool, optional) – If true, return both the closest object and its metric (default false)

  • +
  • threshold (Number, optional) – If set, any objects with metric > threshold will be masked from the result

  • +
+
+
+
+ +
+
+negative()[source]
+

Returns the negative of the vector

+
+ +
+
+subtract(other)[source]
+

Subtract a vector from another elementwise using x, y, z, and t components

+
+ +
+
+sum(axis=-1)[source]
+

Sum an array of vectors elementwise using x, y, z, and t components

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.vector.PolarTwoVector.html b/api/coffea.nanoevents.methods.vector.PolarTwoVector.html new file mode 100644 index 000000000..7263ca987 --- /dev/null +++ b/api/coffea.nanoevents.methods.vector.PolarTwoVector.html @@ -0,0 +1,237 @@ + + + + + + + + + PolarTwoVector — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

PolarTwoVector

+
+
+class coffea.nanoevents.methods.vector.PolarTwoVector[source]
+

Bases: TwoVector

+

A polar coordinate 2-dimensional vector

+

This mixin class requires the parent class to provide items r and phi. +Some additional properties are overridden for performance

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + +

phi

Azimuthal angle relative to X axis in XY plane

r

Distance from origin in XY plane

r2

Squared r

x

Cartesian x value

y

Cartesian y value

+

Methods Summary

+ + + + + + + + + +

multiply(other)

Multiply this vector by a scalar elementwise using using x and y components

negative()

Returns the negative of the vector

+

Attributes Documentation

+
+
+phi
+

Azimuthal angle relative to X axis in XY plane

+

\(\text{arctan2}(y, x)\)

+
+ +
+
+r
+

Distance from origin in XY plane

+

\(\sqrt{x^2+y^2}\)

+
+ +
+
+r2
+

Squared r

+
+ +
+
+x
+

Cartesian x value

+

\(r \cos{\phi}\)

+
+ +
+
+y
+

Cartesian y value

+

\(r \sin{\phi}\)

+
+ +

Methods Documentation

+
+
+multiply(other)[source]
+

Multiply this vector by a scalar elementwise using using x and y components

+

In reality, this directly adjusts r and phi for performance

+
+ +
+
+negative()[source]
+

Returns the negative of the vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.html b/api/coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.html new file mode 100644 index 000000000..067db45c8 --- /dev/null +++ b/api/coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.html @@ -0,0 +1,294 @@ + + + + + + + + + PtEtaPhiELorentzVector — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

PtEtaPhiELorentzVector

+
+
+class coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector[source]
+

Bases: LorentzVector, SphericalThreeVector

+

A Lorentz vector using pseudorapidity and energy

+

This mixin class requires the parent class to provide items pt, eta, phi, and energy. +Some additional properties are overridden for performance

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

E

Alias for t

energy

Alias for t

eta

Pseudorapidity

phi

Azimuthal angle relative to X axis in XY plane

pt

Alias for r

r

Distance from origin in XY plane

rho

Distance from origin in 3D

rho2

Squared rho

t

Cartesian time component

theta

Inclination angle from XY plane

z

Cartesian z value

+

Methods Summary

+ + + + + + + + + +

multiply(other)

Multiply this vector by a scalar elementwise using x, y, z, and t components

negative()

Returns the negative of the vector

+

Attributes Documentation

+
+
+E
+

Alias for t

+
+ +
+
+energy
+

Alias for t

+
+ +
+
+eta
+

Pseudorapidity

+

\(-\ln\tan(\theta/2) = \text{arcsinh}(z/r)\)

+
+ +
+
+phi
+

Azimuthal angle relative to X axis in XY plane

+

\(\text{arctan2}(y, x)\)

+
+ +
+
+pt
+

Alias for r

+
+ +
+
+r
+

Distance from origin in XY plane

+

\(\sqrt{x^2+y^2} = \rho \sin(\theta)\)

+
+ +
+
+rho
+

Distance from origin in 3D

+

\(\sqrt{x^2+y^2+z^2} = \sqrt{r^2+z^2}\)

+
+ +
+
+rho2
+

Squared rho

+
+ +
+
+t
+

Cartesian time component

+

\(\sqrt{\rho^2+m^2}\)

+
+ +
+
+theta
+

Inclination angle from XY plane

+

\(\text{arctan2}(r, z) = 2\text{arctan}(e^{-\eta})\)

+
+ +
+
+z
+

Cartesian z value

+

\(r \sinh(\eta)\)

+
+ +

Methods Documentation

+
+
+multiply(other)[source]
+

Multiply this vector by a scalar elementwise using x, y, z, and t components

+

In reality, this directly adjusts pt, eta, phi and energy for performance

+
+ +
+
+negative()[source]
+

Returns the negative of the vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.html b/api/coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.html new file mode 100644 index 000000000..743ddea03 --- /dev/null +++ b/api/coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.html @@ -0,0 +1,304 @@ + + + + + + + + + PtEtaPhiMLorentzVector — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

PtEtaPhiMLorentzVector

+
+
+class coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector[source]
+

Bases: LorentzVector, SphericalThreeVector

+

A Lorentz vector using pseudorapidity and mass

+

This mixin class requires the parent class to provide items pt, eta, phi, and mass. +Some additional properties are overridden for performance

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

E

Alias for t

eta

Pseudorapidity

mass

Invariant mass (+, -, -, -)

mass2

Squared mass

phi

Azimuthal angle relative to X axis in XY plane

pt

Alias for r

r

Distance from origin in XY plane

rho

Distance from origin in 3D

rho2

Squared rho

t

Cartesian time component

theta

Inclination angle from XY plane

z

Cartesian z value

+

Methods Summary

+ + + + + + + + + +

multiply(other)

Multiply this vector by a scalar elementwise using x, y, z, and t components

negative()

Returns the negative of the vector

+

Attributes Documentation

+
+
+E
+

Alias for t

+
+ +
+
+eta
+

Pseudorapidity

+

\(-\ln\tan(\theta/2) = \text{arcsinh}(z/r)\)

+
+ +
+
+mass
+

Invariant mass (+, -, -, -)

+

\(\sqrt{t^2-x^2-y^2-z^2}\)

+
+ +
+
+mass2
+

Squared mass

+
+ +
+
+phi
+

Azimuthal angle relative to X axis in XY plane

+

\(\text{arctan2}(y, x)\)

+
+ +
+
+pt
+

Alias for r

+
+ +
+
+r
+

Distance from origin in XY plane

+

\(\sqrt{x^2+y^2} = \rho \sin(\theta)\)

+
+ +
+
+rho
+

Distance from origin in 3D

+

\(\sqrt{x^2+y^2+z^2} = \sqrt{r^2+z^2}\)

+
+ +
+
+rho2
+

Squared rho

+
+ +
+
+t
+

Cartesian time component

+

\(\sqrt{\rho^2+m^2}\)

+
+ +
+
+theta
+

Inclination angle from XY plane

+

\(\text{arctan2}(r, z) = 2\text{arctan}(e^{-\eta})\)

+
+ +
+
+z
+

Cartesian z value

+

\(\rho \cos(\theta) = r \sinh(\eta)\)

+
+ +

Methods Documentation

+
+
+multiply(other)[source]
+

Multiply this vector by a scalar elementwise using x, y, z, and t components

+

In reality, this directly adjusts pt, eta, phi and mass for performance

+
+ +
+
+negative()[source]
+

Returns the negative of the vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.vector.SphericalThreeVector.html b/api/coffea.nanoevents.methods.vector.SphericalThreeVector.html new file mode 100644 index 000000000..3197da330 --- /dev/null +++ b/api/coffea.nanoevents.methods.vector.SphericalThreeVector.html @@ -0,0 +1,246 @@ + + + + + + + + + SphericalThreeVector — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

SphericalThreeVector

+
+
+class coffea.nanoevents.methods.vector.SphericalThreeVector[source]
+

Bases: ThreeVector, PolarTwoVector

+

A spherical coordinate 3-dimensional vector

+

This mixin class requires the parent class to provide items rho, theta, and phi. +Some additional properties are overridden for performance

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + +

p

Alias for rho

p2

Squared p

r

Distance from origin in XY plane

rho

Distance from origin in 3D

theta

Inclination angle from XY plane

z

Cartesian z value

+

Methods Summary

+ + + + + + + + + +

multiply(other)

Multiply this vector by a scalar elementwise using x, y, and z components

negative()

Returns the negative of the vector

+

Attributes Documentation

+
+
+p
+

Alias for rho

+
+ +
+
+p2
+

Squared p

+
+ +
+
+r
+

Distance from origin in XY plane

+

\(\sqrt{x^2+y^2} = \rho \sin(\theta)\)

+
+ +
+
+rho
+

Distance from origin in 3D

+

\(\sqrt{x^2+y^2+z^2} = \sqrt{r^2+z^2}\)

+
+ +
+
+theta
+

Inclination angle from XY plane

+

\(\text{arctan2}(r, z)\)

+
+ +
+
+z
+

Cartesian z value

+

\(\rho \cos(\theta)\)

+
+ +

Methods Documentation

+
+
+multiply(other)[source]
+

Multiply this vector by a scalar elementwise using x, y, and z components

+

In reality, this directly adjusts r, theta and phi for performance

+
+ +
+
+negative()[source]
+

Returns the negative of the vector

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.vector.ThreeVector.html b/api/coffea.nanoevents.methods.vector.ThreeVector.html new file mode 100644 index 000000000..2a6543284 --- /dev/null +++ b/api/coffea.nanoevents.methods.vector.ThreeVector.html @@ -0,0 +1,307 @@ + + + + + + + + + ThreeVector — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

ThreeVector

+
+
+class coffea.nanoevents.methods.vector.ThreeVector[source]
+

Bases: TwoVector

+

A cartesian 3-dimensional vector

+

A heavy emphasis towards a momentum vector interpretation is assumed. +This mixin class requires the parent class to provide items x, y, and z.

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + +

p

Alias for rho

p2

Squared p

pz

Alias for z

rho

Distance from origin in 3D

rho2

Squared rho

theta

Inclination angle from XY plane

unit

Unit vector, a vector of length 1 pointing in the same direction

+

Methods Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

absolute()

Returns magnitude of the 3D vector

add(other)

Add two vectors together elementwise using x, y, and z components

cross(other)

Compute the cross product of two vectors

dot(other)

Compute the dot product of two vectors

multiply(other)

Multiply this vector by a scalar elementwise using x, y, and z components

negative()

Returns the negative of the vector

subtract(other)

Subtract a vector from another elementwise using x, y, and z components

sum([axis])

Sum an array of vectors elementwise using x, y, and z components

+

Attributes Documentation

+
+
+p
+

Alias for rho

+
+ +
+
+p2
+

Squared p

+
+ +
+
+pz
+

Alias for z

+
+ +
+
+rho
+

Distance from origin in 3D

+

\(\sqrt{x^2+y^2+z^2} = \sqrt{r^2+z^2}\)

+
+ +
+
+rho2
+

Squared rho

+
+ +
+
+theta
+

Inclination angle from XY plane

+

\(\text{arctan2}(r, z)\)

+
+ +
+
+unit
+

Unit vector, a vector of length 1 pointing in the same direction

+
+ +

Methods Documentation

+
+
+absolute()[source]
+

Returns magnitude of the 3D vector

+

Alias for rho

+
+ +
+
+add(other)[source]
+

Add two vectors together elementwise using x, y, and z components

+
+ +
+
+cross(other)[source]
+

Compute the cross product of two vectors

+
+ +
+
+dot(other)[source]
+

Compute the dot product of two vectors

+
+ +
+
+multiply(other)[source]
+

Multiply this vector by a scalar elementwise using x, y, and z components

+
+ +
+
+negative()[source]
+

Returns the negative of the vector

+
+ +
+
+subtract(other)[source]
+

Subtract a vector from another elementwise using x, y, and z components

+
+ +
+
+sum(axis=-1)[source]
+

Sum an array of vectors elementwise using x, y, and z components

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.nanoevents.methods.vector.TwoVector.html b/api/coffea.nanoevents.methods.vector.TwoVector.html new file mode 100644 index 000000000..0da274a04 --- /dev/null +++ b/api/coffea.nanoevents.methods.vector.TwoVector.html @@ -0,0 +1,328 @@ + + + + + + + + + TwoVector — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

TwoVector

+
+
+class coffea.nanoevents.methods.vector.TwoVector[source]
+

Bases: object

+

A cartesian 2-dimensional vector

+

A heavy emphasis towards a momentum vector interpretation is assumed, hence +properties like px and py are provided in addition to x and y.

+

This mixin class requires the parent class to provide items x and y.

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

phi

Polar angle relative to X axis

pt

Alias for r

pt2

Alias for r2

px

Alias for x

py

Alias for y

r

Distance from origin in XY plane

r2

Squared r

unit

Unit vector, a vector of length 1 pointing in the same direction

+

Methods Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

absolute()

Returns magnitude of the 2D vector

add(other)

Add two vectors together elementwise using x and y components

delta_phi(other)

Compute difference in angle between two vectors

divide(other)

Divide this vector by a scalar elementwise using its cartesian components

dot(other)

Compute the dot product of two vectors

multiply(other)

Multiply this vector by a scalar elementwise using x and y components

negative()

Returns the negative of the vector

subtract(other)

Substract a vector from another elementwise using x and y compontents

sum([axis])

Sum an array of vectors elementwise using x and y components

+

Attributes Documentation

+
+
+phi
+

Polar angle relative to X axis

+

\(\text{arctan2}(y, x)\)

+
+ +
+
+pt
+

Alias for r

+
+ +
+
+pt2
+

Alias for r2

+
+ +
+
+px
+

Alias for x

+
+ +
+
+py
+

Alias for y

+
+ +
+
+r
+

Distance from origin in XY plane

+

\(\sqrt{x^2+y^2}\)

+
+ +
+
+r2
+

Squared r

+
+ +
+
+unit
+

Unit vector, a vector of length 1 pointing in the same direction

+
+ +

Methods Documentation

+
+
+absolute()[source]
+

Returns magnitude of the 2D vector

+

Alias for r

+
+ +
+
+add(other)[source]
+

Add two vectors together elementwise using x and y components

+
+ +
+
+delta_phi(other)[source]
+

Compute difference in angle between two vectors

+

Returns a value within [-pi, pi)

+
+ +
+
+divide(other)[source]
+

Divide this vector by a scalar elementwise using its cartesian components

+

This is realized by using the multiplication functionality

+
+ +
+
+dot(other)[source]
+

Compute the dot product of two vectors

+
+ +
+
+multiply(other)[source]
+

Multiply this vector by a scalar elementwise using x and y components

+
+ +
+
+negative()[source]
+

Returns the negative of the vector

+
+ +
+
+subtract(other)[source]
+

Substract a vector from another elementwise using x and y compontents

+
+ +
+
+sum(axis=-1)[source]
+

Sum an array of vectors elementwise using x and y components

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.AccumulatorABC.html b/api/coffea.processor.AccumulatorABC.html new file mode 100644 index 000000000..6ea7baff2 --- /dev/null +++ b/api/coffea.processor.AccumulatorABC.html @@ -0,0 +1,244 @@ + + + + + + + + + AccumulatorABC — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

AccumulatorABC

+
+
+class coffea.processor.AccumulatorABC[source]
+

Bases: object

+

Abstract base class for an accumulator

+

Accumulators are abstract objects that enable the reduce stage of the typical map-reduce +scaleout that we do in Coffea. One concrete example is a histogram. The idea is that an +accumulator definition holds enough information to be able to create an empty accumulator +(the identity() method) and add two compatible accumulators together (the add() method). +The former is not strictly necessary, but helps with book-keeping. Here we show an example usage +of a few accumulator types. An arbitrary-depth nesting of dictionary accumulators is supported, much +like the behavior of directories in ROOT hadd.

+

After defining an accumulator:

+
from coffea.processor import dict_accumulator, column_accumulator, defaultdict_accumulator
+from coffea.hist import Hist, Bin
+import numpy as np
+
+adef = dict_accumulator({
+    'cutflow': defaultdict_accumulator(int),
+    'pt': Hist("counts", Bin("pt", "$p_T$", 100, 0, 100)),
+    'final_pt': column_accumulator(np.zeros(shape=(0,))),
+})
+
+
+

Notice that this function does not mutate adef:

+
def fill(n):
+    ptvals = np.random.exponential(scale=30, size=n)
+    cut = ptvals > 200.
+    acc = adef.identity()
+    acc['cutflow']['pt>200'] += cut.sum()
+    acc['pt'].fill(pt=ptvals)
+    acc['final_pt'] += column_accumulator(ptvals[cut])
+    return acc
+
+
+

As such, we can execute it several times in parallel and reduce the result:

+
import concurrent.futures
+with concurrent.futures.ThreadPoolExecutor() as executor:
+    outputs = executor.map(fill, [2000, 2000])
+
+combined = sum(outputs, adef.identity())
+
+
+
+
Derived classes must implement
    +
  • identity(): returns a new object of same type as self, +such that self + self.identity() == self

  • +
  • add(other): adds an object of same type as self to self

  • +
+
+
+

Concrete implementations are then provided for __add__, __radd__, and __iadd__.

+

Methods Summary

+ + + + + + + + + +

add(other)

Add another accumulator to this one in-place

identity()

Identity of the accumulator

+

Methods Documentation

+
+
+abstract add(other)[source]
+

Add another accumulator to this one in-place

+
+ +
+
+abstract identity()[source]
+

Identity of the accumulator

+

A value such that any other value added to it will return +the other value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.DaskExecutor.html b/api/coffea.processor.DaskExecutor.html new file mode 100644 index 000000000..a4dc51021 --- /dev/null +++ b/api/coffea.processor.DaskExecutor.html @@ -0,0 +1,274 @@ + + + + + + + + + DaskExecutor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

DaskExecutor

+
+
+class coffea.processor.DaskExecutor(status: bool = True, unit: str = 'items', desc: str = 'Processing', compression: int | None = 1, function_name: str | None = None, client: dask.distributed.Client | None = None, treereduction: int = 20, priority: int = 0, retries: int = 3, heavy_input: bytes | None = None, use_dataframes: bool = False, worker_affinity: bool = False)[source]
+

Bases: ExecutorBase

+

Execute using dask futures

+
+
Parameters:
+
    +
  • items (list) – List of input arguments

  • +
  • function (callable) – A function to be called on each input, which returns an accumulator instance

  • +
  • accumulator (Accumulatable) – An accumulator to collect the output of the function

  • +
  • client (distributed.client.Client) – A dask distributed client instance

  • +
  • treereduction (int, optional) – Tree reduction factor for output accumulators (default: 20)

  • +
  • status (bool, optional) – If true (default), enable progress bar

  • +
  • compression (int, optional) – Compress accumulator outputs in flight with LZ4, at level specified (default 1) +Set to None for no compression.

  • +
  • priority (int, optional) – Task priority, default 0

  • +
  • retries (int, optional) – Number of retries for failed tasks (default: 3)

  • +
  • heavy_input (serializable, optional) – Any value placed here will be broadcast to workers and joined to input +items in a tuple (item, heavy_input) that is passed to function.

  • +
  • function_name (str, optional) – Name of the function being passed

  • +
  • use_dataframes (bool, optional) –

    Retrieve output as a distributed Dask DataFrame (default: False). +The outputs of individual tasks must be Pandas DataFrames.

    +
    +

    Note

    +

    If heavy_input is set, function is assumed to be pure.

    +
    +

  • +
+
+
+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + +

client

heavy_input

priority

retries

treereduction

use_dataframes

worker_affinity

+

Methods Summary

+ + + + + + +

__call__(items, function, accumulator)

Call self as a function.

+

Attributes Documentation

+
+
+client: dask.distributed.Client | None = None
+
+ +
+
+heavy_input: bytes | None = None
+
+ +
+
+priority: int = 0
+
+ +
+
+retries: int = 3
+
+ +
+
+treereduction: int = 20
+
+ +
+
+use_dataframes: bool = False
+
+ +
+
+worker_affinity: bool = False
+
+ +

Methods Documentation

+
+
+__call__(items: Iterable, function: Callable, accumulator: Addable | MutableSet | MutableMapping)[source]
+

Call self as a function.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.FuturesExecutor.html b/api/coffea.processor.FuturesExecutor.html new file mode 100644 index 000000000..c20c005fb --- /dev/null +++ b/api/coffea.processor.FuturesExecutor.html @@ -0,0 +1,263 @@ + + + + + + + + + FuturesExecutor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

FuturesExecutor

+
+
+class coffea.processor.FuturesExecutor(status: bool = True, unit: str = 'items', desc: str = 'Processing', compression: int | None = 1, function_name: str | None = None, pool: ~typing.Callable[[...], ~concurrent.futures._base.Executor] | ~concurrent.futures._base.Executor = <class 'concurrent.futures.process.ProcessPoolExecutor'>, mergepool: ~typing.Callable[[...], ~concurrent.futures._base.Executor] | ~concurrent.futures._base.Executor | bool | None = None, recoverable: bool = False, merging: bool | ~typing.Tuple[int, int, int] = False, workers: int = 1, tailtimeout: int | None = None)[source]
+

Bases: ExecutorBase

+

Execute using multiple local cores using python futures

+
+
Parameters:
+
    +
  • items (list) – List of input arguments

  • +
  • function (callable) – A function to be called on each input, which returns an accumulator instance

  • +
  • accumulator (Accumulatable) – An accumulator to collect the output of the function

  • +
  • pool (concurrent.futures.Executor class or instance, optional) – The type of futures executor to use, defaults to ProcessPoolExecutor. +You can pass an instance instead of a class to re-use an executor

  • +
  • workers (int, optional) – Number of parallel processes for futures (default 1)

  • +
  • status (bool, optional) – If true (default), enable progress bar

  • +
  • desc (str, optional) – Label of progress description (default: ‘Processing’)

  • +
  • unit (str, optional) – Label of progress bar bar unit (default: ‘items’)

  • +
  • compression (int, optional) – Compress accumulator outputs in flight with LZ4, at level specified (default 1) +Set to None for no compression.

  • +
  • recoverable (bool, optional) – Instead of raising Exception right away, the exception is captured and returned +up for custom parsing. Already completed items will be returned as well.

  • +
  • checkpoints (bool) – To do

  • +
  • merging (bool | tuple(int, int, int), optional) – Enables submitting intermediate merge jobs to the executor. Format is +(n_batches, min_batch_size, max_batch_size). Passing True will use default: (5, 4, 100), +aka as they are returned try to split completed jobs into 5 batches, but of at least 4 and at most 100 items. +Default is False - results get merged as they finish in the main process.

  • +
  • nparts (int, optional) – Number of merge jobs to create at a time. Also pass via ``merging(X, …, …)’’

  • +
  • minred (int, optional) – Minimum number of items to merge in one job. Also pass via ``merging(…, X, …)’’

  • +
  • maxred (int, optional) – maximum number of items to merge in one job. Also pass via ``merging(…, …, X)’’

  • +
  • mergepool (concurrent.futures.Executor class or instance | int, optional) – Supply an additional executor to process merge jobs indepedently. +An int will be interpretted as ProcessPoolExecutor(max_workers=int).

  • +
  • tailtimeout (int, optional) – Timeout requirement on job tails. Cancel all remaining jobs if none have finished +in the timeout window.

  • +
+
+
+

Attributes Summary

+ + + + + + + + + + + + + + + + + + +

mergepool

merging

recoverable

tailtimeout

workers

+

Methods Summary

+ + + + + + +

__call__(items, function, accumulator)

Call self as a function.

+

Attributes Documentation

+
+
+mergepool: Callable[[...], Executor] | Executor | bool | None = None
+
+ +
+
+merging: bool | Tuple[int, int, int] = False
+
+ +
+
+recoverable: bool = False
+
+ +
+
+tailtimeout: int | None = None
+
+ +
+
+workers: int = 1
+
+ +

Methods Documentation

+
+
+__call__(items: Iterable, function: Callable, accumulator: Addable | MutableSet | MutableMapping)[source]
+

Call self as a function.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.IterativeExecutor.html b/api/coffea.processor.IterativeExecutor.html new file mode 100644 index 000000000..5edbe9076 --- /dev/null +++ b/api/coffea.processor.IterativeExecutor.html @@ -0,0 +1,213 @@ + + + + + + + + + IterativeExecutor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

IterativeExecutor

+
+
+class coffea.processor.IterativeExecutor(status: bool = True, unit: str = 'items', desc: str = 'Processing', compression: int | None = 1, function_name: str | None = None, workers: int = 1)[source]
+

Bases: ExecutorBase

+

Execute in one thread iteratively

+
+
Parameters:
+
    +
  • items (list) – List of input arguments

  • +
  • function (callable) – A function to be called on each input, which returns an accumulator instance

  • +
  • accumulator (Accumulatable) – An accumulator to collect the output of the function

  • +
  • status (bool) – If true (default), enable progress bar

  • +
  • unit (str) – Label of progress bar unit

  • +
  • desc (str) – Label of progress bar description

  • +
  • compression (int, optional) – Ignored for iterative executor

  • +
+
+
+

Attributes Summary

+ + + + + + +

workers

+

Methods Summary

+ + + + + + +

__call__(items, function, accumulator)

Call self as a function.

+

Attributes Documentation

+
+
+workers: int = 1
+
+ +

Methods Documentation

+
+
+__call__(items: Iterable, function: Callable, accumulator: Addable | MutableSet | MutableMapping)[source]
+

Call self as a function.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.LazyDataFrame.html b/api/coffea.processor.LazyDataFrame.html new file mode 100644 index 000000000..a85ab0de4 --- /dev/null +++ b/api/coffea.processor.LazyDataFrame.html @@ -0,0 +1,255 @@ + + + + + + + + + LazyDataFrame — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

LazyDataFrame

+
+
+class coffea.processor.LazyDataFrame(tree, entrystart=None, entrystop=None, preload_items=None, metadata=None)[source]
+

Bases: MutableMapping

+

Simple delayed uproot reader (a la lazyarrays)

+

One can access branches either through df["bname"] or df.bname, although +the latter is restricted to branches that do not start with a leading underscore. +Keeps track of values accessed, in the materialized attribute.

+
+
Parameters:
+
    +
  • tree (uproot.TTree) – Tree to read

  • +
  • entrystart (int, optional) – First entry to read, default: 0

  • +
  • entrystop (int, optional) – Last entry to read, default None (read to end)

  • +
  • preload_items (iterable) – Force preloading of a set of columns from the tree

  • +
  • metadata (Mapping) – Additional metadata for the dataframe

  • +
+
+
+

Attributes Summary

+ + + + + + + + + + + + + + + + + + +

available

Set of available columns

columns

Set of available columns

materialized

Set of columns read from tree

metadata

size

Length of column vector

+

Methods Summary

+ + + + + + +

preload(columns)

Force loading of several columns

+

Attributes Documentation

+
+
+available
+

Set of available columns

+
+ +
+
+columns
+

Set of available columns

+
+ +
+
+materialized
+

Set of columns read from tree

+
+ +
+
+metadata
+
+ +
+
+size
+

Length of column vector

+
+ +

Methods Documentation

+
+
+preload(columns)[source]
+

Force loading of several columns

+
+
Parameters:
+

columns (iterable) – A list of columns to load

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.NanoAODSchema.html b/api/coffea.processor.NanoAODSchema.html new file mode 100644 index 000000000..a50d8c283 --- /dev/null +++ b/api/coffea.processor.NanoAODSchema.html @@ -0,0 +1,297 @@ + + + + + + + + + NanoAODSchema — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

NanoAODSchema

+
+
+class coffea.processor.NanoAODSchema(base_form, version='latest')[source]
+

Bases: BaseSchema

+

NanoAOD schema builder

+

The NanoAOD schema is built from all branches found in the supplied file, based on +the naming pattern of the branches. The following additional arrays are constructed:

+
    +
  • Any branches named n{name} are assumed to be counts branches and converted to offsets o{name}

  • +
  • Any local index branches with names matching {source}_{target}Idx* are converted to global indexes for the event chunk (postfix G)

  • +
  • Any nested_items are constructed, if the necessary branches are available

  • +
  • Any special_items are constructed, if the necessary branches are available

  • +
+

From those arrays, NanoAOD collections are formed as collections of branches grouped by name, where:

+
    +
  • one branch exists named name and no branches start with name_, interpreted as a single flat array;

  • +
  • one branch exists named name, one named n{name}, and no branches start with name_, interpreted as a single jagged array;

  • +
  • no branch exists named {name} and many branches start with name_*, interpreted as a flat table; or

  • +
  • one branch exists named n{name} and many branches start with name_*, interpreted as a jagged table.

  • +
+

Collections are assigned mixin types according to the mixins mapping. +All collections are then zipped into one base.NanoEvents record and returned.

+

There is a class-level variable warn_missing_crossrefs which will alter the behavior of +NanoAODSchema. If warn_missing_crossrefs is true then when a missing global index cross-ref +target is encountered a warning will be issued. Regardless, the cross-reference is dropped.

+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + +

all_cross_references

Cross-references, where an index is to be interpreted with respect to another collection

behavior

Behaviors necessary to implement this schema

mixins

Default configuration for mixin types, based on the collection name.

nested_index_items

Nested collections, where nesting is accomplished by assuming the target can be unflattened according to a source counts

nested_items

Nested collections, where nesting is accomplished by a fixed-length set of indexers

special_items

Special arrays, where the callable and input arrays are specified in the value

warn_missing_crossrefs

+

Methods Summary

+ + + + + + + + + + + + +

v5(base_form)

Build the NanoEvents assuming NanoAODv5

v6(base_form)

Build the NanoEvents assuming NanoAODv6

v7(base_form)

Build the NanoEvents assuming NanoAODv7

+

Attributes Documentation

+
+
+all_cross_references = {'Electron_genPartIdx': 'GenPart', 'Electron_jetIdx': 'Jet', 'Electron_photonIdx': 'Photon', 'FatJet_genJetAK8Idx': 'GenJetAK8', 'FatJet_subJetIdx1': 'SubJet', 'FatJet_subJetIdx2': 'SubJet', 'FsrPhoton_muonIdx': 'Muon', 'GenPart_genPartIdxMother': 'GenPart', 'GenVisTau_genPartIdxMother': 'GenPart', 'Jet_electronIdx1': 'Electron', 'Jet_electronIdx2': 'Electron', 'Jet_genJetIdx': 'GenJet', 'Jet_muonIdx1': 'Muon', 'Jet_muonIdx2': 'Muon', 'LowPtElectron_electronIdx': 'Electron', 'LowPtElectron_genPartIdx': 'GenPart', 'LowPtElectron_photonIdx': 'Photon', 'Muon_fsrPhotonIdx': 'FsrPhoton', 'Muon_genPartIdx': 'GenPart', 'Muon_jetIdx': 'Jet', 'Photon_electronIdx': 'Electron', 'Photon_genPartIdx': 'GenPart', 'Photon_jetIdx': 'Jet', 'Tau_genPartIdx': 'GenPart', 'Tau_jetIdx': 'Jet'}
+

Cross-references, where an index is to be interpreted with respect to another collection

+

Each such cross-reference will be converted to a global indexer, so that arbitrarily sliced events +can still resolve the indirection back the parent events

+
+ +
+
+behavior
+

Behaviors necessary to implement this schema

+
+ +
+
+mixins = {'CaloMET': 'MissingET', 'ChsMET': 'MissingET', 'Electron': 'Electron', 'FatJet': 'FatJet', 'FsrPhoton': 'FsrPhoton', 'GenDressedLepton': 'PtEtaPhiMCollection', 'GenIsolatedPhoton': 'PtEtaPhiMCollection', 'GenJet': 'PtEtaPhiMCollection', 'GenJetAK8': 'PtEtaPhiMCollection', 'GenMET': 'MissingET', 'GenPart': 'GenParticle', 'GenVisTau': 'GenVisTau', 'IsoTrack': 'PtEtaPhiMCollection', 'Jet': 'Jet', 'LHEPart': 'PtEtaPhiMCollection', 'LowPtElectron': 'LowPtElectron', 'MET': 'MissingET', 'METFixEE2017': 'MissingET', 'Muon': 'Muon', 'PV': 'Vertex', 'Photon': 'Photon', 'PuppiMET': 'MissingET', 'RawMET': 'MissingET', 'RawPuppiMET': 'MissingET', 'SV': 'SecondaryVertex', 'SoftActivityJet': 'PtEtaPhiMCollection', 'SubGenJetAK8': 'PtEtaPhiMCollection', 'SubJet': 'PtEtaPhiMCollection', 'Tau': 'Tau', 'TkMET': 'MissingET', 'TrigObj': 'PtEtaPhiMCollection'}
+

Default configuration for mixin types, based on the collection name.

+

The types are implemented in the coffea.nanoevents.methods.nanoaod module.

+
+ +
+
+nested_index_items = {'FatJet_pFCandsIdxG': ('FatJet_nConstituents', 'FatJetPFCands'), 'GenFatJet_pFCandsIdxG': ('GenJetAK8_nConstituents', 'GenFatJetCands'), 'GenJet_pFCandsIdxG': ('GenJet_nConstituents', 'GenJetCands'), 'Jet_pFCandsIdxG': ('Jet_nConstituents', 'JetPFCands')}
+

Nested collections, where nesting is accomplished by assuming the target can be unflattened according to a source counts

+
+ +
+
+nested_items = {'FatJet_subJetIdxG': ['FatJet_subJetIdx1G', 'FatJet_subJetIdx2G'], 'Jet_electronIdxG': ['Jet_electronIdx1G', 'Jet_electronIdx2G'], 'Jet_muonIdxG': ['Jet_muonIdx1G', 'Jet_muonIdx2G']}
+

Nested collections, where nesting is accomplished by a fixed-length set of indexers

+
+ +
+
+special_items = {'GenPart_childrenIdxG': (<function children_form>, ('oGenPart', 'GenPart_genPartIdxMotherG')), 'GenPart_distinctChildrenDeepIdxG': (<function distinctChildrenDeep_form>, ('oGenPart', 'GenPart_genPartIdxMotherG', 'GenPart_pdgId')), 'GenPart_distinctChildrenIdxG': (<function children_form>, ('oGenPart', 'GenPart_distinctParentIdxG')), 'GenPart_distinctParentIdxG': (<function distinctParent_form>, ('GenPart_genPartIdxMotherG', 'GenPart_pdgId'))}
+

Special arrays, where the callable and input arrays are specified in the value

+
+ +
+
+warn_missing_crossrefs = True
+
+ +

Methods Documentation

+
+
+classmethod v5(base_form)[source]
+

Build the NanoEvents assuming NanoAODv5

+
+ +
+
+classmethod v6(base_form)[source]
+

Build the NanoEvents assuming NanoAODv6

+
+ +
+
+classmethod v7(base_form)[source]
+

Build the NanoEvents assuming NanoAODv7

+

For example, one can use NanoEventsFactory.from_root("file.root", schemaclass=NanoAODSchema.v7) +to ensure NanoAODv7 compatibility.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.PackedSelection.html b/api/coffea.processor.PackedSelection.html new file mode 100644 index 000000000..bcfd52936 --- /dev/null +++ b/api/coffea.processor.PackedSelection.html @@ -0,0 +1,259 @@ + + + + + + + + + PackedSelection — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

PackedSelection

+
+
+class coffea.processor.PackedSelection(dtype='uint64')[source]
+

Bases: object

+

Store boolean mask vectors in a compact manner

+

This class can store several boolean masks (cuts, selections) and +evaluate arbitrary combinations of the requirements in an CPU-efficient way

+
+
Parameters:
+

dtype (str) – internal bitwidth of mask vector, which governs the maximum +number of boolean masks storable in this object. +By default, up to 64 masks can be stored, but smaller values +for the numpy.dtype may be more efficient.

+
+
+

Attributes Summary

+ + + + + + +

names

Current list of mask names available

+

Methods Summary

+ + + + + + + + + + + + +

add(name, selection)

Add a named mask

all(*names)

Shorthand for require, where all the values are True

require(**names)

Return a mask vector corresponding to specific requirements

+

Attributes Documentation

+
+
+names
+

Current list of mask names available

+
+ +

Methods Documentation

+
+
+add(name, selection)[source]
+

Add a named mask

+
+
Parameters:
+
    +
  • name (str) – name of the mask

  • +
  • selection (numpy.ndarray) – a flat array of dtype bool. +If not the first mask added, it must also have +the same shape as previously added masks.

  • +
+
+
+
+ +
+
+all(*names)[source]
+

Shorthand for require, where all the values are True

+
+ +
+
+require(**names)[source]
+

Return a mask vector corresponding to specific requirements

+

Specify an exact requirement on an arbitrary subset of the masks

+
+
Parameters:
+

**names (kwargs) – Each argument to require specific value for, in form arg=True +or arg=False.

+
+
+

Examples

+

If

+
>>> selection.names
+['cut1', 'cut2', 'cut3']
+
+
+

then

+
>>> selection.require(cut1=True, cut2=False)
+array([True, False, True, ...])
+
+
+

returns a boolean array where each entry passes if the corresponding entry has +cut1 == True, cut2 == False, and cut3 arbitrary.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.ParslExecutor.html b/api/coffea.processor.ParslExecutor.html new file mode 100644 index 000000000..bf1d583be --- /dev/null +++ b/api/coffea.processor.ParslExecutor.html @@ -0,0 +1,272 @@ + + + + + + + + + ParslExecutor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

ParslExecutor

+
+
+class coffea.processor.ParslExecutor(status: bool = True, unit: str = 'items', desc: str = 'Processing', compression: int | None = 1, function_name: str | None = None, tailtimeout: int | None = None, config: parsl.config.Config | None = None, recoverable: bool = False, merging: bool | Tuple[int, int, int] | None = False, jobs_executors: str | List = 'all', merges_executors: str | List = 'all')[source]
+

Bases: ExecutorBase

+

Execute using parsl pyapp wrapper

+
+
Parameters:
+
    +
  • items (list) – List of input arguments

  • +
  • function (callable) – A function to be called on each input, which returns an accumulator instance

  • +
  • accumulator (Accumulatable) – An accumulator to collect the output of the function

  • +
  • config (parsl.config.Config, optional) –

    A parsl DataFlow configuration object. Necessary if there is no active kernel

    +
    +

    Note

    +

    In general, it is safer to construct the DFK with parsl.load(config) prior to calling this function

    +
    +

  • +
  • status (bool) – If true (default), enable progress bar

  • +
  • unit (str) – Label of progress bar unit

  • +
  • desc (str) – Label of progress bar description

  • +
  • compression (int, optional) – Compress accumulator outputs in flight with LZ4, at level specified (default 1) +Set to None for no compression.

  • +
  • recoverable (bool, optional) – Instead of raising Exception right away, the exception is captured and returned +up for custom parsing. Already completed items will be returned as well.

  • +
  • merging (bool | tuple(int, int, int), optional) – Enables submitting intermediate merge jobs to the executor. Format is +(n_batches, min_batch_size, max_batch_size). Passing True will use default: (5, 4, 100), +aka as they are returned try to split completed jobs into 5 batches, but of at least 4 and at most 100 items. +Default is False - results get merged as they finish in the main process.

  • +
  • jobs_executors (list | "all" optional) – Labels of the executors (from dfk.config.executors) that will process main jobs. +Default is ‘all’. Recommended is ['jobs'], while passing label='jobs' to the primary executor.

  • +
  • merges_executors (list | "all" optional) – Labels of the executors (from dfk.config.executors) that will process main jobs. +Default is ‘all’. Recommended is ['merges'], while passing label='merges' to the executor dedicated towards merge jobs.

  • +
  • tailtimeout (int, optional) – Timeout requirement on job tails. Cancel all remaining jobs if none have finished +in the timeout window.

  • +
+
+
+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + +

config

jobs_executors

merges_executors

merging

recoverable

tailtimeout

+

Methods Summary

+ + + + + + +

__call__(items, function, accumulator)

Call self as a function.

+

Attributes Documentation

+
+
+config: parsl.config.Config | None = None
+
+ +
+
+jobs_executors: str | List = 'all'
+
+ +
+
+merges_executors: str | List = 'all'
+
+ +
+
+merging: bool | Tuple[int, int, int] | None = False
+
+ +
+
+recoverable: bool = False
+
+ +
+
+tailtimeout: int | None = None
+
+ +

Methods Documentation

+
+
+__call__(items: Iterable, function: Callable, accumulator: Addable | MutableSet | MutableMapping)[source]
+

Call self as a function.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.ProcessorABC.html b/api/coffea.processor.ProcessorABC.html new file mode 100644 index 000000000..c17f68a44 --- /dev/null +++ b/api/coffea.processor.ProcessorABC.html @@ -0,0 +1,223 @@ + + + + + + + + + ProcessorABC — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

ProcessorABC

+
+
+class coffea.processor.ProcessorABC[source]
+

Bases: object

+

ABC for a generalized processor

+

The various data delivery mechanisms (spark, striped, uproot, uproot+futures, condor, …) +receive such an object and the appropriate metadata to deliver NanoEvents to it. +It is expected that the entire processor object can be serializable (check with save) +No attempt should be made to track state inside an instance of ProcessorABC, it is to be +treated simply as a bundle of methods.

+

Examples

+

A skeleton processor:

+
from coffea import hist, processor
+
+class MyProcessor(processor.ProcessorABC):
+    def __init__(self, flag=False):
+        self._flag = flag
+
+    def process(self, events):
+        out = {"sumw": len(events)}
+
+        # ...
+
+        return {events.metadata.dataset: out}
+
+    def postprocess(self, accumulator):
+        pass
+
+p = MyProcessor()
+
+
+

Methods Summary

+ + + + + + + + + +

postprocess(accumulator)

Final processing on aggregated accumulator

process(events)

Processes a single NanoEvents chunk

+

Methods Documentation

+
+
+abstract postprocess(accumulator)[source]
+

Final processing on aggregated accumulator

+

Do any final processing on the resulting accumulator object, it should be modified in-place

+
+ +
+
+abstract process(events)[source]
+

Processes a single NanoEvents chunk

+

Returns a filled accumulator object

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.Runner.html b/api/coffea.processor.Runner.html new file mode 100644 index 000000000..e00ebaa0a --- /dev/null +++ b/api/coffea.processor.Runner.html @@ -0,0 +1,441 @@ + + + + + + + + + Runner — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Runner

+
+
+class coffea.processor.Runner(executor: ~coffea.processor.executor.ExecutorBase, pre_executor: ~coffea.processor.executor.ExecutorBase | None = None, chunksize: int = 100000, maxchunks: int | None = None, metadata_cache: ~collections.abc.MutableMapping | None = None, dynamic_chunksize: ~typing.Dict | None = None, skipbadfiles: bool = False, xrootdtimeout: int | None = 60, align_clusters: bool = False, savemetrics: bool = False, mmap: bool = False, schema: ~coffea.nanoevents.schemas.base.BaseSchema | None = <class 'coffea.nanoevents.schemas.base.BaseSchema'>, cachestrategy: ~typing.Literal['dask-worker'] | ~typing.Callable[[...], ~collections.abc.MutableMapping] | None = None, processor_compression: int = 1, use_skyhook: bool | None = False, skyhook_options: ~typing.Dict | None = <factory>, format: str = 'root')[source]
+

Bases: object

+

A tool to run a processor using uproot for data delivery

+

A convenience wrapper to submit jobs for a file set, which is a +dictionary of dataset: [file list] entries. Supports only uproot TTree +reading, via NanoEvents or LazyDataFrame. For more customized processing, +e.g. to read other objects from the files and pass them into data frames, +one can write a similar function in their user code.

+
+
Parameters:
+
    +
  • executor (ExecutorBase instance) – Executor, which implements a callable with inputs: items, function, accumulator +and performs some action equivalent to: +for item in items: accumulator += function(item)

  • +
  • pre_executor (ExecutorBase instance) – Executor, used to calculate fileset metadata +Defaults to executor

  • +
  • chunksize (int, optional) – Maximum number of entries to process at a time in the data frame, default: 100k

  • +
  • maxchunks (int, optional) – Maximum number of chunks to process per dataset +Defaults to processing the whole dataset

  • +
  • metadata_cache (mapping, optional) – A dict-like object to use as a cache for (file, tree) metadata that is used to +determine chunking. Defaults to a in-memory LRU cache that holds 100k entries +(about 1MB depending on the length of filenames, etc.) If you edit an input file +(please don’t) during a session, the session can be restarted to clear the cache.

  • +
  • dynamic_chunksize (dict, optional) – Whether to adapt the chunksize for units of work to run in the targets given. +Currently supported are ‘wall_time’ (in seconds), and ‘memory’ (in MB). +E.g., with {“wall_time”: 120, “memory”: 2048}, the chunksize will +be dynamically adapted so that processing jobs each run in about +two minutes, using two GB of memory. (Currently only for the WorkQueueExecutor.)

  • +
+
+
+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

align_clusters

cachestrategy

chunksize

dynamic_chunksize

format

maxchunks

metadata_cache

mmap

pre_executor

processor_compression

retries

savemetrics

skipbadfiles

use_dataframes

use_skyhook

xrootdtimeout

+

Methods Summary

+ + + + + + + + + + + + + + + + + + + + + + + + +

__call__(fileset, treename, processor_instance)

Run the processor_instance on a given fileset

automatic_retries(retries, skipbadfiles, ...)

This should probably defined on Executor-level.

get_cache(cachestrategy)

metadata_fetcher(xrootdtimeout, ...)

preprocess(fileset, treename)

Run the processor_instance on a given fileset

read_coffea_config()

run(fileset, processor_instance[, treename])

Run the processor_instance on a given fileset

+

Attributes Documentation

+
+
+align_clusters: bool = False
+
+ +
+
+cachestrategy: Literal['dask-worker'] | Callable[[...], MutableMapping] | None = None
+
+ +
+
+chunksize: int = 100000
+
+ +
+
+dynamic_chunksize: Dict | None = None
+
+ +
+
+format: str = 'root'
+
+ +
+
+maxchunks: int | None = None
+
+ +
+
+metadata_cache: MutableMapping | None = None
+
+ +
+
+mmap: bool = False
+
+ +
+
+pre_executor: ExecutorBase | None = None
+
+ +
+
+processor_compression: int = 1
+
+ +
+
+retries
+
+ +
+
+savemetrics: bool = False
+
+ +
+
+skipbadfiles: bool = False
+
+ +
+
+use_dataframes
+
+ +
+
+use_skyhook: bool | None = False
+
+ +
+
+xrootdtimeout: int | None = 60
+
+ +

Methods Documentation

+
+
+__call__(fileset: Dict, treename: str, processor_instance: ProcessorABC) Addable | MutableSet | MutableMapping[source]
+

Run the processor_instance on a given fileset

+
+
Parameters:
+
    +
  • fileset (dict) – A dictionary {dataset: [file, file], } +Optionally, if some files’ tree name differ, the dictionary can be specified: +{dataset: {'treename': 'name', 'files': [file, file]}, }

  • +
  • treename (str) – name of tree inside each root file, can be None; +treename can also be defined in fileset, which will override the passed treename

  • +
  • processor_instance (ProcessorABC) – An instance of a class deriving from ProcessorABC

  • +
+
+
+
+ +
+
+static automatic_retries(retries: int, skipbadfiles: bool, func, *args, **kwargs)[source]
+

This should probably defined on Executor-level.

+
+ +
+
+static get_cache(cachestrategy)[source]
+
+ +
+
+static metadata_fetcher(xrootdtimeout: int, align_clusters: bool, item: FileMeta) Addable | MutableSet | MutableMapping[source]
+
+ +
+
+preprocess(fileset: Dict, treename: str) Generator[source]
+

Run the processor_instance on a given fileset

+
+
Parameters:
+
    +
  • fileset (dict) – A dictionary {dataset: [file, file], } +Optionally, if some files’ tree name differ, the dictionary can be specified: +{dataset: {'treename': 'name', 'files': [file, file]}, }

  • +
  • treename (str) – name of tree inside each root file, can be None; +treename can also be defined in fileset, which will override the passed treename

  • +
+
+
+
+ +
+
+static read_coffea_config()[source]
+
+ +
+
+run(fileset: Dict | str | List[WorkItem] | Generator, processor_instance: ProcessorABC, treename: str = None) Addable | MutableSet | MutableMapping[source]
+

Run the processor_instance on a given fileset

+
+
Parameters:
+
    +
  • fileset (dict | str | List[WorkItem] | Generator) –

      +
    • A dictionary {dataset: [file, file], } +Optionally, if some files’ tree name differ, the dictionary can be specified: +{dataset: {'treename': 'name', 'files': [file, file]}, }

    • +
    • A single file name

    • +
    • File chunks for self.preprocess()

    • +
    • Chunk generator

    • +
    +

  • +
  • treename (str, optional) – name of tree inside each root file, can be None; +treename can also be defined in fileset, which will override the passed treename +Not needed if processing premade chunks

  • +
  • processor_instance (ProcessorABC) – An instance of a class deriving from ProcessorABC

  • +
+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.TreeMakerSchema.html b/api/coffea.processor.TreeMakerSchema.html new file mode 100644 index 000000000..b2a1d43b0 --- /dev/null +++ b/api/coffea.processor.TreeMakerSchema.html @@ -0,0 +1,236 @@ + + + + + + + + + TreeMakerSchema — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

TreeMakerSchema

+
+
+class coffea.processor.TreeMakerSchema(base_form)[source]
+

Bases: BaseSchema

+

TreeMaker schema builder

+

The TreeMaker schema is built from all branches found in the supplied file, +based on the naming pattern of the branches. There are two steps of to the +generation of array collections:

+
    +
  • Objects with vector-like quantities (momentum, coordinate points) in the +TreeMaker n-tuples are stored using ROOT PtEtaPhiEVectors and XYZPoint +classes with maximum TTree splitting. These variable branches are grouped +into a single collection with the original object name, with the +corresponding coordinate variables names mapped to the standard variable +names for coffea.nanoevents.methods.vector behaviors. For example: +- The “Jets” branch in a TreeMaker n-tuple branch stores ‘PtEtaPhiEVector’s

    +
    +

    corresponding to the momentum of AK4 jets. The resulting collection after +this first step would contain the vector variables in the form of +Jets.pt, Jets.eta, Jets.phi, Jets.energy, and addition vector quantities +(px) can be accessed via the usual vector behavior methods.

    +
    +
      +
    • The “PrimaryVertices” branch in a TreeMaker n-tuple branch stores +‘XYZPoint’s corresponding to the coordinates of the primary vertices, The +resulting collection after this first step wold contain the coordinate +variables in the form of PrimaryVertices.x, PrimaryVertices.y, +PrimaryVertices.z.

    • +
    +
  • +
  • Extended quantities of physic objects are stored in the format +<Object>_<variable>, such as “Jets_jecFactor”. Such variables will be +merged into the collection <Object>, so the branch “Jets_jetFactor” will be +access to in the array format as “Jets.jecFactor”. An exception to the

  • +
+

All collections are then zipped into one base.NanoEvents record and +returned.

+

Attributes Summary

+ + + + + + +

behavior

Behaviors necessary to implement this schema

+

Methods Summary

+ + + + + + +

uproot_writeable()

Converting a TreeMakerSchema event into something that is uproot writeable.

+

Attributes Documentation

+
+
+behavior
+

Behaviors necessary to implement this schema

+
+ +

Methods Documentation

+
+
+classmethod uproot_writeable()[source]
+

Converting a TreeMakerSchema event into something that is uproot +writeable. Based off the discussion thread here [1], but added specific +cased to handled the nested structures define for TreeMaker n-tuples. +[1] https://github.com/CoffeaTeam/coffea/discussions/735

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.Weights.html b/api/coffea.processor.Weights.html new file mode 100644 index 000000000..7bc9373a5 --- /dev/null +++ b/api/coffea.processor.Weights.html @@ -0,0 +1,283 @@ + + + + + + + + + Weights — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

Weights

+
+
+class coffea.processor.Weights(size, storeIndividual=False)[source]
+

Bases: object

+

Container for event weights and associated systematic shifts

+

This container keeps track of correction factors and systematic +effects that can be encoded as multiplicative modifiers to the event weight. +All weights are stored in vector form.

+
+
Parameters:
+
    +
  • size (int) – size of the weight arrays to be handled (i.e. the number of events / instances).

  • +
  • storeIndividual (bool, optional) – store not only the total weight + variations, but also each individual weight. +Default is false.

  • +
+
+
+

Attributes Summary

+ + + + + + +

variations

List of available modifiers

+

Methods Summary

+ + + + + + + + + + + + +

add(name, weight[, weightUp, weightDown, shift])

Add a new weight

partial_weight([include, exclude])

Partial event weight vector

weight([modifier])

Current event weight vector

+

Attributes Documentation

+
+
+variations
+

List of available modifiers

+
+ +

Methods Documentation

+
+
+add(name, weight, weightUp=None, weightDown=None, shift=False)[source]
+

Add a new weight

+

Adds a named correction to the event weight, and optionally also associated +systematic uncertainties.

+
+
Parameters:
+
    +
  • name (str) – name of correction

  • +
  • weight (numpy.ndarray) – the nominal event weight associated with the correction

  • +
  • weightUp (numpy.ndarray, optional) – weight with correction uncertainty shifted up (if available)

  • +
  • weightDown (numpy.ndarray, optional) – weight with correction uncertainty shifted down. If weightUp is supplied, and +the correction uncertainty is symmetric, this can be set to None to auto-calculate +the down shift as 1 / weightUp.

  • +
  • shift (bool, optional) – if True, interpret weightUp and weightDown as a realtive difference (additive) to the +nominal value

  • +
+
+
+
+

Note

+

weightUp and weightDown are assumed to be rvalue-like and may be modified in-place by this function

+
+
+ +
+
+partial_weight(include=[], exclude=[])[source]
+

Partial event weight vector

+

Return a partial weight by multiplying a subset of all weights. +Can be operated either by specifying weights to include or +weights to exclude, but not both at the same time. The method +can only be used if the individual weights are stored via the +storeIndividual argument in the Weights initializer.

+
+
Parameters:
+
    +
  • include (list) – Weight names to include, defaults to []

  • +
  • exclude (list) – Weight names to exclude, defaults to []

  • +
+
+
Returns:
+

weight – The weight vector, corresponding to only the effect of the +corrections specified.

+
+
Return type:
+

numpy.ndarray

+
+
+
+ +
+
+weight(modifier=None)[source]
+

Current event weight vector

+
+
Parameters:
+

modifier (str, optional) – if supplied, provide event weight corresponding to a particular +systematic uncertainty shift, of form str(name + 'Up') or (Down)

+
+
Returns:
+

weight – The weight vector, possibly modified by the effect of a given systematic variation.

+
+
Return type:
+

numpy.ndarray

+
+
+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.WorkQueueExecutor.html b/api/coffea.processor.WorkQueueExecutor.html new file mode 100644 index 000000000..ae2667449 --- /dev/null +++ b/api/coffea.processor.WorkQueueExecutor.html @@ -0,0 +1,560 @@ + + + + + + + + + WorkQueueExecutor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

WorkQueueExecutor

+
+
+class coffea.processor.WorkQueueExecutor(status: bool = True, unit: str = 'items', desc: str = 'Processing', compression: int | None = 9, function_name: str | None = None, retries: int = 2, manager_name: str | None = None, port: int | ~typing.Tuple[int, int] | None = None, filepath: str = '.', events_total: int | None = None, x509_proxy: str | None = None, verbose: bool = False, print_stdout: bool = False, status_display_interval: int | None = 10, debug_log: str | None = None, stats_log: str | None = None, transactions_log: str | None = None, tasks_accum_log: str | None = None, password_file: str | None = None, ssl: bool | ~typing.Tuple[str, str] = False, environment_file: str | None = None, extra_input_files: ~typing.List = <factory>, wrapper: str | None = None, resource_monitor: str | None = 'off', resources_mode: str | None = 'max-seen', split_on_exhaustion: bool | None = True, fast_terminate_workers: int | None = None, cores: int | None = None, memory: int | None = None, disk: int | None = None, gpus: int | None = None, treereduction: int = 20, chunksize: int = 100000, dynamic_chunksize: ~typing.Dict | None = None, custom_init: ~typing.Callable | None = None, bar_format: str | None = None, chunks_accum_in_mem: int | None = None, master_name: str | None = None, chunks_per_accum: int | None = None)[source]
+

Bases: ExecutorBase

+

Execute using Work Queue

+

For more information, see Work Queue Executor

+
+
Parameters:
+
    +
  • items (sequence or generator) – Sequence of input arguments

  • +
  • function (callable) – A function to be called on each input, which returns an accumulator instance

  • +
  • accumulator (Accumulatable) – An accumulator to collect the output of the function

  • +
  • status (bool) – If true (default), enable progress bar

  • +
  • unit (str) – Label of progress bar unit

  • +
  • desc (str) – Label of progress bar description

  • +
  • compression (int, optional) – Compress accumulator outputs in flight with LZ4, at level specified (default 9) +None` sets level to 1 (minimal compression)

  • +
  • options (# work queue specific)

  • +
  • cores (int) – Maximum number of cores for work queue task. If unset, use a whole worker.

  • +
  • memory (int) – Maximum amount of memory (in MB) for work queue task. If unset, use a whole worker.

  • +
  • disk (int) – Maximum amount of disk space (in MB) for work queue task. If unset, use a whole worker.

  • +
  • gpus (int) – Number of GPUs to allocate to each task. If unset, use zero.

  • +
  • resource_monitor (str) –

    If given, one of ‘off’, ‘measure’, or ‘watchdog’. Default is ‘off’. +- ‘off’: turns off resource monitoring. Overriden to ‘watchdog’ if resources_mode

    +
    +

    is not set to ‘fixed’.

    +
    +
      +
    • +
      ’measure’: turns on resource monitoring for Work Queue. The

      resources used per task are measured.

      +
      +
      +
    • +
    • +
      ’watchdog’: in addition to measuring resources, tasks are terminated if they

      go above the cores, memory, or disk specified.

      +
      +
      +
    • +
    +

  • +
  • resources_mode (str) –

    one of ‘fixed’, ‘max-seen’, or ‘max-throughput’. Default is ‘max-seen’. +Sets the strategy to automatically allocate resources to tasks. +- ‘fixed’: allocate cores, memory, and disk specified for each task. +- ‘max-seen’ or ‘auto’: use the cores, memory, and disk given as maximum values to allocate,

    +
    +

    but first try each task by allocating the maximum values seen. Leads +to a good compromise between parallelism and number of retries.

    +
    +
      +
    • +
      ’max-throughput’: Like max-seen, but first tries the task with an

      allocation that maximizes overall throughput.

      +
      +
      +
    • +
    +

    If resources_mode is other than ‘fixed’, preprocessing and +accumulation tasks always use the ‘max-seen’ strategy, as the +former tasks always use the same resources, the latter has a +distribution of resources that increases over time.

    +

  • +
  • split_on_exhaustion (bool) – Whether to split a processing task in half according to its chunksize when it exhausts its +the cores, memory, or disk allocated to it. If False, a task that exhausts resources +permanently fails. Default is True.

  • +
  • fast_terminate_workers (int) – Terminate workers on which tasks have been running longer than average. +The time limit is computed by multiplying the average runtime of tasks +by the value of ‘fast_terminate_workers’. Since there are +legitimately slow tasks, no task may trigger fast termination in +two distinct workers. Less than 1 disables it.

  • +
  • manager_name (str) – Name to refer to this work queue manager. +Sets port to 0 (any available port) if port not given.

  • +
  • port (int or tuple(int, int)) – Port number or range (inclusive of ports )for work queue manager program. +Defaults to 9123 if manager_name not given.

  • +
  • password_file (str) – Location of a file containing a password used to authenticate workers.

  • +
  • ssl (bool or tuple(str, str)) – Enable ssl encryption between manager and workers. If a tuple, then it +should be of the form (key, cert), where key and cert are paths to the files +containing the key and certificate in pem format. If True, auto-signed temporary +key and cert are generated for the session.

  • +
  • extra_input_files (list) – A list of files in the current working directory to send along with each task. +Useful for small custom libraries and configuration files needed by the processor.

  • +
  • x509_proxy (str) – Path to the X509 user proxy. If None (the default), use the value of the +environment variable X509_USER_PROXY, or fallback to the file /tmp/x509up_u${UID} if +exists. If False, disables the default behavior and no proxy is sent.

  • +
  • environment_file (optional, str) – Conda python environment tarball to use. If not given, assume that +the python environment is already setup at the execution site.

  • +
  • wrapper (str) – Wrapper script to run/open python environment tarball. Defaults to python_package_run found in PATH.

  • +
  • treereduction (int) – Number of processed chunks per accumulation task. Defaults is 20.

  • +
  • verbose (bool) – If true, emit a message on each task submission and completion. +Default is false.

  • +
  • print_stdout (bool) – If true (default), print the standard output of work queue task on completion.

  • +
  • debug_log (str) – Filename for debug output

  • +
  • stats_log (str) – Filename for tasks statistics output

  • +
  • transactions_log (str) – Filename for tasks lifetime reports output

  • +
  • tasks_accum_log (str) – Filename for the log of tasks that have been processed and accumulated.

  • +
  • filepath (str) – Path to the parent directory where to create the staging directory. +Default is “.” (current working directory).

  • +
  • custom_init (function, optional) – A function that takes as an argument the queue’s WorkQueue object. +The function is called just before the first work unit is submitted +to the queue.

  • +
+
+
+

Attributes Summary

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

bar_format

chunks_accum_in_mem

chunks_per_accum

chunksize

compression

cores

custom_init

debug_log

disk

dynamic_chunksize

environment_file

events_total

fast_terminate_workers

filepath

gpus

manager_name

master_name

memory

password_file

port

print_stdout

resource_monitor

resources_mode

retries

split_on_exhaustion

ssl

stats_log

status_display_interval

tasks_accum_log

transactions_log

treereduction

verbose

wrapper

x509_proxy

+

Methods Summary

+ + + + + + +

__call__(items, function, accumulator)

Call self as a function.

+

Attributes Documentation

+
+
+bar_format: str | None = None
+
+ +
+
+chunks_accum_in_mem: int | None = None
+
+ +
+
+chunks_per_accum: int | None = None
+
+ +
+
+chunksize: int = 100000
+
+ +
+
+compression: int | None = 9
+
+ +
+
+cores: int | None = None
+
+ +
+
+custom_init: Callable | None = None
+
+ +
+
+debug_log: str | None = None
+
+ +
+
+disk: int | None = None
+
+ +
+
+dynamic_chunksize: Dict | None = None
+
+ +
+
+environment_file: str | None = None
+
+ +
+
+events_total: int | None = None
+
+ +
+
+fast_terminate_workers: int | None = None
+
+ +
+
+filepath: str = '.'
+
+ +
+
+gpus: int | None = None
+
+ +
+
+manager_name: str | None = None
+
+ +
+
+master_name: str | None = None
+
+ +
+
+memory: int | None = None
+
+ +
+
+password_file: str | None = None
+
+ +
+
+port: int | Tuple[int, int] | None = None
+
+ +
+
+print_stdout: bool = False
+
+ +
+
+resource_monitor: str | None = 'off'
+
+ +
+
+resources_mode: str | None = 'max-seen'
+
+ +
+
+retries: int = 2
+
+ +
+
+split_on_exhaustion: bool | None = True
+
+ +
+
+ssl: bool | Tuple[str, str] = False
+
+ +
+
+stats_log: str | None = None
+
+ +
+
+status_display_interval: int | None = 10
+
+ +
+
+tasks_accum_log: str | None = None
+
+ +
+
+transactions_log: str | None = None
+
+ +
+
+treereduction: int = 20
+
+ +
+
+verbose: bool = False
+
+ +
+
+wrapper: str | None = None
+
+ +
+
+x509_proxy: str | None = None
+
+ +

Methods Documentation

+
+
+__call__(items: Iterable, function: Callable, accumulator: Addable | MutableSet | MutableMapping)[source]
+

Call self as a function.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.accumulate.html b/api/coffea.processor.accumulate.html new file mode 100644 index 000000000..6daefbe28 --- /dev/null +++ b/api/coffea.processor.accumulate.html @@ -0,0 +1,147 @@ + + + + + + + + + accumulate — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

accumulate

+
+
+coffea.processor.accumulate(items: Iterable[Addable | MutableSet | MutableMapping | None], accum: Addable | MutableSet | MutableMapping | None = None) Addable | MutableSet | MutableMapping | None[source]
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.column_accumulator.html b/api/coffea.processor.column_accumulator.html new file mode 100644 index 000000000..2481ef45e --- /dev/null +++ b/api/coffea.processor.column_accumulator.html @@ -0,0 +1,234 @@ + + + + + + + + + column_accumulator — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

column_accumulator

+
+
+class coffea.processor.column_accumulator(value)[source]
+

Bases: AccumulatorABC

+

An appendable numpy ndarray

+
+
Parameters:
+

value (numpy.ndarray) – The identity value array, which should be an empty ndarray +with the desired row shape. The column dimension will correspond to +the first index of value shape.

+
+
+

Examples

+

If a set of accumulators is defined as:

+
a = column_accumulator(np.array([]))
+b = column_accumulator(np.array([1., 2., 3.]))
+c = column_accumulator(np.array([4., 5., 6.]))
+
+
+

then:

+
>>> a + b
+column_accumulator(array([1., 2., 3.]))
+>>> c + b + a
+column_accumulator(array([4., 5., 6., 1., 2., 3.]))
+
+
+

Attributes Summary

+ + + + + + +

value

The current value of the column

+

Methods Summary

+ + + + + + + + + +

add(other)

Add another accumulator to this one in-place

identity()

Identity of the accumulator

+

Attributes Documentation

+
+
+value
+

The current value of the column

+

Returns a numpy array where the first dimension is the column dimension

+
+ +

Methods Documentation

+
+
+add(other)[source]
+

Add another accumulator to this one in-place

+
+ +
+
+identity()[source]
+

Identity of the accumulator

+

A value such that any other value added to it will return +the other value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.dask_executor.html b/api/coffea.processor.dask_executor.html new file mode 100644 index 000000000..68cda86b2 --- /dev/null +++ b/api/coffea.processor.dask_executor.html @@ -0,0 +1,170 @@ + + + + + + + + + dask_executor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/coffea.processor.defaultdict_accumulator.html b/api/coffea.processor.defaultdict_accumulator.html new file mode 100644 index 000000000..4d8c86a0e --- /dev/null +++ b/api/coffea.processor.defaultdict_accumulator.html @@ -0,0 +1,199 @@ + + + + + + + + + defaultdict_accumulator — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

defaultdict_accumulator

+
+
+class coffea.processor.defaultdict_accumulator[source]
+

Bases: defaultdict, AccumulatorABC

+

A defaultdict with accumulator semantics

+

See collections.defaultdict for further info. +It is assumed that the contents of the dict have accumulator semantics

+

Methods Summary

+ + + + + + + + + +

add(other)

Add another accumulator to this one in-place

identity()

Identity of the accumulator

+

Methods Documentation

+
+
+add(other)[source]
+

Add another accumulator to this one in-place

+
+ +
+
+identity()[source]
+

Identity of the accumulator

+

A value such that any other value added to it will return +the other value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.dict_accumulator.html b/api/coffea.processor.dict_accumulator.html new file mode 100644 index 000000000..323794afe --- /dev/null +++ b/api/coffea.processor.dict_accumulator.html @@ -0,0 +1,199 @@ + + + + + + + + + dict_accumulator — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

dict_accumulator

+
+
+class coffea.processor.dict_accumulator[source]
+

Bases: dict, AccumulatorABC

+

A dictionary with accumulator semantics

+

See dict for further info. +It is assumed that the contents of the dict have accumulator semantics.

+

Methods Summary

+ + + + + + + + + +

add(other)

Add another accumulator to this one in-place

identity()

Identity of the accumulator

+

Methods Documentation

+
+
+add(other)[source]
+

Add another accumulator to this one in-place

+
+ +
+
+identity()[source]
+

Identity of the accumulator

+

A value such that any other value added to it will return +the other value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.futures_executor.html b/api/coffea.processor.futures_executor.html new file mode 100644 index 000000000..e1309d31c --- /dev/null +++ b/api/coffea.processor.futures_executor.html @@ -0,0 +1,170 @@ + + + + + + + + + futures_executor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/coffea.processor.iterative_executor.html b/api/coffea.processor.iterative_executor.html new file mode 100644 index 000000000..192ab89ff --- /dev/null +++ b/api/coffea.processor.iterative_executor.html @@ -0,0 +1,170 @@ + + + + + + + + + iterative_executor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/coffea.processor.list_accumulator.html b/api/coffea.processor.list_accumulator.html new file mode 100644 index 000000000..833b1516e --- /dev/null +++ b/api/coffea.processor.list_accumulator.html @@ -0,0 +1,198 @@ + + + + + + + + + list_accumulator — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

list_accumulator

+
+
+class coffea.processor.list_accumulator(iterable=(), /)[source]
+

Bases: list, AccumulatorABC

+

A list with accumulator semantics

+

See list for further info

+

Methods Summary

+ + + + + + + + + +

add(other)

Add another accumulator to this one in-place

identity()

Identity of the accumulator

+

Methods Documentation

+
+
+add(other)[source]
+

Add another accumulator to this one in-place

+
+ +
+
+identity()[source]
+

Identity of the accumulator

+

A value such that any other value added to it will return +the other value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.parsl_executor.html b/api/coffea.processor.parsl_executor.html new file mode 100644 index 000000000..ccdbca119 --- /dev/null +++ b/api/coffea.processor.parsl_executor.html @@ -0,0 +1,170 @@ + + + + + + + + + parsl_executor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/coffea.processor.run_spark_job.html b/api/coffea.processor.run_spark_job.html new file mode 100644 index 000000000..d5d40bf4a --- /dev/null +++ b/api/coffea.processor.run_spark_job.html @@ -0,0 +1,177 @@ + + + + + + + + + run_spark_job — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

run_spark_job

+
+
+coffea.processor.run_spark_job(fileset, processor_instance, executor, executor_args={}, spark=None, partitionsize=200000, thread_workers=16)[source]
+

A wrapper to submit spark jobs

+

A convenience wrapper to submit jobs for spark datasets, which is a +dictionary of dataset: [file list] entries. Presently supports reading of +parquet files converted from root. For more customized processing, +e.g. to read other objects from the files and pass them into data frames, +one can write a similar function in their user code.

+
+
Parameters:
+
    +
  • fileset (dict) – dictionary {dataset: [file, file], }

  • +
  • processor_instance (ProcessorABC) –

    An instance of a class deriving from ProcessorABC

    +
    +

    Note

    +

    The processor instance must define all the columns in data and MC that it reads as .columns

    +
    +

  • +
  • executor

    anything that inherits from SparkExecutor like spark_executor

    +

    In general, a function that takes 3 arguments: items, function accumulator +and performs some action equivalent to: +for item in items: accumulator += function(item)

    +

  • +
  • executor_args – arguments to send to the creation of a spark session

  • +
  • spark

    an optional already created spark instance

    +

    if None then we create an ephemeral spark instance using a config

    +

  • +
  • partitionsize – partition size to try to aim for (coalescese only, repartition too expensive)

  • +
  • thread_workers – how many spark jobs to let fly in parallel during processing steps

  • +
+
+
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.set_accumulator.html b/api/coffea.processor.set_accumulator.html new file mode 100644 index 000000000..32349240d --- /dev/null +++ b/api/coffea.processor.set_accumulator.html @@ -0,0 +1,203 @@ + + + + + + + + + set_accumulator — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

set_accumulator

+
+
+class coffea.processor.set_accumulator[source]
+

Bases: set, AccumulatorABC

+

A set with accumulator semantics

+

See set for further info

+

Methods Summary

+ + + + + + + + + +

add(other)

Add another accumulator to this one in-place

identity()

Identity of the accumulator

+

Methods Documentation

+
+
+add(other)[source]
+

Add another accumulator to this one in-place

+
+

Note

+

This replaces set.add behavior, unfortunately. +A workaround is to use set.update, e.g. a.update({'val'})

+
+
+ +
+
+identity()[source]
+

Identity of the accumulator

+

A value such that any other value added to it will return +the other value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.value_accumulator.html b/api/coffea.processor.value_accumulator.html new file mode 100644 index 000000000..74b820c56 --- /dev/null +++ b/api/coffea.processor.value_accumulator.html @@ -0,0 +1,205 @@ + + + + + + + + + value_accumulator — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

value_accumulator

+
+
+class coffea.processor.value_accumulator(default_factory, initial=None)[source]
+

Bases: AccumulatorABC

+

Holds a value of arbitrary type

+
+
Parameters:
+
    +
  • default_factory (callable) – a function that returns an instance of the desired identity value

  • +
  • initial (bool, optional) – an initial value, if the identity is not the desired initial value

  • +
+
+
+

Methods Summary

+ + + + + + + + + +

add(other)

Add another accumulator to this one in-place

identity()

Identity of the accumulator

+

Methods Documentation

+
+
+add(other)[source]
+

Add another accumulator to this one in-place

+
+ +
+
+identity()[source]
+

Identity of the accumulator

+

A value such that any other value added to it will return +the other value

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.processor.work_queue_executor.html b/api/coffea.processor.work_queue_executor.html new file mode 100644 index 000000000..ad907308e --- /dev/null +++ b/api/coffea.processor.work_queue_executor.html @@ -0,0 +1,170 @@ + + + + + + + + + work_queue_executor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/coffea.util.SpeedColumn.html b/api/coffea.util.SpeedColumn.html new file mode 100644 index 000000000..b2d7dc83a --- /dev/null +++ b/api/coffea.util.SpeedColumn.html @@ -0,0 +1,161 @@ + + + + + + + + + SpeedColumn — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

SpeedColumn

+
+
+class coffea.util.SpeedColumn(fmt: str = '.1f', table_column: Column | None = None)[source]
+

Bases: ProgressColumn

+

Renders human readable transfer speed.

+

Methods Summary

+ + + + + + +

render(task)

Show data transfer speed.

+

Methods Documentation

+
+
+render(task: Any) Text[source]
+

Show data transfer speed.

+
+ +
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.util.awkward_rewrap.html b/api/coffea.util.awkward_rewrap.html new file mode 100644 index 000000000..e58a03a49 --- /dev/null +++ b/api/coffea.util.awkward_rewrap.html @@ -0,0 +1,151 @@ + + + + + + + + + awkward_rewrap — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

awkward_rewrap

+
+
+coffea.util.awkward_rewrap(arr, like_what, gfunc)[source]
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.util.deprecate.html b/api/coffea.util.deprecate.html new file mode 100644 index 000000000..ee6013670 --- /dev/null +++ b/api/coffea.util.deprecate.html @@ -0,0 +1,151 @@ + + + + + + + + + deprecate — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

deprecate

+
+
+coffea.util.deprecate(exception, version, date=None)[source]
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.util.load.html b/api/coffea.util.load.html new file mode 100644 index 000000000..8ed6d0ef7 --- /dev/null +++ b/api/coffea.util.load.html @@ -0,0 +1,152 @@ + + + + + + + + + load — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

load

+
+
+coffea.util.load(filename)[source]
+

Load a coffea file from disk

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.util.rewrap_recordarray.html b/api/coffea.util.rewrap_recordarray.html new file mode 100644 index 000000000..bcf731b01 --- /dev/null +++ b/api/coffea.util.rewrap_recordarray.html @@ -0,0 +1,151 @@ + + + + + + + + + rewrap_recordarray — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

rewrap_recordarray

+
+
+coffea.util.rewrap_recordarray(layout, depth, data)[source]
+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/api/coffea.util.rich_bar.html b/api/coffea.util.rich_bar.html new file mode 100644 index 000000000..320a42241 --- /dev/null +++ b/api/coffea.util.rich_bar.html @@ -0,0 +1,151 @@ + + + + + + + + + rich_bar — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/api/coffea.util.save.html b/api/coffea.util.save.html new file mode 100644 index 000000000..fda4bfa45 --- /dev/null +++ b/api/coffea.util.save.html @@ -0,0 +1,153 @@ + + + + + + + + + save — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+ +
+
+ +
+

save

+
+
+coffea.util.save(output, filename)[source]
+

Save a coffea object or collection thereof to disk

+

This function can accept any picklable object. Suggested suffix: .coffea

+
+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/concepts.html b/concepts.html new file mode 100644 index 000000000..c7e60b361 --- /dev/null +++ b/concepts.html @@ -0,0 +1,182 @@ + + + + + + + + + Coffea concepts — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Coffea concepts

+

This page explains concepts and terminology used within the coffea package. +It is intended to provide a high-level overview, while details can be found in other sections of the documentation.

+
+

Columnar analysis

+

Columnar analysis is a paradigm that describes the way the user writes the analysis application that is best described +in contrast to the the traditional paradigm in high-energy particle physics (HEP) of using an event loop. In an event loop, the analysis operates row-wise +on the input data (in HEP, one row usually corresponds to one reconstructed particle collision event.) Each row +is a structure containing several fields, such as the properties of the visible outgoing particles +that were reconstructed in a collision event. The analysis code manipulates this structure to either output derived +quantities or summary statistics in the form of histograms. In contrast, columnar analysis operates on individual +columns of data spanning a chunk (partition, batch) of rows using array programming +primitives in turn, to compute derived quantities and summary statistics. Array programming is widely used within +the scientific python ecosystem, supported by the numpy library. +However, although the existing scientific python stack is fully capable of analyzing rectangular arrays (i.e. +no variable-length array dimensions), HEP data is very irregular, and manipulating it can become awkward without +first generalizing array structure a bit. The awkward package does this, +extending array programming capabilities to the complexity of HEP data.

+_images/columnar.png + +
+
+

Coffea processor

+

In almost all HEP analyses, each row corresponds to an independent event, and it is exceptionally rare +to need to compute inter-row derived quantites. Due to this, horizontal scale-out is almost trivial: +each chunk of rows can be operated on independently. Further, if the output of an analysis is restricted +to reducible accumulators such as histograms (abstracted by AccumulatorABC), then outputs can even be merged via tree reduction. +The ProcessorABC class is an abstraction to encapsulate analysis code so that it can be easily scaled out, leaving +the delivery of input columns and reduction of output accumulators to the coffea framework.

+
+
+

Scale-out

+

Often, the computation requirements of a HEP data analysis exceed the resources of a single thread of execution. +To facilitate parallelization and allow the user to access more compute resources, coffea employs various executors +to ease the transition between a local analysis on a small set of test data to a full-scale analysis. +The executors roughly fall into two categories: local and distributed.

+
+

Local executors

+

Currently, two local executors exist: iterative_executor and futures_executor. +The iterative executor simply processes each chunk of an input dataset in turn, using the current +python thread. The futures executor employs python multiprocessing to spawn multiple python processes +that process chunks in parallel on the machine. Processes are used rather than threads to avoid +performance limitations due to the CPython global interpreter lock.

+
+
+

Distributed executors

+

Currently, coffea supports four types of distributed executors:

+
+
+
+

These executors use their respective underlying libraries to distribute processing tasks over multiple machines.

+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/examples.html b/examples.html new file mode 100644 index 000000000..40ed9b5c4 --- /dev/null +++ b/examples.html @@ -0,0 +1,171 @@ + + + + + + + + + Coffea by Example — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Coffea by Example

+

The following pages are rendered jupyter notebooks that provide an overview and example usage of Coffea features. +Each notebook builds on the previous one so it is recommended to go through them in order.

+ +

A few coffea features are now deprecated in favor of dedicated libraries:

+ +
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/genindex.html b/genindex.html new file mode 100644 index 000000000..85f6810d5 --- /dev/null +++ b/genindex.html @@ -0,0 +1,1661 @@ + + + + + + + + Index — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Index

+ +
+ _ + | A + | B + | C + | D + | E + | F + | G + | H + | I + | J + | K + | L + | M + | N + | P + | R + | S + | T + | U + | V + | W + | X + | Y + | Z + +
+

_

+ + +
+ +

A

+ + + +
+ +

B

+ + + +
+ +

C

+ + + +
+ +

D

+ + + +
+ +

E

+ + + +
+ +

F

+ + + +
+ +

G

+ + + +
+ +

H

+ + + +
+ +

I

+ + + +
+ +

J

+ + + +
+ +

K

+ + +
+ +

L

+ + + +
+ +

M

+ + + +
+ +

N

+ + + +
+ +

P

+ + + +
+ +

R

+ + + +
+ +

S

+ + + +
+ +

T

+ + + +
+ +

U

+ + + +
+ +

V

+ + + +
+ +

W

+ + + +
+ +

X

+ + + +
+ +

Y

+ + +
+ +

Z

+ + +
+ + + +
+
+
+ +
+ +
+

© Copyright 2019, Fermi National Accelerator Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 000000000..1fae01ded --- /dev/null +++ b/index.html @@ -0,0 +1,1332 @@ + + + + + + + + + coffea - Columnar Object Framework For Effective Analysis — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • + View page source +
  • +
+
+
+
+
+ +
+

coffea - Columnar Object Framework For Effective Analysis

+https://zenodo.org/badge/159673139.svg + +https://github.com/CoffeaTeam/coffea/workflows/CI%2FCD/badge.svg + +https://codecov.io/gh/CoffeaTeam/coffea/branch/master/graph/badge.svg?event=schedule + +https://badge.fury.io/py/coffea.svg + +https://img.shields.io/pypi/dm/coffea.svg + +https://img.shields.io/conda/vn/conda-forge/coffea.svg + +https://badges.gitter.im/CoffeaTeam/coffea.svg + +https://mybinder.org/badge_logo.svg + +

Basic tools and wrappers for enabling not-too-alien syntax when running columnar Collider HEP analysis.

+

coffea is a prototype package for pulling together all the typical needs +of a high-energy collider physics (HEP) experiment analysis using the scientific +python ecosystem. It makes use of uproot +and awkward-array to provide an +array-based syntax for manipulating HEP event data in an efficient and numpythonic +way. There are sub-packages that implement histogramming, plotting, and look-up +table functionalities that are needed to convey scientific insight, apply transformations +to data, and correct for discrepancies in Monte Carlo simulations compared to data.

+

coffea also supplies facilities for horizontally scaling an analysis in order to reduce +time-to-insight in a way that is largely independent of the resource the analysis +is being executed on. By making use of modern big-data technologies like +Apache Spark, parsl, +Dask , and Work Queue, +it is possible with coffea to scale a HEP analysis from a testing +on a laptop to: a large multi-core server, computing clusters, and super-computers without +the need to alter or otherwise adapt the analysis code itself.

+

coffea is a HEP community project collaborating with iris-hep +and is currently a prototype. We welcome input to improve its quality as we progress towards +a sensible refactorization into the scientific python ecosystem and a first release. Please +feel free to contribute at our github repo!

+
+
+

Installation

+

Install coffea like any other Python package:

+
pip install coffea
+
+
+

or similar (use sudo, --user, virtualenv, or pip-in-conda if you wish). +For more details, see the Installing coffea section of the documentation.

+
+
+

Strict dependencies

+ +

The following are installed automatically when you install coffea with pip:

+
    +
  • numpy (1.15+);

  • +
  • uproot for interacting with ROOT files and handling their data transparently;

  • +
  • awkward-array to manipulate complex-structured columnar data, such as jagged arrays;

  • +
  • numba just-in-time compilation of python functions;

  • +
  • scipy for many statistical functions;

  • +
  • matplotlib as a plotting backend;

  • +
  • and other utility packages, as enumerated in setup.py.

  • +
+
+
+

Documentation

+

All documentation is hosted at https://coffeateam.github.io/coffea/

+
+ +
+
+
+

Indices and tables

+ +
+ + +
+
+
+ +
+ +
+

© Copyright 2019, Fermi National Accelerator Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/installation.html b/installation.html new file mode 100644 index 000000000..770542553 --- /dev/null +++ b/installation.html @@ -0,0 +1,337 @@ + + + + + + + + + Installing coffea — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Installing coffea

+
+

Quick start

+

To try coffea now, without installing anything, you can experiment with our +hosted tutorial notebooks.

+
+
+

Platform support

+

Coffea is a python package distributed via PyPI. A python installation is required to use coffea. +Python version 3.6 or newer is required.

+

All functional features in each supported python version are routinely tested. +You can see the python version you have installed by typing the following at the command prompt:

+
>>> python --version
+
+
+

or, in some cases, if both python 2 and 3 are available, you can find the python 3 version via:

+
>>> python3 --version
+
+
+

coffea core functionality is routinely tested on Windows, Linux and MacOS. +All Local executors are tested against all three platforms, +however the Distributed executors are not routinely tested on Windows.

+

Coffea starts from v0.5.0 in the PyPI repository since before v0.5.0 it was hosted as fnal-column-analysis-tools. If you are still using fnal-column-analysis-tools, please move to coffea!

+
+
+

Install coffea

+

To install coffea, there are several mostly-equivalent options:

+
+
    +
  • install coffea system-wide using pip install coffea;

  • +
  • if you do not have administrator permissions, install as local user with pip install --user coffea;

  • +
  • if you prefer to not place coffea in your global environment, you can set up a Virtual environment;

  • +
  • if you use Conda, simply conda install coffea;

  • +
  • or, if you like to use containers, see Pre-built images below.

  • +
+
+

To update a previously installed coffea to a newer version, use: pip install --upgrade coffea +Although not required, it is recommended to also install Jupyter, as it provides a more interactive development environment. +The installation procedure is essentially identical as above: pip install jupyter. (If you use conda, conda install jupyter is a better option.)

+

In rare cases, you may find that the pip executable in your path does not correspond to the same python installation as the python executable. This is a sign of a broken python environment. However, this can be bypassed by using the syntax python -m pip ... in place of pip ....

+
+
+

Install optional dependencies

+

Coffea supports several optional components that require additional package installations. +In particular, all of the Distributed executors require additional packages. +The necessary dependencies can be installed easily via pip using the setuptools extras facility:

+
+
    +
  • Apache Spark distributed executor: pip install coffea[spark]

  • +
  • parsl distributed executor: pip install coffea[parsl]

  • +
  • dask distributed executor: pip install coffea[dask]

  • +
  • Work Queue distributed executor: see Work Queue Executor for installation instructions

  • +
+
+

Multiple extras can be installed together via, e.g. pip install coffea[dask,spark]

+
+
+

Virtual environment

+

Virtual environments are a good way to isolate python environments, and ensure no hidden dependencies. +You can find more information at https://docs.python.org/3/library/venv.html

+
python -m venv my_env
+source my_env/bin/activate
+pip install coffea
+
+
+
+
+

Pre-built images

+

A complete coffea + scientific python environment is available as a docker image:

+
docker run -it --name docker-coffea-base coffeateam/coffea-base
+
+
+

More information is available at https://github.com/CoffeaTeam/docker-coffea-base#readme +Additionally there is an image with dask dependencies (including dask-jobqueue):

+
docker run -it --name docker-coffea-dask coffeateam/coffea-dask
+
+
+

With corresponding repo at https://github.com/CoffeaTeam/docker-coffea-dask#readme

+

If you use singularity, there are preconverted images available via the unpacked.cern.ch service. For example, you can start a shell with:

+
singularity shell -B ${PWD}:/work /cvmfs/unpacked.cern.ch/registry.hub.docker.com/coffeateam/coffea-dask:latest
+
+
+
+
+

Install via cvmfs

+

Although the local installation can work anywhere, if the base environment does not already have most of the coffea dependencies, then the user-local package directory can become quite bloated. +An option to avoid this bloat is to use a base python environment provided via CERN LCG, which is available on any system that has the cvmfs directory /cvmfs/sft.cern.ch/ mounted. +Simply source a LCG release (shown here: 98python3) and install:

+
# check your platform: CC7 shown below, for SL6 it would be "x86_64-slc6-gcc8-opt"
+source /cvmfs/sft.cern.ch/lcg/views/LCG_98python3/x86_64-centos7-gcc9-opt/setup.sh  # or .csh, etc.
+pip install --user coffea
+
+
+

This method can be fragile, since the LCG-distributed packages may conflict with the coffea dependencies. In general it is better to define your own environment or use an image.

+
+
+

Creating a portable virtual environment

+

In some instances, it may be useful to have a self-contained environment that can be relocated. +One use case is for users of coffea that do not have access to a distributed compute cluster that is compatible with +one of the coffea distributed executors. Here, a fallback solution can be found by creating traditional batch jobs (e.g. condor) +which then use coffea local executors, possibly multi-threaded. In this case, often the user-local python package directory +is not available from batch workers, so a portable python enviroment needs to be created. +Annoyingly, python virtual environments are not portable by default due to several hardcoded paths in specific locations, however +there are two workarounds presented below. In both cases, we make a virtual environment that starts from a non-system base +python environment to lower the amount of needed installations in the virtual environment. One can always start a venv from scratch, +but the number of coffea dependencies makes the installation rather large, up to a few hundred MB.

+
+

Container-based

+

If we start from one of the singularity containers from the Pre-built images section, we don’t have to install nearly as much +software in our virtual environment, letting the container image take care of the majority of the codebase. For example, the following +code starts from the coffea-dask image and adds a special python module that is not included in the base image:

+
singularity shell -B ${PWD}:/srv /cvmfs/unpacked.cern.ch/registry.hub.docker.com/coffeateam/coffea-dask:latest
+cd /srv
+python -m venv --without-pip --system-site-packages myenv
+source myenv/bin/activate
+python -m pip install --ignore-installed h5py
+
+
+

This creates a virtual environmennt myenv and a directory with the same name where the extra python module h5py will be +installed. At this point, the terminal prompt will look like (myenv) Singularity>, indicating you are inside a singularity +image and have myenv activated. Next time you log in, only lines 1, 2, and 4 need to be re-executed.

+

If using HTCondor for job submission, you can create a tarball of the virtual environment directory and then submit condor +jobs using the +SingularityImage HTCondor option. +Note that this option is not enabled by default in HTCondor installations, so you may need to talk to your site administrator to be +able to use this option. You will also need to create a small wrapper script to re-source the environment to have the job use the +same environment as your interactive container. +A complete example that runs at FNAL LPC is shown in this gist.

+
+
+

LCG-based

+

There are not many locations to edit to make a venv portable, and some sed hacks can save the day. +Here is an example of a bash script that installs coffea on top of the LCG 98python3 software stack inside a portable virtual environment, +with the caveat that cvmfs must be visible from batch workers:

+
#!/usr/bin/env bash
+NAME=coffeaenv
+LCG=/cvmfs/sft.cern.ch/lcg/views/LCG_98python3/x86_64-centos7-gcc9-opt
+
+source $LCG/setup.sh
+# following https://aarongorka.com/blog/portable-virtualenv/, an alternative is https://github.com/pantsbuild/pex
+python -m venv --copies $NAME
+source $NAME/bin/activate
+LOCALPATH=$NAME$(python -c 'import sys; print(f"/lib/python{sys.version_info.major}.{sys.version_info.minor}/site-packages")')
+export PYTHONPATH=${LOCALPATH}:$PYTHONPATH
+python -m pip install setuptools pip wheel --upgrade
+python -m pip install coffea
+sed -i '1s/#!.*python$/#!\/usr\/bin\/env python/' $NAME/bin/*
+sed -i '40s/.*/VIRTUAL_ENV="$(cd "$(dirname "$(dirname "${BASH_SOURCE[0]}" )")" \&\& pwd)"/' $NAME/bin/activate
+sed -i "2a source ${LCG}/setup.sh" $NAME/bin/activate
+sed -i "3a export PYTHONPATH=${LOCALPATH}:\$PYTHONPATH" $NAME/bin/activate
+tar -zcf ${NAME}.tar.gz ${NAME}
+
+
+

The resulting tarball size is about 60 MB. +An example batch job wrapper script is:

+
#!/usr/bin/env bash
+tar -zxf coffeaenv.tar.gz
+source coffeaenv/bin/activate
+
+echo "Running command:" $@
+time $@ || exit $?
+
+
+

Note that this environment only functions from the working directory of the wrapper script due to having relative paths. +Unless you install jupyter into this environment (which may bloat the tarball–LCG98 jupyter is reasonably recent), it is not visible inside the LCG jupyter server. From a shell with the virtual environment activated, you can execute:

+
python -m ipykernel install --user --name=coffeaenv
+
+
+

to make a new kernel available that uses this environment.

+
+
+
+

For Developers

+
    +
  1. Download source:

  2. +
+
+
git clone https://github.com/CoffeaTeam/coffea
+
+
+
+
    +
  1. Install with development dependencies:

  2. +
+
+
cd coffea
+pip install --editable .[dev]
+// or if you need to work on the executors, e.g. dask,
+pip install --editable .[dev,dask]
+
+
+
+
    +
  1. Develop a cool new feature or fix some bugs

  2. +
  3. Lint source, run tests, and build documentation:

  4. +
+
+
flake8 coffea tests setup.py
+black coffea tests setup.py
+pytest tests
+pushd docs && make html && popd
+
+
+
+
    +
  1. Make a pull request!

  2. +
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.analysis_tools.html b/modules/coffea.analysis_tools.html new file mode 100644 index 000000000..d8e7fbba1 --- /dev/null +++ b/modules/coffea.analysis_tools.html @@ -0,0 +1,169 @@ + + + + + + + + + coffea.analysis_tools — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.analysis_tools

+

Tools of general use for columnar analysis

+

These helper classes were previously part of coffea.processor +but have been migrated and updated to be compatible with awkward-array 1.0

+
+

Classes

+ + + + + + + + + + + + +

PackedSelection([dtype])

Store several boolean arrays in a compact manner

WeightStatistics([sumw, sumw2, minw, maxw, n])

Weights(size[, storeIndividual])

Container for event weights and associated systematic shifts

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.analysis_tools.PackedSelection, coffea.analysis_tools.WeightStatistics, coffea.analysis_tools.Weights
+ + + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.btag_tools.html b/modules/coffea.btag_tools.html new file mode 100644 index 000000000..6d9c12ce5 --- /dev/null +++ b/modules/coffea.btag_tools.html @@ -0,0 +1,158 @@ + + + + + + + + + coffea.btag_tools — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.btag_tools

+

BTag tools: CMS analysis-level b-tagging corrections and uncertainties

+

These classes provide computation of CMS b-tagging and mistagging +corrections and uncertainties on columnar data.

+
+

Classes

+ + + + + + +

BTagScaleFactor(filename, workingpoint[, ...])

A class holding one complete BTag scale factor for a given working point

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.btag_tools.btagscalefactor.BTagScaleFactor
+ + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.hist.html b/modules/coffea.hist.html new file mode 100644 index 000000000..af1293d7a --- /dev/null +++ b/modules/coffea.hist.html @@ -0,0 +1,226 @@ + + + + + + + + + coffea.hist — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.hist

+

Histogramming tools

+

coffea.hist is a histogram filling, transformation, and plotting sub-package, utilizing +numpy arrays for storage and matplotlib plotting routines for visualization.

+

Features found in this package are similar to those found in +packages such as histbook (deprecated), +boost-histogram (in development), +physt, and built-in numpy +histogram utilities.

+
+

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

poisson_interval(sumw, sumw2[, coverage])

Frequentist coverage interval for Poisson-distributed observations

clopper_pearson_interval(num, denom[, coverage])

Compute Clopper-Pearson coverage interval for a binomial distribution

normal_interval(pw, tw, pw2, tw2[, coverage])

Compute errors based on the expansion of pass/(pass + fail), possibly weighted

plot1d(hist[, ax, clear, overlay, stack, ...])

Create a 1D plot from a 1D or 2D Hist object

plotratio(num, denom[, ax, clear, overflow, ...])

Create a ratio plot, dividing two compatible histograms

plot2d(hist, xaxis[, ax, clear, xoverflow, ...])

Create a 2D plot from a 2D Hist object

plotgrid(h[, figure, row, col, overlay, ...])

Create a grid of plots, enumerating identifiers on up to 3 axes

export1d(hist)

Export a 1-dimensional Hist object to uproot

+
+
+

Classes

+ + + + + + + + + + + + + + + + + + +

Hist(label, *axes, **kwargs)

Specify a multidimensional histogram.

Bin(name, label, n_or_arr[, lo, hi])

A binned axis with name, label, and binning.

Interval(lo, hi[, label])

Real number interval

Cat(name, label[, sorting])

A category axis with name and label

StringBin(name[, label])

A string used to fill a sparse axis

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.hist.hist_tools.Hist, coffea.hist.hist_tools.Bin, coffea.hist.hist_tools.Interval, coffea.hist.hist_tools.Cat, coffea.hist.hist_tools.StringBin
+ + + + + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.jetmet_tools.html b/modules/coffea.jetmet_tools.html new file mode 100644 index 000000000..c6bd4668f --- /dev/null +++ b/modules/coffea.jetmet_tools.html @@ -0,0 +1,188 @@ + + + + + + + + + coffea.jetmet_tools — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.jetmet_tools

+

JetMET tools: CMS analysis-level jet corrections and uncertainties

+

These classes provide computation of CMS jet energy scale and jet energy resolution +corrections and uncertainties on columnar data.

+
+

Classes

+ + + + + + + + + + + + + + + + + + + + + + + + +

FactorizedJetCorrector(**kwargs)

This class is a columnar implementation of the FactorizedJetCorrector tool in CMSSW and FWLite.

JetResolution(**kwargs)

This class is a columnar implementation of the JetResolution tool in CMSSW and FWLite.

JetResolutionScaleFactor(**kwargs)

This class is a columnar implementation of the JetResolutionScaleFactor tool in CMSSW and FWLite.

JetCorrectionUncertainty(**kwargs)

This class is a columnar implementation of the JetCorrectionUncertainty tool in CMSSW and FWLite.

JECStack(corrections[, jec, junc, jer, jersf])

CorrectedJetsFactory(name_map, jec_stack)

CorrectedMETFactory(name_map)

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.jetmet_tools.FactorizedJetCorrector.FactorizedJetCorrector, coffea.jetmet_tools.JetResolution.JetResolution, coffea.jetmet_tools.JetResolutionScaleFactor.JetResolutionScaleFactor, coffea.jetmet_tools.JetCorrectionUncertainty.JetCorrectionUncertainty, coffea.jetmet_tools.JECStack.JECStack, coffea.jetmet_tools.CorrectedJetsFactory.CorrectedJetsFactory, coffea.jetmet_tools.CorrectedMETFactory.CorrectedMETFactory
+ + + + + + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.lookup_tools.html b/modules/coffea.lookup_tools.html new file mode 100644 index 000000000..2fabd3ac8 --- /dev/null +++ b/modules/coffea.lookup_tools.html @@ -0,0 +1,163 @@ + + + + + + + + + coffea.lookup_tools — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.lookup_tools

+

Lookup tools

+

These classes enable efficient extraction of precomputed lookup tables +from multiple source file formats into a uniform function-call accessor.

+
+

Classes

+ + + + + + + + + +

extractor()

This class defines a common entry point for defining functions that extract the inputs to build lookup tables from various kinds of files.

evaluator(names, types, primitives)

The evaluator class serves as a single point of extry for looking up values of histograms and other functions read in with the extractor class.

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.lookup_tools.extractor.extractor, coffea.lookup_tools.evaluator.evaluator
+ + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.lumi_tools.html b/modules/coffea.lumi_tools.html new file mode 100644 index 000000000..40e359db4 --- /dev/null +++ b/modules/coffea.lumi_tools.html @@ -0,0 +1,169 @@ + + + + + + + + + coffea.lumi_tools — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.lumi_tools

+

Tools to parse CMS luminosity non-event data

+

These tools are currently tailored to the CMS experiment +data formats, however they could be generalized and/or compartmentalized +into a standalone package.

+
+

Classes

+ + + + + + + + + + + + +

LumiData(lumi_csv)

Holds per-lumiSection integrated lumi values

LumiList([runs, lumis])

Mergeable list of unique (run, lumiSection) values

LumiMask(jsonfile)

Holds a luminosity mask index, and provides vectorized lookup

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.lumi_tools.lumi_tools.LumiData, coffea.lumi_tools.lumi_tools.LumiList, coffea.lumi_tools.lumi_tools.LumiMask
+ + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.nanoevents.html b/modules/coffea.nanoevents.html new file mode 100644 index 000000000..f9ae11650 --- /dev/null +++ b/modules/coffea.nanoevents.html @@ -0,0 +1,191 @@ + + + + + + + + + coffea.nanoevents — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.nanoevents

+

NanoEvents and helpers

+
+

Classes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +

NanoEventsFactory(schema, mapping, partition_key)

A factory class to build NanoEvents objects

BaseSchema(base_form)

Base schema builder

NanoAODSchema(base_form[, version])

NanoAOD schema builder

PFNanoAODSchema(base_form[, version])

PFNano schema builder

TreeMakerSchema(base_form)

TreeMaker schema builder

PHYSLITESchema(base_form)

PHYSLITE schema builder - work in progress.

DelphesSchema(base_form[, version])

Delphes schema builder

PDUNESchema(base_form)

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.nanoevents.factory.NanoEventsFactory, coffea.nanoevents.schemas.base.BaseSchema, coffea.nanoevents.schemas.nanoaod.NanoAODSchema, coffea.nanoevents.schemas.nanoaod.PFNanoAODSchema, coffea.nanoevents.schemas.treemaker.TreeMakerSchema, coffea.nanoevents.schemas.physlite.PHYSLITESchema, coffea.nanoevents.schemas.delphes.DelphesSchema, coffea.nanoevents.schemas.pdune.PDUNESchema
+ + + + + + + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.nanoevents.methods.base.html b/modules/coffea.nanoevents.methods.base.html new file mode 100644 index 000000000..31b8a6707 --- /dev/null +++ b/modules/coffea.nanoevents.methods.base.html @@ -0,0 +1,166 @@ + + + + + + + + + coffea.nanoevents.methods.base — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.nanoevents.methods.base

+

Basic NanoEvents and NanoCollection mixins

+
+

Classes

+ + + + + + + + + + + + +

NanoCollection()

A NanoEvents collection

NanoEvents()

NanoEvents mixin class

Systematic()

A base mixin class to describe and build variations on a feature of an nanoevents object.

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.nanoevents.methods.base.NanoCollection, coffea.nanoevents.methods.base.NanoEvents, coffea.nanoevents.methods.base.Systematic
+ + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.nanoevents.methods.candidate.html b/modules/coffea.nanoevents.methods.candidate.html new file mode 100644 index 000000000..d46fb9950 --- /dev/null +++ b/modules/coffea.nanoevents.methods.candidate.html @@ -0,0 +1,176 @@ + + + + + + + + + coffea.nanoevents.methods.candidate — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.nanoevents.methods.candidate

+

Physics object candidate mixin

+

This provides just a Lorentz vector with charge, but maybe +in the future it will provide some sort of composite candiate building tool +that automatically resolves duplicates in the chain.

+
+

Classes

+ + + + + + + + + + + + +

Candidate()

A Lorentz vector with charge

PtEtaPhiMCandidate()

A Lorentz vector in eta, mass coordinates with charge

PtEtaPhiECandidate()

A Lorentz vector in eta, energy coordinates with charge

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.nanoevents.methods.candidate.Candidate, coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate, coffea.nanoevents.methods.candidate.PtEtaPhiECandidate
+ + + + + + + + + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.nanoevents.methods.nanoaod.html b/modules/coffea.nanoevents.methods.nanoaod.html new file mode 100644 index 000000000..580392ec4 --- /dev/null +++ b/modules/coffea.nanoevents.methods.nanoaod.html @@ -0,0 +1,246 @@ + + + + + + + + + coffea.nanoevents.methods.nanoaod — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.nanoevents.methods.nanoaod

+

Mixins for the CMS NanoAOD schema

+
+

Classes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

PtEtaPhiMCollection()

Generic collection that has Lorentz vector properties

GenParticle()

NanoAOD generator-level particle object, including parent and child self-references

GenVisTau()

NanoAOD visible tau object

Electron()

NanoAOD electron object

LowPtElectron()

NanoAOD low-pt electron object

Muon()

NanoAOD muon object

Tau()

NanoAOD tau object

Photon()

NanoAOD photon object

FsrPhoton()

NanoAOD fsr photon object

Jet()

NanoAOD narrow radius jet object

FatJet()

NanoAOD large radius jet object

MissingET()

NanoAOD Missing transverse energy object

Vertex()

NanoAOD vertex object

SecondaryVertex()

NanoAOD secondary vertex object

AssociatedPFCand()

PFNano PF candidate to jet association object

AssociatedSV()

PFNano secondary vertex to jet association object

PFCand()

PFNano particle flow candidate object

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection, coffea.nanoevents.methods.nanoaod.GenParticle, coffea.nanoevents.methods.nanoaod.GenVisTau, coffea.nanoevents.methods.nanoaod.Electron, coffea.nanoevents.methods.nanoaod.LowPtElectron, coffea.nanoevents.methods.nanoaod.Muon, coffea.nanoevents.methods.nanoaod.Tau, coffea.nanoevents.methods.nanoaod.Photon, coffea.nanoevents.methods.nanoaod.FsrPhoton, coffea.nanoevents.methods.nanoaod.Jet, coffea.nanoevents.methods.nanoaod.FatJet, coffea.nanoevents.methods.nanoaod.MissingET, coffea.nanoevents.methods.nanoaod.Vertex, coffea.nanoevents.methods.nanoaod.SecondaryVertex, coffea.nanoevents.methods.nanoaod.AssociatedPFCand, coffea.nanoevents.methods.nanoaod.AssociatedSV, coffea.nanoevents.methods.nanoaod.PFCand
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.nanoevents.methods.vector.html b/modules/coffea.nanoevents.methods.vector.html new file mode 100644 index 000000000..4e3d17a78 --- /dev/null +++ b/modules/coffea.nanoevents.methods.vector.html @@ -0,0 +1,228 @@ + + + + + + + + + coffea.nanoevents.methods.vector — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.nanoevents.methods.vector

+

2D, 3D, and Lorentz vector class mixins

+

These mixins will eventually be superceded by the vector library, +which will hopefully be feature-compatible. The 2D vector provides cartesian and polar coordinate attributes, +where r represents the polar distance from the origin.. The 3D vector provides cartesian and spherical coordinates, +where rho represents the 3D distance from the origin and r is the axial distance from the z axis, so that it can +subclass the 2D vector. The Lorentz vector also subclasses the 3D vector, adding t as the fourth +cartesian coordinate. Aliases typical of momentum vectors are also provided.

+

A small example:

+
import numpy as np
+import awkward as ak
+from coffea.nanoevents.methods import vector
+
+n = 1000
+
+vec = ak.zip(
+    {
+        "x": np.random.normal(size=n),
+        "y": np.random.normal(size=n),
+        "z": np.random.normal(size=n),
+    },
+    with_name="ThreeVector",
+    behavior=vector.behavior,
+)
+
+vec4 = ak.zip(
+    {
+        "pt": vec.r,
+        "eta": -np.log(np.tan(vec.theta/2)),
+        "phi": vec.phi,
+        "mass": np.full(n, 1.),
+    },
+    with_name="PtEtaPhiMLorentzVector",
+    behavior=vector.behavior,
+)
+
+assert np.allclose(np.array(vec4.x), np.array(vec.x))
+assert np.allclose(np.array(vec4.y), np.array(vec.y))
+assert np.allclose(np.array(vec4.z), np.array(vec.z))
+assert np.allclose(np.array(abs(2*vec + vec4) / abs(vec)), 3)
+
+
+
+

Classes

+ + + + + + + + + + + + + + + + + + + + + + + + +

TwoVector()

A cartesian 2-dimensional vector

PolarTwoVector()

A polar coordinate 2-dimensional vector

ThreeVector()

A cartesian 3-dimensional vector

SphericalThreeVector()

A spherical coordinate 3-dimensional vector

LorentzVector()

A cartesian Lorentz vector

PtEtaPhiMLorentzVector()

A Lorentz vector using pseudorapidity and mass

PtEtaPhiELorentzVector()

A Lorentz vector using pseudorapidity and energy

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.nanoevents.methods.vector.TwoVector, coffea.nanoevents.methods.vector.PolarTwoVector, coffea.nanoevents.methods.vector.ThreeVector, coffea.nanoevents.methods.vector.SphericalThreeVector, coffea.nanoevents.methods.vector.LorentzVector, coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector, coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector
+ + + + + + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.processor.html b/modules/coffea.processor.html new file mode 100644 index 000000000..4545b7de2 --- /dev/null +++ b/modules/coffea.processor.html @@ -0,0 +1,292 @@ + + + + + + + + + coffea.processor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.processor

+

A framework for analysis scale-out

+
+

Functions

+ + + + + + + + + +

run_spark_job(fileset, processor_instance, ...)

A wrapper to submit spark jobs

accumulate(items[, accum])

+
+
+

Classes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

ProcessorABC()

ABC for a generalized processor

LazyDataFrame(tree[, entrystart, entrystop, ...])

Simple delayed uproot reader (a la lazyarrays)

Weights(size[, storeIndividual])

Container for event weights and associated systematic shifts

PackedSelection([dtype])

Store boolean mask vectors in a compact manner

IterativeExecutor([status, unit, desc, ...])

Execute in one thread iteratively

FuturesExecutor(status, unit, desc, ...)

Execute using multiple local cores using python futures

DaskExecutor([status, unit, desc, ...])

Execute using dask futures

ParslExecutor([status, unit, desc, ...])

Execute using parsl pyapp wrapper

WorkQueueExecutor(status, unit, desc, ...)

Execute using Work Queue

Runner(executor, pre_executor, chunksize, ...)

A tool to run a processor using uproot for data delivery

AccumulatorABC()

Abstract base class for an accumulator

value_accumulator(default_factory[, initial])

Holds a value of arbitrary type

list_accumulator([iterable])

A list with accumulator semantics

set_accumulator

A set with accumulator semantics

dict_accumulator

A dictionary with accumulator semantics

defaultdict_accumulator

A defaultdict with accumulator semantics

column_accumulator(value)

An appendable numpy ndarray

NanoAODSchema(base_form[, version])

NanoAOD schema builder

TreeMakerSchema(base_form)

TreeMaker schema builder

iterative_executor

alias of IterativeExecutor

futures_executor

alias of FuturesExecutor

dask_executor

alias of DaskExecutor

parsl_executor

alias of ParslExecutor

work_queue_executor

alias of WorkQueueExecutor

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.processor.processor.ProcessorABC, coffea.processor.dataframe.LazyDataFrame, coffea.processor.helpers.Weights, coffea.processor.helpers.PackedSelection, coffea.processor.executor.IterativeExecutor, coffea.processor.executor.FuturesExecutor, coffea.processor.executor.DaskExecutor, coffea.processor.executor.ParslExecutor, coffea.processor.executor.WorkQueueExecutor, coffea.processor.executor.Runner, coffea.processor.accumulator.AccumulatorABC, coffea.processor.accumulator.value_accumulator, coffea.processor.accumulator.list_accumulator, coffea.processor.accumulator.set_accumulator, coffea.processor.accumulator.dict_accumulator, coffea.processor.accumulator.defaultdict_accumulator, coffea.processor.accumulator.column_accumulator, coffea.nanoevents.schemas.nanoaod.NanoAODSchema, coffea.nanoevents.schemas.treemaker.TreeMakerSchema, coffea.processor.executor.IterativeExecutor, coffea.processor.executor.FuturesExecutor, coffea.processor.executor.DaskExecutor, coffea.processor.executor.ParslExecutor, coffea.processor.executor.WorkQueueExecutor
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/modules/coffea.util.html b/modules/coffea.util.html new file mode 100644 index 000000000..261c02358 --- /dev/null +++ b/modules/coffea.util.html @@ -0,0 +1,221 @@ + + + + + + + + + coffea.util — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

coffea.util

+

Utility functions

+
+

Functions

+ + + + + + + + + + + + + + + + + + + + + +

awkward_rewrap(arr, like_what, gfunc)

deprecate(exception, version[, date])

load(filename)

Load a coffea file from disk

rewrap_recordarray(layout, depth, data)

rich_bar()

save(output, filename)

Save a coffea object or collection thereof to disk

+
+
+

Classes

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Any(*args, **kwargs)

Special type indicating an unconstrained type.

BarColumn([bar_width, style, ...])

Renders a visual progress bar.

Column(header, footer, header_style, ...)

Defines a column within a ~Table.

Progress(*columns[, console, auto_refresh, ...])

Renders an auto-updating progress bar(s).

ProgressColumn([table_column])

Base class for a widget to use in progress display.

SpeedColumn([fmt, table_column])

Renders human readable transfer speed.

Text([text, style, justify, overflow, ...])

Text with color / style.

TextColumn(text_format[, style, justify, ...])

A column containing text.

TimeElapsedColumn([table_column])

Renders time elapsed.

TimeRemainingColumn([compact, ...])

Renders estimated time remaining.

partial

partial(func, *args, **keywords) - new function with partial application of the given arguments and keywords.

+
+
+

Class Inheritance Diagram

+
Inheritance diagram of coffea.util.SpeedColumn
+ + + +
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/notebooks/accumulators.html b/notebooks/accumulators.html new file mode 100644 index 000000000..d48261929 --- /dev/null +++ b/notebooks/accumulators.html @@ -0,0 +1,652 @@ + + + + + + + + + Analysis tools and accumulators — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Analysis tools and accumulators

+

This is a rendered copy of accumulators.ipynb. You can optionally run it interactively on binder at this link

+

Now that we know how to access data with NanoEvents and apply corrections, let’s go through some useful columnar analysis tools and idioms for building accumulators, namely, the eventual output of a coffea processor that has natural “merge” semantics. The most familiar type of accumulator is the histogram, but other types are useful in certain contexts.

+

We’ll use our small sample file to demonstrate the utilities, although it won’t be very interesting to analyze

+
+
[1]:
+
+
+
import numpy as np
+import awkward as ak
+from coffea.nanoevents import NanoEventsFactory, NanoAODSchema
+
+fname = "https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/nano_dy.root"
+events = NanoEventsFactory.from_root(
+    fname,
+    schemaclass=NanoAODSchema.v6,
+    metadata={"dataset": "DYJets"},
+).events()
+
+
+
+

To generate some mock systematics, we’ll use one of the scale factors from the applying_corrections notebook (note you will have to at least execute the cell that downloads test data in that notebook for this to work)

+
+
[2]:
+
+
+
from coffea.lookup_tools import extractor
+
+ext = extractor()
+ext.add_weight_sets(["* * data/testSF2d.histo.root"])
+ext.finalize()
+evaluator = ext.make_evaluator()
+evaluator.keys()
+
+
+
+
+
[2]:
+
+
+
+
+dict_keys(['scalefactors_Tight_Electron', 'scalefactors_Tight_Electron_error'])
+
+
+
+

Weights

+

This is a container for event weights and associated systematic shifts, which helps track the product of the weights (i.e. the total event weight to be used for filling histograms) as well as systematic variations to that product. Here we demo its use by constructing an event weight consisting of the generator weight, the \(\alpha_s\) uncertainty variation, and the electron ID scale factor with its associated systematic.

+
+
[3]:
+
+
+
from coffea.analysis_tools import Weights
+
+weights = Weights(len(events))
+
+weights.add("genWeight", events.genWeight)
+
+weights.add(
+    "alphaS",
+    # in NanoAOD, the generator weights are already stored with respect to nominal
+    weight=np.ones(len(events)),
+    # 31 => alphas(MZ)=0.1165 central value; 32 => alphas(MZ)=0.1195
+    # per https://lhapdfsets.web.cern.ch/current/PDF4LHC15_nnlo_30_pdfas/PDF4LHC15_nnlo_30_pdfas.info
+    # which was found by looking up the LHA ID in events.LHEPdfWeight.__doc__
+    weightUp=events.LHEPdfWeight[:, 32],
+    weightDown=events.LHEPdfWeight[:, 31],
+)
+
+eleSF = evaluator["scalefactors_Tight_Electron"](events.Electron.eta, events.Electron.pt)
+eleSFerror = evaluator["scalefactors_Tight_Electron_error"](events.Electron.eta, events.Electron.pt)
+weights.add(
+    "eleSF",
+    # the event weight is the product of the per-electron weights
+    # note, in a real analysis we would first have to select electrons of interest
+    weight=ak.prod(eleSF, axis=1),
+    weightUp=ak.prod(eleSF + eleSFerror, axis=1),
+)
+
+
+
+

A WeightStatistics object tracks the smallest and largest weights seen per type, as well as some other summary statistics. It is kept internally and can be accessed via weights.weightStatistics. This object is addable, so it can be used in an accumulator.

+
+
[4]:
+
+
+
weights.weightStatistics
+
+
+
+
+
[4]:
+
+
+
+
+{'genWeight': WeightStatistics(sumw=578762.4375, sumw2=27678371840.0, minw=-26331.201171875, maxw=26331.201171875, n=40),
+ 'alphaS': WeightStatistics(sumw=40.0, sumw2=40.0, minw=1.0, maxw=1.0, n=40),
+ 'eleSF': WeightStatistics(sumw=38.26972579956055, sumw2=36.81547546386719, minw=0.6674144268035889, maxw=1.0077519416809082, n=40)}
+
+
+

Then the total event weight is available via

+
+
[5]:
+
+
+
weights.weight()
+
+
+
+
+
[5]:
+
+
+
+
+array([ 26331.20117188,  23933.4196682 ,  24385.06528643,  17224.10489525,
+        26331.20117188,  26535.31910775, -23236.21447283,  26067.890625  ,
+        26331.20117188,  25105.68057538,  26331.20117188,  26061.82814944,
+        26061.82814944, -26331.20117188,  26331.20117188,  24421.85661211,
+       -24854.62516629,  26331.20117188, -19978.69273076,  26331.20117188,
+        22168.68846612, -25134.17258657,  26331.20117188,  26331.20117188,
+        26331.20117188,  24770.33051391,  26331.20117188,  22732.29949574,
+        26331.20117188,  24421.85661211,  26331.20117188,  25857.1530546 ,
+        26331.20117188, -23903.50101615,  26331.20117188, -24770.33051391,
+        26331.20117188, -24906.05914783,  26331.20117188, -26331.20117188])
+
+
+

And the total event weight with a given variation is available via

+
+
[6]:
+
+
+
weights.weight("eleSFUp")
+
+
+
+
+
[6]:
+
+
+
+
+array([ 26331.20117188,  24397.53583916,  25294.0252539 ,  17997.89462374,
+        26331.20117188,  27253.27428405, -23502.68164558,  26067.890625  ,
+        26331.20117188,  25230.22218679,  26331.20117188,  26779.78332574,
+        26779.78332574, -26331.20117188,  26331.20117188,  24885.97278307,
+       -24977.92136851,  26331.20117188, -20983.93483174,  26331.20117188,
+        22734.27398292, -25869.18763094,  26331.20117188,  26331.20117188,
+        26331.20117188,  25448.12088952,  26331.20117188,  22998.76666849,
+        26331.20117188,  24885.97278307,  26331.20117188,  26254.27086417,
+        26331.20117188, -24141.51091823,  26331.20117188, -25448.12088952,
+        26331.20117188, -25583.84952343,  26331.20117188, -26331.20117188])
+
+
+

all variations tracked by the weights object are available via

+
+
[7]:
+
+
+
weights.variations
+
+
+
+
+
[7]:
+
+
+
+
+{'alphaSDown', 'alphaSUp', 'eleSFDown', 'eleSFUp'}
+
+
+
+
+

PackedSelection

+

This class can store several boolean arrays in a memory-efficient mannner and evaluate arbitrary combinations of boolean requirements in an CPU-efficient way. Supported inputs include 1D numpy or awkward arrays. This makes it a good tool to form analysis signal and control regions, and to implement cutflow or “N-1” plots.

+

Below we create a packed selection with some typical selections for a Z+jets study, to be used later to form same-sign and opposite-sign \(ee\) and \(\mu\mu\) event categories/regions.

+
+
[8]:
+
+
+
from coffea.analysis_tools import PackedSelection
+
+selection = PackedSelection()
+
+selection.add("twoElectron", ak.num(events.Electron) == 2)
+selection.add("eleOppSign", ak.sum(events.Electron.charge, axis=1) == 0)
+selection.add("noElectron", ak.num(events.Electron) == 0)
+
+selection.add("twoMuon", ak.num(events.Muon) == 2)
+selection.add("muOppSign", ak.sum(events.Muon.charge, axis=1) == 0)
+selection.add("noMuon", ak.num(events.Muon) == 0)
+
+
+selection.add(
+    "leadPt20",
+    # assuming one of `twoElectron` or `twoMuon` is imposed, this implies at least one is above threshold
+    ak.any(events.Electron.pt >= 20.0, axis=1) | ak.any(events.Muon.pt >= 20.0, axis=1)
+)
+
+print(selection.names)
+
+
+
+
+
+
+
+
+['twoElectron', 'eleOppSign', 'noElectron', 'twoMuon', 'muOppSign', 'noMuon', 'leadPt20']
+
+
+

To evaluate a boolean mask (e.g. to filter events) we can use the selection.all(*names) function, which will compute the AND of all listed boolean selections

+
+
[9]:
+
+
+
selection.all("twoElectron", "noMuon", "leadPt20")
+
+
+
+
+
[9]:
+
+
+
+
+array([False, False,  True, False, False, False, False, False, False,
+       False, False, False, False, False, False, False, False, False,
+       False, False,  True,  True, False, False, False, False, False,
+       False, False, False, False, False, False, False, False, False,
+       False, False, False, False])
+
+
+

We can also be more specific and require that a specific set of selections have a given value (with the unspecified ones allowed to be either true or false) using selection.require

+
+
[10]:
+
+
+
selection.require(twoElectron=True, noMuon=True, eleOppSign=False)
+
+
+
+
+
[10]:
+
+
+
+
+array([False, False, False,  True, False, False, False, False, False,
+       False, False, False, False, False, False, False, False, False,
+       False, False, False, False, False, False, False, False, False,
+       False, False, False, False, False, False, False, False, False,
+       False, False, False, False])
+
+
+

Using the python syntax for passing an arguments variable, we can easily implement a “N-1” style selection

+
+
[11]:
+
+
+
allCuts = {"twoElectron", "noMuon", "leadPt20"}
+for cut in allCuts:
+    nev = selection.all(*(allCuts - {cut})).sum()
+    print(f"Events passing all cuts, ignoring {cut}: {nev}")
+
+nev = selection.all(*allCuts).sum()
+print(f"Events passing all cuts: {nev}")
+
+
+
+
+
+
+
+
+Events passing all cuts, ignoring noMuon: 3
+Events passing all cuts, ignoring twoElectron: 10
+Events passing all cuts, ignoring leadPt20: 5
+Events passing all cuts: 3
+
+
+
+
+

Accumulator semantics

+

Prior to coffea 0.7.2, accumulators were more explicit in that they inherited from AccumulatorABC. Such accumulators are still supported, but now the requirements for an acuumulator output of a processor have been relaxed to the protocol:

+
class Addable(Protocol):
+    def __add__(self: T, other: T) -> T:
+        ...
+
+
+Accumulatable = Union[Addable, MutableSet, MutableMapping]
+
+
+

Essentially, any item that can be added, any set, or any dictionary of the above, can be used as an accumulator:

+
+
[12]:
+
+
+
from coffea.processor import accumulate
+
+accumulate([
+    {"num": 0, "val": 3.1},
+    {"num": 2, "val": 4.0, "thing": {"a", "b"}},
+    {"num": 2, "val": 4.0, "thing": {"a", "c"}},
+])
+
+
+
+
+
[12]:
+
+
+
+
+{'num': 4, 'val': 11.1, 'thing': {'a', 'b', 'c'}}
+
+
+

Since hist histograms are addable, they can be used as well:

+
+
[13]:
+
+
+
import hist
+
+def makehist():
+    return hist.Hist.new.Reg(10, 0, 1).Double()
+
+h = accumulate([
+    makehist().fill([0.1, 0.1, 0.3]),
+    makehist().fill([0.1, 0.3, 0.5]),
+])
+print(h.values())
+h
+
+
+
+
+
+
+
+
+[0. 3. 0. 2. 0. 1. 0. 0. 0. 0.]
+
+
+
+
[13]:
+
+
+
+ +
+
+ + + +0 + + +1 + + +Axis 0 + + + +
+
+Regular(10, 0, 1, label='Axis 0')
+
+Double() Σ=6.0 + +
+
+
+
+
+

Bringing it together

+

Let’s build an output accumulator that stores, per dataset: - the sum of weights for the events processed, to use for later luminosity-normalizing the yields; - a histogram of the dilepton invariant mass, with category axes for various selection regions of interest and systematics; and - the weight statistics, for debugging purposes

+
+
[14]:
+
+
+
regions = {
+    "ee": {"twoElectron": True, "noMuon": True, "leadPt20": True, "eleOppSign": True},
+    "eeSS": {"twoElectron": True, "noMuon": True, "leadPt20": True, "eleOppSign": False},
+    "mm": {"twoMuon": True, "noElectron": True, "leadPt20": True, "muOppSign": True},
+    "mmSS": {"twoMuon": True, "noElectron": True, "leadPt20": True, "muOppSign": False},
+}
+
+masshist = (
+    hist.Hist.new
+    .StrCat(regions.keys(), name="region")
+    .StrCat(["nominal"] + list(weights.variations), name="systematic")
+    .Reg(60, 60, 120, name="mass", label="$m_{ll}$ [GeV]")
+    .Weight()
+)
+
+for region, cuts in regions.items():
+    goodevent = selection.require(**cuts)
+
+    if region.startswith("ee"):
+        mass = events.Electron[goodevent].sum().mass
+    elif region.startswith("mm"):
+        mass = events.Muon[goodevent].sum().mass
+
+    masshist.fill(
+        region=region,
+        systematic="nominal",
+        mass=mass,
+        weight=weights.weight()[goodevent],
+    )
+    for syst in weights.variations:
+        masshist.fill(
+            region=region,
+            systematic=syst,
+            mass=mass,
+            weight=weights.weight(syst)[goodevent],
+        )
+
+out = {
+    events.metadata["dataset"]: {
+        "sumw": ak.sum(events.genWeight),
+        "mass": masshist,
+        "weightStats": weights.weightStatistics,
+    }
+}
+
+out
+
+
+
+
+
[14]:
+
+
+
+
+{'DYJets': {'sumw': 578762.44,
+  'mass': Hist(
+    StrCategory(['ee', 'eeSS', 'mm', 'mmSS'], name='region', label='region'),
+    StrCategory(['nominal', 'alphaSUp', 'eleSFUp', 'alphaSDown', 'eleSFDown'], name='systematic', label='systematic'),
+    Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]'),
+    storage=Weight()) # Sum: WeightedSum(value=621215, variance=2.20829e+10),
+  'weightStats': {'genWeight': WeightStatistics(sumw=578762.4375, sumw2=27678371840.0, minw=-26331.201171875, maxw=26331.201171875, n=40),
+   'alphaS': WeightStatistics(sumw=40.0, sumw2=40.0, minw=1.0, maxw=1.0, n=40),
+   'eleSF': WeightStatistics(sumw=38.26972579956055, sumw2=36.81547546386719, minw=0.6674144268035889, maxw=1.0077519416809082, n=40)}}}
+
+
+

The cell below demonstrates that indeed this output is accumulatable. So if we were to return such a result from a coffea processor, we would be all ready to process thousands of files!

+
+
[15]:
+
+
+
accumulate([out, out])
+
+
+
+
+
[15]:
+
+
+
+
+{'DYJets': {'mass': Hist(
+    StrCategory(['ee', 'eeSS', 'mm', 'mmSS'], name='region', label='region'),
+    StrCategory(['nominal', 'alphaSUp', 'eleSFUp', 'alphaSDown', 'eleSFDown'], name='systematic', label='systematic'),
+    Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]'),
+    storage=Weight()) # Sum: WeightedSum(value=1.24243e+06, variance=4.41659e+10),
+  'weightStats': {'genWeight': WeightStatistics(sumw=1157524.875, sumw2=55356743680.0, minw=-26331.201171875, maxw=26331.201171875, n=80),
+   'alphaS': WeightStatistics(sumw=80.0, sumw2=80.0, minw=1.0, maxw=1.0, n=80),
+   'eleSF': WeightStatistics(sumw=76.5394515991211, sumw2=73.63095092773438, minw=0.6674144268035889, maxw=1.0077519416809082, n=80)},
+  'sumw': 1157524.9}}
+
+
+

The mass histogram itself is not very interesting with only 40 input events, however

+
+
[16]:
+
+
+
out["DYJets"]["mass"][sum, "nominal", :]
+
+
+
+
+
[16]:
+
+
+
+ +
+
+ + + +60 + + +120 + + +$m_{ll}$ [GeV] + + + +
+
+Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]')
+
+Weight() Σ=WeightedSum(value=126744, variance=4.49114e+09) + +
+
+
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/notebooks/accumulators.ipynb b/notebooks/accumulators.ipynb new file mode 100644 index 000000000..a5ae2c31f --- /dev/null +++ b/notebooks/accumulators.ipynb @@ -0,0 +1,693 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Analysis tools and accumulators\n", + "\n", + "This is a rendered copy of [accumulators.ipynb](https://github.com/CoffeaTeam/coffea/blob/master/binder/accumulators.ipynb). You can optionally run it interactively on [binder at this link](https://mybinder.org/v2/gh/coffeateam/coffea/master?filepath=binder%2Faccumulators.ipynb)\n", + "\n", + "Now that we know how to access data with NanoEvents and apply corrections, let's go through some useful columnar analysis tools and idioms for building _accumulators_, namely, the eventual output of a coffea processor that has natural \"merge\" semantics. The most familiar type of accumulator is the histogram, but other types are useful in certain contexts.\n", + "\n", + "We'll use our small sample file to demonstrate the utilities, although it won't be very interesting to analyze" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import awkward as ak\n", + "from coffea.nanoevents import NanoEventsFactory, NanoAODSchema\n", + "\n", + "fname = \"https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/nano_dy.root\"\n", + "events = NanoEventsFactory.from_root(\n", + " fname,\n", + " schemaclass=NanoAODSchema.v6,\n", + " metadata={\"dataset\": \"DYJets\"},\n", + ").events()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To generate some mock systematics, we'll use one of the scale factors from the applying_corrections notebook (note you will have to at least execute the cell that downloads test data in that notebook for this to work)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "dict_keys(['scalefactors_Tight_Electron', 'scalefactors_Tight_Electron_error'])" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from coffea.lookup_tools import extractor\n", + "\n", + "ext = extractor()\n", + "ext.add_weight_sets([\"* * data/testSF2d.histo.root\"])\n", + "ext.finalize()\n", + "evaluator = ext.make_evaluator()\n", + "evaluator.keys()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Weights\n", + "\n", + "This is a container for event weights and associated systematic shifts, which helps track the product of the weights (i.e. the total event weight to be used for filling histograms) as well as systematic variations to that product. Here we demo its use by constructing an event weight consisting of the generator weight, the $\\alpha_s$ uncertainty variation, and the electron ID scale factor with its associated systematic." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "from coffea.analysis_tools import Weights\n", + "\n", + "weights = Weights(len(events))\n", + "\n", + "weights.add(\"genWeight\", events.genWeight)\n", + "\n", + "weights.add(\n", + " \"alphaS\",\n", + " # in NanoAOD, the generator weights are already stored with respect to nominal\n", + " weight=np.ones(len(events)),\n", + " # 31 => alphas(MZ)=0.1165 central value; 32 => alphas(MZ)=0.1195\n", + " # per https://lhapdfsets.web.cern.ch/current/PDF4LHC15_nnlo_30_pdfas/PDF4LHC15_nnlo_30_pdfas.info\n", + " # which was found by looking up the LHA ID in events.LHEPdfWeight.__doc__\n", + " weightUp=events.LHEPdfWeight[:, 32],\n", + " weightDown=events.LHEPdfWeight[:, 31],\n", + ")\n", + "\n", + "eleSF = evaluator[\"scalefactors_Tight_Electron\"](events.Electron.eta, events.Electron.pt)\n", + "eleSFerror = evaluator[\"scalefactors_Tight_Electron_error\"](events.Electron.eta, events.Electron.pt)\n", + "weights.add(\n", + " \"eleSF\",\n", + " # the event weight is the product of the per-electron weights\n", + " # note, in a real analysis we would first have to select electrons of interest\n", + " weight=ak.prod(eleSF, axis=1),\n", + " weightUp=ak.prod(eleSF + eleSFerror, axis=1),\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A [WeightStatistics](https://coffeateam.github.io/coffea/api/coffea.analysis_tools.WeightStatistics.html) object tracks the smallest and largest weights seen per type, as well as some other summary statistics. It is kept internally and can be accessed via `weights.weightStatistics`. This object is addable, so it can be used in an accumulator." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'genWeight': WeightStatistics(sumw=578762.4375, sumw2=27678371840.0, minw=-26331.201171875, maxw=26331.201171875, n=40),\n", + " 'alphaS': WeightStatistics(sumw=40.0, sumw2=40.0, minw=1.0, maxw=1.0, n=40),\n", + " 'eleSF': WeightStatistics(sumw=38.26972579956055, sumw2=36.81547546386719, minw=0.6674144268035889, maxw=1.0077519416809082, n=40)}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights.weightStatistics" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Then the total event weight is available via" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 26331.20117188, 23933.4196682 , 24385.06528643, 17224.10489525,\n", + " 26331.20117188, 26535.31910775, -23236.21447283, 26067.890625 ,\n", + " 26331.20117188, 25105.68057538, 26331.20117188, 26061.82814944,\n", + " 26061.82814944, -26331.20117188, 26331.20117188, 24421.85661211,\n", + " -24854.62516629, 26331.20117188, -19978.69273076, 26331.20117188,\n", + " 22168.68846612, -25134.17258657, 26331.20117188, 26331.20117188,\n", + " 26331.20117188, 24770.33051391, 26331.20117188, 22732.29949574,\n", + " 26331.20117188, 24421.85661211, 26331.20117188, 25857.1530546 ,\n", + " 26331.20117188, -23903.50101615, 26331.20117188, -24770.33051391,\n", + " 26331.20117188, -24906.05914783, 26331.20117188, -26331.20117188])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights.weight()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the total event weight with a given variation is available via" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([ 26331.20117188, 24397.53583916, 25294.0252539 , 17997.89462374,\n", + " 26331.20117188, 27253.27428405, -23502.68164558, 26067.890625 ,\n", + " 26331.20117188, 25230.22218679, 26331.20117188, 26779.78332574,\n", + " 26779.78332574, -26331.20117188, 26331.20117188, 24885.97278307,\n", + " -24977.92136851, 26331.20117188, -20983.93483174, 26331.20117188,\n", + " 22734.27398292, -25869.18763094, 26331.20117188, 26331.20117188,\n", + " 26331.20117188, 25448.12088952, 26331.20117188, 22998.76666849,\n", + " 26331.20117188, 24885.97278307, 26331.20117188, 26254.27086417,\n", + " 26331.20117188, -24141.51091823, 26331.20117188, -25448.12088952,\n", + " 26331.20117188, -25583.84952343, 26331.20117188, -26331.20117188])" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights.weight(\"eleSFUp\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "all variations tracked by the `weights` object are available via" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'alphaSDown', 'alphaSUp', 'eleSFDown', 'eleSFUp'}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "weights.variations" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## PackedSelection\n", + "\n", + "This class can store several boolean arrays in a memory-efficient mannner and evaluate arbitrary combinations of boolean requirements in an CPU-efficient way. Supported inputs include 1D numpy or awkward arrays. This makes it a good tool to form analysis signal and control regions, and to implement cutflow or \"N-1\" plots.\n", + "\n", + "Below we create a packed selection with some typical selections for a Z+jets study, to be used later to form same-sign and opposite-sign $ee$ and $\\mu\\mu$ event categories/regions." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['twoElectron', 'eleOppSign', 'noElectron', 'twoMuon', 'muOppSign', 'noMuon', 'leadPt20']\n" + ] + } + ], + "source": [ + "from coffea.analysis_tools import PackedSelection\n", + "\n", + "selection = PackedSelection()\n", + "\n", + "selection.add(\"twoElectron\", ak.num(events.Electron) == 2)\n", + "selection.add(\"eleOppSign\", ak.sum(events.Electron.charge, axis=1) == 0)\n", + "selection.add(\"noElectron\", ak.num(events.Electron) == 0)\n", + "\n", + "selection.add(\"twoMuon\", ak.num(events.Muon) == 2)\n", + "selection.add(\"muOppSign\", ak.sum(events.Muon.charge, axis=1) == 0)\n", + "selection.add(\"noMuon\", ak.num(events.Muon) == 0)\n", + "\n", + "\n", + "selection.add(\n", + " \"leadPt20\",\n", + " # assuming one of `twoElectron` or `twoMuon` is imposed, this implies at least one is above threshold\n", + " ak.any(events.Electron.pt >= 20.0, axis=1) | ak.any(events.Muon.pt >= 20.0, axis=1)\n", + ")\n", + "\n", + "print(selection.names)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To evaluate a boolean mask (e.g. to filter events) we can use the `selection.all(*names)` function, which will compute the AND of all listed boolean selections" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([False, False, True, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, True, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False])" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "selection.all(\"twoElectron\", \"noMuon\", \"leadPt20\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also be more specific and require that a specific set of selections have a given value (with the unspecified ones allowed to be either true or false) using `selection.require`" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([False, False, False, True, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False, False, False, False, False, False,\n", + " False, False, False, False])" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "selection.require(twoElectron=True, noMuon=True, eleOppSign=False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Using the python syntax for passing an arguments variable, we can easily implement a \"N-1\" style selection" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Events passing all cuts, ignoring noMuon: 3\n", + "Events passing all cuts, ignoring twoElectron: 10\n", + "Events passing all cuts, ignoring leadPt20: 5\n", + "Events passing all cuts: 3\n" + ] + } + ], + "source": [ + "allCuts = {\"twoElectron\", \"noMuon\", \"leadPt20\"}\n", + "for cut in allCuts:\n", + " nev = selection.all(*(allCuts - {cut})).sum()\n", + " print(f\"Events passing all cuts, ignoring {cut}: {nev}\")\n", + "\n", + "nev = selection.all(*allCuts).sum()\n", + "print(f\"Events passing all cuts: {nev}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Accumulator semantics\n", + "\n", + "Prior to coffea 0.7.2, accumulators were more explicit in that they inherited from [AccumulatorABC](https://coffeateam.github.io/coffea/api/coffea.processor.AccumulatorABC.html). Such accumulators are still supported, but now the requirements for an acuumulator output of a processor have been relaxed to the protocol:\n", + "```python\n", + "class Addable(Protocol):\n", + " def __add__(self: T, other: T) -> T:\n", + " ...\n", + "\n", + "\n", + "Accumulatable = Union[Addable, MutableSet, MutableMapping]\n", + "```\n", + "\n", + "Essentially, any item that can be added, any set, or any dictionary of the above, can be used as an accumulator:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'num': 4, 'val': 11.1, 'thing': {'a', 'b', 'c'}}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from coffea.processor import accumulate\n", + "\n", + "accumulate([\n", + " {\"num\": 0, \"val\": 3.1},\n", + " {\"num\": 2, \"val\": 4.0, \"thing\": {\"a\", \"b\"}},\n", + " {\"num\": 2, \"val\": 4.0, \"thing\": {\"a\", \"c\"}},\n", + "])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since `hist` histograms are addable, they can be used as well:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[0. 3. 0. 2. 0. 1. 0. 0. 0. 0.]\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "Axis 0\n", + "\n", + "\n", + "\n", + "
\n", + "
\n", + "Regular(10, 0, 1, label='Axis 0')
\n", + "
\n", + "Double() Σ=6.0\n", + "\n", + "
\n", + "
\n", + "" + ], + "text/plain": [ + "Hist(Regular(10, 0, 1, label='Axis 0'), storage=Double()) # Sum: 6.0" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import hist\n", + "\n", + "def makehist():\n", + " return hist.Hist.new.Reg(10, 0, 1).Double()\n", + "\n", + "h = accumulate([\n", + " makehist().fill([0.1, 0.1, 0.3]),\n", + " makehist().fill([0.1, 0.3, 0.5]),\n", + "])\n", + "print(h.values())\n", + "h" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Bringing it together\n", + "\n", + "Let's build an output accumulator that stores, per dataset:\n", + " - the sum of weights for the events processed, to use for later luminosity-normalizing the yields;\n", + " - a histogram of the dilepton invariant mass, with category axes for various selection regions of interest and systematics; and\n", + " - the weight statistics, for debugging purposes\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'DYJets': {'sumw': 578762.44,\n", + " 'mass': Hist(\n", + " StrCategory(['ee', 'eeSS', 'mm', 'mmSS'], name='region', label='region'),\n", + " StrCategory(['nominal', 'alphaSUp', 'eleSFUp', 'alphaSDown', 'eleSFDown'], name='systematic', label='systematic'),\n", + " Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=621215, variance=2.20829e+10),\n", + " 'weightStats': {'genWeight': WeightStatistics(sumw=578762.4375, sumw2=27678371840.0, minw=-26331.201171875, maxw=26331.201171875, n=40),\n", + " 'alphaS': WeightStatistics(sumw=40.0, sumw2=40.0, minw=1.0, maxw=1.0, n=40),\n", + " 'eleSF': WeightStatistics(sumw=38.26972579956055, sumw2=36.81547546386719, minw=0.6674144268035889, maxw=1.0077519416809082, n=40)}}}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "regions = {\n", + " \"ee\": {\"twoElectron\": True, \"noMuon\": True, \"leadPt20\": True, \"eleOppSign\": True},\n", + " \"eeSS\": {\"twoElectron\": True, \"noMuon\": True, \"leadPt20\": True, \"eleOppSign\": False},\n", + " \"mm\": {\"twoMuon\": True, \"noElectron\": True, \"leadPt20\": True, \"muOppSign\": True},\n", + " \"mmSS\": {\"twoMuon\": True, \"noElectron\": True, \"leadPt20\": True, \"muOppSign\": False},\n", + "}\n", + "\n", + "masshist = (\n", + " hist.Hist.new\n", + " .StrCat(regions.keys(), name=\"region\")\n", + " .StrCat([\"nominal\"] + list(weights.variations), name=\"systematic\")\n", + " .Reg(60, 60, 120, name=\"mass\", label=\"$m_{ll}$ [GeV]\")\n", + " .Weight()\n", + ")\n", + "\n", + "for region, cuts in regions.items():\n", + " goodevent = selection.require(**cuts)\n", + "\n", + " if region.startswith(\"ee\"):\n", + " mass = events.Electron[goodevent].sum().mass\n", + " elif region.startswith(\"mm\"):\n", + " mass = events.Muon[goodevent].sum().mass\n", + "\n", + " masshist.fill(\n", + " region=region,\n", + " systematic=\"nominal\",\n", + " mass=mass,\n", + " weight=weights.weight()[goodevent],\n", + " )\n", + " for syst in weights.variations:\n", + " masshist.fill(\n", + " region=region,\n", + " systematic=syst,\n", + " mass=mass,\n", + " weight=weights.weight(syst)[goodevent],\n", + " )\n", + "\n", + "out = {\n", + " events.metadata[\"dataset\"]: {\n", + " \"sumw\": ak.sum(events.genWeight),\n", + " \"mass\": masshist,\n", + " \"weightStats\": weights.weightStatistics,\n", + " }\n", + "}\n", + "\n", + "out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The cell below demonstrates that indeed this output is accumulatable. So if we were to return such a result from a coffea processor, we would be all ready to process thousands of files!" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'DYJets': {'mass': Hist(\n", + " StrCategory(['ee', 'eeSS', 'mm', 'mmSS'], name='region', label='region'),\n", + " StrCategory(['nominal', 'alphaSUp', 'eleSFUp', 'alphaSDown', 'eleSFDown'], name='systematic', label='systematic'),\n", + " Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=1.24243e+06, variance=4.41659e+10),\n", + " 'weightStats': {'genWeight': WeightStatistics(sumw=1157524.875, sumw2=55356743680.0, minw=-26331.201171875, maxw=26331.201171875, n=80),\n", + " 'alphaS': WeightStatistics(sumw=80.0, sumw2=80.0, minw=1.0, maxw=1.0, n=80),\n", + " 'eleSF': WeightStatistics(sumw=76.5394515991211, sumw2=73.63095092773438, minw=0.6674144268035889, maxw=1.0077519416809082, n=80)},\n", + " 'sumw': 1157524.9}}" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "accumulate([out, out])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The mass histogram itself is not very interesting with only 40 input events, however" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "
\n", + "
\n", + "\n", + "\n", + "\n", + "60\n", + "\n", + "\n", + "120\n", + "\n", + "\n", + "$m_{ll}$ [GeV]\n", + "\n", + "\n", + "\n", + "
\n", + "
\n", + "Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]')
\n", + "
\n", + "Weight() Σ=WeightedSum(value=126744, variance=4.49114e+09)\n", + "\n", + "
\n", + "
\n", + "" + ], + "text/plain": [ + "Hist(Regular(60, 60, 120, name='mass', label='$m_{ll}$ [GeV]'), storage=Weight()) # Sum: WeightedSum(value=126744, variance=4.49114e+09)" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "out[\"DYJets\"][\"mass\"][sum, \"nominal\", :]" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/applying_corrections.html b/notebooks/applying_corrections.html new file mode 100644 index 000000000..b0f8479b5 --- /dev/null +++ b/notebooks/applying_corrections.html @@ -0,0 +1,649 @@ + + + + + + + + + Applying corrections to columnar data — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Applying corrections to columnar data

+

Here we will show how to apply corrections to columnar data using:

+
    +
  • the coffea.lookup_tools package, which is designed to read in ROOT histograms and a variety of data file formats popular within CMS into a standardized lookup table format;

  • +
  • CMS-specific extensions to the above, for jet corrections (coffea.jetmet_tools) and b-tagging efficiencies/uncertainties (coffea.btag_tools);

  • +
  • the correctionlib package, which provides a experiment-agnostic serializable data format for common correction functions.

  • +
+

Test data: We’ll use NanoEvents to construct some test data.

+
+
[1]:
+
+
+
import awkward as ak
+from coffea.nanoevents import NanoEventsFactory, NanoAODSchema
+
+fname = "https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/nano_dy.root"
+events = NanoEventsFactory.from_root(
+    fname,
+    schemaclass=NanoAODSchema.v6,
+    metadata={"dataset": "DYJets"},
+).events()
+
+
+
+
+

Coffea lookup_tools

+

The entrypoint for coffea.lookup_tools is the extractor class.

+
+
[2]:
+
+
+
from coffea.lookup_tools import extractor
+
+
+
+
+
[3]:
+
+
+
%%bash
+# download some sample correction sources
+mkdir -p data
+pushd data
+PREFIX=https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples
+curl -Os $PREFIX/testSF2d.histo.root
+curl -Os $PREFIX/Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi.jec.txt
+curl -Os $PREFIX/Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi.junc.txt
+curl -Os $PREFIX/DeepCSV_102XSF_V1.btag.csv.gz
+popd
+
+
+
+
+
+
+
+
+~/src/coffea/binder/data ~/src/coffea/binder
+~/src/coffea/binder
+
+
+
+

Opening a root file and using it as a lookup table

+

In tests/samples, there is an example file with a TH2F histogram named scalefactors_Tight_Electron. The following code reads that histogram into an evaluator instance, under the key testSF2d and applies it to some electrons.

+
+
[4]:
+
+
+
ext = extractor()
+# several histograms can be imported at once using wildcards (*)
+ext.add_weight_sets(["testSF2d scalefactors_Tight_Electron data/testSF2d.histo.root"])
+ext.finalize()
+
+evaluator = ext.make_evaluator()
+
+print("available evaluator keys:")
+for key in evaluator.keys():
+    print("\t", key)
+print("testSF2d:", evaluator['testSF2d'])
+print("type of testSF2d:", type(evaluator['testSF2d']))
+
+
+
+
+
+
+
+
+available evaluator keys:
+         testSF2d
+testSF2d: 2 dimensional histogram with axes:
+        1: [-2.5   -2.    -1.566 -1.444 -0.8    0.     0.8    1.444  1.566  2.
+  2.5  ]
+        2: [ 10.  20.  35.  50.  90. 150. 500.]
+
+type of testSF2d: <class 'coffea.lookup_tools.dense_lookup.dense_lookup'>
+
+
+
+
[5]:
+
+
+
print("Electron eta:", events.Electron.eta)
+print("Electron pt:", events.Electron.pt)
+print("Scale factor:", evaluator["testSF2d"](events.Electron.eta, events.Electron.pt))
+
+
+
+
+
+
+
+
+Electron eta: [[], [1.83], [-0.293, -0.904], [-2.19, 1.65], ... [-0.0595], [], [0.381], [], []]
+Electron pt: [[], [29.6], [60.1, 51.7], [10.7, 8.6], [], ... [], [15.6], [], [7.68], [], []]
+Scale factor: [[], [0.909], [0.953, 0.972], [0.807, 0.827], ... [0.941], [], [0.946], [], []]
+
+
+
+
+

Building and using your own correction from a histogram

+

To use a histogram or ratio of histograms to build your own correction, you can use lookup_tools to simplify the implementation. Here we create some mock data for two slightly different pt and eta spectra (say, from two different generators) and derive a correction to reweight one sample to the other.

+
+
[6]:
+
+
+
import numpy as np
+import hist
+import matplotlib.pyplot as plt
+
+dists = (
+    hist.Hist.new
+    .StrCat(["gen1", "gen2", "gen2rwt"], name="dataset")
+    .Reg(20, 0, 100, name="pt")
+    .Reg(4, -3, 3, name="eta")
+    .Weight()
+    .fill(
+        dataset="gen1",
+        pt=np.random.exponential(scale=10.0, size=10000) + np.random.exponential(scale=10.0, size=10000),
+        eta=np.random.normal(scale=1, size=10000)
+    )
+    .fill(
+        dataset="gen2",
+        pt=np.random.exponential(scale=10.0, size=10000) + np.random.exponential(scale=15.0, size=10000),
+        eta=np.random.normal(scale=1.1, size=10000)
+    )
+)
+
+fig, ax = plt.subplots()
+dists[:, :, sum].plot1d(ax=ax)
+ax.legend(title="dataset")
+
+
+
+
+
[6]:
+
+
+
+
+<matplotlib.legend.Legend at 0x134ceb190>
+
+
+
+
+
+
+../_images/notebooks_applying_corrections_10_1.png +
+
+

Now we derive a correction as a function of \(p_T\) and \(\eta\) to gen2 such that it agrees with gen1. We’ll set it to 1 anywhere we run out of statistics for the correction, to avoid divide by zero issues

+
+
[7]:
+
+
+
from coffea.lookup_tools.dense_lookup import dense_lookup
+
+num = dists["gen1", :, :].values()
+den = dists["gen2", :, :].values()
+sf = np.where(
+    (num > 0) & (den > 0),
+    num / np.maximum(den, 1) * den.sum() / num.sum(),
+    1.0,
+)
+
+corr = dense_lookup(sf, [ax.edges for ax in dists.axes[1:]])
+print(corr)
+
+# a quick way to plot the scale factor is to steal the axis definitions from the input histograms:
+sfhist = hist.Hist(*dists.axes[1:], data=sf)
+sfhist.plot2d()
+
+
+
+
+
+
+
+
+2 dimensional histogram with axes:
+        1: [  0.   5.  10.  15.  20.  25.  30.  35.  40.  45.  50.  55.  60.  65.
+  70.  75.  80.  85.  90.  95. 100.]
+        2: [-3.  -1.5  0.   1.5  3. ]
+
+
+
+
+
[7]:
+
+
+
+
+ColormeshArtists(pcolormesh=<matplotlib.collections.QuadMesh object at 0x134eac6a0>, cbar=<matplotlib.colorbar.Colorbar object at 0x134eb87c0>, text=[])
+
+
+
+
+
+
+../_images/notebooks_applying_corrections_12_2.png +
+
+

Now we generate some new mock data as if it was drawn from gen2 and reweight it with our corr to match gen1

+
+
[8]:
+
+
+
ptvals = np.random.exponential(scale=10.0, size=10000) + np.random.exponential(scale=15.0, size=10000)
+etavals = np.random.normal(scale=1.1, size=10000)
+
+dists.fill(
+    dataset="gen2rwt",
+    pt=ptvals,
+    eta=etavals,
+    weight=corr(ptvals, etavals)
+)
+
+fig, ax = plt.subplots()
+dists[:, :, sum].plot1d(ax=ax)
+ax.legend(title="dataset")
+
+
+
+
+
[8]:
+
+
+
+
+<matplotlib.legend.Legend at 0x134f44f40>
+
+
+
+
+
+
+../_images/notebooks_applying_corrections_14_1.png +
+
+

Note that corr() can accept also jagged arrays if need be.

+
+
+
+

CMS high-level tools

+
+

Applying energy scale transformations with jetmet_tools

+

The coffea.jetmet_tools package provides a convenience class JetTransformer which applies specified corrections and computes uncertainties in one call. First we build the desired jet correction stack to apply. This will usually be some set of the various JEC and JER correction text files that depends on the jet cone size (AK4, AK8) and the pileup mitigation algorithm, as +well as the data-taking year they are associated with.

+
+
[9]:
+
+
+
from coffea.jetmet_tools import FactorizedJetCorrector, JetCorrectionUncertainty
+from coffea.jetmet_tools import JECStack, CorrectedJetsFactory
+import awkward as ak
+import numpy as np
+
+ext = extractor()
+ext.add_weight_sets([
+    "* * data/Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi.jec.txt",
+    "* * data/Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi.junc.txt",
+])
+ext.finalize()
+
+jec_stack_names = [
+    "Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi",
+    "Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi"
+]
+
+evaluator = ext.make_evaluator()
+
+jec_inputs = {name: evaluator[name] for name in jec_stack_names}
+jec_stack = JECStack(jec_inputs)
+### more possibilities are available if you send in more pieces of the JEC stack
+# mc2016_ak8_jxform = JECStack(["more", "names", "of", "JEC parts"])
+
+print(dir(evaluator))
+
+
+
+
+
+
+
+
+['Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi', 'Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi']
+
+
+

Now we prepare some auxilary variables that are used to parameterize the jet energy corrections, such as jet area, mass, and event \(\rho\) (mean pileup energy density), and pass all of these into the CorrectedJetsFactory:

+
+
[10]:
+
+
+
name_map = jec_stack.blank_name_map
+name_map['JetPt'] = 'pt'
+name_map['JetMass'] = 'mass'
+name_map['JetEta'] = 'eta'
+name_map['JetA'] = 'area'
+
+jets = events.Jet
+
+jets['pt_raw'] = (1 - jets['rawFactor']) * jets['pt']
+jets['mass_raw'] = (1 - jets['rawFactor']) * jets['mass']
+jets['pt_gen'] = ak.values_astype(ak.fill_none(jets.matched_gen.pt, 0), np.float32)
+jets['rho'] = ak.broadcast_arrays(events.fixedGridRhoFastjetAll, jets.pt)[0]
+name_map['ptGenJet'] = 'pt_gen'
+name_map['ptRaw'] = 'pt_raw'
+name_map['massRaw'] = 'mass_raw'
+name_map['Rho'] = 'rho'
+
+events_cache = events.caches[0]
+corrector = FactorizedJetCorrector(
+    Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi=evaluator['Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi'],
+)
+uncertainties = JetCorrectionUncertainty(
+    Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi=evaluator['Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi']
+)
+
+jet_factory = CorrectedJetsFactory(name_map, jec_stack)
+corrected_jets = jet_factory.build(jets, lazy_cache=events_cache)
+
+print('starting columns:', set(ak.fields(jets)))
+print('new columns:', set(ak.fields(corrected_jets)) - set(ak.fields(jets)))
+
+
+
+
+
+
+
+
+starting columns: {'btagCSVV2', 'electronIdx1', 'electronIdx2', 'eta', 'muonSubtrFactor', 'btagCMVA', 'bRegCorr', 'btagDeepFlavB', 'jercCHPUF', 'chEmEF', 'pt_raw', 'muonIdx2', 'nMuons', 'cleanmask', 'muonIdx1G', 'genJetIdxG', 'puId', 'muEF', 'mass', 'genJetIdx', 'muonIdx1', 'area', 'hadronFlavour', 'btagDeepC', 'qgl', 'rawFactor', 'mass_raw', 'partonFlavour', 'phi', 'btagDeepFlavC', 'nElectrons', 'electronIdx2G', 'rho', 'btagDeepB', 'neHEF', 'pt_gen', 'muonIdx2G', 'neEmEF', 'electronIdx1G', 'jercCHF', 'muonIdxG', 'jetId', 'nConstituents', 'electronIdxG', 'bRegRes', 'pt', 'chHEF'}
+new columns: {'jet_energy_correction', 'mass_orig', 'pt_orig', 'pt_jec', 'JES_jes', 'mass_jec', 'jet_energy_uncertainty_jes'}
+
+
+

Below we show that the corrected jets indeed have a different \(p_T\) and mass than we started with

+
+
[11]:
+
+
+
print('untransformed pt ratios', jets.pt/jets.pt_raw)
+print('untransformed mass ratios', jets.mass/jets.mass_raw)
+
+print('transformed pt ratios', corrected_jets.pt/corrected_jets.pt_raw)
+print('transformed mass ratios', corrected_jets.mass/corrected_jets.mass_raw)
+
+print('JES UP pt ratio', corrected_jets.JES_jes.up.pt/corrected_jets.pt_raw)
+print('JES DOWN pt ratio', corrected_jets.JES_jes.down.pt/corrected_jets.pt_raw)
+
+
+
+
+
+
+
+
+untransformed pt ratios [[1.12, 1.09, 1.2, 1.35, 1.27], [1.03, ... 1.28, 1.1, 1.13, 0.989], [1.13, 0.978]]
+untransformed mass ratios [[1.12, 1.09, 1.2, 1.35, 1.27], [1.03, ... 1.28, 1.1, 1.13, 0.989], [1.13, 0.978]]
+transformed pt ratios [[1.2, 1.3, 1.46, 2.09, 2.1], [1.09, 1.29, ... 1.84, 1.47, 1.36, 1.16], [1.37, 1.15]]
+transformed mass ratios [[1.2, 1.3, 1.46, 2.09, 2.1], [1.09, 1.29, ... 1.84, 1.47, 1.36, 1.16], [1.37, 1.15]]
+JES UP pt ratio [[1.22, 1.35, 1.56, 2.34, 2.37], [1.1, ... 2.07, 1.52, 1.41, 1.2], [1.41, 1.17]]
+JES DOWN pt ratio [[1.19, 1.25, 1.35, 1.83, 1.83], [1.08, ... 1.6, 1.41, 1.32, 1.13], [1.33, 1.12]]
+
+
+
+
+

Applying CMS b-tagging corrections with btag_tools

+

The coffea.btag_tools module provides the high-level utility BTagScaleFactor which calculates per-jet weights for b-tagging as well as light flavor mis-tagging efficiencies. Uncertainties can be calculated as well.

+
+
[12]:
+
+
+
from coffea.btag_tools import BTagScaleFactor
+
+btag_sf = BTagScaleFactor("data/DeepCSV_102XSF_V1.btag.csv.gz", "medium")
+
+print("SF:", btag_sf.eval("central", events.Jet.hadronFlavour, abs(events.Jet.eta), events.Jet.pt))
+print("systematic +:", btag_sf.eval("up", events.Jet.hadronFlavour, abs(events.Jet.eta), events.Jet.pt))
+print("systematic -:", btag_sf.eval("down", events.Jet.hadronFlavour, abs(events.Jet.eta), events.Jet.pt))
+
+
+
+
+
+
+
+
+SF: [[1.52, 1.56, 1.59, 1.6, 1.6], [0.969, 1.57, ... 1.59, 1.6, 1.6, 1.6], [1.6, 1.6]]
+systematic +: [[1.72, 1.77, 1.79, 1.8, 1.8], [1.01, 1.78, ... 1.8, 1.8, 1.8, 1.8], [1.8, 1.8]]
+systematic -: [[1.31, 1.36, 1.38, 1.4, 1.4], [0.925, 1.37, ... 1.39, 1.4, 1.4, 1.4], [1.4, 1.4]]
+
+
+
+
+
+

Using correctionlib

+

For the most part, using correctionlib is straightforward. We’ll show here how to convert the custom correction we derived earlier (corr) into a correctionlib object, and save it in the json format:

+
+
[13]:
+
+
+
import correctionlib, rich
+import correctionlib.convert
+
+# without a name, the resulting object will fail validation
+sfhist.name = "gen2_to_gen1"
+sfhist.label = "out"
+clibcorr = correctionlib.convert.from_histogram(sfhist)
+clibcorr.description = "Reweights gen2 to agree with gen1"
+# set overflow bins behavior (default is to raise an error when out of bounds)
+clibcorr.data.flow = "clamp"
+
+cset = correctionlib.schemav2.CorrectionSet(
+    schema_version=2,
+    description="my custom corrections",
+    corrections=[clibcorr],
+)
+rich.print(cset)
+
+with open("data/mycorrections.json", "w") as fout:
+    fout.write(cset.json(exclude_unset=True))
+
+
+
+
+
+
+
+
CorrectionSet (schema v2)
+my custom corrections
+📂
+└── 📈 gen2_to_gen1 (v0)
+    Reweights gen2 to agree with gen1
+    Node counts: MultiBinning: 1
+    ╭──────────── ▶ input ─────────────╮ ╭──────────── ▶ input ────────────╮
+    │ pt (real)                        │ │ eta (real)                      │
+    │ pt                               │ │ eta                             │
+    │ Range: [0.0, 100.0), overflow ok │ │ Range: [-3.0, 3.0), overflow ok │
+    ╰──────────────────────────────────╯ ╰─────────────────────────────────╯
+    ╭─── ◀ output ───╮
+    │ out (real)     │
+    │ No description │
+    ╰────────────────╯
+
+
+

We can now use this new correction in a similar way to the original corr() object:

+
+
[14]:
+
+
+
ceval = cset.to_evaluator()
+
+ceval["gen2_to_gen1"].evaluate(ptvals, etavals)
+
+
+
+
+
[14]:
+
+
+
+
+array([1.55691586, 1.36319225, 1.36319225, ..., 1.55691586, 0.64304079,
+       1.02863368])
+
+
+

At the time of writing, correctionlib does not support jagged arrays. But we can work around this using awkward utilities flatten and unflatten, as shown below

+
+
[15]:
+
+
+
def myJetSF(jets):
+    j, nj = ak.flatten(jets), ak.num(jets)
+    sf = ceval["gen2_to_gen1"].evaluate(np.array(j.pt), np.array(j.eta))
+    return ak.unflatten(sf, nj)
+
+myJetSF(events.Jet)
+
+
+
+
+
[15]:
+
+
+
+
+<Array [[0.498, 0.211, 0.86, ... [1.15, 1.17]] type='40 * var * float64'>
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/notebooks/applying_corrections.ipynb b/notebooks/applying_corrections.ipynb new file mode 100644 index 000000000..7620b05a8 --- /dev/null +++ b/notebooks/applying_corrections.ipynb @@ -0,0 +1,679 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Applying corrections to columnar data\n", + "\n", + "Here we will show how to apply corrections to columnar data using:\n", + "\n", + "- the `coffea.lookup_tools` package, which is designed to read in ROOT histograms and a variety of data file formats popular within CMS into a standardized lookup table format;\n", + "- CMS-specific extensions to the above, for jet corrections (`coffea.jetmet_tools`) and b-tagging efficiencies/uncertainties (`coffea.btag_tools`);\n", + "- the [correctionlib](https://cms-nanoaod.github.io/correctionlib/) package, which provides a experiment-agnostic serializable data format for common correction functions." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Test data**:\n", + "We'll use NanoEvents to construct some test data." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import awkward as ak\n", + "from coffea.nanoevents import NanoEventsFactory, NanoAODSchema\n", + "\n", + "fname = \"https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/nano_dy.root\"\n", + "events = NanoEventsFactory.from_root(\n", + " fname,\n", + " schemaclass=NanoAODSchema.v6,\n", + " metadata={\"dataset\": \"DYJets\"},\n", + ").events()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Coffea lookup_tools\n", + "\n", + "The entrypoint for `coffea.lookup_tools` is the [extractor class](https://coffeateam.github.io/coffea/api/coffea.lookup_tools.extractor.html#coffea.lookup_tools.extractor)." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "from coffea.lookup_tools import extractor" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "~/src/coffea/binder/data ~/src/coffea/binder\n", + "~/src/coffea/binder\n" + ] + } + ], + "source": [ + "%%bash\n", + "# download some sample correction sources\n", + "mkdir -p data\n", + "pushd data\n", + "PREFIX=https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples\n", + "curl -Os $PREFIX/testSF2d.histo.root\n", + "curl -Os $PREFIX/Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi.jec.txt\n", + "curl -Os $PREFIX/Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi.junc.txt\n", + "curl -Os $PREFIX/DeepCSV_102XSF_V1.btag.csv.gz\n", + "popd" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Opening a root file and using it as a lookup table\n", + "\n", + "In [tests/samples](https://github.com/CoffeaTeam/coffea/tree/master/tests/samples), there is an example file with a `TH2F` histogram named `scalefactors_Tight_Electron`. The following code reads that histogram into an [evaluator](https://coffeateam.github.io/coffea/api/coffea.lookup_tools.evaluator.html#coffea.lookup_tools.evaluator) instance, under the key `testSF2d` and applies it to some electrons." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "available evaluator keys:\n", + "\t testSF2d\n", + "testSF2d: 2 dimensional histogram with axes:\n", + "\t1: [-2.5 -2. -1.566 -1.444 -0.8 0. 0.8 1.444 1.566 2.\n", + " 2.5 ]\n", + "\t2: [ 10. 20. 35. 50. 90. 150. 500.]\n", + "\n", + "type of testSF2d: \n" + ] + } + ], + "source": [ + "ext = extractor()\n", + "# several histograms can be imported at once using wildcards (*)\n", + "ext.add_weight_sets([\"testSF2d scalefactors_Tight_Electron data/testSF2d.histo.root\"])\n", + "ext.finalize()\n", + "\n", + "evaluator = ext.make_evaluator()\n", + "\n", + "print(\"available evaluator keys:\")\n", + "for key in evaluator.keys():\n", + " print(\"\\t\", key)\n", + "print(\"testSF2d:\", evaluator['testSF2d'])\n", + "print(\"type of testSF2d:\", type(evaluator['testSF2d']))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Electron eta: [[], [1.83], [-0.293, -0.904], [-2.19, 1.65], ... [-0.0595], [], [0.381], [], []]\n", + "Electron pt: [[], [29.6], [60.1, 51.7], [10.7, 8.6], [], ... [], [15.6], [], [7.68], [], []]\n", + "Scale factor: [[], [0.909], [0.953, 0.972], [0.807, 0.827], ... [0.941], [], [0.946], [], []]\n" + ] + } + ], + "source": [ + "print(\"Electron eta:\", events.Electron.eta)\n", + "print(\"Electron pt:\", events.Electron.pt)\n", + "print(\"Scale factor:\", evaluator[\"testSF2d\"](events.Electron.eta, events.Electron.pt))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Building and using your own correction from a histogram\n", + "\n", + "To use a histogram or ratio of histograms to build your own correction, you can use `lookup_tools` to simplify the implementation. Here we create some mock data for two slightly different pt and eta spectra (say, from two different generators) and derive a correction to reweight one sample to the other." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import numpy as np\n", + "import hist\n", + "import matplotlib.pyplot as plt\n", + "\n", + "dists = (\n", + " hist.Hist.new\n", + " .StrCat([\"gen1\", \"gen2\", \"gen2rwt\"], name=\"dataset\")\n", + " .Reg(20, 0, 100, name=\"pt\")\n", + " .Reg(4, -3, 3, name=\"eta\")\n", + " .Weight()\n", + " .fill(\n", + " dataset=\"gen1\",\n", + " pt=np.random.exponential(scale=10.0, size=10000) + np.random.exponential(scale=10.0, size=10000),\n", + " eta=np.random.normal(scale=1, size=10000)\n", + " )\n", + " .fill(\n", + " dataset=\"gen2\",\n", + " pt=np.random.exponential(scale=10.0, size=10000) + np.random.exponential(scale=15.0, size=10000),\n", + " eta=np.random.normal(scale=1.1, size=10000)\n", + " )\n", + ")\n", + "\n", + "fig, ax = plt.subplots()\n", + "dists[:, :, sum].plot1d(ax=ax)\n", + "ax.legend(title=\"dataset\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we derive a correction as a function of $p_T$ and $\\eta$ to `gen2` such that it agrees with `gen1`. We'll set it to 1 anywhere we run out of statistics for the correction, to avoid divide by zero issues" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2 dimensional histogram with axes:\n", + "\t1: [ 0. 5. 10. 15. 20. 25. 30. 35. 40. 45. 50. 55. 60. 65.\n", + " 70. 75. 80. 85. 90. 95. 100.]\n", + "\t2: [-3. -1.5 0. 1.5 3. ]\n", + "\n" + ] + }, + { + "data": { + "text/plain": [ + "ColormeshArtists(pcolormesh=, cbar=, text=[])" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaEAAAEKCAYAAAC7c+rvAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAXd0lEQVR4nO3df7BndX3f8edrf/E78mNFERah45aGOlXIFqE6HX4Yg8aRpNUW0kbj6GyT0Qk2Oh01LVRTp7VJtXE0mh2hQuqgDv7aKpFgpEU6kQiICCy2W6NhVwTXhQXCz7v33T++Z9vr9f783vvdz/2e+3zMnNnvOd/P55zPuefufX8/P76fT6oKSZJaWNO6AJKk1csgJElqxiAkSWrGICRJasYgJElqxiAkSWqmaRBKcmiSv0zy7SR3J3nPDGkOSfLpJDuT3JLklAZFlSSNQOua0FPA+VX1IuDFwIVJzp6W5k3AQ1X1AuCDwPsPbhElSaPSNAjVwGPd7vpum/7t2YuAq7rX1wIXJMlBKqIkaYTWtS5AkrXAbcALgI9U1S3TkpwI3AdQVRNJ9gHHAXumnWcrsBVgzdoNv3DYUccvuiy1hJ9G9g+fd83EEmatmBw+7+SG4T+DZP/w182QWbN/cuhr8tQzQ2etQzcMnTePPzl0Xg4Z/rqsGe5z2sTha4e+5LrHl/CfYAmWVObHJoa/7pHD/8F4fM+uPVX17MXm+6Xzjqif7B3Nz/m2O5+6vqouHMnJ59A8CFXVfuDFSY4GPp/khVV11xDn2QZsAzjymE31ogsuXXRZnjx2+F/mQ/YN/wfysB8/PXTetU8M/5/osZMPHzrvIQ8Pf901zwz3s1r3yFNDXzPf2z103snTTh7+unf8r6HzrjnlpKHzTh5xyFD59pzxrKGvufFb+4bOuxRLKfPxNz84dN4HX7b4D7oH3P7x3/nBMPn27N3PLdcP/3sxl/Un/J+NIznxPJoHoQOq6uEkNwIXAlOD0G5gE7AryTrgWcBPGhRRkhor9tcSWgRWoNaj457d1YBIchjwi8C905JtB97QvX4t8LVy1lVJq1ABk9RItlZa14ROAK7q+oXWAJ+pqi8leS9wa1VtB64A/iTJTmAvcHG74kpSW5P0qybUNAhV1Z3AGTMcv2zK6yeB1x3McknSSlQUz/SsOa51TUiStEAF7G/YdDYKBiFJGiMt+29GwSAkSWOigP09G5dlEJKkMdKvHiGDkCSNjaLsE5IktVEFz/QrBhmEJGl8hP30a/5mg5AkjYliSXMWr0gGIUkaI9aEJElNDL6sahCSJDVQwDPVekHs5WUQkqQxUYT9bRc/WHYGIUkaI5Nlc5wkqQH7hCRJDYX99glJkloYrKxqEJIkNVAVnq61rYuxrAxCkjRGJu0TkiS1MBiYYHOcJKkJByZIkhpxYIIkqan9fllVktRCEZ6pfv3Z7tfdSFKPOTBBktRMEZvjJEntODBBktREFQ7RliS1MRiY0GbaniSbgKuB5zDontpWVX84Lc25wBeBv+oOfa6q3jvXeQ1CkjRGGg5MmADeXlW3JzkKuC3JDVV1z7R0X6+qVy/0pAYhSRoTRZotaldV9wP3d68fTbIDOBGYHoQWxSAkSWNkJQzRTnIKcAZwywxvn5Pk28APgXdU1d1zncsgJEljooDJ0Q1M2Jjk1in726pq2/RESY4EPgu8raoemfb27cDzq+qxJK8CvgBsnuuiBiFJGhsZ5fLee6pqy5xXT9YzCECfrKrPTX9/alCqquuS/FGSjVW1Z7ZzGoQkaUwUtBwdF+AKYEdVfWCWNM8FHqiqSnIWsAb4yVznNQhJ0pioyiib4+bzUuDXge8kuaM79m7gZICq+hjwWuC3kkwATwAXV1XNdVKDkCSNkVZfVq2qm2HutsCq+jDw4cWc1yAkSWNisJ6Qc8dJkppwZVVJUiODIdrWhCRJDbScO25UDEKSNEZcykGS1MRgKQeb4yRJjdgnJElqYjCLts1xkqQGBtP2GIQkSU30rybU9G6SXJnkwSR3zfL+uUn2Jbmj2y472GWUpJVkkoxka6V1TegTDOYZunqONItaKlaS+srRccusqm7qVuiTJC1A35rjWteEFmJBS8Um2QpsBVh3zDH86B8s/kEdMuuyS/N7bNPwvxgbHj50+LyPDp2VdU/MOcP6nJ46evhfnfWP7R8q39M/d8TQ19xw5KlD583k8D+nnHHa0HnXPPQ3w1/3qWeGynfsPcNfc83ex4bOy8TE0FmPvWLO1aPnVD//t4fO28JgdJw1oYNpwUvFdsvQbgM4ZNOm4f9qSNIKVcBEz2pCK/puquqRqnqse30dsD7JxsbFkqRmJmvNSLZWVnRNaJilYiWpt8rmuGWV5BrgXGBjkl3A5cB6GH6pWEnqKxe1W2ZVdck87y96qVhJ6jNrQpKkJlzUTpLUTBEmJlf0eLJFMwhJ0hixT0iS1EbZHCdJasQ+IUlSUwYhSVITRdjvwARJUisOTJAkNVEOTJAktVQ9C0L9alyUpF4bTGA6im3eKyebktyY5J4kdye5dIY0SfKhJDuT3JnkzPnOa01IksZIw5rQBPD2qro9yVHAbUluqKp7pqR5JYM13zYDLwE+2v07K4OQJI2JKtg/2SYIVdX9wP3d60eT7ABOBKYGoYuAq7vVDr6R5OgkJ3R5Z2QQkqQxMsLRcRuT3Dplf1u3YvXPSHIKcAZwy7S3TgTum7K/qztmEJKkcVeMtDluT1VtmS9RkiOBzwJvq6pHlnpRg5AkjY22K6smWc8gAH2yqj43Q5LdwKYp+yd1x2bl6DhJGiNVo9nmkyTAFcCOqvrALMm2A6/vRsmdDeybqz8IrAlJ0lhpODrupcCvA99Jckd37N3AyQBV9THgOuBVwE7gceCN853UICRJY2IwOq5NA1ZV3Qxzj4roRsW9ZTHnNQhJ0hhZSNPZODEISdIY6du0PQYhSRoTRQxCkqR2etYaZxCSpLFRUI2m7RkVg5AkjRGb4yRJzTg6TpLUxIjnjmvCICRJ46IAg5AkqRWb4yRJjcTRcZKkhqwJSZKaKAcmSJJasiYkSWrHmpAkqZXJ1gVYXgYhSRoXfk9IktSS3xOSJLVjEJIkNWNznCSplVgTkiQ1UQGn7ZEkNWNNSJLUzGoNQkmOATYDhx44VlU3jaJQkqRZrMYglOTNwKXAScAdwNnAXwDnj6xkkqSf1sMvq65ZYLpLgb8P/KCqzgPOAB5e6sWTXJjku0l2JnnnDO8fkuTT3fu3JDllqdeUpHGWGs3WykKD0JNV9SQMAkNV3QuctpQLJ1kLfAR4JXA6cEmS06clexPwUFW9APgg8P6lXFOSxl6NaGtkoUFoV5KjgS8ANyT5IvCDJV77LGBnVX2vqp4GPgVcNC3NRcBV3etrgQuS9KsuKkmL0LImlOTKJA8muWuW989Nsi/JHd122XznXFCfUFX9avfy3ya5EXgW8KcLK/asTgTum7K/C3jJbGmqaiLJPuA4YM/0kyXZCmwFWHf0MWRi8bHqiROGn572kL0Ljec/q9YOnZW1Ty/hI8wSwnmWMJNvrR3uwmv2D39NlvLZZQlZawnjTyePPHT+RLOYOGL9UPnWPrWEH/LExPB5l2DNmX93+MxPD1/m47963/yJRqFtn9AngA8DV8+R5utV9eqFnnBBfzmT/MmB11X1P6pqO3DlQi9yMFTVtqraUlVb1h5xROviSNLyG1VT3AI/y3Yjovcu090AC2+O+6mPGl1/zi8s8dq7gU1T9k/qjs2YJsk6BjWwnyzxupI0vkYXhDYmuXXKtnXIEp6T5NtJ/jTJvNXUORsLkrwLeDdwWJJHDhwGnga2DVnAA74JbE5yKoNgczHwa9PSbAfewGA4+GuBr1X1bSJzSVq4pTSFz2NPVW1Z4jluB55fVY8leRWDcQSb58owZ02oqv59VR0FfAB4C/Cfuv0zgM8vpaRVNQG8Fbge2AF8pqruTvLeJK/pkl0BHJdkJ/A7wM8M45akVWUFj46rqkeq6rHu9XXA+iQb58qz0G7Tn2PwBdXzgfcAjwKfZfDdoaF1hbxu2rHLprx+EnjdUq4hSX3R+js980nyXOCBqqokZzGo6MzZhbLQIHRWVZ2Z5FsAVfVQkg1LK64kadEajo5Lcg1wLoP+o13A5cB6gKr6GINuk99KMgE8AVw8XxfKQoPQM91ghOoK8mxgdC2TkqSZNawJVdUl87z/YQZDuBdsoUHoQwz6gI5P8j4G0e5fL+ZCkqSlW8nNccNY6JdVP5nkNuACBqPjfqWqdoy0ZJKkn1YjHR3XxIK/z93NF3fvCMsiSZrPaqwJSZJWCIOQJKmVvvUJDT/rpiRJS2RNSJLGSc9qQgYhSRoXq3l0nCRpBbAmJElqIfRvYIJBSJLGiUFIktTECp9FexgGIUkaJw5MkCS1Yk1IktSOQUiS1MQyLsW9UhiEJGmM2BwnSWrHICRJasVpeyRJbdgnJElqJd3WJwYhSRon1oQkSa04Ok6S1I5BSJLUhIvaSZKasiYkSWrFPiFJUjsGIUlSK32rCa1pXQBJ0gIVg0XtRrEtQJIrkzyY5K5Z3k+SDyXZmeTOJGfOd06DkCSNiTCoCY1iW6BPABfO8f4rgc3dthX46HwnNAhJ0jipEW0LuXTVTcDeOZJcBFxdA98Ajk5ywlzntE9IksZIamSdQhuT3Dplf1tVbVvkOU4E7puyv6s7dv9sGQxCkjQuRjuL9p6q2jKys8/CICRJY2SFj47bDWyasn9Sd2xW9glJ0hjJ5Gi2ZbIdeH03Su5sYF9VzdoUB9aEJGm8NKwJJbkGOJdB/9Eu4HJgPUBVfQy4DngVsBN4HHjjfOc0CEnSuFjccOrlv3zVJfO8X8BbFnNOg5AkjZOV3Se0aAYhSRoTB76s2icGIUkaI5nsVxQyCEnSuBjt94SaMAhJ0hjp28qqTb4nlOR1Se5OMplk1m/oJvl+ku8kuWPadBKStDo1nDtuFFrVhO4C/hHwxwtIe15V7RlxeSRpLDgwYRlU1Q6AJC0uL0njqYDRTWDaxErvEyrgz5IU8MdzzeiaZCuD9StYf+QxHPX9Ia6W4VsnMzF0ViaOGD7v4Q8Mf+HsH/6XeXL98B8gDn3g8aHyPX3cYUNfcynW3/PXQ+edfP5zh86bJ54ZOu+GPfuGyvflv/jS0Nf85XNePXTeB1++af5EK85xw2f9+PBZ+9YnNLIglOSrwEz/A3+3qr64wNO8rKp2JzkeuCHJvd16Fj+jC1DbAA4/flO/PipIEn5PaFGq6uXLcI7d3b8PJvk8cBYwYxCSpN6r6l1z3IqdRTvJEUmOOvAaeAWDAQ2StGo1Xt572bUaov2r3Qys5wBfTnJ9d/x5Sa7rkj0HuDnJt4G/BL5cVV9pUV5JWjEcor10VfV54PMzHP8hg2nAqarvAS86yEWTpBXNPiFJUhsFLGFU60pkEJKkMWJNSJLUTs9GxxmEJGmMWBOSJLXhUg6SpFbC0qbbWokMQpI0RmKfkCSpCZvjJEnt9G/uOIOQJI0RR8dJktqxJiRJaqIcHSdJaqlfMcggJEnjpG9DtFfsonaSpBkcWF11ubcFSHJhku8m2ZnknTO8/xtJfpzkjm5783zntCYkSeOigMk2l06yFvgI8IvALuCbSbZX1T3Tkn66qt660PMahCRpTIRq2Rx3FrCzW3CUJJ8CLgKmB6FFsTlOksbJ5ORoNtiY5NYp29ZpVz4RuG/K/q7u2HT/OMmdSa5Nsmm+27EmJEnjYrTNcXuqassSz/HfgGuq6qkk/wK4Cjh/rgwGIUkaIw2b43YDU2s2J3XH/p+q+smU3Y8D/3G+k9ocJ0njpN3ouG8Cm5OcmmQDcDGwfWqCJCdM2X0NsGO+k1oTkqSx0W4C06qaSPJW4HpgLXBlVd2d5L3ArVW1HfjtJK8BJoC9wG/Md16DkCSNiwIaTttTVdcB1007dtmU1+8C3rWYcxqEJGmM9G3GBIOQJI0Tg5AkqYkCJg1CkqQmXFlVktSSQUiS1EQB+xvNYDoiBiFJGhsFZRCSJLVic5wkqQlHx0mSmrImJElqxiAkSWqiCvbvb12KZWUQkqRxYk1IktSMQUiS1EY5Ok6S1EhB+WVVSVIzTtsjSWqiCiYNQpKkVhyYIElqpawJSZLacFE7SVIrTmAqSWqlgOrZtD1rWl04ye8luTPJHUn+LMnzZkn3hiT/u9vecLDLKUkrRnWL2o1ia6RZEAJ+v6r+XlW9GPgScNn0BEmOBS4HXgKcBVye5JiDWkpJWkFqskaytdIsCFXVI1N2j2BQ05zul4AbqmpvVT0E3ABceDDKJ0krUs9qQqmGIy2SvA94PbAPOK+qfjzt/XcAh1bVv+v2/w3wRFX9wQzn2gps7XZfCNw1yrKvIBuBPa0LcZCspnuF1XW/q+leAU6rqqMWmynJVxj8rEZhT1Ud9A/5Iw1CSb4KPHeGt363qr44Jd27GASby6flX3AQmpbv1qrasuQbGAPea3+tpvtdTfcKq+9+5zLS0XFV9fIFJv0kcB2D/p+pdgPnTtk/CfjvSy6YJGlFaDk6bvOU3YuAe2dIdj3wiiTHdAMSXtEdkyT1QMvvCf2HJKcBk8APgN8ESLIF+M2qenNV7U3ye8A3uzzvraq9Czj3tpGUeGXyXvtrNd3varpXWH33O6umAxMkSatby+8JSZJWOYOQJKmZXgWhJBcm+W6SnUne2bo8yynJpiQ3Jrknyd1JLu2OH5vkhm5aoxv6NqNEkrVJvpXkS93+qUlu6Z7xp5NsaF3G5ZDk6CTXJrk3yY4k5/T52Sb5l93v8V1JrklyaF+ebZIrkzyY5K4px2Z8lhn4UHfPdyY5s13J2+hNEEqyFvgI8ErgdOCSJKe3LdWymgDeXlWnA2cDb+nu753An1fVZuDPu/0+uRTYMWX//cAHq+oFwEPAm5qUavn9IfCVqvo7wIsY3HMvn22SE4HfBrZU1QuBtcDF9OfZfoKfndlltmf5SmBzt20FPnqQyrhi9CYIMZhbbmdVfa+qngY+xWDody9U1f1VdXv3+lEGf6ROZHCPV3XJrgJ+pUkBRyDJScAvAx/v9gOcD1zbJenF/SZ5FvAPgSsAqurpqnqYHj9bBiNzD0uyDjgcuJ+ePNuqugmYPop3tmd5EXB1DXwDODrJCQeloCtEn4LQicB9U/Z3dcd6J8kpwBnALcBzqur+7q0fAc9pVa4R+M/Av2IwjB/gOODhqpro9vvyjE8Ffgz8l67p8eNJjqCnz7aqdgN/APw1g+CzD7iNfj7bA2Z7lqvm79Zs+hSEVoUkRwKfBd42bRJYajDevhdj7pO8Gniwqm5rXZaDYB1wJvDRqjoD+BumNb317Nkew6AGcCrwPAYTGK+aiYn79CyXQ5+C0G5g05T9k7pjvZFkPYMA9Mmq+lx3+IED1ffu3wdblW+ZvRR4TZLvM2haPZ9Bv8nRXRMO9OcZ7wJ2VdUt3f61DIJSX5/ty4G/qqofV9UzwOcYPO8+PtsDZnuWvf+7NZ8+BaFvApu7ETYbGHR0bm9cpmXT9YdcAeyoqg9MeWs7cGCxvzcAX5yedxxV1buq6qSqOoXBs/xaVf0z4EbgtV2yXtxvVf0IuK+bQQTgAuAeevpsGTTDnZ3k8O73+sD99u7ZTjHbs9wOvL4bJXc2sG9Ks92q0KsZE5K8ikE/wlrgyqp6X9sSLZ8kLwO+DnyH/99H8m4G/UKfAU5mMP3RP1ng1EZjI8m5wDuq6tVJ/haDmtGxwLeAf15VTzUs3rJI8mIGAzA2AN8D3sjgQ2Ivn22S9wD/lMGoz28Bb2bQFzL2zzbJNQwmXt4IPMBgYuYvMMOz7ILwhxk0Rz4OvLGqbm1Q7GZ6FYQkSeOlT81xkqQxYxCSJDVjEJIkNWMQkiQ1YxCSJDVjEJIWKMnbkhzeuhxSnzhEW1qgbvaGLVW1p3VZpL5YN38SaXXpJoj9CoNJNc8E7gZuYjDP2Y1J9lTVee1KKPWHzXHSzE4D/qiqfh54hMFMBj8EzjMAScvHICTN7L6q+p/d6/8KvKxlYaS+MghJM5veWWrnqTQCBiFpZicnOad7/WvAzcCjwFHtiiT1j0FImtl3gbck2QEcA3wU2AZ8JcmNTUsm9YhDtKVputFxX6qqF7Yui9R31oQkSc1YE5IkNWNNSJLUjEFIktSMQUiS1IxBSJLUjEFIktTM/wVlRpG7m2uvLAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "from coffea.lookup_tools.dense_lookup import dense_lookup\n", + "\n", + "num = dists[\"gen1\", :, :].values()\n", + "den = dists[\"gen2\", :, :].values()\n", + "sf = np.where(\n", + " (num > 0) & (den > 0),\n", + " num / np.maximum(den, 1) * den.sum() / num.sum(),\n", + " 1.0,\n", + ")\n", + "\n", + "corr = dense_lookup(sf, [ax.edges for ax in dists.axes[1:]])\n", + "print(corr)\n", + "\n", + "# a quick way to plot the scale factor is to steal the axis definitions from the input histograms:\n", + "sfhist = hist.Hist(*dists.axes[1:], data=sf)\n", + "sfhist.plot2d()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we generate some new mock data as if it was drawn from `gen2` and reweight it with our `corr` to match `gen1`" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAX0AAAEGCAYAAACJnEVTAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAAsTAAALEwEAmpwYAAAl70lEQVR4nO3deZhU1Z3/8feXpWmbQBBoZU+jP5Y0CC3disoyTkwiioLGBcwkApMnmIl5EvNLHFzyjEbi/OKSODEzg+IouAeXBNEohhgT0cSlcRClpQUMhIYGEZQG2qZZvr8/6lanpKu6qmvp6q76vJ6nnr51zr1V51L6rVPnnvs95u6IiEh+6JTtBoiISNtR0BcRySMK+iIieURBX0Qkjyjoi4jkkS7ZbkA8ffv29ZKSkmw3Q0Skw1i1atWH7l4cra7dB/2SkhIqKyuz3QwRkQ7DzDbHqtPwjohIHokb9M1ssJm9aGZVZrbWzL4XlPc2sxVmtj74e2xQbmZ2p5ltMLM1ZjYu4rVmBfuvN7NZmTstERGJJpGe/iHgB+5eCpwGXGlmpcA1wAvuPgx4IXgOcA4wLHjMBRZA6EsCuAEYD5wK3BD+ohARkbYRd0zf3WuB2mB7r5m9CwwEpgNnBrvdD/wRmBeUP+Ch/A6vmlkvM+sf7LvC3XcDmNkKYArwaBrPR0Q6sIMHD1JTU0NDQ0O2m9IhFBYWMmjQILp27ZrwMa26kGtmJcDJwGvA8cEXAsB24PhgeyCwJeKwmqAsVnm095lL6FcCQ4YMaU0TRaQDq6mpoUePHpSUlGBm2W5Ou+bu7Nq1i5qaGoYOHZrwcQlfyDWzzwBPAle5e91Rb+5A2jK3uftCd69w94ri4qizjkQkBzU0NNCnTx8F/ASYGX369Gn1r6KEgr6ZdSUU8B92918HxTuCYRuCvx8E5VuBwRGHDwrKYpWLiDRRwE9cMv9WiczeMeBe4F13/3lE1TIgPANnFvBURPnlwSye04A9wTDQ88CXzezY4ALul4MyERFpI4n09CcAXwe+YGarg8e5wE+BL5nZeuCLwXOAZ4H3gQ3APcC3AYILuPOBN4LHTeGLuiIibeHGG2/k9ttvj1m/dOlSqqqq0vqemzZt4pFHHknra6Yikdk7LwOxfkOcFWV/B66M8Vr3Afe1poG5Zs7yOQAsmrIoyy0RkaMtXbqU8847j9LS0rS9Zjjof/WrX03ba6ZCd+SKSE67+eabGT58OBMnTqS6uhqAe+65h1NOOYWxY8dy0UUXUV9fz5///GeWLVvG1VdfTVlZGRs3boy6H8Djjz/O6NGjGTt2LJMnTwbg8OHDXH311ZxyyimMGTOGu+++G4BrrrmGlStXUlZWxh133JGdf4RI7t6uH+Xl5Z5LZj8322c/NzvbzRBpl6qqqtL6epWVlT569Gjfv3+/79mzx0888US/7bbb/MMPP2za5/rrr/c777zT3d1nzZrljz/+eFNdrP1Gjx7tNTU17u7+0Ucfubv73Xff7fPnz3d394aGBi8vL/f333/fX3zxRZ86dWpazytStH8zoNJjxNR2n3BNRCRZK1eu5MILL6SoqAiAadOmAfDOO+/wox/9iI8//ph9+/Zx9tlnRz0+1n4TJkxg9uzZXHrppXzlK18B4He/+x1r1qzhiSeeAGDPnj2sX7+egoKCTJ9mqyjop9ktr9/Cut3rYtaH68Jj+0cb2Xsk806dl5G2iUjI7NmzWbp0KWPHjmXx4sX88Y9/bNV+d911F6+99hq//e1vKS8vZ9WqVbg7v/zlL5t9gcR67WzRmH6ardu9jurd1UkdW727usUvDBFpncmTJ7N06VI++eQT9u7dy9NPPw3A3r176d+/PwcPHuThhx9u2r9Hjx7s3bu36Xms/TZu3Mj48eO56aabKC4uZsuWLZx99tksWLCAgwcPAvDee++xf//+Zq+ZberpZ8CI3iNizs5pafZOrN6/iCRn3LhxzJgxg7Fjx3LcccdxyimnADB//nzGjx9PcXEx48ePbwrKM2fO5Jvf/CZ33nknTzzxRMz9rr76atavX4+7c9ZZZzF27FjGjBnDpk2bGDduHO5OcXExS5cuZcyYMXTu3JmxY8cye/Zsvv/972ft3wPAQmP+7VdFRYV3pEVU4k3JTCToazqn5Kt3332Xz3/+89luRocS7d/MzFa5e0W0/dXTb2NVtXXxdxIRyRCN6YuI5BH19NtYSeMPs90EEclj6umLiOQR9fTTbNOu/dQ3HmbG3X+JWh8e049Wv6mgjqKCzhltn4jkNwX9JLQ0y6a+8TD1Bw7FTlHXgvoDh1JtmkjeCXegllxxepZb0jEo6GdAUbcuLJkT/T/Alv4DHb9IH4dIrpgyZQqvvvoqEydO5Jlnnsl2c5poTF9EJAOuvvpqHnzwwWw3oxkF/SRU1dZpvr1Ijpo/fz4jRoxg4sSJXHbZZdx+++1s3LiRKVOmUF5ezqRJk1i3LpQuZfbs2Xz3u9/ljDPO4IQTTmhKtgZw1lln0aNHj2ydRkwaT4giXtK0+oOhnNrR0iY02BYKfXCz8jCNO4ok5sdPr6VqW/PO1dEdrvC1sJNu/PTqq6X9ezY7tnRAT244f1TM93zjjTd48skneeuttzh48CDjxo2jvLycuXPnctdddzFs2DBee+01vv3tb/OHP/wBgNraWl5++WXWrVvHtGnTuPjii1t9rm0pbtA3s/uA84AP3H10ULYEGBHs0gv42N3LzKwEeBcIZxx71d2/FRxTDiwGjiG0pOL3vJ3mgAgnTRvRe0T8nY9S6IMpPBI76ItI+/XKK68wffp0CgsLKSws5Pzzz6ehoYE///nPXHLJJU37HThwoGn7ggsuoFOnTpSWlrJjx45sNLtVEunpLwb+E3ggXODuM8LbZvYzYE/E/hvdvSzK6ywAvgm8RijoTwGea3WL20hLSdPGL7oIiD57J9ZUTRFpnZZ65JEyPXvnyJEj9OrVi9WrV0et79atW9N2O+3Hfkoia+S+FPTgmzEzAy4FvtDSa5hZf6Cnu78aPH8AuIB2GvTjzbWv99DPyWj1VbV1UX9Wikj7N2HCBK644gquvfZaDh06xDPPPMPcuXMZOnQojz/+OJdccgnuzpo1axg7dmy2m5uUVC/kTgJ2uPv6iLKhZva/ZvYnM5sUlA0EaiL2qQnKojKzuWZWaWaVO3fuTLGJrdc01z4Jpf17UjpAQV+kIzrllFOYNm0aY8aM4ZxzzuGkk07is5/9LA8//DD33nsvY8eOZdSoUTz11FNxX2vSpElccsklvPDCCwwaNIjnn38+7jFtIdULuZcBj0Y8rwWGuPuuYAx/qZkl9hstgrsvBBZCKLVyim1MSktz7cPz6WPVi0jH9cMf/pAbb7yR+vp6Jk+eTHl5OUOHDmX58uXN9l28ePGnnu/bt69pe+XKlZlualKSDvpm1gX4ClAeLnP3A8CBYHuVmW0EhgNbgUERhw8KyjokJU0TaT/SPZY/d+5cqqqqaGhoYNasWYwbNy6tr59tqfT0vwisc/emYRszKwZ2u/thMzsBGAa87+67zazOzE4jdCH3cuCXqTRcRCQTHnnkkWw3IaMSmbL5KHAm0NfMaoAb3P1eYCafHtoBmAzcZGYHgSPAt9x9d1D3bf4+ZfM52ulF3ERorr2IdFSJzN65LEb57ChlTwJPxti/EhjdyvaJiEgaKQ2DiEgeUdAXkY5t0dTQQxKioN+BzFk+J2q+HxFpX1avXs3pp5/OqFGjGDNmDEuWLMl2k5oo4ZqISJoVFRXxwAMPMGzYMLZt20Z5eTlnn302vXr1ynbTFPRFRCLNnz+fhx56iOLiYgYPHkx5eTkXXnghV155JTt37qSoqIh77rmHkSNHMnv2bHr27EllZSXbt2/n1ltv5eKLL2b48OFNrzdgwACOO+44du7cqaAvIhLTc9fA9rebl29f8+nnjftDf//fUdlt+41pfmy/k+Ccn8Z8y0ykVn799ddpbGzkxBNPjHvKbUFBv51psC0xx+3DOf5bGtcf2Xsk806dl5G2ieS6dKdWrq2t5etf/zr3338/nTq1j0uoCvrtSOGRwSldWq/eXR1/J5GOooUe+aeEZ+7M+W1GmpFsauW6ujqmTp3KzTffzGmnnZaRtiVDQb8d6XcotEzBoinR7/gN9/Bj5fnXzB6R1KQrtXJjYyMXXnghl19+ebtbSat9/N4QEWkH0pVa+bHHHuOll15i8eLFlJWVUVZWFvOXQltTT19EJEI6Uit/7Wtf42tf+1pbNLfVFPQ7kFjDOiJ5Lc1j+UqtLCKSR3I9tbLG9EVE8oiCfgcy4+6/xFysXUQkEQr6IiJ5REFfRDo0ZZ9tHV3IbWeqautiDuFU1dYBxKzfVFBHUUHnjLVNRBKzevVq/uVf/oW6ujo6d+7M9ddfz4wZM5J6raVLlzJ8+HBKS0vT0ra4PX0zu8/MPjCzdyLKbjSzrWa2OnicG1F3rZltMLNqMzs7onxKULbBzK5JS+tzTOmAnpT275n08fUHDlHfeDiNLRKRZIRTK69du5bly5dz1VVX8fHHHzfb7/Dh+P+/Ll26lKqqqrS1LZGe/mLgP4EHjiq/w91vjywws1JCC6aPAgYAvzezcI7R/wK+BNQAb5jZMndP35nkgBvOH9VifbiHH2th9vGL9MNNJFWZTq1cUlLCjBkzWLFiBVdddRW/+MUvWLVqFW+99RZlZWVs3ryZIUOGcOKJJ/Lggw+ybNky/vSnP/GTn/yEJ598MuVsnYksjP6SmZUk+HrTgV+5+wHgr2a2ATg1qNvg7u8DmNmvgn0V9EUkqltev6Ups2yko8vqD9UDcPojn+4Mjew9stmx8bLQtlVq5T59+vDmm2+GzvOWW6irq2PlypVUVFSwcuVKJk6cyHHHHccZZ5zBtGnTOO+889KWwyeVruF3zOxyoBL4gbt/BAwEXo3YpyYoA9hyVPn4WC9sZnOBuQBDhgxJoYkiIolrq9TKkeP7Z5xxBq+88govvfQS1113HcuXL8fdmTRpUkbOMdmgvwCYD3jw92fAP6erUe6+EFgIUFFR4XF2zxuxhnVEclGi60LEyz6bqkykVu7evXvT9uTJk1m5ciWbN29m+vTp3HLLLZgZU6dmZrH3pKZsuvsOdz/s7keAe/j7EM5WIHL5mkFBWazy/LNo6t/zf4tIuzJhwgSefvppGhoa2LdvH8888wxFRUVNqZUhFNjfeuutFl+nNamVJ02axEMPPcSwYcPo1KkTvXv35tlnn2XixIkA9OjRg71796bnBEky6JtZ/4inFwLhmT3LgJlm1s3MhgLDgNeBN4BhZjbUzAoIXexdlnyzRUTSLxuplUtKSnB3Jk+eDMDEiRPp1asXxx57LAAzZ87ktttu4+STT2bjxo0pn2Pc4R0zexQ4E+hrZjXADcCZZlZGaHhnE3AFgLuvNbPHCF2gPQRc6e6Hg9f5DvA80Bm4z93Xptx6EZE0y3Rq5U2bNjUr27Ll75c8r7vuOq677rqm5xMmTGjbKZvuflmU4ntb2P9m4OYo5c8Cz7aqdR1RrMWcw8KLOsca4omzcLOIfFq6x/KVWllaZ/vboUe/k5I7VkSyKtdTKyvoZ0K/k2Iv7NDSIs66wCuCu2Nm2W5GhxA5WyhRSrgmIu1GYWEhu3btSiqY5Rt3Z9euXRQWFrbqOPX0RaTdGDRoEDU1NezcuTPbTekQCgsLGTRoUKuOUdBva2lez1Mkl3Tt2pWhQ4dmuxk5TcM7IiJ5REFfRCSPKOh3JErhICIpUtAXEckjCvoiInlEs3eS0dINVqna/nbsIZw4KRw+d3ArB+yY9LdJRHKGgn57kkzqhgiF3pCmhohIrlLQb0/iJVqL8wujYWFZetsjIjlHQT+Kfoe20c0/SW6YJdlkayIibUAXcqPo5p8kP1TS7yQFfRFpt9TTj6HBCpPLlJlJSuEgIilST19EJI/EDfpmdp+ZfWBm70SU3WZm68xsjZn9xsx6BeUlZvaJma0OHndFHFNuZm+b2QYzu9OUMFtEpM0l0tNfDEw5qmwFMNrdxwDvAddG1G1097Lg8a2I8gXANwktlj4symt2HHN+q6EWEemQ4gZ9d38J2H1U2e/c/VDw9FWgxYTOZtYf6Onur3podYQHgAuSarGIiCQtHWP6/ww8F/F8qJn9r5n9ycwmBWUDgZqIfWqCsqjMbK6ZVZpZpRZTEBFJn5SCvpldDxwCHg6KaoEh7n4y8H+BR8ysZ2tf190XunuFu1cUFxen0kQREYmQ9JRNM5sNnAecFQzZ4O4HgAPB9ioz2wgMB7by6SGgQUGZiIi0oaR6+mY2BfhXYJq710eUF5tZ52D7BEIXbN9391qgzsxOC2btXA48lXLrRUSkVeL29M3sUeBMoK+Z1QA3EJqt0w1YEcy8fDWYqTMZuMnMDgJHgG+5e/gi8LcJzQQ6htA1gMjrAJJp2bqhTETalbhB390vi1J8b4x9nwSejFFXCYxuVetERCStdEeuiEgeUe6dHFPoDTGyf7a8AAsQShQXL72ziHRoCvo5JKVVs7a/nb6GiEi7paCfQ7Z3GRDamBPlskq8C7kt/QIQkZyhMX0RkTyioC8ikkc0vJMvND9fRFBPX0Qkryjoi4jkEQX9PDHj7r8w4+6/ZLsZIpJlCvoiInlEF3JzTP2BQ1F79FW1dQAxe/v/tmsP3Qu6UJLJxolI1ino55Cigs6hjcbWH1vfeDi9jRGRdklBP4eU9OkOwKIppzerC/fwl1zRvA5g7b93zlzDRKTdUNDPE5sKbg+2oma+FpE8oQu5IiJ5RD39HFO9u5o5y+c0K+/UbRtA1DqA/X33UXKwM7dmtHUikm0K+jlkZO+RSR+7uasu5Irkg4SCvpndB5wHfODuo4Oy3sASoATYBFzq7h8FC5//AjgXqAdmu/ubwTGzgB8FL/sTd78/faci806dF7Mu3MNfNGVR1PpLF5Zlokki0s4kOqa/GJhyVNk1wAvuPgx4IXgOcA4wLHjMBRZA05fEDcB44FTgBjM7NpXGi4hI6yTU03f3l8ys5Kji6cCZwfb9wB+BeUH5A+7uwKtm1svM+gf7rnD33QBmtoLQF8mjqZ2CJCJWD19E8ksqs3eOd/faYHs7cHywPRDYErFfTVAWq7wZM5trZpVmVrlz584UmigiIpHSMmUz6NV7Ol4reL2F7l7h7hXFxcXpellJ1qKpWk5RJEekEvR3BMM2BH8/CMq3AoMj9hsUlMUqFxGRNpJK0F8GzAq2ZwFPRZRfbiGnAXuCYaDngS+b2bHBBdwvB2UiItJGEp2y+SihC7F9zayG0CycnwKPmdk3gM3ApcHuzxKarrmB0JTNOQDuvtvM5gNvBPvdFL6oK+1DoTdEH8bZvib0t6Uhnn4nwTk/zUzDRCRtEp29c1mMqrOi7OvAlTFe5z7gvoRbJ23mgB2T/MHb305fQ0Qko3RHrgCwvcuA0MacKAnZwj38WIur6yKvSIehhGsiInlEPX2JL1YPX0Q6nLzs6WuRcBHJV3nZ09eCIiKSr3I26P/46bVUbauLWlfvh4DYi4QfcadTJ8tY20REsiVnh3eqttVRVRs96MfTqZPR2RT0wzQcJpI7cranv73LEoo+t4Wi/j2bV/6tEYCiIQujHlu9/QgjKMhk80REsiJng35Dpy002BZgVKuPHUEBI/Mw6NcfOBS1Rx/+xRSrt/9vu/bQvaALJZlsnIikRc4GfYBCHxw1j3y8VaTy8WajooLOoY3GKJX9/jvYuCZKJdQ3aqlFkY4ip4O+JK6kT3cAFk05vVnd+EWh/0yWzGleB7D23ztnrmEiklYK+tKkend106+gSPUH6wGi1gHs77uPkoOduTWjrRORdMjLoK+lA5sb2XtkzLrPfObjYKtf1PrNXeMM78TL3SMibSYvg740N+/UeTHr4l0DuXRhWSaaJCIZoKAvcSXyyyhmLn6In49fufhF2oyCvqRMufhFOg4FfUlZi7n4oeUx/TycHiuSTUmnYTCzEWa2OuJRZ2ZXmdmNZrY1ovzciGOuNbMNZlZtZmen5xRERCRRSff03b0aKAMws87AVuA3hNbEvcPdb4/c38xKgZmEbpEdAPzezIa7u+7syXWatSPSbqQr4dpZwEZ339zCPtOBX7n7AXf/K6GF009N0/uLiEgC0hX0ZwKPRjz/jpmtMbP7zOzYoGwgsCVin5qgrBkzm2tmlWZWuXPnzjQ1UUREUg76ZlYATAMeD4oWACcSGvqpBX7W2td094XuXuHuFcXFxak2UUREAuno6Z8DvOnuOwDcfYe7H3b3I8A9/H0IZyswOOK4QUGZiIi0kXQE/cuIGNoxs/4RdRcC7wTby4CZZtbNzIYCw4DX0/D+IiKSoJTm6ZtZd+BLwBURxbeaWRngwKZwnbuvNbPHgCrgEHClZu6IiLStlIK+u+8H+hxV9vUW9r8ZuDmV9xQRkeTl7Bq5IiLSnIK+ZJwWVhdpPxT0RUTySH4mXNOiHmkXa1F1aHlhdS2qLtK28jPoS1q1uKh6HFpUXaRt5WzQ73doG938k+ipe+Mt6rH97dDCHpKQlhZVBxi/6CIAlkRJvaxF1UXaVs6O6XfzT0KrOSWj30kK+u3FoqnKuS+SRjnb0wdosMKWF+7QmH7aVO+ublpL92idum0DiFq/v+8+Sg525taMtk5EwnI66MekYJ9WI3uPTPrYzV0Pp7a+LmiNXZFWyM+gL2k179R5LdaHe/jRFliffs/pNNgnyb+51tgVaRUFfcm4aME+LKX1dSPrRSQhCvrSvmkoTiStcnb2joiINKegLyKSRxT0RUTyiIK+iEgeUdAXEckjCvoiInkk5aBvZpvM7G0zW21mlUFZbzNbYWbrg7/HBuVmZnea2QYzW2Nm41J9fxERSVy6evr/6O5l7l4RPL8GeMHdhwEvBM8BzgGGBY+5wII0vb+IiCQgU8M704H7g+37gQsiyh/wkFeBXmbWP0NtEBGRo6Qj6DvwOzNbZWZzg7Lj3b022N4OHB9sDwS2RBxbE5R9ipnNNbNKM6vcuXNnGpooeUlpmUWaSUcahonuvtXMjgNWmNm6yEp3dzPz1ryguy8EFgJUVFS06lgREYkt5aDv7luDvx+Y2W+AU4EdZtbf3WuD4ZsPgt23AoMjDh8UlIkkb/vbya2QBkrLLHknpeEdM+tuZj3C28CXgXeAZcCsYLdZwFPB9jLg8mAWz2nAnohhIJHWS2WVs+1vKzWz5J1Ue/rHA78xs/BrPeLuy83sDeAxM/sGsBm4NNj/WeBcYANQD0RfakkkUS310pWWWaSZlIK+u78PjI1Svgs4K0q5A1em8p6SX2bc/RcAllwRfdH1Fikts0gzyqcvWVd/4FBTcD9aVW0dQMx6gNIBPbnh/FEZaZtIrlHQl6wqKugc2mhM7vjwl4KIJEZBX7KqpE93ABZNiT58M37RRQAsibGcYku/AESkOQV9ybrq3dVNi6cfrVO3bQAx6zcV1FF4ZDCQxJi/SB5S0JesGtl7ZErHN9gW5YoVaQUFfcmqeafOa7E+3MNfNGVR1Prw8I+IJEZBX9q1WMFeRJKjH8YiInlEQV9EJI8o6EvOmnH3XzSlU+QoGtOXDi/WHb3x7ub9t1176F7QhZJolfHy9oh0UAr60qGlckdvfeNhSg6+r7TMklcU9KVDa+mO3nh38z5763A2HepMUll7lJJZOigFfenwYt3RG+9u3qrifRQeqeBPc/6jeaXSMkuOUtCXDi2VO3pbvJtXY/mSoxT0pUOLd0dvS3Q3r+QjTdkUEckjSQd9MxtsZi+aWZWZrTWz7wXlN5rZVjNbHTzOjTjmWjPbYGbVZnZ2Ok5AREQSl8rwziHgB+7+ZrA4+iozWxHU3eHut0fubGalwExgFDAA+L2ZDXf3wym0QUREWiHpnr6717r7m8H2XuBdYGALh0wHfuXuB9z9r4QWRz812fcXEZHWS8uYvpmVACcDrwVF3zGzNWZ2n5kdG5QNBLZEHFZDjC8JM5trZpVmVrlz5850NFGkbS2aqmmd0i6lPHvHzD4DPAlc5e51ZrYAmA948PdnwD+35jXdfSGwEKCiosJTbaNIRmx/O3Zgj3dHr+7mlSxJKeibWVdCAf9hd/81gLvviKi/B3gmeLoVGBxx+KCgTKTj6XdS8sfqbl7JoqSDvpkZcC/wrrv/PKK8v7vXBk8vBN4JtpcBj5jZzwldyB0GvJ7s+4tkVSq9dA37SBal0tOfAHwdeNvMVgdl1wGXmVkZoeGdTcAVAO6+1sweA6oIzfy5UjN3pL0KZ+ZccoUWXJfcknTQd/eXAYtS9WwLx9wM3Jzse4qkW73/LeqdufvYD8D4Rd1jHjvgmBP5zcxbk3vjRK4H9BsTvV7XAyQFSsMgeWvAMSey7ZPkjq33vyV9rK4HSDYp6EveaqmXHs7MGWth9pTy9sTrpbeU4VPXAyRFCvoiUcQK9m1CGT4lg5RwTUQkj6inL5KkBtsSc4GWdbvXAbHz/Y/sPTL5tNCpXAQGXQjOcwr6IkkoPDK4xd/J+/b1Cm30bl5Xvbs6+TdO5SIw6EKwKOiLJKPfoRlU1dZR39gz+g61dQDUe/P6wwW3s2nX/uTeONUeui4E5z0FfZEklA6IEewTUH/gUBpbItI6CvoiSbjh/FFJHzt+UZcWrwfEk9L1AMl7CvoibazwyGDqDx6iKhgCOtq+xtDQz2cKmt8N3GBb2LRrP/O0EoUkSUFfpI194bhvUrWtDhqj14e/DEr6Nx9CqvKfUq+UVZICBX2RNpbq0FDKYk351HTPvKCgL5JPUpjyeUv9etbt2AFRrkXEuy8hXKdrEdmnoC/SwcTKDAqw+2/nANB7yHMxjx9wzKiksoOuW1xBtTcwIupc/2CsKsZ9ANU0wu73QUE/6xT0RTqQeJlBiz63MLThg6PWp5QdtKA7IxphkR/fvC7O0NCcA+9BwydKJ90OKOiLdCBJ5+8PjF90UcxfCvF+JTTYJ/TuegL802Otf+NH/gEa94eWVmot3UWcVgr6InmkpV8KBf2eCLaiLxzTWN+PbQd6N60q1hqbCvpSVHB8cl8Yi6a2nG8oEfql0ERBXySPpPJL4cdPrw1NNY0iPM20NMo0UwjdhZz0DWnd9jGy/yDmxfqVEG9oaPPLoUc2fjG0wy+bNg/6ZjYF+AXQGfgfd29f/yIiElUqU03/4d6h7G4gqRvS6jvtptJgXb8R0V+8/xdbfvNuZYxsPBj9SyORaaqxZPrLJkNfGG0a9M2sM/BfwJeAGuANM1vm7lVt2Q4RaVvxbkhrEqV+df39dOq2LakvDPj7l8avvX/zyn4p3Noc59h+A0spooFC2xG9XY17ASgq6NG8snE/I3d8RCbmOrV1T/9UYIO7vw9gZr8CpgMK+iI5LJVfCT9+umfSXxgA27ssoaHTlqh1iUxxTdZ7B4sB6Nmla/QdwsVRfoHUd3sPPN4JJ6etg/5AIPJfvwYYf/ROZjYXmBs83WdmySYg72tX2IdJHttR9QV0zrkt384XMnbOv07/S6bJO9B38Zyk49fnYlW0ywu57r4QWJjq65hZpbtXpKFJHYbOOffl2/mCzjmd2nqN3K1A5F0jg4IyERFpA20d9N8AhpnZUDMrAGYCy9q4DSIieatNh3fc/ZCZfQd4ntCUzfvcfW0G3zLlIaIOSOec+/LtfEHnnDbmnsx90SIi0hG19fCOiIhkkYK+iEgeycmgb2ZTzKzazDaY2TXZbk8mmNlgM3vRzKrMbK2ZfS8o721mK8xsffD32Gy3Nd3MrLOZ/a+ZPRM8H2pmrwWf95JgkkDOMLNeZvaEma0zs3fN7PRc/5zN7PvBf9fvmNmjZlaYa5+zmd1nZh+Y2TsRZVE/Vwu5Mzj3NWY2Ltn3zbmgH5Hq4RygFLjMzEqz26qMOAT8wN1LgdOAK4PzvAZ4wd2HAS8Ez3PN94B3I57fAtzh7v8H+Aj4RlZalTm/AJa7+0hgLKFzz9nP2cwGAt8FKtx9NKFJHzPJvc95MTDlqLJYn+s5wLDgMRdYkOyb5lzQJyLVg7s3AuFUDznF3Wvd/c1gey+hQDCQ0LneH+x2P3BBVhqYIWY2CJgK/E/w3IAvAOG8wDl1zmb2WWAycC+Auze6+8fk+OdMaGbhMWbWBSgCasmxz9ndXwJ2H1Uc63OdDjzgIa8CvcwsSjKh+HIx6EdL9TAwS21pE2ZWApwMvAYc7+61QdV2IMoyRx3afwD/ChwJnvcBPnb3Q8HzXPu8hwI7gUXBkNb/mFl3cvhzdvetwO3A3wgF+z3AKnL7cw6L9bmmLa7lYtDPK2b2GeBJ4Cp3/1QaQg/Nx82ZOblmdh7wgbuvynZb2lAXYBywwN1PBvZz1FBODn7OxxLq2Q4FBhBa1eXoYZCcl6nPNReDft6kejCzroQC/sPuHs4ctSP8sy/4+0G22pcBE4BpZraJ0LDdFwiNd/cKhgEg9z7vGqDG3V8Lnj9B6Esglz/nLwJ/dfed7n6QUFa0CeT25xwW63NNW1zLxaCfF6kegrHse4F33f3nEVXLgFnB9izgqbZuW6a4+7XuPsjdSwh9rn9w938CXgQuDnbLtXPeDmwxs/AKImcRSkWes58zoWGd08ysKPjvPHzOOfs5R4j1uS4DLg9m8ZwG7IkYBmodd8+5B3Au8B6wEbg+2+3J0DlOJPTTbw2wOnicS2iM+wVgPfB7oHe225qh8z8TeCbYPgF4HdgAPA50y3b70nyuZUBl8FkvBY7N9c8Z+DGwDngHeBDolmufM/AooWsWBwn9ovtGrM8VMEKzEjcCbxOa2ZTU+yoNg4hIHsnF4R0REYlBQV9EJI8o6IuI5BEFfRGRPKKgLyKSRxT0RVJkZleZWVG22yGSCE3ZFElRcIdwhbt/mO22iMTTpmvkinRkQWK75YSSf40D1gIvEcoP86KZfeju/5i9ForEp+EdkdYZAfy3u38eqAMKgG3APyrgS0egoC/SOlvc/ZVg+yFC6TBEOgwFfZHWOfoimC6KSYeioC/SOkPM7PRg+6vAy8BeoEf2miSSOAV9kdapJrQe8buEsl0uABYCy83sxay2TCQBmrIpkqBg9s4zHlqsW6RDUk9fRCSPqKcvIpJH1NMXEckjCvoiInlEQV9EJI8o6IuI5BEFfRGRPPL/ASniytaNZ17tAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "ptvals = np.random.exponential(scale=10.0, size=10000) + np.random.exponential(scale=15.0, size=10000)\n", + "etavals = np.random.normal(scale=1.1, size=10000)\n", + "\n", + "dists.fill(\n", + " dataset=\"gen2rwt\",\n", + " pt=ptvals,\n", + " eta=etavals,\n", + " weight=corr(ptvals, etavals)\n", + ")\n", + "\n", + "fig, ax = plt.subplots()\n", + "dists[:, :, sum].plot1d(ax=ax)\n", + "ax.legend(title=\"dataset\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Note that `corr()` can accept also jagged arrays if need be." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## CMS high-level tools\n", + "\n", + "### Applying energy scale transformations with jetmet_tools\n", + "\n", + "The `coffea.jetmet_tools` package provides a convenience class [JetTransformer](https://coffeateam.github.io/coffea/api/coffea.jetmet_tools.JetTransformer.html#coffea.jetmet_tools.JetTransformer) which applies specified corrections and computes uncertainties in one call. First we build the desired jet correction stack to apply. This will usually be some set of the various JEC and JER correction text files that depends on the jet cone size (AK4, AK8) and the pileup mitigation algorithm, as well as the data-taking year they are associated with." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "['Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi', 'Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi']\n" + ] + } + ], + "source": [ + "from coffea.jetmet_tools import FactorizedJetCorrector, JetCorrectionUncertainty\n", + "from coffea.jetmet_tools import JECStack, CorrectedJetsFactory\n", + "import awkward as ak\n", + "import numpy as np\n", + "\n", + "ext = extractor()\n", + "ext.add_weight_sets([\n", + " \"* * data/Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi.jec.txt\",\n", + " \"* * data/Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi.junc.txt\",\n", + "])\n", + "ext.finalize()\n", + "\n", + "jec_stack_names = [\n", + " \"Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi\",\n", + " \"Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi\"\n", + "]\n", + "\n", + "evaluator = ext.make_evaluator()\n", + "\n", + "jec_inputs = {name: evaluator[name] for name in jec_stack_names}\n", + "jec_stack = JECStack(jec_inputs)\n", + "### more possibilities are available if you send in more pieces of the JEC stack\n", + "# mc2016_ak8_jxform = JECStack([\"more\", \"names\", \"of\", \"JEC parts\"])\n", + "\n", + "print(dir(evaluator))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now we prepare some auxilary variables that are used to parameterize the jet energy corrections, such as jet area, mass, and event $\\rho$ (mean pileup energy density), and pass all of these into the `CorrectedJetsFactory`:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "starting columns: {'btagCSVV2', 'electronIdx1', 'electronIdx2', 'eta', 'muonSubtrFactor', 'btagCMVA', 'bRegCorr', 'btagDeepFlavB', 'jercCHPUF', 'chEmEF', 'pt_raw', 'muonIdx2', 'nMuons', 'cleanmask', 'muonIdx1G', 'genJetIdxG', 'puId', 'muEF', 'mass', 'genJetIdx', 'muonIdx1', 'area', 'hadronFlavour', 'btagDeepC', 'qgl', 'rawFactor', 'mass_raw', 'partonFlavour', 'phi', 'btagDeepFlavC', 'nElectrons', 'electronIdx2G', 'rho', 'btagDeepB', 'neHEF', 'pt_gen', 'muonIdx2G', 'neEmEF', 'electronIdx1G', 'jercCHF', 'muonIdxG', 'jetId', 'nConstituents', 'electronIdxG', 'bRegRes', 'pt', 'chHEF'}\n", + "new columns: {'jet_energy_correction', 'mass_orig', 'pt_orig', 'pt_jec', 'JES_jes', 'mass_jec', 'jet_energy_uncertainty_jes'}\n" + ] + } + ], + "source": [ + "name_map = jec_stack.blank_name_map\n", + "name_map['JetPt'] = 'pt'\n", + "name_map['JetMass'] = 'mass'\n", + "name_map['JetEta'] = 'eta'\n", + "name_map['JetA'] = 'area'\n", + "\n", + "jets = events.Jet\n", + " \n", + "jets['pt_raw'] = (1 - jets['rawFactor']) * jets['pt']\n", + "jets['mass_raw'] = (1 - jets['rawFactor']) * jets['mass']\n", + "jets['pt_gen'] = ak.values_astype(ak.fill_none(jets.matched_gen.pt, 0), np.float32)\n", + "jets['rho'] = ak.broadcast_arrays(events.fixedGridRhoFastjetAll, jets.pt)[0]\n", + "name_map['ptGenJet'] = 'pt_gen'\n", + "name_map['ptRaw'] = 'pt_raw'\n", + "name_map['massRaw'] = 'mass_raw'\n", + "name_map['Rho'] = 'rho'\n", + " \n", + "events_cache = events.caches[0]\n", + "corrector = FactorizedJetCorrector(\n", + " Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi=evaluator['Fall17_17Nov2017_V32_MC_L2Relative_AK4PFPuppi'],\n", + ")\n", + "uncertainties = JetCorrectionUncertainty(\n", + " Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi=evaluator['Fall17_17Nov2017_V32_MC_Uncertainty_AK4PFPuppi']\n", + ")\n", + "\n", + "jet_factory = CorrectedJetsFactory(name_map, jec_stack)\n", + "corrected_jets = jet_factory.build(jets, lazy_cache=events_cache)\n", + "\n", + "print('starting columns:', set(ak.fields(jets)))\n", + "print('new columns:', set(ak.fields(corrected_jets)) - set(ak.fields(jets)))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Below we show that the corrected jets indeed have a different $p_T$ and mass than we started with" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "untransformed pt ratios [[1.12, 1.09, 1.2, 1.35, 1.27], [1.03, ... 1.28, 1.1, 1.13, 0.989], [1.13, 0.978]]\n", + "untransformed mass ratios [[1.12, 1.09, 1.2, 1.35, 1.27], [1.03, ... 1.28, 1.1, 1.13, 0.989], [1.13, 0.978]]\n", + "transformed pt ratios [[1.2, 1.3, 1.46, 2.09, 2.1], [1.09, 1.29, ... 1.84, 1.47, 1.36, 1.16], [1.37, 1.15]]\n", + "transformed mass ratios [[1.2, 1.3, 1.46, 2.09, 2.1], [1.09, 1.29, ... 1.84, 1.47, 1.36, 1.16], [1.37, 1.15]]\n", + "JES UP pt ratio [[1.22, 1.35, 1.56, 2.34, 2.37], [1.1, ... 2.07, 1.52, 1.41, 1.2], [1.41, 1.17]]\n", + "JES DOWN pt ratio [[1.19, 1.25, 1.35, 1.83, 1.83], [1.08, ... 1.6, 1.41, 1.32, 1.13], [1.33, 1.12]]\n" + ] + } + ], + "source": [ + "print('untransformed pt ratios', jets.pt/jets.pt_raw)\n", + "print('untransformed mass ratios', jets.mass/jets.mass_raw)\n", + "\n", + "print('transformed pt ratios', corrected_jets.pt/corrected_jets.pt_raw)\n", + "print('transformed mass ratios', corrected_jets.mass/corrected_jets.mass_raw)\n", + "\n", + "print('JES UP pt ratio', corrected_jets.JES_jes.up.pt/corrected_jets.pt_raw)\n", + "print('JES DOWN pt ratio', corrected_jets.JES_jes.down.pt/corrected_jets.pt_raw)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Applying CMS b-tagging corrections with btag_tools\n", + "The `coffea.btag_tools` module provides the high-level utility [BTagScaleFactor](https://coffeateam.github.io/coffea/api/coffea.btag_tools.BTagScaleFactor.html#coffea.btag_tools.BTagScaleFactor) which calculates per-jet weights for b-tagging as well as light flavor mis-tagging efficiencies. Uncertainties can be calculated as well." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "SF: [[1.52, 1.56, 1.59, 1.6, 1.6], [0.969, 1.57, ... 1.59, 1.6, 1.6, 1.6], [1.6, 1.6]]\n", + "systematic +: [[1.72, 1.77, 1.79, 1.8, 1.8], [1.01, 1.78, ... 1.8, 1.8, 1.8, 1.8], [1.8, 1.8]]\n", + "systematic -: [[1.31, 1.36, 1.38, 1.4, 1.4], [0.925, 1.37, ... 1.39, 1.4, 1.4, 1.4], [1.4, 1.4]]\n" + ] + } + ], + "source": [ + "from coffea.btag_tools import BTagScaleFactor\n", + "\n", + "btag_sf = BTagScaleFactor(\"data/DeepCSV_102XSF_V1.btag.csv.gz\", \"medium\")\n", + "\n", + "print(\"SF:\", btag_sf.eval(\"central\", events.Jet.hadronFlavour, abs(events.Jet.eta), events.Jet.pt))\n", + "print(\"systematic +:\", btag_sf.eval(\"up\", events.Jet.hadronFlavour, abs(events.Jet.eta), events.Jet.pt))\n", + "print(\"systematic -:\", btag_sf.eval(\"down\", events.Jet.hadronFlavour, abs(events.Jet.eta), events.Jet.pt))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Using correctionlib\n", + "\n", + "For the most part, using correctionlib is straightforward. We'll show here how to convert the custom correction we derived earlier (`corr`) into a correctionlib object, and save it in the json format:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "
CorrectionSet (schema v2)                                                                    \n",
+       "my custom corrections                                                                        \n",
+       "📂                                                                                           \n",
+       "└── 📈 gen2_to_gen1 (v0)                                                                     \n",
+       "    Reweights gen2 to agree with gen1                                                        \n",
+       "    Node counts: MultiBinning: 1                                                             \n",
+       "    ╭──────────── ▶ input ─────────────╮ ╭──────────── ▶ input ────────────╮                 \n",
+       "    │ pt (real)                        │ │ eta (real)                      │                 \n",
+       "    │ pt                               │ │ eta                             │                 \n",
+       "    │ Range: [0.0, 100.0), overflow ok │ │ Range: [-3.0, 3.0), overflow ok │                 \n",
+       "    ╰──────────────────────────────────╯ ╰─────────────────────────────────╯                 \n",
+       "    ╭─── ◀ output ───╮                                                                       \n",
+       "    │ out (real)     │                                                                       \n",
+       "    │ No description │                                                                       \n",
+       "    ╰────────────────╯                                                                       \n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1mCorrectionSet\u001b[0m (\u001b[3mschema v2\u001b[0m) \n", + "my custom corrections \n", + "📂 \n", + "└── 📈 \u001b[1mgen2_to_gen1\u001b[0m (v0) \n", + " Reweights gen2 to agree with gen1 \n", + " Node counts: \u001b[1mMultiBinning\u001b[0m: 1 \n", + " ╭──────────── ▶ input ─────────────╮ ╭──────────── ▶ input ────────────╮ \n", + " │ \u001b[1mpt\u001b[0m (real) │ │ \u001b[1meta\u001b[0m (real) │ \n", + " │ pt │ │ eta │ \n", + " │ Range: [0.0, 100.0), overflow ok │ │ Range: [-3.0, 3.0), overflow ok │ \n", + " ╰──────────────────────────────────╯ ╰─────────────────────────────────╯ \n", + " ╭─── ◀ output ───╮ \n", + " │ \u001b[1mout\u001b[0m (real) │ \n", + " │ \u001b[3mNo description\u001b[0m │ \n", + " ╰────────────────╯ \n" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import correctionlib, rich\n", + "import correctionlib.convert\n", + "\n", + "# without a name, the resulting object will fail validation\n", + "sfhist.name = \"gen2_to_gen1\"\n", + "sfhist.label = \"out\"\n", + "clibcorr = correctionlib.convert.from_histogram(sfhist)\n", + "clibcorr.description = \"Reweights gen2 to agree with gen1\"\n", + "# set overflow bins behavior (default is to raise an error when out of bounds)\n", + "clibcorr.data.flow = \"clamp\"\n", + "\n", + "cset = correctionlib.schemav2.CorrectionSet(\n", + " schema_version=2,\n", + " description=\"my custom corrections\",\n", + " corrections=[clibcorr],\n", + ")\n", + "rich.print(cset)\n", + "\n", + "with open(\"data/mycorrections.json\", \"w\") as fout:\n", + " fout.write(cset.json(exclude_unset=True))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can now use this new correction in a similar way to the original `corr()` object:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([1.55691586, 1.36319225, 1.36319225, ..., 1.55691586, 0.64304079,\n", + " 1.02863368])" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ceval = cset.to_evaluator()\n", + "\n", + "ceval[\"gen2_to_gen1\"].evaluate(ptvals, etavals)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "At the time of writing, correctionlib does not support jagged arrays. But we can work around this using awkward utilities `flatten` and `unflatten`, as shown below" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def myJetSF(jets):\n", + " j, nj = ak.flatten(jets), ak.num(jets)\n", + " sf = ceval[\"gen2_to_gen1\"].evaluate(np.array(j.pt), np.array(j.eta))\n", + " return ak.unflatten(sf, nj)\n", + "\n", + "myJetSF(events.Jet)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/histograms.html b/notebooks/histograms.html new file mode 100644 index 000000000..f831fc5fd --- /dev/null +++ b/notebooks/histograms.html @@ -0,0 +1,1080 @@ + + + + + + + + + Coffea Histograms (deprecated) — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Coffea Histograms (deprecated)

+

This feature is deprecated in favor of hist and mplhep. A migration guide can be found in discussion CoffeaTeam/coffea#705

+

This is a rendered copy of histograms.ipynb. You can optionally run it interactively on binder at this link

+

In scientific python, histograms seem to be considered as a plot style, on equal footing with, e.g. scatter plots. It may well be that HEP is the only place where users need to plot pre-binned data, and thus must use histograms as persistent objects representing reduced data. In Coffea, the hist subpackage provides a persistable mergable histogram object. This notebook will discuss a few ways that such objects can be +manipulated.

+

A histogram object roughly goes through three stages in its life:

+
    +
  • Filling

  • +
  • Transformation (projection, rebinning, integrating)

  • +
  • Plotting

  • +
+

We’ll go over examples of each stage in this notebook, and conclude with some styling examples.

+
+

Filling

+

Let’s start with filling. We’ll use a random distribution near and dear to of b and c factory physicists, and have the numpy builtin histogram function do the work for us:

+
+
[1]:
+
+
+
import numpy as np
+from scipy.stats import argus
+
+vals = argus(chi=.5).rvs(size=1000)
+
+hist = np.histogram(vals)
+print(hist)
+
+
+
+
+
+
+
+
+(array([ 16,  47,  66,  95, 125, 113, 137, 167, 143,  91]), array([0.002894  , 0.10257766, 0.20226132, 0.30194498, 0.40162865,
+       0.50131231, 0.60099597, 0.70067963, 0.80036329, 0.90004695,
+       0.99973061]))
+
+
+

So we’re done, right? Probably not: we have more than 1000 events, and probably need to use some map-reduce paradigm to fill the histogram because we can’t keep all 1 billion vals in memory. So we need two things: a binning, so that all histograms that were independently created can be added, and the ability to add two histograms.

+
+
[2]:
+
+
+
binning = np.linspace(0, 1, 50)
+
+def add_histos(h1, h2):
+    h1sumw, h1binning = h1
+    h2sumw, h2binning = h2
+    if h1binning.shape == h2binning.shape and np.all(h1binning==h2binning):
+        return h1sumw+h2sumw, h1binning
+    else:
+        raise ValueError("The histograms have inconsistent binning")
+
+
+
+
+
[3]:
+
+
+
vals2 = argus(chi=.5).rvs(size=1000)
+
+hist1 = np.histogram(vals, bins=binning)
+hist2 = np.histogram(vals, bins=binning)
+
+hist = add_histos(hist1, hist2)
+print(hist)
+
+
+
+
+
+
+
+
+(array([ 2,  6,  6,  6, 12, 18, 20, 16, 14, 28, 22, 26, 28, 42, 18, 34, 28,
+       48, 40, 42, 42, 60, 46, 62, 46, 52, 46, 38, 52, 54, 50, 58, 72, 54,
+       50, 74, 80, 58, 70, 70, 42, 64, 68, 52, 60, 32, 44, 30, 18]), array([0.        , 0.02040816, 0.04081633, 0.06122449, 0.08163265,
+       0.10204082, 0.12244898, 0.14285714, 0.16326531, 0.18367347,
+       0.20408163, 0.2244898 , 0.24489796, 0.26530612, 0.28571429,
+       0.30612245, 0.32653061, 0.34693878, 0.36734694, 0.3877551 ,
+       0.40816327, 0.42857143, 0.44897959, 0.46938776, 0.48979592,
+       0.51020408, 0.53061224, 0.55102041, 0.57142857, 0.59183673,
+       0.6122449 , 0.63265306, 0.65306122, 0.67346939, 0.69387755,
+       0.71428571, 0.73469388, 0.75510204, 0.7755102 , 0.79591837,
+       0.81632653, 0.83673469, 0.85714286, 0.87755102, 0.89795918,
+       0.91836735, 0.93877551, 0.95918367, 0.97959184, 1.        ]))
+
+
+

So now we have everything we need to make our own equivalent to ROOT TH1, from a filling perspective:

+
+
[4]:
+
+
+
class myTH1:
+    def __init__(self, binning):
+        self._binning = binning
+        self._sumw = np.zeros(binning.size - 1)
+
+    def fill(self, values, weights=None):
+        sumw, _ = np.histogram(values, bins=self._binning, weights=weights)
+        self._sumw += sumw
+
+    def __add__(self, other):
+        if not isinstance(other, myTH1):
+            raise ValueError
+        if not np.array_equal(other._binning, self._binning):
+            raise ValueError("The histograms have inconsistent binning")
+        out = myTH1(self._binning)
+        out._sumw = self._sumw + other._sumw
+        return out
+
+
+
+
+
[5]:
+
+
+
binning = np.linspace(0, 1, 50)
+
+h1 = myTH1(binning)
+h1.fill(vals)
+
+h2 = myTH1(binning)
+h2.fill(vals2)
+
+h = h1 + h2
+print(h._sumw)
+
+
+
+
+
+
+
+
+[ 3.  3.  7.  5.  9. 18. 16. 17. 15. 24. 26. 27. 34. 37. 23. 38. 29. 46.
+ 40. 40. 36. 50. 47. 49. 57. 49. 50. 44. 59. 69. 55. 52. 68. 54. 48. 72.
+ 72. 64. 55. 74. 57. 64. 63. 55. 49. 39. 39. 31. 22.]
+
+
+

Homework: add sumw2 support.

+

Of course, we might want multidimensional histograms. There is np.histogramdd:

+
+
[6]:
+
+
+
xyz = np.random.multivariate_normal(mean=[1, 3, 7], cov=np.eye(3), size=10000)
+
+xbins = np.linspace(-10, 10, 20)
+ybins = np.linspace(-10, 10, 20)
+zbins = np.linspace(-10, 10, 20)
+hnumpy = np.histogramdd(xyz, bins=(xbins, ybins, zbins))
+
+
+
+

but we are becoming challenged by book-keeping of the variables. The histogram class in Coffea is designed to simplify this operation, and the eventual successor (for filling purposes) boost-histogram has similar syntax.

+

In the constructor you specify each axis, either as a numeric Bin axis or a categorical Cat axis. Each axis constructor takes arguments similar to ROOT TH1 constructors. One can pass an array to the Bin axis for non-uniform binning. Then the fill call is as simple as passing the respective arrays to histo.fill.

+
+
[7]:
+
+
+
import coffea.hist as hist
+
+histo = hist.Hist("Counts",
+                  hist.Cat("sample", "sample name"),
+                  hist.Bin("x", "x value", 20, -10, 10),
+                  hist.Bin("y", "y value", 20, -10, 10),
+                  hist.Bin("z", "z value", 20, -10, 10),
+                 )
+
+histo.fill(sample="sample 1", x=xyz[:,0], y=xyz[:,1], z=xyz[:,2])
+
+# suppose we have another sample of xyz values
+xyz_sample2 = np.random.multivariate_normal(mean=[1, 3, 7], cov=np.eye(3), size=10000)
+
+# additionally, lets assume entries in sample 2 have some non-uniform weight equal to atan(distance from origin)
+weight = np.arctan(np.sqrt(np.power(xyz_sample2, 2).sum(axis=1)))
+
+# weight is a reserved keyword in Hist, and can be added to any fill() call
+histo.fill(sample="sample 2", x=xyz_sample2[:,0], y=xyz_sample2[:,1], z=xyz_sample2[:,2], weight=weight)
+
+print(histo)
+
+
+
+
+
+
+
+
+<Hist (sample,x,y,z) instance at 0x7fa15cf61390>
+
+
+
+
[8]:
+
+
+
# For more details, look at:
+# help(hist.Hist)
+# help(hist.Bin)
+# help(hist.Cat)
+
+
+
+
+
+

Transformation

+

Here are a few examples of transformations on multidimensional histograms in Coffea. For each, the docstring (help(function) or shift+tab in Jupyter) provides useful info.

+
+
[9]:
+
+
+
# sum all x bins within nominal range (-10, 10)
+histo.sum("x", overflow='none')
+
+
+
+
+
[9]:
+
+
+
+
+<Hist (sample,y,z) instance at 0x7fa15ba1af10>
+
+
+

There is some analog to fancy array slicing for histogram objects, which is supported (with reasonable consistency) in Coffea, where the slice boundaries are physical axis values, rather than bin indices. All values outside the slice range are merged into overflow bins.

+

For a lengthy discussion on possible slicing syntax for the future, see boost-histogram#35.

+
+
[10]:
+
+
+
sliced = histo[:,0:,4:,0:]
+display(sliced)
+display(sliced.identifiers("y", overflow='all'))
+
+
+
+
+
+
+
+
+<Hist (sample,x,y,z) instance at 0x7fa15de8e650>
+
+
+
+
+
+
+
+[<Interval ((-inf, 4)) instance at 0x7fa15ea2c710>,
+ <Interval ([4, 5)) instance at 0x7fa15ea2c790>,
+ <Interval ([5, 6)) instance at 0x7fa15ea2c7d0>,
+ <Interval ([6, 7)) instance at 0x7fa15ea2c810>,
+ <Interval ([7, 8)) instance at 0x7fa15ea2c850>,
+ <Interval ([8, 9)) instance at 0x7fa15ea2c8d0>,
+ <Interval ([9, 10)) instance at 0x7fa15ea2c910>,
+ <Interval ([10, inf)) instance at 0x7fa15ea2c950>]
+
+
+
+
[11]:
+
+
+
# integrate y bins from -2 to +10
+histo.integrate("y", slice(0, 10))
+
+
+
+
+
[11]:
+
+
+
+
+<Hist (sample,x,z) instance at 0x7fa15ea2cd50>
+
+
+
+
[12]:
+
+
+
# rebin z axis by providing a new axis definition
+histo.rebin("z", hist.Bin("znew", "rebinned z value", [-10, -6, 6, 10]))
+
+
+
+
+
[12]:
+
+
+
+
+<Hist (sample,x,y,znew) instance at 0x7fa15eb2d710>
+
+
+
+
[13]:
+
+
+
# merge categorical axes
+mapping = {
+    'all samples': ['sample 1', 'sample 2'],
+    'just sample 1': ['sample 1'],
+}
+histo.group("sample", hist.Cat("cat", "new category"), mapping)
+
+
+
+
+
[13]:
+
+
+
+
+<Hist (cat,x,y,z) instance at 0x7fa15eb307d0>
+
+
+
+
[14]:
+
+
+
# scale entire histogram by 3 (in-place)
+histo.scale(3.)
+
+
+
+
+
[15]:
+
+
+
# scale samples by different values (also in-place)
+scales = {
+    'sample 1': 1.2,
+    'sample 2': 0.2,
+}
+histo.scale(scales, axis='sample')
+
+
+
+
+
[16]:
+
+
+
# useful debugging tool: print bins, aka 'identifiers'
+display(histo.identifiers('sample'))
+display(histo.identifiers('x'))
+
+
+
+
+
+
+
+
+[<StringBin (sample 1) instance at 0x7fa15e7ab7d0>,
+ <StringBin (sample 2) instance at 0x7fa15e7ab810>]
+
+
+
+
+
+
+
+[<Interval ([-10, -9)) instance at 0x7fa15ceadfd0>,
+ <Interval ([-9, -8)) instance at 0x7fa15ceadd90>,
+ <Interval ([-8, -7)) instance at 0x7fa15cead350>,
+ <Interval ([-7, -6)) instance at 0x7fa15cead750>,
+ <Interval ([-6, -5)) instance at 0x7fa15ceadb50>,
+ <Interval ([-5, -4)) instance at 0x7fa15cead1d0>,
+ <Interval ([-4, -3)) instance at 0x7fa15ceade90>,
+ <Interval ([-3, -2)) instance at 0x7fa15cead250>,
+ <Interval ([-2, -1)) instance at 0x7fa15ceada90>,
+ <Interval ([-1, 0)) instance at 0x7fa15cead210>,
+ <Interval ([0, 1)) instance at 0x7fa15cead090>,
+ <Interval ([1, 2)) instance at 0x7fa15cead710>,
+ <Interval ([2, 3)) instance at 0x7fa15cead610>,
+ <Interval ([3, 4)) instance at 0x7fa15cead0d0>,
+ <Interval ([4, 5)) instance at 0x7fa15bec6710>,
+ <Interval ([5, 6)) instance at 0x7fa15ce87f90>,
+ <Interval ([6, 7)) instance at 0x7fa15eb361d0>,
+ <Interval ([7, 8)) instance at 0x7fa15eb36250>,
+ <Interval ([8, 9)) instance at 0x7fa15eb36310>,
+ <Interval ([9, 10)) instance at 0x7fa15eb363d0>]
+
+
+
+
[17]:
+
+
+
# bin contents are accessed using values
+histo.sum('x', 'y').values(sumw2=False)
+
+
+
+
+
[17]:
+
+
+
+
+{('sample 1',): array([0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00,
+        0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00,
+        0.00000e+00, 0.00000e+00, 3.60000e+00, 5.40000e+01, 7.23600e+02,
+        4.83120e+03, 1.24164e+04, 1.24344e+04, 4.68720e+03, 8.13600e+02]),
+ ('sample 2',): array([0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
+        0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
+        0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
+        7.67352230e-01, 1.23975181e+01, 1.91084135e+02, 1.16950599e+03,
+        3.00209800e+03, 2.88614286e+03, 1.20687727e+03, 1.68492970e+02])}
+
+
+
+
[18]:
+
+
+
# data can be exported to ROOT via uproot3 (soon uproot v4 as well), but only 1D
+import uproot3
+import os
+
+if os.path.exists("output.root"):
+    os.remove("output.root")
+
+outputfile = uproot3.create("output.root")
+h = histo.sum('x', 'y')
+for sample in h.identifiers('sample'):
+    outputfile[sample.name] = hist.export1d(h.integrate('sample', sample))
+outputfile.close()
+
+
+
+
+
+
+
+
+/Users/lagray/miniconda3/envs/coffea-work/lib/python3.7/site-packages/uproot3/__init__.py:138: FutureWarning: Consider switching from 'uproot3' to 'uproot', since the new interface became the default in 2020.
+
+    pip install -U uproot
+
+In Python:
+
+    >>> import uproot
+    >>> with uproot.open(...) as file:
+    ...
+
+  FutureWarning
+
+
+
+
+

Plotting

+

The most integrated plotting utility in the scientific python ecosystem, by far, is matplotlib. However, as we will see, it is not tailored to HEP needs.

+

Let’s start by looking at basic mpl histogramming.

+
+
[19]:
+
+
+
%matplotlib inline
+import matplotlib.pyplot as plt
+
+
+
+
+
[20]:
+
+
+
vals = argus(chi=.5).rvs(size=1000)
+
+# notice the semicolon, which prevents display of the return values
+plt.hist(vals);
+
+
+
+
+
+
+
+../_images/notebooks_histograms_29_0.png +
+
+

Suppose we want to plot pre-binned data, for example from our earlier np.histogram usage. Here we start running into the edge of typical mpl usage. As mentioned before, apparently HEP is the only regular user of pre-binned histograms.

+
+
[21]:
+
+
+
binning = np.linspace(0, 1, 50)
+
+h1vals, h1bins = np.histogram(vals, bins=binning)
+plt.step(x=h1bins[:-1], y=h1vals, where='post');
+
+
+
+
+
+
+
+../_images/notebooks_histograms_31_0.png +
+
+

To facilitate these operations, there is a package called mplhep. This package is available standlaone, but it is also used internally by the coffea.hist subpackage to provide several convenience functions to aid in plotting Hist objects:

+
    +
  • plot1d: Create a 1D plot from a 1D or 2D Hist object

  • +
  • plotratio: Create a ratio plot, dividing two compatible histograms

  • +
  • plot2d: Create a 2D plot from a 2D Hist object

  • +
  • plotgrid: Create a grid of plots, enumerating identifiers on up to 3 axes

  • +
+

Below are some simple examples of using each function on our histo object.

+
+
[22]:
+
+
+
hist.plot1d(histo.sum("x", "y"), overlay='sample');
+
+
+
+
+
+
+
+../_images/notebooks_histograms_33_0.png +
+
+
+
[23]:
+
+
+
hist.plot1d(histo.sum("x", "y"), overlay='sample', stack=True);
+
+
+
+
+
+
+
+../_images/notebooks_histograms_34_0.png +
+
+
+
[24]:
+
+
+
hist.plot2d(histo.sum('x', 'sample'), xaxis='y');
+
+
+
+
+
+
+
+../_images/notebooks_histograms_35_0.png +
+
+
+
[25]:
+
+
+
# make coarse binned hist and look at several distributions
+hnew = (
+    histo
+    .rebin("y", hist.Bin("ynew", "rebinned y value", [0, 3, 5]))
+    .rebin("z", hist.Bin("znew", "rebinned z value", [5, 8, 10]))
+)
+
+hist.plotgrid(hnew, row='ynew', col='znew', overlay='sample');
+
+
+
+
+
+
+
+../_images/notebooks_histograms_36_0.png +
+
+
+
[26]:
+
+
+
numerator = histo.integrate('sample', 'sample 1').sum('y', 'z')
+denominator = histo.sum('sample', 'y', 'z')
+
+numerator.label = r'$\epsilon$'
+ax = hist.plotratio(
+    num=numerator,
+    denom=denominator,
+    error_opts={'color': 'k', 'marker': '.'},
+    unc='clopper-pearson'
+)
+ax.set_ylim(0.6, 1.)
+ax.set_xlim(-10, 10)
+
+
+
+
+
+
+
+
+/Users/lagray/coffea/coffea/binder/coffea/hist/plot.py:357: RuntimeWarning: invalid value encountered in true_divide
+  rsumw = sumw_num / sumw_denom
+
+
+
+
[26]:
+
+
+
+
+(-10.0, 10.0)
+
+
+
+
+
+
+../_images/notebooks_histograms_37_2.png +
+
+
+
+

Styling

+

We’ve covered the basics of plotting, now let’s go over some styling options. To make things more interesting, we’ll load some electron and muon Lorentz vectors from simulated \(H\rightarrow ZZ^{*}\) events into awkward arrays and then plot some kinematic quantities for them, making liberal use of the matplotlib styling options which are exposed through the coffea plotting utilities.

+
+
[27]:
+
+
+
!curl -OL http://scikit-hep.org/uproot3/examples/HZZ.root
+
+
+
+
+
+
+
+
+  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
+                                 Dload  Upload   Total   Spent    Left  Speed
+100  212k  100  212k    0     0  7601k      0 --:--:-- --:--:-- --:--:-- 7601k
+
+
+
+
[28]:
+
+
+
import uproot
+import awkward as ak
+from coffea.nanoevents.methods import vector
+ak.behavior.update(vector.behavior)
+
+fin = uproot.open("HZZ.root")
+tree = fin["events"]
+
+# let's build the lepton arrays back into objects
+# in the future, some of this verbosity can be reduced
+arrays = {k.replace('Electron_', ''): v for k, v in tree.arrays(filter_name="Electron_*", how=dict).items()}
+electrons = ak.zip({'x': arrays.pop('Px'),
+                    'y': arrays.pop('Py'),
+                    'z': arrays.pop("Pz"),
+                    't': arrays.pop("E"),
+                    },
+                    with_name="LorentzVector"
+)
+
+
+arrays = {k.replace('Muon_', ''): v for k,v in tree.arrays(filter_name="Muon_*", how=dict).items()}
+muons = ak.zip({'x': arrays.pop('Px'),
+                'y': arrays.pop('Py'),
+                'z': arrays.pop("Pz"),
+                't': arrays.pop("E"),
+                },
+                with_name="LorentzVector"
+)
+
+print("Avg. electrons/event:", ak.sum(ak.num(electrons))/tree.num_entries)
+print("Avg. muons/event:", ak.sum(ak.num(muons))/tree.num_entries)
+
+
+
+
+
+
+
+
+Avg. electrons/event: 0.07063197026022305
+Avg. muons/event: 1.579925650557621
+
+
+
+
[29]:
+
+
+
lepton_kinematics = hist.Hist(
+    "Events",
+    hist.Cat("flavor", "Lepton flavor"),
+    hist.Bin("pt", "$p_{T}$", 19, 10, 100),
+    hist.Bin("eta", "$\eta$", [-2.5, -1.4, 0, 1.4, 2.5]),
+)
+
+# Pass keyword arguments to fill, all arrays must be flat numpy arrays
+# User is responsible for ensuring all arrays have same jagged structure!
+lepton_kinematics.fill(
+    flavor="electron",
+    pt=ak.flatten(electrons.pt),
+    eta=ak.flatten(electrons.eta)
+)
+lepton_kinematics.fill(
+    flavor="muon",
+    pt=ak.flatten(muons.pt),
+    eta=ak.flatten(muons.eta)
+)
+
+
+
+
+
[30]:
+
+
+
# Now we can start to manipulate this single histogram to plot different views of the data
+# here we look at lepton pt for all eta
+lepton_pt = lepton_kinematics.integrate("eta")
+
+ax = hist.plot1d(
+    lepton_pt,
+    overlay="flavor",
+    stack=True,
+    fill_opts={'alpha': .5, 'edgecolor': (0,0,0,0.3)}
+)
+# all plot calls return the matplotlib axes object, from which
+# you can edit features afterwards using matplotlib object-oriented syntax
+# e.g. maybe you really miss '90s graphics...
+ax.get_legend().shadow = True
+
+
+
+
+
+
+
+../_images/notebooks_histograms_42_0.png +
+
+
+
[31]:
+
+
+
# Clearly the yields are much different, are the shapes similar? We can check by setting `density=True`
+lepton_pt.label = "Density"
+ax = hist.plot1d(lepton_pt, overlay="flavor", density=True)
+
+
+
+
+
+
+
+../_images/notebooks_histograms_43_0.png +
+
+
+
[32]:
+
+
+
# Let's stack them, after defining some nice styling
+stack_fill_opts = {
+    'alpha': 0.8,
+    'edgecolor':(0,0,0,.5)
+}
+stack_error_opts = {
+    'label':'Stat. Unc.',
+    'hatch':'///',
+    'facecolor':'none',
+    'edgecolor':(0,0,0,.5),
+    'linewidth': 0
+}
+# maybe we want to compare different eta regions
+# plotgrid accepts row and column axes, and creates a grid of 1d plots as appropriate
+ax = hist.plotgrid(
+    lepton_kinematics,
+    row="eta",
+    overlay="flavor",
+    stack=True,
+    fill_opts=stack_fill_opts,
+    error_opts=stack_error_opts,
+)
+
+
+
+
+
+
+
+../_images/notebooks_histograms_44_0.png +
+
+
+
[33]:
+
+
+
# Here we create some pseudodata for the pt histogram so we can make a nice data/mc plot
+pthist = lepton_kinematics.sum('eta')
+bin_values = pthist.axis('pt').centers()
+poisson_means = pthist.sum('flavor').values()[()]
+values = np.repeat(bin_values, np.random.poisson(poisson_means))
+pthist.fill(flavor='pseudodata', pt=values)
+
+# Set nicer labels, by accessing the string bins' label property
+pthist.axis('flavor').index('electron').label = 'e Flavor'
+pthist.axis('flavor').index('muon').label = r'$\mu$ Flavor'
+pthist.axis('flavor').index('pseudodata').label = r'Pseudodata from e/$\mu$'
+
+# using regular expressions on flavor name to select just the data
+# another method would be to fill a separate data histogram
+import re
+notdata = re.compile('(?!pseudodata)')
+
+
+
+
+
[34]:
+
+
+
# make a nice ratio plot, adjusting some font sizes
+plt.rcParams.update({
+    'font.size': 14,
+    'axes.titlesize': 18,
+    'axes.labelsize': 18,
+    'xtick.labelsize': 12,
+    'ytick.labelsize': 12
+})
+fig, (ax, rax) = plt.subplots(
+    nrows=2,
+    ncols=1,
+    figsize=(7,7),
+    gridspec_kw={"height_ratios": (3, 1)},
+    sharex=True
+)
+fig.subplots_adjust(hspace=.07)
+
+# Here is an example of setting up a color cycler to color the various fill patches
+# We get the colors from this useful utility: http://colorbrewer2.org/#type=qualitative&scheme=Paired&n=6
+from cycler import cycler
+colors = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c']
+ax.set_prop_cycle(cycler(color=colors))
+
+fill_opts = {
+    'edgecolor': (0,0,0,0.3),
+    'alpha': 0.8
+}
+error_opts = {
+    'label': 'Stat. Unc.',
+    'hatch': '///',
+    'facecolor': 'none',
+    'edgecolor': (0,0,0,.5),
+    'linewidth': 0
+}
+data_err_opts = {
+    'linestyle': 'none',
+    'marker': '.',
+    'markersize': 10.,
+    'color': 'k',
+    'elinewidth': 1,
+}
+
+# plot the MC first
+hist.plot1d(
+    pthist[notdata],
+    overlay="flavor",
+    ax=ax,
+    clear=False,
+    stack=True,
+    line_opts=None,
+    fill_opts=fill_opts,
+    error_opts=error_opts
+)
+# now the pseudodata, setting clear=False to avoid overwriting the previous plot
+hist.plot1d(
+    pthist['pseudodata'],
+    overlay="flavor",
+    ax=ax,
+    clear=False,
+    error_opts=data_err_opts
+)
+
+ax.autoscale(axis='x', tight=True)
+ax.set_ylim(0, None)
+ax.set_xlabel(None)
+leg = ax.legend()
+
+# now we build the ratio plot
+hist.plotratio(
+    num=pthist['pseudodata'].sum("flavor"),
+    denom=pthist[notdata].sum("flavor"),
+    ax=rax,
+    error_opts=data_err_opts,
+    denom_fill_opts={},
+    guide_opts={},
+    unc='num'
+)
+rax.set_ylabel('Ratio')
+rax.set_ylim(0,2)
+
+# add some labels
+coffee = plt.text(0., 1., u"☕",
+                  fontsize=28,
+                  horizontalalignment='left',
+                  verticalalignment='bottom',
+                  transform=ax.transAxes
+                 )
+lumi = plt.text(1., 1., r"1 fb$^{-1}$ (?? TeV)",
+                fontsize=16,
+                horizontalalignment='right',
+                verticalalignment='bottom',
+                transform=ax.transAxes
+               )
+
+
+
+
+
+
+
+../_images/notebooks_histograms_46_0.png +
+
+

Some further styling tools are available through the mplhep package. In particular, there are several stylesheets that update plt.rcParams to conform with experiment style recommendations regarding font face, font sizes, tick mark styles, and other such things. Below is an example application.

+
+
[35]:
+
+
+
import mplhep
+plt.style.use(mplhep.style.ROOT)
+
+# Compare this to the style of the plot drawn previously
+ax = hist.plot1d(lepton_pt, overlay="flavor", density=True)
+
+
+
+
+
+
+
+../_images/notebooks_histograms_48_0.png +
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/notebooks/histograms.ipynb b/notebooks/histograms.ipynb new file mode 100644 index 000000000..d14ddbe6d --- /dev/null +++ b/notebooks/histograms.ipynb @@ -0,0 +1,1190 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Coffea Histograms (deprecated)\n", + "\n", + "_This feature is deprecated in favor of [hist](https://hist.readthedocs.io/en/latest/) and [mplhep](https://mplhep.readthedocs.io/en/latest/). A migration guide can be found in discussion [CoffeaTeam/coffea#705](https://github.com/CoffeaTeam/coffea/discussions/705)_\n", + "\n", + "This is a rendered copy of [histograms.ipynb](https://github.com/CoffeaTeam/coffea/blob/master/binder/histograms.ipynb). You can optionally run it interactively on [binder at this link](https://mybinder.org/v2/gh/coffeateam/coffea/master?filepath=binder%2Fhistograms.ipynb)\n", + "\n", + "In scientific python, histograms seem to be considered as a plot style, on equal footing with, e.g. scatter plots.\n", + "It may well be that HEP is the only place where users need to plot *pre-binned* data, and thus must use histograms as persistent objects representing reduced data. In Coffea, the [hist](https://coffeateam.github.io/coffea/modules/coffea.hist.html) subpackage provides a persistable mergable histogram object. This notebook will discuss a few ways that such objects can be manipulated.\n", + "\n", + "A histogram object roughly goes through three stages in its life:\n", + "\n", + " - Filling\n", + " - Transformation (projection, rebinning, integrating)\n", + " - Plotting\n", + "\n", + "We'll go over examples of each stage in this notebook, and conclude with some styling examples." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Filling\n", + "Let's start with filling. We'll use a random distribution [near and dear](https://en.wikipedia.org/wiki/ARGUS_distribution) to of b and c factory physicists, and have the numpy builtin [histogram function](https://numpy.org/doc/stable/reference/generated/numpy.histogram.html) do the work for us:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(array([ 16, 47, 66, 95, 125, 113, 137, 167, 143, 91]), array([0.002894 , 0.10257766, 0.20226132, 0.30194498, 0.40162865,\n", + " 0.50131231, 0.60099597, 0.70067963, 0.80036329, 0.90004695,\n", + " 0.99973061]))\n" + ] + } + ], + "source": [ + "import numpy as np\n", + "from scipy.stats import argus\n", + "\n", + "vals = argus(chi=.5).rvs(size=1000)\n", + "\n", + "hist = np.histogram(vals)\n", + "print(hist)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So we're done, right?\n", + "Probably not: we have more than 1000 events, and probably need to use some map-reduce paradigm to fill the histogram because we can't keep all 1 billion `vals` in memory. So we need two things: a binning, so that all histograms that were independently created can be added, and the ability to add two histograms." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "binning = np.linspace(0, 1, 50)\n", + "\n", + "def add_histos(h1, h2):\n", + " h1sumw, h1binning = h1\n", + " h2sumw, h2binning = h2\n", + " if h1binning.shape == h2binning.shape and np.all(h1binning==h2binning):\n", + " return h1sumw+h2sumw, h1binning\n", + " else:\n", + " raise ValueError(\"The histograms have inconsistent binning\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "(array([ 2, 6, 6, 6, 12, 18, 20, 16, 14, 28, 22, 26, 28, 42, 18, 34, 28,\n", + " 48, 40, 42, 42, 60, 46, 62, 46, 52, 46, 38, 52, 54, 50, 58, 72, 54,\n", + " 50, 74, 80, 58, 70, 70, 42, 64, 68, 52, 60, 32, 44, 30, 18]), array([0. , 0.02040816, 0.04081633, 0.06122449, 0.08163265,\n", + " 0.10204082, 0.12244898, 0.14285714, 0.16326531, 0.18367347,\n", + " 0.20408163, 0.2244898 , 0.24489796, 0.26530612, 0.28571429,\n", + " 0.30612245, 0.32653061, 0.34693878, 0.36734694, 0.3877551 ,\n", + " 0.40816327, 0.42857143, 0.44897959, 0.46938776, 0.48979592,\n", + " 0.51020408, 0.53061224, 0.55102041, 0.57142857, 0.59183673,\n", + " 0.6122449 , 0.63265306, 0.65306122, 0.67346939, 0.69387755,\n", + " 0.71428571, 0.73469388, 0.75510204, 0.7755102 , 0.79591837,\n", + " 0.81632653, 0.83673469, 0.85714286, 0.87755102, 0.89795918,\n", + " 0.91836735, 0.93877551, 0.95918367, 0.97959184, 1. ]))\n" + ] + } + ], + "source": [ + "vals2 = argus(chi=.5).rvs(size=1000)\n", + "\n", + "hist1 = np.histogram(vals, bins=binning)\n", + "hist2 = np.histogram(vals, bins=binning)\n", + "\n", + "hist = add_histos(hist1, hist2)\n", + "print(hist)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So now we have everything we need to make our own equivalent to ROOT TH1, from a filling perspective:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "class myTH1:\n", + " def __init__(self, binning):\n", + " self._binning = binning\n", + " self._sumw = np.zeros(binning.size - 1)\n", + " \n", + " def fill(self, values, weights=None):\n", + " sumw, _ = np.histogram(values, bins=self._binning, weights=weights)\n", + " self._sumw += sumw\n", + " \n", + " def __add__(self, other):\n", + " if not isinstance(other, myTH1):\n", + " raise ValueError\n", + " if not np.array_equal(other._binning, self._binning):\n", + " raise ValueError(\"The histograms have inconsistent binning\")\n", + " out = myTH1(self._binning)\n", + " out._sumw = self._sumw + other._sumw\n", + " return out" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[ 3. 3. 7. 5. 9. 18. 16. 17. 15. 24. 26. 27. 34. 37. 23. 38. 29. 46.\n", + " 40. 40. 36. 50. 47. 49. 57. 49. 50. 44. 59. 69. 55. 52. 68. 54. 48. 72.\n", + " 72. 64. 55. 74. 57. 64. 63. 55. 49. 39. 39. 31. 22.]\n" + ] + } + ], + "source": [ + "binning = np.linspace(0, 1, 50)\n", + "\n", + "h1 = myTH1(binning)\n", + "h1.fill(vals)\n", + "\n", + "h2 = myTH1(binning)\n", + "h2.fill(vals2)\n", + "\n", + "h = h1 + h2\n", + "print(h._sumw)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Homework: add `sumw2` support.\n", + "\n", + "Of course, we might want multidimensional histograms. There is `np.histogramdd`:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "xyz = np.random.multivariate_normal(mean=[1, 3, 7], cov=np.eye(3), size=10000)\n", + "\n", + "xbins = np.linspace(-10, 10, 20)\n", + "ybins = np.linspace(-10, 10, 20)\n", + "zbins = np.linspace(-10, 10, 20)\n", + "hnumpy = np.histogramdd(xyz, bins=(xbins, ybins, zbins))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "but we are becoming challenged by book-keeping of the variables.\n", + "The [histogram class](https://coffeateam.github.io/coffea/api/coffea.hist.Hist.html#coffea.hist.Hist) in Coffea is designed to simplify this operation, and the eventual successor (for filling purposes) [boost-histogram](https://github.com/scikit-hep/boost-histogram#usage) has similar syntax.\n", + "\n", + "In the constructor you specify each axis, either as a numeric `Bin` axis or a categorical `Cat` axis. Each axis constructor takes arguments similar to ROOT TH1 constructors. One can pass an array to the `Bin` axis for non-uniform binning. Then the fill call is as simple as passing the respective arrays to `histo.fill`." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "import coffea.hist as hist\n", + "\n", + "histo = hist.Hist(\"Counts\",\n", + " hist.Cat(\"sample\", \"sample name\"),\n", + " hist.Bin(\"x\", \"x value\", 20, -10, 10),\n", + " hist.Bin(\"y\", \"y value\", 20, -10, 10),\n", + " hist.Bin(\"z\", \"z value\", 20, -10, 10),\n", + " )\n", + "\n", + "histo.fill(sample=\"sample 1\", x=xyz[:,0], y=xyz[:,1], z=xyz[:,2])\n", + "\n", + "# suppose we have another sample of xyz values\n", + "xyz_sample2 = np.random.multivariate_normal(mean=[1, 3, 7], cov=np.eye(3), size=10000)\n", + "\n", + "# additionally, lets assume entries in sample 2 have some non-uniform weight equal to atan(distance from origin)\n", + "weight = np.arctan(np.sqrt(np.power(xyz_sample2, 2).sum(axis=1)))\n", + "\n", + "# weight is a reserved keyword in Hist, and can be added to any fill() call\n", + "histo.fill(sample=\"sample 2\", x=xyz_sample2[:,0], y=xyz_sample2[:,1], z=xyz_sample2[:,2], weight=weight)\n", + "\n", + "print(histo)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "# For more details, look at:\n", + "# help(hist.Hist)\n", + "# help(hist.Bin)\n", + "# help(hist.Cat)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Transformation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Here are a few examples of transformations on multidimensional histograms in Coffea. For each, the docstring (`help(function)` or shift+tab in Jupyter) provides useful info." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# sum all x bins within nominal range (-10, 10)\n", + "histo.sum(\"x\", overflow='none')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "There is some analog to fancy array slicing for histogram objects, which is supported (with reasonable consistency) in Coffea, where the slice boundaries are physical axis values, rather than bin indices. All values outside the slice range are merged into overflow bins.\n", + "\n", + "For a lengthy discussion on possible slicing syntax for the future, see [boost-histogram#35](https://github.com/scikit-hep/boost-histogram/issues/35)." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sliced = histo[:,0:,4:,0:]\n", + "display(sliced)\n", + "display(sliced.identifiers(\"y\", overflow='all'))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# integrate y bins from -2 to +10\n", + "histo.integrate(\"y\", slice(0, 10))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# rebin z axis by providing a new axis definition\n", + "histo.rebin(\"z\", hist.Bin(\"znew\", \"rebinned z value\", [-10, -6, 6, 10]))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# merge categorical axes\n", + "mapping = {\n", + " 'all samples': ['sample 1', 'sample 2'],\n", + " 'just sample 1': ['sample 1'],\n", + "}\n", + "histo.group(\"sample\", hist.Cat(\"cat\", \"new category\"), mapping)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "# scale entire histogram by 3 (in-place)\n", + "histo.scale(3.)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "# scale samples by different values (also in-place)\n", + "scales = {\n", + " 'sample 1': 1.2,\n", + " 'sample 2': 0.2,\n", + "}\n", + "histo.scale(scales, axis='sample')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "[,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ,\n", + " ]" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# useful debugging tool: print bins, aka 'identifiers'\n", + "display(histo.identifiers('sample'))\n", + "display(histo.identifiers('x'))" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{('sample 1',): array([0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00,\n", + " 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00, 0.00000e+00,\n", + " 0.00000e+00, 0.00000e+00, 3.60000e+00, 5.40000e+01, 7.23600e+02,\n", + " 4.83120e+03, 1.24164e+04, 1.24344e+04, 4.68720e+03, 8.13600e+02]),\n", + " ('sample 2',): array([0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,\n", + " 7.67352230e-01, 1.23975181e+01, 1.91084135e+02, 1.16950599e+03,\n", + " 3.00209800e+03, 2.88614286e+03, 1.20687727e+03, 1.68492970e+02])}" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# bin contents are accessed using values\n", + "histo.sum('x', 'y').values(sumw2=False)" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/lagray/miniconda3/envs/coffea-work/lib/python3.7/site-packages/uproot3/__init__.py:138: FutureWarning: Consider switching from 'uproot3' to 'uproot', since the new interface became the default in 2020.\n", + "\n", + " pip install -U uproot\n", + "\n", + "In Python:\n", + "\n", + " >>> import uproot\n", + " >>> with uproot.open(...) as file:\n", + " ...\n", + "\n", + " FutureWarning\n" + ] + } + ], + "source": [ + "# data can be exported to ROOT via uproot3 (soon uproot v4 as well), but only 1D\n", + "import uproot3\n", + "import os\n", + "\n", + "if os.path.exists(\"output.root\"):\n", + " os.remove(\"output.root\")\n", + "\n", + "outputfile = uproot3.create(\"output.root\")\n", + "h = histo.sum('x', 'y')\n", + "for sample in h.identifiers('sample'):\n", + " outputfile[sample.name] = hist.export1d(h.integrate('sample', sample))\n", + "outputfile.close()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Plotting\n", + "The most integrated plotting utility in the scientific python ecosystem, by far, is [matplotlib](https://matplotlib.org/). However, as we will see, it is not tailored to HEP needs.\n", + "\n", + "Let's start by looking at basic mpl histogramming." + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "vals = argus(chi=.5).rvs(size=1000)\n", + "\n", + "# notice the semicolon, which prevents display of the return values\n", + "plt.hist(vals);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Suppose we want to plot pre-binned data, for example from our earlier `np.histogram` usage. Here we start running into the edge of typical mpl usage. As mentioned before, apparently HEP is the only regular user of pre-binned histograms." + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "binning = np.linspace(0, 1, 50)\n", + "\n", + "h1vals, h1bins = np.histogram(vals, bins=binning)\n", + "plt.step(x=h1bins[:-1], y=h1vals, where='post');" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "To facilitate these operations, there is a package called [mplhep](https://github.com/scikit-hep/mplhep). This package is available standlaone, but it is also used internally by the `coffea.hist` subpackage to provide several convenience functions to aid in plotting `Hist` objects:\n", + "\n", + " * [plot1d](https://coffeateam.github.io/coffea/api/coffea.hist.plot1d.html#coffea.hist.plot1d): Create a 1D plot from a 1D or 2D Hist object\n", + "\n", + " * [plotratio](https://coffeateam.github.io/coffea/api/coffea.hist.plotratio.html#coffea.hist.plotratio): Create a ratio plot, dividing two compatible histograms\n", + "\n", + " * [plot2d](https://coffeateam.github.io/coffea/api/coffea.hist.plot2d.html#coffea.hist.plot2d): Create a 2D plot from a 2D Hist object\n", + "\n", + " * [plotgrid](https://coffeateam.github.io/coffea/api/coffea.hist.plotgrid.html#coffea.hist.plotgrid): Create a grid of plots, enumerating identifiers on up to 3 axes\n", + " \n", + "Below are some simple examples of using each function on our `histo` object." + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZwAAAEGCAYAAABRvCMcAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAh6ElEQVR4nO3de3xU1b338c+Pa+oFAUkBCR5AQQkXKYZb0VNOqYCiYi3eqpWiFVultbYi+OjLW/Vp9ZxHqz5V5CiKfXlBqT5QpSIottYCGiyCXCxRUYOgFBSKHEH09/yxV+IQZpJJMrNnknzfr9e8smfttff+zc5kfll7r1nL3B0REZFsa5brAEREpGlQwhERkVgo4YiISCyUcEREJBZKOCIiEosWuQ4gbh06dPBu3brlOgwRkQZl+fLl/3T3wvrso8klnG7dulFaWprrMEREGhQze7e++9AlNRERiYUSjoiIxEIJR0REYtHk7uEk8/nnn1NeXs5nn32W61AapIKCAoqKimjZsmWuQxGRPKaEA5SXl3PwwQfTrVs3zCzX4TQo7s7WrVspLy+ne/fuuQ5HRPKYLqkBn332GYceeqiSTR2YGYceeqhahyJSIyWcQMmm7nTuRCQdSjgiIhILJZw8M2LECH0xVUQaJSUcEZE6OOveJZx175Kc76MhUcKpwaeffsrYsWM55phj6Nu3L7NnzwbgxhtvZNCgQfTt25dJkyZRMXPqiBEjuPzyyykpKaF37968+uqrnH766fTs2ZNrrrkGgA0bNnD00Udz7rnn0rt3b8aPH8+uXbv2O/Zzzz3HsGHDGDhwIGeccQY7d+7cr86IESOYOnUqgwcPplevXrz00kuVxzj++OMZOHAgAwcO5G9/+xsAL774It/61rcYN24cPXr0YNq0aTz88MMMHjyYfv368dZbbwGwZcsWvve97zFo0CAGDRrEyy+/nPmTKyJNirpF1+DZZ5/lsMMO45lnngFg+/btAEyePJlrr70WgB/84Ac8/fTTnHLKKQC0atWK0tJS7rjjDsaNG8fy5ctp3749RxxxBJdffjkAb775Jvfffz/Dhw/nggsu4O677+aKK66oPO4///lPbrrpJhYtWsSBBx7ILbfcwm233VZ5zER79+7llVdeYf78+dxwww0sWrSIr3/96yxcuJCCggLWr1/POeecU3mp7vXXX2ft2rW0b9+eHj168KMf/YhXXnmFO+64g7vuuovf/va3XHbZZVx++eUcd9xxvPfee4wePZq1a9dm70SLNDKPLHuPuSs2VltnzaYdANW2csYN6ML3hxye0dhyRQmnBv369eOXv/wlU6dO5eSTT+b4448HYPHixdx6663s2rWLbdu20adPn8qEc+qpp1Zu26dPHzp37gxAjx49eP/992nbti1du3Zl+PDhAJx33nnceeed+yScpUuXsmbNmso6e/bsYdiwYUljPP300wE49thj2bBhAxB9mXXy5MmsWLGC5s2b849//KOy/qBBgypjOuKIIxg1alRlvIsXLwZg0aJFrFmzpnKbHTt2sHPnTg466KC6nkqRBqWmhFFTslj2zjYAhnRvX+cYKo6hhNNE9OrVi9dee4358+dzzTXXMHLkSK688kouueQSSktL6dq1K9dff/0+30Np3bo1AM2aNatcrni+d+9eYP+uxFWfuzsnnHACjz76aI0xVhyjefPmlfu//fbb6dixI6+//jpffvklBQUF+9WvGmNifF9++SVLly7dZzuRpmTuio2s2bSD4s5t6rT9kO7ta2ydVCSr2Rcn/2eysd3fUcKpwQcffED79u0577zzaNu2Lffdd19lcunQoQM7d+5kzpw5jB8/vlb7fe+991iyZAnDhg3jkUce4bjjjttn/dChQ7n00kspKyvjyCOP5NNPP2Xjxo306tUrrf1v376doqIimjVrxqxZs/jiiy9qFd+oUaO46667mDJlCgArVqxgwIABtdqHSENX3LlNjckg1XrZnzoN1GDVqlUMHjyYAQMGcMMNN3DNNdfQtm1bLrroIvr27cvo0aMZNGhQrfd71FFH8bvf/Y7evXvz8ccf85Of/GSf9YWFhTz44IOcc8459O/fn2HDhrFu3bq093/JJZcwa9YsjjnmGNatW8eBBx5Yq/juvPNOSktL6d+/P8XFxUyfPr1W24uIVGUVvasyvmOzmcDJwEfu3jeU/SdwCrAHeAuY6O6fhHVXARcCXwA/c/cFoXwMcAfQHLjP3X8TyrsDjwGHAsuBH7j7npriKikp8arfc1m7di29e/eu70tO24YNGzj55JN54403YjtmtsV9DkWyLR9aMPkQQwUzW+7uJfXZRzZbOA8CY6qULQT6unt/4B/AVQBmVgycDfQJ29xtZs3NrDnwO+BEoBg4J9QFuAW43d2P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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "hist.plot1d(histo.sum(\"x\", \"y\"), overlay='sample');" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZwAAAEICAYAAABrtkJsAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAkBElEQVR4nO3de5hWdbn/8fcHEMk8oDISAgYaHggP0YCYWhSKeAp3qWm6JU/8SjFrt1XMri2ZdrC2lpWyLUn0UvBESUoiIlqpKEiACCijog6pEAiGFIXevz/WF3wYnoEZ5nnWMzN8Xtc116x1r+9a615rHuZmrfWd71JEYGZmVm5tKp2AmZltG1xwzMwsFy44ZmaWCxccMzPLhQuOmZnlwgXHzMxyUbaCI2mMpKWS5tWJXyRpoaTnJV1bEL9cUo2kFyQdUxAfkmI1kkYWxHtKejrF75LUvlzHYmZmTady/R2OpE8Dq4HbIqJPin0WuAI4PiLWStojIpZK6g2MA/oDewKPAPumTb0IHA3UAjOA0yNivqS7gQkRMV7SaGBORNy0pbw6deoUPXr0KOmxmpm1ds8+++zfIqKqKdtoV6pk6oqIP0rqUSf8NeCHEbE2tVma4kOB8Sn+iqQasuIDUBMRLwNIGg8MlbQA+Bzw5dRmLDAK2GLB6dGjBzNnztzq4zIz2xZJerWp28j7Gc6+wJHpVtjjkvqleFfg9YJ2tSlWX3x3YGVErKsTNzOzZqpsVzib2d9uwACgH3C3pL3LvVNJw4HhAHvttVe5d2dmZkXkfYVTS/bcJSLiGeB9oBOwBOhe0K5bitUXXw50lNSuTryoiLg5Iqojorqqqkm3IM3MbCvlfYXzO+CzwDRJ+wLtgb8BE4E7JV1H1mmgF/AMIKCXpJ5kBeU04MsREZKmAScD44FhwP05H4uZNTP//ve/qa2t5Z///GelU2mxOnToQLdu3dhuu+1Kvu2yFRxJ44CBQCdJtcCVwBhgTOoq/S9gWGTd5J5Pvc7mA+uACyPivbSdEcBkoC0wJiKeT7u4DBgv6WrgL8At5ToWM2sZamtr2WmnnejRoweSKp1OixMRLF++nNraWnr27Fny7ZetW3RzVV1dHe6lZtY6LViwgP3339/FpgkigoULF3LAAQdsFJf0bERUN2XbHmnAzFoVF5umKef5c8ExM7NcuOCYmZXBwIED/UfmdeTdS83MrMWYW7tyq9d9d+26LTfaxvgKx8y2Ce+++y7HH388Bx98MH369OGuu+4C4KqrrqJfv3706dOH4cOHs74j1cCBA/nxqG9z+nGf5aTPHsq82bP45vn/yYlHfpJfXHs1AEtef42hA/tz+UXnc9JnD+Vb/28Y//jHmg37XPTW35lbu5LRd0zg4E/254ADD2bwCScx/YVa5tau3Oir32FHcPYFF9PnkE/y0b0/xq33TWJu7UoWL17MkUceSd++fenbty9PPvkkAI899hif+cxnGDp0KHvvvTcjR47kjjvuoH///hx44IG89NJLACxbtowvfvGL9OvXj379+vHEE0/kedo34oJjZtuEhx56iD333JM5c+Ywb948hgwZAsCIESOYMWMG8+bN4x//+AcPPPDAhnXatd+OcZOmccqZZ/ONc8/g21f/mPseeZL77xnHyrdXALD4pUWceta5/G7a03x4x524e+zGf6Hx9orl/OqGn/B/437LXX94nN4HHcJtv7qxaI7vrXuPOx+YyqWjvs/on2aD6e+xxx5MmTKFWbNmcdddd/H1r399Q/s5c+YwevRoFixYwO23386LL77IM888w3nnncfPf/5zAC6++GK++c1vMmPGDO677z7OO++80p3URvItNTPbJhx44IF861vf4rLLLuOEE07gyCOPBGDatGlce+21rFmzhhUrVvDxj3+cE088EYCBRx8LwMf2780+++1PVeePANBtr4/y5l+XsNPOu/CRPbvyiX4DADj+C6cybsz/MeyrF23Y79xZM3h50Qt85T+yAvfvf/+bg/r2o5hBx54AQO8DD+Gvr7+2of2IESOYPXs2bdu25cUXX9zQvl+/fnTp0gWAffbZh8GDB2841mnTpgHwyCOPMH/+/A3rvPPOO6xevZodd9xxq8/l1nLBMbNtwr777susWbOYNGkS3/nOdxg0aBCXXnopF1xwATNnzqR79+6MGjVqo1EK2rffHoA2bdqwXfsPXrnVpk0b3luXPaPZpBtxnfmIYMCRA/nRL7f8t+kb9te2Le+9l23/+uuvp3PnzsyZM4f333+fDh06bGi//fbbb5TT+vk2bdqwLuX3/vvvM3369I3WqxTfUjOzbcJf//pXdthhB84880wuueQSZs2ataG4dOrUidWrV3Pvvfc2ertvLKllzrPPAPCH39274WpnvYP69mP2zKd5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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "hist.plot1d(histo.sum(\"x\", \"y\"), overlay='sample', stack=True);" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "hist.plot2d(histo.sum('x', 'sample'), xaxis='y');" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAuUAAAHwCAYAAAAByRFLAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAABrBElEQVR4nO3deZwU5bX/8c9hjwoiQpBNEQUdGBBxAAkYSYioASUhuGOMGskVvTcxcb2Xn0Gjueq910QT4xIXMBFFiUaiREXFxAWUgaDAgIoKsrmBggOiouf3Rz0z9gzdM90z013dM9/369Wv6a56qup0TfWp008tbe6OiIiIiIjEp1ncAYiIiIiINHUqykVEREREYqaiXEREREQkZirKRURERERipqJcRERERCRmKspFRERERGLWpItyM3vGzH6cYty+ZlZuZs1jiGu1mX0n18utFoOb2YFxxpDIzKaa2efhf7J7Dpb3kpn1y+L8p5rZn2sYv9zMRmZr+TUsd5qZXZXr5ebL8qszs57hs1BuZpNysLzjzGxmtpdTSJSna4xBeVp5OufiXn51uc7TacTzFzM7ti7TNumivCbu/ra77+HuX8QdS2NjZs3MbHJIqO+Z2QcJj/9Xw6Qzw/9kW5iPmdm1ZrYpPK41M0szhpPN7FUz2xJimG5m7RKa/C9wZT3eZr24ez93fyau5TdWZjbEzB40s7XVtrvltUza3t1vC/NI3AFUPGrabqvH8G0zW2xmW83szcSdiLv/DehnZgPq9g6bFuXp7FGerp3ydHY0RJ4O8znRzFaY2cdmVmZm38sghvPNrNTMPjWzaUnGjzKzlWa23czmmdl+CaOvBer0paXRFuVm1iLuGGRXIRk/AIwGzgb2cfeOCY9fZTC7ScD3gEOAAcBxwE/SnPZ5YLi77wn0AlpQ9UM0G/iWme2TQTyV4ui5k5qZ2Q+A+4A/A32qbXd16W1rH4qPPdLdbs2sJfAQcCuwJ3AScL2ZHZLQ7F6ibbvRU57OT8rTEpeGytNm1i3M4+dAO+AiYIaZfT3NWWwg2tbuTDLvjsCDwP8DOgClQOURTnd/CWhnZiXpxluhURXlFh1OvMTMXgG2mVkLMzvczF4ws4/M7GXb9VDTAaEnYKuZPWxmHcK8KnrDWoTXz5jZr8zs+fCt64nwj0lse4aZvR2+0f1XQlzNzOxSM3sj9BTcX7GcMP50M1sTxv0XKZjZYDN7NzGRmNl4M3s5SduhZvZOtbbfD+um4pvo/LBeNprZ782sVYrlVjl8bGY/MrPnEl4fbGZzzWxz6NU4MdV7AE4Hvubu33P3pe7+ZQ1ta3MG8H/uvs7d1wP/B/wonQndfa27f5Aw6AvgwITxO4BFwNHpzM+iw3k3m9kcM9tGtKPoatFhrPfN7C0z+49qk7Uxs5lhe1qcWJhZwqFxiw6h3m9md4e2yxM/7KHthWb2ikU9SjPNrE3C+LFmtiT8r1+whF5YMzs0LPtji06bqJwuyXt82ar2DnuSzxMW9UyMTXjdIqyDQeH1A2Hb3GJm/7QUh5+rb2dhWOXhejNrbWb/Gz5z75rZLWb2tRTzagfcABzl7g+6+yep3meWdSDaQfzJIwuBFUDfhDbPAGNiiC0nTHk6sa3ydA2UpyvHHWrK05nqDnzk7n8PufZRYBtwQDoTh+X/FdiUZPR4YLm7PxC2wanAIWZ2cEKbZ6hDHm9URXlwCtGKaA90Bh4l+rbTAbgQ+IuZdUpo/0PgLKALsBO4sYZ5nwqcCXwdaBXml2gEcBAwCrjczIrC8H8n6ik4EugKfAjcBGBmfYGbiZJgV2Bvoo1pF2EHvomo96LC6cDdSdq+SLQBfrta/DPC8y+AC4COwLAQ8+TUbz05i84bnBvm+3XgZOAP4X0lMxH4dabLSaEfkLijezkMS4uZjTCzLcDHwA+A31ZrsoKodyddpwJXA22BF4C/hZi6Ea3fn5lZ4s5jHFFvVAei9fdXi3pSkzmeqPegPVHv0O+rjT8ROAbYn6g36kfhPR5K9E3/J0Tb1q3A7JAoWwF/Bf4UYniAaD0k5e6HVPQME/U+vAosTtL0XqLPYYWjgQ/cvaLt34HeRNvLYuCeVMusxTVAH2Ag0Y66G3B5irZjgcfc/Y06LiuZNWa2zszuslD41cbd3yVaP2eaWXMzGwbsByTu1FYAPa3qYfrGRnka5el0KE8rT9dRKbDCzI4PufZ7wKfAKw0w7yrbdDhV6w2qbteZbpeVM2s0D2A1cFbC60uIeqQS2zwOnBGePwNckzCuL/AZ0BzoCTjQIqHtlIS2k4k2HhLadk8Y/xJwcni+AhiVMK4L8DnRobjLgfsSxu0eYvhOivd4CXBPeN4B2A50SdH2KuDO8LwtUfLfL0XbnwEPJbx24MCE9/7jhHE/Ap4Lz08Cnq02r1uBX6ZYzkpgC/BRikeq6aYCf6427Avg4ITXvUPcluF20y3Mv0+14VdXrL805jENuDvh9VDg7WptLgPuSng/CxLGNQM2AkckbMvfSWj7ZLXt9JNq2/3EhNfXAbeE5zcDv6oWx6tEhcc3iQ7RWcK4F4CranmvI4D3qq+vhPEHEu1Adwuv7wEuT9G2ffif7ZmwHq+qvp1V3y4BI/R6JIwbBryVYjmXAp/UsN29mmK6niTkgTBsD6CE6PPbGZgFPJ7B9nYc8C5RcbkTOKfa+JZhmftmsh0XygPl6eptlafT226Up78apzxddbqeVMvTYfjZQDlRnt0OjMlkm/OvPp/Tqg27g4ScFIY9D/wo4fU5wNOZLq8xns+3NuH5fsAJZnZcwrCWwLwU7deE8al6vd5JeL6daOeczvj9gIfMLPEQ4BdEO/SuiTG4+zYzS3a4pMKfib797U70rftZd9+You0M4AUzO5focMtid18DYGZ9gOuJiovdiHY8i2pYbir7AUPN7KOEYS2IvtUnsx6Y5O7/rMOyqisnOhWgQjug3MMnIl3uvt7MHiPq4RiUMKotUSJIV/Vtr2u19dIceDZZe3f/0szWEW0PyVTfttqYWQt335lifMV89gPOMLN/TxjfKox3YH219bUmxfIBMLMewP1EBdNrydq4+yozWwEcZ2Z/I+o9OjRM35xoJ3oC0Amo+Ex0JCoC0tWJaLtdZF9dM2ZE6ziZ9cC97n5WBstIyt3LiXphAN41s/OBjWbW1t0/rmnacHjzPqLP41yiAuURM9vg0eFViLY7yGzbKzTK019Rnk6D8rTydCbCaUXXASOJevoPIzr6cKy7L6nn7Ktv04TXifk/0+0SaJynryRuuGuJemDaJzx2d/drEtr0SHi+L1HPSOI5bA1hLXBstTjaeHR+3cbEGMxsN6LDV0mFaeYTJe/TSZ1Ucfcyog/vsVQ9JArRN/OVQG93bwf8J9GHJZltRB+sCokX1awF/lHtve3h7uemmNd9RN+GG8Jyqh4eOiQMq4sW7HquWRFVD7vWpvq291a19dLW3b+b0Cbx/96M6HD4hgzjrs1a4Opqcezm7vcSbXvdzKrcCWHfVDMK5wH+Ffitu/+9luVWHBodB5S5+6ow/NQw7DtEFzr2rJh9knlU2e6s6sVcHxD1qPRLeF97enTINplHgDFm1quWuOui4v+eTj4tBl5z98fd/Ut3f5Xo1I3E22cVAavdfWsDx5lPlKe/aqs8nT7l6YjydO0GAv9099KQaxcCLxK9p/qqsk2HL98HUHW7znS7BBpnUZ7oz0TfAo8O5xS1MbORZpZ4LuBEM+sbkuyVwCxv+Ntr3QJcbeGWOWbWyczGhXGzgLHhvLlWIYba/i93AxcD/YmuAK7JDOCnRIfAHkgY3hbYCpSH3rtUyRlgCTDezHYLF2+cnTDuEaCPRRdBtQyPwQnnaVZ3B9DCzO41s/1rib02dwM/N7NuZtYV+AXRYTWg8sKaHyWb0MxOM7N9w/P9iHoFnkoY34bom/XchGFJL5hJ4SXgY4suaPta2P6KzWxwQpvDLLoArAXRYelPgQVpzj9dfwT+zaILyszMdjezMWbWlqho2An8R/i/jQeG1DCvO4GV7n5dGsu9j+ic2nOpWmS0JXqfm4gSeU3nrb5MdHvAgeH/MbVihEcXnv0R+I2Fq+nDdpD0gi93/5DoM/OEmY22etx1IazLgyy6MHBvovObn3H3LWH8VDN7JsXk/wJ6W3RbRDOzA4jOo0w8z/FIovM5mwrlaeXpHyWbUHlaeTqN95DKQuAIMxsYlnsocAQh14Yck/JojUUXvrYh6tWvyEsVZ5c8BBSb2Q9Cm8uBV9x9ZcIs6pTHG3VR7u5rib7t/SfwPtG30Yuo+r7/RJQg3iG6orn6ldcN4Qaiiz6eMLOPiT7QQ0OMy4HziD4QG4kuLlpXy/weIhxqdffttbS9l2jjeNqrXsV+IdG34Y+JPjQ1/WDJb4jOn3wXmE7CBR/hcP1ooguHNhCtx2uB1slmFD6kY4ClROvjo2qPX9byfhLdSnSRzlJgGVGP460AYce5N6mTZ1+iQ8bbiM4Fe5XoHLAKxxEVWhvC/HoQraul6QQWCoaxRN/W3yLqMbidqNehwsNE53p+SNSbNt7dP09n/uly91Ki9/X7sJxVhIuL3P0zop68HwGbQyw1FQ8nA9+3qlf2H5FiuRuJdibfoOq2dTdRr+B6oIwadm7hsOuVwJPA61S9GBKi83ZXAQvMbGtod1AN85tOdCHVZcD71ba7V2t439X1Ah4j2h6WEe28Ei+Y6kG0TSWL4Q2iCxZvJCq2/gH8hWjbqHAKYTtuCpSnAeVp5Wnl6Yr5NUiedvd/EH1BmBU+z38Bfu3uT4QmPYjOzU9lClEv/6VEFz5/Eobh7u8TXWx7NdH/ayjRegeiOzARnaL1UrrxVk7rmZ3WJXnCzN4AfuLuT8YdSy6Y2RSiD+nnQDcPP0xRQ/sRwHnufkpN7WqY/kXgbHdfFl5PJDoEd1ld5ieFKfTOvQrsAC5y9z+mMc0SogsGazrnONW0xwGnu3tNt6uTAqE8rTwt2VfHPH078IC7P56FeP4C3OHuczKeVkV54bHo5vrXEl1VXZ/7x4qISBYoT4tIphrj3VcaNYvOVe1L1JumRC8ikmeUp0WkLtRTLiIiIiISs0Z9oaeIiIiISCFQUS4iIiIiErNGeU55x44dvWfPnnGHISJSJ4sWLfrA3TvFHUcuKW+LSKFqqJzdKIvynj17UlpaWntDEZE8ZGY1/ox2Y6S8LSKFqqFytk5fERERERGJmYpyEREREZGYqSgXEREREYlZozynXESy7/PPP2fdunXs2LEj7lAKVps2bejevTstW7aMOxQRaeSUs+sv2zlbRbmI1Mm6deto27YtPXv2xMziDqfguDubNm1i3bp17L///nGHIyKNnHJ2/eQiZ+v0FRGpkx07drD33nsrudeRmbH33nur10pEckI5u35ykbNVlItInSm514/Wn4jkknJO/WR7/akoF2lAJ906n5NunR93GE3OyJEjdY9rEZECoZydnIpyEREREZGYqSgXyRONqZd927ZtjBkzhkMOOYTi4mJmzpwJwJVXXsngwYMpLi5m0qRJuDsQ9ZpccMEFlJSUUFRUxMKFCxk/fjy9e/dmypQpAKxevZqDDz6Y0047jaKiIiZMmMD27dt3WfYTTzzBsGHDGDRoECeccALl5eW7tBk5ciSXXHIJQ4YMoU+fPjz77LOVyzjiiCMYNGgQgwYN4oUXXgDgmWee4cgjj2TcuHH06tWLSy+9lHvuuYchQ4bQv39/3njjDQDef/99fvCDHzB48GAGDx7M888/3/ArV0SkgSln50nOdvdG9zjssMNcJA4n3vKCn3jLCzmfNg5lZWUpx82aNct//OMfV77+6KOP3N1906ZNlcMmTpzos2fPdnf3I4880i+++GJ3d//tb3/rXbp08Q0bNviOHTu8W7du/sEHH/hbb73lgD/33HPu7n7mmWf6//zP/1ROv3DhQn///ff9iCOO8PLycnd3v+aaa/yKK67YJb4jjzzSf/7zn7u7+6OPPuqjRo1yd/dt27b5J5984u7ur732mlfkknnz5vmee+5ZGVPXrl398ssvr4z3pz/9qbu7n3LKKf7ss8+6u/uaNWv84IMPrtN6BEo9D3JpLh/K2yLZpZyd/zlbt0QUydCMF9/m4SXrk44r27gVoMYe73EDu3Hq0H2zElu+6N+/P7/4xS+45JJLGDt2LEcccQQA8+bN47rrrmP79u1s3ryZfv36cdxxxwFw/PHHV07br18/unTpAkCvXr1Yu3Yt7du3p0ePHgwfPhyAiRMncuONN3LhhRdWLnfBggWUlZVVtvnss88YNmxY0hjHjx8PwGGHHcbq1auB6D6+559/PkuWLKF58+a89tprle0HDx5cGdMBBxzA6NGjK+OdN28eAE8++SRlZWWV02zdupXy8nL22GOPuq5KEZGsU86OxJ2zVZSLZOjhJesp27iVvl3aZTxtRdHe2IvyPn36sHjxYubMmcOUKVMYNWoUF198MZMnT6a0tJQePXowderUKreWat26NQDNmjWrfF7xeufOncCuV75Xf+3uHHXUUdx77721xlixjObNm1fO/ze/+Q2dO3fm5Zdf5ssvv6RNmza7tK8eY2J8X375JQsWLKgynYhIvlPOzo+craJcpA76dmnHzJ/s+m2+ooc82biK8WUbtybtSW9MvewbNmygQ4cOTJw4kfbt23P77bdXJvOOHTtSXl7OrFmzmDBhQkbzffvtt5k/fz7Dhg1jxowZjBgxosr4ww8/nPPOO49Vq1Zx4IEHsm3bNtavX0+fPn3Smv+WLVvo3r07zZo1Y/r06XzxxRcZxTd69Gh+97vfcdFFFwGwZMkSBg4cmNE8RERyTTk7P3J2Vi/0NLPVZrbUzJaYWWkY1sHM5prZ6+HvXmG4mdmNZrbKzF4xs0EJ8zkjtH/dzM7IZswi2TRuYLc69bBDVLSnOm0m3yxdupQhQ4YwcOBArrjiCqZMmUL79u0555xzKC4u5uijj2bw4MEZz/eggw7ipptuoqioiA8//JBzzz23yvhOnToxbdo0TjnlFAYMGMCwYcNYuXJl2vOfPHky06dP55BDDmHlypXsvvvuGcV34403UlpayoABA+jbty+33HJLRtOLiMRBOTs/crZF56dnaeZmq4ESd/8gYdh1wGZ3v8bMLgX2cvdLzOy7wL8D3wWGAje4+1Az6wCUAiWAA4uAw9z9w1TLLSkpcd3/UrKlpt7w2nrK6zrf+s47G1asWEFRUVHOlrd69WrGjh3LsmXLcrbMXEi2Hs1skbuXxBRSLJS3RbJLObthZDNnx3FLxHHA9PB8OvC9hOF3hwtZFwDtzawLcDQw1903h0J8LnBMjmMWEREREcmabJ9T7sATZubAre5+G9DZ3TeG8e8AncPzbsDahGnXhWGphovknXzpxW6Mevbs2eh6XEREGivl7Mxluygf4e7rzezrwFwzq3KikLt7KNjrzcwmAZMA9t03/y+EExFp6pS3RUS+ktXTV9x9ffj7HvAQMAR4N5yWQvj7Xmi+HuiRMHn3MCzV8OrLus3dS9y9pFOnTg39VkSybuZPhqmnXZoU5W0Rka9krSg3s93NrG3Fc2A0sAyYDVTcQeUM4OHwfDbww3AXlsOBLeE0l8eB0Wa2V7hTy+gwTERERESkUcjm6SudgYfCjeJbADPc/TEzWwjcb2ZnA2uAE0P7OUR3XlkFbAfOBHD3zWb2K2BhaHelu2/OYtwikiX5dgcZERFJTTk7t7LWU+7ub7r7IeHRz92vDsM3ufsod+/t7t+pKLDDXVfOc/cD3L2/u5cmzOtOdz8wPO7KVswiIqmMHDmSTG7Z98ADD9CvXz+aNWuW0XQiIlJ/hZiz47gloohIo1dcXMyDDz7IN7/5zbhDERGRWuRDzlZRLiIFadu2bYwZM4ZDDjmE4uJiZs6cCcCVV17J4MGDKS4uZtKkSVT8QNrIkSO54IILKCkpoaioiIULFzJ+/Hh69+7NlClTgOjHLg4++GBOO+00ioqKmDBhAtu3b99l2U888QTDhg1j0KBBnHDCCZSXl+/SpqioiIMOOiiLa0BEpHAoZ9cu27dEFJEm4Iq/Ladsw9ZdhpdtrDps+6c7Aeg/teq12n27tNtl2r5d2/HL4/qlXOZjjz1G165defTRRwHYsmULAOeffz6XX345AKeffjqPPPIIxx13HACtWrWitLSUG264gXHjxrFo0SI6dOjAAQccwAUXXADAq6++yh133MHw4cM566yz+MMf/sCFF15YudwPPviAq666iieffJLdd9+da6+9luuvv75ymSIi+U45Oz9ztnrKRaQg9e/fn7lz53LJJZfw7LPPsueeewIwb948hg4dSv/+/Xn66adZvnx55TTHH3985bT9+vWjS5cutG7dml69erF2bfQbZT169GD48OEATJw4keeee67KchcsWEBZWRnDhw9n4MCBTJ8+nTVr1uTiLYuIFCzl7Nqpp1xE6q2m3pFEDXklf58+fVi8eDFz5sxhypQpjBo1iosvvpjJkydTWlpKjx49mDp1Kjt27KicpnXr1gA0a9as8nnF6507ox6hcMeoStVfuztHHXUU9957b73fg4hIHJSz85N6ykWkIG3YsIHddtuNiRMnctFFF7F48eLKZN6xY0fKy8uZNWtWxvN9++23mT8/2hHNmDGDESNGVBl/+OGH8/zzz7Nq1SogOk/ytddeq+e7ERFp3JSza6eiXEQK0tKlSxkyZAgDBw7kiiuuYMqUKbRv355zzjmH4uJijj76aAYPHpzxfA866CBuuukmioqK+PDDDzn33HOrjO/UqRPTpk3jlFNOYcCAAQwbNoyVK1fuMp+HHnqI7t27M3/+fMaMGcPRRx9d5/cqIlLolLNrZxVXuTYmJSUlrvsCS7bE9WMK+fYjDitWrKCoqCijafLtPVS3evVqxo4dy7Jly3K2zGTr0cwWuXtJzoLIA8rbItmlnN0wspmzdU65iORMviZ2ERHZlXJ2bun0FRGRoGfPnjntcRERkbprbDlbRbmIiIiISMxUlIuIiIiIxExFuYiIiIhIzFSUi0ju3DUmeoiISP5Tzs4pFeUiImkYOXIkmdyy76KLLuLggw9mwIABfP/73+ejjz7KXnAiIlJFIeZsFeUiIllw1FFHsWzZMl555RX69OnDf//3f8cdkoiIpJAPOVtFuYgUpG3btjFmzBgOOeQQiouLmTlzJgBXXnklgwcPpri4mEmTJlHxA2kjR47kggsuoKSkhKKiIhYuXMj48ePp3bs3U6ZMAaIfojj44IM57bTTKCoqYsKECWzfvn2XZT/xxBMMGzaMQYMGccIJJ1BeXr5Lm9GjR9OiRfRTEIcffjjr1q3L1qoQEcl7ytm1048HiUj9/f1SeGfprsPfeaXq68+2RX//u0fV4fsM2HXaffrDsdekXORjjz1G165defTRRwHYsmULAOeffz6XX345AKeffjqPPPIIxx13HACtWrWitLSUG264gXHjxrFo0SI6dOjAAQccwAUXXADAq6++yh133MHw4cM566yz+MMf/sCFF15YudwPPviAq666iieffJLdd9+da6+9luuvv75ymcnceeednHTSSSnHi4jklHJ2XuZs9ZSLSEHq378/c+fO5ZJLLuHZZ59lzz33BGDevHkMHTqU/v378/TTT7N8+fLKaY4//vjKafv160eXLl1o3bo1vXr1Yu3atQD06NGD4cOHAzBx4kSee+65KstdsGABZWVlDB8+nIEDBzJ9+nTWrFmTMs6rr76aFi1acNpppzXo+xcRKSTK2bVTT7mI1F8NvSNVVFzFf+aj9V5knz59WLx4MXPmzGHKlCmMGjWKiy++mMmTJ1NaWkqPHj2YOnUqO3bsqJymdevWADRr1qzyecXrnTt3AmBmVZZT/bW7c9RRR3HvvffWGuO0adN45JFHeOqpp3aZj4hIbJSzk4o7Z6unXEQK0oYNG9htt92YOHEiF110EYsXL65M5h07dqS8vJxZs2ZlPN+3336b+fPnAzBjxgxGjBhRZfzhhx/O888/z6pVq4DoPMnXXnttl/k89thjXHfddcyePZvddtst4zhERBoT5ezaqadcRArS0qVLueiii2jWrBktW7bk5ptvpn379pxzzjkUFxezzz77MHjw4Izne9BBB3HTTTdx1lln0bdvX84999wq4zt16sS0adM45ZRT+PTTTwG46qqr6NOnT5V2559/Pp9++ilHHXUUEO0Ybrnlljq+WxGRwqacXTuruMq1MSkpKfFM7k0pkomTbo2+kc/8ybAmsdxUVqxYQVFRUWYTNeCh0GxYvXo1Y8eOZdmyZTlbZrL1aGaL3L0kZ0HkAeVtkexSzm4Y2czZ6ikXkdzJ08QuIiJJKGfnlM4pFxEJevbsmdMeFxERqbvGlrNVlIuIiIiIxExFuYjUWWO8JiWXtP5EJJeUc+on2+sv60W5mTU3s3+Z2SPh9f5m9qKZrTKzmWbWKgxvHV6vCuN7JszjsjD8VTM7Otsxi0jt2rRpw6ZNm5Tk68jd2bRpE23atIk7FBFpApSz6ycXOTsXF3r+FFgBtAuvrwV+4+73mdktwNnAzeHvh+5+oJmdHNqdZGZ9gZOBfkBX4Ekz6+PuX+QgdhFJoXv37qxbt473338/7lAKVps2bejevXvcYYhIE6CcXX/ZztlZLcrNrDswBrga+LlFP4/0beDU0GQ6MJWoKB8XngPMAn4f2o8D7nP3T4G3zGwVMASYn83YRaRmLVu2ZP/99487DBERSYNydv7L9ukrvwUuBr4Mr/cGPnL3neH1OqBbeN4NWAsQxm8J7SuHJ5mmkplNMrNSMyvVt0ARkfynvC0i8pWsFeVmNhZ4z90XZWsZidz9NncvcfeSTp065WKRIiJSD8rbIiJfyebpK8OB483su0AbonPKbwDam1mL0BveHVgf2q8HegDrzKwFsCewKWF4hcRpREREREQKXtZ6yt39Mnfv7u49iS7UfNrdTwPmARNCszOAh8Pz2eE1YfzTHl0iPBs4OdydZX+gN/BStuIWEREREcm1XNx9pbpLgPvM7CrgX8AdYfgdwJ/ChZybiQp53H25md0PlAE7gfN05xURERERaUxyUpS7+zPAM+H5m0R3T6neZgdwQorprya6g4uIiIiISKOjX/QUEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmGVclJvZXmY2IBvBiIhI46J9hohIetIqys3sGTNrZ2YdgMXAH83s+uyGJiIihUj7DBGRzKXbU76nu28FxgN3u/tQ4DvZC0tERAqY9hkiIhlKtyhvYWZdgBOBR7IYj4iIFD7tM0REMpRuUX4F8Diwyt0Xmlkv4PWaJjCzNmb2kpm9bGbLzeyKMHx/M3vRzFaZ2UwzaxWGtw6vV4XxPRPmdVkY/qqZHV2ndyoiIrmS8T5DRKSpa5Fmu43uXnmhjru/mcb5gZ8C33b3cjNrCTxnZn8Hfg78xt3vM7NbgLOBm8PfD939QDM7GbgWOMnM+gInA/2ArsCTZtbH3b/I5I2KiEjO1GWfISLSpKXbU/67NIdV8kh5eNkyPBz4NjArDJ8OfC88HxdeE8aPMjMLw+9z90/d/S1gFTAkzbhFRCT3Mt5niIg0dTX2lJvZMOAbQCcz+3nCqHZA89pmbmbNgUXAgcBNwBvAR+6+MzRZB3QLz7sBawHcfaeZbQH2DsMXJMw2cRoREckT9d1niIg0ZbX1lLcC9iAq3tsmPLYCE2qbubt/4e4Dge5EvdsH1yfYmpjZJDMrNbPS999/P1uLERGR1DLaZyhvi4h8pcaecnf/B/APM5vm7mvquhB3/8jM5gHDgPZm1iL0lncH1odm64EewDozawHsCWxKGF4hcZrEZdwG3AZQUlLidY1VRETqJtN9hvK2iMhX0r3Qs7WZ3Qb0TJzG3b+dagIz6wR8HgryrwFHEV28OY+ox+Q+4Azg4TDJ7PB6fhj/tLu7mc0GZoSLhLoCvYGX0n6HIiKSaxnvM0REmrp0i/IHgFuA24F073rSBZgezitvBtzv7o+YWRlwn5ldBfwLuCO0vwP4k5mtAjYT3XEFd19uZvcDZcBO4DzdeUVEJK/VZZ8hItKkpVuU73T3mzOZsbu/AhyaZPibJLl7irvvAE5IMa+rgaszWb6IiMQm432GiEhTl+4tEf9mZpPNrIuZdah4ZDUyEREpVNpniIhkKN2e8jPC34sShjnQq2HDERGRRkD7DBGRDKVVlLv7/tkOREREGgftM0REMpdWUW5mP0w23N3vbthwRESk0GmfISKSuXRPXxmc8LwNMApYDCjBiohIddpniIhkKN3TV/498bWZtSe6z7iIiEgV2meIiGQu3buvVLcN0DmDIiKSDu0zRERqke455X8junIeoDlQBNyfraBERKRwaZ8hIpK5dM8p/9+E5zuBNe6+LgvxiIhI4dM+Q0QkQ2mdvuLu/wBWAm2BvYDPshmUiIgULu0zREQyl1ZRbmYnAi8BJwAnAi+a2YRsBiYiIoVJ+wwRkcyle/rKfwGD3f09ADPrBDwJzMpWYCIiUrC0zxARyVC6d19pVpFcg00ZTCsiIk2L9hkiIhlKt6f8MTN7HLg3vD4JmJOdkEREpMBpnyEikqEai3IzOxDo7O4Xmdl4YEQYNR+4J9vBiYhI4dA+Q0Sk7mrrKf8tcBmAuz8IPAhgZv3DuOOyGJuIiBSW36J9hohIndR2jl9nd19afWAY1jMrEYmISKHSPkNEpI5qK8rb1zDuaw0Yh4iIFL72NYzTPkNEpAa1FeWlZnZO9YFm9mNgUXZCEhGRAqV9hohIHdV2TvnPgIfM7DS+SqglQCvg+1mMS0RECs/P0D5DRKROaizK3f1d4Btm9i2gOAx+1N2fznpkIiJSULTPEBGpu7TuU+7u84B5WY5FREQaAe0zREQyp19YExERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiVnWinIz62Fm88yszMyWm9lPw/AOZjbXzF4Pf/cKw83MbjSzVWb2ipkNSpjXGaH962Z2RrZiFhERERGJQzZ7yncCv3D3vsDhwHlm1he4FHjK3XsDT4XXAMcCvcNjEnAzREU88EtgKDAE+GVFIS8iXznp1vmcdOv8uMMQERGROshaUe7uG919cXj+MbAC6AaMA6aHZtOB74Xn44C7PbIAaG9mXYCjgbnuvtndPwTmAsdkK24RFbciIiKSa2n9eFB9mVlP4FDgRaCzu28Mo94BOofn3YC1CZOtC8NSDa++jElEPezsu+++DRi9SP4o27g15ReGso1bAVKOHzewG6cO1WdD8ofytojIV7J+oaeZ7QH8BfiZu29NHOfuDnhDLMfdb3P3Encv6dSpU0PMUiSvjBvYjb5d2tVp2rKNW3l4yfoGjkikfpS3RUS+ktWecjNrSVSQ3+PuD4bB75pZF3ffGE5PeS8MXw/0SJi8exi2HhhZbfgz2YxbGrcZL75dY4FaW49z2catdS6O6+PUofvW2NNdEe/MnwxLOU5ERETyUzbvvmLAHcAKd78+YdRsoOIOKmcADycM/2G4C8vhwJZwmsvjwGgz2ytc4Dk6DBOpk4eXrK8svOuib5d2jBu4yxlUIiIiInWWzZ7y4cDpwFIzWxKG/SdwDXC/mZ0NrAFODOPmAN8FVgHbgTMB3H2zmf0KWBjaXenum7MYtzQBfbu0S9qjDDX3OOezQotXREREvpK1otzdnwMsxehRSdo7cF6Ked0J3Nlw0YmIiIiI5I+c3H1FpJCox1lERERyLet3XxERERERkZqpKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEREREZGYqSgXEREREYmZinIRERERkZi1iDsAkYJTehcsnZV83DuvRH/3GZB6+v4ToOTMho9LRERECpZ6ykUytXQWvLO0btO+szR1QS8iIiJNlnrKRepin/5w5qO7Dr9rTPQ32biK8e8s/apdIvWyi4iINFkqykUaUqpivEL/CXWfd0XvvIpyERGRRkdFuUgulZxZ96I6We+6iIiINAo6p1xEREREJGZZK8rN7E4ze8/MliUM62Bmc83s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yuV+8MEHXHXVVTz55JPsvvvuXHvttVx//fWVyxQRkV0pZ9dORblIhupTWL/4VnSN8tD9O2S83Ip552NRfsXfllO2YesuwytirrD9050A9J9a9QZKfbu022Xavl3b8cvj+qVcZv/+/fnFL37BJZdcwtixYzniiCMAmDdvHtdddx3bt29n8+bN9OvXrzLBH3/88ZXT9uvXjy5dugDQq1cv1q5dS/v27enRowfDhw8HYOLEidx4441VEvyCBQsoKyurbPPZZ58xbJguzhWRwqGcnZ85W0W5SIYeXrKeso1bkyal2gzdv0PK3u7a7r5SqBfbZEufPn1YvHgxc+bMYcqUKYwaNYqLL76YyZMnU1paSo8ePZg6dSo7duyonKZ169YANGvWrPJ5xeudO6OdT7hjVKXqr92do446invvvTdbb01EpNFRzq6dinKROujbpV3S4rmp3tawpt6RRA25fjZs2ECHDh2YOHEi7du35/bbb69M5h07dqS8vJxZs2YxYcKEjOb79ttvM3/+fIYNG8aMGTMYMWJElfGHH3445513HqtWreLAAw9k27ZtrF+/nj59+tT7PYmI5IJydn7mbF3oKSIFaenSpQwZMoSBAwdyxRVXMGXKFNq3b88555xDcXExRx99NIMHD854vgcddBA33XQTRUVFfPjhh5x77rlVxnfq1Ilp06ZxyimnMGDAAIYNG8bKlSt3mc9DDz1E9+7dmT9/PmPGjOHoo4+u83sVESl0ytm1s4qrXBuTkpIS132BJVtq6jnIZk95vvXCr1ixgqKiooymybf3UN3q1asZO3Ysy5Yty9kyk61HM1vk7iU5CyIPKG+LZJdydsPIZs5WT7mIiIiISMx0TrlIA8rX3oR8ke/rp2fPnjntcRERyWfK2bmlnnIRERERkZipKBcRERERiZmKchERERGRmKkoFxERERGJmYpyEcmdu8ZEjwI0cuRIMrll30UXXcTBBx/MgAED+P73v89HH32UveBERLJBOTunVJSLiGTBUUcdxbJly3jllVfo06cP//3f/x13SCIikkI+5GwV5SJSkLZt28aYMWM45JBDKC4uZubMmQBceeWVDB48mOLiYiZNmkTFD6SNHDmSCy64gJKSEoqKili4cCHjx4+nd+/eTJkyBYh+iOLggw/mtNNOo6ioiAkTJrB9+/Zdlv3EE08wbNgwBg0axAkn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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# make coarse binned hist and look at several distributions\n", + "hnew = (\n", + " histo\n", + " .rebin(\"y\", hist.Bin(\"ynew\", \"rebinned y value\", [0, 3, 5]))\n", + " .rebin(\"z\", hist.Bin(\"znew\", \"rebinned z value\", [5, 8, 10]))\n", + ")\n", + "\n", + "hist.plotgrid(hnew, row='ynew', col='znew', overlay='sample');" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/Users/lagray/coffea/coffea/binder/coffea/hist/plot.py:357: RuntimeWarning: invalid value encountered in true_divide\n", + " rsumw = sumw_num / sumw_denom\n" + ] + }, + { + "data": { + "text/plain": [ + "(-10.0, 10.0)" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "numerator = histo.integrate('sample', 'sample 1').sum('y', 'z')\n", + "denominator = histo.sum('sample', 'y', 'z')\n", + "\n", + "numerator.label = r'$\\epsilon$'\n", + "ax = hist.plotratio(\n", + " num=numerator,\n", + " denom=denominator,\n", + " error_opts={'color': 'k', 'marker': '.'},\n", + " unc='clopper-pearson'\n", + ")\n", + "ax.set_ylim(0.6, 1.)\n", + "ax.set_xlim(-10, 10)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Styling\n", + "\n", + "We've covered the basics of plotting, now let's go over some styling options. To make things more interesting, we'll load some electron and muon Lorentz vectors from simulated $H\\rightarrow ZZ^{*}$ events into awkward arrays and then plot some kinematic quantities for them, making liberal use of the matplotlib styling options which are exposed through the coffea plotting utilities." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " % Total % Received % Xferd Average Speed Time Time Time Current\r\n", + " Dload Upload Total Spent Left Speed\r\n", + "\r", + " 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0\r", + "100 212k 100 212k 0 0 7601k 0 --:--:-- --:--:-- --:--:-- 7601k\r\n" + ] + } + ], + "source": [ + "!curl -OL http://scikit-hep.org/uproot3/examples/HZZ.root" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Avg. electrons/event: 0.07063197026022305\n", + "Avg. muons/event: 1.579925650557621\n" + ] + } + ], + "source": [ + "import uproot\n", + "import awkward as ak\n", + "from coffea.nanoevents.methods import vector\n", + "ak.behavior.update(vector.behavior)\n", + "\n", + "fin = uproot.open(\"HZZ.root\")\n", + "tree = fin[\"events\"]\n", + "\n", + "# let's build the lepton arrays back into objects\n", + "# in the future, some of this verbosity can be reduced\n", + "arrays = {k.replace('Electron_', ''): v for k, v in tree.arrays(filter_name=\"Electron_*\", how=dict).items()}\n", + "electrons = ak.zip({'x': arrays.pop('Px'), \n", + " 'y': arrays.pop('Py'), \n", + " 'z': arrays.pop(\"Pz\"),\n", + " 't': arrays.pop(\"E\"),\n", + " },\n", + " with_name=\"LorentzVector\"\n", + ")\n", + "\n", + "\n", + "arrays = {k.replace('Muon_', ''): v for k,v in tree.arrays(filter_name=\"Muon_*\", how=dict).items()}\n", + "muons = ak.zip({'x': arrays.pop('Px'), \n", + " 'y': arrays.pop('Py'), \n", + " 'z': arrays.pop(\"Pz\"),\n", + " 't': arrays.pop(\"E\"),\n", + " },\n", + " with_name=\"LorentzVector\"\n", + ")\n", + "\n", + "print(\"Avg. electrons/event:\", ak.sum(ak.num(electrons))/tree.num_entries)\n", + "print(\"Avg. muons/event:\", ak.sum(ak.num(muons))/tree.num_entries)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "lepton_kinematics = hist.Hist(\n", + " \"Events\",\n", + " hist.Cat(\"flavor\", \"Lepton flavor\"),\n", + " hist.Bin(\"pt\", \"$p_{T}$\", 19, 10, 100),\n", + " hist.Bin(\"eta\", \"$\\eta$\", [-2.5, -1.4, 0, 1.4, 2.5]),\n", + ")\n", + "\n", + "# Pass keyword arguments to fill, all arrays must be flat numpy arrays\n", + "# User is responsible for ensuring all arrays have same jagged structure!\n", + "lepton_kinematics.fill(\n", + " flavor=\"electron\",\n", + " pt=ak.flatten(electrons.pt),\n", + " eta=ak.flatten(electrons.eta)\n", + ")\n", + "lepton_kinematics.fill(\n", + " flavor=\"muon\",\n", + " pt=ak.flatten(muons.pt),\n", + " eta=ak.flatten(muons.eta)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Now we can start to manipulate this single histogram to plot different views of the data\n", + "# here we look at lepton pt for all eta\n", + "lepton_pt = lepton_kinematics.integrate(\"eta\")\n", + "\n", + "ax = hist.plot1d(\n", + " lepton_pt,\n", + " overlay=\"flavor\",\n", + " stack=True,\n", + " fill_opts={'alpha': .5, 'edgecolor': (0,0,0,0.3)}\n", + ")\n", + "# all plot calls return the matplotlib axes object, from which\n", + "# you can edit features afterwards using matplotlib object-oriented syntax\n", + "# e.g. maybe you really miss '90s graphics...\n", + "ax.get_legend().shadow = True" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZgAAAEICAYAAABiXeIWAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8vihELAAAACXBIWXMAAAsTAAALEwEAmpwYAAAnXklEQVR4nO3de3hU9b3v8feXEO6iAl5oIjvhCCoQQIiAVarIEbFeUIpCtRapFT3qc7rrUTfd55gix21r20e7az1V3IiWeqHgVlJLvYC6Fa1IUCQSRBFjDYUKwQaVO3zPH2slHUKSmZBZM5PJ5/U882TNWr+15juTgW9+12XujoiISLK1S3cAIiKSnZRgREQkEkowIiISCSUYERGJhBKMiIhEon26A0iFXr16eUFBQbrDEBFpVVauXLnV3Y853PPbRIIpKCigrKws3WGIiLQqZvZJS85XE5mIiERCCUZERCKhBCMiIpFoE30wItK27N27l6qqKnbt2pXuUFqFTp06kZ+fT25ublKvqwQjIlmnqqqKI444goKCAsws3eFkNHenurqaqqoqCgsLk3ptNZGJSNbZtWsXPXv2VHJJgJnRs2fPSGp7SjAikpWUXBIX1WelBCMiIpFQghGRNqNbt24tvsaqVatYvHhxEqIJLFiwgFNOOYUxY8bwyiuvcOGFFybt2ummBCONmvzgn5n84J/THYZIRkl2gpkzZw4PPfQQL7/8ctKu2Zh9+/ZF/hqxlGBEpE376KOPGD9+PMOHD2f06NG8//77AFx99dVcf/31FBcX079/f5599ln27NlDSUkJ8+fPZ+jQocyfP59t27ZxySWXMHjwYEaNGsXq1asBmDlzJt/73vc4++yz6du3L7/61a8Oee1Zs2axbNkyrrnmGm699daDjr311lucfvrpnHrqqXz9619n3bp1AIwaNYo1a9bUlTv77LMpKytrMo6rrrqKM844g6uuuiqSz7BR7p71j+HDh7s03+UPvOGXP/BGusMQabaKiooG93ft2vWQfeecc45/8MEH7u7+5ptv+pgxY9zdferUqX7eeef5/v37/YMPPvC8vDzfuXOnz50712+88ca682+66SafOXOmu7svXbrUhwwZ4u7uP/7xj/3000/3Xbt2+ZYtW7xHjx6+Z8+eQ17/rLPO8hUrVri7+8svv+wXXHCBu7vX1NT43r173d39xRdf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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Clearly the yields are much different, are the shapes similar? We can check by setting `density=True`\n", + "lepton_pt.label = \"Density\"\n", + "ax = hist.plot1d(lepton_pt, overlay=\"flavor\", density=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Let's stack them, after defining some nice styling\n", + "stack_fill_opts = {\n", + " 'alpha': 0.8,\n", + " 'edgecolor':(0,0,0,.5)\n", + "}\n", + "stack_error_opts = {\n", + " 'label':'Stat. Unc.',\n", + " 'hatch':'///',\n", + " 'facecolor':'none',\n", + " 'edgecolor':(0,0,0,.5),\n", + " 'linewidth': 0\n", + "}\n", + "# maybe we want to compare different eta regions\n", + "# plotgrid accepts row and column axes, and creates a grid of 1d plots as appropriate\n", + "ax = hist.plotgrid(\n", + " lepton_kinematics,\n", + " row=\"eta\",\n", + " overlay=\"flavor\",\n", + " stack=True,\n", + " fill_opts=stack_fill_opts,\n", + " error_opts=stack_error_opts,\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "# Here we create some pseudodata for the pt histogram so we can make a nice data/mc plot\n", + "pthist = lepton_kinematics.sum('eta')\n", + "bin_values = pthist.axis('pt').centers()\n", + "poisson_means = pthist.sum('flavor').values()[()]\n", + "values = np.repeat(bin_values, np.random.poisson(poisson_means))\n", + "pthist.fill(flavor='pseudodata', pt=values)\n", + "\n", + "# Set nicer labels, by accessing the string bins' label property\n", + "pthist.axis('flavor').index('electron').label = 'e Flavor'\n", + "pthist.axis('flavor').index('muon').label = r'$\\mu$ Flavor'\n", + "pthist.axis('flavor').index('pseudodata').label = r'Pseudodata from e/$\\mu$'\n", + "\n", + "# using regular expressions on flavor name to select just the data\n", + "# another method would be to fill a separate data histogram\n", + "import re\n", + "notdata = re.compile('(?!pseudodata)')" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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Q25uLqtXr/a3P/zww7Rv377KAB5jxozhjDPOAGDXrl1MnDiR9u3b06xZMwYNGsQ777zjf+wJJ5zA+PHjmTRpEu3ateOYY44J6echyUVhKiktmEO3wQatRFdhYSHdu3enZcuW/mUrV64kPT2d3r17R+Q5SkpKmDhxIsuWLeOtt94iKyuL4cOH+/cezznnHLZv387rr7/uX6e4uJiXX36Z888/H4Crr76a5557jscee4yVK1fSr18/hg4dysaN/zsn/fTTT+OcY8mSJTz55JMRqV0Sm8JUUlawh24b4jnURFRYWMiAAQMqLFu5ciW9e/emSZMmNa63cOFCMjMz/bfAS5wqGzlyJCNHjqR79+4cdthhPP7446xfv55ly5YBsM8++3DaaafxzDPP+NeZO3cujRs35owzzqCkpIQHHniA2267jdNPP51evXrx4IMP0r59e2bMmOFf5+CDD+bOO++kZ8+e9OrVK9QfiSQRdUCSlFSfQ7cK0sRQWFjI2WefXWHZihUr6uxINHjwYB5++GH//drGJl63bh3XX389BQUFbNmyhb1797J3716+/vpr/2POP/98LrzwQkpLS2nRogXPPPMMI0eOpFmzZqxatYrdu3dXOHSblpbG0UcfzWeffeZfdsQRRwT7siVFaM9UUlI4h24VpLG3d+9ePv744yp7psuXL68zTFu0aEG3bt38t06dOtX42GHDhrFlyxYeeughCgoKWLlyJY0bN67QSej000+ncePGvPzyy2zevJl///vf/kO8tQkcA7byCFuS+rRnKikp2EO3U6ZMqbVdYmPt2rWUlpay//77+5d9/PHHrF27NmKXuGzdupU1a9Zw//33c+KJJwKePd/KM4o0bdqUc845h2eeeYYffviBDh06cMIJJwDQtWtX0tPTeffdd+natSvgmYVo6dKljBkzJiJ1SnJSmEpKCvbQ7dSpU2ttl9jwTTJw3333ceWVV1JUVMTEiRMBT+/ZSNhnn31o27YtjzzyCJ07d2bDhg1Mnjy52p6/559/PkOGDGH9+vWMHj2aRo08B/EyMjIYP34811xzDW3btuXggw/m7rvvZtOmTVx++eURqVOSk8JUUtJxx5/ItoAJgcvKdrF92zayWrfmqWdnV3l8MO37tduPJYvfjGrd0dJp/44xG0jB93z1UVhYyCmnnMK3335L37596dGjBzfccAPj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gwbxt7/9rdb1ysvLueWWWzjssMPYd999yczM5MUXX+Trr2N/Tvqwww7z/3///T2To2/evBnwfGk99thj/UEqqUdh2gDU9kGXl5fHYYcd5v8jrzz8X13rQ/J3xmkIEjlIfZo1a8Ypp5zCDTfcwHvvvcfFF1/M1KlTKSsrq3GdO+64gzvvvJPJkyfzxhtvUFhYyIgRI2pdJ1itWrUCYLt3zOhA27ZtIysrq8KywDl3fed09+7dG3YdkhwUpimurg+6b775huHDh3P//fcDFYf/C2b9ZDjHKcH16k6EXr2BevfuzZ49e/znUdPT06ucY3znnXcYPnw4F1xwAdnZ2XTt2pW1a9dWeEx16wWje/fuNGrUiA8//LDC8i+//JLt27dz6KGHBr2t/v37884770Qk5CUxKUxTXLDzhV588cWAZ/i/WAepznFGXyIH6datWznppJN4+umnWbVqFevXr+f5559n+vTpDBkyxL+H2KVLF5YsWcKGDRv44YcfAM95xzfeeIN33nmHNWvWMGHCBNavX1/ltS9btoyioiJ++OEH/95iz549a732tGXLllxyySVMnjyZl19+mfXr1/P2228zduxYBg0axHHHHRf0a7z88sspLi7m3HPP5YMPPuCLL75g1qxZFBYWAvDSSy/Rs2dPNmzYUJ8fnSQQhWmKi9YHpQZ9T35dunTh6quvrjEIw20PVmZmJoMGDeKee+7h+OOPp0+fPvzlL39hzJgx/gkTAG688Ua++eYbunbtSrt27QC47rrrOOqoo8jLy2Pw4MFkZGQwduzYCtufNGkS6enp9O7dm3bt2vnPp37++ef+UK7JPffcw29/+1uuvfZa+vTpw4UXXki/fv2YP3++/1BuMDp16sTbb79NWVkZJ554Iv379+fee++lcWNPH9Dt27fz+eefs3v37qC3KYnFnHPxriFmcnJy3PLly+NdRtzVFJRmhnOuziA9tHefoKZBU5DWbtKoPD4uXBHRba5evZpevXpFdJsiya62vwsz+9A5lxPuc+jSmBQXOOk2RG7i7dquk6zrOsp4XmcpIhINCtMU55t0G+reI4z3xNsiIslK50wbiESfeFtEJJkpTBuA+lyeonOcIiL1p8O8KS7YQemPyzuDnTt31NquIBURqZ72TFNcsIPSd+h0YIXh/6prFxGR6ilMU1ywg9LXt11ERP5HYZrigh2U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lPg7Ofkek56ezrvvvutfVl5eztKlS+ndu3dQ29i6dStr1qzhL3/5CyeffDK9evXil19+Yc+ePRVqS09Pr/C7Dna9UNX12iIl2N/Xyy+/XKEX79q1ayktLWX//ff3L/v4449Zu3at9kxFGrraDt3m5+ezdOlSSktLAU8vUV9HIN+5y8rr19azsz7S0tL8zxHL86Q1Wb9+PQ899BBnnHEGnTp14ssvv2TVqlWMHz+eli1bMmnSJCZNmoRzjsGDB1NcXOzv+XnppZcCcNJJJzFx4kTmzZvHoYceykMPPcQ333zj/7lnZmZy8cUXc80119CuXTv2339/brzxxgqBlpGRwfjx47nmmmto27YtBx98MHfffTebNm3i8ssvD2ob++yzD23btuWRRx6hc+fObNiwgcmTJ/s72fh06dKFZcuWUVRURGZmJm3atAlqvVDV9doiJZjf15YtW3j//ff517/+5V+vsLAQgPvuu48rr7ySoqIi//Wnu3btilh9oVKYisRJWdmuWs+B/uc///EHqU9gR6BYdEZKFC1atGDt2rWcc845/PDDD7Rv356xY8dyzTXXAHDTTTfRvn177rjjDsaPH0+rVq3Izs7m6quv9m/jt7/9LatWreK3v/0tAFdccQVnnXUWP/zwg/8xd9xxByUlJZx11lm0aNGC//f//l+Vzli33XYbABdddBHbtm2jf//+LFy4kI4dOwa1jUaNGvHcc8/xhz/8gb59+9KtWzfuvPPOKp2LJk2axIUXXkjv3r3ZsWMH69evD2q9cNT12iKlrt/X/PnzOfLII2nfvr1/ncLCQk455RS+/fZb+vbtS48ePbjhhhsYP3489957L6eeempEa6wvq3wOIZXl5OS45cuXx7uMmOqXPYA7Zsf+kgap24UnDeD9996t8RzotGnTmDNnToVAzczMZNasWfTt27faIF29ejW9evWKWI1mVuU8o0i0nXnmmRxzzDEVvgwNHTqU/v37c+utt9Z7e7X9XZjZh865nJCL9dI5U5E4qes60+uuu46jjz6azMxMAH9HoF69esVsj3TKlClR3b5IdY455hj/oCE+hYWFFXoSJ5q4HuY1s6eBIUAG8D0w3Tn3qLdtCDADOBAoAMY5577ytjUFHgB+DZR617sr9q9AJHQtW+9Lv+yK18yVle1i+7ZtZLVuzVPPzsY5R5t2+1FcXEybdvvx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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# make a nice ratio plot, adjusting some font sizes\n", + "plt.rcParams.update({\n", + " 'font.size': 14,\n", + " 'axes.titlesize': 18,\n", + " 'axes.labelsize': 18,\n", + " 'xtick.labelsize': 12,\n", + " 'ytick.labelsize': 12\n", + "})\n", + "fig, (ax, rax) = plt.subplots(\n", + " nrows=2,\n", + " ncols=1,\n", + " figsize=(7,7),\n", + " gridspec_kw={\"height_ratios\": (3, 1)},\n", + " sharex=True\n", + ")\n", + "fig.subplots_adjust(hspace=.07)\n", + "\n", + "# Here is an example of setting up a color cycler to color the various fill patches\n", + "# We get the colors from this useful utility: http://colorbrewer2.org/#type=qualitative&scheme=Paired&n=6\n", + "from cycler import cycler\n", + "colors = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c']\n", + "ax.set_prop_cycle(cycler(color=colors))\n", + "\n", + "fill_opts = {\n", + " 'edgecolor': (0,0,0,0.3),\n", + " 'alpha': 0.8\n", + "}\n", + "error_opts = {\n", + " 'label': 'Stat. Unc.',\n", + " 'hatch': '///',\n", + " 'facecolor': 'none',\n", + " 'edgecolor': (0,0,0,.5),\n", + " 'linewidth': 0\n", + "}\n", + "data_err_opts = {\n", + " 'linestyle': 'none',\n", + " 'marker': '.',\n", + " 'markersize': 10.,\n", + " 'color': 'k',\n", + " 'elinewidth': 1,\n", + "}\n", + "\n", + "# plot the MC first\n", + "hist.plot1d(\n", + " pthist[notdata], \n", + " overlay=\"flavor\", \n", + " ax=ax,\n", + " clear=False,\n", + " stack=True, \n", + " line_opts=None,\n", + " fill_opts=fill_opts,\n", + " error_opts=error_opts\n", + ")\n", + "# now the pseudodata, setting clear=False to avoid overwriting the previous plot\n", + "hist.plot1d(\n", + " pthist['pseudodata'],\n", + " overlay=\"flavor\",\n", + " ax=ax,\n", + " clear=False,\n", + " error_opts=data_err_opts\n", + ")\n", + "\n", + "ax.autoscale(axis='x', tight=True)\n", + "ax.set_ylim(0, None)\n", + "ax.set_xlabel(None)\n", + "leg = ax.legend()\n", + "\n", + "# now we build the ratio plot\n", + "hist.plotratio(\n", + " num=pthist['pseudodata'].sum(\"flavor\"),\n", + " denom=pthist[notdata].sum(\"flavor\"), \n", + " ax=rax,\n", + " error_opts=data_err_opts, \n", + " denom_fill_opts={},\n", + " guide_opts={},\n", + " unc='num'\n", + ")\n", + "rax.set_ylabel('Ratio')\n", + "rax.set_ylim(0,2)\n", + "\n", + "# add some labels\n", + "coffee = plt.text(0., 1., u\"☕\",\n", + " fontsize=28, \n", + " horizontalalignment='left', \n", + " verticalalignment='bottom', \n", + " transform=ax.transAxes\n", + " )\n", + "lumi = plt.text(1., 1., r\"1 fb$^{-1}$ (?? TeV)\",\n", + " fontsize=16, \n", + " horizontalalignment='right', \n", + " verticalalignment='bottom', \n", + " transform=ax.transAxes\n", + " )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Some further styling tools are available through the `mplhep` package. In particular, there are several stylesheets that update `plt.rcParams` to conform with experiment style recommendations regarding font face, font sizes, tick mark styles, and other such things. Below is an example application." + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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OteppDQidomIn0bEIxGxc4v9/wn8GvhP4EJgfmmfJEnqpL/+9a9AliSVJwhtbMCAARx88MEArSYuARxzzDEMGjSoYt13vvOdQHY1dfHixZuM56GHHgKyBKutpyQNGzaMf//3fweomGABHHrooRX3b7nllpuMoSu8/vWv54QTTuAtb3nLBvvXrl3L7373O/7rv/6rYr3Bgwfzrne9C4D//d//3eDYz3/+c1JKjB07lokTJzbvL39mRxxxRMU/KgAOPvhgNt98c6DyZ7brrruy/fbbd/Dd1b+a1ymNiB2Ae4HtNtq/E/D50rd/BF4FDgC+GhH/l1K6r9Y+JUlSNkMdYOnSpR1a7ui5555rtW+PPfZos/wOO+zAlltuyapVq3j44YcZN25cu+2XE6xNPbazfLytpHT06PyfybN+/Xp++9vfcuONN/LAAw/w0EMPsWTJEl599dV2651wwgn84Ac/4KabbmLFihUMHz4cgNmzZwPwgQ98YIMR5I58ZuUVDh588MGKn9lOO+1U5burbzUnpcCngBHAE8AFwDOl/ccBmwP3pJT2B4iIRuA04KOlrSRJqtHatWurKl/psnely9MtbbZZliK89NJLm2w/u+1w08ptvvLKKxWPbyqm7vbUU0/xzne+s/nWiM0335x/+7d/4+1vfzsTJ05khx12YPLkyRXrHnbYYWy//fY8/fTTzJ07l/e973089thj3HbbbQwYMICTTjppg/Jd8ZkNGTKkmrdX9zpz+f5tZDe+npZSakopvVzaf0xp/w9alL2ktJ2IJEnqlL322guA173udR2aQFJOslp65JFH2mz/mWee4fnnn9+gr/bsueeeAM3rgralfCvA6173uk22mYcPfvCD3Hnnney5557ceOONvPDCC9xxxx1cdtllnHLKKbzhDW9os+5mm23G1KlTgX9dwr/mmmsAOProo9l55503KN+Rz6zl7RP1+pl1pc4kpeUx9lvLOyIblz649G3Lu5jLY867daI/SZLEvxLFhx9+mBdffLHNcn/7299YsGABTzzxRKtjN998c5ujdeVnxsO/kqf2jBkzBoAHH3ywzQXkywley/jryerVq/nVr34FwHe/+12OPvro5lHKsvIl97accMIJANxwww2sXr26+dJ9pYlM5c/spptuavPWgPnz57N69WqgPj+zrtaZpLR87aDlGdsX2BZYmlJq+SfYZhXKSpKkGowZM4a99tqL9evXt/mUokcffZR9992XN7/5zfz9739vdfzPf/4zP/vZz1rtX7FiBRdeeCEAU6ZMYauttmpVZuNk9uCDD2brrbdm3bp1zJw5s2Ky++Uvf5lnn32WAQMGcOSRR3bkbfaolrdElCcXtfTyyy/z9a9/vfn7Su/xkEMOYeedd2bNmjU0NjZy5513Mnz48OaJYy0dc8wxADzwwAP86Ec/anX8lVdeaV4F4XWve11zEtuXdSYpLU/HO6jFvhml7cZrPexb2j7Wif4kSeqzVqxYwZIlS9p9PfZY9t/ogAED+OIXvwjA17/+dU455RTuueceXnzxRZYvX861117LW97yFlavXs0BBxzQajZ52UknncRXvvIVHnroIZ555hmKxSL7778/ixcv3qCPjf3lL39h7dq1zYnZ1ltvzbnnngtkjyCdNm0ad955Jy+88AJ/+tOf+I//+A++8IUvAPDhD394kxOi8rDttts2T/76+Mc/zoIFC1izZg3Lli3jl7/8JW9961v59a9/3Vz+F7/4Rav7PAcMGMB73/tegObP44QTTqiY5B566KEcffTRQHbbwAUXXMCiRYt4/vnn+cMf/sCkSZOYN28eAF/4whc6NKGt16t1gVOyx4auJ7s0Pwk4FlhJNtv+2Bbldudfs/Bnd/fCq73hhYvnqwUXz5f6t/IC7x15bbzY+5e+9KV2y48bNy499dRTG9QpL+R+5plntvlITyBddtllrWL94Q9/uMHjNvfaa6/mY+vWrUunnnpqu/Ece+yxafXq1Ru02XLx/LaUF4t/61vfWtNn29HF8+fMmdNm7Jtttln61re+lcaMGdO8b8qUKa36nD9//gb17rjjjjbje+qpp9LEiRPb/cw+97nPddnnUasW56duF8+/GHga2AP4DTAH2Ar4EzAXICJOJxtRnVCq841O9CdJklr41Kc+xV133cWHPvQh9t9/f7bcckt23nln3vKWt9DU1MQ999zT5jqWEydOZOHChZx22mnsvPPODBkyhDe+8Y3MmDGDO++8kzPPPLNVnRNPPJHTTz+d7bbbjgEDBmywJNHAgQP5/ve/T7FY5KSTTuLf/u3f2GKLLXjDG97AtGnTuOqqq5gzZw5Dhw7tts+js975zndy6623cswxx7DrrrsyePDg5ocM3H///Zx11ln89Kc/ZezYsey4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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import mplhep\n", + "plt.style.use(mplhep.style.ROOT)\n", + "\n", + "# Compare this to the style of the plot drawn previously\n", + "ax = hist.plot1d(lepton_pt, overlay=\"flavor\", density=True)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/nanoevents.html b/notebooks/nanoevents.html new file mode 100644 index 000000000..512c9704e --- /dev/null +++ b/notebooks/nanoevents.html @@ -0,0 +1,577 @@ + + + + + + + + + Reading data with coffea NanoEvents — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Reading data with coffea NanoEvents

+

This is a rendered copy of nanoevents.ipynb. You can optionally run it interactively on binder at this link

+

NanoEvents is a Coffea utility to wrap flat nTuple structures (such as the CMS NanoAOD format) into a single awkward array with appropriate object methods (such as Lorentz vector methods\(^*\)), cross references, and nested objects, all lazily accessed\(^\dagger\) from the source ROOT TTree via uproot. The interpretation of the TTree data is configurable via schema +objects, which are community-supplied for various source file types. These schema objects allow a richer interpretation of the file contents than the uproot.lazy methods. Currently available schemas include:

+
    +
  • BaseSchema, which provides a simple representation of the input TTree, where each branch is available verbatim as events.branch_name, effectively the same behavior as uproot.lazy. Any branches that uproot supports at “full speed” (i.e. that are fully split and either flat or single-jagged) can be read by this schema;

  • +
  • NanoAODSchema, which is optimized to provide all methods and cross-references in CMS NanoAOD format;

  • +
  • PFNanoAODSchema, which builds a double-jagged particle flow candidate colllection events.jet.constituents from compatible PFNanoAOD input files;

  • +
  • TreeMakerSchema which is designed to read TTrees made by TreeMaker, an alternative CMS nTuplization format;

  • +
  • PHYSLITESchema, for the ATLAS DAOD_PHYSLITE derivation, a compact centrally-produced data format similar to CMS NanoAOD; and

  • +
  • DelphesSchema, for reading Delphes fast simulation nTuples.

  • +
+

We welcome contributions for new schemas, and can assist with the design of them.

+

\(^*\) Vector methods are currently made possible via the coffea vector methods mixin class structure. In a future version of coffea, they will instead be provided by the dedicated scikit-hep vector library, which provides a more rich feature set. The coffea vector methods predate the release of the vector library.

+

\(^\dagger\) Lazy access refers to only fetching the needed data from the (possibly remote) file when a sub-array is first accessed. The sub-array is then materialized and subsequent access of the sub-array uses a cached value in memory. As such, fully materializing a NanoEvents object may require a significant amount of memory.

+

In this demo, we will use NanoEvents to read a small CMS NanoAOD sample. The events object can be instantiated as follows:

+
+
[1]:
+
+
+
import awkward as ak
+from coffea.nanoevents import NanoEventsFactory, NanoAODSchema
+
+fname = "https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/nano_dy.root"
+events = NanoEventsFactory.from_root(
+    fname,
+    schemaclass=NanoAODSchema.v6,
+    metadata={"dataset": "DYJets"},
+).events()
+
+
+
+

In the factory constructor, we also pass the desired schema version (the latest version of NanoAOD can be built with schemaclass=NanoAODSchema) for this file and some extra metadata that we can later access with events.metadata. In a later example, we will show how to set up this metadata in coffea processors where the events object is pre-created for you. Consider looking at the +from_root class method to see all optional arguments.

+

The events object is an awkward array, which at its top level is a record array with one record for each “collection”, where a collection is a grouping of fields (TBranches) based on the naming conventions of NanoAODSchema. For example, in the file we opened, the branches:

+
Generator_binvar
+Generator_scalePDF
+Generator_weight
+Generator_x1
+Generator_x2
+Generator_xpdf1
+Generator_xpdf2
+Generator_id1
+Generator_id2
+
+
+

are grouped into one sub-record named Generator which can be accessed using either getitem or getattr syntax, i.e. events["Generator"] or events.Generator. e.g.

+
+
[2]:
+
+
+
events.Generator.id1
+
+
+
+
+
[2]:
+
+
+
+
+<Array [1, -1, -1, 21, 21, ... 2, -2, -1, 2, 1] type='40 * int32[parameters={"__...'>
+
+
+
+
[3]:
+
+
+
# all names can be listed with:
+events.Generator.fields
+
+
+
+
+
[3]:
+
+
+
+
+['binvar', 'scalePDF', 'weight', 'x1', 'x2', 'xpdf1', 'xpdf2', 'id1', 'id2']
+
+
+

In CMS NanoAOD, each TBranch has a self-documenting help string embedded in the title field, which is carried into the NanoEvents, e.g. executing the following cell should produce a help pop-up:

+
Type:            Array
+String form:     [1, -1, -1, 21, 21, 4, 2, -2, 2, 1, 3, 1, ... -1, -1, 1, -2, 2, 1, 2, -2, -1, 2, 1]
+Length:          40
+File:            ~/src/awkward-1.0/awkward1/highlevel.py
+Docstring:       id of first parton
+Class docstring: ...
+
+
+

where the Docstring shows information about the content of this array.

+
+
[4]:
+
+
+
events.Generator.id1?
+
+
+
+

Based on a collection’s name or contents, some collections acquire additional methods, which are extra features exposed by the code in the mixin classes of the coffea.nanoevents.methods modules. For example, although events.GenJet has the fields:

+
+
[5]:
+
+
+
events.GenJet.fields
+
+
+
+
+
[5]:
+
+
+
+
+['eta', 'mass', 'phi', 'pt', 'partonFlavour', 'hadronFlavour']
+
+
+

we can access additional attributes associated to each generated jet by virtue of the fact that they can be interpreted as Lorentz vectors:

+
+
[6]:
+
+
+
events.GenJet.energy
+
+
+
+
+
[6]:
+
+
+
+
+<Array [[217, 670, 258], ... 16], [76.9]] type='40 * var * float32'>
+
+
+

We can call more complex methods, like computing the distance \(\Delta R = \sqrt{\Delta \eta^2 + \Delta \phi ^2}\) between two LorentzVector objects:

+
+
[7]:
+
+
+
# find distance between leading jet and all electrons in each event
+dr = events.Jet[:, 0].delta_r(events.Electron)
+dr
+
+
+
+
+
[7]:
+
+
+
+
+<Array [[], [3.13], [3.45, ... 0.0858], [], []] type='40 * var * float32'>
+
+
+
+
[8]:
+
+
+
# find minimum distance
+ak.min(dr, axis=1)
+
+
+
+
+
[8]:
+
+
+
+
+<Array [None, 3.13, 2.18, ... None, None] type='40 * ?float32'>
+
+
+
+
[9]:
+
+
+
# a convenience method for this operation on all jets is available
+events.Jet.nearest(events.Electron)
+
+
+
+
+
[9]:
+
+
+
+
+<ElectronArray [[None, None, None, ... [None, None]] type='40 * var * ?electron'>
+
+
+

The assignment of methods classes to collections is done inside the schema object during the initial creation of the array, governed by the awkward array’s __record__ parameter and the associated behavior. See ak.behavior for a more detailed explanation of array behaviors.

+

Additional methods provide convenience functions for interpreting some branches, e.g. CMS NanoAOD packs several jet identification flag bits into a single integer, jetId. By implementing the bit-twiddling in the Jet mixin, the analsyis code becomes more clear:

+
+
[10]:
+
+
+
print(events.Jet.jetId)
+print(events.Jet.isTight)
+
+
+
+
+
+
+
+
+[[6, 6, 6, 6, 6], [6, 2, 6, 6, 6, 6, 6, 0], ... 6], [6], [6, 6, 0, 6, 6, 6], [6, 6]]
+[[True, True, True, True, True], [True, ... False, True, True, True], [True, True]]
+
+
+

We can also define convenience functions to unpack and apply some mask to a set of flags, e.g. for generated particles:

+
+
[11]:
+
+
+
print(f"Raw status flags: {events.GenPart.statusFlags}")
+events.GenPart.hasFlags(['isPrompt', 'isLastCopy'])
+
+
+
+
+
+
+
+
+Raw status flags: [[10625, 27009, 4481, 22913, 257, 257, ... 13884, 13884, 12876, 12876, 12876, 12876]]
+
+
+
+
[11]:
+
+
+
+
+<Array [[True, True, False, ... False, False]] type='40 * var * bool'>
+
+
+

CMS NanoAOD also contains pre-computed cross-references for some types of collections. For example, there is a TBranch Electron_genPartIdx which indexes the GenPart collection per event to give the matched generated particle, and -1 if no match is found. NanoEvents transforms these indices into an awkward indexed array pointing to the collection, so that one can directly access the matched particle using getattr syntax:

+
+
[12]:
+
+
+
events.Electron.matched_gen.pdgId
+
+
+
+
+
[12]:
+
+
+
+
+<Array [[], [-11], [-11, ... [None], [], []] type='40 * var * ?int32[parameters=...'>
+
+
+
+
[13]:
+
+
+
events.Muon[ak.num(events.Muon)>0].matched_jet.pt
+
+
+
+
+
[13]:
+
+
+
+
+<Array [[84.4, 29.4], [31.1, ... 26.1], [25.8]] type='12 * var * ?float32[parame...'>
+
+
+

For generated particles, the parent index is similarly mapped:

+
+
[14]:
+
+
+
events.GenPart.parent.pdgId
+
+
+
+
+
[14]:
+
+
+
+
+<Array [[None, None, 1, 1, ... 111, 111, 111]] type='40 * var * ?int32[parameter...'>
+
+
+

In addition, using the parent index, a helper method computes the inverse mapping, namely, children. As such, one can find particle siblings with:

+
+
[15]:
+
+
+
events.GenPart.parent.children.pdgId
+# notice this is a doubly-jagged array
+
+
+
+
+
[15]:
+
+
+
+
+<Array [[None, None, [23, 21, ... [22, 22]]] type='40 * var * option[var * ?int3...'>
+
+
+

Since often one wants to shortcut repeated particles in a decay sequence, a helper method distinctParent is also available. Here we use it to find the parent particle ID for all prompt electrons:

+
+
[16]:
+
+
+
events.GenPart[
+    (abs(events.GenPart.pdgId) == 11)
+    & events.GenPart.hasFlags(['isPrompt', 'isLastCopy'])
+].distinctParent.pdgId
+
+
+
+
+
[16]:
+
+
+
+
+<Array [[], [23, 23], [23, ... [23, 23], []] type='40 * var * ?int32[parameters=...'>
+
+
+

Events can be filtered like any other awkward array using boolean fancy-indexing

+
+
[17]:
+
+
+
mmevents = events[ak.num(events.Muon) == 2]
+zmm = mmevents.Muon[:, 0] + mmevents.Muon[:, 1]
+zmm.mass
+
+
+
+
+
[17]:
+
+
+
+
+<Array [94.6, 87.6, 88, 90.4, 89.1, 31.6] type='6 * float32'>
+
+
+
+
[18]:
+
+
+
# a convenience method is available to sum vectors along an axis:
+mmevents.Muon.sum(axis=1).mass
+
+
+
+
+
[18]:
+
+
+
+
+<Array [94.6, 87.6, 88, 90.4, 89.1, 31.6] type='6 * float32'>
+
+
+

As expected for this sample, most of the dimuon events have a pair invariant mass close to that of a Z boson. But what about the last event? Let’s take a look at the generator information:

+
+
[19]:
+
+
+
print(mmevents[-1].Muon.matched_gen.pdgId)
+print(mmevents[-1].Muon.matched_gen.hasFlags(["isPrompt"]))
+
+
+
+
+
+
+
+
+[-13, 13]
+[False, False]
+
+
+

So they are real generated muons, but they are not prompt (i.e. from the initial decay of a heavy resonance)

+

Let’s look at their parent particles:

+
+
[20]:
+
+
+
mmevents[-1].Muon.matched_gen.parent.pdgId
+
+
+
+
+
[20]:
+
+
+
+
+<Array [-15, 15] type='2 * ?int32[parameters={"__doc__": "PDG id"}]'>
+
+
+

aha! They are muons coming from tau lepton decays, and hence a fair amount of the Z mass is carried away by the neutrinos:

+
+
[21]:
+
+
+
print(mmevents[-1].Muon.matched_gen.sum().mass)
+print(mmevents[-1].Muon.matched_gen.parent.sum().mass)
+
+
+
+
+
+
+
+
+31.265271292167853
+91.68363205830444
+
+
+

One can assign new variables to the arrays, with some caveats:

+
    +
  • Assignment must use setitem (events["path", "to", "name"] = value)

  • +
  • Assignment to a sliced events won’t be accessible from the original variable

  • +
  • New variables are not visible from cross-references

  • +
+
+
[22]:
+
+
+
mmevents["Electron", "myvariable"] = mmevents.Electron.pt + zmm.mass
+mmevents.Electron.myvariable
+
+
+
+
+
[22]:
+
+
+
+
+<Array [[], [121], [], [], [], []] type='6 * var * float32'>
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/notebooks/nanoevents.ipynb b/notebooks/nanoevents.ipynb new file mode 100644 index 000000000..87bf187dc --- /dev/null +++ b/notebooks/nanoevents.ipynb @@ -0,0 +1,639 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Reading data with coffea NanoEvents\n", + "\n", + "This is a rendered copy of [nanoevents.ipynb](https://github.com/CoffeaTeam/coffea/blob/master/binder/nanoevents.ipynb). You can optionally run it interactively on [binder at this link](https://mybinder.org/v2/gh/coffeateam/coffea/master?filepath=binder%2Fnanoevents.ipynb)\n", + "\n", + "NanoEvents is a Coffea utility to wrap flat nTuple structures (such as the CMS [NanoAOD](https://www.epj-conferences.org/articles/epjconf/pdf/2019/19/epjconf_chep2018_06021.pdf) format) into a single awkward array with appropriate object methods (such as Lorentz vector methods$^*$), cross references, and nested objects, all lazily accessed$^\\dagger$ from the source ROOT TTree via uproot. The interpretation of the TTree data is configurable via [schema objects](https://coffeateam.github.io/coffea/modules/coffea.nanoevents.html#classes), which are community-supplied for various source file types. These schema objects allow a richer interpretation of the file contents than the [uproot.lazy](https://uproot4.readthedocs.io/en/latest/uproot4.behaviors.TBranch.lazy.html) methods. Currently available schemas include:\n", + "\n", + " - `BaseSchema`, which provides a simple representation of the input TTree, where each branch is available verbatim as `events.branch_name`, effectively the same behavior as `uproot.lazy`. Any branches that uproot supports at \"full speed\" (i.e. that are fully split and either flat or single-jagged) can be read by this schema;\n", + " - `NanoAODSchema`, which is optimized to provide all methods and cross-references in CMS NanoAOD format;\n", + " - `PFNanoAODSchema`, which builds a double-jagged particle flow candidate colllection `events.jet.constituents` from compatible PFNanoAOD input files;\n", + " - `TreeMakerSchema` which is designed to read TTrees made by [TreeMaker](https://github.com/TreeMaker/TreeMaker), an alternative CMS nTuplization format;\n", + " - `PHYSLITESchema`, for the ATLAS DAOD_PHYSLITE derivation, a compact centrally-produced data format similar to CMS NanoAOD; and\n", + " - `DelphesSchema`, for reading Delphes fast simulation [nTuples](https://cp3.irmp.ucl.ac.be/projects/delphes/wiki/WorkBook/RootTreeDescription).\n", + "\n", + "We welcome contributions for new schemas, and can assist with the design of them.\n", + "\n", + "$^*$ Vector methods are currently made possible via the [coffea vector](https://coffeateam.github.io/coffea/modules/coffea.nanoevents.methods.vector.html) methods mixin class structure. In a future version of coffea, they will instead be provided by the dedicated scikit-hep [vector](https://vector.readthedocs.io/en/latest/) library, which provides a more rich feature set. The coffea vector methods predate the release of the vector library.\n", + "\n", + "$^\\dagger$ _Lazy_ access refers to only fetching the needed data from the (possibly remote) file when a sub-array is first accessed. The sub-array is then _materialized_ and subsequent access of the sub-array uses a cached value in memory. As such, fully materializing a `NanoEvents` object may require a significant amount of memory.\n", + "\n", + "\n", + "In this demo, we will use NanoEvents to read a small CMS NanoAOD sample. The events object can be instantiated as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import awkward as ak\n", + "from coffea.nanoevents import NanoEventsFactory, NanoAODSchema\n", + "\n", + "fname = \"https://raw.githubusercontent.com/CoffeaTeam/coffea/master/tests/samples/nano_dy.root\"\n", + "events = NanoEventsFactory.from_root(\n", + " fname,\n", + " schemaclass=NanoAODSchema.v6,\n", + " metadata={\"dataset\": \"DYJets\"},\n", + ").events()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the factory constructor, we also pass the desired schema version (the latest version of NanoAOD can be built with `schemaclass=NanoAODSchema`) for this file and some extra metadata that we can later access with `events.metadata`. In a later example, we will show how to set up this metadata in coffea processors where the `events` object is pre-created for you. Consider looking at the [from_root](https://coffeateam.github.io/coffea/api/coffea.nanoevents.NanoEventsFactory.html#coffea.nanoevents.NanoEventsFactory.from_root) class method to see all optional arguments.\n", + "\n", + "The `events` object is an awkward array, which at its top level is a record array with one record for each \"collection\", where a collection is a grouping of fields (TBranches) based on the naming conventions of [NanoAODSchema](https://coffeateam.github.io/coffea/api/coffea.nanoevents.NanoAODSchema.html). For example, in the file we opened, the branches:\n", + "```\n", + "Generator_binvar\n", + "Generator_scalePDF\n", + "Generator_weight\n", + "Generator_x1\n", + "Generator_x2\n", + "Generator_xpdf1\n", + "Generator_xpdf2\n", + "Generator_id1\n", + "Generator_id2\n", + "```\n", + "are grouped into one sub-record named `Generator` which can be accessed using either getitem or getattr syntax, i.e. `events[\"Generator\"]` or `events.Generator`. e.g." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.Generator.id1" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['binvar', 'scalePDF', 'weight', 'x1', 'x2', 'xpdf1', 'xpdf2', 'id1', 'id2']" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# all names can be listed with:\n", + "events.Generator.fields" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In CMS NanoAOD, each TBranch has a self-documenting help string embedded in the title field, which is carried into the NanoEvents, e.g. executing the following cell should produce a help pop-up:\n", + "```\n", + "Type: Array\n", + "String form: [1, -1, -1, 21, 21, 4, 2, -2, 2, 1, 3, 1, ... -1, -1, 1, -2, 2, 1, 2, -2, -1, 2, 1]\n", + "Length: 40\n", + "File: ~/src/awkward-1.0/awkward1/highlevel.py\n", + "Docstring: id of first parton\n", + "Class docstring: ...\n", + "```\n", + "where the `Docstring` shows information about the content of this array." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "events.Generator.id1?" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Based on a collection's name or contents, some collections acquire additional _methods_, which are extra features exposed by the code in the mixin classes of the `coffea.nanoevents.methods` modules. For example, although `events.GenJet` has the fields:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "['eta', 'mass', 'phi', 'pt', 'partonFlavour', 'hadronFlavour']" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenJet.fields" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "we can access additional attributes associated to each generated jet by virtue of the fact that they can be interpreted as [Lorentz vectors](https://coffeateam.github.io/coffea/api/coffea.nanoevents.methods.vector.LorentzVector.html#coffea.nanoevents.methods.vector.LorentzVector):" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenJet.energy" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can call more complex methods, like computing the distance $\\Delta R = \\sqrt{\\Delta \\eta^2 + \\Delta \\phi ^2}$ between two LorentzVector objects:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# find distance between leading jet and all electrons in each event\n", + "dr = events.Jet[:, 0].delta_r(events.Electron)\n", + "dr" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# find minimum distance\n", + "ak.min(dr, axis=1)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# a convenience method for this operation on all jets is available\n", + "events.Jet.nearest(events.Electron)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The assignment of methods classes to collections is done inside the schema object during the initial creation of the array, governed by the awkward array's `__record__` parameter and the associated behavior. See [ak.behavior](https://awkward-array.readthedocs.io/en/latest/ak.behavior.html) for a more detailed explanation of array behaviors.\n", + "\n", + "Additional methods provide convenience functions for interpreting some branches, e.g. CMS NanoAOD packs several jet identification flag bits into a single integer, `jetId`. By implementing the bit-twiddling in the [Jet mixin](https://github.com/CoffeaTeam/coffea/blob/7045c06b9448d2be4315e65d432e6d8bd117d6d7/coffea/nanoevents/methods/nanoaod.py#L279-L282), the analsyis code becomes more clear:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[[6, 6, 6, 6, 6], [6, 2, 6, 6, 6, 6, 6, 0], ... 6], [6], [6, 6, 0, 6, 6, 6], [6, 6]]\n", + "[[True, True, True, True, True], [True, ... False, True, True, True], [True, True]]\n" + ] + } + ], + "source": [ + "print(events.Jet.jetId)\n", + "print(events.Jet.isTight)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We can also define convenience functions to unpack and apply some mask to a set of flags, e.g. for generated particles:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Raw status flags: [[10625, 27009, 4481, 22913, 257, 257, ... 13884, 13884, 12876, 12876, 12876, 12876]]\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print(f\"Raw status flags: {events.GenPart.statusFlags}\")\n", + "events.GenPart.hasFlags(['isPrompt', 'isLastCopy'])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "CMS NanoAOD also contains pre-computed cross-references for some types of collections. For example, there is a TBranch `Electron_genPartIdx` which indexes the `GenPart` collection per event to give the matched generated particle, and `-1` if no match is found. NanoEvents transforms these indices into an awkward _indexed array_ pointing to the collection, so that one can directly access the matched particle using getattr syntax:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.Electron.matched_gen.pdgId" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.Muon[ak.num(events.Muon)>0].matched_jet.pt" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For generated particles, the parent index is similarly mapped:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenPart.parent.pdgId" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In addition, using the parent index, a helper method computes the inverse mapping, namely, `children`. As such, one can find particle siblings with:" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenPart.parent.children.pdgId\n", + "# notice this is a doubly-jagged array" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Since often one wants to shortcut repeated particles in a decay sequence, a helper method `distinctParent` is also available. Here we use it to find the parent particle ID for all prompt electrons:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "events.GenPart[\n", + " (abs(events.GenPart.pdgId) == 11)\n", + " & events.GenPart.hasFlags(['isPrompt', 'isLastCopy'])\n", + "].distinctParent.pdgId" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Events can be filtered like any other awkward array using boolean fancy-indexing" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mmevents = events[ak.num(events.Muon) == 2]\n", + "zmm = mmevents.Muon[:, 0] + mmevents.Muon[:, 1]\n", + "zmm.mass" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# a convenience method is available to sum vectors along an axis:\n", + "mmevents.Muon.sum(axis=1).mass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As expected for this sample, most of the dimuon events have a pair invariant mass close to that of a Z boson. But what about the last event? Let's take a look at the generator information:" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-13, 13]\n", + "[False, False]\n" + ] + } + ], + "source": [ + "print(mmevents[-1].Muon.matched_gen.pdgId)\n", + "print(mmevents[-1].Muon.matched_gen.hasFlags([\"isPrompt\"]))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "So they are real generated muons, but they are not prompt (i.e. from the initial decay of a heavy resonance)\n", + "\n", + "Let's look at their parent particles:" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mmevents[-1].Muon.matched_gen.parent.pdgId" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "aha! They are muons coming from tau lepton decays, and hence a fair amount of the Z mass is carried away by the neutrinos:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "31.265271292167853\n", + "91.68363205830444\n" + ] + } + ], + "source": [ + "print(mmevents[-1].Muon.matched_gen.sum().mass)\n", + "print(mmevents[-1].Muon.matched_gen.parent.sum().mass)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One can assign new variables to the arrays, with some caveats:\n", + "\n", + " * Assignment must use setitem (`events[\"path\", \"to\", \"name\"] = value`)\n", + " * Assignment to a sliced `events` won't be accessible from the original variable\n", + " * New variables are not visible from cross-references" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mmevents[\"Electron\", \"myvariable\"] = mmevents.Electron.pt + zmm.mass\n", + "mmevents.Electron.myvariable" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/notebooks/processor.html b/notebooks/processor.html new file mode 100644 index 000000000..918db3583 --- /dev/null +++ b/notebooks/processor.html @@ -0,0 +1,860 @@ + + + + + + + + + Coffea Processors — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Coffea Processors

+

This is a rendered copy of processor.ipynb. You can optionally run it interactively on binder at this link

+

Coffea relies mainly on uproot to provide access to ROOT files for analysis. As a usual analysis will involve processing tens to thousands of files, totalling gigabytes to terabytes of data, there is a certain amount of work to be done to build a parallelized framework to process the data in a reasonable amount of time. Of course, one can work directly within uproot to achieve this, as we’ll show in the beginning, but coffea provides the +coffea.processor module, which allows users to worry just about the actual analysis code and not about how to implement efficient parallelization, assuming that the parallization is a trivial map-reduce operation (e.g. filling histograms and adding them together). The module provides the following key features:

+
    +
  • A ProcessorABC abstract base class that can be derived from to implement the analysis code;

  • +
  • A NanoEvents interface to the arrays being read from the TTree as inputs;

  • +
  • A generic accumulate() utility to reduce the outputs to a single result, as showin in the accumulators notebook tutorial; and

  • +
  • A set of parallel executors to access multicore processing or distributed computing systems such as Dask, Parsl, Spark, WorkQueue, and others.

  • +
+

Let’s start by writing a simple processor class that reads some CMS open data and plots a dimuon mass spectrum. We’ll start by copying the ProcessorABC skeleton and filling in some details:

+
    +
  • Remove flag, as we won’t use it

  • +
  • Adding a new histogram for \(m_{\mu \mu}\)

  • +
  • Building a Candidate record for muons, since we will read it with BaseSchema interpretation (the files used here could be read with NanoAODSchema but we want to show how to build vector objects from other TTree formats)

  • +
  • Calculating the dimuon invariant mass

  • +
+
+
[1]:
+
+
+
import awkward as ak
+from coffea import processor
+from coffea.nanoevents.methods import candidate
+import hist
+
+class MyProcessor(processor.ProcessorABC):
+    def __init__(self):
+        pass
+
+    def process(self, events):
+        dataset = events.metadata['dataset']
+        muons = ak.zip(
+            {
+                "pt": events.Muon_pt,
+                "eta": events.Muon_eta,
+                "phi": events.Muon_phi,
+                "mass": events.Muon_mass,
+                "charge": events.Muon_charge,
+            },
+            with_name="PtEtaPhiMCandidate",
+            behavior=candidate.behavior,
+        )
+
+        h_mass = (
+            hist.Hist.new
+            .StrCat(["opposite", "same"], name="sign")
+            .Log(1000, 0.2, 200., name="mass", label="$m_{\mu\mu}$ [GeV]")
+            .Int64()
+        )
+
+        cut = (ak.num(muons) == 2) & (ak.sum(muons.charge, axis=1) == 0)
+        # add first and second muon in every event together
+        dimuon = muons[cut][:, 0] + muons[cut][:, 1]
+        h_mass.fill(sign="opposite", mass=dimuon.mass)
+
+        cut = (ak.num(muons) == 2) & (ak.sum(muons.charge, axis=1) != 0)
+        dimuon = muons[cut][:, 0] + muons[cut][:, 1]
+        h_mass.fill(sign="same", mass=dimuon.mass)
+
+        return {
+            dataset: {
+                "entries": len(events),
+                "mass": h_mass,
+            }
+        }
+
+    def postprocess(self, accumulator):
+        pass
+
+
+
+

If we were to just use bare uproot to execute this processor, we could do that with the following example, which:

+
    +
  • Opens a CMS open data file

  • +
  • Creates a NanoEvents object using BaseSchema (roughly equivalent to the output of uproot.lazy)

  • +
  • Creates a MyProcessor instance

  • +
  • Runs the process() function, which returns our accumulators

  • +
+
+
[2]:
+
+
+
import uproot
+from coffea.nanoevents import NanoEventsFactory, BaseSchema
+
+filename = "root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root"
+file = uproot.open(filename)
+events = NanoEventsFactory.from_root(
+    file,
+    entry_stop=10000,
+    metadata={"dataset": "DoubleMuon"},
+    schemaclass=BaseSchema,
+).events()
+p = MyProcessor()
+out = p.process(events)
+out
+
+
+
+
+
[2]:
+
+
+
+
+{'DoubleMuon': {'entries': 10000,
+  'mass': Hist(
+    StrCategory(['opposite', 'same'], name='sign', label='sign'),
+    Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\mu\\mu}$ [GeV]'),
+    storage=Int64()) # Sum: 4939.0 (4951.0 with flow)}}
+
+
+
+
[3]:
+
+
+
import matplotlib.pyplot as plt
+
+fig, ax = plt.subplots()
+out["DoubleMuon"]["mass"].plot1d(ax=ax)
+ax.set_xscale("log")
+ax.legend(title="Dimuon charge")
+
+
+
+
+
[3]:
+
+
+
+
+<matplotlib.legend.Legend at 0x7f083c0c6310>
+
+
+
+
+
+
+../_images/notebooks_processor_4_1.png +
+
+

One could expand on this code to run over several chunks of the file, setting entry_start and entry_stop as appropriate. Then, several datasets could be processed by iterating over several files. However, the processor Runner can help with this! One lists the datasets and corresponding files, the processor they want to run, and which executor they want to use. Available executors derive from ExecutorBase and +are listed here. Since these files are very large, we limit to just reading the first few chunks of events from each dataset with maxchunks.

+
+
[4]:
+
+
+
fileset = {
+    'DoubleMuon': [
+        'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root',
+        'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012C_DoubleMuParked.root',
+    ],
+    'ZZ to 4mu': [
+        'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/ZZTo4mu.root'
+    ]
+}
+
+iterative_run = processor.Runner(
+    executor = processor.IterativeExecutor(compression=None),
+    schema=BaseSchema,
+    maxchunks=10,
+)
+
+out = iterative_run(
+    fileset,
+    treename="Events",
+    processor_instance=MyProcessor(),
+)
+out
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/opt/conda/lib/python3.8/site-packages/awkward/_connect/_numpy.py:195: RuntimeWarning:
+invalid value encountered in sqrt
+  result = getattr(ufunc, method)(
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
[4]:
+
+
+
+
+{'ZZ to 4mu': {'entries': 999380,
+  'mass': Hist(
+    StrCategory(['opposite', 'same'], name='sign', label='sign'),
+    Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\mu\\mu}$ [GeV]'),
+    storage=Int64()) # Sum: 192074.0 (192500.0 with flow)},
+ 'DoubleMuon': {'entries': 1000560,
+  'mass': Hist(
+    StrCategory(['opposite', 'same'], name='sign', label='sign'),
+    Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\mu\\mu}$ [GeV]'),
+    storage=Int64()) # Sum: 519403.0 (520002.0 with flow)}}
+
+
+

Now, if we want to use more than a single core on our machine, we simply change IterativeExecutor for FuturesExecutor, which uses the python concurrent.futures standard library. We can then set the most interesting argument to the FuturesExecutor: the number of +cores to use (2):

+
+
[5]:
+
+
+
futures_run = processor.Runner(
+    executor = processor.FuturesExecutor(compression=None, workers=2),
+    schema=BaseSchema,
+    maxchunks=10,
+)
+
+out = futures_run(
+    fileset,
+    "Events",
+    processor_instance=MyProcessor()
+)
+out
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
[5]:
+
+
+
+
+{'ZZ to 4mu': {'entries': 999380,
+  'mass': Hist(
+    StrCategory(['opposite', 'same'], name='sign', label='sign'),
+    Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\mu\\mu}$ [GeV]'),
+    storage=Int64()) # Sum: 192074.0 (192500.0 with flow)},
+ 'DoubleMuon': {'entries': 1000560,
+  'mass': Hist(
+    StrCategory(['opposite', 'same'], name='sign', label='sign'),
+    Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\mu\\mu}$ [GeV]'),
+    storage=Int64()) # Sum: 519403.0 (520002.0 with flow)}}
+
+
+

Hopefully this ran faster than the previous cell, but that may depend on how many cores are available on the machine you are running this notebook and your connection to eospublic.cern.ch. At least the output will be prettier now:

+
+
[6]:
+
+
+
fig, ax = plt.subplots(figsize=(10, 6))
+out["DoubleMuon"]["mass"].plot1d(ax=ax)
+ax.set_xscale("log")
+ax.legend(title="Dimuon charge")
+
+
+
+
+
[6]:
+
+
+
+
+<matplotlib.legend.Legend at 0x7f08123c89d0>
+
+
+
+
+
+
+../_images/notebooks_processor_10_1.png +
+
+
+

Getting fancy

+

Let’s flesh out this analysis into a 4-muon analysis, searching for diboson events:

+
+
[8]:
+
+
+
from collections import defaultdict
+import numba
+
+
+@numba.njit
+def find_4lep(events_leptons, builder):
+    """Search for valid 4-lepton combinations from an array of events * leptons {charge, ...}
+
+    A valid candidate has two pairs of leptons that each have balanced charge
+    Outputs an array of events * candidates {indices 0..3} corresponding to all valid
+    permutations of all valid combinations of unique leptons in each event
+    (omitting permutations of the pairs)
+    """
+    for leptons in events_leptons:
+        builder.begin_list()
+        nlep = len(leptons)
+        for i0 in range(nlep):
+            for i1 in range(i0 + 1, nlep):
+                if leptons[i0].charge + leptons[i1].charge != 0:
+                    continue
+                for i2 in range(nlep):
+                    for i3 in range(i2 + 1, nlep):
+                        if len({i0, i1, i2, i3}) < 4:
+                            continue
+                        if leptons[i2].charge + leptons[i3].charge != 0:
+                            continue
+                        builder.begin_tuple(4)
+                        builder.index(0).integer(i0)
+                        builder.index(1).integer(i1)
+                        builder.index(2).integer(i2)
+                        builder.index(3).integer(i3)
+                        builder.end_tuple()
+        builder.end_list()
+
+    return builder
+
+
+class FancyDimuonProcessor(processor.ProcessorABC):
+    def process(self, events):
+        dataset_axis = hist.axis.StrCategory([], growth=True, name="dataset", label="Primary dataset")
+        mass_axis = hist.axis.Regular(300, 0, 300, name="mass", label=r"$m_{\mu\mu}$ [GeV]")
+        pt_axis = hist.axis.Regular(300, 0, 300, name="pt", label=r"$p_{T,\mu}$ [GeV]")
+
+        h_nMuons = hist.Hist(
+            dataset_axis,
+            hist.axis.IntCategory(range(6), name="nMuons", label="Number of good muons"),
+            storage="weight", label="Counts",
+        )
+        h_m4mu = hist.Hist(dataset_axis, mass_axis, storage="weight", label="Counts")
+        h_mZ1 = hist.Hist(dataset_axis, mass_axis, storage="weight", label="Counts")
+        h_mZ2 = hist.Hist(dataset_axis, mass_axis, storage="weight", label="Counts")
+        h_ptZ1mu1 = hist.Hist(dataset_axis, pt_axis, storage="weight", label="Counts")
+        h_ptZ1mu2 = hist.Hist(dataset_axis, pt_axis, storage="weight", label="Counts")
+
+        cutflow = defaultdict(int)
+
+        dataset = events.metadata['dataset']
+        muons = ak.zip({
+            "pt": events.Muon_pt,
+            "eta": events.Muon_eta,
+            "phi": events.Muon_phi,
+            "mass": events.Muon_mass,
+            "charge": events.Muon_charge,
+            "softId": events.Muon_softId,
+            "isolation": events.Muon_pfRelIso03_all,
+        }, with_name="PtEtaPhiMCandidate", behavior=candidate.behavior)
+
+        # make sure they are sorted by transverse momentum
+        muons = muons[ak.argsort(muons.pt, axis=1)]
+
+        cutflow['all events'] += len(muons)
+
+        # impose some quality and minimum pt cuts on the muons
+        muons = muons[
+            muons.softId
+            & (muons.pt > 5)
+            & (muons.isolation < 0.2)
+        ]
+        cutflow['at least 4 good muons'] += ak.sum(ak.num(muons) >= 4)
+        h_nMuons.fill(dataset=dataset, nMuons=ak.num(muons))
+
+        # reduce first axis: skip events without enough muons
+        muons = muons[ak.num(muons) >= 4]
+
+        # find all candidates with helper function
+        fourmuon = find_4lep(muons, ak.ArrayBuilder()).snapshot()
+        if ak.all(ak.num(fourmuon) == 0):
+            # skip processing as it is an EmptyArray
+            return {
+                'nMuons': h_nMuons,
+                'cutflow': {dataset: cutflow},
+            }
+        fourmuon = [muons[fourmuon[idx]] for idx in "0123"]
+        fourmuon = ak.zip({
+            "z1": ak.zip({
+                "lep1": fourmuon[0],
+                "lep2": fourmuon[1],
+                "p4": fourmuon[0] + fourmuon[1],
+            }),
+            "z2": ak.zip({
+                "lep1": fourmuon[2],
+                "lep2": fourmuon[3],
+                "p4": fourmuon[2] + fourmuon[3],
+            }),
+        })
+
+        cutflow['at least one candidate'] += ak.sum(ak.num(fourmuon) > 0)
+
+        # require minimum dimuon mass
+        fourmuon = fourmuon[(fourmuon.z1.p4.mass > 60.) & (fourmuon.z2.p4.mass > 20.)]
+        cutflow['minimum dimuon mass'] += ak.sum(ak.num(fourmuon) > 0)
+
+        # choose permutation with z1 mass closest to nominal Z boson mass
+        bestz1 = ak.singletons(ak.argmin(abs(fourmuon.z1.p4.mass - 91.1876), axis=1))
+        fourmuon = ak.flatten(fourmuon[bestz1])
+
+        h_m4mu.fill(
+            dataset=dataset,
+            mass=(fourmuon.z1.p4 + fourmuon.z2.p4).mass,
+        )
+        h_mZ1.fill(
+            dataset=dataset,
+            mass=fourmuon.z1.p4.mass,
+        )
+        h_mZ2.fill(
+            dataset=dataset,
+            mass=fourmuon.z2.p4.mass,
+        )
+        h_ptZ1mu1.fill(
+            dataset=dataset,
+            pt=fourmuon.z1.lep1.pt,
+        )
+        h_ptZ1mu2.fill(
+            dataset=dataset,
+            pt=fourmuon.z1.lep2.pt,
+        )
+        return {
+            'nMuons': h_nMuons,
+            'mass': h_m4mu,
+            'mass_z1': h_mZ1,
+            'mass_z2': h_mZ2,
+            'pt_z1_mu1': h_ptZ1mu1,
+            'pt_z1_mu2': h_ptZ1mu2,
+            'cutflow': {dataset: cutflow},
+        }
+
+    def postprocess(self, accumulator):
+        pass
+
+
+
+
+
[9]:
+
+
+
import time
+
+tstart = time.time()
+
+fileset = {
+    'DoubleMuon': [
+        'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root',
+        'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012C_DoubleMuParked.root',
+    ],
+    'ZZ to 4mu': [
+        'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/ZZTo4mu.root'
+    ]
+}
+
+
+run = processor.Runner(
+    executor = processor.FuturesExecutor(compression=None, workers=4),
+    schema=BaseSchema,
+    chunksize=100_000,
+    # maxchunks=10,  # total 676 chunks
+)
+
+output = run(
+    fileset,
+    "Events",
+    processor_instance=FancyDimuonProcessor(),
+)
+
+elapsed = time.time() - tstart
+print(output)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{'nMuons': Hist(
+  StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),
+  IntCategory([0, 1, 2, 3, 4, 5], name='nMuons', label='Number of good muons'),
+  storage=Weight()) # Sum: WeightedSum(value=6.76277e+07, variance=6.76277e+07) (WeightedSum(value=6.76279e+07, variance=6.76279e+07) with flow), 'mass': Hist(
+  StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),
+  Regular(300, 0, 300, name='mass', label='$m_{\\mu\\mu}$ [GeV]'),
+  storage=Weight()) # Sum: WeightedSum(value=65472, variance=65472) (WeightedSum(value=82352, variance=82352) with flow), 'mass_z1': Hist(
+  StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),
+  Regular(300, 0, 300, name='mass', label='$m_{\\mu\\mu}$ [GeV]'),
+  storage=Weight()) # Sum: WeightedSum(value=82303, variance=82303) (WeightedSum(value=82352, variance=82352) with flow), 'mass_z2': Hist(
+  StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),
+  Regular(300, 0, 300, name='mass', label='$m_{\\mu\\mu}$ [GeV]'),
+  storage=Weight()) # Sum: WeightedSum(value=81873, variance=81873) (WeightedSum(value=82352, variance=82352) with flow), 'pt_z1_mu1': Hist(
+  StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),
+  Regular(300, 0, 300, name='pt', label='$p_{T,\\mu}$ [GeV]'),
+  storage=Weight()) # Sum: WeightedSum(value=82351, variance=82351) (WeightedSum(value=82352, variance=82352) with flow), 'pt_z1_mu2': Hist(
+  StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),
+  Regular(300, 0, 300, name='pt', label='$p_{T,\\mu}$ [GeV]'),
+  storage=Weight()) # Sum: WeightedSum(value=82170, variance=82170) (WeightedSum(value=82352, variance=82352) with flow), 'cutflow': {'ZZ to 4mu': defaultdict(<class 'int'>, {'all events': 1499064, 'at least 4 good muons': 143618, 'at least one candidate': 143055, 'minimum dimuon mass': 81867}), 'DoubleMuon': defaultdict(<class 'int'>, {'all events': 66128870, 'at least 4 good muons': 8289, 'at least one candidate': 3849, 'minimum dimuon mass': 485})}}
+
+
+
+
[10]:
+
+
+
nevt = output['cutflow']['ZZ to 4mu']['all events'] + output['cutflow']['DoubleMuon']['all events']
+print("Events/s:", nevt / elapsed)
+
+
+
+
+
+
+
+
+Events/s: 153664.49672142894
+
+
+

What follows is just us looking at the output, you can execute it if you wish

+
+
[11]:
+
+
+
# scale ZZ simulation to expected yield
+lumi = 11.6  # 1/fb
+zzxs = 7200 * 0.0336**2  # approximate 8 TeV ZZ(4mu)
+nzz = output['cutflow']['ZZ to 4mu']['all events']
+
+scaled = {}
+for name, h in output.items():
+    if isinstance(h, hist.Hist):
+        scaled[name] = h.copy()
+        scaled[name].view()[0, :] *= lumi * zzxs / nzz
+
+
+
+
+
[12]:
+
+
+
fig, ax = plt.subplots()
+scaled['nMuons'].plot1d(ax=ax, overlay='dataset')
+ax.set_yscale('log')
+ax.set_ylim(1, None)
+
+
+
+
+
[12]:
+
+
+
+
+(1, 122819923.5463199)
+
+
+
+
+
+
+../_images/notebooks_processor_17_1.png +
+
+
+
[13]:
+
+
+
fig, ax = plt.subplots()
+
+scaled['mass'][:, ::hist.rebin(4)].plot1d(ax=ax, overlay='dataset');
+
+
+
+
+
+
+
+../_images/notebooks_processor_18_0.png +
+
+
+
[14]:
+
+
+
fig, ax = plt.subplots()
+
+scaled['mass_z1'].plot1d(ax=ax, overlay='dataset');
+
+
+
+
+
+
+
+../_images/notebooks_processor_19_0.png +
+
+
+
[15]:
+
+
+
fig, ax = plt.subplots()
+
+scaled['mass_z2'].plot1d(ax=ax, overlay='dataset')
+ax.set_xlim(2, 300)
+# ax.set_xscale('log')
+
+
+
+
+
[15]:
+
+
+
+
+(2.0, 300.0)
+
+
+
+
+
+
+../_images/notebooks_processor_20_1.png +
+
+
+
[16]:
+
+
+
fig, ax = plt.subplots()
+
+scaled['pt_z1_mu1'].plot1d(ax=ax, overlay='dataset');
+
+
+
+
+
+
+
+../_images/notebooks_processor_21_0.png +
+
+
+
[17]:
+
+
+
fig, ax = plt.subplots()
+
+scaled['pt_z1_mu2'].plot1d(ax=ax, overlay='dataset');
+
+
+
+
+
+
+
+../_images/notebooks_processor_22_0.png +
+
+
+
[ ]:
+
+
+

+
+
+
+
+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/notebooks/processor.ipynb b/notebooks/processor.ipynb new file mode 100644 index 000000000..92a2e0ce9 --- /dev/null +++ b/notebooks/processor.ipynb @@ -0,0 +1,947 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Coffea Processors\n", + "This is a rendered copy of [processor.ipynb](https://github.com/CoffeaTeam/coffea/blob/master/binder/processor.ipynb). You can optionally run it interactively on [binder at this link](https://mybinder.org/v2/gh/coffeateam/coffea/master?filepath=binder%2Fprocessor.ipynb)\n", + "\n", + "Coffea relies mainly on [uproot](https://github.com/scikit-hep/uproot) to provide access to ROOT files for analysis.\n", + "As a usual analysis will involve processing tens to thousands of files, totalling gigabytes to terabytes of data, there is a certain amount of work to be done to build a parallelized framework to process the data in a reasonable amount of time. Of course, one can work directly within uproot to achieve this, as we'll show in the beginning, but coffea provides the `coffea.processor` module, which allows users to worry just about the actual analysis code and not about how to implement efficient parallelization, assuming that the parallization is a trivial map-reduce operation (e.g. filling histograms and adding them together). The module provides the following key features:\n", + "\n", + " * A `ProcessorABC` abstract base class that can be derived from to implement the analysis code;\n", + " * A [NanoEvents](https://coffeateam.github.io/coffea/notebooks/nanoevents.html) interface to the arrays being read from the TTree as inputs;\n", + " * A generic `accumulate()` utility to reduce the outputs to a single result, as showin in the accumulators notebook tutorial; and\n", + " * A set of parallel executors to access multicore processing or distributed computing systems such as [Dask](https://distributed.dask.org/en/latest/), [Parsl](http://parsl-project.org/), [Spark](https://spark.apache.org/), [WorkQueue](https://cctools.readthedocs.io/en/latest/work_queue/), and others.\n", + "\n", + "Let's start by writing a simple processor class that reads some CMS open data and plots a dimuon mass spectrum.\n", + "We'll start by copying the [ProcessorABC](https://coffeateam.github.io/coffea/api/coffea.processor.ProcessorABC.html#coffea.processor.ProcessorABC) skeleton and filling in some details:\n", + "\n", + " * Remove `flag`, as we won't use it\n", + " * Adding a new histogram for $m_{\\mu \\mu}$\n", + " * Building a [Candidate](https://coffeateam.github.io/coffea/api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate.html#coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate) record for muons, since we will read it with `BaseSchema` interpretation (the files used here could be read with `NanoAODSchema` but we want to show how to build vector objects from other TTree formats) \n", + " * Calculating the dimuon invariant mass" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import awkward as ak\n", + "from coffea import processor\n", + "from coffea.nanoevents.methods import candidate\n", + "import hist\n", + "\n", + "class MyProcessor(processor.ProcessorABC):\n", + " def __init__(self):\n", + " pass\n", + "\n", + " def process(self, events):\n", + " dataset = events.metadata['dataset']\n", + " muons = ak.zip(\n", + " {\n", + " \"pt\": events.Muon_pt,\n", + " \"eta\": events.Muon_eta,\n", + " \"phi\": events.Muon_phi,\n", + " \"mass\": events.Muon_mass,\n", + " \"charge\": events.Muon_charge,\n", + " },\n", + " with_name=\"PtEtaPhiMCandidate\",\n", + " behavior=candidate.behavior,\n", + " )\n", + "\n", + " h_mass = (\n", + " hist.Hist.new\n", + " .StrCat([\"opposite\", \"same\"], name=\"sign\")\n", + " .Log(1000, 0.2, 200., name=\"mass\", label=\"$m_{\\mu\\mu}$ [GeV]\")\n", + " .Int64()\n", + " )\n", + "\n", + " cut = (ak.num(muons) == 2) & (ak.sum(muons.charge, axis=1) == 0)\n", + " # add first and second muon in every event together\n", + " dimuon = muons[cut][:, 0] + muons[cut][:, 1]\n", + " h_mass.fill(sign=\"opposite\", mass=dimuon.mass)\n", + "\n", + " cut = (ak.num(muons) == 2) & (ak.sum(muons.charge, axis=1) != 0)\n", + " dimuon = muons[cut][:, 0] + muons[cut][:, 1]\n", + " h_mass.fill(sign=\"same\", mass=dimuon.mass)\n", + "\n", + " return {\n", + " dataset: {\n", + " \"entries\": len(events),\n", + " \"mass\": h_mass,\n", + " }\n", + " }\n", + "\n", + " def postprocess(self, accumulator):\n", + " pass" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If we were to just use bare uproot to execute this processor, we could do that with the following example, which:\n", + "\n", + " * Opens a CMS open data file\n", + " * Creates a NanoEvents object using `BaseSchema` (roughly equivalent to the output of `uproot.lazy`)\n", + " * Creates a `MyProcessor` instance\n", + " * Runs the `process()` function, which returns our accumulators\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{'DoubleMuon': {'entries': 10000,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 4939.0 (4951.0 with flow)}}" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import uproot\n", + "from coffea.nanoevents import NanoEventsFactory, BaseSchema\n", + "\n", + "filename = \"root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root\"\n", + "file = uproot.open(filename)\n", + "events = NanoEventsFactory.from_root(\n", + " file,\n", + " entry_stop=10000,\n", + " metadata={\"dataset\": \"DoubleMuon\"},\n", + " schemaclass=BaseSchema,\n", + ").events()\n", + "p = MyProcessor()\n", + "out = p.process(events)\n", + "out" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAEPCAYAAAC5sYRSAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAAsDElEQVR4nO3de5hU5Znv/e/d1Seag8rJoBAaZxQFGohpQJQQdphtzKuJqImSiQ6eYsyWxODWiBkjnZgxvpm8OfDqRHGMshO3kHhITHR0J86QaIJIE4kKeIgIQkRogUBDH6vq3n/Uoau7q89dXV2rfp/r6qtrne+1Vvddz3rWs55l7o6IiARLQbYDEBGR/qfkLiISQEruIiIBpOQuIhJASu4iIgGk5C4iEkCF2Q4AYPTo0V5eXp7tMEREcsqmTZved/cx6aYNiuReXl5OdXV1tsMQEckpZrazo2mqlhERCSAldxGRAFJyFxEJoC7r3M3sx8B5wD53nxYfNxJYC5QDO4CL3f1gfNotwFVABPiyuz/Tm8Cam5vZvXs3DQ0NvVlc2igtLWX8+PEUFRVlOxQRGQDduaH6IHAX8L9Sxi0HnnX3O81seXz4ZjObAiwGpgInAL81s1PcPdLTwHbv3s3w4cMpLy/HzHq6uKRwd/bv38/u3buZNGlStsMRkQHQZbWMu/8eONBm9PnA6vjn1cCilPFr3L3R3d8G/gLM7k1gDQ0NjBo1Som9H5gZo0aN0lWQSB7pbZ378e6+ByD+e2x8/InArpT5dsfH9YoSe//RsRTJL/19QzVdBknbYbyZXWNm1WZWXVNT062Vh0IhZs6cydSpU5kxYwbf+973iEajAFRXV/PlL3+514FnWlVVFd/97nezHYaI5InePsS018zGufseMxsH7IuP3w1MSJlvPPBuuhW4+ypgFUBlZWW33hgyZMgQNm/eDMC+ffv4x3/8Rw4dOsQ3vvENKisrqays7N3e5IBIJEIoFMp2GCKSI3pbcn8CWBL/vAT4Zcr4xWZWYmaTgJOBF/sWYnpjx45l1apV3HXXXbg769at47zzzgNipeQlS5Zw9tlnU15ezmOPPcZXv/pVKioqOOecc2hubgZiT8a+//77QKzkv2DBAgAOHDjAokWLmD59OmeccQYvv/xycr1XXnklCxYs4KSTTmLlypVpY3v66ac5/fTTmTFjBgsXLkyO37p1a9plFy1axIc//GGmTp3KqlWrkuOHDRvGbbfdxpw5c1i/fj33338/p5xyCgsWLODzn/88S5cuBaCmpoaLLrqIWbNmMWvWLP7whz/001EWCZ5L7l3PJfeuz3YYmefunf4ADwN7gGZiJfOrgFHAs8Cb8d8jU+b/Z+At4HXgE12t39358Ic/7G1t3bq13bihQ4e2G3fsscf6e++95//1X//l5557rru7r1ixws866yxvamryzZs3+5AhQ/ypp55yd/dFixb5448/7u7uEydO9JqaGnd337hxo3/0ox91d/elS5d6VVWVu7s/++yzPmPGjOR6586d6w0NDV5TU+MjR470pqamVvHs27fPx48f79u3b3d39/3793e5bGKeuro6nzp1qr///vvusYPpa9eudXf3v/71rz5x4kTfv3+/NzU1+bx58/y6665zd/fPfvaz/txzz7m7+86dO/3UU09td5w6OqYi+ebie/7oF9/zx2yH0S+Aau8gr3ZZLePun+1g0sJ0I939X4B/6f7XS994B++A/cQnPkFRUREVFRVEIhHOOeccACoqKtixY0en63z++ed59NFHAfjYxz7G/v37OXToEADnnnsuJSUllJSUMHbsWPbu3cv48eOTy77wwgvMnz8/2eRw5MiRyWkdLbty5Uoef/xxAHbt2sWbb77JqFGjCIVCXHTRRQC8+OKLfPSjH02u7zOf+QxvvPEGAL/97W/ZunVrcjuHDx+mtraW4cOHd+8gikjgDIqOw3pr+/bthEIhxo4dy7Zt21pNKykpAaCgoICioqJka5GCggLC4TAAhYWFyRuyqc0E031hJJZPrBdiN3gT60pdtqOWKemWXbduHb/97W9Zv349ZWVlLFiwIBlLaWlpsp69oy8xgGg0yvr16xkyZEiH84hIfsnZ7gdqamq49tprWbp0aa+b+ZWXl7Np0yaAZEkdYP78+Tz00EMArFu3jtGjRzNixIhurXPu3Ln87ne/4+233wZi9fedOXToEMcddxxlZWW89tprvPDCC2nnmz17Nr/73e84ePAg4XC4Vbxnn302d911V3I4cdNZRNrbuucwW/ccznYYGZdTJff6+npmzpxJc3MzhYWFXHbZZdxwww29Xt+KFSu46qqruOOOO5gzZ05yfFVVFVdccQXTp0+nrKyM1atXd7KW1saMGcOqVau48MILiUajjB07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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "fig, ax = plt.subplots()\n", + "out[\"DoubleMuon\"][\"mass\"].plot1d(ax=ax)\n", + "ax.set_xscale(\"log\")\n", + "ax.legend(title=\"Dimuon charge\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "One could expand on this code to run over several chunks of the file, setting `entry_start` and `entry_stop` as appropriate. Then, several datasets could be processed by iterating over several files. However, the processor [Runner](https://coffeateam.github.io/coffea/api/coffea.processor.Runner.html) can help with this! One lists the datasets and corresponding files, the processor they want to run, and which executor they want to use. Available executors derive from `ExecutorBase` and are listed [here](https://coffeateam.github.io/coffea/modules/coffea.processor.html#classes). Since these files are very large, we limit to just reading the first few chunks of events from each dataset with `maxchunks`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "e4fb80c50d72479a8b3906c885982cd4", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n",
+       "
\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "17b53a251fbb4038896bcd937ea8a2dc", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
/opt/conda/lib/python3.8/site-packages/awkward/_connect/_numpy.py:195: RuntimeWarning: \n",
+       "invalid value encountered in sqrt\n",
+       "  result = getattr(ufunc, method)(\n",
+       "
\n" + ], + "text/plain": [ + "/opt/conda/lib/python3.8/site-packages/awkward/_connect/_numpy.py:195: RuntimeWarning: \n", + "invalid value encountered in sqrt\n", + " result = getattr(ufunc, method)(\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n",
+       "
\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "{'ZZ to 4mu': {'entries': 999380,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 192074.0 (192500.0 with flow)},\n", + " 'DoubleMuon': {'entries': 1000560,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 519403.0 (520002.0 with flow)}}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fileset = {\n", + " 'DoubleMuon': [\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root',\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012C_DoubleMuParked.root',\n", + " ],\n", + " 'ZZ to 4mu': [\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/ZZTo4mu.root'\n", + " ]\n", + "}\n", + "\n", + "iterative_run = processor.Runner(\n", + " executor = processor.IterativeExecutor(compression=None),\n", + " schema=BaseSchema,\n", + " maxchunks=10,\n", + ")\n", + "\n", + "out = iterative_run(\n", + " fileset,\n", + " treename=\"Events\",\n", + " processor_instance=MyProcessor(),\n", + ")\n", + "out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Now, if we want to use more than a single core on our machine, we simply change [IterativeExecutor](https://coffeateam.github.io/coffea/api/coffea.processor.IterativeExecutor.html) for [FuturesExecutor](https://coffeateam.github.io/coffea/api/coffea.processor.FuturesExecutor.html), which uses the python [concurrent.futures](https://docs.python.org/3/library/concurrent.futures.html) standard library. We can then set the most interesting argument to the `FuturesExecutor`: the number of cores to use (2):" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "5448fcf953e3448e9fc80882b54a26aa", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n",
+       "
\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "{'ZZ to 4mu': {'entries': 999380,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 192074.0 (192500.0 with flow)},\n", + " 'DoubleMuon': {'entries': 1000560,\n", + " 'mass': Hist(\n", + " StrCategory(['opposite', 'same'], name='sign', label='sign'),\n", + " Regular(1000, 0.2, 200, transform=log, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Int64()) # Sum: 519403.0 (520002.0 with flow)}}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "futures_run = processor.Runner(\n", + " executor = processor.FuturesExecutor(compression=None, workers=2),\n", + " schema=BaseSchema,\n", + " maxchunks=10,\n", + ")\n", + "\n", + "out = futures_run(\n", + " fileset,\n", + " \"Events\",\n", + " processor_instance=MyProcessor()\n", + ")\n", + "out" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Hopefully this ran faster than the previous cell, but that may depend on how many cores are available on the machine you are running this notebook and your connection to `eospublic.cern.ch`. At least the output will be prettier now:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlwAAAF7CAYAAAAHXVWjAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAABFZklEQVR4nO3deXxU1cH/8c/JvoeEJCwJEHbZUcIiIFBRoHXBvdaquFSrldra2qp9fNxauz2trfxcqK1b1borLrhUEBSVxYAssu9JCJCQkJ3s5/fHHUICSUhIbibJfN+vV16ZOXPunTPhMvOdc84911hrERERERH3+Hm7ASIiIiKdnQKXiIiIiMsUuERERERcpsAlIiIi4jIFLhERERGXBXi7AScTFxdnk5OTvd0MERERkZNavXr1IWtt/PHl7T5wJScnk5qa6u1miIiIiJyUMWZvfeUaUhQRERFxmQKXiIiIiMsUuERERERc1u7ncImIiEjLVVRUkJGRQWlpqbeb0imEhISQlJREYGBgk+orcImIiPiAjIwMIiMjSU5Oxhjj7eZ0aNZacnJyyMjIoG/fvk3aRkOKIiIiPqC0tJSuXbsqbLUCYwxdu3ZtVm+hApeIiIiPUNhqPc39WypwiYiIiLhMgUtERMRH+fv7M3r0aIYNG8aoUaN45JFHqK6uBiA1NZXbb7/dyy1s2AMPPMBf/vIXbzejyTRpXkRExEeFhoaydu1aALKysrjqqqvIz8/nwQcfJCUlhZSUFO820EVVVVX4+/u32fOph0tERERISEjgqaee4rHHHsNay9KlSzn//PMBpzdpzpw5zJgxg+TkZN566y1+/etfM2LECGbNmkVFRQXgXI7v0KFDgNNDNm3aNAByc3O56KKLGDlyJBMmTGD9+vU1+73hhhuYNm0a/fr1Y968efW27aOPPuKMM85g1KhRTJ8+vaZ806ZN9W570UUXMWbMGIYNG8ZTTz1VUx4REcF9993H+PHjWb58OU8//TSDBg1i2rRp3HTTTcydOxeA7OxsLr30UsaOHcvYsWP58ssvW/z3VQ+XiIiIANCvXz+qq6vJyso64bGdO3eyZMkSNm3axJlnnsmbb77Jn//8Zy6++GIWLlzIRRdd1OB+77//fk4//XQWLFjAp59+yrXXXlvTs7ZlyxaWLFlCYWEhgwcP5tZbb62ztlV2djY33XQTn3/+OX379iU3N7fmsYa2feaZZ4iNjeXIkSOMHTuWSy+9lK5du1JcXMzw4cN56KGHyMzM5Oqrr2bNmjVERkZy9tlnM2rUKAB+9rOfcccddzB58mTS0tKYOXMmmzdvbtHfVoFLREREalhr6y3/7ne/S2BgICNGjKCqqopZs2YBMGLECPbs2dPoPr/44gvefPNNAM4++2xycnLIz88H4LzzziM4OJjg4GASEhI4ePAgSUlJNduuWLGCKVOm1Kx3FRsbW/NYQ9vOmzePt99+G4D09HS2b99O165d8ff359JLLwVg1apVTJ06tWZ/l19+Odu2bQNg0aJFbNq0qeZ5CgoKKCwsJDIysml/xHoocIlIo37x2lp2ZRfzl8tHMSAhwtvNEREX7dq1C39/fxISEk7o0QkODgbAz8+PwMDAmmUR/Pz8qKysBCAgIKBm0n3tNarqC3FHtz+6X3Am8R/dV+1tG1qCob5tly5dyqJFi1i+fDlhYWFMmzatpi0hISE187YaCpYA1dXVLF++nNDQ0AbrNJfmcIlIo95as4+16XkcKa/ydlNExEXZ2dnccsstzJ0795TX60pOTmb16tUANT1aAFOmTOGll14CYOnSpcTFxREVFdWkfZ555pl89tln7N69G6DOkGJ98vPziYmJISwsjC1btrBixYp6640bN47PPvuMw4cPU1lZWae9M2bM4LHHHqu5f3T4syXUwyUiIuKjjhw5wujRo6moqCAgIIBrrrmGX/ziF6e8v/vvv58bb7yR3//+94wfP76m/IEHHuD6669n5MiRhIWF8fzzzzd5n/Hx8Tz11FNccsklVFdXk5CQwCeffNJg/VmzZjF//nxGjhzJ4MGDmTBhQr31EhMT+c1vfsP48ePp2bMnQ4cOJTo6GoB58+Zx2223MXLkSCorK5kyZQrz589vcpvrYxrrUmsPUlJSbGpqqrebIeKzku9eCMB7cyczIinay60RkVO1efNmhgwZ4u1mtCtFRUVERERQWVnJxRdfzA033MDFF1/c5O3r+5saY1Zba09YT0NDiiIiIuKTHnjgAUaPHs3w4cPp27dvo2datpSGFEVERMQnteVK9erhEhEREXGZApeIiIiIyxS4RERERFymwCUiIiLiMgUuERER8QmpqancfvvtgLMA61dffdVmz62zFEVERMQnpKSkkJLiLJG1dOlSIiIimDhxYps8t3q4RERExCseeeQRhg8fzvDhw/n73//Onj17OO2005gzZw4jR47ksssuo6SkBHAuG3TXXXcxbtw4xo0bx44dOwDYu3cv06dPZ+TIkUyfPp20tDQAXn/9dYYPH86oUaOYMmUK4ISs888/nz179jB//nz+9re/MXr0aJYtW0Z2djaXXnopY8eOZezYsXz55Zet+lrVwyUiIuLDHnxvI5syC1p1n0N7RnH/BcMarbN69WqeffZZVq5cibWW8ePHM3XqVLZu3crTTz/NpEmTuOGGG3jiiSe48847AYiKimLVqlX8+9//5uc//znvv/8+c+fO5dprr2XOnDk888wz3H777SxYsICHHnqIjz/+mMTERPLy8uo8d3JyMrfccgsRERE1+77qqqu44447mDx5MmlpacycOfOEC3i3hHq4REREpM198cUXXHzxxYSHhxMREcEll1zCsmXL6NWrF5MmTQLg6quv5osvvqjZ5gc/+EHN7+XLlwOwfPlyrrrqKgCuueaamvqTJk3iuuuu45///CdVVVUnbc+iRYuYO3cuo0eP5sILL6SgoIDCwsJWe73q4RIREfFhJ+uJcktD13I2xjR4v6Hb9dWfP38+K1euZOHChYwePZq1a9c22p7q6mqWL19OaGhoU5rfbOrhEhERkTY3ZcoUFixYQElJCcXFxbz99tucddZZpKWl1fRevfzyy0yePLlmm1dffbXm95lnngnAxIkTeeWVVwB46aWXaurv3LmT8ePH89BDDxEXF0d6enqd54+MjKzTgzVjxgwee+yxmvsnC2jNpcAlIiIibe6MM87guuuuY9y4cYwfP54f/ehHxMTEMGTIEJ5//nlGjhxJbm4ut956a802ZWVljB8/nkcffZS//e1vAMybN49nn32WkSNH8sILL/Doo48C8Ktf/YoRI0YwfPhwpkyZwqhRo+o8/wUXXMDbb79dM2l+3rx5pKamMnLkSIYOHcr8+fNb9fWahrr02ouUlBSbmprq7WaI+KzkuxcC8N7cyYxIivZya0TkVG3evJkhQ4Z4uxmN2rNnD+effz7ffvvtCY8lJyeTmppKXFycF1pWv/r+psaY1dbalOPrqodLRERExGWaNC8iIiLtQnJycr29W+D0fnVk6uESERERcZkCl4iIiIjLFLhEREREXKbAJSIiIuIyBS4RERERlylwiYiIiLhMgUtERETa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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots(figsize=(10, 6))\n", + "out[\"DoubleMuon\"][\"mass\"].plot1d(ax=ax)\n", + "ax.set_xscale(\"log\")\n", + "ax.legend(title=\"Dimuon charge\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Getting fancy\n", + "Let's flesh out this analysis into a 4-muon analysis, searching for diboson events:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "from collections import defaultdict\n", + "import numba\n", + "\n", + "\n", + "@numba.njit\n", + "def find_4lep(events_leptons, builder):\n", + " \"\"\"Search for valid 4-lepton combinations from an array of events * leptons {charge, ...}\n", + " \n", + " A valid candidate has two pairs of leptons that each have balanced charge\n", + " Outputs an array of events * candidates {indices 0..3} corresponding to all valid\n", + " permutations of all valid combinations of unique leptons in each event\n", + " (omitting permutations of the pairs)\n", + " \"\"\"\n", + " for leptons in events_leptons:\n", + " builder.begin_list()\n", + " nlep = len(leptons)\n", + " for i0 in range(nlep):\n", + " for i1 in range(i0 + 1, nlep):\n", + " if leptons[i0].charge + leptons[i1].charge != 0:\n", + " continue\n", + " for i2 in range(nlep):\n", + " for i3 in range(i2 + 1, nlep):\n", + " if len({i0, i1, i2, i3}) < 4:\n", + " continue\n", + " if leptons[i2].charge + leptons[i3].charge != 0:\n", + " continue\n", + " builder.begin_tuple(4)\n", + " builder.index(0).integer(i0)\n", + " builder.index(1).integer(i1)\n", + " builder.index(2).integer(i2)\n", + " builder.index(3).integer(i3)\n", + " builder.end_tuple()\n", + " builder.end_list()\n", + "\n", + " return builder\n", + "\n", + "\n", + "class FancyDimuonProcessor(processor.ProcessorABC):\n", + " def process(self, events):\n", + " dataset_axis = hist.axis.StrCategory([], growth=True, name=\"dataset\", label=\"Primary dataset\")\n", + " mass_axis = hist.axis.Regular(300, 0, 300, name=\"mass\", label=r\"$m_{\\mu\\mu}$ [GeV]\")\n", + " pt_axis = hist.axis.Regular(300, 0, 300, name=\"pt\", label=r\"$p_{T,\\mu}$ [GeV]\")\n", + " \n", + " h_nMuons = hist.Hist(\n", + " dataset_axis,\n", + " hist.axis.IntCategory(range(6), name=\"nMuons\", label=\"Number of good muons\"),\n", + " storage=\"weight\", label=\"Counts\",\n", + " )\n", + " h_m4mu = hist.Hist(dataset_axis, mass_axis, storage=\"weight\", label=\"Counts\")\n", + " h_mZ1 = hist.Hist(dataset_axis, mass_axis, storage=\"weight\", label=\"Counts\")\n", + " h_mZ2 = hist.Hist(dataset_axis, mass_axis, storage=\"weight\", label=\"Counts\")\n", + " h_ptZ1mu1 = hist.Hist(dataset_axis, pt_axis, storage=\"weight\", label=\"Counts\")\n", + " h_ptZ1mu2 = hist.Hist(dataset_axis, pt_axis, storage=\"weight\", label=\"Counts\")\n", + " \n", + " cutflow = defaultdict(int)\n", + " \n", + " dataset = events.metadata['dataset']\n", + " muons = ak.zip({\n", + " \"pt\": events.Muon_pt,\n", + " \"eta\": events.Muon_eta,\n", + " \"phi\": events.Muon_phi,\n", + " \"mass\": events.Muon_mass,\n", + " \"charge\": events.Muon_charge,\n", + " \"softId\": events.Muon_softId,\n", + " \"isolation\": events.Muon_pfRelIso03_all,\n", + " }, with_name=\"PtEtaPhiMCandidate\", behavior=candidate.behavior)\n", + " \n", + " # make sure they are sorted by transverse momentum\n", + " muons = muons[ak.argsort(muons.pt, axis=1)]\n", + " \n", + " cutflow['all events'] += len(muons)\n", + " \n", + " # impose some quality and minimum pt cuts on the muons\n", + " muons = muons[\n", + " muons.softId\n", + " & (muons.pt > 5)\n", + " & (muons.isolation < 0.2)\n", + " ]\n", + " cutflow['at least 4 good muons'] += ak.sum(ak.num(muons) >= 4)\n", + " h_nMuons.fill(dataset=dataset, nMuons=ak.num(muons))\n", + " \n", + " # reduce first axis: skip events without enough muons\n", + " muons = muons[ak.num(muons) >= 4]\n", + " \n", + " # find all candidates with helper function\n", + " fourmuon = find_4lep(muons, ak.ArrayBuilder()).snapshot()\n", + " if ak.all(ak.num(fourmuon) == 0):\n", + " # skip processing as it is an EmptyArray\n", + " return {\n", + " 'nMuons': h_nMuons,\n", + " 'cutflow': {dataset: cutflow},\n", + " }\n", + " fourmuon = [muons[fourmuon[idx]] for idx in \"0123\"]\n", + " fourmuon = ak.zip({\n", + " \"z1\": ak.zip({\n", + " \"lep1\": fourmuon[0],\n", + " \"lep2\": fourmuon[1],\n", + " \"p4\": fourmuon[0] + fourmuon[1],\n", + " }),\n", + " \"z2\": ak.zip({\n", + " \"lep1\": fourmuon[2],\n", + " \"lep2\": fourmuon[3],\n", + " \"p4\": fourmuon[2] + fourmuon[3],\n", + " }),\n", + " })\n", + " \n", + " cutflow['at least one candidate'] += ak.sum(ak.num(fourmuon) > 0)\n", + " \n", + " # require minimum dimuon mass\n", + " fourmuon = fourmuon[(fourmuon.z1.p4.mass > 60.) & (fourmuon.z2.p4.mass > 20.)]\n", + " cutflow['minimum dimuon mass'] += ak.sum(ak.num(fourmuon) > 0)\n", + " \n", + " # choose permutation with z1 mass closest to nominal Z boson mass\n", + " bestz1 = ak.singletons(ak.argmin(abs(fourmuon.z1.p4.mass - 91.1876), axis=1))\n", + " fourmuon = ak.flatten(fourmuon[bestz1])\n", + " \n", + " h_m4mu.fill(\n", + " dataset=dataset,\n", + " mass=(fourmuon.z1.p4 + fourmuon.z2.p4).mass,\n", + " )\n", + " h_mZ1.fill(\n", + " dataset=dataset, \n", + " mass=fourmuon.z1.p4.mass,\n", + " )\n", + " h_mZ2.fill(\n", + " dataset=dataset, \n", + " mass=fourmuon.z2.p4.mass,\n", + " )\n", + " h_ptZ1mu1.fill(\n", + " dataset=dataset,\n", + " pt=fourmuon.z1.lep1.pt,\n", + " )\n", + " h_ptZ1mu2.fill(\n", + " dataset=dataset,\n", + " pt=fourmuon.z1.lep2.pt,\n", + " )\n", + " return {\n", + " 'nMuons': h_nMuons,\n", + " 'mass': h_m4mu,\n", + " 'mass_z1': h_mZ1,\n", + " 'mass_z2': h_mZ2,\n", + " 'pt_z1_mu1': h_ptZ1mu1,\n", + " 'pt_z1_mu2': h_ptZ1mu2,\n", + " 'cutflow': {dataset: cutflow},\n", + " }\n", + "\n", + " def postprocess(self, accumulator):\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "6f0938c279944980a1e4fd122f54d690", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "Output()" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
\n"
+      ],
+      "text/plain": []
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "text/html": [
+       "
\n",
+       "
\n" + ], + "text/plain": [ + "\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{'nMuons': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " IntCategory([0, 1, 2, 3, 4, 5], name='nMuons', label='Number of good muons'),\n", + " storage=Weight()) # Sum: WeightedSum(value=6.76277e+07, variance=6.76277e+07) (WeightedSum(value=6.76279e+07, variance=6.76279e+07) with flow), 'mass': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=65472, variance=65472) (WeightedSum(value=82352, variance=82352) with flow), 'mass_z1': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=82303, variance=82303) (WeightedSum(value=82352, variance=82352) with flow), 'mass_z2': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='mass', label='$m_{\\\\mu\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=81873, variance=81873) (WeightedSum(value=82352, variance=82352) with flow), 'pt_z1_mu1': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='pt', label='$p_{T,\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=82351, variance=82351) (WeightedSum(value=82352, variance=82352) with flow), 'pt_z1_mu2': Hist(\n", + " StrCategory(['ZZ to 4mu', 'DoubleMuon'], growth=True, name='dataset', label='Primary dataset'),\n", + " Regular(300, 0, 300, name='pt', label='$p_{T,\\\\mu}$ [GeV]'),\n", + " storage=Weight()) # Sum: WeightedSum(value=82170, variance=82170) (WeightedSum(value=82352, variance=82352) with flow), 'cutflow': {'ZZ to 4mu': defaultdict(, {'all events': 1499064, 'at least 4 good muons': 143618, 'at least one candidate': 143055, 'minimum dimuon mass': 81867}), 'DoubleMuon': defaultdict(, {'all events': 66128870, 'at least 4 good muons': 8289, 'at least one candidate': 3849, 'minimum dimuon mass': 485})}}\n" + ] + } + ], + "source": [ + "import time\n", + "\n", + "tstart = time.time() \n", + "\n", + "fileset = {\n", + " 'DoubleMuon': [\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root',\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012C_DoubleMuParked.root',\n", + " ],\n", + " 'ZZ to 4mu': [\n", + " 'root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/ZZTo4mu.root'\n", + " ]\n", + "}\n", + "\n", + "\n", + "run = processor.Runner(\n", + " executor = processor.FuturesExecutor(compression=None, workers=4),\n", + " schema=BaseSchema,\n", + " chunksize=100_000,\n", + " # maxchunks=10, # total 676 chunks\n", + ")\n", + "\n", + "output = run(\n", + " fileset,\n", + " \"Events\",\n", + " processor_instance=FancyDimuonProcessor(),\n", + ")\n", + "\n", + "elapsed = time.time() - tstart\n", + "print(output)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Events/s: 153664.49672142894\n" + ] + } + ], + "source": [ + "nevt = output['cutflow']['ZZ to 4mu']['all events'] + output['cutflow']['DoubleMuon']['all events']\n", + "print(\"Events/s:\", nevt / elapsed)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "What follows is just us looking at the output, you can execute it if you wish" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [], + "source": [ + "# scale ZZ simulation to expected yield\n", + "lumi = 11.6 # 1/fb\n", + "zzxs = 7200 * 0.0336**2 # approximate 8 TeV ZZ(4mu)\n", + "nzz = output['cutflow']['ZZ to 4mu']['all events']\n", + "\n", + "scaled = {}\n", + "for name, h in output.items():\n", + " if isinstance(h, hist.Hist):\n", + " scaled[name] = h.copy()\n", + " scaled[name].view()[0, :] *= lumi * zzxs / nzz" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1, 122819923.5463199)" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "scaled['nMuons'].plot1d(ax=ax, overlay='dataset')\n", + "ax.set_yscale('log')\n", + "ax.set_ylim(1, None)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['mass'][:, ::hist.rebin(4)].plot1d(ax=ax, overlay='dataset');" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['mass_z1'].plot1d(ax=ax, overlay='dataset');" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(2.0, 300.0)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['mass_z2'].plot1d(ax=ax, overlay='dataset')\n", + "ax.set_xlim(2, 300)\n", + "# ax.set_xscale('log')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['pt_z1_mu1'].plot1d(ax=ax, overlay='dataset');" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax = plt.subplots()\n", + "\n", + "scaled['pt_z1_mu2'].plot1d(ax=ax, overlay='dataset');" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.13" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/objects.inv b/objects.inv new file mode 100644 index 000000000..087321611 Binary files /dev/null and b/objects.inv differ diff --git a/py-modindex.html b/py-modindex.html new file mode 100644 index 000000000..f301470d3 --- /dev/null +++ b/py-modindex.html @@ -0,0 +1,192 @@ + + + + + + + + Python Module Index — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + +

Python Module Index

+ +
+ c +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ c
+ coffea +
    + coffea.analysis_tools +
    + coffea.btag_tools +
    + coffea.hist +
    + coffea.jetmet_tools +
    + coffea.lookup_tools +
    + coffea.lumi_tools +
    + coffea.nanoevents +
    + coffea.nanoevents.methods.base +
    + coffea.nanoevents.methods.candidate +
    + coffea.nanoevents.methods.nanoaod +
    + coffea.nanoevents.methods.vector +
    + coffea.processor +
    + coffea.util +
+ + +
+
+
+ +
+ +
+

© Copyright 2019, Fermi National Accelerator Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file diff --git a/reference.html b/reference.html new file mode 100644 index 000000000..8d99e56a4 --- /dev/null +++ b/reference.html @@ -0,0 +1,184 @@ + + + + + + + + + API Reference Guide — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

API Reference Guide

+

Coffea: a column object framework for effective analysis.

+

When executing

+
>>> import coffea
+
+
+

a subset of the full coffea package is imported into the python environment. +Some packages must be imported explicitly, so as to avoid importing unnecessary +and/or heavy dependencies. Below lists the packages available in the coffea namespace.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

coffea.analysis_tools

Tools of general use for columnar analysis

coffea.btag_tools

BTag tools: CMS analysis-level b-tagging corrections and uncertainties

coffea.hist

Histogramming tools

coffea.jetmet_tools

JetMET tools: CMS analysis-level jet corrections and uncertainties

coffea.lookup_tools

Lookup tools

coffea.lumi_tools

Tools to parse CMS luminosity non-event data

coffea.nanoevents

NanoEvents and helpers

coffea.nanoevents.methods.base

Basic NanoEvents and NanoCollection mixins

coffea.nanoevents.methods.candidate

Physics object candidate mixin

coffea.nanoevents.methods.nanoaod

Mixins for the CMS NanoAOD schema

coffea.nanoevents.methods.vector

2D, 3D, and Lorentz vector class mixins

coffea.processor

A framework for analysis scale-out

coffea.util

Utility functions

+
+ + +
+
+ +
+
+
+
+ + + + \ No newline at end of file diff --git a/search.html b/search.html new file mode 100644 index 000000000..8dc2d1257 --- /dev/null +++ b/search.html @@ -0,0 +1,127 @@ + + + + + + + + Search — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
    +
  • + +
  • +
  • +
+
+
+
+
+ + + + +
+ +
+ +
+
+
+ +
+ +
+

© Copyright 2019, Fermi National Accelerator Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + + + + + + \ No newline at end of file diff --git a/searchindex.js b/searchindex.js new file mode 100644 index 000000000..3a85c567f --- /dev/null +++ b/searchindex.js @@ -0,0 +1 @@ +Search.setIndex({"alltitles": {"API Reference Guide": [[122, null]], "Accumulator semantics": [[117, "Accumulator-semantics"]], "AccumulatorABC": [[67, null]], "Analysis tools and accumulators": [[117, null]], "Applying CMS b-tagging corrections with btag_tools": [[118, "Applying-CMS-b-tagging-corrections-with-btag_tools"]], "Applying corrections to columnar data": [[118, null]], "Applying energy scale transformations with jetmet_tools": [[118, "Applying-energy-scale-transformations-with-jetmet_tools"]], "AssociatedPFCand": [[43, null]], "AssociatedSV": [[44, null]], "BTagScaleFactor": [[3, null]], "BaseSchema": [[29, null]], "Bin": [[4, null]], "Bringing it together": [[117, "Bringing-it-together"]], "Building and using your own correction from a histogram": [[118, "Building-and-using-your-own-correction-from-a-histogram"]], "CMS high-level tools": [[118, "CMS-high-level-tools"]], "Candidate": [[40, null]], "Cat": [[5, null]], "Class Inheritance Diagram": [[104, "class-inheritance-diagram"], [105, "class-inheritance-diagram"], [106, "class-inheritance-diagram"], [107, "class-inheritance-diagram"], [108, "class-inheritance-diagram"], [109, "class-inheritance-diagram"], [110, "class-inheritance-diagram"], [111, "class-inheritance-diagram"], [112, "class-inheritance-diagram"], [113, "class-inheritance-diagram"], [114, "class-inheritance-diagram"], [115, "class-inheritance-diagram"], [116, "class-inheritance-diagram"]], "Classes": [[104, "classes"], [105, "classes"], [106, "classes"], [107, "classes"], [108, "classes"], [109, "classes"], [110, "classes"], [111, "classes"], [112, "classes"], [113, "classes"], [114, "classes"], [115, "classes"], [116, "classes"]], "Coffea Histograms (deprecated)": [[119, null]], "Coffea Processors": [[121, null]], "Coffea by Example": [[101, null]], "Coffea concepts": [[100, null]], "Coffea lookup_tools": [[118, "Coffea-lookup_tools"]], "Coffea processor": [[100, "coffea-processor"]], "Columnar analysis": [[100, "columnar-analysis"]], "Container-based": [[103, "container-based"]], "CorrectedJetsFactory": [[17, null]], "CorrectedMETFactory": [[18, null]], "Creating a portable virtual environment": [[103, "creating-a-portable-virtual-environment"]], "DaskExecutor": [[68, null]], "DelphesSchema": [[30, null]], "Distributed executors": [[100, "distributed-executors"]], "Documentation": [[102, "documentation"]], "Electron": [[45, null]], "FactorizedJetCorrector": [[19, null]], "FatJet": [[46, null]], "Filling": [[119, "Filling"]], "For Developers": [[103, "for-developers"]], "FsrPhoton": [[47, null]], "Functions": [[106, "functions"], [115, "functions"], [116, "functions"]], "FuturesExecutor": [[69, null]], "GenParticle": [[48, null]], "GenVisTau": [[49, null]], "Getting fancy": [[121, "Getting-fancy"]], "Hist": [[6, null]], "Indices and tables": [[102, "indices-and-tables"]], "Install coffea": [[103, "install-coffea"]], "Install optional dependencies": [[103, "install-optional-dependencies"]], "Install via cvmfs": [[103, "install-via-cvmfs"]], "Installation": [[102, "installation"]], "Installing coffea": [[103, null]], "Interval": [[7, null]], "IterativeExecutor": [[70, null]], "JECStack": [[20, null]], "Jet": [[50, null]], "JetCorrectionUncertainty": [[21, null]], "JetResolution": [[22, null]], "JetResolutionScaleFactor": [[23, null]], "LCG-based": [[103, "lcg-based"]], "LazyDataFrame": [[71, null]], "Local executors": [[100, "local-executors"]], "LorentzVector": [[60, null]], "LowPtElectron": [[51, null]], "LumiData": [[26, null]], "LumiList": [[27, null]], "LumiMask": [[28, null]], "MissingET": [[52, null]], "Muon": [[53, null]], "NanoAODSchema": [[31, null], [72, null]], "NanoCollection": [[37, null]], "NanoEvents": [[38, null]], "NanoEventsFactory": [[32, null]], "Opening a root file and using it as a lookup table": [[118, "Opening-a-root-file-and-using-it-as-a-lookup-table"]], "PDUNESchema": [[33, null]], "PFCand": [[54, null]], "PFNanoAODSchema": [[34, null]], "PHYSLITESchema": [[35, null]], "PackedSelection": [[0, null], [73, null], [117, "PackedSelection"]], "ParslExecutor": [[74, null]], "Photon": [[55, null]], "Platform support": [[103, "platform-support"]], "Plotting": [[119, "Plotting"]], "PolarTwoVector": [[61, null]], "Pre-built images": [[103, "pre-built-images"]], "ProcessorABC": [[75, null]], "PtEtaPhiECandidate": [[41, null]], "PtEtaPhiELorentzVector": [[62, null]], "PtEtaPhiMCandidate": [[42, null]], "PtEtaPhiMCollection": [[56, null]], "PtEtaPhiMLorentzVector": [[63, null]], "Quick start": [[103, "quick-start"]], "Reading data with coffea NanoEvents": [[120, null]], "Runner": [[76, null]], "Scale-out": [[100, "scale-out"]], "SecondaryVertex": [[57, null]], "SpeedColumn": [[93, null]], "SphericalThreeVector": [[64, null]], "Strict dependencies": [[102, "strict-dependencies"]], "StringBin": [[8, null]], "Styling": [[119, "Styling"]], "Systematic": [[39, null]], "Tau": [[58, null]], "ThreeVector": [[65, null]], "Transformation": [[119, "Transformation"]], "TreeMakerSchema": [[36, null], [77, null]], "TwoVector": [[66, null]], "Using correctionlib": [[118, "Using-correctionlib"]], "Vertex": [[59, null]], "Virtual environment": [[103, "virtual-environment"]], "WeightStatistics": [[1, null]], "Weights": [[2, null], [78, null], [117, "Weights"]], "Work Queue Executor": [[123, null]], "WorkQueueExecutor": [[79, null]], "accumulate": [[80, null]], "awkward_rewrap": [[94, null]], "clopper_pearson_interval": [[9, null]], "coffea - Columnar Object Framework For Effective Analysis": [[102, null]], "coffea.analysis_tools": [[104, null]], "coffea.btag_tools": [[105, null]], "coffea.hist": [[106, null]], "coffea.jetmet_tools": [[107, null]], "coffea.lookup_tools": [[108, null]], "coffea.lumi_tools": [[109, null]], "coffea.nanoevents": [[110, null]], "coffea.nanoevents.methods.base": [[111, null]], "coffea.nanoevents.methods.candidate": [[112, null]], "coffea.nanoevents.methods.nanoaod": [[113, null]], "coffea.nanoevents.methods.vector": [[114, null]], "coffea.processor": [[115, null]], "coffea.util": [[116, null]], "column_accumulator": [[81, null]], "dask_executor": [[82, null]], "defaultdict_accumulator": [[83, null]], "deprecate": [[95, null]], "dict_accumulator": [[84, null]], "evaluator": [[24, null]], "export1d": [[10, null]], "extractor": [[25, null]], "futures_executor": [[85, null]], "iterative_executor": [[86, null]], "list_accumulator": [[87, null]], "load": [[96, null]], "normal_interval": [[11, null]], "parsl_executor": [[88, null]], "plot1d": [[12, null]], "plot2d": [[13, null]], "plotgrid": [[14, null]], "plotratio": [[15, null]], "poisson_interval": [[16, null]], "rewrap_recordarray": [[97, null]], "rich_bar": [[98, null]], "run_spark_job": [[89, null]], "save": [[99, null]], "set_accumulator": [[90, null]], "value_accumulator": [[91, null]], "work_queue_executor": [[92, null]]}, "docnames": ["api/coffea.analysis_tools.PackedSelection", "api/coffea.analysis_tools.WeightStatistics", "api/coffea.analysis_tools.Weights", "api/coffea.btag_tools.BTagScaleFactor", "api/coffea.hist.Bin", "api/coffea.hist.Cat", "api/coffea.hist.Hist", "api/coffea.hist.Interval", "api/coffea.hist.StringBin", "api/coffea.hist.clopper_pearson_interval", "api/coffea.hist.export1d", "api/coffea.hist.normal_interval", "api/coffea.hist.plot1d", "api/coffea.hist.plot2d", "api/coffea.hist.plotgrid", "api/coffea.hist.plotratio", "api/coffea.hist.poisson_interval", "api/coffea.jetmet_tools.CorrectedJetsFactory", "api/coffea.jetmet_tools.CorrectedMETFactory", "api/coffea.jetmet_tools.FactorizedJetCorrector", "api/coffea.jetmet_tools.JECStack", "api/coffea.jetmet_tools.JetCorrectionUncertainty", "api/coffea.jetmet_tools.JetResolution", "api/coffea.jetmet_tools.JetResolutionScaleFactor", "api/coffea.lookup_tools.evaluator", "api/coffea.lookup_tools.extractor", "api/coffea.lumi_tools.LumiData", "api/coffea.lumi_tools.LumiList", "api/coffea.lumi_tools.LumiMask", "api/coffea.nanoevents.BaseSchema", "api/coffea.nanoevents.DelphesSchema", "api/coffea.nanoevents.NanoAODSchema", "api/coffea.nanoevents.NanoEventsFactory", "api/coffea.nanoevents.PDUNESchema", "api/coffea.nanoevents.PFNanoAODSchema", "api/coffea.nanoevents.PHYSLITESchema", "api/coffea.nanoevents.TreeMakerSchema", "api/coffea.nanoevents.methods.base.NanoCollection", "api/coffea.nanoevents.methods.base.NanoEvents", "api/coffea.nanoevents.methods.base.Systematic", "api/coffea.nanoevents.methods.candidate.Candidate", "api/coffea.nanoevents.methods.candidate.PtEtaPhiECandidate", "api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate", "api/coffea.nanoevents.methods.nanoaod.AssociatedPFCand", "api/coffea.nanoevents.methods.nanoaod.AssociatedSV", "api/coffea.nanoevents.methods.nanoaod.Electron", "api/coffea.nanoevents.methods.nanoaod.FatJet", "api/coffea.nanoevents.methods.nanoaod.FsrPhoton", "api/coffea.nanoevents.methods.nanoaod.GenParticle", "api/coffea.nanoevents.methods.nanoaod.GenVisTau", "api/coffea.nanoevents.methods.nanoaod.Jet", "api/coffea.nanoevents.methods.nanoaod.LowPtElectron", "api/coffea.nanoevents.methods.nanoaod.MissingET", "api/coffea.nanoevents.methods.nanoaod.Muon", "api/coffea.nanoevents.methods.nanoaod.PFCand", "api/coffea.nanoevents.methods.nanoaod.Photon", "api/coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection", "api/coffea.nanoevents.methods.nanoaod.SecondaryVertex", "api/coffea.nanoevents.methods.nanoaod.Tau", "api/coffea.nanoevents.methods.nanoaod.Vertex", "api/coffea.nanoevents.methods.vector.LorentzVector", "api/coffea.nanoevents.methods.vector.PolarTwoVector", "api/coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector", "api/coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector", "api/coffea.nanoevents.methods.vector.SphericalThreeVector", "api/coffea.nanoevents.methods.vector.ThreeVector", "api/coffea.nanoevents.methods.vector.TwoVector", "api/coffea.processor.AccumulatorABC", "api/coffea.processor.DaskExecutor", "api/coffea.processor.FuturesExecutor", "api/coffea.processor.IterativeExecutor", "api/coffea.processor.LazyDataFrame", "api/coffea.processor.NanoAODSchema", "api/coffea.processor.PackedSelection", "api/coffea.processor.ParslExecutor", "api/coffea.processor.ProcessorABC", "api/coffea.processor.Runner", "api/coffea.processor.TreeMakerSchema", "api/coffea.processor.Weights", "api/coffea.processor.WorkQueueExecutor", "api/coffea.processor.accumulate", "api/coffea.processor.column_accumulator", "api/coffea.processor.dask_executor", "api/coffea.processor.defaultdict_accumulator", "api/coffea.processor.dict_accumulator", "api/coffea.processor.futures_executor", "api/coffea.processor.iterative_executor", "api/coffea.processor.list_accumulator", "api/coffea.processor.parsl_executor", "api/coffea.processor.run_spark_job", "api/coffea.processor.set_accumulator", "api/coffea.processor.value_accumulator", "api/coffea.processor.work_queue_executor", "api/coffea.util.SpeedColumn", "api/coffea.util.awkward_rewrap", "api/coffea.util.deprecate", "api/coffea.util.load", "api/coffea.util.rewrap_recordarray", "api/coffea.util.rich_bar", "api/coffea.util.save", "concepts", "examples", "index", "installation", "modules/coffea.analysis_tools", "modules/coffea.btag_tools", "modules/coffea.hist", "modules/coffea.jetmet_tools", "modules/coffea.lookup_tools", "modules/coffea.lumi_tools", "modules/coffea.nanoevents", "modules/coffea.nanoevents.methods.base", "modules/coffea.nanoevents.methods.candidate", "modules/coffea.nanoevents.methods.nanoaod", "modules/coffea.nanoevents.methods.vector", "modules/coffea.processor", "modules/coffea.util", "notebooks/accumulators", "notebooks/applying_corrections", "notebooks/histograms", "notebooks/nanoevents", "notebooks/processor", "reference", "wq"], "envversion": {"nbsphinx": 4, "sphinx": 64, "sphinx.domains.c": 3, "sphinx.domains.changeset": 1, "sphinx.domains.citation": 1, "sphinx.domains.cpp": 9, "sphinx.domains.index": 1, "sphinx.domains.javascript": 3, "sphinx.domains.math": 2, "sphinx.domains.python": 4, "sphinx.domains.rst": 2, "sphinx.domains.std": 2, "sphinx.ext.intersphinx": 1}, "filenames": ["api/coffea.analysis_tools.PackedSelection.rst", "api/coffea.analysis_tools.WeightStatistics.rst", "api/coffea.analysis_tools.Weights.rst", "api/coffea.btag_tools.BTagScaleFactor.rst", "api/coffea.hist.Bin.rst", "api/coffea.hist.Cat.rst", "api/coffea.hist.Hist.rst", "api/coffea.hist.Interval.rst", "api/coffea.hist.StringBin.rst", "api/coffea.hist.clopper_pearson_interval.rst", "api/coffea.hist.export1d.rst", "api/coffea.hist.normal_interval.rst", "api/coffea.hist.plot1d.rst", "api/coffea.hist.plot2d.rst", "api/coffea.hist.plotgrid.rst", "api/coffea.hist.plotratio.rst", "api/coffea.hist.poisson_interval.rst", "api/coffea.jetmet_tools.CorrectedJetsFactory.rst", "api/coffea.jetmet_tools.CorrectedMETFactory.rst", "api/coffea.jetmet_tools.FactorizedJetCorrector.rst", "api/coffea.jetmet_tools.JECStack.rst", "api/coffea.jetmet_tools.JetCorrectionUncertainty.rst", "api/coffea.jetmet_tools.JetResolution.rst", "api/coffea.jetmet_tools.JetResolutionScaleFactor.rst", "api/coffea.lookup_tools.evaluator.rst", "api/coffea.lookup_tools.extractor.rst", "api/coffea.lumi_tools.LumiData.rst", "api/coffea.lumi_tools.LumiList.rst", "api/coffea.lumi_tools.LumiMask.rst", "api/coffea.nanoevents.BaseSchema.rst", "api/coffea.nanoevents.DelphesSchema.rst", "api/coffea.nanoevents.NanoAODSchema.rst", "api/coffea.nanoevents.NanoEventsFactory.rst", "api/coffea.nanoevents.PDUNESchema.rst", "api/coffea.nanoevents.PFNanoAODSchema.rst", "api/coffea.nanoevents.PHYSLITESchema.rst", "api/coffea.nanoevents.TreeMakerSchema.rst", "api/coffea.nanoevents.methods.base.NanoCollection.rst", "api/coffea.nanoevents.methods.base.NanoEvents.rst", "api/coffea.nanoevents.methods.base.Systematic.rst", "api/coffea.nanoevents.methods.candidate.Candidate.rst", "api/coffea.nanoevents.methods.candidate.PtEtaPhiECandidate.rst", "api/coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate.rst", "api/coffea.nanoevents.methods.nanoaod.AssociatedPFCand.rst", "api/coffea.nanoevents.methods.nanoaod.AssociatedSV.rst", "api/coffea.nanoevents.methods.nanoaod.Electron.rst", "api/coffea.nanoevents.methods.nanoaod.FatJet.rst", "api/coffea.nanoevents.methods.nanoaod.FsrPhoton.rst", "api/coffea.nanoevents.methods.nanoaod.GenParticle.rst", "api/coffea.nanoevents.methods.nanoaod.GenVisTau.rst", "api/coffea.nanoevents.methods.nanoaod.Jet.rst", "api/coffea.nanoevents.methods.nanoaod.LowPtElectron.rst", "api/coffea.nanoevents.methods.nanoaod.MissingET.rst", "api/coffea.nanoevents.methods.nanoaod.Muon.rst", "api/coffea.nanoevents.methods.nanoaod.PFCand.rst", "api/coffea.nanoevents.methods.nanoaod.Photon.rst", "api/coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection.rst", "api/coffea.nanoevents.methods.nanoaod.SecondaryVertex.rst", "api/coffea.nanoevents.methods.nanoaod.Tau.rst", "api/coffea.nanoevents.methods.nanoaod.Vertex.rst", "api/coffea.nanoevents.methods.vector.LorentzVector.rst", "api/coffea.nanoevents.methods.vector.PolarTwoVector.rst", "api/coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.rst", "api/coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.rst", "api/coffea.nanoevents.methods.vector.SphericalThreeVector.rst", "api/coffea.nanoevents.methods.vector.ThreeVector.rst", "api/coffea.nanoevents.methods.vector.TwoVector.rst", "api/coffea.processor.AccumulatorABC.rst", "api/coffea.processor.DaskExecutor.rst", "api/coffea.processor.FuturesExecutor.rst", "api/coffea.processor.IterativeExecutor.rst", "api/coffea.processor.LazyDataFrame.rst", "api/coffea.processor.NanoAODSchema.rst", "api/coffea.processor.PackedSelection.rst", "api/coffea.processor.ParslExecutor.rst", "api/coffea.processor.ProcessorABC.rst", "api/coffea.processor.Runner.rst", "api/coffea.processor.TreeMakerSchema.rst", "api/coffea.processor.Weights.rst", "api/coffea.processor.WorkQueueExecutor.rst", "api/coffea.processor.accumulate.rst", "api/coffea.processor.column_accumulator.rst", "api/coffea.processor.dask_executor.rst", "api/coffea.processor.defaultdict_accumulator.rst", "api/coffea.processor.dict_accumulator.rst", "api/coffea.processor.futures_executor.rst", "api/coffea.processor.iterative_executor.rst", "api/coffea.processor.list_accumulator.rst", "api/coffea.processor.parsl_executor.rst", "api/coffea.processor.run_spark_job.rst", "api/coffea.processor.set_accumulator.rst", "api/coffea.processor.value_accumulator.rst", "api/coffea.processor.work_queue_executor.rst", "api/coffea.util.SpeedColumn.rst", "api/coffea.util.awkward_rewrap.rst", "api/coffea.util.deprecate.rst", "api/coffea.util.load.rst", "api/coffea.util.rewrap_recordarray.rst", "api/coffea.util.rich_bar.rst", "api/coffea.util.save.rst", "concepts.rst", "examples.rst", "index.rst", "installation.rst", "modules/coffea.analysis_tools.rst", "modules/coffea.btag_tools.rst", "modules/coffea.hist.rst", "modules/coffea.jetmet_tools.rst", "modules/coffea.lookup_tools.rst", "modules/coffea.lumi_tools.rst", "modules/coffea.nanoevents.rst", "modules/coffea.nanoevents.methods.base.rst", "modules/coffea.nanoevents.methods.candidate.rst", "modules/coffea.nanoevents.methods.nanoaod.rst", "modules/coffea.nanoevents.methods.vector.rst", "modules/coffea.processor.rst", "modules/coffea.util.rst", "notebooks/accumulators.ipynb", "notebooks/applying_corrections.ipynb", "notebooks/histograms.ipynb", "notebooks/nanoevents.ipynb", "notebooks/processor.ipynb", "reference.rst", "wq.rst"], "indexentries": {"__call__() (coffea.btag_tools.btagscalefactor method)": [[3, "coffea.btag_tools.BTagScaleFactor.__call__", false]], "__call__() (coffea.lumi_tools.lumimask method)": [[28, "coffea.lumi_tools.LumiMask.__call__", false]], "__call__() (coffea.processor.daskexecutor method)": [[68, "coffea.processor.DaskExecutor.__call__", false]], "__call__() (coffea.processor.futuresexecutor method)": [[69, "coffea.processor.FuturesExecutor.__call__", false]], "__call__() (coffea.processor.iterativeexecutor method)": [[70, "coffea.processor.IterativeExecutor.__call__", false]], "__call__() (coffea.processor.parslexecutor method)": [[74, "coffea.processor.ParslExecutor.__call__", false]], "__call__() (coffea.processor.runner method)": [[76, "coffea.processor.Runner.__call__", false]], "__call__() (coffea.processor.workqueueexecutor method)": [[79, "coffea.processor.WorkQueueExecutor.__call__", false]], "absolute() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.absolute", false]], "absolute() (coffea.nanoevents.methods.vector.threevector method)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.absolute", false]], "absolute() (coffea.nanoevents.methods.vector.twovector method)": [[66, "coffea.nanoevents.methods.vector.TwoVector.absolute", false]], "accumulate() (in module coffea.processor)": [[80, "coffea.processor.accumulate", false]], "accumulatorabc (class in coffea.processor)": [[67, "coffea.processor.AccumulatorABC", false]], "add() (coffea.analysis_tools.packedselection method)": [[0, "coffea.analysis_tools.PackedSelection.add", false]], "add() (coffea.analysis_tools.weights method)": [[2, "coffea.analysis_tools.Weights.add", false]], "add() (coffea.analysis_tools.weightstatistics method)": [[1, "coffea.analysis_tools.WeightStatistics.add", false]], "add() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.add", false]], "add() (coffea.nanoevents.methods.candidate.candidate method)": [[40, "coffea.nanoevents.methods.candidate.Candidate.add", false]], "add() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.add", false]], "add() (coffea.nanoevents.methods.vector.threevector method)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.add", false]], "add() (coffea.nanoevents.methods.vector.twovector method)": [[66, "coffea.nanoevents.methods.vector.TwoVector.add", false]], "add() (coffea.processor.accumulatorabc method)": [[67, "coffea.processor.AccumulatorABC.add", false]], "add() (coffea.processor.column_accumulator method)": [[81, "coffea.processor.column_accumulator.add", false]], "add() (coffea.processor.defaultdict_accumulator method)": [[83, "coffea.processor.defaultdict_accumulator.add", false]], "add() (coffea.processor.dict_accumulator method)": [[84, "coffea.processor.dict_accumulator.add", false]], "add() (coffea.processor.list_accumulator method)": [[87, "coffea.processor.list_accumulator.add", false]], "add() (coffea.processor.packedselection method)": [[73, "coffea.processor.PackedSelection.add", false]], "add() (coffea.processor.set_accumulator method)": [[90, "coffea.processor.set_accumulator.add", false]], "add() (coffea.processor.value_accumulator method)": [[91, "coffea.processor.value_accumulator.add", false]], "add() (coffea.processor.weights method)": [[78, "coffea.processor.Weights.add", false]], "add_kind() (coffea.nanoevents.methods.base.systematic class method)": [[39, "coffea.nanoevents.methods.base.Systematic.add_kind", false]], "add_multivariation() (coffea.analysis_tools.weights method)": [[2, "coffea.analysis_tools.Weights.add_multivariation", false]], "add_systematic() (coffea.nanoevents.methods.base.systematic method)": [[39, "coffea.nanoevents.methods.base.Systematic.add_systematic", false]], "add_weight_set() (coffea.lookup_tools.extractor method)": [[25, "coffea.lookup_tools.extractor.add_weight_set", false]], "add_weight_sets() (coffea.lookup_tools.extractor method)": [[25, "coffea.lookup_tools.extractor.add_weight_sets", false]], "align_clusters (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.align_clusters", false]], "all() (coffea.analysis_tools.packedselection method)": [[0, "coffea.analysis_tools.PackedSelection.all", false]], "all() (coffea.processor.packedselection method)": [[73, "coffea.processor.PackedSelection.all", false]], "all_cross_references (coffea.nanoevents.nanoaodschema attribute)": [[31, "coffea.nanoevents.NanoAODSchema.all_cross_references", false]], "all_cross_references (coffea.nanoevents.pfnanoaodschema attribute)": [[34, "coffea.nanoevents.PFNanoAODSchema.all_cross_references", false]], "all_cross_references (coffea.processor.nanoaodschema attribute)": [[72, "coffea.processor.NanoAODSchema.all_cross_references", false]], "any() (coffea.analysis_tools.packedselection method)": [[0, "coffea.analysis_tools.PackedSelection.any", false]], "associatedpfcand (class in coffea.nanoevents.methods.nanoaod)": [[43, "coffea.nanoevents.methods.nanoaod.AssociatedPFCand", false]], "associatedsv (class in coffea.nanoevents.methods.nanoaod)": [[44, "coffea.nanoevents.methods.nanoaod.AssociatedSV", false]], "automatic_retries() (coffea.processor.runner static method)": [[76, "coffea.processor.Runner.automatic_retries", false]], "available (coffea.processor.lazydataframe attribute)": [[71, "coffea.processor.LazyDataFrame.available", false]], "awkward_rewrap() (in module coffea.util)": [[94, "coffea.util.awkward_rewrap", false]], "axes() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.axes", false]], "axis() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.axis", false]], "bar_format (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.bar_format", false]], "baseschema (class in coffea.nanoevents)": [[29, "coffea.nanoevents.BaseSchema", false]], "behavior (coffea.nanoevents.baseschema attribute)": [[29, "coffea.nanoevents.BaseSchema.behavior", false]], "behavior (coffea.nanoevents.delphesschema attribute)": [[30, "coffea.nanoevents.DelphesSchema.behavior", false]], "behavior (coffea.nanoevents.nanoaodschema attribute)": [[31, "coffea.nanoevents.NanoAODSchema.behavior", false]], "behavior (coffea.nanoevents.pduneschema attribute)": [[33, "coffea.nanoevents.PDUNESchema.behavior", false]], "behavior (coffea.nanoevents.physliteschema attribute)": [[35, "coffea.nanoevents.PHYSLITESchema.behavior", false]], "behavior (coffea.nanoevents.treemakerschema attribute)": [[36, "coffea.nanoevents.TreeMakerSchema.behavior", false]], "behavior (coffea.processor.nanoaodschema attribute)": [[72, "coffea.processor.NanoAODSchema.behavior", false]], "behavior (coffea.processor.treemakerschema attribute)": [[77, "coffea.processor.TreeMakerSchema.behavior", false]], "bin (class in coffea.hist)": [[4, "coffea.hist.Bin", false]], "blank_name_map (coffea.jetmet_tools.jecstack attribute)": [[20, "coffea.jetmet_tools.JECStack.blank_name_map", false]], "boost() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.boost", false]], "boostvec (coffea.nanoevents.methods.vector.lorentzvector attribute)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.boostvec", false]], "btagscalefactor (class in coffea.btag_tools)": [[3, "coffea.btag_tools.BTagScaleFactor", false]], "build() (coffea.jetmet_tools.correctedjetsfactory method)": [[17, "coffea.jetmet_tools.CorrectedJetsFactory.build", false]], "build() (coffea.jetmet_tools.correctedmetfactory method)": [[18, "coffea.jetmet_tools.CorrectedMETFactory.build", false]], "cachestrategy (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.cachestrategy", false]], "candidate (class in coffea.nanoevents.methods.candidate)": [[40, "coffea.nanoevents.methods.candidate.Candidate", false]], "cat (class in coffea.hist)": [[5, "coffea.hist.Cat", false]], "centers() (coffea.hist.bin method)": [[4, "coffea.hist.Bin.centers", false]], "charge (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.charge", false]], "children (coffea.nanoevents.methods.nanoaod.genparticle attribute)": [[48, "coffea.nanoevents.methods.nanoaod.GenParticle.children", false]], "chunks_accum_in_mem (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.chunks_accum_in_mem", false]], "chunks_per_accum (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.chunks_per_accum", false]], "chunksize (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.chunksize", false]], "chunksize (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.chunksize", false]], "clear() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.clear", false]], "clear() (coffea.lumi_tools.lumilist method)": [[27, "coffea.lumi_tools.LumiList.clear", false]], "client (coffea.processor.daskexecutor attribute)": [[68, "coffea.processor.DaskExecutor.client", false]], "clopper_pearson_interval() (in module coffea.hist)": [[9, "coffea.hist.clopper_pearson_interval", false]], "coffea.analysis_tools": [[104, "module-coffea.analysis_tools", false]], "coffea.btag_tools": [[105, "module-coffea.btag_tools", false]], "coffea.hist": [[106, "module-coffea.hist", false]], "coffea.jetmet_tools": [[107, "module-coffea.jetmet_tools", false]], "coffea.lookup_tools": [[108, "module-coffea.lookup_tools", false]], "coffea.lumi_tools": [[109, "module-coffea.lumi_tools", false]], "coffea.nanoevents": [[110, "module-coffea.nanoevents", false]], "coffea.nanoevents.methods.base": [[111, "module-coffea.nanoevents.methods.base", false]], "coffea.nanoevents.methods.candidate": [[112, "module-coffea.nanoevents.methods.candidate", false]], "coffea.nanoevents.methods.nanoaod": [[113, "module-coffea.nanoevents.methods.nanoaod", false]], "coffea.nanoevents.methods.vector": [[114, "module-coffea.nanoevents.methods.vector", false]], "coffea.processor": [[115, "module-coffea.processor", false]], "coffea.util": [[116, "module-coffea.util", false]], "collection_map (coffea.nanoevents.methods.nanoaod.associatedpfcand attribute)": [[43, "coffea.nanoevents.methods.nanoaod.AssociatedPFCand.collection_map", false]], "collection_map (coffea.nanoevents.methods.nanoaod.associatedsv attribute)": [[44, "coffea.nanoevents.methods.nanoaod.AssociatedSV.collection_map", false]], "column_accumulator (class in coffea.processor)": [[81, "coffea.processor.column_accumulator", false]], "columns (coffea.processor.lazydataframe attribute)": [[71, "coffea.processor.LazyDataFrame.columns", false]], "compatible() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.compatible", false]], "compression (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.compression", false]], "config (coffea.processor.parslexecutor attribute)": [[74, "coffea.processor.ParslExecutor.config", false]], "constituents (coffea.nanoevents.methods.nanoaod.fatjet attribute)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet.constituents", false]], "constituents (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.constituents", false]], "copy() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.copy", false]], "cores (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.cores", false]], "correctedjetsfactory (class in coffea.jetmet_tools)": [[17, "coffea.jetmet_tools.CorrectedJetsFactory", false]], "correctedmetfactory (class in coffea.jetmet_tools)": [[18, "coffea.jetmet_tools.CorrectedMETFactory", false]], "cross() (coffea.nanoevents.methods.vector.threevector method)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.cross", false]], "custom_init (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.custom_init", false]], "dask_executor (in module coffea.processor)": [[82, "coffea.processor.dask_executor", false]], "daskexecutor (class in coffea.processor)": [[68, "coffea.processor.DaskExecutor", false]], "debug_log (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.debug_log", false]], "default_dtype (coffea.hist.hist attribute)": [[6, "coffea.hist.Hist.DEFAULT_DTYPE", false]], "defaultdict_accumulator (class in coffea.processor)": [[83, "coffea.processor.defaultdict_accumulator", false]], "delphesschema (class in coffea.nanoevents)": [[30, "coffea.nanoevents.DelphesSchema", false]], "delta_phi() (coffea.nanoevents.methods.vector.twovector method)": [[66, "coffea.nanoevents.methods.vector.TwoVector.delta_phi", false]], "delta_r() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.delta_r", false]], "delta_r2() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.delta_r2", false]], "dense_axes() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.dense_axes", false]], "dense_dim() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.dense_dim", false]], "deprecate() (in module coffea.util)": [[95, "coffea.util.deprecate", false]], "describe_variations() (coffea.nanoevents.methods.base.systematic method)": [[39, "coffea.nanoevents.methods.base.Systematic.describe_variations", false]], "dict_accumulator (class in coffea.processor)": [[84, "coffea.processor.dict_accumulator", false]], "dim() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.dim", false]], "disk (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.disk", false]], "distinctchildren (coffea.nanoevents.methods.nanoaod.genparticle attribute)": [[48, "coffea.nanoevents.methods.nanoaod.GenParticle.distinctChildren", false]], "distinctchildrendeep (coffea.nanoevents.methods.nanoaod.genparticle attribute)": [[48, "coffea.nanoevents.methods.nanoaod.GenParticle.distinctChildrenDeep", false]], "distinctparent (coffea.nanoevents.methods.nanoaod.genparticle attribute)": [[48, "coffea.nanoevents.methods.nanoaod.GenParticle.distinctParent", false]], "divide() (coffea.nanoevents.methods.vector.twovector method)": [[66, "coffea.nanoevents.methods.vector.TwoVector.divide", false]], "docstrings (coffea.nanoevents.delphesschema attribute)": [[30, "coffea.nanoevents.DelphesSchema.docstrings", false]], "dot() (coffea.nanoevents.methods.vector.threevector method)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.dot", false]], "dot() (coffea.nanoevents.methods.vector.twovector method)": [[66, "coffea.nanoevents.methods.vector.TwoVector.dot", false]], "dynamic_chunksize (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.dynamic_chunksize", false]], "dynamic_chunksize (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.dynamic_chunksize", false]], "e (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.E", false]], "e (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.E", false]], "edges() (coffea.hist.bin method)": [[4, "coffea.hist.Bin.edges", false]], "electron (class in coffea.nanoevents.methods.nanoaod)": [[45, "coffea.nanoevents.methods.nanoaod.Electron", false]], "energy (coffea.nanoevents.methods.vector.lorentzvector attribute)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.energy", false]], "energy (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.energy", false]], "environment_file (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.environment_file", false]], "eta (coffea.nanoevents.methods.vector.lorentzvector attribute)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.eta", false]], "eta (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.eta", false]], "eta (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.eta", false]], "eval() (coffea.btag_tools.btagscalefactor method)": [[3, "coffea.btag_tools.BTagScaleFactor.eval", false]], "evaluator (class in coffea.lookup_tools)": [[24, "coffea.lookup_tools.evaluator", false]], "events() (coffea.nanoevents.nanoeventsfactory method)": [[32, "coffea.nanoevents.NanoEventsFactory.events", false]], "events_total (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.events_total", false]], "explodes_how() (coffea.nanoevents.methods.base.systematic method)": [[39, "coffea.nanoevents.methods.base.Systematic.explodes_how", false]], "export1d() (in module coffea.hist)": [[10, "coffea.hist.export1d", false]], "extract_from_file() (coffea.lookup_tools.extractor method)": [[25, "coffea.lookup_tools.extractor.extract_from_file", false]], "extractor (class in coffea.lookup_tools)": [[25, "coffea.lookup_tools.extractor", false]], "factorizedjetcorrector (class in coffea.jetmet_tools)": [[19, "coffea.jetmet_tools.FactorizedJetCorrector", false]], "fail (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.FAIL", false]], "fail (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.FAIL", false]], "fast_terminate_workers (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.fast_terminate_workers", false]], "fatjet (class in coffea.nanoevents.methods.nanoaod)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet", false]], "fields (coffea.hist.hist attribute)": [[6, "coffea.hist.Hist.fields", false]], "filepath (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.filepath", false]], "fill() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.fill", false]], "finalize() (coffea.lookup_tools.extractor method)": [[25, "coffea.lookup_tools.extractor.finalize", false]], "flags (coffea.nanoevents.methods.nanoaod.genparticle attribute)": [[48, "coffea.nanoevents.methods.nanoaod.GenParticle.FLAGS", false]], "flav_b (coffea.btag_tools.btagscalefactor attribute)": [[3, "coffea.btag_tools.BTagScaleFactor.FLAV_B", false]], "flav_c (coffea.btag_tools.btagscalefactor attribute)": [[3, "coffea.btag_tools.BTagScaleFactor.FLAV_C", false]], "flav_udsg (coffea.btag_tools.btagscalefactor attribute)": [[3, "coffea.btag_tools.BTagScaleFactor.FLAV_UDSG", false]], "form (coffea.nanoevents.baseschema attribute)": [[29, "coffea.nanoevents.BaseSchema.form", false]], "format (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.format", false]], "from_parquet() (coffea.nanoevents.nanoeventsfactory class method)": [[32, "coffea.nanoevents.NanoEventsFactory.from_parquet", false]], "from_preloaded() (coffea.nanoevents.nanoeventsfactory class method)": [[32, "coffea.nanoevents.NanoEventsFactory.from_preloaded", false]], "from_root() (coffea.nanoevents.nanoeventsfactory class method)": [[32, "coffea.nanoevents.NanoEventsFactory.from_root", false]], "fsrphoton (class in coffea.nanoevents.methods.nanoaod)": [[47, "coffea.nanoevents.methods.nanoaod.FsrPhoton", false]], "futures_executor (in module coffea.processor)": [[85, "coffea.processor.futures_executor", false]], "futuresexecutor (class in coffea.processor)": [[69, "coffea.processor.FuturesExecutor", false]], "genparticle (class in coffea.nanoevents.methods.nanoaod)": [[48, "coffea.nanoevents.methods.nanoaod.GenParticle", false]], "genvistau (class in coffea.nanoevents.methods.nanoaod)": [[49, "coffea.nanoevents.methods.nanoaod.GenVisTau", false]], "get_cache() (coffea.processor.runner static method)": [[76, "coffea.processor.Runner.get_cache", false]], "get_lumi() (coffea.lumi_tools.lumidata method)": [[26, "coffea.lumi_tools.LumiData.get_lumi", false]], "getcorrection() (coffea.jetmet_tools.factorizedjetcorrector method)": [[19, "coffea.jetmet_tools.FactorizedJetCorrector.getCorrection", false]], "getresolution() (coffea.jetmet_tools.jetresolution method)": [[22, "coffea.jetmet_tools.JetResolution.getResolution", false]], "getscalefactor() (coffea.jetmet_tools.jetresolutionscalefactor method)": [[23, "coffea.jetmet_tools.JetResolutionScaleFactor.getScaleFactor", false]], "getsubcorrections() (coffea.jetmet_tools.factorizedjetcorrector method)": [[19, "coffea.jetmet_tools.FactorizedJetCorrector.getSubCorrections", false]], "getuncertainty() (coffea.jetmet_tools.jetcorrectionuncertainty method)": [[21, "coffea.jetmet_tools.JetCorrectionUncertainty.getUncertainty", false]], "gpus (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.gpus", false]], "group() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.group", false]], "hasflags() (coffea.nanoevents.methods.nanoaod.genparticle method)": [[48, "coffea.nanoevents.methods.nanoaod.GenParticle.hasFlags", false]], "heavy_input (coffea.processor.daskexecutor attribute)": [[68, "coffea.processor.DaskExecutor.heavy_input", false]], "hi (coffea.hist.interval attribute)": [[7, "coffea.hist.Interval.hi", false]], "hist (class in coffea.hist)": [[6, "coffea.hist.Hist", false]], "identifiers() (coffea.hist.bin method)": [[4, "coffea.hist.Bin.identifiers", false]], "identifiers() (coffea.hist.cat method)": [[5, "coffea.hist.Cat.identifiers", false]], "identifiers() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.identifiers", false]], "identity() (coffea.analysis_tools.weightstatistics method)": [[1, "coffea.analysis_tools.WeightStatistics.identity", false]], "identity() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.identity", false]], "identity() (coffea.processor.accumulatorabc method)": [[67, "coffea.processor.AccumulatorABC.identity", false]], "identity() (coffea.processor.column_accumulator method)": [[81, "coffea.processor.column_accumulator.identity", false]], "identity() (coffea.processor.defaultdict_accumulator method)": [[83, "coffea.processor.defaultdict_accumulator.identity", false]], "identity() (coffea.processor.dict_accumulator method)": [[84, "coffea.processor.dict_accumulator.identity", false]], "identity() (coffea.processor.list_accumulator method)": [[87, "coffea.processor.list_accumulator.identity", false]], "identity() (coffea.processor.set_accumulator method)": [[90, "coffea.processor.set_accumulator.identity", false]], "identity() (coffea.processor.value_accumulator method)": [[91, "coffea.processor.value_accumulator.identity", false]], "import_file() (coffea.lookup_tools.extractor method)": [[25, "coffea.lookup_tools.extractor.import_file", false]], "index() (coffea.hist.bin method)": [[4, "coffea.hist.Bin.index", false]], "index() (coffea.hist.cat method)": [[5, "coffea.hist.Cat.index", false]], "integrate() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.integrate", false]], "interval (class in coffea.hist)": [[7, "coffea.hist.Interval", false]], "isloose (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.isLoose", false]], "isloose (coffea.nanoevents.methods.nanoaod.fatjet attribute)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet.isLoose", false]], "isloose (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.isLoose", false]], "isloose (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.isLoose", false]], "ismedium (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.isMedium", false]], "ismedium (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.isMedium", false]], "istight (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.isTight", false]], "istight (coffea.nanoevents.methods.nanoaod.fatjet attribute)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet.isTight", false]], "istight (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.isTight", false]], "istight (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.isTight", false]], "istightleptonveto (coffea.nanoevents.methods.nanoaod.fatjet attribute)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet.isTightLeptonVeto", false]], "istightleptonveto (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.isTightLeptonVeto", false]], "isveto (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.isVeto", false]], "iterative_executor (in module coffea.processor)": [[86, "coffea.processor.iterative_executor", false]], "iterativeexecutor (class in coffea.processor)": [[70, "coffea.processor.IterativeExecutor", false]], "jec (coffea.jetmet_tools.jecstack attribute)": [[20, "coffea.jetmet_tools.JECStack.jec", false]], "jecstack (class in coffea.jetmet_tools)": [[20, "coffea.jetmet_tools.JECStack", false]], "jer (coffea.jetmet_tools.jecstack attribute)": [[20, "coffea.jetmet_tools.JECStack.jer", false]], "jersf (coffea.jetmet_tools.jecstack attribute)": [[20, "coffea.jetmet_tools.JECStack.jersf", false]], "jet (class in coffea.nanoevents.methods.nanoaod)": [[50, "coffea.nanoevents.methods.nanoaod.Jet", false]], "jet (coffea.nanoevents.methods.nanoaod.associatedpfcand attribute)": [[43, "coffea.nanoevents.methods.nanoaod.AssociatedPFCand.jet", false]], "jet (coffea.nanoevents.methods.nanoaod.associatedsv attribute)": [[44, "coffea.nanoevents.methods.nanoaod.AssociatedSV.jet", false]], "jetcorrectionuncertainty (class in coffea.jetmet_tools)": [[21, "coffea.jetmet_tools.JetCorrectionUncertainty", false]], "jetresolution (class in coffea.jetmet_tools)": [[22, "coffea.jetmet_tools.JetResolution", false]], "jetresolutionscalefactor (class in coffea.jetmet_tools)": [[23, "coffea.jetmet_tools.JetResolutionScaleFactor", false]], "jobs_executors (coffea.processor.parslexecutor attribute)": [[74, "coffea.processor.ParslExecutor.jobs_executors", false]], "junc (coffea.jetmet_tools.jecstack attribute)": [[20, "coffea.jetmet_tools.JECStack.junc", false]], "keys() (coffea.lookup_tools.evaluator method)": [[24, "coffea.lookup_tools.evaluator.keys", false]], "label (coffea.hist.hist attribute)": [[6, "coffea.hist.Hist.label", false]], "label (coffea.hist.interval attribute)": [[7, "coffea.hist.Interval.label", false]], "label (coffea.hist.stringbin attribute)": [[8, "coffea.hist.StringBin.label", false]], "lazydataframe (class in coffea.processor)": [[71, "coffea.processor.LazyDataFrame", false]], "levels (coffea.jetmet_tools.jetcorrectionuncertainty attribute)": [[21, "coffea.jetmet_tools.JetCorrectionUncertainty.levels", false]], "list_accumulator (class in coffea.processor)": [[87, "coffea.processor.list_accumulator", false]], "lo (coffea.hist.interval attribute)": [[7, "coffea.hist.Interval.lo", false]], "load() (in module coffea.util)": [[96, "coffea.util.load", false]], "loose (coffea.btag_tools.btagscalefactor attribute)": [[3, "coffea.btag_tools.BTagScaleFactor.LOOSE", false]], "loose (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.LOOSE", false]], "loose (coffea.nanoevents.methods.nanoaod.fatjet attribute)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet.LOOSE", false]], "loose (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.LOOSE", false]], "loose (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.LOOSE", false]], "lorentzvector (class in coffea.nanoevents.methods.vector)": [[60, "coffea.nanoevents.methods.vector.LorentzVector", false]], "lowptelectron (class in coffea.nanoevents.methods.nanoaod)": [[51, "coffea.nanoevents.methods.nanoaod.LowPtElectron", false]], "lumidata (class in coffea.lumi_tools)": [[26, "coffea.lumi_tools.LumiData", false]], "lumilist (class in coffea.lumi_tools)": [[27, "coffea.lumi_tools.LumiList", false]], "lumimask (class in coffea.lumi_tools)": [[28, "coffea.lumi_tools.LumiMask", false]], "make_evaluator() (coffea.lookup_tools.extractor method)": [[25, "coffea.lookup_tools.extractor.make_evaluator", false]], "manager_name (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.manager_name", false]], "mass (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.mass", false]], "mass (coffea.nanoevents.methods.vector.lorentzvector attribute)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.mass", false]], "mass (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.mass", false]], "mass2 (coffea.nanoevents.methods.vector.lorentzvector attribute)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.mass2", false]], "mass2 (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.mass2", false]], "master_name (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.master_name", false]], "matched_electron (coffea.nanoevents.methods.nanoaod.lowptelectron attribute)": [[51, "coffea.nanoevents.methods.nanoaod.LowPtElectron.matched_electron", false]], "matched_electron (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.matched_electron", false]], "matched_electrons (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.matched_electrons", false]], "matched_fsrphoton (coffea.nanoevents.methods.nanoaod.muon attribute)": [[53, "coffea.nanoevents.methods.nanoaod.Muon.matched_fsrPhoton", false]], "matched_gen (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.matched_gen", false]], "matched_gen (coffea.nanoevents.methods.nanoaod.fatjet attribute)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet.matched_gen", false]], "matched_gen (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.matched_gen", false]], "matched_gen (coffea.nanoevents.methods.nanoaod.lowptelectron attribute)": [[51, "coffea.nanoevents.methods.nanoaod.LowPtElectron.matched_gen", false]], "matched_gen (coffea.nanoevents.methods.nanoaod.muon attribute)": [[53, "coffea.nanoevents.methods.nanoaod.Muon.matched_gen", false]], "matched_gen (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.matched_gen", false]], "matched_gen (coffea.nanoevents.methods.nanoaod.tau attribute)": [[58, "coffea.nanoevents.methods.nanoaod.Tau.matched_gen", false]], "matched_jet (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.matched_jet", false]], "matched_jet (coffea.nanoevents.methods.nanoaod.muon attribute)": [[53, "coffea.nanoevents.methods.nanoaod.Muon.matched_jet", false]], "matched_jet (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.matched_jet", false]], "matched_jet (coffea.nanoevents.methods.nanoaod.tau attribute)": [[58, "coffea.nanoevents.methods.nanoaod.Tau.matched_jet", false]], "matched_muon (coffea.nanoevents.methods.nanoaod.fsrphoton attribute)": [[47, "coffea.nanoevents.methods.nanoaod.FsrPhoton.matched_muon", false]], "matched_muons (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.matched_muons", false]], "matched_photon (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.matched_photon", false]], "matched_photon (coffea.nanoevents.methods.nanoaod.lowptelectron attribute)": [[51, "coffea.nanoevents.methods.nanoaod.LowPtElectron.matched_photon", false]], "materialized (coffea.processor.lazydataframe attribute)": [[71, "coffea.processor.LazyDataFrame.materialized", false]], "maxchunks (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.maxchunks", false]], "maxitems (coffea.analysis_tools.packedselection attribute)": [[0, "coffea.analysis_tools.PackedSelection.maxitems", false]], "medium (coffea.btag_tools.btagscalefactor attribute)": [[3, "coffea.btag_tools.BTagScaleFactor.MEDIUM", false]], "medium (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.MEDIUM", false]], "medium (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.MEDIUM", false]], "memory (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.memory", false]], "mergepool (coffea.processor.futuresexecutor attribute)": [[69, "coffea.processor.FuturesExecutor.mergepool", false]], "merges_executors (coffea.processor.parslexecutor attribute)": [[74, "coffea.processor.ParslExecutor.merges_executors", false]], "merging (coffea.processor.futuresexecutor attribute)": [[69, "coffea.processor.FuturesExecutor.merging", false]], "merging (coffea.processor.parslexecutor attribute)": [[74, "coffea.processor.ParslExecutor.merging", false]], "metadata (coffea.nanoevents.methods.base.nanoevents attribute)": [[38, "coffea.nanoevents.methods.base.NanoEvents.metadata", false]], "metadata (coffea.processor.lazydataframe attribute)": [[71, "coffea.processor.LazyDataFrame.metadata", false]], "metadata_cache (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.metadata_cache", false]], "metadata_fetcher() (coffea.processor.runner static method)": [[76, "coffea.processor.Runner.metadata_fetcher", false]], "metric_table() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.metric_table", false]], "mid (coffea.hist.interval attribute)": [[7, "coffea.hist.Interval.mid", false]], "missinget (class in coffea.nanoevents.methods.nanoaod)": [[52, "coffea.nanoevents.methods.nanoaod.MissingET", false]], "mixins (coffea.nanoevents.delphesschema attribute)": [[30, "coffea.nanoevents.DelphesSchema.mixins", false]], "mixins (coffea.nanoevents.nanoaodschema attribute)": [[31, "coffea.nanoevents.NanoAODSchema.mixins", false]], "mixins (coffea.nanoevents.pduneschema attribute)": [[33, "coffea.nanoevents.PDUNESchema.mixins", false]], "mixins (coffea.nanoevents.pfnanoaodschema attribute)": [[34, "coffea.nanoevents.PFNanoAODSchema.mixins", false]], "mixins (coffea.nanoevents.physliteschema attribute)": [[35, "coffea.nanoevents.PHYSLITESchema.mixins", false]], "mixins (coffea.processor.nanoaodschema attribute)": [[72, "coffea.processor.NanoAODSchema.mixins", false]], "mmap (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.mmap", false]], "module": [[104, "module-coffea.analysis_tools", false], [105, "module-coffea.btag_tools", false], [106, "module-coffea.hist", false], [107, "module-coffea.jetmet_tools", false], [108, "module-coffea.lookup_tools", false], [109, "module-coffea.lumi_tools", false], [110, "module-coffea.nanoevents", false], [111, "module-coffea.nanoevents.methods.base", false], [112, "module-coffea.nanoevents.methods.candidate", false], [113, "module-coffea.nanoevents.methods.nanoaod", false], [114, "module-coffea.nanoevents.methods.vector", false], [115, "module-coffea.processor", false], [116, "module-coffea.util", false]], "multiply() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.multiply", false]], "multiply() (coffea.nanoevents.methods.vector.polartwovector method)": [[61, "coffea.nanoevents.methods.vector.PolarTwoVector.multiply", false]], "multiply() (coffea.nanoevents.methods.vector.ptetaphielorentzvector method)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.multiply", false]], "multiply() (coffea.nanoevents.methods.vector.ptetaphimlorentzvector method)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.multiply", false]], "multiply() (coffea.nanoevents.methods.vector.sphericalthreevector method)": [[64, "coffea.nanoevents.methods.vector.SphericalThreeVector.multiply", false]], "multiply() (coffea.nanoevents.methods.vector.threevector method)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.multiply", false]], "multiply() (coffea.nanoevents.methods.vector.twovector method)": [[66, "coffea.nanoevents.methods.vector.TwoVector.multiply", false]], "muon (class in coffea.nanoevents.methods.nanoaod)": [[53, "coffea.nanoevents.methods.nanoaod.Muon", false]], "name (coffea.hist.stringbin attribute)": [[8, "coffea.hist.StringBin.name", false]], "names (coffea.analysis_tools.packedselection attribute)": [[0, "coffea.analysis_tools.PackedSelection.names", false]], "names (coffea.processor.packedselection attribute)": [[73, "coffea.processor.PackedSelection.names", false]], "nan() (coffea.hist.interval method)": [[7, "coffea.hist.Interval.nan", false]], "nanoaodschema (class in coffea.nanoevents)": [[31, "coffea.nanoevents.NanoAODSchema", false]], "nanoaodschema (class in coffea.processor)": [[72, "coffea.processor.NanoAODSchema", false]], "nanocollection (class in coffea.nanoevents.methods.base)": [[37, "coffea.nanoevents.methods.base.NanoCollection", false]], "nanoevents (class in coffea.nanoevents.methods.base)": [[38, "coffea.nanoevents.methods.base.NanoEvents", false]], "nanoeventsfactory (class in coffea.nanoevents)": [[32, "coffea.nanoevents.NanoEventsFactory", false]], "nearest() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.nearest", false]], "negative() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.negative", false]], "negative() (coffea.nanoevents.methods.vector.polartwovector method)": [[61, "coffea.nanoevents.methods.vector.PolarTwoVector.negative", false]], "negative() (coffea.nanoevents.methods.vector.ptetaphielorentzvector method)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.negative", false]], "negative() (coffea.nanoevents.methods.vector.ptetaphimlorentzvector method)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.negative", false]], "negative() (coffea.nanoevents.methods.vector.sphericalthreevector method)": [[64, "coffea.nanoevents.methods.vector.SphericalThreeVector.negative", false]], "negative() (coffea.nanoevents.methods.vector.threevector method)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.negative", false]], "negative() (coffea.nanoevents.methods.vector.twovector method)": [[66, "coffea.nanoevents.methods.vector.TwoVector.negative", false]], "nested_index_items (coffea.nanoevents.nanoaodschema attribute)": [[31, "coffea.nanoevents.NanoAODSchema.nested_index_items", false]], "nested_index_items (coffea.processor.nanoaodschema attribute)": [[72, "coffea.processor.NanoAODSchema.nested_index_items", false]], "nested_items (coffea.nanoevents.nanoaodschema attribute)": [[31, "coffea.nanoevents.NanoAODSchema.nested_items", false]], "nested_items (coffea.processor.nanoaodschema attribute)": [[72, "coffea.processor.NanoAODSchema.nested_items", false]], "normal_interval() (in module coffea.hist)": [[11, "coffea.hist.normal_interval", false]], "p (coffea.nanoevents.methods.vector.sphericalthreevector attribute)": [[64, "coffea.nanoevents.methods.vector.SphericalThreeVector.p", false]], "p (coffea.nanoevents.methods.vector.threevector attribute)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.p", false]], "p2 (coffea.nanoevents.methods.vector.sphericalthreevector attribute)": [[64, "coffea.nanoevents.methods.vector.SphericalThreeVector.p2", false]], "p2 (coffea.nanoevents.methods.vector.threevector attribute)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.p2", false]], "p4 (coffea.nanoevents.methods.nanoaod.secondaryvertex attribute)": [[57, "coffea.nanoevents.methods.nanoaod.SecondaryVertex.p4", false]], "packedselection (class in coffea.analysis_tools)": [[0, "coffea.analysis_tools.PackedSelection", false]], "packedselection (class in coffea.processor)": [[73, "coffea.processor.PackedSelection", false]], "parent (coffea.nanoevents.methods.nanoaod.genparticle attribute)": [[48, "coffea.nanoevents.methods.nanoaod.GenParticle.parent", false]], "parent (coffea.nanoevents.methods.nanoaod.genvistau attribute)": [[49, "coffea.nanoevents.methods.nanoaod.GenVisTau.parent", false]], "parsl_executor (in module coffea.processor)": [[88, "coffea.processor.parsl_executor", false]], "parslexecutor (class in coffea.processor)": [[74, "coffea.processor.ParslExecutor", false]], "partial_weight() (coffea.analysis_tools.weights method)": [[2, "coffea.analysis_tools.Weights.partial_weight", false]], "partial_weight() (coffea.processor.weights method)": [[78, "coffea.processor.Weights.partial_weight", false]], "password_file (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.password_file", false]], "pduneschema (class in coffea.nanoevents)": [[33, "coffea.nanoevents.PDUNESchema", false]], "pf (coffea.nanoevents.methods.nanoaod.associatedpfcand attribute)": [[43, "coffea.nanoevents.methods.nanoaod.AssociatedPFCand.pf", false]], "pfcand (class in coffea.nanoevents.methods.nanoaod)": [[54, "coffea.nanoevents.methods.nanoaod.PFCand", false]], "pfnanoaodschema (class in coffea.nanoevents)": [[34, "coffea.nanoevents.PFNanoAODSchema", false]], "phi (coffea.nanoevents.methods.vector.polartwovector attribute)": [[61, "coffea.nanoevents.methods.vector.PolarTwoVector.phi", false]], "phi (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.phi", false]], "phi (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.phi", false]], "phi (coffea.nanoevents.methods.vector.twovector attribute)": [[66, "coffea.nanoevents.methods.vector.TwoVector.phi", false]], "photon (class in coffea.nanoevents.methods.nanoaod)": [[55, "coffea.nanoevents.methods.nanoaod.Photon", false]], "physliteschema (class in coffea.nanoevents)": [[35, "coffea.nanoevents.PHYSLITESchema", false]], "plot1d() (in module coffea.hist)": [[12, "coffea.hist.plot1d", false]], "plot2d() (in module coffea.hist)": [[13, "coffea.hist.plot2d", false]], "plotgrid() (in module coffea.hist)": [[14, "coffea.hist.plotgrid", false]], "plotratio() (in module coffea.hist)": [[15, "coffea.hist.plotratio", false]], "poisson_interval() (in module coffea.hist)": [[16, "coffea.hist.poisson_interval", false]], "polartwovector (class in coffea.nanoevents.methods.vector)": [[61, "coffea.nanoevents.methods.vector.PolarTwoVector", false]], "port (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.port", false]], "pos (coffea.nanoevents.methods.nanoaod.vertex attribute)": [[59, "coffea.nanoevents.methods.nanoaod.Vertex.pos", false]], "postprocess() (coffea.processor.processorabc method)": [[75, "coffea.processor.ProcessorABC.postprocess", false]], "pre_executor (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.pre_executor", false]], "preload() (coffea.processor.lazydataframe method)": [[71, "coffea.processor.LazyDataFrame.preload", false]], "preprocess() (coffea.processor.runner method)": [[76, "coffea.processor.Runner.preprocess", false]], "print_stdout (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.print_stdout", false]], "priority (coffea.processor.daskexecutor attribute)": [[68, "coffea.processor.DaskExecutor.priority", false]], "process() (coffea.processor.processorabc method)": [[75, "coffea.processor.ProcessorABC.process", false]], "processor_compression (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.processor_compression", false]], "processorabc (class in coffea.processor)": [[75, "coffea.processor.ProcessorABC", false]], "project() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.project", false]], "pt (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.pt", false]], "pt (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.pt", false]], "pt (coffea.nanoevents.methods.vector.twovector attribute)": [[66, "coffea.nanoevents.methods.vector.TwoVector.pt", false]], "pt2 (coffea.nanoevents.methods.vector.twovector attribute)": [[66, "coffea.nanoevents.methods.vector.TwoVector.pt2", false]], "ptetaphiecandidate (class in coffea.nanoevents.methods.candidate)": [[41, "coffea.nanoevents.methods.candidate.PtEtaPhiECandidate", false]], "ptetaphielorentzvector (class in coffea.nanoevents.methods.vector)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector", false]], "ptetaphimcandidate (class in coffea.nanoevents.methods.candidate)": [[42, "coffea.nanoevents.methods.candidate.PtEtaPhiMCandidate", false]], "ptetaphimcollection (class in coffea.nanoevents.methods.nanoaod)": [[56, "coffea.nanoevents.methods.nanoaod.PtEtaPhiMCollection", false]], "ptetaphimlorentzvector (class in coffea.nanoevents.methods.vector)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector", false]], "pvec (coffea.nanoevents.methods.vector.lorentzvector attribute)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.pvec", false]], "px (coffea.nanoevents.methods.vector.twovector attribute)": [[66, "coffea.nanoevents.methods.vector.TwoVector.px", false]], "py (coffea.nanoevents.methods.vector.twovector attribute)": [[66, "coffea.nanoevents.methods.vector.TwoVector.py", false]], "pz (coffea.nanoevents.methods.vector.threevector attribute)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.pz", false]], "r (coffea.nanoevents.methods.nanoaod.missinget attribute)": [[52, "coffea.nanoevents.methods.nanoaod.MissingET.r", false]], "r (coffea.nanoevents.methods.vector.polartwovector attribute)": [[61, "coffea.nanoevents.methods.vector.PolarTwoVector.r", false]], "r (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.r", false]], "r (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.r", false]], "r (coffea.nanoevents.methods.vector.sphericalthreevector attribute)": [[64, "coffea.nanoevents.methods.vector.SphericalThreeVector.r", false]], "r (coffea.nanoevents.methods.vector.twovector attribute)": [[66, "coffea.nanoevents.methods.vector.TwoVector.r", false]], "r2 (coffea.nanoevents.methods.vector.polartwovector attribute)": [[61, "coffea.nanoevents.methods.vector.PolarTwoVector.r2", false]], "r2 (coffea.nanoevents.methods.vector.twovector attribute)": [[66, "coffea.nanoevents.methods.vector.TwoVector.r2", false]], "read_coffea_config() (coffea.processor.runner static method)": [[76, "coffea.processor.Runner.read_coffea_config", false]], "readcsv() (coffea.btag_tools.btagscalefactor class method)": [[3, "coffea.btag_tools.BTagScaleFactor.readcsv", false]], "rebin() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.rebin", false]], "recoverable (coffea.processor.futuresexecutor attribute)": [[69, "coffea.processor.FuturesExecutor.recoverable", false]], "recoverable (coffea.processor.parslexecutor attribute)": [[74, "coffea.processor.ParslExecutor.recoverable", false]], "reduced() (coffea.hist.bin method)": [[4, "coffea.hist.Bin.reduced", false]], "remove() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.remove", false]], "render() (coffea.util.speedcolumn method)": [[93, "coffea.util.SpeedColumn.render", false]], "require() (coffea.analysis_tools.packedselection method)": [[0, "coffea.analysis_tools.PackedSelection.require", false]], "require() (coffea.processor.packedselection method)": [[73, "coffea.processor.PackedSelection.require", false]], "reshape (coffea.btag_tools.btagscalefactor attribute)": [[3, "coffea.btag_tools.BTagScaleFactor.RESHAPE", false]], "resource_monitor (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.resource_monitor", false]], "resources_mode (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.resources_mode", false]], "retries (coffea.processor.daskexecutor attribute)": [[68, "coffea.processor.DaskExecutor.retries", false]], "retries (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.retries", false]], "retries (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.retries", false]], "rewrap_recordarray() (in module coffea.util)": [[97, "coffea.util.rewrap_recordarray", false]], "rho (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.rho", false]], "rho (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.rho", false]], "rho (coffea.nanoevents.methods.vector.sphericalthreevector attribute)": [[64, "coffea.nanoevents.methods.vector.SphericalThreeVector.rho", false]], "rho (coffea.nanoevents.methods.vector.threevector attribute)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.rho", false]], "rho2 (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.rho2", false]], "rho2 (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.rho2", false]], "rho2 (coffea.nanoevents.methods.vector.threevector attribute)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.rho2", false]], "rich_bar() (in module coffea.util)": [[98, "coffea.util.rich_bar", false]], "run() (coffea.processor.runner method)": [[76, "coffea.processor.Runner.run", false]], "run_spark_job() (in module coffea.processor)": [[89, "coffea.processor.run_spark_job", false]], "runner (class in coffea.processor)": [[76, "coffea.processor.Runner", false]], "save() (in module coffea.util)": [[99, "coffea.util.save", false]], "savemetrics (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.savemetrics", false]], "scale() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.scale", false]], "secondaryvertex (class in coffea.nanoevents.methods.nanoaod)": [[57, "coffea.nanoevents.methods.nanoaod.SecondaryVertex", false]], "set_accumulator (class in coffea.processor)": [[90, "coffea.processor.set_accumulator", false]], "signature (coffea.jetmet_tools.factorizedjetcorrector attribute)": [[19, "coffea.jetmet_tools.FactorizedJetCorrector.signature", false]], "signature (coffea.jetmet_tools.jetcorrectionuncertainty attribute)": [[21, "coffea.jetmet_tools.JetCorrectionUncertainty.signature", false]], "signature (coffea.jetmet_tools.jetresolution attribute)": [[22, "coffea.jetmet_tools.JetResolution.signature", false]], "signature (coffea.jetmet_tools.jetresolutionscalefactor attribute)": [[23, "coffea.jetmet_tools.JetResolutionScaleFactor.signature", false]], "singletons (coffea.nanoevents.delphesschema attribute)": [[30, "coffea.nanoevents.DelphesSchema.singletons", false]], "size (coffea.hist.bin attribute)": [[4, "coffea.hist.Bin.size", false]], "size (coffea.hist.cat attribute)": [[5, "coffea.hist.Cat.size", false]], "size (coffea.processor.lazydataframe attribute)": [[71, "coffea.processor.LazyDataFrame.size", false]], "skipbadfiles (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.skipbadfiles", false]], "sorting (coffea.hist.cat attribute)": [[5, "coffea.hist.Cat.sorting", false]], "sparse_axes() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.sparse_axes", false]], "sparse_dim() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.sparse_dim", false]], "sparse_nbins() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.sparse_nbins", false]], "special_items (coffea.nanoevents.nanoaodschema attribute)": [[31, "coffea.nanoevents.NanoAODSchema.special_items", false]], "special_items (coffea.processor.nanoaodschema attribute)": [[72, "coffea.processor.NanoAODSchema.special_items", false]], "speedcolumn (class in coffea.util)": [[93, "coffea.util.SpeedColumn", false]], "sphericalthreevector (class in coffea.nanoevents.methods.vector)": [[64, "coffea.nanoevents.methods.vector.SphericalThreeVector", false]], "split_on_exhaustion (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.split_on_exhaustion", false]], "ssl (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.ssl", false]], "stats_log (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.stats_log", false]], "status_display_interval (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.status_display_interval", false]], "stringbin (class in coffea.hist)": [[8, "coffea.hist.StringBin", false]], "subjets (coffea.nanoevents.methods.nanoaod.fatjet attribute)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet.subjets", false]], "subtract() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.subtract", false]], "subtract() (coffea.nanoevents.methods.vector.threevector method)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.subtract", false]], "subtract() (coffea.nanoevents.methods.vector.twovector method)": [[66, "coffea.nanoevents.methods.vector.TwoVector.subtract", false]], "sum() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.sum", false]], "sum() (coffea.nanoevents.methods.candidate.candidate method)": [[40, "coffea.nanoevents.methods.candidate.Candidate.sum", false]], "sum() (coffea.nanoevents.methods.vector.lorentzvector method)": [[60, "coffea.nanoevents.methods.vector.LorentzVector.sum", false]], "sum() (coffea.nanoevents.methods.vector.threevector method)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.sum", false]], "sum() (coffea.nanoevents.methods.vector.twovector method)": [[66, "coffea.nanoevents.methods.vector.TwoVector.sum", false]], "sv (coffea.nanoevents.methods.nanoaod.associatedsv attribute)": [[44, "coffea.nanoevents.methods.nanoaod.AssociatedSV.sv", false]], "systematic (class in coffea.nanoevents.methods.base)": [[39, "coffea.nanoevents.methods.base.Systematic", false]], "systematics (coffea.nanoevents.methods.base.systematic attribute)": [[39, "coffea.nanoevents.methods.base.Systematic.systematics", false]], "t (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.t", false]], "t (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.t", false]], "tailtimeout (coffea.processor.futuresexecutor attribute)": [[69, "coffea.processor.FuturesExecutor.tailtimeout", false]], "tailtimeout (coffea.processor.parslexecutor attribute)": [[74, "coffea.processor.ParslExecutor.tailtimeout", false]], "tasks_accum_log (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.tasks_accum_log", false]], "tau (class in coffea.nanoevents.methods.nanoaod)": [[58, "coffea.nanoevents.methods.nanoaod.Tau", false]], "theta (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.theta", false]], "theta (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.theta", false]], "theta (coffea.nanoevents.methods.vector.sphericalthreevector attribute)": [[64, "coffea.nanoevents.methods.vector.SphericalThreeVector.theta", false]], "theta (coffea.nanoevents.methods.vector.threevector attribute)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.theta", false]], "threevector (class in coffea.nanoevents.methods.vector)": [[65, "coffea.nanoevents.methods.vector.ThreeVector", false]], "tight (coffea.btag_tools.btagscalefactor attribute)": [[3, "coffea.btag_tools.BTagScaleFactor.TIGHT", false]], "tight (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.TIGHT", false]], "tight (coffea.nanoevents.methods.nanoaod.fatjet attribute)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet.TIGHT", false]], "tight (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.TIGHT", false]], "tight (coffea.nanoevents.methods.nanoaod.photon attribute)": [[55, "coffea.nanoevents.methods.nanoaod.Photon.TIGHT", false]], "tightlepveto (coffea.nanoevents.methods.nanoaod.fatjet attribute)": [[46, "coffea.nanoevents.methods.nanoaod.FatJet.TIGHTLEPVETO", false]], "tightlepveto (coffea.nanoevents.methods.nanoaod.jet attribute)": [[50, "coffea.nanoevents.methods.nanoaod.Jet.TIGHTLEPVETO", false]], "to_boost() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.to_boost", false]], "to_hist() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.to_hist", false]], "top_objects (coffea.nanoevents.pduneschema attribute)": [[33, "coffea.nanoevents.PDUNESchema.top_objects", false]], "transactions_log (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.transactions_log", false]], "treemakerschema (class in coffea.nanoevents)": [[36, "coffea.nanoevents.TreeMakerSchema", false]], "treemakerschema (class in coffea.processor)": [[77, "coffea.processor.TreeMakerSchema", false]], "treereduction (coffea.processor.daskexecutor attribute)": [[68, "coffea.processor.DaskExecutor.treereduction", false]], "treereduction (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.treereduction", false]], "truth_collections (coffea.nanoevents.physliteschema attribute)": [[35, "coffea.nanoevents.PHYSLITESchema.truth_collections", false]], "twovector (class in coffea.nanoevents.methods.vector)": [[66, "coffea.nanoevents.methods.vector.TwoVector", false]], "uncertainties() (coffea.jetmet_tools.correctedjetsfactory method)": [[17, "coffea.jetmet_tools.CorrectedJetsFactory.uncertainties", false]], "uncertainties() (coffea.jetmet_tools.correctedmetfactory method)": [[18, "coffea.jetmet_tools.CorrectedMETFactory.uncertainties", false]], "unit (coffea.nanoevents.methods.vector.threevector attribute)": [[65, "coffea.nanoevents.methods.vector.ThreeVector.unit", false]], "unit (coffea.nanoevents.methods.vector.twovector attribute)": [[66, "coffea.nanoevents.methods.vector.TwoVector.unit", false]], "uproot_writeable() (coffea.nanoevents.treemakerschema class method)": [[36, "coffea.nanoevents.TreeMakerSchema.uproot_writeable", false]], "uproot_writeable() (coffea.processor.treemakerschema class method)": [[77, "coffea.processor.TreeMakerSchema.uproot_writeable", false]], "use_dataframes (coffea.processor.daskexecutor attribute)": [[68, "coffea.processor.DaskExecutor.use_dataframes", false]], "use_dataframes (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.use_dataframes", false]], "use_skyhook (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.use_skyhook", false]], "v1() (coffea.nanoevents.delphesschema class method)": [[30, "coffea.nanoevents.DelphesSchema.v1", false]], "v5() (coffea.nanoevents.nanoaodschema class method)": [[31, "coffea.nanoevents.NanoAODSchema.v5", false]], "v5() (coffea.processor.nanoaodschema class method)": [[72, "coffea.processor.NanoAODSchema.v5", false]], "v6() (coffea.nanoevents.nanoaodschema class method)": [[31, "coffea.nanoevents.NanoAODSchema.v6", false]], "v6() (coffea.processor.nanoaodschema class method)": [[72, "coffea.processor.NanoAODSchema.v6", false]], "v7() (coffea.nanoevents.nanoaodschema class method)": [[31, "coffea.nanoevents.NanoAODSchema.v7", false]], "v7() (coffea.processor.nanoaodschema class method)": [[72, "coffea.processor.NanoAODSchema.v7", false]], "value (coffea.processor.column_accumulator attribute)": [[81, "coffea.processor.column_accumulator.value", false]], "value_accumulator (class in coffea.processor)": [[91, "coffea.processor.value_accumulator", false]], "values() (coffea.hist.hist method)": [[6, "coffea.hist.Hist.values", false]], "variations (coffea.analysis_tools.weights attribute)": [[2, "coffea.analysis_tools.Weights.variations", false]], "variations (coffea.processor.weights attribute)": [[78, "coffea.processor.Weights.variations", false]], "verbose (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.verbose", false]], "vertex (class in coffea.nanoevents.methods.nanoaod)": [[59, "coffea.nanoevents.methods.nanoaod.Vertex", false]], "veto (coffea.nanoevents.methods.nanoaod.electron attribute)": [[45, "coffea.nanoevents.methods.nanoaod.Electron.VETO", false]], "warn_missing_crossrefs (coffea.nanoevents.delphesschema attribute)": [[30, "coffea.nanoevents.DelphesSchema.warn_missing_crossrefs", false]], "warn_missing_crossrefs (coffea.nanoevents.nanoaodschema attribute)": [[31, "coffea.nanoevents.NanoAODSchema.warn_missing_crossrefs", false]], "warn_missing_crossrefs (coffea.processor.nanoaodschema attribute)": [[72, "coffea.processor.NanoAODSchema.warn_missing_crossrefs", false]], "weight() (coffea.analysis_tools.weights method)": [[2, "coffea.analysis_tools.Weights.weight", false]], "weight() (coffea.processor.weights method)": [[78, "coffea.processor.Weights.weight", false]], "weights (class in coffea.analysis_tools)": [[2, "coffea.analysis_tools.Weights", false]], "weights (class in coffea.processor)": [[78, "coffea.processor.Weights", false]], "weightstatistics (class in coffea.analysis_tools)": [[1, "coffea.analysis_tools.WeightStatistics", false]], "weightstatistics (coffea.analysis_tools.weights attribute)": [[2, "coffea.analysis_tools.Weights.weightStatistics", false]], "work_queue_executor (in module coffea.processor)": [[92, "coffea.processor.work_queue_executor", false]], "worker_affinity (coffea.processor.daskexecutor attribute)": [[68, "coffea.processor.DaskExecutor.worker_affinity", false]], "workers (coffea.processor.futuresexecutor attribute)": [[69, "coffea.processor.FuturesExecutor.workers", false]], "workers (coffea.processor.iterativeexecutor attribute)": [[70, "coffea.processor.IterativeExecutor.workers", false]], "workqueueexecutor (class in coffea.processor)": [[79, "coffea.processor.WorkQueueExecutor", false]], "wrapper (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.wrapper", false]], "x (coffea.nanoevents.methods.vector.polartwovector attribute)": [[61, "coffea.nanoevents.methods.vector.PolarTwoVector.x", false]], "x509_proxy (coffea.processor.workqueueexecutor attribute)": [[79, "coffea.processor.WorkQueueExecutor.x509_proxy", false]], "xrootdtimeout (coffea.processor.runner attribute)": [[76, "coffea.processor.Runner.xrootdtimeout", false]], "y (coffea.nanoevents.methods.vector.polartwovector attribute)": [[61, "coffea.nanoevents.methods.vector.PolarTwoVector.y", false]], "z (coffea.nanoevents.methods.vector.ptetaphielorentzvector attribute)": [[62, "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector.z", false]], "z (coffea.nanoevents.methods.vector.ptetaphimlorentzvector attribute)": [[63, "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector.z", false]], "z (coffea.nanoevents.methods.vector.sphericalthreevector attribute)": [[64, "coffea.nanoevents.methods.vector.SphericalThreeVector.z", false]]}, "objects": {"coffea": [[104, 0, 0, "-", "analysis_tools"], [105, 0, 0, "-", "btag_tools"], [106, 0, 0, "-", "hist"], [107, 0, 0, "-", "jetmet_tools"], [108, 0, 0, "-", "lookup_tools"], [109, 0, 0, "-", "lumi_tools"], [110, 0, 0, "-", "nanoevents"], [115, 0, 0, "-", "processor"], [116, 0, 0, "-", "util"]], "coffea.analysis_tools": [[0, 1, 1, "", "PackedSelection"], [1, 1, 1, "", "WeightStatistics"], [2, 1, 1, "", "Weights"]], "coffea.analysis_tools.PackedSelection": [[0, 2, 1, "", "add"], [0, 2, 1, "", "all"], [0, 2, 1, "", "any"], [0, 3, 1, "", "maxitems"], [0, 3, 1, "", "names"], [0, 2, 1, "", "require"]], "coffea.analysis_tools.WeightStatistics": [[1, 2, 1, "", "add"], [1, 2, 1, "", "identity"]], "coffea.analysis_tools.Weights": [[2, 2, 1, "", "add"], [2, 2, 1, "", "add_multivariation"], [2, 2, 1, "", "partial_weight"], [2, 3, 1, "", "variations"], [2, 2, 1, "", "weight"], [2, 3, 1, "", "weightStatistics"]], "coffea.btag_tools": [[3, 1, 1, "", "BTagScaleFactor"]], "coffea.btag_tools.BTagScaleFactor": [[3, 3, 1, "", "FLAV_B"], [3, 3, 1, "", "FLAV_C"], [3, 3, 1, "", "FLAV_UDSG"], [3, 3, 1, "", "LOOSE"], [3, 3, 1, "", "MEDIUM"], [3, 3, 1, "", "RESHAPE"], [3, 3, 1, "", "TIGHT"], [3, 2, 1, "", "__call__"], [3, 2, 1, "", "eval"], [3, 2, 1, "", "readcsv"]], "coffea.hist": [[4, 1, 1, "", "Bin"], [5, 1, 1, "", "Cat"], [6, 1, 1, "", "Hist"], [7, 1, 1, "", "Interval"], [8, 1, 1, "", "StringBin"], [9, 4, 1, "", "clopper_pearson_interval"], [10, 4, 1, "", "export1d"], [11, 4, 1, "", "normal_interval"], [12, 4, 1, "", "plot1d"], [13, 4, 1, "", "plot2d"], [14, 4, 1, "", "plotgrid"], [15, 4, 1, "", "plotratio"], [16, 4, 1, "", "poisson_interval"]], "coffea.hist.Bin": [[4, 2, 1, "", "centers"], [4, 2, 1, "", "edges"], [4, 2, 1, "", "identifiers"], [4, 2, 1, "", "index"], [4, 2, 1, "", "reduced"], [4, 3, 1, "", "size"]], "coffea.hist.Cat": [[5, 2, 1, "", "identifiers"], [5, 2, 1, "", "index"], [5, 3, 1, "", "size"], [5, 3, 1, "", "sorting"]], "coffea.hist.Hist": [[6, 3, 1, "", "DEFAULT_DTYPE"], [6, 2, 1, "", "add"], [6, 2, 1, "", "axes"], [6, 2, 1, "", "axis"], [6, 2, 1, "", "clear"], [6, 2, 1, "", "compatible"], [6, 2, 1, "", "copy"], [6, 2, 1, "", "dense_axes"], [6, 2, 1, "", "dense_dim"], [6, 2, 1, "", "dim"], [6, 3, 1, "", "fields"], [6, 2, 1, "", "fill"], [6, 2, 1, "", "group"], [6, 2, 1, "", "identifiers"], [6, 2, 1, "", "identity"], [6, 2, 1, "", "integrate"], [6, 3, 1, "", "label"], [6, 2, 1, "", "project"], [6, 2, 1, "", "rebin"], [6, 2, 1, "", "remove"], [6, 2, 1, "", "scale"], [6, 2, 1, "", "sparse_axes"], [6, 2, 1, "", "sparse_dim"], [6, 2, 1, "", "sparse_nbins"], [6, 2, 1, "", "sum"], [6, 2, 1, "", "to_boost"], [6, 2, 1, "", "to_hist"], [6, 2, 1, "", "values"]], "coffea.hist.Interval": [[7, 3, 1, "", "hi"], [7, 3, 1, "", "label"], [7, 3, 1, "", "lo"], [7, 3, 1, "", "mid"], [7, 2, 1, "", "nan"]], "coffea.hist.StringBin": [[8, 3, 1, "", "label"], [8, 3, 1, "", "name"]], "coffea.jetmet_tools": [[17, 1, 1, "", "CorrectedJetsFactory"], [18, 1, 1, "", "CorrectedMETFactory"], [19, 1, 1, "", "FactorizedJetCorrector"], [20, 1, 1, "", "JECStack"], [21, 1, 1, "", "JetCorrectionUncertainty"], [22, 1, 1, "", "JetResolution"], [23, 1, 1, "", "JetResolutionScaleFactor"]], "coffea.jetmet_tools.CorrectedJetsFactory": [[17, 2, 1, "", "build"], [17, 2, 1, "", "uncertainties"]], "coffea.jetmet_tools.CorrectedMETFactory": [[18, 2, 1, "", "build"], [18, 2, 1, "", "uncertainties"]], "coffea.jetmet_tools.FactorizedJetCorrector": [[19, 2, 1, "", "getCorrection"], [19, 2, 1, "", "getSubCorrections"], [19, 3, 1, "", "signature"]], "coffea.jetmet_tools.JECStack": [[20, 3, 1, "", "blank_name_map"], [20, 3, 1, "", "jec"], [20, 3, 1, "", "jer"], [20, 3, 1, "", "jersf"], [20, 3, 1, "", "junc"]], "coffea.jetmet_tools.JetCorrectionUncertainty": [[21, 2, 1, "", "getUncertainty"], [21, 3, 1, "", "levels"], [21, 3, 1, "", "signature"]], "coffea.jetmet_tools.JetResolution": [[22, 2, 1, "", "getResolution"], [22, 3, 1, "", "signature"]], "coffea.jetmet_tools.JetResolutionScaleFactor": [[23, 2, 1, "", "getScaleFactor"], [23, 3, 1, "", "signature"]], "coffea.lookup_tools": [[24, 1, 1, "", "evaluator"], [25, 1, 1, "", "extractor"]], "coffea.lookup_tools.evaluator": [[24, 2, 1, "", "keys"]], "coffea.lookup_tools.extractor": [[25, 2, 1, "", "add_weight_set"], [25, 2, 1, "", "add_weight_sets"], [25, 2, 1, "", "extract_from_file"], [25, 2, 1, "", "finalize"], [25, 2, 1, "", "import_file"], [25, 2, 1, "", "make_evaluator"]], "coffea.lumi_tools": [[26, 1, 1, "", "LumiData"], [27, 1, 1, "", "LumiList"], [28, 1, 1, "", "LumiMask"]], "coffea.lumi_tools.LumiData": [[26, 2, 1, "", "get_lumi"]], "coffea.lumi_tools.LumiList": [[27, 2, 1, "", "clear"]], "coffea.lumi_tools.LumiMask": [[28, 2, 1, "", "__call__"]], "coffea.nanoevents": [[29, 1, 1, "", "BaseSchema"], [30, 1, 1, "", "DelphesSchema"], [31, 1, 1, "", "NanoAODSchema"], [32, 1, 1, "", "NanoEventsFactory"], [33, 1, 1, "", "PDUNESchema"], [34, 1, 1, "", "PFNanoAODSchema"], [35, 1, 1, "", "PHYSLITESchema"], [36, 1, 1, "", "TreeMakerSchema"]], "coffea.nanoevents.BaseSchema": [[29, 3, 1, "", "behavior"], [29, 3, 1, "", "form"]], "coffea.nanoevents.DelphesSchema": [[30, 3, 1, "", "behavior"], [30, 3, 1, "", "docstrings"], [30, 3, 1, "", "mixins"], [30, 3, 1, "", "singletons"], [30, 2, 1, "", "v1"], [30, 3, 1, "", "warn_missing_crossrefs"]], "coffea.nanoevents.NanoAODSchema": [[31, 3, 1, "", "all_cross_references"], [31, 3, 1, "", "behavior"], [31, 3, 1, "", "mixins"], [31, 3, 1, "", "nested_index_items"], [31, 3, 1, "", "nested_items"], [31, 3, 1, "", "special_items"], [31, 2, 1, "", "v5"], [31, 2, 1, "", "v6"], [31, 2, 1, "", "v7"], [31, 3, 1, "", "warn_missing_crossrefs"]], "coffea.nanoevents.NanoEventsFactory": [[32, 2, 1, "", "events"], [32, 2, 1, "", "from_parquet"], [32, 2, 1, "", "from_preloaded"], [32, 2, 1, "", "from_root"]], "coffea.nanoevents.PDUNESchema": [[33, 3, 1, "", "behavior"], [33, 3, 1, "", "mixins"], [33, 3, 1, "", "top_objects"]], "coffea.nanoevents.PFNanoAODSchema": [[34, 3, 1, "", "all_cross_references"], [34, 3, 1, "", "mixins"]], "coffea.nanoevents.PHYSLITESchema": [[35, 3, 1, "", "behavior"], [35, 3, 1, "", "mixins"], [35, 3, 1, "", "truth_collections"]], "coffea.nanoevents.TreeMakerSchema": [[36, 3, 1, "", "behavior"], [36, 2, 1, "", "uproot_writeable"]], "coffea.nanoevents.methods": [[111, 0, 0, "-", "base"], [112, 0, 0, "-", "candidate"], [113, 0, 0, "-", "nanoaod"], [114, 0, 0, "-", "vector"]], "coffea.nanoevents.methods.base": [[37, 1, 1, "", "NanoCollection"], [38, 1, 1, "", "NanoEvents"], [39, 1, 1, "", "Systematic"]], "coffea.nanoevents.methods.base.NanoEvents": [[38, 3, 1, "", "metadata"]], "coffea.nanoevents.methods.base.Systematic": [[39, 2, 1, "", "add_kind"], [39, 2, 1, "", "add_systematic"], [39, 2, 1, "", "describe_variations"], [39, 2, 1, "", "explodes_how"], [39, 3, 1, "", "systematics"]], "coffea.nanoevents.methods.candidate": [[40, 1, 1, "", "Candidate"], [41, 1, 1, "", "PtEtaPhiECandidate"], [42, 1, 1, "", "PtEtaPhiMCandidate"]], "coffea.nanoevents.methods.candidate.Candidate": [[40, 2, 1, "", "add"], [40, 2, 1, "", "sum"]], "coffea.nanoevents.methods.nanoaod": [[43, 1, 1, "", "AssociatedPFCand"], [44, 1, 1, "", "AssociatedSV"], [45, 1, 1, "", "Electron"], [46, 1, 1, "", "FatJet"], [47, 1, 1, "", "FsrPhoton"], [48, 1, 1, "", "GenParticle"], [49, 1, 1, "", "GenVisTau"], [50, 1, 1, "", "Jet"], [51, 1, 1, "", "LowPtElectron"], [52, 1, 1, "", "MissingET"], [53, 1, 1, "", "Muon"], [54, 1, 1, "", "PFCand"], [55, 1, 1, "", "Photon"], [56, 1, 1, "", "PtEtaPhiMCollection"], [57, 1, 1, "", "SecondaryVertex"], [58, 1, 1, "", "Tau"], [59, 1, 1, "", "Vertex"]], "coffea.nanoevents.methods.nanoaod.AssociatedPFCand": [[43, 3, 1, "", "collection_map"], [43, 3, 1, "", "jet"], [43, 3, 1, "", "pf"]], "coffea.nanoevents.methods.nanoaod.AssociatedSV": [[44, 3, 1, "", "collection_map"], [44, 3, 1, "", "jet"], [44, 3, 1, "", "sv"]], "coffea.nanoevents.methods.nanoaod.Electron": [[45, 3, 1, "", "FAIL"], [45, 3, 1, "", "LOOSE"], [45, 3, 1, "", "MEDIUM"], [45, 3, 1, "", "TIGHT"], [45, 3, 1, "", "VETO"], [45, 3, 1, "", "isLoose"], [45, 3, 1, "", "isMedium"], [45, 3, 1, "", "isTight"], [45, 3, 1, "", "isVeto"], [45, 3, 1, "", "matched_gen"], [45, 3, 1, "", "matched_jet"], [45, 3, 1, "", "matched_photon"]], "coffea.nanoevents.methods.nanoaod.FatJet": [[46, 3, 1, "", "LOOSE"], [46, 3, 1, "", "TIGHT"], [46, 3, 1, "", "TIGHTLEPVETO"], [46, 3, 1, "", "constituents"], [46, 3, 1, "", "isLoose"], [46, 3, 1, "", "isTight"], [46, 3, 1, "", "isTightLeptonVeto"], [46, 3, 1, "", "matched_gen"], [46, 3, 1, "", "subjets"]], "coffea.nanoevents.methods.nanoaod.FsrPhoton": [[47, 3, 1, "", "matched_muon"]], "coffea.nanoevents.methods.nanoaod.GenParticle": [[48, 3, 1, "", "FLAGS"], [48, 3, 1, "", "children"], [48, 3, 1, "", "distinctChildren"], [48, 3, 1, "", "distinctChildrenDeep"], [48, 3, 1, "", "distinctParent"], [48, 2, 1, "", "hasFlags"], [48, 3, 1, "", "parent"]], "coffea.nanoevents.methods.nanoaod.GenVisTau": [[49, 3, 1, "", "parent"]], "coffea.nanoevents.methods.nanoaod.Jet": [[50, 3, 1, "", "LOOSE"], [50, 3, 1, "", "TIGHT"], [50, 3, 1, "", "TIGHTLEPVETO"], [50, 3, 1, "", "constituents"], [50, 3, 1, "", "isLoose"], [50, 3, 1, "", "isTight"], [50, 3, 1, "", "isTightLeptonVeto"], [50, 3, 1, "", "matched_electrons"], [50, 3, 1, "", "matched_gen"], [50, 3, 1, "", "matched_muons"]], "coffea.nanoevents.methods.nanoaod.LowPtElectron": [[51, 3, 1, "", "matched_electron"], [51, 3, 1, "", "matched_gen"], [51, 3, 1, "", "matched_photon"]], "coffea.nanoevents.methods.nanoaod.MissingET": [[52, 3, 1, "", "r"]], "coffea.nanoevents.methods.nanoaod.Muon": [[53, 3, 1, "", "matched_fsrPhoton"], [53, 3, 1, "", "matched_gen"], [53, 3, 1, "", "matched_jet"]], "coffea.nanoevents.methods.nanoaod.Photon": [[55, 3, 1, "", "FAIL"], [55, 3, 1, "", "LOOSE"], [55, 3, 1, "", "MEDIUM"], [55, 3, 1, "", "TIGHT"], [55, 3, 1, "", "charge"], [55, 3, 1, "", "isLoose"], [55, 3, 1, "", "isMedium"], [55, 3, 1, "", "isTight"], [55, 3, 1, "", "mass"], [55, 3, 1, "", "matched_electron"], [55, 3, 1, "", "matched_gen"], [55, 3, 1, "", "matched_jet"]], "coffea.nanoevents.methods.nanoaod.SecondaryVertex": [[57, 3, 1, "", "p4"]], "coffea.nanoevents.methods.nanoaod.Tau": [[58, 3, 1, "", "matched_gen"], [58, 3, 1, "", "matched_jet"]], "coffea.nanoevents.methods.nanoaod.Vertex": [[59, 3, 1, "", "pos"]], "coffea.nanoevents.methods.vector": [[60, 1, 1, "", "LorentzVector"], [61, 1, 1, "", "PolarTwoVector"], [62, 1, 1, "", "PtEtaPhiELorentzVector"], [63, 1, 1, "", "PtEtaPhiMLorentzVector"], [64, 1, 1, "", "SphericalThreeVector"], [65, 1, 1, "", "ThreeVector"], [66, 1, 1, "", "TwoVector"]], "coffea.nanoevents.methods.vector.LorentzVector": [[60, 2, 1, "", "absolute"], [60, 2, 1, "", "add"], [60, 2, 1, "", "boost"], [60, 3, 1, "", "boostvec"], [60, 2, 1, "", "delta_r"], [60, 2, 1, "", "delta_r2"], [60, 3, 1, "", "energy"], [60, 3, 1, "", "eta"], [60, 3, 1, "", "mass"], [60, 3, 1, "", "mass2"], [60, 2, 1, "", "metric_table"], [60, 2, 1, "", "multiply"], [60, 2, 1, "", "nearest"], [60, 2, 1, "", "negative"], [60, 3, 1, "", "pvec"], [60, 2, 1, "", "subtract"], [60, 2, 1, "", "sum"]], "coffea.nanoevents.methods.vector.PolarTwoVector": [[61, 2, 1, "", "multiply"], [61, 2, 1, "", "negative"], [61, 3, 1, "", "phi"], [61, 3, 1, "", "r"], [61, 3, 1, "", "r2"], [61, 3, 1, "", "x"], [61, 3, 1, "", "y"]], "coffea.nanoevents.methods.vector.PtEtaPhiELorentzVector": [[62, 3, 1, "", "E"], [62, 3, 1, "", "energy"], [62, 3, 1, "", "eta"], [62, 2, 1, "", "multiply"], [62, 2, 1, "", "negative"], [62, 3, 1, "", "phi"], [62, 3, 1, "", "pt"], [62, 3, 1, "", "r"], [62, 3, 1, "", "rho"], [62, 3, 1, "", "rho2"], [62, 3, 1, "", "t"], [62, 3, 1, "", "theta"], [62, 3, 1, "", "z"]], "coffea.nanoevents.methods.vector.PtEtaPhiMLorentzVector": [[63, 3, 1, "", "E"], [63, 3, 1, "", "eta"], [63, 3, 1, "", "mass"], [63, 3, 1, "", "mass2"], [63, 2, 1, "", "multiply"], [63, 2, 1, "", "negative"], [63, 3, 1, "", "phi"], [63, 3, 1, "", "pt"], [63, 3, 1, "", "r"], [63, 3, 1, "", "rho"], [63, 3, 1, "", "rho2"], [63, 3, 1, "", "t"], [63, 3, 1, "", "theta"], [63, 3, 1, "", "z"]], "coffea.nanoevents.methods.vector.SphericalThreeVector": [[64, 2, 1, "", "multiply"], [64, 2, 1, "", "negative"], [64, 3, 1, "", "p"], [64, 3, 1, "", "p2"], [64, 3, 1, "", "r"], [64, 3, 1, "", "rho"], [64, 3, 1, "", "theta"], [64, 3, 1, "", "z"]], "coffea.nanoevents.methods.vector.ThreeVector": [[65, 2, 1, "", "absolute"], [65, 2, 1, "", "add"], [65, 2, 1, "", "cross"], [65, 2, 1, "", "dot"], [65, 2, 1, "", "multiply"], [65, 2, 1, "", "negative"], [65, 3, 1, "", "p"], [65, 3, 1, "", "p2"], [65, 3, 1, "", "pz"], [65, 3, 1, "", "rho"], [65, 3, 1, "", "rho2"], [65, 2, 1, "", "subtract"], [65, 2, 1, "", "sum"], [65, 3, 1, "", "theta"], [65, 3, 1, "", "unit"]], "coffea.nanoevents.methods.vector.TwoVector": [[66, 2, 1, "", "absolute"], [66, 2, 1, "", "add"], [66, 2, 1, "", "delta_phi"], [66, 2, 1, "", "divide"], [66, 2, 1, "", "dot"], [66, 2, 1, "", "multiply"], [66, 2, 1, "", "negative"], [66, 3, 1, "", "phi"], [66, 3, 1, "", "pt"], [66, 3, 1, "", "pt2"], [66, 3, 1, "", "px"], [66, 3, 1, "", "py"], [66, 3, 1, "", "r"], [66, 3, 1, "", "r2"], [66, 2, 1, "", "subtract"], [66, 2, 1, "", "sum"], [66, 3, 1, "", "unit"]], "coffea.processor": [[67, 1, 1, "", "AccumulatorABC"], [68, 1, 1, "", "DaskExecutor"], [69, 1, 1, "", "FuturesExecutor"], [70, 1, 1, "", "IterativeExecutor"], [71, 1, 1, "", "LazyDataFrame"], [72, 1, 1, "", "NanoAODSchema"], [73, 1, 1, "", "PackedSelection"], [74, 1, 1, "", "ParslExecutor"], [75, 1, 1, "", "ProcessorABC"], [76, 1, 1, "", "Runner"], [77, 1, 1, "", "TreeMakerSchema"], [78, 1, 1, "", "Weights"], [79, 1, 1, "", "WorkQueueExecutor"], [80, 4, 1, "", "accumulate"], [81, 1, 1, "", "column_accumulator"], [82, 3, 1, "", "dask_executor"], [83, 1, 1, "", "defaultdict_accumulator"], [84, 1, 1, "", "dict_accumulator"], [85, 3, 1, "", "futures_executor"], [86, 3, 1, "", "iterative_executor"], [87, 1, 1, "", "list_accumulator"], [88, 3, 1, "", "parsl_executor"], [89, 4, 1, "", "run_spark_job"], [90, 1, 1, "", "set_accumulator"], [91, 1, 1, "", "value_accumulator"], [92, 3, 1, "", "work_queue_executor"]], "coffea.processor.AccumulatorABC": [[67, 2, 1, "", "add"], [67, 2, 1, "", "identity"]], "coffea.processor.DaskExecutor": [[68, 2, 1, "", "__call__"], [68, 3, 1, "", "client"], [68, 3, 1, "", "heavy_input"], [68, 3, 1, "", "priority"], [68, 3, 1, "", "retries"], [68, 3, 1, "", "treereduction"], [68, 3, 1, "", "use_dataframes"], [68, 3, 1, "", "worker_affinity"]], "coffea.processor.FuturesExecutor": [[69, 2, 1, "", "__call__"], [69, 3, 1, "", "mergepool"], [69, 3, 1, "", "merging"], [69, 3, 1, "", "recoverable"], [69, 3, 1, "", "tailtimeout"], [69, 3, 1, "", "workers"]], "coffea.processor.IterativeExecutor": [[70, 2, 1, "", "__call__"], [70, 3, 1, "", "workers"]], "coffea.processor.LazyDataFrame": [[71, 3, 1, "", "available"], [71, 3, 1, "", "columns"], [71, 3, 1, "", "materialized"], [71, 3, 1, "", "metadata"], [71, 2, 1, "", "preload"], [71, 3, 1, "", "size"]], "coffea.processor.NanoAODSchema": [[72, 3, 1, "", "all_cross_references"], [72, 3, 1, "", "behavior"], [72, 3, 1, "", "mixins"], [72, 3, 1, "", "nested_index_items"], [72, 3, 1, "", "nested_items"], [72, 3, 1, "", "special_items"], [72, 2, 1, "", "v5"], [72, 2, 1, "", "v6"], [72, 2, 1, "", "v7"], [72, 3, 1, "", "warn_missing_crossrefs"]], "coffea.processor.PackedSelection": [[73, 2, 1, "", "add"], [73, 2, 1, "", "all"], [73, 3, 1, "", "names"], [73, 2, 1, "", "require"]], "coffea.processor.ParslExecutor": [[74, 2, 1, "", "__call__"], [74, 3, 1, "", "config"], [74, 3, 1, "", "jobs_executors"], [74, 3, 1, "", "merges_executors"], [74, 3, 1, "", "merging"], [74, 3, 1, "", "recoverable"], [74, 3, 1, "", "tailtimeout"]], "coffea.processor.ProcessorABC": [[75, 2, 1, "", "postprocess"], [75, 2, 1, "", "process"]], "coffea.processor.Runner": [[76, 2, 1, "", "__call__"], [76, 3, 1, "", "align_clusters"], [76, 2, 1, "", "automatic_retries"], [76, 3, 1, "", "cachestrategy"], [76, 3, 1, "", "chunksize"], [76, 3, 1, "", "dynamic_chunksize"], [76, 3, 1, "", "format"], [76, 2, 1, "", "get_cache"], [76, 3, 1, "", "maxchunks"], [76, 3, 1, "", "metadata_cache"], [76, 2, 1, "", "metadata_fetcher"], [76, 3, 1, "", "mmap"], [76, 3, 1, "", "pre_executor"], [76, 2, 1, "", "preprocess"], [76, 3, 1, "", "processor_compression"], [76, 2, 1, "", "read_coffea_config"], [76, 3, 1, "", "retries"], [76, 2, 1, "", "run"], [76, 3, 1, "", "savemetrics"], [76, 3, 1, "", "skipbadfiles"], [76, 3, 1, "", "use_dataframes"], [76, 3, 1, "", "use_skyhook"], [76, 3, 1, "", "xrootdtimeout"]], "coffea.processor.TreeMakerSchema": [[77, 3, 1, "", "behavior"], [77, 2, 1, "", "uproot_writeable"]], "coffea.processor.Weights": [[78, 2, 1, "", "add"], [78, 2, 1, "", "partial_weight"], [78, 3, 1, "", "variations"], [78, 2, 1, "", "weight"]], "coffea.processor.WorkQueueExecutor": [[79, 2, 1, "", "__call__"], [79, 3, 1, "", "bar_format"], [79, 3, 1, "", "chunks_accum_in_mem"], [79, 3, 1, "", "chunks_per_accum"], [79, 3, 1, "", "chunksize"], [79, 3, 1, "", "compression"], [79, 3, 1, "", "cores"], [79, 3, 1, "", "custom_init"], [79, 3, 1, "", "debug_log"], [79, 3, 1, "", "disk"], [79, 3, 1, "", "dynamic_chunksize"], [79, 3, 1, "", "environment_file"], [79, 3, 1, "", "events_total"], [79, 3, 1, "", "fast_terminate_workers"], [79, 3, 1, "", "filepath"], [79, 3, 1, "", "gpus"], [79, 3, 1, "", "manager_name"], [79, 3, 1, "", "master_name"], [79, 3, 1, "", "memory"], [79, 3, 1, "", "password_file"], [79, 3, 1, "", "port"], [79, 3, 1, "", "print_stdout"], [79, 3, 1, "", "resource_monitor"], [79, 3, 1, "", "resources_mode"], [79, 3, 1, "", "retries"], [79, 3, 1, "", "split_on_exhaustion"], [79, 3, 1, "", "ssl"], [79, 3, 1, "", "stats_log"], [79, 3, 1, "", "status_display_interval"], [79, 3, 1, "", "tasks_accum_log"], [79, 3, 1, "", "transactions_log"], [79, 3, 1, "", "treereduction"], [79, 3, 1, "", "verbose"], [79, 3, 1, "", "wrapper"], [79, 3, 1, "", "x509_proxy"]], "coffea.processor.column_accumulator": [[81, 2, 1, "", "add"], [81, 2, 1, "", "identity"], [81, 3, 1, "", "value"]], "coffea.processor.defaultdict_accumulator": [[83, 2, 1, "", "add"], [83, 2, 1, "", "identity"]], "coffea.processor.dict_accumulator": [[84, 2, 1, "", "add"], [84, 2, 1, "", "identity"]], "coffea.processor.list_accumulator": [[87, 2, 1, "", "add"], [87, 2, 1, "", "identity"]], "coffea.processor.set_accumulator": [[90, 2, 1, "", "add"], [90, 2, 1, "", "identity"]], "coffea.processor.value_accumulator": [[91, 2, 1, "", "add"], [91, 2, 1, "", "identity"]], "coffea.util": [[93, 1, 1, "", "SpeedColumn"], [94, 4, 1, "", "awkward_rewrap"], [95, 4, 1, "", "deprecate"], [96, 4, 1, "", "load"], [97, 4, 1, "", "rewrap_recordarray"], [98, 4, 1, "", "rich_bar"], [99, 4, 1, "", "save"]], "coffea.util.SpeedColumn": [[93, 2, 1, "", "render"]]}, "objnames": {"0": ["py", "module", "Python module"], "1": ["py", "class", "Python class"], "2": ["py", "method", "Python method"], "3": ["py", "attribute", "Python attribute"], "4": ["py", "function", "Python function"]}, "objtypes": {"0": "py:module", "1": "py:class", "2": "py:method", "3": "py:attribute", "4": "py:function"}, "terms": {"": [4, 30, 36, 77, 79, 117, 119, 120, 121, 123], "0": [1, 3, 4, 6, 9, 10, 11, 16, 30, 32, 45, 46, 50, 55, 67, 68, 71, 79, 103, 104, 117, 118, 119, 120, 121, 123], "00": [119, 123], "00000000e": 119, "00000e": 119, "00209800e": 119, "002894": 119, "0077519416809082": 117, "01": [118, 119], "0109068": 30, "0123": 121, "02": 119, "02040816": 119, "0252539": 117, "02863368": 118, "03": [118, 119], "0336": 121, "04": 119, "04081633": 119, "05914783": 117, "0595": 118, "06": [117, 123], "06122449": 119, "06528643": 117, "07": [118, 119, 121], "07063197026022305": 119, "08": 118, "08163265": 119, "0858": 120, "09": [117, 118], "0x10d84b550": 6, "0x134ceb190": 118, "0x134eac6a0": 118, "0x134eb87c0": 118, "0x134f44f40": 118, "0x7f08123c89d0": 121, "0x7f083c0c6310": 121, "0x7fa15ba1af10": 119, "0x7fa15bec6710": 119, "0x7fa15ce87f90": 119, "0x7fa15cead090": 119, "0x7fa15cead0d0": 119, "0x7fa15cead1d0": 119, "0x7fa15cead210": 119, "0x7fa15cead250": 119, "0x7fa15cead350": 119, "0x7fa15cead610": 119, "0x7fa15cead710": 119, "0x7fa15cead750": 119, "0x7fa15ceada90": 119, "0x7fa15ceadb50": 119, "0x7fa15ceadd90": 119, "0x7fa15ceade90": 119, "0x7fa15ceadfd0": 119, "0x7fa15cf61390": 119, "0x7fa15de8e650": 119, "0x7fa15e7ab7d0": 119, "0x7fa15e7ab810": 119, "0x7fa15ea2c710": 119, "0x7fa15ea2c790": 119, "0x7fa15ea2c7d0": 119, "0x7fa15ea2c810": 119, "0x7fa15ea2c850": 119, "0x7fa15ea2c8d0": 119, "0x7fa15ea2c910": 119, "0x7fa15ea2c950": 119, "0x7fa15ea2cd50": 119, "0x7fa15eb2d710": 119, "0x7fa15eb307d0": 119, "0x7fa15eb361d0": 119, "0x7fa15eb36250": 119, "0x7fa15eb36310": 119, "0x7fa15eb363d0": 119, "1": [2, 3, 4, 6, 10, 12, 13, 15, 25, 30, 36, 40, 45, 46, 48, 50, 55, 60, 65, 66, 68, 69, 70, 74, 76, 77, 78, 79, 81, 102, 103, 104, 114, 117, 118, 119, 120, 121, 123], "10": [6, 79, 117, 118, 119, 120, 121, 123], "100": [10, 67, 69, 74, 118, 119, 123], "1000": [114, 119, 121, 123], "10000": [118, 119, 121], "100000": [76, 79, 123], "100056": 123, "1000560": 121, "100_000": 121, "100k": 76, "10204082": 119, "10257766": 119, "10489525": 117, "10625": 120, "11": [117, 118, 119, 120, 121], "111": 120, "113": 119, "1157524": 117, "1165": 117, "1195": 117, "12": [117, 118, 119, 120, 121], "120": [76, 117, 123], "12088952": 117, "121": 120, "12244898": 119, "122819923": 121, "125": 119, "126744": 117, "1287": 16, "12876": 120, "13": [117, 118, 119, 120, 121], "1309": 16, "13600e": 119, "137": 119, "138": 119, "13884": 120, "14": [117, 118, 119, 120, 121], "14285714": 119, "143": 119, "143055": 121, "143618": 121, "1499064": 121, "15": [102, 117, 118, 119, 120, 121], "150": 118, "1530546": 117, "153664": 121, "16": [89, 117, 118, 119, 120, 121], "16326531": 119, "167": 119, "16950599e": 119, "17": [118, 119, 120, 121], "17224": 117, "17258657": 117, "17997": 117, "18": [119, 120], "18367347": 119, "1876": 121, "18763094": 117, "19": [118, 119, 120], "192074": 121, "192500": 121, "195": 121, "19978": 117, "1d": [0, 4, 12, 117, 119], "1f": 93, "1f78b4": 119, "1mb": 76, "2": [3, 4, 6, 16, 25, 30, 45, 46, 50, 55, 60, 61, 62, 63, 64, 65, 66, 79, 81, 103, 114, 117, 118, 119, 120, 121, 123], "20": [6, 10, 68, 79, 117, 118, 119, 120, 121], "200": [67, 121], "2000": [67, 123], "200000": 89, "201171875": 117, "20117188": 117, "2020": 119, "20226132": 119, "20408163": 119, "2048": 76, "20687727e": 119, "20829e": 117, "20983": 117, "21": [119, 120], "211": 118, "212k": 119, "21447283": 117, "217": 120, "22": [118, 119, 120], "22168": 117, "22218679": 117, "2244898": 119, "22732": 117, "22734": 117, "22913": 120, "22998": 117, "23": [119, 120], "23236": 117, "23502": 117, "23600e": 119, "23903": 117, "23933": 117, "23975181e": 119, "24": 119, "24141": 117, "24164e": 119, "24243e": 117, "24344e": 119, "24385": 117, "24397": 117, "24421": 117, "24489796": 119, "24770": 117, "24854": 117, "24885": 117, "24906": 117, "24977": 117, "25": [118, 119, 120], "25105": 117, "25134": 117, "25230": 117, "25294": 117, "25448": 117, "25583": 117, "257": 120, "258": 120, "25857": 117, "25869": 117, "26": [119, 120], "26061": 117, "26067": 117, "26254": 117, "26331": 117, "265271292167853": 120, "26530612": 119, "26535": 117, "26779": 117, "26972579956055": 117, "27": [118, 119], "27009": 120, "27086417": 117, "27253": 117, "27398292": 117, "27428405": 117, "27678371840": 117, "28": [118, 119], "28571429": 119, "29": [118, 119, 120], "293": 118, "29949574": 117, "2a": 103, "2d": [12, 13, 26, 66, 114, 119], "2g": 13, "3": [3, 4, 6, 14, 25, 45, 55, 64, 65, 68, 81, 89, 102, 103, 114, 117, 118, 119, 120, 121, 123], "30": [67, 118, 119], "300": 121, "30194498": 119, "30612245": 119, "306462_13tev_promptreco_collisions17_json": 26, "31": [117, 118, 119, 120], "31910775": 117, "32": [0, 117, 118, 119, 123], "32653061": 119, "33": [118, 119], "33051391": 117, "33a02c": 119, "34": [118, 119, 120], "34693878": 119, "35": [118, 119], "357": 119, "36": [117, 118, 119], "36319225": 118, "36734694": 119, "37": [118, 119], "38": [117, 118, 119], "381": 118, "3849": 121, "3877551": 119, "39": [117, 118, 119, 120, 121], "3a": 103, "3d": [62, 63, 64, 65, 114], "4": [3, 30, 45, 57, 69, 74, 81, 103, 117, 118, 119, 120, 121, 123], "40": [103, 117, 118, 119, 120], "40000e": 119, "400224": 123, "40162865": 119, "40816327": 119, "41": 118, "41659e": 117, "4196682": 117, "42": 119, "42857143": 119, "4375": 117, "44": [117, 119], "444": 118, "4481": 120, "44897959": 119, "45": [118, 120], "46": [118, 119], "46938776": 119, "47": [118, 119], "48": 119, "485": 121, "48979592": 119, "49": 119, "49114e": 117, "4939": 121, "4951": 121, "49672142894": 121, "498": 118, "4mu": 121, "5": [3, 6, 30, 69, 74, 81, 103, 117, 118, 119, 120, 121, 123], "50": [118, 119], "500": 118, "50101615": 117, "50131231": 119, "51": 118, "51020408": 119, "51091823": 117, "519403": 121, "52": [118, 119], "520002": 121, "53061224": 119, "53583916": 117, "5394515991211": 117, "54": 119, "5463199": 121, "55": [118, 119], "55102041": 119, "55356743680": 117, "55691586": 118, "56": 118, "566": 118, "57": [118, 119], "57142857": 119, "578762": 117, "579925650557621": 119, "58": 119, "59": [118, 119], "59183673": 119, "6": [81, 102, 103, 117, 118, 119, 120, 121, 123], "60": [76, 103, 117, 118, 119, 121, 123], "60000e": 119, "60099597": 119, "6122449": 119, "62": 119, "621215": 117, "62516629": 117, "63": 119, "63095092773438": 117, "63265306": 119, "64": [73, 119], "64304079": 118, "65": 118, "65306122": 119, "65472": 121, "66": 119, "66128870": 121, "6674144268035889": 117, "670": 120, "67346939": 119, "67352230e": 119, "676": 121, "68": [9, 11, 16, 118, 119], "68057538": 117, "68164558": 117, "6826894921370859": [9, 11, 16], "68363205830444": 120, "68492970e": 119, "68720e": 119, "68846612": 117, "69": 119, "69273076": 117, "69387755": 119, "7": [117, 118, 119, 120], "70": [118, 119], "70067963": 119, "705": 119, "71428571": 119, "72": [118, 119], "7200": 121, "73": 117, "73469388": 119, "735": [36, 77], "74": 119, "75": 118, "75510204": 119, "76": [117, 120], "7601k": 119, "76277e": 121, "76279e": 121, "76666849": 117, "77": 118, "7755102": 119, "78": 118, "78332574": 117, "79": 118, "79591837": 119, "8": [117, 118, 119, 120, 121, 123], "80": [117, 118, 119], "80036329": 119, "807": 118, "81547546386719": 117, "81632653": 119, "81867": 121, "81873": 121, "82170": 121, "82303": 121, "82351": 121, "82352": 121, "827": 118, "82814944": 117, "8289": 121, "83": 118, "83120e": 119, "83673469": 119, "84": [118, 120], "84952343": 117, "85": 118, "85661211": 117, "85714286": 119, "86": 118, "87": 120, "875": 117, "87755102": 119, "88": 120, "88614286e": 119, "89": 120, "890625": 117, "89462374": 117, "89795918": 119, "9": [79, 117, 118, 119, 120, 121, 123], "90": [118, 119, 120], "90004695": 119, "904": 118, "909": 118, "91": [119, 120, 121], "91084135e": 119, "9123": [79, 123], "91836735": 119, "92136851": 117, "925": 118, "93483174": 117, "93877551": 119, "94": 120, "941": 118, "946": 118, "95": [118, 119], "953": 118, "95918367": 119, "969": 118, "972": 118, "97278307": 117, "978": 118, "97959184": 119, "989": 118, "98python3": 103, "999380": 121, "99973061": 119, "A": [1, 3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 15, 26, 29, 32, 37, 39, 40, 41, 42, 48, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 74, 75, 76, 79, 81, 83, 84, 87, 89, 90, 91, 101, 103, 114, 115, 117, 119, 121, 123], "AND": 117, "And": 117, "As": [67, 119, 120, 121], "At": [103, 118, 121], "But": [118, 120], "By": [73, 102, 120], "For": [16, 30, 31, 36, 60, 72, 76, 77, 79, 89, 118, 119, 120, 123], "If": [0, 2, 3, 6, 12, 13, 14, 15, 16, 25, 31, 48, 60, 68, 69, 70, 72, 73, 74, 76, 78, 79, 81, 103, 121, 123], "In": [6, 12, 61, 62, 63, 64, 74, 89, 100, 103, 118, 119, 120, 123], "It": [19, 21, 22, 23, 25, 75, 83, 84, 100, 102, 117, 119, 123], "No": [6, 75, 118], "Not": 76, "OR": 0, "Of": [119, 121], "One": [67, 71, 103, 119, 120, 121], "Or": 123, "Such": [36, 77, 117], "The": [0, 2, 3, 4, 5, 6, 8, 14, 24, 25, 26, 29, 30, 31, 32, 34, 35, 36, 60, 67, 68, 69, 72, 75, 77, 78, 79, 81, 89, 100, 101, 102, 103, 114, 117, 118, 119, 120, 121, 123], "Then": [117, 119, 121], "There": [31, 36, 72, 77, 102, 103, 119], "These": [36, 77, 100, 104, 105, 107, 108, 109, 114, 120], "To": [69, 100, 103, 117, 118, 119, 123], "With": [103, 123], "_": [31, 36, 72, 77, 119], "__": 120, "__add__": [67, 117, 119], "__call__": [3, 24, 28, 68, 69, 70, 74, 76, 79, 102], "__doc__": [117, 120], "__getitem__": 4, "__iadd__": 67, "__init__": [75, 119, 121], "__radd__": 67, "__record__": 120, "_base": 69, "_bin": 119, "_connect": 121, "_eventindex": 35, "_flag": 75, "_ireduc": 4, "_jet1": 21, "_level_ord": 19, "_numpi": 121, "_size": 30, "_sumw": 119, "a6cee3": 119, "aarongorka": 103, "ab": [114, 118, 120, 121], "abc": [6, 75, 76, 115, 116], "abil": 119, "abl": [67, 103], "about": [76, 103, 120, 121, 123], "abov": [79, 103, 117, 118], "absolut": [60, 65, 66, 102], "abstract": [39, 67, 75, 100, 121], "acc": 67, "accept": [3, 99, 118, 119], "access": [29, 32, 36, 71, 77, 100, 103, 117, 119, 120, 121], "access_log": 32, "accessor": [48, 49, 108], "accomplish": [31, 72], "accord": [6, 13, 31, 35, 46, 50, 72, 79, 123], "accum": 80, "accumul": [1, 6, 67, 68, 69, 70, 74, 75, 76, 79, 81, 83, 84, 87, 89, 90, 91, 100, 101, 102, 104, 106, 115, 121, 123], "accumulat": [68, 69, 70, 74, 79, 117], "accumulatorabc": [1, 6, 81, 83, 84, 87, 90, 91, 100, 102, 104, 106, 115, 117], "achiev": 121, "acquir": 120, "action": [76, 89], "activ": [74, 103, 123], "actual": 121, "acuumul": 117, "ad": [0, 1, 4, 36, 67, 73, 77, 81, 83, 84, 87, 90, 91, 114, 117, 119, 121], "adapt": [76, 102], "add": [0, 1, 2, 6, 25, 32, 40, 60, 65, 66, 67, 73, 78, 81, 83, 84, 87, 90, 91, 102, 103, 117, 119, 121, 123], "add_histo": 119, "add_kind": [39, 102], "add_multivari": [2, 102], "add_systemat": [39, 102], "add_weight_set": [24, 25, 102, 117, 118], "addabl": [68, 69, 70, 74, 76, 79, 80, 117], "addit": [2, 30, 31, 36, 61, 62, 63, 64, 66, 69, 71, 72, 77, 78, 79, 103, 120], "addition": [103, 119], "adef": 67, "adher": 5, "adjust": [61, 62, 63, 64, 119, 123], "administr": 103, "admiss": 6, "advanc": 37, "after": [14, 36, 67, 77, 119], "afterward": 119, "against": 103, "aggreg": 75, "agnost": 118, "agre": 118, "aha": 120, "aid": 119, "aim": 89, "ak": [114, 117, 118, 119, 120, 121, 123], "ak4": [36, 77, 118], "ak8": 118, "aka": [69, 74, 119], "algorithm": 118, "alia": [60, 62, 63, 64, 65, 66, 82, 85, 86, 88, 92], "alias": 114, "alien": 102, "align_clust": [76, 102], "all": [0, 2, 3, 6, 16, 19, 21, 22, 23, 25, 30, 31, 35, 36, 39, 60, 69, 72, 73, 74, 77, 78, 89, 100, 102, 103, 117, 118, 119, 120, 121], "all_cross_refer": [31, 34, 72, 102], "allclos": 114, "allcut": 117, "allnan": 6, "alloc": [79, 123], "allow": [0, 4, 6, 10, 25, 100, 117, 120, 121], "almost": 100, "along": [6, 79, 120], "alpha": [117, 119], "alpha_": 117, "alphaq": 30, "alphaqcd": 30, "alphasdown": 117, "alphasup": 117, "alreadi": [32, 69, 74, 79, 89, 103, 117], "also": [0, 2, 3, 69, 73, 76, 78, 102, 103, 114, 117, 118, 119, 120, 123], "alter": [31, 72, 102], "altern": [103, 120], "although": [71, 100, 103, 117, 120], "alwai": [3, 79, 103], "amount": [79, 103, 120, 121], "an": [0, 3, 4, 6, 13, 14, 24, 25, 28, 31, 34, 35, 36, 39, 40, 60, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 76, 77, 79, 81, 89, 91, 100, 101, 102, 103, 117, 118, 119, 120, 121, 123], "analog": 119, "analsyi": 120, "analys": 100, "analysi": [35, 101, 103, 104, 105, 107, 115, 121, 122, 123], "analysis_tool": [0, 1, 2, 102, 117], "analysiselectron": 35, "analysismuno": 35, "analyz": [100, 117], "angl": [30, 61, 62, 63, 64, 65, 66], "ani": [0, 1, 3, 6, 14, 25, 30, 31, 32, 60, 67, 68, 72, 75, 79, 81, 83, 84, 87, 90, 91, 93, 99, 102, 103, 117, 119, 120], "annoyingli": 103, "anoth": [1, 6, 27, 31, 34, 60, 65, 66, 67, 72, 81, 83, 84, 87, 90, 91, 119], "anyth": [89, 103], "anywher": [103, 118], "apach": [100, 102, 103], "api": 102, "appar": 119, "append": [60, 81], "appli": [6, 19, 25, 60, 101, 102, 117, 120], "applic": [100, 119, 123], "applying_correct": 117, "approach": 30, "appropri": [75, 119, 120, 121, 123], "approxim": [16, 121], "ar": [0, 2, 3, 4, 5, 6, 12, 15, 24, 25, 26, 28, 30, 31, 34, 35, 36, 48, 61, 62, 63, 64, 66, 67, 69, 72, 73, 74, 76, 77, 78, 79, 100, 101, 102, 103, 106, 109, 114, 117, 118, 119, 120, 121, 123], "arbitrari": [0, 5, 32, 38, 67, 73, 91, 117], "arbitrarili": [31, 34, 72], "arcsinh": [60, 62, 63], "arctan": [62, 63, 119], "arctan2": [61, 62, 63, 64, 65, 66], "area": [25, 30, 118], "arg": [0, 73, 76], "argmin": 121, "argsort": 121, "argu": 119, "argument": [0, 2, 5, 6, 24, 39, 48, 60, 68, 69, 70, 73, 74, 78, 79, 89, 117, 119, 120, 121, 123], "around": 118, "arr": 94, "arrai": [0, 2, 3, 4, 6, 14, 24, 26, 28, 30, 31, 32, 36, 40, 45, 46, 48, 50, 55, 60, 65, 66, 72, 73, 77, 78, 81, 100, 102, 104, 106, 114, 117, 118, 119, 120, 121], "array_equ": 119, "array_sourc": 32, "arraybuild": 121, "arxiv": 16, "ascend": 19, "assert": [114, 123], "assign": [31, 35, 72, 120], "assist": 120, "associ": [2, 15, 43, 44, 57, 78, 117, 118, 120], "associatedpfcand": [34, 102, 113], "associatedsv": [34, 102, 113], "assum": [2, 7, 24, 30, 31, 60, 65, 66, 68, 72, 78, 79, 83, 84, 117, 119, 121], "atan": 119, "atla": [35, 120], "attach": [30, 35, 39], "attempt": 75, "attribut": [0, 2, 3, 4, 5, 6, 7, 8, 19, 20, 21, 22, 23, 29, 30, 31, 32, 33, 34, 35, 36, 38, 39, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 55, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, 81, 114, 120], "authent": [79, 123], "auto": [2, 78, 79, 123], "automat": [79, 102, 112, 123], "automatic_retri": [76, 102], "autoscal": 119, "aux": 35, "auxdyn": 35, "auxilari": 118, "avail": [0, 2, 19, 22, 23, 24, 25, 31, 71, 72, 73, 78, 79, 102, 103, 117, 118, 119, 120, 121, 122, 123], "averag": [16, 30, 79, 119], "avg": 119, "avoid": [100, 103, 118, 119, 122], "awai": [69, 74, 120], "awkward": [0, 3, 29, 32, 60, 100, 102, 104, 114, 117, 118, 119, 120, 121, 123], "awkward1": 120, "awkward_rewrap": 102, "ax": [4, 6, 12, 13, 14, 15, 60, 102, 117, 118, 119, 121], "axhlin": 15, "axi": [4, 5, 6, 8, 12, 13, 14, 15, 40, 60, 61, 62, 63, 65, 66, 102, 106, 114, 117, 118, 119, 120, 121, 123], "axial": 114, "axis_nam": 6, "azimuth": [30, 61, 62, 63], "b": [3, 25, 26, 81, 101, 102, 103, 105, 117, 119], "b2df8a": 119, "back": [31, 34, 72, 119], "backend": 102, "balanc": 121, "band": 15, "bar": [15, 68, 69, 70, 74, 79, 123], "bar_format": [79, 102], "bare": [32, 121], "base": [0, 1, 2, 3, 4, 5, 6, 7, 8, 11, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 83, 84, 87, 90, 91, 93, 102, 110, 113, 115, 120, 121], "base_form": [29, 30, 31, 33, 34, 35, 36, 72, 77], "baseschema": [30, 31, 32, 33, 35, 36, 72, 76, 77, 102, 110, 115, 120, 121], "bash": [103, 118], "bash_sourc": 103, "basic": [29, 102, 111, 119], "batch": [69, 74, 100, 103, 123], "batch_typ": 123, "beam": [26, 30, 33], "becam": 119, "becaus": 119, "becom": [100, 103, 119, 120], "been": [30, 35, 79, 104, 117], "befor": [5, 12, 13, 15, 79, 103, 119], "begin": [121, 123], "begin_list": 121, "begin_tupl": 121, "behavior": [6, 12, 13, 14, 15, 29, 30, 31, 33, 35, 36, 67, 72, 77, 79, 90, 102, 114, 118, 119, 120, 121, 123], "being": [6, 68, 102, 121], "below": [103, 117, 118, 119, 122, 123], "best": 100, "bestz1": 121, "beta": 30, "betastar": 30, "better": [15, 103], "between": [30, 60, 66, 79, 100, 120, 123], "big": 102, "billion": 119, "bin": [3, 5, 6, 7, 8, 10, 12, 13, 14, 15, 16, 21, 22, 23, 67, 102, 103, 106, 118, 119], "bin_valu": 119, "binder": [117, 118, 119, 120, 121], "binomi": 9, "binomial_proportion_confidence_interv": 9, "binvar": 120, "binwnorm": [12, 13], "bird": 6, "bit": [46, 48, 50, 100, 120], "bitwidth": [0, 73], "black": 103, "blank": [12, 15], "blank_name_map": [20, 102, 118], "bloat": 103, "blog": 103, "bname": 71, "book": [67, 119], "bool": [0, 2, 3, 6, 12, 13, 15, 28, 60, 68, 69, 70, 73, 74, 76, 78, 79, 91, 120], "boolean": [0, 45, 46, 48, 50, 55, 73, 117, 120], "boost": [60, 102, 106, 119], "boost_histogram": 6, "boostvec": [60, 102], "boson": [120, 121], "both": [2, 6, 60, 78, 103, 123], "bottom": [3, 119], "bound": [3, 7, 16, 39, 118], "boundari": [4, 6, 7, 119], "branch": [29, 30, 31, 32, 36, 71, 72, 77, 120], "branch_nam": 120, "bregcorr": 118, "bregr": 118, "bril": 26, "brilcalc": 26, "bring": [101, 102], "broadcast": [6, 60, 68], "broadcast_arrai": 118, "broken": [19, 103], "btag": [2, 3, 25, 30, 105, 118], "btag_sf": 118, "btag_tool": [3, 101, 102], "btagalgo": 30, "btagcmva": 118, "btagcsvv2": 118, "btagdeepb": 118, "btagdeepc": 118, "btagdeepflavb": 118, "btagdeepflavc": 118, "btagphi": 30, "btagscalefactor": [102, 105, 118], "btovar": 123, "btv": 25, "btvsumpt2": 30, "bug": 103, "build": [17, 18, 25, 30, 31, 32, 35, 39, 72, 101, 102, 103, 112, 117, 119, 120, 121, 123], "builder": [29, 30, 31, 34, 35, 36, 72, 77, 121], "built": [30, 31, 36, 72, 77, 102, 106, 120], "builtin": 119, "bundl": 75, "byl": 26, "bypass": 103, "byte": 68, "c": [3, 9, 11, 16, 26, 81, 103, 117, 119, 123], "ca": 16, "cach": [25, 32, 76, 118, 120], "cachestrategi": [76, 102], "calcul": [2, 15, 16, 21, 22, 23, 26, 76, 78, 118, 121], "call": [3, 4, 8, 12, 13, 14, 15, 16, 24, 25, 68, 69, 70, 74, 79, 108, 118, 119, 120], "callabl": [31, 39, 60, 68, 69, 70, 72, 74, 76, 79, 91], "calojet02": 30, "calojet04": 30, "calojet08": 30, "calojet15": 30, "calomet": [31, 34, 72], "calorimet": 30, "can": [0, 2, 4, 5, 7, 8, 19, 21, 22, 23, 24, 25, 27, 30, 31, 34, 36, 60, 67, 69, 71, 72, 73, 75, 76, 77, 78, 89, 99, 100, 103, 114, 117, 118, 119, 120, 121, 123], "cancel": [69, 74], "candiat": 112, "candid": [34, 41, 42, 43, 54, 102, 113, 120, 121, 123], "cap": [12, 15], "capabl": 100, "captur": [69, 74], "care": [4, 103], "carlo": 102, "carri": [30, 120], "cartesian": [60, 61, 62, 63, 64, 65, 66, 114], "case": [5, 6, 12, 36, 60, 77, 103], "cat": [6, 102, 106, 119], "categor": 119, "categori": [5, 100, 117, 119], "caus": 123, "caveat": [103, 120], "cbar": 118, "cc7": 103, "ccl": 123, "cd": 103, "cell": [117, 120, 121], "center": [4, 13, 102, 119], "centos7": 103, "central": [3, 9, 11, 16, 117, 118, 120], "cern": [26, 103, 117, 121, 123], "cert": 79, "cert_294927": 26, "certain": [117, 121], "certif": 79, "ceval": 118, "ch": [26, 103, 117, 121, 123], "chain": [48, 112], "challeng": 119, "chang": [4, 5, 121, 123], "channel": 123, "charg": [30, 40, 41, 42, 55, 102, 112, 117, 121, 123], "charm": 3, "check": [6, 19, 28, 48, 75, 103, 119], "checkpoint": 69, "chemef": 118, "chhef": 118, "chi": 119, "child": [30, 48], "children": [35, 48, 102, 120], "children_form": [31, 72], "choos": [0, 121, 123], "chsmet": [31, 34, 72], "chunk": [31, 72, 75, 76, 79, 100, 121, 123], "chunks_accum_in_mem": [79, 102], "chunks_per_accum": [79, 102], "chunksiz": [76, 79, 102, 121, 123], "clamp": 118, "class": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 83, 84, 87, 89, 90, 91, 93, 100, 102, 117, 118, 119, 120, 121, 123], "classmethod": [3, 30, 31, 32, 36, 39, 72, 77], "cleanmask": 118, "clear": [6, 12, 13, 15, 27, 76, 102, 119, 120], "clearli": 119, "clibcorr": 118, "client": [68, 102], "clip": 3, "clone": 103, "clopper": [9, 15, 119], "clopper_pearson_interv": 102, "close": [10, 35, 39, 119, 120], "closest": [30, 60, 121], "cloud": 123, "cluster": [102, 103, 123], "cm": [25, 26, 28, 34, 101, 102, 105, 107, 109, 113, 120, 121], "cms_opendata_2012_nanoaod": [121, 123], "cmssw": [19, 21, 22, 23], "co": [61, 63, 64], "coalesces": 89, "coars": 119, "code": [30, 76, 89, 100, 102, 103, 118, 120, 121, 123], "codebas": 103, "coffe": 119, "coffea": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 117, 122, 123], "coffeaenv": 103, "coffeateam": [36, 77, 102, 103, 117, 118, 119, 120], "col": [14, 119], "col_overflow": 14, "collabor": 102, "collect": [6, 31, 34, 35, 36, 37, 56, 68, 69, 70, 72, 74, 76, 77, 79, 83, 99, 115, 118, 120, 121, 123], "collection_map": [43, 44, 102], "collid": 102, "collis": 100, "colllect": 120, "color": [13, 119], "colorbar": 118, "colorbrewer2": 119, "colormeshartist": 118, "column": [6, 14, 35, 39, 48, 71, 81, 89, 93, 100, 102, 103, 118, 119, 122], "column_accumul": [67, 102, 115], "columnar": [19, 21, 22, 23, 101, 104, 105, 107, 117], "com": [34, 36, 77, 103, 117, 118, 120], "comb": 3, "combin": [0, 35, 60, 67, 73, 117, 121], "combinedmuontrackparticl": 35, "come": [30, 120, 123], "command": [26, 103], "common": [15, 25, 118], "commun": [102, 120], "compact": [0, 73, 120], "compar": [102, 119], "compartment": 109, "compat": [6, 15, 30, 31, 60, 67, 72, 102, 103, 104, 114, 119, 120], "compil": [102, 119], "complet": [3, 69, 74, 79, 103, 123], "complex": [100, 102, 120], "compon": [30, 40, 60, 61, 62, 63, 64, 65, 66, 103], "compont": [60, 66], "composit": 112, "compress": [3, 68, 69, 70, 74, 79, 102, 121], "compromis": 79, "comput": [9, 11, 65, 66, 79, 100, 102, 103, 105, 107, 117, 118, 120, 121, 123], "concept": 102, "conclud": 119, "concret": 67, "concurr": [67, 69, 121], "conda": [79, 102, 103, 121, 123], "condor": [75, 103, 123], "condor_submit_work": 123, "cone": 118, "config": [26, 74, 89, 102], "configur": [31, 34, 35, 72, 74, 79, 120, 123], "conflict": [12, 13, 103], "conform": 119, "connect": [121, 123], "consid": [119, 120], "consist": [19, 117, 119], "constitu": [30, 46, 50, 102, 120], "construct": [6, 7, 30, 31, 48, 72, 74, 117, 118], "constructor": [5, 119, 120], "contain": [2, 3, 30, 36, 77, 78, 79, 100, 102, 115, 117, 120, 123], "content": [6, 12, 13, 14, 15, 25, 83, 84, 119, 120], "context": [39, 117], "continu": 121, "contrast": 100, "contribut": [30, 102, 120], "control": [6, 117, 123], "contructor": 24, "convei": 102, "conveni": [76, 89, 118, 119, 120], "convent": [60, 120], "convert": [6, 12, 13, 25, 30, 31, 34, 36, 72, 77, 89, 118], "cool": 103, "cooper": 123, "coordin": [6, 30, 36, 41, 42, 61, 64, 77, 114], "copi": [6, 102, 103, 117, 119, 120, 121], "core": [69, 79, 102, 103, 121, 123], "corr": 118, "correct": [2, 3, 19, 20, 21, 22, 23, 25, 78, 101, 102, 105, 107, 117], "corrected_jet": [18, 118], "correctedjetsfactori": [102, 107, 118], "correctedmetfactori": [102, 107], "correctionlib": [101, 102], "correctionset": 118, "corrector": [19, 118], "correl": 39, "correspond": [0, 2, 4, 5, 6, 28, 35, 36, 73, 77, 78, 81, 100, 103, 121], "corrl1": [19, 21, 22, 23], "cotang": 30, "could": [39, 109, 121], "count": [6, 16, 30, 31, 67, 72, 118, 119, 121], "coupl": 30, "cours": [119, 121], "cov": 119, "cover": 119, "coverag": [9, 11, 16], "cpu": [0, 73, 117], "cpython": 100, "creat": [4, 6, 10, 12, 13, 14, 15, 35, 37, 67, 69, 79, 89, 102, 117, 118, 119, 120, 121, 123], "creation": [89, 120, 123], "cross": [30, 31, 34, 35, 37, 65, 72, 102, 120], "crosssect": 30, "crosssectionerror": 30, "cset": 118, "csh": 103, "csv": [3, 25, 26, 118], "ctgtheta": 30, "curl": [118, 119], "current": [0, 2, 6, 27, 73, 76, 78, 79, 81, 100, 102, 109, 117, 119, 120], "custom": [8, 69, 74, 76, 79, 89, 118, 123], "custom_init": [79, 102], "cut": [45, 55, 67, 73, 117, 121, 123], "cut1": [0, 73], "cut2": [0, 73], "cut3": [0, 73], "cutbas": [45, 55], "cutflow": [67, 117, 121], "cvmf": [26, 102], "cycler": 119, "d": 6, "d0": 30, "d1": 30, "d2": 30, "dagger": 120, "dai": 103, "dame": 123, "daod_physlit": [35, 120], "dask": [68, 76, 100, 102, 103, 121], "dask_executor": [100, 102], "daskexecutor": [82, 102, 115], "data": [15, 16, 24, 39, 75, 76, 89, 93, 97, 100, 101, 102, 105, 107, 109, 117, 119, 121, 123], "data_err_opt": 119, "databas": 28, "dataflow": 74, "datafram": [3, 68, 71, 115], "dataset": [75, 76, 89, 100, 117, 118, 120, 121, 123], "dataset_axi": 121, "date": 95, "dear": 119, "debug": [79, 117, 119, 123], "debug_log": [79, 102, 123], "decai": 120, "declar": 123, "dedic": [74, 101, 120], "deep": 6, "deepcsv_102xsf_v1": 118, "def": [67, 75, 117, 118, 119, 121, 123], "default": [0, 2, 3, 5, 6, 9, 11, 12, 13, 15, 16, 25, 31, 32, 34, 35, 60, 68, 69, 70, 71, 72, 73, 74, 76, 78, 79, 103, 118, 119], "default_dtyp": [6, 102], "default_factori": 91, "defaultdict": [83, 115, 121, 123], "defaultdict_accumul": [67, 102, 115], "defin": [6, 7, 19, 25, 36, 67, 76, 77, 81, 89, 103, 119, 120, 123], "definit": [5, 6, 19, 21, 22, 23, 67, 118, 119], "degre": 30, "delai": 71, "deliv": 75, "deliveri": [75, 76, 100], "delph": [30, 110, 120], "delphesev": 30, "delphesschema": [102, 110, 120], "delta": [60, 120], "delta_phi": [66, 102], "delta_r": [60, 102, 120], "delta_r2": [60, 102], "deltar": 30, "demo": [117, 120], "demonstr": 117, "den": 118, "denom": [9, 15, 119], "denom_fill_opt": [15, 119], "denomin": [9, 11, 15, 119], "denot": 6, "dens": 6, "dense_ax": [6, 102], "dense_dim": [6, 102], "dense_lookup": 118, "denseaxi": [4, 6, 106], "densiti": [12, 13, 30, 118, 119], "depend": [3, 6, 76, 118, 121, 122, 123], "deposit": 30, "deprec": [101, 102, 106], "depth": [60, 67, 97], "deriv": [3, 32, 35, 67, 76, 89, 100, 118, 120, 121], "desc": [68, 69, 70, 74, 79], "descend": 29, "describ": [4, 5, 6, 39, 100], "describe_vari": [39, 102], "descript": [4, 6, 12, 13, 14, 15, 25, 69, 70, 74, 79, 118], "design": [118, 119, 120], "desir": [32, 81, 91, 118, 120], "detail": [100, 102, 119, 120, 121], "determin": [25, 76], "dev": 103, "develop": [102, 106, 123], "df": [3, 71], "dfk": 74, "diagram": 102, "diboson": 121, "dict": [6, 12, 13, 15, 25, 32, 76, 79, 83, 84, 89, 119], "dict_accumul": [67, 102, 115], "dict_kei": 117, "dictionari": [12, 15, 67, 76, 84, 89, 117], "differ": [2, 21, 48, 66, 76, 78, 118, 119, 123], "dilepton": 117, "dim": [6, 102], "dimens": [6, 12, 13, 81, 100], "dimension": [10, 25, 61, 64, 65, 66, 118], "dimuon": [120, 121, 123], "dir": [118, 123], "direct": [29, 65, 66, 123], "directli": [60, 61, 62, 63, 64, 120, 121, 123], "directori": [67, 79, 103, 123], "dirnam": 103, "disabl": 79, "discr": 3, "discrep": 102, "discret": 123, "discrimin": 3, "discuss": [36, 77, 119], "disk": [79, 96, 99, 102, 123], "displai": [119, 123], "dist": 118, "distanc": [30, 60, 61, 62, 63, 64, 65, 66, 114, 119, 120], "distinct": [48, 79], "distinctchildren": [48, 102], "distinctchildrendeep": [48, 102], "distinctchildrendeep_form": [31, 72], "distinctpar": [48, 102, 120], "distinctparent_form": [31, 72], "distribut": [9, 15, 16, 68, 79, 102, 103, 119, 121, 123], "divid": [6, 15, 60, 66, 102, 118, 119, 123], "dload": 119, "do": [25, 39, 67, 69, 71, 75, 103, 119, 121], "doc": 103, "docker": 103, "docstr": [30, 102, 119, 120], "document": [0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 39, 40, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 55, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 83, 84, 87, 90, 91, 93, 100, 103, 120, 123], "doe": [67, 100, 103, 118], "domain": [12, 13], "don": [76, 103], "done": [119, 120, 121], "dot": [65, 66, 102], "doubl": [117, 120], "doublemuon": [121, 123], "doubli": 120, "down": [2, 19, 25, 78, 118], "down_val": 21, "download": [103, 117, 118], "downsampl": 6, "dr": 120, "draw": [12, 13, 15], "drawn": [12, 13, 14, 15, 118, 119], "drop": [30, 31, 72], "dtype": [0, 6, 28, 73], "duck": 6, "due": [100, 103], "duplic": 112, "durat": 32, "dure": [76, 89, 120], "dyjet": [117, 118, 120], "dynam": [35, 76], "dynamic_chunks": [76, 79, 102], "dz": 30, "e": [2, 4, 6, 12, 13, 25, 26, 30, 32, 39, 60, 62, 63, 76, 78, 89, 90, 100, 102, 103, 117, 119, 120, 121, 123], "e31a1c": 119, "ea": 25, "each": [0, 2, 3, 4, 6, 13, 29, 31, 34, 35, 48, 68, 69, 70, 72, 73, 74, 76, 78, 79, 100, 101, 103, 119, 120, 121, 123], "earlier": [118, 119], "eas": 100, "easi": 25, "easili": [100, 103, 117], "echo": 103, "ecosystem": [100, 102, 119], "edg": [4, 6, 30, 102, 118, 119], "edgecolor": 119, "edit": [25, 76, 103, 119], "ee": 117, "eem": 30, "eess": 117, "effect": [2, 5, 16, 25, 78, 120, 122], "effici": [0, 15, 28, 73, 102, 108, 117, 118, 121], "eflowneutralhadron": 30, "eflowphoton": 30, "eflowtrack": 30, "egm": 25, "ehad": 30, "ehadovereem": 30, "either": [2, 6, 12, 13, 14, 15, 71, 78, 100, 117, 119, 120], "elaps": [121, 123], "electromagnet": 30, "electron": [30, 31, 34, 35, 51, 72, 102, 113, 117, 118, 119, 120], "electron_": 119, "electron_genpartidx": [31, 34, 72, 120], "electron_jetidx": [31, 34, 72], "electron_photonidx": [31, 34, 72], "electronarrai": 120, "electronidx1": 118, "electronidx1g": 118, "electronidx2": 118, "electronidx2g": 118, "electronidxg": 118, "elementlink": 35, "elementwis": [40, 60, 61, 62, 63, 64, 65, 66], "eleoppsign": 117, "elesf": 117, "elesfdown": 117, "elesferror": 117, "elesfup": 117, "elif": 117, "elinewidth": 119, "els": 119, "emark": [12, 15], "embed": 120, "emit": 79, "emphasi": [60, 65, 66], "emploi": 100, "empti": [13, 67, 81, 123], "emptyarrai": 121, "en": 9, "enabl": [67, 68, 69, 70, 74, 79, 102, 103, 108], "encapsul": 100, "encod": [2, 78], "encount": [31, 72, 119, 121], "encrypt": 79, "end": [4, 12, 13, 14, 15, 32, 71], "end3d": 33, "end4d": 33, "end_list": 121, "end_tupl": 121, "energi": [19, 21, 22, 23, 25, 30, 36, 41, 52, 60, 62, 77, 100, 101, 102, 107, 120], "enough": [67, 121], "ensur": [30, 31, 72, 103, 119, 123], "entir": [75, 119], "entri": [0, 15, 25, 28, 30, 32, 48, 71, 73, 76, 89, 119, 121], "entry_start": [32, 121], "entry_stop": [32, 121], "entrypoint": 118, "entrystart": 71, "entrystop": 71, "enumer": [3, 14, 48, 102, 119], "env": [103, 119, 123], "enviro": [103, 123], "environ": [79, 102, 122, 123], "environmennt": 103, "environment_fil": [79, 102, 123], "eo": [121, 123], "eospubl": [121, 123], "ephemer": 89, "epsilon": 119, "equal": [12, 13, 119], "equival": [76, 89, 103, 119, 121], "error": [11, 15, 25, 30, 118, 123], "error_opt": [12, 15, 119], "errorbar": [12, 15], "errorctgtheta": 30, "errord0": 30, "errordz": 30, "errori": 30, "errorp": 30, "errorphi": 30, "errorpt": 30, "errort": 30, "errorx": 30, "errorz": 30, "essenti": [29, 103, 117], "et": 30, "eta": [3, 24, 30, 36, 41, 42, 60, 62, 63, 77, 102, 114, 117, 118, 119, 120, 121, 123], "etaout": 30, "etav": 118, "etc": [3, 8, 32, 35, 76, 103], "eval": [3, 102, 118], "evalu": [0, 3, 25, 30, 39, 60, 73, 102, 108, 117, 118], "even": 100, "evenli": 6, "event": [2, 10, 30, 31, 32, 34, 36, 39, 72, 75, 77, 78, 100, 102, 109, 117, 118, 119, 120, 121, 123], "eventlhef": 30, "events_cach": 118, "events_lepton": 121, "events_tot": [79, 102], "eventu": [114, 117, 119], "everi": [121, 123], "everyth": 119, "exact": [0, 73], "exampl": [0, 6, 10, 24, 30, 31, 36, 60, 67, 72, 73, 75, 77, 81, 102, 103, 114, 118, 119, 120, 121, 123], "exce": 100, "except": [3, 36, 69, 74, 77, 95], "exception": 100, "exclud": [2, 78], "exclude_unset": 118, "exclus": 7, "execut": [67, 68, 69, 70, 74, 79, 100, 102, 103, 117, 120, 121, 122, 123], "executor": [67, 69, 70, 74, 76, 79, 89, 102, 103, 115, 121], "executor_arg": 89, "executorbas": [68, 69, 70, 74, 76, 79, 115, 121], "exhaust": [79, 123], "exist": [12, 14, 31, 48, 72, 79, 100, 119], "exit": 103, "expand": [48, 121], "expans": 11, "expect": [25, 32, 75, 120, 121], "expens": 89, "experi": [102, 103, 109, 118, 119], "explain": 100, "explan": 120, "explicit": [46, 50, 117], "explicitli": 122, "explodes_how": [39, 102], "exponenti": [67, 118], "export": [10, 103, 119], "export1d": [102, 119], "expos": [119, 120], "express": 119, "ext": [117, 118], "extend": [25, 34, 36, 77, 100], "extens": 118, "extra": [12, 13, 14, 15, 103, 120], "extra_input_fil": 79, "extract": [6, 24, 25, 26, 108], "extract_from_fil": [25, 102], "extractor": [24, 102, 108, 117, 118], "extrapolatedmuontrackparticl": 35, "extri": 24, "ey": 119, "f": [9, 11, 16, 103, 117, 120, 123], "face": 119, "facecolor": 119, "facil": [102, 103], "facilit": [100, 119], "fact": 120, "factor": [2, 3, 6, 23, 68, 78, 117, 118], "factori": [32, 76, 79, 110, 119, 120, 123], "factorizedjetcorrector": [102, 107, 118], "fail": [11, 45, 55, 68, 79, 102, 118], "fair": 120, "fall": 100, "fall17_17nov2017_v32_mc_l2relative_ak4pfpuppi": 118, "fall17_17nov2017_v32_mc_uncertainty_ak4pfpuppi": 118, "fallback": [79, 103], "fals": [0, 2, 3, 6, 12, 13, 15, 60, 68, 69, 73, 74, 75, 76, 78, 79, 117, 119, 120, 123], "familiar": 117, "fanci": [101, 102, 119, 120], "fancydimuonprocessor": 121, "far": 119, "fast": [79, 120], "fast_terminate_work": [79, 102], "faster": 121, "fatjet": [31, 34, 43, 44, 72, 102, 113], "fatjet_electronidx3sj": 34, "fatjet_genjetak8idx": [31, 34, 72], "fatjet_muonidx3sj": 34, "fatjet_nconstitu": [31, 72], "fatjet_pfcandsidxg": [31, 72], "fatjet_subjetidx1": [31, 34, 72], "fatjet_subjetidx1g": [31, 72], "fatjet_subjetidx2": [31, 34, 72], "fatjet_subjetidx2g": [31, 72], "fatjet_subjetidxg": [31, 72], "fatjetpfcand": [31, 34, 43, 72], "fatjetpfcands_jetidx": 34, "fatjetpfcands_pfcandsidx": 34, "fatjetsv": [34, 44], "fatjetsvs_jetidx": 34, "fatjetsvs_svidx": 34, "favor": [101, 119], "favorit": 123, "fb": [119, 121], "fb9a99": 119, "featur": [39, 101, 103, 106, 114, 119, 120, 121], "feel": 102, "fetch": 120, "few": [67, 101, 103, 119, 121, 123], "field": [6, 35, 100, 102, 118, 120], "fig": [118, 119, 121], "figsiz": [119, 121], "figur": 14, "file": [3, 10, 25, 26, 28, 29, 30, 31, 32, 36, 72, 76, 77, 79, 89, 96, 101, 102, 108, 117, 119, 120, 121, 123], "file_convert": 25, "filemeta": 76, "filenam": [3, 32, 76, 79, 96, 99, 121], "filepath": [79, 102], "fileset": [76, 89, 121, 123], "fill": [0, 4, 5, 6, 8, 10, 15, 67, 75, 101, 102, 106, 117, 118, 121, 123], "fill_between": [12, 15], "fill_non": 118, "fill_opt": [12, 119], "fill_valu": 0, "filter": [117, 120], "filter_nam": 119, "fin": 119, "final": [24, 25, 75, 102, 117, 118], "final_pt": 67, "find": [60, 103, 120, 121, 123], "find_4lep": 121, "finish": [69, 74], "first": [0, 6, 30, 36, 48, 71, 73, 77, 79, 81, 100, 102, 117, 118, 119, 120, 121, 123], "fix": [31, 39, 72, 79, 103], "fixedgridrhofastjetal": 118, "fjc": 19, "flag": [48, 75, 102, 120, 121], "flake8": 103, "flat": [0, 6, 31, 72, 73, 119, 120], "flatten": [118, 119, 121], "flav_b": [3, 102], "flav_c": [3, 102], "flav_udsg": [3, 102], "flavor": [3, 30, 118, 119], "flavoralgo": 30, "flavorphi": 30, "flavour": 30, "flesh": 121, "flight": [68, 69, 74, 79], "float": [4, 6, 7, 9, 11, 12, 13, 16, 123], "float32": [118, 120], "float64": 118, "flow": [4, 6, 54, 118, 120, 121], "fly": 89, "fmt": 93, "fnal": 103, "fname": [117, 118, 120], "follow": [3, 6, 19, 21, 22, 23, 30, 31, 35, 60, 72, 101, 102, 103, 118, 120, 121], "font": 119, "fontsiz": 119, "foot": 119, "forc": 71, "forg": 123, "form": [0, 2, 29, 31, 35, 36, 60, 72, 73, 77, 78, 79, 100, 102, 117, 120], "format": [3, 13, 19, 21, 25, 28, 34, 36, 69, 74, 76, 77, 79, 102, 108, 109, 118, 120, 121, 123], "former": [67, 79], "formmat": 3, "found": [30, 31, 36, 72, 77, 79, 100, 103, 106, 117, 119, 120], "four": 100, "fourmuon": 121, "fourth": 114, "fout": [10, 118], "fracpt": 30, "fraction": 30, "fragil": 103, "frame": [60, 76, 89], "framework": [100, 115, 121, 122, 123], "free": 102, "freedom": 30, "frequenc": [4, 6], "frequentist": 16, "friendli": 123, "from": [4, 6, 12, 13, 25, 26, 29, 30, 31, 32, 35, 36, 48, 60, 61, 62, 63, 64, 65, 66, 67, 71, 72, 74, 75, 76, 77, 89, 96, 101, 102, 103, 108, 114, 117, 119, 120, 121, 123], "from_histogram": 118, "from_parquet": [32, 102], "from_preload": [32, 102], "from_root": [30, 31, 32, 72, 102, 117, 118, 120, 121], "fromhardprocess": 48, "fromhardprocessbeforefsr": 48, "fsr": 47, "fsrphoton": [31, 34, 72, 102, 113], "fsrphoton_muonidx": [31, 34, 72], "fuction": 12, "full": [100, 114, 120, 122], "fullfil": 39, "fulli": [100, 120], "func": 76, "function": [2, 3, 6, 12, 13, 15, 19, 21, 22, 23, 24, 25, 31, 39, 60, 66, 67, 68, 69, 70, 72, 74, 76, 78, 79, 89, 91, 99, 102, 103, 108, 117, 118, 119, 120, 121, 123], "function_nam": [68, 69, 70, 74, 79], "further": [25, 83, 84, 87, 90, 100, 119], "futur": [67, 68, 69, 75, 100, 112, 119, 120, 121], "futures_executor": [100, 102], "futures_run": 121, "futuresexecutor": [85, 102, 115, 121], "futurewarn": 119, "fwlite": [19, 21, 22, 23], "g": [2, 6, 26, 31, 32, 72, 76, 89, 90, 103, 117, 119, 120, 121, 123], "garwood": 16, "gb": 76, "gcc8": 103, "gcc9": 103, "gees": 6, "gen": 30, "gen1": 118, "gen2": 118, "gen2_to_gen1": 118, "gen2rwt": 118, "gencand": [34, 43], "gendeltaz": 30, "gendressedlepton": [31, 34, 72], "gener": [3, 4, 16, 30, 36, 48, 56, 74, 75, 76, 77, 79, 89, 100, 103, 104, 109, 117, 118, 120, 121], "generator_binvar": 120, "generator_id1": 120, "generator_id2": 120, "generator_scalepdf": 120, "generator_weight": 120, "generator_x1": 120, "generator_x2": 120, "generator_xpdf1": 120, "generator_xpdf2": 120, "genfatjet_pfcandsidxg": [31, 72], "genfatjetcand": [31, 34, 43, 72], "genfatjetcands_jetidx": 34, "genfatjetcands_pfcandsidx": 34, "genfatjetsv": [34, 44], "genfatjetsvs_jetidx": 34, "genfatjetsvs_svidx": 34, "genisolatedphoton": [31, 34, 72], "genjet": [30, 31, 34, 43, 44, 72, 120], "genjet02": 30, "genjet04": 30, "genjet08": 30, "genjet15": 30, "genjet_nconstitu": [31, 72], "genjet_pfcandsidxg": [31, 72], "genjetak8": [31, 34, 43, 44, 72], "genjetak8_nconstitu": [31, 72], "genjetcand": [31, 34, 43, 72], "genjetcands_jetidx": 34, "genjetcands_pfcandsidx": 34, "genjetidx": 118, "genjetidxg": 118, "genjetsv": [34, 44], "genjetsvs_jetidx": 34, "genjetsvs_svidx": 34, "genmet": [31, 34, 72], "genmissinget": 30, "genpart": [31, 34, 72, 120], "genpart_childrenidxg": [31, 72], "genpart_distinctchildrendeepidxg": [31, 72], "genpart_distinctchildrenidxg": [31, 72], "genpart_distinctparentidxg": [31, 72], "genpart_genpartidxmoth": [31, 34, 72], "genpart_genpartidxmotherg": [31, 72], "genpart_pdgid": [31, 72], "genparticl": [31, 34, 72, 102, 113], "genpartidxmoth": 48, "gensumpt2": 30, "genvistau": [31, 34, 72, 102, 113], "genvistau_genpartidxmoth": [31, 34, 72], "genweight": 117, "get": [6, 39, 69, 74, 101, 102, 119], "get_cach": [76, 102], "get_legend": 119, "get_lumi": [26, 102], "getattr": [120, 121], "getcorrect": [19, 102], "getitem": 120, "getpass": 123, "getresolut": [22, 102], "getscalefactor": [23, 102], "getsubcorrect": [19, 102], "getuncertainti": [21, 102], "getus": 123, "gev": [30, 117, 121, 123], "gfunc": 94, "gigabyt": 121, "gist": 103, "git": 103, "github": [34, 36, 77, 102, 103], "githubusercont": [117, 118, 120], "give": 120, "given": [2, 3, 5, 6, 21, 22, 23, 25, 60, 76, 78, 79, 117, 123], "global": [31, 32, 34, 35, 72, 100, 103], "gluon": 3, "go": [79, 101, 117, 119, 123], "goe": 119, "golden": 28, "good": [79, 103, 117, 121], "goodev": 117, "govern": [0, 73, 120], "gpu": [79, 102, 123], "gradual": 123, "graphic": 119, "greater": 7, "grid": [13, 14, 119], "gridspec_kw": 119, "group": [6, 31, 36, 72, 77, 102, 119, 120], "growth": 121, "gsftrackparticl": 35, "gt": [118, 119, 120, 121], "guid": [15, 102, 119], "guide_opt": [15, 119], "gz": [3, 103, 118, 123], "h": [6, 10, 14, 117, 119, 121], "h1": 119, "h1bin": 119, "h1sumw": 119, "h1val": 119, "h2": 119, "h2bin": 119, "h2sumw": 119, "h5py": 103, "h_m4mu": 121, "h_mass": 121, "h_mz1": 121, "h_mz2": 121, "h_nmuon": 121, "h_ptz1mu1": 121, "h_ptz1mu2": 121, "ha": [6, 24, 30, 35, 56, 73, 79, 103, 117, 119, 120, 121], "hack": 103, "hadd": 67, "hadron": [3, 30], "hadronflavour": [118, 120], "half": [79, 123], "handl": [2, 36, 77, 78, 102], "hard": 30, "hardcod": 103, "hasflag": [48, 102, 120], "hatch": 119, "have": [0, 3, 6, 28, 32, 39, 69, 73, 74, 79, 83, 84, 103, 104, 117, 118, 119, 120, 121, 123], "heavi": [30, 60, 65, 66, 120, 122], "heavy_input": [68, 102], "height_ratio": 119, "help": [67, 117, 119, 120, 121], "helper": [37, 104, 110, 115, 120, 121], "henc": [66, 120], "hep": [30, 100, 102, 119, 120], "hepmcev": 30, "here": [36, 67, 68, 77, 103, 117, 118, 119, 120, 121, 123], "hi": [4, 7, 102], "hidden": 103, "high": [100, 101, 102], "highest": [19, 22, 23], "highlevel": 120, "hist": [4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 67, 75, 102, 117, 118, 119, 121, 123], "hist1": 119, "hist2": 119, "hist_tool": 106, "histbook": [6, 106], "histo": [24, 25, 117, 118, 119], "histogram": [4, 5, 6, 10, 12, 13, 14, 15, 24, 25, 67, 100, 101, 102, 106, 117, 121], "histogramdd": 119, "hit": 30, "hnew": 119, "hnumpi": 119, "hold": [3, 26, 28, 32, 67, 76, 91], "homework": 119, "honk": 6, "hopefulli": [114, 121], "horizont": [15, 30, 100, 102], "horizontalalign": 119, "host": [102, 103], "hostnam": 123, "how": [6, 12, 39, 89, 117, 118, 119, 120, 121, 123], "howev": [100, 103, 109, 117, 119, 121], "hspace": 119, "ht": 30, "htcondor": [103, 123], "html": [16, 103], "http": [9, 11, 16, 34, 36, 77, 102, 103, 117, 118, 119, 120], "hub": 103, "human": 93, "hundr": 103, "hzz": 119, "i": [0, 2, 3, 4, 5, 6, 7, 12, 13, 14, 15, 16, 19, 21, 22, 23, 24, 25, 26, 29, 30, 31, 32, 34, 35, 36, 38, 39, 48, 60, 65, 66, 67, 68, 69, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 84, 89, 90, 91, 100, 101, 102, 103, 106, 114, 117, 118, 119, 120, 121, 122, 123], "i0": 121, "i1": 121, "i2": 121, "i3": 121, "id": [30, 48, 117, 120, 123], "id1": [30, 120], "id2": [30, 120], "idea": 67, "ident": [1, 6, 67, 81, 83, 84, 87, 90, 91, 102, 103], "identif": [4, 5, 120], "identifi": [4, 5, 6, 12, 14, 102, 119], "idiom": 117, "idx": [31, 72, 121], "ignor": [48, 70, 103, 117], "ignore_miss": 3, "imag": 102, "immut": [4, 5, 8], "impact": 30, "implement": [19, 21, 22, 23, 29, 30, 31, 32, 33, 34, 35, 36, 67, 72, 76, 77, 102, 117, 118, 120, 121], "impli": 117, "import": [10, 25, 67, 75, 103, 114, 117, 118, 119, 120, 121, 122, 123], "import_fil": [25, 102], "impos": [117, 121], "improv": 102, "incl": 3, "inclin": [62, 63, 64, 65], "includ": [2, 4, 6, 34, 48, 78, 103, 117, 120, 123], "inclus": [0, 7, 79], "inconsist": 119, "increas": 79, "increment": 6, "inde": [117, 118], "indeped": 69, "independ": [100, 102, 119], "indettrackparticl": 35, "index": [4, 5, 24, 28, 30, 31, 34, 35, 46, 48, 50, 72, 81, 102, 119, 120, 121], "indic": [4, 6, 15, 35, 103, 119, 120, 121], "indirect": [31, 34, 72], "individu": [2, 68, 78, 100], "ine": 16, "inf": [1, 7, 119], "info": [3, 34, 83, 84, 87, 90, 117, 119, 123], "inform": [67, 79, 103, 120, 123], "infrastructur": 123, "inherit": [89, 102, 117], "initi": [2, 78, 91, 120, 123], "inlin": 119, "input": [0, 19, 21, 22, 23, 24, 25, 31, 60, 68, 69, 70, 72, 74, 76, 79, 100, 102, 117, 118, 120, 121], "insid": [75, 76, 103, 120], "insight": 102, "inspect": 3, "instal": [119, 123], "instanc": [2, 6, 32, 68, 69, 70, 74, 75, 76, 78, 79, 89, 91, 103, 118, 119, 121, 123], "instanti": 120, "instead": [0, 3, 35, 69, 74, 120, 123], "instruct": 103, "int": [2, 3, 4, 6, 32, 60, 67, 68, 69, 70, 71, 74, 76, 78, 79, 121], "int3": 120, "int32": 120, "int64": 121, "int_rang": 6, "intcategori": 121, "integ": [4, 120, 121], "integr": [5, 6, 12, 13, 26, 102, 119], "intend": 100, "inter": 100, "interact": [30, 102, 103, 117, 119, 120, 121], "interest": [117, 119, 121], "interfac": [32, 39, 119, 121], "intermedi": [69, 74], "intern": [0, 5, 12, 13, 15, 73, 117, 119], "interpol": 6, "interpret": [2, 12, 13, 15, 31, 34, 48, 60, 65, 66, 69, 72, 78, 100, 120, 121], "interv": [4, 9, 11, 15, 16, 102, 106, 119], "invalid": [119, 121], "invari": [30, 60, 63, 117, 120, 121], "invers": 120, "involv": 121, "io": 102, "ipykernel": 103, "ipynb": [117, 119, 120, 121], "iri": 102, "irregular": 100, "isdecayedleptonhadron": 48, "isdirecthadrondecayproduct": 48, "isdirecthardprocesstaudecayproduct": 48, "isdirectprompttaudecayproduct": 48, "isdirecttaudecayproduct": 48, "isfirstcopi": 48, "ishardprocess": 48, "ishardprocesstaudecayproduct": 48, "isinst": [119, 121], "islastcopi": [48, 120], "islastcopybeforefsr": 48, "islic": 4, "isloos": [45, 46, 50, 55, 102], "ismedium": [45, 55, 102], "isol": [30, 103, 121], "isolationvar": 30, "isolationvarrhocorr": 30, "isotrack": [31, 34, 72], "isprompt": [48, 120], "isprompttaudecayproduct": 48, "ispu": 30, "issu": [31, 72, 118], "istaudecayproduct": 48, "istight": [45, 46, 50, 55, 102, 120], "istightleptonveto": [46, 50, 102], "isveto": [45, 102], "item": [32, 40, 41, 42, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 74, 76, 79, 80, 89, 117, 119, 121, 123], "iter": [6, 21, 39, 68, 69, 70, 71, 74, 79, 80, 87, 100, 115, 121], "iterative_executor": [100, 102], "iterative_run": 121, "iterativeexecutor": [86, 102, 115, 121], "iteritems_opt": 32, "its": [6, 60, 66, 79, 102, 117, 119, 120, 123], "itself": [102, 117, 123], "j": 118, "jag": [31, 72, 102, 118, 119, 120], "jcu": 21, "je": [21, 118], "jec": [19, 20, 25, 102, 118], "jec_input": 118, "jec_jet1": 19, "jec_jet2": 19, "jec_stack": [17, 118], "jec_stack_nam": 118, "jecfactor": [36, 77], "jecstack": [102, 107, 118], "jer": [20, 22, 23, 102, 118], "jercchf": 118, "jercchpuf": 118, "jersf": [20, 23, 25, 102], "jes_j": 118, "jet": [3, 17, 19, 21, 22, 23, 25, 30, 31, 34, 35, 36, 43, 44, 46, 72, 77, 102, 107, 113, 117, 118, 120], "jet_electronidx1": [31, 34, 72], "jet_electronidx1g": [31, 72], "jet_electronidx2": [31, 34, 72], "jet_electronidx2g": [31, 72], "jet_electronidxg": [31, 72], "jet_energy_correct": 118, "jet_energy_uncertainty_j": 118, "jet_factori": 118, "jet_genjetidx": [31, 34, 72], "jet_muonidx1": [31, 34, 72], "jet_muonidx1g": [31, 72], "jet_muonidx2": [31, 34, 72], "jet_muonidx2g": [31, 72], "jet_muonidxg": [31, 72], "jet_nconstitu": [31, 72], "jet_pfcandsidxg": [31, 72], "jeta": 118, "jetcorr": 19, "jetcorrectionuncertainti": [102, 107, 118], "jeteta": 118, "jetid": [46, 50, 118, 120], "jetmass": 118, "jetmet": 107, "jetmet_tool": [17, 18, 19, 20, 21, 22, 23, 101, 102], "jetparameter1": [19, 21, 22, 23], "jetpfcand": [31, 34, 43, 72], "jetpfcands_jetidx": 34, "jetpfcands_pfcandsidx": 34, "jetproperty1": [19, 21, 22, 23], "jetpt": 118, "jetr": 22, "jetresolut": [102, 107], "jetresolutionscalefactor": [102, 107], "jetressf": 23, "jets_jecfactor": [36, 77], "jets_jetfactor": [36, 77], "jetsv": [34, 44], "jetsvs_jetidx": 34, "jetsvs_svidx": 34, "jettransform": 118, "jetunc": 21, "jme": 25, "job": [69, 74, 76, 89, 103], "jobconfig": 26, "jobqueu": 103, "jobs_executor": [74, 102], "join": 68, "jr": [22, 25], "json": [25, 26, 28, 118], "jsonfil": 28, "junc": [20, 21, 25, 102, 118], "jupyt": [101, 103, 119], "just": [79, 102, 112, 119, 121], "k": 119, "keep": [2, 3, 39, 67, 71, 78, 119], "keep_df": 3, "kei": [6, 24, 32, 79, 102, 117, 118, 121], "kept": 117, "kernel": [74, 103], "keyword": [4, 5, 6, 119], "kind": [25, 39], "kinemat": 119, "know": 117, "kwarg": [0, 6, 14, 19, 21, 22, 23, 73, 76], "l": 30, "la": 71, "lab": 123, "label": [4, 5, 6, 7, 8, 13, 15, 69, 70, 74, 79, 102, 117, 118, 119, 121, 123], "labels": 119, "lagrai": 119, "lambda": 60, "laptop": 102, "larg": [46, 102, 103, 121, 123], "larger": [0, 123], "largest": 117, "last": [30, 32, 48, 71, 120], "later": [3, 25, 117, 120], "latest": [30, 31, 34, 72, 103, 120], "latter": [71, 79], "launch": 123, "layout": 97, "lazi": [120, 121], "lazili": [32, 120], "lazy_cach": [17, 18, 118], "lazyarrai": 71, "lazydatafram": [76, 102, 115], "lcg": 102, "lcg98": 103, "lcg_98python3": 103, "lead": [30, 71, 79, 120], "leadpt20": 117, "least": [69, 74, 117, 121, 123], "leav": [12, 13, 15, 100], "left": 119, "leg": 119, "legend": [8, 12, 13, 15, 118, 119, 121], "legend_opt": 12, "legitim": 79, "len": [75, 117, 121, 123], "length": [30, 31, 65, 66, 71, 72, 76, 100, 120], "lengthi": 119, "lep1": 121, "lep2": 121, "lepton": [46, 50, 119, 120, 121], "lepton_kinemat": 119, "lepton_pt": 119, "less": 79, "let": [89, 103, 117, 119, 120, 121], "level": [19, 21, 22, 23, 29, 31, 38, 48, 68, 69, 72, 74, 76, 79, 100, 101, 102, 105, 107, 120], "lexicograph": 8, "lha": 117, "lhapdfset": 117, "lhcoevent": 30, "lhepart": [31, 34, 72], "lhepdfweight": 117, "lib": [103, 119, 121], "liber": 119, "librari": [79, 100, 101, 103, 114, 120, 121], "life": 119, "lifetim": 79, "light": [3, 118], "like": [2, 19, 21, 22, 23, 24, 25, 32, 36, 66, 67, 76, 77, 78, 79, 89, 102, 103, 120, 123], "like_what": 94, "limit": [79, 100, 121], "line": [15, 25, 103], "line_opt": [12, 119], "linestyl": 119, "linewidth": 119, "link": [117, 119, 120, 121], "linspac": 119, "lint": 103, "linux": 103, "list": [0, 2, 4, 5, 6, 12, 19, 21, 22, 23, 25, 27, 28, 32, 39, 48, 60, 68, 69, 70, 71, 73, 74, 76, 78, 79, 87, 89, 117, 120, 121, 122], "list_accumul": [102, 115], "listen": 123, "liter": [6, 76], "ll": [117, 118, 119, 121], "ln": [60, 62, 63], "lo": [4, 7, 102], "load": [32, 71, 74, 102, 119], "local": [25, 26, 31, 69, 72, 102, 103, 123], "local_nam": 25, "localhost": 123, "localpath": 103, "locat": [79, 103], "lock": 100, "log": [79, 103, 114, 121, 123], "longer": 79, "longitudin": 30, "look": [24, 102, 103, 117, 119, 120, 121], "lookup": [4, 5, 25, 28, 101, 102, 108], "lookup_tool": [24, 25, 101, 102, 117], "lookup_typ": 24, "loop": 100, "loos": [3, 45, 46, 50, 55, 102], "lorentz": [40, 41, 42, 56, 60, 62, 63, 112, 114, 119, 120], "lorentzvector": [33, 40, 62, 63, 102, 112, 113, 114, 119, 120], "lot": 123, "low": 51, "lower": [4, 7, 103], "lowptelectron": [31, 34, 72, 102, 113], "lowptelectron_electronidx": [31, 34, 72], "lowptelectron_genpartidx": [31, 34, 72], "lowptelectron_photonidx": [31, 34, 72], "lpc": 103, "lru": 76, "lt": [118, 119, 120, 121], "lumi": [26, 27, 28, 119, 121], "lumi2017": 26, "lumi_csv": 26, "lumi_tool": [26, 27, 28, 102], "lumidata": [102, 109], "lumilist": [26, 102, 109], "lumimask": [102, 109], "luminos": [26, 28, 109, 117], "lumisect": [26, 27, 28], "lz4": [68, 69, 74, 79], "m": [6, 16, 30, 62, 63, 103, 123], "m1": 30, "m2": 30, "m_": [117, 121, 123], "machin": [100, 121, 123], "maco": 103, "made": [4, 75, 120], "magnitud": [60, 65, 66], "mai": [2, 6, 16, 73, 78, 79, 103, 119, 120, 121, 123], "main": [69, 74, 123], "mainli": [35, 121], "major": 103, "make": [102, 103, 117, 119, 121], "make_evalu": [24, 25, 102, 117, 118], "makehist": 117, "manag": [79, 123], "manager_host_port": 123, "manager_nam": [79, 102, 123], "mani": [31, 72, 89, 102, 103, 121], "manipul": [100, 102, 119], "manner": [0, 73], "mannner": [0, 117], "manual": 123, "map": [3, 6, 24, 31, 32, 35, 36, 67, 71, 72, 76, 77, 115, 119, 120, 121], "mark": [45, 46, 50, 55, 119], "marker": [12, 15, 119], "markers": 119, "mask": [0, 28, 60, 73, 117, 120], "mask_out": 28, "mass": [30, 42, 55, 60, 63, 102, 114, 117, 118, 120, 121, 123], "mass2": [60, 63, 102], "mass_axi": 121, "mass_jec": 118, "mass_orig": 118, "mass_raw": 118, "mass_z1": 121, "mass_z2": 121, "masshist": 117, "massraw": 118, "master": [117, 118, 120], "master_nam": [79, 102, 123], "match": [3, 6, 31, 72, 118, 120], "matched_electron": [50, 51, 55, 102], "matched_fsrphoton": [53, 102], "matched_gen": [45, 46, 50, 51, 53, 55, 58, 102, 118, 120], "matched_jet": [45, 53, 55, 58, 102, 120], "matched_muon": [47, 50, 102], "matched_photon": [45, 51, 102], "materi": [32, 71, 102, 120], "matplotlib": [12, 13, 14, 15, 102, 106, 118, 119, 121], "max": [3, 79, 123], "max_batch_s": [69, 74], "max_work": [69, 123], "maxchunk": [76, 102, 121, 123], "maxim": 79, "maximum": [0, 12, 36, 69, 73, 76, 77, 79, 118, 123], "maxitem": [0, 102], "maxr": 69, "maxw": [1, 117], "mayb": [112, 119], "mb": [76, 79, 103, 123], "mc": [15, 89, 119], "mc2016_ak8_jxform": 118, "mcmaster": 16, "mean": [4, 5, 6, 118, 119], "meansqdeltar": 30, "measur": [30, 79, 123], "mechan": 75, "medium": [3, 45, 55, 102, 118], "memori": [0, 76, 79, 102, 117, 119, 120, 123], "mention": 119, "merg": [3, 27, 36, 69, 74, 77, 100, 102, 117, 119], "mergabl": 119, "mergeabl": 27, "mergepool": [69, 102], "merges_executor": [74, 102], "messag": 79, "met": [18, 30, 31, 34, 72], "metadata": [32, 38, 71, 75, 76, 102, 117, 118, 120, 121, 123], "metadata_cach": [76, 102], "metadata_fetch": [76, 102], "metfixee2017": [31, 34, 72], "method": [0, 1, 2, 3, 4, 5, 6, 7, 17, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 83, 84, 87, 90, 91, 93, 102, 103, 119, 120, 121, 123], "metric": 60, "metric_t": [60, 102], "mi": 118, "mid": [7, 102], "midpoint": 7, "might": 119, "migrat": [104, 119], "min": [3, 60, 120], "min_batch_s": [69, 74], "min_work": 123, "miniconda3": 119, "minim": 79, "minimum": [45, 55, 69, 120, 121], "minor": 103, "minr": 69, "minut": 76, "minw": [1, 117], "miss": [30, 31, 52, 72, 119], "missinget": [30, 31, 34, 72, 102, 113], "mistag": 105, "mitig": 118, "mixin": [30, 31, 33, 34, 35, 37, 38, 39, 40, 41, 42, 60, 61, 62, 63, 64, 65, 66, 72, 102, 111, 112, 113, 114, 120], "mkdir": 118, "mm": 117, "mmap": [76, 102], "mmevent": 120, "mmss": 117, "mock": [117, 118], "modern": 102, "modifi": [2, 75, 78], "modifiernam": 2, "modul": [31, 34, 35, 72, 102, 103, 118, 120, 121], "momenta": 30, "momentum": [3, 30, 36, 57, 60, 65, 66, 77, 114, 121], "monitor": 79, "mont": 102, "more": [34, 48, 73, 76, 79, 89, 100, 102, 103, 117, 118, 119, 120, 121, 123], "most": [69, 74, 103, 117, 118, 119, 120, 121], "mostli": 103, "mother": 48, "mount": 103, "move": 103, "mpi": 30, "mpl": 119, "mplhep": 119, "mu": [117, 119, 121, 123], "much": [67, 103, 119], "muef": 118, "multi": [30, 102, 103], "multibin": 118, "multicor": 121, "multidimension": [6, 119], "multipl": [2, 66, 69, 78, 100, 103, 108], "multipli": [2, 60, 61, 62, 63, 64, 65, 66, 78, 79, 102], "multiprocess": 100, "multivariate_norm": 119, "muon": [30, 31, 34, 35, 72, 102, 113, 117, 119, 120, 121, 123], "muon_": 119, "muon_charg": [121, 123], "muon_eta": [121, 123], "muon_fsrphotonidx": [31, 34, 72], "muon_genpartidx": [31, 34, 72], "muon_jetidx": [31, 34, 72], "muon_mass": [121, 123], "muon_pfreliso03_al": 121, "muon_phi": [121, 123], "muon_pt": [121, 123], "muon_softid": 121, "muonidx1": 118, "muonidx1g": 118, "muonidx2": 118, "muonidx2g": 118, "muonidxg": 118, "muonspectrometertrackparticl": 35, "muonsubtrfactor": 118, "muoppsign": 117, "must": [0, 6, 19, 21, 22, 23, 32, 39, 67, 68, 73, 89, 103, 119, 120, 122, 123], "mutabl": [7, 8], "mutablemap": [68, 69, 70, 71, 74, 76, 79, 80, 115, 117], "mutableset": [68, 69, 70, 74, 76, 79, 80, 117], "mutat": 67, "my": [118, 123], "my_env": 103, "my_password_fil": 123, "my_secret_password": 123, "mycorrect": 118, "myenv": 103, "myhist": 10, "myjetsf": 118, "myprocessor": [75, 121, 123], "myth1": 119, "myvari": 120, "mz": 117, "n": [1, 4, 6, 25, 30, 31, 36, 67, 72, 77, 114, 117, 119], "n_batch": [69, 74], "n_or_arr": 4, "name": [0, 2, 3, 4, 5, 6, 8, 14, 24, 25, 30, 31, 32, 34, 35, 36, 39, 68, 72, 73, 76, 77, 78, 79, 102, 103, 117, 118, 119, 120, 121, 123], "name1": [19, 21, 22, 23], "name_": [31, 72], "name_map": [17, 18, 118], "namespac": 122, "nan": [6, 7, 102], "nanflow": 4, "nano_di": [117, 118, 120], "nanoaod": [31, 32, 34, 35, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 72, 102, 110, 115, 117, 120], "nanoaodschema": [32, 34, 35, 102, 110, 115, 117, 118, 120, 121], "nanoaodv5": [31, 72], "nanoaodv6": [31, 72], "nanoaodv7": [30, 31, 72], "nanocollect": [43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 58, 59, 102, 111, 113], "nanoev": [29, 30, 31, 32, 33, 34, 35, 36, 37, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 72, 75, 76, 77, 101, 102, 115, 117, 118, 119, 121, 123], "nanoeventsfactori": [30, 31, 72, 102, 110, 117, 118, 120, 121], "narrow": 50, "nativefil": 32, "natur": 117, "ncharg": 30, "ncol": 119, "nconstitu": 118, "ndarrai": [0, 2, 3, 4, 9, 11, 14, 16, 26, 27, 28, 73, 78, 81], "ndcctool": 123, "ndf": 30, "nearest": [3, 16, 60, 102, 120], "nearli": 103, "necessari": [19, 21, 22, 23, 29, 30, 31, 33, 35, 36, 67, 72, 74, 77, 103], "need": [0, 39, 60, 76, 79, 100, 102, 103, 118, 119, 120, 123], "neemef": 118, "neg": [60, 61, 62, 63, 64, 65, 66, 102], "nehef": 118, "nelectron": 118, "nest": [31, 36, 67, 72, 77, 120], "nested_index_item": [31, 72, 102], "nested_item": [31, 72, 102], "neutral": 30, "neutrino": 120, "nev": 117, "nevt": 121, "new": [0, 2, 4, 6, 14, 25, 60, 67, 78, 103, 117, 118, 119, 120, 121, 123], "new_axi": 6, "new_bin": 6, "newer": 103, "next": 103, "nice": 119, "nicer": 119, "nicknam": 25, "nj": 118, "njit": 121, "nlep": 121, "nmuon": [118, 121], "nneutral": 30, "node": 118, "noelectron": 117, "nomin": [2, 3, 12, 13, 14, 15, 16, 78, 117, 119, 121], "nomuon": 117, "non": [6, 12, 39, 103, 109, 119], "none": [2, 3, 4, 6, 7, 8, 12, 13, 14, 15, 20, 25, 27, 32, 60, 68, 69, 70, 71, 74, 76, 78, 79, 80, 89, 91, 93, 95, 119, 120, 121, 123], "nonzero": 16, "normal": [6, 10, 12, 13, 114, 117, 118], "normal_interv": 102, "normtag": 26, "normtag_phys": 26, "notdata": 119, "note": [12, 13, 15, 60, 103, 117, 118, 123], "notebook": [101, 103, 117, 119, 121], "notic": [67, 119, 120], "notr": 123, "now": [101, 103, 117, 118, 119, 121], "np": [67, 81, 114, 117, 118, 119], "npart": 69, "nrow": 119, "nsubjetsprun": 30, "nsubjetssoftdrop": 30, "nsubjetstrim": 30, "ntimehit": 30, "ntupl": 120, "ntupliz": 120, "null": 0, "num": [9, 15, 117, 118, 119, 120, 121, 123], "num_entri": 119, "num_row": 32, "numba": [102, 121], "number": [0, 2, 4, 5, 6, 7, 9, 11, 25, 27, 28, 30, 60, 68, 69, 73, 76, 78, 79, 103, 121, 123], "numer": [9, 11, 15, 119], "numpi": [0, 2, 3, 4, 6, 9, 10, 11, 14, 16, 26, 27, 28, 32, 67, 73, 78, 81, 100, 102, 106, 114, 117, 118, 119], "numpython": 102, "nzz": 121, "o": [30, 31, 72, 118, 119], "obbject": 6, "object": [0, 2, 3, 6, 7, 8, 10, 12, 13, 14, 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 36, 37, 38, 39, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 57, 58, 59, 60, 66, 67, 73, 74, 75, 76, 77, 78, 79, 89, 99, 112, 117, 118, 119, 120, 121, 122], "observ": [6, 16], "off": [36, 77, 79], "offset": [30, 31, 32, 72], "often": [100, 103, 120], "ogenpart": [31, 72], "ok": 118, "ol": 119, "old": 6, "old_ax": 6, "old_axi": 6, "old_nbin": 6, "omit": [14, 121], "onc": 118, "one": [0, 1, 3, 6, 10, 12, 13, 15, 25, 30, 31, 35, 36, 48, 60, 67, 69, 70, 72, 76, 77, 79, 81, 83, 84, 87, 89, 90, 91, 100, 101, 103, 117, 118, 120, 121, 123], "ones": [6, 48, 117], "onli": [2, 6, 32, 76, 78, 89, 103, 117, 119, 120, 123], "onto": 6, "open": [3, 32, 79, 101, 102, 119, 120, 121, 123], "opendata": 123, "oper": [2, 6, 78, 100, 119, 120, 121], "opposit": [117, 121], "opt": [103, 121], "optim": [16, 120], "option": [0, 2, 3, 4, 5, 6, 9, 11, 12, 13, 14, 15, 16, 32, 60, 68, 69, 70, 71, 74, 76, 78, 79, 89, 91, 102, 117, 119, 120, 121, 123], "order": [5, 7, 8, 12, 19, 60, 101, 102, 123], "org": [9, 16, 103, 119], "orient": 119, "origin": [29, 36, 61, 62, 63, 64, 65, 66, 77, 114, 118, 119, 120], "other": [1, 6, 24, 28, 37, 39, 40, 60, 61, 62, 63, 64, 65, 66, 67, 76, 79, 81, 83, 84, 87, 89, 90, 91, 100, 102, 117, 118, 119, 120, 121, 123], "otherwis": [4, 14, 102], "our": [102, 103, 117, 118, 119, 121, 123], "out": [3, 6, 10, 24, 75, 102, 115, 117, 118, 119, 121], "outgo": 100, "output": [10, 26, 67, 68, 69, 70, 74, 79, 99, 100, 117, 118, 119, 121, 123], "outputfil": 119, "outsid": [119, 123], "over": [6, 12, 13, 26, 39, 79, 100, 119, 121], "overal": 79, "overflow": [4, 6, 12, 13, 14, 15, 118, 119], "overlai": [12, 14, 119, 121], "overlap": 7, "overlay_overflow": 12, "overload": 24, "overrid": 76, "overridden": [6, 61, 62, 63, 64], "overriden": [8, 79], "overview": [100, 101], "overwrit": 119, "own": [60, 101, 102, 103, 119], "p": [30, 64, 65, 75, 102, 118, 121, 123], "p2": [64, 65, 102], "p4": [57, 102, 121], "p_": [119, 121], "p_2": 123, "p_3": 123, "p_4": 123, "p_5": 123, "p_t": [67, 118], "pack": [0, 48, 117, 120, 123], "packag": [100, 102, 103, 106, 109, 118, 119, 121, 122], "packedselect": [101, 102, 104, 115], "page": [100, 101, 102], "pair": [119, 120, 121], "panda": [3, 68], "pantsbuild": 103, "paradigm": [100, 119], "paral": 121, "parallel": [67, 69, 79, 89, 100, 121], "param": 120, "paramet": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 26, 27, 28, 30, 32, 48, 60, 68, 69, 70, 71, 73, 74, 76, 78, 79, 81, 89, 91, 120], "parameter": 118, "parameter1": [19, 21, 22, 23], "pare": 25, "parent": [30, 31, 34, 35, 40, 41, 42, 48, 49, 60, 61, 62, 63, 64, 65, 66, 72, 79, 102, 120], "parquet": [32, 89], "parquet_opt": 32, "parquetfil": 32, "pars": [3, 28, 69, 74, 109], "parsl": [74, 100, 102, 103, 121], "parsl_executor": [100, 102], "parslexecutor": [88, 102, 115], "part": [104, 118], "partial": [2, 78], "partial_weight": [2, 78, 102], "particl": [30, 35, 48, 49, 54, 100, 120], "particleflowjet02": 30, "particleflowjet04": 30, "particleflowjet08": 30, "particleflowjet15": 30, "particular": [2, 78, 103, 119], "particularli": 2, "partit": [89, 100], "partition_kei": 32, "partitions": 89, "parton": [30, 120], "partonflavour": [118, 120], "pass": [4, 5, 11, 12, 13, 14, 15, 32, 68, 69, 73, 74, 75, 76, 89, 117, 118, 119, 120, 121, 123], "password": [79, 123], "password_fil": [79, 102, 123], "patch": [13, 119], "patch_opt": 13, "path": [26, 28, 30, 32, 79, 103, 119, 120], "pathlib": 32, "pattern": [30, 31, 35, 36, 72, 77], "pb": [26, 30], "pcolormesh": [13, 118], "pdf": [16, 30], "pdf1": 30, "pdf2": 30, "pdf4lhc15_nnlo_30_pdfa": 117, "pdg": [48, 120], "pdgid": 120, "pdune": 110, "pduneschema": [102, 110], "pearson": [9, 15, 119], "pem": 79, "per": [3, 6, 26, 76, 79, 117, 118, 120, 123], "perform": [6, 61, 62, 63, 64, 76, 89, 100], "perman": 79, "permiss": 103, "permut": 121, "persist": 119, "persistent_cach": 32, "perspect": 119, "peter": 16, "pex": 103, "pf": [34, 43, 102], "pfcand": [34, 43, 102, 113], "pfnano": [34, 43, 44, 54], "pfnanoaod": 120, "pfnanoaodschema": [102, 110, 120], "ph": 30, "phi": [30, 36, 41, 42, 60, 61, 62, 63, 64, 66, 77, 102, 114, 118, 120, 121, 123], "phiouter": 30, "photon": [30, 31, 34, 47, 72, 102, 113], "photon_electronidx": [31, 34, 72], "photon_genpartidx": [31, 34, 72], "photon_jetidx": [31, 34, 72], "physic": [36, 77, 100, 102, 112, 119], "physicist": 119, "physlit": [35, 110], "physliteschema": [102, 110, 120], "physt": 106, "pi": 66, "picklabl": 99, "pid": 30, "piec": 118, "pile": 30, "pileup": 118, "pip": [102, 103, 119], "place": [1, 2, 6, 12, 13, 15, 32, 67, 68, 75, 78, 81, 83, 84, 87, 90, 91, 103, 119], "placement": 5, "plane": [30, 60, 61, 62, 63, 64, 65, 66], "platform": 102, "pleas": [76, 102, 103], "plot": [5, 12, 13, 14, 15, 101, 102, 106, 117, 118, 121], "plot1d": [5, 8, 14, 102, 118, 119, 121], "plot2d": [102, 118, 119], "plot_opt": 14, "plotgrid": [102, 119], "plotratio": [102, 119], "plt": [118, 119, 121], "plu": 6, "po": [59, 102], "pog": 26, "point": [3, 24, 25, 30, 36, 65, 66, 77, 103, 120], "poisson": [15, 16, 119], "poisson_interv": 102, "poisson_mean": 119, "poissonalpha": 16, "polar": [61, 66, 114], "polartwovector": [52, 64, 102, 112, 113, 114], "pool": [69, 123], "pop": [119, 120], "popd": [103, 118], "popular": 118, "port": [79, 102, 123], "portabl": [102, 123], "posit": [6, 30, 46, 50, 59], "possibl": [5, 24, 25, 48, 102, 118, 119, 120], "possibli": [2, 11, 78, 103, 120], "post": 119, "postfix": [31, 72], "postprocess": [75, 102, 121, 123], "power": 119, "pre": [32, 102, 119, 120], "pre_0": 123, "pre_1": 123, "pre_executor": [76, 102], "precomput": 108, "preconvert": 103, "predat": 120, "prefer": 103, "preferenti": 8, "prefix": [25, 35, 118], "preload": [71, 102], "preload_item": 71, "premad": 76, "prepar": 118, "preprocess": [76, 79, 102, 123], "present": [25, 89, 103], "prettier": 121, "prevent": 119, "previou": [101, 119, 121], "previous": [0, 73, 103, 104, 119], "primari": [36, 74, 77, 121], "primaryvertic": [36, 77], "primit": [24, 100], "print": [79, 103, 117, 118, 119, 120, 121, 123], "print_stdout": [79, 102, 123], "printf": 13, "prior": [74, 117], "prioriti": [68, 102], "probabl": [12, 13, 76, 119], "procedur": 103, "process": [25, 30, 68, 69, 70, 74, 75, 76, 79, 89, 100, 102, 117, 121, 123], "processid": 30, "processor": [67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 101, 102, 104, 106, 117, 120, 123], "processor_compress": [76, 102], "processor_inst": [76, 89, 121], "processorabc": [76, 89, 100, 102, 115, 121, 123], "processpoolexecutor": 69, "proctim": 30, "prod": 117, "produc": [6, 8, 25, 120, 123], "product": [60, 65, 66, 117], "program": [32, 79, 100, 123], "progress": [35, 68, 69, 70, 74, 79, 102, 116, 123], "progresscolumn": [93, 116], "project": [6, 102, 119], "prompt": [103, 120], "proper": 16, "properti": [3, 19, 21, 22, 23, 56, 61, 62, 63, 64, 66, 100, 119, 123], "property1": [19, 21, 22, 23], "protocol": 117, "prototyp": 102, "provid": [2, 25, 28, 37, 40, 41, 42, 60, 61, 62, 63, 64, 65, 66, 67, 78, 100, 101, 102, 103, 105, 107, 112, 114, 118, 119, 120, 121, 123], "proxi": 79, "prune": 30, "prunedp4": 30, "pseudodata": 119, "pseudorapid": [30, 60, 62, 63], "pseudorapitii": 3, "pt": [3, 16, 24, 30, 36, 41, 42, 51, 62, 63, 66, 67, 77, 102, 114, 117, 118, 119, 120, 121, 123], "pt2": [66, 102], "pt_axi": 121, "pt_gen": 118, "pt_jec": 118, "pt_orig": 118, "pt_raw": 118, "pt_z1_mu1": 121, "pt_z1_mu2": 121, "ptd": 30, "ptetaphiecandid": [102, 112], "ptetaphielorentzvector": [41, 102, 112, 114], "ptetaphievector": [36, 77], "ptetaphimcandid": [45, 47, 49, 51, 53, 54, 55, 58, 102, 112, 113, 121, 123], "ptetaphimcollect": [31, 34, 72, 102, 113], "ptetaphimlorentzvector": [42, 46, 48, 50, 56, 102, 112, 113, 114], "ptgenjet": 118, "pthist": 119, "ptraw": 118, "ptval": [67, 118], "puid": 118, "pull": [102, 103], "puppimet": [31, 34, 72], "pure": 68, "purpos": [117, 119, 123], "pushd": [103, 118], "pv": [31, 34, 72], "pvec": [60, 102], "pw": 11, "pw2": 11, "pwd": 103, "px": [30, 36, 66, 77, 102, 119], "py": [30, 66, 102, 103, 119, 120, 121], "pyapp": 74, "pyarrow": 32, "pypi": 103, "pyplot": [118, 119, 121], "pytest": 103, "python": [32, 69, 79, 100, 102, 103, 117, 119, 121, 122, 123], "python3": [103, 119, 121], "python_packag": 123, "python_package_run": 79, "pythonpath": 103, "pz": [30, 65, 102, 119], "q": 30, "qcd": 30, "qed": 30, "qgl": 118, "quadmesh": 118, "qualit": 119, "qualiti": [102, 121], "quantit": 100, "quantiti": [36, 77, 100, 119], "quark": [3, 30], "queri": 48, "queue": [79, 100, 102, 103], "quick": [102, 118], "quickli": [6, 32], "quit": 103, "r": [52, 60, 61, 62, 63, 64, 65, 66, 102, 114, 119, 120, 121, 123], "r2": [61, 66, 102], "radiu": [46, 50], "rais": [69, 74, 118, 119], "ran": 121, "random": [6, 10, 67, 114, 118, 119], "rang": [4, 6, 12, 13, 14, 15, 30, 79, 118, 119, 121], "rapid": 30, "rare": [100, 103], "rather": [100, 103, 119], "ratio": [15, 30, 118, 119], "raw": [117, 118, 120], "rawfactor": 118, "rawmet": [31, 34, 72], "rawpuppimet": [31, 34, 72], "rax": 119, "rcparam": 119, "re": [6, 69, 103, 119], "read": [3, 24, 30, 32, 71, 76, 89, 101, 102, 118, 121], "read_coffea_config": [76, 102], "read_csv": 3, "readabl": 93, "readcsv": [3, 102], "reader": 71, "readi": 117, "readm": 103, "readonlydirectori": 32, "readtim": 30, "real": [7, 117, 118, 120, 123], "realiti": [61, 62, 63, 64], "realiz": 66, "realli": 119, "realtiv": [2, 78], "reason": [103, 119, 121], "rebin": [6, 102, 119, 121], "receiv": [75, 119], "recent": 103, "reco_beam": 33, "reco_daughter_allshow": 33, "reco_daughter_alltrack": 33, "recobeam": 33, "recommend": [74, 101, 103, 119], "reconstruct": 100, "record": [31, 32, 35, 36, 48, 72, 77, 120, 121], "recover": [69, 74, 102], "rectangular": [13, 100], "redrawn": 14, "reduc": [4, 6, 67, 100, 102, 119, 121], "reduce_list": [24, 25], "reduct": [68, 100], "ref": [31, 72], "refactor": 102, "refer": [5, 30, 31, 32, 34, 35, 37, 48, 72, 79, 102, 120], "reg": [117, 118], "regard": 119, "regardless": [31, 72], "region": [117, 119], "regist": [39, 123], "registri": 103, "regular": [117, 119, 121, 123], "rel": [61, 62, 63, 66, 103], "relat": 35, "relax": 117, "releas": [102, 103, 120], "reli": 121, "reloc": 103, "remain": [6, 12, 14, 69, 74], "remot": [120, 123], "remov": [6, 14, 35, 102, 119, 121], "render": [93, 101, 102, 117, 119, 120, 121], "repartit": 89, "repeat": [119, 120], "replac": [90, 119], "repo": [102, 103], "report": 79, "repositori": 103, "repres": [3, 12, 13, 14, 15, 114, 119], "represent": [8, 120], "request": 103, "requir": [0, 40, 41, 42, 48, 60, 61, 62, 63, 64, 65, 66, 69, 73, 74, 100, 102, 103, 117, 120, 121, 123], "reserv": [6, 119], "reset": 6, "reshap": [3, 102], "reso": 22, "resolut": [22, 23, 107], "resolv": [31, 34, 72, 112], "reson": 120, "resourc": [79, 100, 102, 123], "resource_monitor": [79, 102], "resources_mod": [79, 102, 123], "respect": [3, 31, 34, 72, 100, 117, 119], "respons": 119, "rest": 60, "restart": 76, "restrict": [71, 100], "result": [6, 36, 60, 67, 69, 74, 75, 77, 103, 117, 118, 121], "retri": [68, 76, 79, 102], "retriev": 68, "return": [0, 1, 2, 3, 4, 5, 6, 10, 12, 13, 14, 15, 19, 21, 22, 23, 24, 26, 28, 29, 31, 35, 36, 39, 45, 46, 48, 50, 55, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 83, 84, 87, 90, 91, 117, 118, 119, 121, 123], "return_combin": 60, "return_metr": 60, "revstat": 16, "reweight": [6, 118], "rewrap_recordarrai": 102, "rho": [30, 60, 62, 63, 64, 65, 102, 114, 118], "rho2": [62, 63, 65, 102], "rich": [116, 118, 120], "rich_bar": 102, "richer": 120, "right": [69, 74, 119], "rightarrow": 119, "ring": 30, "root": [10, 24, 25, 29, 30, 31, 32, 36, 67, 72, 76, 77, 89, 101, 102, 117, 119, 120, 121, 123], "roughli": [100, 119, 121], "routin": [103, 106], "row": [14, 81, 100, 119], "row_overflow": 14, "rs120203": 16, "rsumw": 119, "run": [26, 27, 28, 76, 79, 102, 103, 117, 118, 119, 120, 121, 123], "run2012b_doublemupark": [121, 123], "run2012c_doublemupark": [121, 123], "run_fn": 123, "run_spark_job": [100, 102], "runlumi": 26, "runner": [102, 115, 121, 123], "runtim": [79, 123], "runtime_cach": 32, "runtimewarn": [119, 121], "rv": 119, "rvalu": [2, 78], "s743": 16, "safer": 74, "sai": 118, "same": [0, 2, 4, 6, 24, 60, 65, 66, 67, 73, 78, 79, 103, 117, 119, 120, 121, 123], "sampl": [24, 117, 118, 119, 120, 123], "satisfi": 60, "save": [5, 75, 102, 103, 118], "savemetr": [76, 102], "scalar": [30, 60, 61, 62, 63, 64, 65, 66], "scalarht": 30, "scale": [3, 6, 15, 16, 21, 23, 30, 67, 101, 102, 107, 115, 117, 119, 121, 123], "scalefactors_tight_electron": [24, 117, 118], "scalefactors_tight_electron_error": 117, "scaleout": 67, "scalepdf": [30, 120], "scatter": 119, "schema": [29, 30, 31, 32, 33, 34, 35, 36, 72, 76, 77, 110, 113, 115, 118, 120, 121], "schema_vers": 118, "schemaclass": [30, 31, 32, 72, 117, 118, 120, 121], "schemav2": 118, "scheme": 119, "scientif": [100, 102, 103, 119], "scikit": [119, 120], "scipi": [102, 119], "scracth": 123, "scratch": [103, 123], "scratch_dir": 123, "script": [79, 103, 123], "search": [102, 121], "second": [30, 76, 121, 123], "secondari": [30, 34, 44, 57], "secondaryvertex": [31, 34, 72, 102, 113], "secret": 123, "section": [30, 100, 102, 103], "sed": 103, "see": [3, 4, 5, 6, 12, 13, 14, 15, 16, 30, 79, 83, 84, 87, 90, 102, 103, 119, 120, 123], "seem": 119, "seen": [5, 79, 117], "select": [0, 45, 55, 73, 117, 119], "self": [3, 48, 60, 67, 68, 69, 70, 74, 75, 76, 79, 103, 117, 119, 120, 121, 123], "semant": [83, 84, 87, 90, 101, 102], "semicolon": 119, "send": [79, 89, 118], "sensibl": 102, "sent": [79, 123], "separ": 119, "sequenc": [6, 79, 120], "seri": 19, "serializ": [68, 75, 118], "serv": 24, "server": [102, 103], "servic": 103, "session": [76, 79, 89], "set": [2, 3, 5, 6, 15, 16, 19, 21, 22, 23, 25, 28, 31, 48, 60, 68, 69, 71, 72, 74, 76, 78, 79, 81, 90, 100, 103, 117, 118, 119, 120, 121, 123], "set_accumul": [102, 115], "set_prop_cycl": 119, "set_xlabel": 119, "set_xlim": [119, 121], "set_xscal": 121, "set_ylabel": 119, "set_ylim": [119, 121], "set_yscal": 121, "setitem": 120, "setup": [79, 102, 103, 123], "setuptool": 103, "sever": [0, 67, 71, 73, 100, 103, 117, 118, 119, 120, 121, 123], "sf": [2, 118], "sfhist": 118, "sft": 103, "sh": 103, "shadow": 119, "shape": [0, 3, 6, 24, 60, 67, 73, 81, 119], "sharex": 119, "shell": 103, "shift": [2, 78, 117, 119], "short": 123, "shortcut": 120, "shorthand": [0, 73], "should": [4, 60, 75, 76, 79, 81, 120, 123], "show": [67, 93, 118, 120, 121, 123], "shower": 33, "showin": 121, "shown": [103, 118], "sibl": 120, "side": [30, 123], "sigma": 30, "sign": [79, 103, 117, 121], "signal": [30, 117], "signatur": [19, 21, 22, 23, 102], "signific": 120, "similar": [13, 14, 76, 89, 102, 106, 118, 119, 120, 123], "similarli": [120, 123], "simpl": [71, 119, 120, 121, 123], "simpli": [75, 100, 103, 121], "simplifi": [118, 119], "simul": [102, 119, 120, 121], "sin": [61, 62, 63, 64], "sinc": [79, 103, 117, 119, 120, 121], "singl": [2, 6, 15, 24, 31, 36, 72, 75, 76, 77, 100, 119, 120, 121, 123], "singleton": [30, 102, 121], "singular": 103, "singularityimag": 103, "sinh": [62, 63], "site": [26, 79, 103, 119, 121, 123], "siteconf": 26, "size": [2, 4, 5, 6, 10, 15, 67, 71, 78, 89, 102, 103, 114, 115, 118, 119], "skeleton": [75, 121], "skip": [12, 13, 15, 121], "skipbadfil": [76, 102], "skyhook_opt": [32, 76], "sl6": 103, "slc6": 103, "slice": [4, 6, 31, 34, 72, 119, 120], "slightli": 118, "slow": 79, "small": [79, 100, 103, 114, 117, 120], "smaller": [0, 73], "smallest": 117, "snapshot": 121, "so": [6, 16, 31, 34, 35, 36, 72, 76, 77, 100, 101, 103, 114, 117, 119, 120, 122], "soft": 30, "softactivityjet": [31, 34, 72], "softdrop": 30, "softdroppedp4": 30, "softdroppedsubjet1": 30, "softdroppedsubjet2": 30, "softid": 121, "softwar": [103, 123], "solut": [16, 103], "some": [6, 10, 12, 15, 37, 61, 62, 63, 64, 76, 89, 103, 112, 117, 118, 119, 120, 121, 122], "someth": [25, 36, 77], "soon": 119, "sort": [5, 102, 112, 121], "sourc": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 103, 108, 118, 120, 123], "sourcenam": 21, "space": 79, "span": 100, "spark": [75, 89, 100, 102, 103, 121], "spark_executor": 89, "sparkexecutor": 89, "spars": [5, 6, 8], "sparse_ax": [6, 102], "sparse_dim": [6, 102], "sparse_nbin": [6, 102], "sparseaxi": [5, 6, 106], "spawn": 100, "speci": 6, "special": [4, 7, 12, 13, 15, 31, 72, 103], "special_item": [31, 72, 102], "specif": [0, 36, 73, 77, 79, 103, 117, 118], "specifi": [0, 2, 6, 12, 13, 14, 15, 19, 21, 22, 23, 25, 31, 60, 68, 69, 72, 73, 74, 76, 78, 79, 118, 119], "spectra": 118, "spectrum": 121, "speed": [93, 119, 120], "speedcolumn": [102, 116], "spent": 119, "spheric": [64, 114], "sphericalthreevector": [62, 63, 102, 112, 113, 114], "split": [36, 69, 74, 77, 79, 120, 123], "split_on_exhaust": [79, 102, 123], "sqrt": [60, 61, 62, 63, 64, 65, 66, 119, 120, 121], "squar": [6, 11, 16, 30, 60, 61, 62, 63, 64, 65, 66], "src": [118, 120], "srv": 103, "ssl": [79, 102], "stabl": 26, "stack": [5, 12, 100, 103, 118, 119], "stack_error_opt": 119, "stack_fill_opt": 119, "stage": [67, 79, 119], "standalon": 109, "standard": [36, 77, 79, 118, 121], "standlaon": 119, "start": [4, 31, 32, 71, 72, 102, 118, 119, 121, 123], "start3d": 33, "start4d": 33, "startswith": 117, "stat": 119, "state": 75, "static": 76, "statist": [79, 100, 102, 117, 118], "stats_log": [79, 102], "statu": [30, 48, 68, 69, 70, 74, 79, 120], "status_display_interv": [79, 102], "statusflag": [48, 120], "steal": 118, "step": [12, 36, 77, 89, 119], "still": [31, 34, 72, 103, 117], "stop": [4, 25, 32], "storabl": [0, 73], "storag": [6, 106, 117, 121], "store": [0, 2, 6, 24, 25, 36, 73, 77, 78, 117], "storeindividu": [2, 78], "str": [0, 2, 3, 4, 5, 6, 8, 12, 13, 14, 15, 26, 28, 32, 39, 48, 68, 69, 70, 73, 74, 76, 78, 79, 93], "straightforward": 118, "strategi": 79, "strcat": [117, 118, 121], "strcategori": [117, 121, 123], "strictli": 67, "string": [5, 6, 8, 119, 120], "stringbin": [5, 102, 106, 119], "stripe": 75, "structur": [6, 36, 77, 100, 102, 119, 120], "stub": 6, "studi": 117, "style": [13, 26, 101, 102, 117], "stylesheet": 119, "sub": [32, 102, 106, 120], "subclass": 114, "subgenjetak8": [31, 34, 72], "subjet": [30, 31, 34, 46, 72, 102], "subjet_subgenjetak8idx": 34, "subjetti": 30, "sublead": 30, "submiss": [79, 103], "submit": [69, 74, 76, 79, 89, 103, 123], "subpackag": 119, "subplot": [118, 119, 121], "subplots_adjust": 119, "subprocess": 30, "subsequ": [48, 120], "subset": [0, 2, 6, 39, 73, 78, 122], "substitut": 16, "substract": 66, "subtract": [60, 65, 66, 102], "success": [9, 11, 123], "successor": 119, "sudo": 102, "suffix": 99, "suggest": 99, "sum": [4, 6, 11, 12, 13, 14, 15, 16, 30, 40, 60, 65, 66, 67, 102, 117, 118, 119, 120, 121, 123], "summari": [0, 1, 2, 3, 4, 5, 6, 7, 8, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 38, 39, 40, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 55, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 81, 83, 84, 87, 90, 91, 93, 100, 117], "sumpt": 30, "sumpt2": 30, "sumptcharg": 30, "sumptchargedpu": 30, "sumptneutr": 30, "sumw": [1, 16, 75, 117, 119, 123], "sumw2": [1, 6, 16, 117, 119], "sumw_denom": 119, "sumw_num": 119, "super": 102, "superced": 114, "suppli": [2, 6, 12, 13, 30, 31, 36, 69, 72, 77, 78, 102, 120], "support": [0, 3, 4, 25, 67, 76, 89, 100, 102, 117, 118, 119, 120], "suppos": 119, "sure": [6, 121], "sv": [31, 34, 44, 57, 72, 102], "switch": 119, "sy": 103, "symmetr": [2, 78], "syntax": [102, 103, 117, 119, 120], "syst": 117, "system": [103, 121, 123], "systemat": [2, 3, 25, 38, 45, 46, 50, 51, 52, 53, 55, 58, 78, 102, 111, 113, 117, 118], "t": [30, 40, 60, 62, 63, 76, 102, 103, 114, 117, 118, 119, 120, 121, 123], "tab": 119, "tabl": [25, 28, 31, 72, 101, 108], "table_column": 93, "tag": [3, 25, 30, 101, 102, 105], "tail": [69, 74], "tailor": [109, 119], "tailtimeout": [69, 74, 102], "take": [12, 79, 89, 103, 118, 119, 120], "taken": 4, "talk": 103, "tan": [60, 62, 63, 114], "tar": [103, 123], "tarbal": [79, 103, 123], "target": [30, 31, 72, 76], "task": [68, 79, 93, 100, 123], "tasks_accum_log": [79, 102], "tau": [30, 31, 34, 49, 72, 102, 113, 120], "tau_genpartidx": [31, 34, 72], "tau_jetidx": [31, 34, 72], "taujet": 35, "tautag": 30, "tbranch": 120, "technologi": 102, "temporari": [79, 123], "ten": 121, "terabyt": 121, "termin": [79, 103], "terminologi": 100, "test": [24, 100, 102, 103, 117, 118, 120, 123], "testsf2d": [24, 117, 118], "tev": [119, 121], "text": [13, 25, 60, 61, 62, 63, 64, 65, 66, 93, 118, 119], "text_opt": 13, "th1": [10, 119], "th2f": 118, "than": [7, 60, 79, 100, 118, 119, 120, 121], "thefil": 25, "thei": [6, 60, 69, 74, 79, 109, 117, 118, 120, 121], "them": [35, 76, 89, 101, 119, 120, 121], "thereof": 99, "theta": [30, 60, 62, 63, 64, 65, 102, 114], "thetyp": 25, "thi": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 13, 14, 15, 16, 19, 21, 22, 23, 25, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 57, 60, 61, 62, 63, 64, 65, 66, 67, 72, 73, 74, 76, 77, 78, 79, 81, 83, 84, 87, 90, 91, 99, 100, 103, 106, 112, 117, 118, 119, 120, 121, 123], "thing": [117, 119, 123], "those": [25, 31, 72, 106], "thousand": [117, 121], "thread": [36, 70, 77, 100, 103], "thread_work": 89, "threadpoolexecutor": 67, "three": [59, 103, 119], "threevector": [33, 60, 64, 102, 112, 113, 114], "threshold": [60, 117], "through": [24, 71, 101, 117, 119], "throughput": 79, "throw": 3, "thu": 119, "tick": 119, "tight": [3, 45, 46, 50, 55, 102, 119], "tightlepveto": [46, 50, 102], "time": [2, 30, 62, 63, 67, 69, 76, 78, 79, 102, 103, 118, 119, 121, 123], "timeout": [69, 74], "titl": [118, 120, 121], "titles": 119, "tkmet": [31, 34, 72], "tmp": [79, 123], "tmpdir": 123, "to_boost": [6, 102], "to_evalu": 118, "to_hist": [6, 102], "togeth": [40, 60, 65, 66, 67, 101, 102, 103, 121, 123], "too": [89, 102], "tool": [19, 21, 22, 23, 76, 101, 102, 103, 104, 105, 106, 107, 108, 109, 112, 119], "top": [29, 38, 103, 120], "top_object": [33, 102], "total": [2, 6, 7, 8, 30, 78, 117, 119, 121], "touter": 30, "toward": [60, 65, 66, 74, 102], "tower": 30, "track": [2, 30, 33, 57, 71, 75, 78, 117], "trackjet02": 30, "trackjet04": 30, "trackjet08": 30, "trackjet15": 30, "trackparticl": 35, "tradit": [100, 103], "transactions_log": [79, 102], "transax": 119, "transfer": [93, 123], "transform": [101, 102, 106, 120, 121], "transit": 100, "transpar": 102, "transvers": [3, 30, 52, 121], "treat": [6, 75], "treatment": 16, "tree": [32, 68, 71, 76, 100, 119], "treemak": [36, 77, 110, 115, 120], "treemakerschema": [102, 110, 115, 120], "treenam": [76, 121], "treepath": 32, "treereduct": [68, 79, 102], "tri": [79, 123], "trial": [9, 11], "trigger": [6, 30, 79], "trigobj": [31, 34, 72], "trim": 30, "trimmedp4": 30, "trival": 5, "trivial": [100, 121], "true": [0, 2, 3, 6, 12, 13, 15, 28, 30, 31, 48, 60, 68, 69, 70, 72, 73, 74, 78, 79, 117, 118, 119, 120, 121, 123], "true_beam": 33, "true_divid": 119, "truebeam": 33, "truth3": 35, "truth_collect": [35, 102], "truthboson": 35, "truthbottom": 35, "truthelectron": 35, "truthmuon": 35, "truthneutrino": 35, "truthparticl": 35, "truthphoton": 35, "truthtau": 35, "truthtop": 35, "try": [69, 74, 79, 89, 103], "tstart": [121, 123], "ttree": [36, 71, 76, 77, 120, 121], "tupl": [3, 6, 28, 36, 39, 60, 68, 69, 74, 77, 79], "turn": [79, 100], "tutori": [103, 121], "tw": 11, "tw2": 11, "twiddl": 120, "twiki": [19, 21, 22, 23], "two": [6, 12, 13, 15, 36, 40, 60, 65, 66, 67, 76, 77, 79, 100, 103, 118, 119, 120, 121], "twoelectron": 117, "twomuon": 117, "twovector": [61, 65, 102, 112, 113, 114], "tx": 30, "txt": [25, 26, 118, 123], "ty": 30, "type": [0, 2, 3, 10, 12, 13, 14, 15, 24, 25, 28, 31, 34, 35, 37, 38, 39, 67, 69, 72, 76, 78, 79, 91, 100, 103, 117, 118, 119, 120], "typic": [67, 102, 114, 117, 119], "u": [26, 119, 121], "ud": 3, "ufunc": 121, "uid": 79, "uint16": 0, "uint32": 0, "uint64": [0, 73], "unc": [15, 119], "uncertainti": [2, 15, 17, 18, 21, 39, 78, 102, 105, 107, 117, 118], "unchang": 29, "under": [6, 118], "underflow": 4, "underli": [6, 100], "underscor": 71, "understand": 6, "unflatten": [31, 72, 118], "unfortun": 90, "uniform": [4, 108, 119], "union": [39, 117], "uniqu": [27, 32, 121], "unit": [12, 13, 60, 65, 66, 68, 69, 70, 74, 76, 79, 102], "univers": 123, "unless": 103, "unnecessari": 122, "unpack": [103, 120], "unset": 79, "unspecifi": 117, "untransform": 118, "unweight": 16, "unzip": 60, "up": [0, 2, 14, 24, 30, 69, 73, 74, 78, 102, 103, 117, 118, 119, 120, 123], "up_val": 21, "updat": [90, 103, 104, 119, 123], "upgrad": 103, "upload": 119, "upon": 6, "upper": [4, 7, 16], "uproot": [10, 32, 36, 71, 75, 76, 77, 102, 119, 120, 121], "uproot3": [10, 119], "uproot3_method": 10, "uproot_opt": 32, "uproot_writ": [36, 77, 102], "urad": 30, "us": [2, 3, 4, 5, 6, 8, 13, 19, 21, 22, 23, 25, 30, 31, 32, 35, 36, 37, 38, 40, 48, 60, 61, 62, 63, 64, 65, 66, 68, 69, 72, 74, 76, 77, 78, 79, 89, 90, 100, 101, 102, 103, 104, 117, 119, 120, 121, 123], "usag": [67, 101, 119], "use_datafram": [68, 76, 102], "use_skyhook": [76, 102], "user": [6, 76, 79, 89, 100, 102, 103, 119, 121, 123], "usr": 103, "usual": [4, 12, 13, 36, 77, 100, 118, 121, 123], "util": [93, 94, 95, 96, 97, 98, 99, 102, 106, 117, 118, 119, 120, 121], "uuid": 32, "v": 119, "v0": [103, 118], "v1": [30, 102], "v2": 118, "v4": 119, "v5": [31, 72, 102], "v6": [31, 72, 102, 117, 118, 120], "v7": [31, 72, 102], "val": [90, 117, 119], "valid": [28, 118, 121, 123], "vals2": 119, "valu": [0, 1, 2, 3, 4, 5, 6, 12, 13, 15, 24, 25, 26, 27, 30, 31, 45, 55, 61, 62, 63, 64, 66, 67, 68, 71, 72, 73, 78, 79, 81, 83, 84, 87, 90, 91, 102, 117, 118, 119, 120, 121, 123], "value_accumul": [102, 115], "valueerror": 119, "values_astyp": 118, "var": [10, 118, 120], "vari": 39, "variabl": [10, 30, 31, 36, 72, 77, 79, 100, 117, 118, 119, 120], "varianc": [117, 121], "variat": [2, 39, 78, 102, 117], "varieti": 118, "variou": [25, 75, 100, 117, 118, 119, 120, 123], "varying_funct": 39, "ve": 119, "vec": 114, "vec4": 114, "vector": [0, 2, 4, 9, 11, 16, 27, 28, 30, 36, 40, 41, 42, 56, 57, 59, 60, 61, 62, 63, 64, 65, 66, 71, 73, 77, 78, 102, 112, 113, 119, 120, 121], "venv": 103, "verbatim": 120, "verbos": [79, 102, 119, 123], "veri": [100, 117, 121], "veric": 30, "version": [30, 31, 34, 72, 95, 103, 120], "version_info": 103, "versu": 30, "vertex": [30, 31, 34, 44, 57, 72, 102, 113], "vertexindex": 30, "vertic": [34, 36, 77], "verticalalign": 119, "veto": [45, 46, 50, 102], "via": [2, 10, 27, 36, 69, 76, 77, 78, 100, 102, 117, 119, 120], "view": [32, 103, 119, 121], "virtu": 120, "virtual": 102, "virtual_env": 103, "virtualenv": [102, 103], "visibl": [49, 100, 103, 120], "visual": 106, "vocal": 6, "vtx3d": 33, "w": [118, 123], "wa": [5, 103, 117, 118], "wai": [0, 73, 100, 102, 103, 117, 118, 119, 123], "wall_tim": 76, "want": [12, 13, 119, 120, 121], "warn": [16, 31, 72], "warn_missing_crossref": [30, 31, 72, 102], "watchdog": 79, "we": [67, 89, 102, 103, 117, 118, 119, 120, 121], "web": 117, "weight": [6, 11, 12, 13, 16, 25, 30, 101, 102, 104, 115, 118, 119, 120, 121], "weightdown": [2, 78, 117], "weightedsum": [117, 121], "weightlhef": 30, "weightsdesc": 25, "weightsdown": 2, "weightstat": 117, "weightstatist": [2, 102, 104, 117], "weightsup": 2, "weightup": [2, 78, 117], "welcom": [102, 120], "well": [60, 69, 74, 117, 118, 119], "were": [32, 100, 104, 117, 119, 121], "wgt": 24, "what": [39, 120, 121], "wheel": 103, "when": [4, 5, 12, 16, 31, 72, 79, 102, 118, 120, 122, 123], "where": [0, 4, 5, 6, 28, 29, 31, 34, 35, 48, 60, 72, 73, 79, 81, 103, 114, 118, 119, 120], "whether": [12, 13, 15, 76, 79], "which": [0, 3, 6, 7, 8, 13, 16, 31, 32, 60, 68, 69, 70, 72, 73, 74, 76, 79, 81, 89, 103, 114, 117, 118, 119, 120, 121, 123], "while": [74, 100], "whole": [6, 25, 76, 79, 123], "wide": [100, 103], "width": [4, 12, 13], "wiki": 9, "wikipedia": 9, "wildcard": [25, 118], "window": [69, 74, 103], "wise": 100, "wish": [102, 121], "with_nam": [114, 119, 121, 123], "within": [4, 30, 66, 100, 118, 119, 121], "without": [100, 102, 103, 118, 121], "wold": [36, 77], "won": [117, 120, 121], "word": 30, "work": [3, 35, 76, 79, 100, 102, 103, 117, 118, 119, 121], "work_queu": 123, "work_queue_executor": [100, 102], "work_queue_executor_arg": 123, "work_queue_factori": 123, "work_queue_work": 123, "workaround": [90, 103], "worker": [68, 69, 70, 76, 79, 102, 103, 121, 123], "worker_affin": [68, 102], "workflow": 123, "workingpoint": 3, "workitem": 76, "workload": 123, "workqueu": [79, 121], "workqueueexecutor": [76, 92, 102, 115, 123], "worri": 121, "wors": 15, "would": [4, 36, 77, 103, 117, 119], "wq": 123, "wq_manager_nam": 123, "wq_port": 123, "wrap": 120, "wrapper": [74, 76, 79, 89, 102, 103], "write": [10, 76, 89, 100, 118, 121, 123], "writeabl": [36, 77], "written": 123, "www": 16, "x": [6, 12, 13, 14, 15, 30, 36, 40, 60, 61, 62, 63, 64, 65, 66, 69, 77, 102, 114, 119], "x1": [30, 120], "x2": [30, 120], "x509": 79, "x509_proxi": [79, 102], "x509_user_proxi": 79, "x509up_u": 79, "x86_64": 103, "xaxi": [13, 119], "xbin": 119, "xd": 30, "xerr": 15, "xferd": 119, "xml": 26, "xouter": 30, "xoverflow": 13, "xpdf1": 120, "xpdf2": 120, "xrootd": 123, "xrootdtimeout": [76, 102], "xtick": 119, "xy": [61, 62, 63, 64, 65, 66], "xyz": 119, "xyz_sample2": 119, "xyzpoint": [36, 77], "y": [6, 15, 30, 36, 40, 60, 61, 62, 63, 64, 65, 66, 77, 102, 114, 119], "ybin": 119, "yd": 30, "ye": 123, "year": 118, "yield": [117, 119, 121], "ynew": 119, "you": [12, 13, 19, 21, 22, 23, 25, 39, 69, 76, 102, 103, 117, 118, 119, 120, 121, 123], "your": [101, 102, 103, 121, 123], "youter": 30, "yoverflow": 13, "ytick": 119, "z": [30, 36, 40, 60, 62, 63, 64, 65, 77, 102, 114, 117, 119, 120, 121], "z1": 121, "z2": 121, "zbin": 119, "zcf": 103, "zd": 30, "zero": [6, 16, 67, 79, 118, 119, 123], "zip": [21, 31, 35, 36, 72, 77, 114, 119, 121, 123], "zmm": 120, "znew": 119, "zouter": 30, "zxf": 103, "zz": [119, 121], "zzto4mu": 121, "zzx": 121, "\u03c3": 117}, "titles": ["PackedSelection", "WeightStatistics", "Weights", "BTagScaleFactor", "Bin", "Cat", "Hist", "Interval", "StringBin", "clopper_pearson_interval", "export1d", "normal_interval", "plot1d", "plot2d", "plotgrid", "plotratio", "poisson_interval", "CorrectedJetsFactory", "CorrectedMETFactory", "FactorizedJetCorrector", "JECStack", "JetCorrectionUncertainty", "JetResolution", "JetResolutionScaleFactor", "evaluator", "extractor", "LumiData", "LumiList", "LumiMask", "BaseSchema", "DelphesSchema", "NanoAODSchema", "NanoEventsFactory", "PDUNESchema", "PFNanoAODSchema", "PHYSLITESchema", "TreeMakerSchema", "NanoCollection", "NanoEvents", "Systematic", "Candidate", "PtEtaPhiECandidate", "PtEtaPhiMCandidate", "AssociatedPFCand", "AssociatedSV", "Electron", "FatJet", "FsrPhoton", "GenParticle", "GenVisTau", "Jet", "LowPtElectron", "MissingET", "Muon", "PFCand", "Photon", "PtEtaPhiMCollection", "SecondaryVertex", "Tau", "Vertex", "LorentzVector", "PolarTwoVector", "PtEtaPhiELorentzVector", "PtEtaPhiMLorentzVector", "SphericalThreeVector", "ThreeVector", "TwoVector", "AccumulatorABC", "DaskExecutor", "FuturesExecutor", "IterativeExecutor", "LazyDataFrame", "NanoAODSchema", "PackedSelection", "ParslExecutor", "ProcessorABC", "Runner", "TreeMakerSchema", "Weights", "WorkQueueExecutor", "accumulate", "column_accumulator", "dask_executor", "defaultdict_accumulator", "dict_accumulator", "futures_executor", "iterative_executor", "list_accumulator", "parsl_executor", "run_spark_job", "set_accumulator", "value_accumulator", "work_queue_executor", "SpeedColumn", "awkward_rewrap", "deprecate", "load", "rewrap_recordarray", "rich_bar", "save", "Coffea concepts", "Coffea by Example", "coffea - Columnar Object Framework For Effective Analysis", "Installing coffea", "coffea.analysis_tools", "coffea.btag_tools", "coffea.hist", "coffea.jetmet_tools", "coffea.lookup_tools", "coffea.lumi_tools", "coffea.nanoevents", "coffea.nanoevents.methods.base", "coffea.nanoevents.methods.candidate", "coffea.nanoevents.methods.nanoaod", "coffea.nanoevents.methods.vector", "coffea.processor", "coffea.util", "Analysis tools and accumulators", "Applying corrections to columnar data", "Coffea Histograms (deprecated)", "Reading data with coffea NanoEvents", "Coffea Processors", "API Reference Guide", "Work Queue Executor"], "titleterms": {"For": [102, 103], "accumul": [80, 117], "accumulatorabc": 67, "analysi": [100, 102, 117], "analysis_tool": 104, "api": 122, "appli": 118, "associatedpfcand": 43, "associatedsv": 44, "awkward_rewrap": 94, "b": 118, "base": [103, 111], "baseschema": 29, "bin": 4, "bring": 117, "btag_tool": [105, 118], "btagscalefactor": 3, "build": 118, "built": 103, "candid": [40, 112], "cat": 5, "class": [104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116], "clopper_pearson_interv": 9, "cm": 118, "coffea": [100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 118, 119, 120, 121], "column_accumul": 81, "columnar": [100, 102, 118], "concept": 100, "contain": 103, "correct": 118, "correctedjetsfactori": 17, "correctedmetfactori": 18, "correctionlib": 118, "creat": 103, "cvmf": 103, "dask_executor": 82, "daskexecutor": 68, "data": [118, 120], "defaultdict_accumul": 83, "delphesschema": 30, "depend": [102, 103], "deprec": [95, 119], "develop": 103, "diagram": [104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116], "dict_accumul": 84, "distribut": 100, "document": 102, "effect": 102, "electron": 45, "energi": 118, "environ": 103, "evalu": 24, "exampl": 101, "executor": [100, 123], "export1d": 10, "extractor": 25, "factorizedjetcorrector": 19, "fanci": 121, "fatjet": 46, "file": 118, "fill": 119, "framework": 102, "from": 118, "fsrphoton": 47, "function": [106, 115, 116], "futures_executor": 85, "futuresexecutor": 69, "genparticl": 48, "genvistau": 49, "get": 121, "guid": 122, "high": 118, "hist": [6, 106], "histogram": [118, 119], "imag": 103, "indic": 102, "inherit": [104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116], "instal": [102, 103], "interv": 7, "iterative_executor": 86, "iterativeexecutor": 70, "jecstack": 20, "jet": 50, "jetcorrectionuncertainti": 21, "jetmet_tool": [107, 118], "jetresolut": 22, "jetresolutionscalefactor": 23, "lazydatafram": 71, "lcg": 103, "level": 118, "list_accumul": 87, "load": 96, "local": 100, "lookup": 118, "lookup_tool": [108, 118], "lorentzvector": 60, "lowptelectron": 51, "lumi_tool": 109, "lumidata": 26, "lumilist": 27, "lumimask": 28, "method": [111, 112, 113, 114], "missinget": 52, "muon": 53, "nanoaod": 113, "nanoaodschema": [31, 72], "nanocollect": 37, "nanoev": [38, 110, 111, 112, 113, 114, 120], "nanoeventsfactori": 32, "normal_interv": 11, "object": 102, "open": 118, "option": 103, "out": 100, "own": 118, "packedselect": [0, 73, 117], "parsl_executor": 88, "parslexecutor": 74, "pduneschema": 33, "pfcand": 54, "pfnanoaodschema": 34, "photon": 55, "physliteschema": 35, "platform": 103, "plot": 119, "plot1d": 12, "plot2d": 13, "plotgrid": 14, "plotratio": 15, "poisson_interv": 16, "polartwovector": 61, "portabl": 103, "pre": 103, "processor": [100, 115, 121], "processorabc": 75, "ptetaphiecandid": 41, "ptetaphielorentzvector": 62, "ptetaphimcandid": 42, "ptetaphimcollect": 56, "ptetaphimlorentzvector": 63, "queue": 123, "quick": 103, "read": 120, "refer": 122, "rewrap_recordarrai": 97, "rich_bar": 98, "root": 118, "run_spark_job": 89, "runner": 76, "save": 99, "scale": [100, 118], "secondaryvertex": 57, "semant": 117, "set_accumul": 90, "speedcolumn": 93, "sphericalthreevector": 64, "start": 103, "strict": 102, "stringbin": 8, "style": 119, "support": 103, "systemat": 39, "tabl": [102, 118], "tag": 118, "tau": 58, "threevector": 65, "togeth": 117, "tool": [117, 118], "transform": [118, 119], "treemakerschema": [36, 77], "twovector": 66, "us": 118, "util": 116, "value_accumul": 91, "vector": 114, "vertex": 59, "via": 103, "virtual": 103, "weight": [2, 78, 117], "weightstatist": 1, "work": 123, "work_queue_executor": 92, "workqueueexecutor": 79, "your": 118}}) \ No newline at end of file diff --git a/wq.html b/wq.html new file mode 100644 index 000000000..ae55f226b --- /dev/null +++ b/wq.html @@ -0,0 +1,398 @@ + + + + + + + + + Work Queue Executor — coffea 0.7.23 documentation + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+ +
+
+
+
+ +
+

Work Queue Executor

+

Work Queue is a +distributed computing framework used to build large scale manager-worker +applications, developed by the Cooperative Computing Lab +(CCL) at the University of Notre Dame. This executor functions as the +manager program which divides up a Coffea data analysis workload into +discrete tasks. A large number of worker processes running on +cluster or cloud systems will execute the tasks.

+

To set up Coffea and Work Queue together, you may need to +create a Conda environment, install the software, and then +create a tarball containing the environment. The tarball is +sent to each worker in order to provide the same environment +as the manager machine.

+
# Create a new environment
+conda create --yes --name coffea-env -c conda-forge python coffea xrootd ndcctools conda conda-pack
+conda activate coffea-env
+
+# Pack the environment into a portable tarball.
+conda-pack --output coffea-env.tar.gz
+
+
+

To run an analysis, you must set up a work queue executor +with appropriate arguments. Here is a complete example:

+
###############################################################################
+# Example of Coffea with the Work Queue executor.
+#
+# To execute, start this application, and then start workers that will connect
+# to it and execute tasks.
+#
+# Note that, as written, this only processes 4 data chunks and should complete
+# in a short time.  For a real run, change maxchunks=None in the main program
+# below.
+#
+# For simple testing this script will automatically use one local worker. To
+# scale this up, see the wq.Factory configuration below to change to your
+# favorite batch system.
+###############################################################################
+
+###############################################################################
+# Sample processor class given in the Coffea manual.
+###############################################################################
+import work_queue as wq
+
+from coffea.processor import Runner
+from coffea.processor import WorkQueueExecutor
+
+###############################################################################
+# Collect and display setup info.
+###############################################################################
+
+print("------------------------------------------------")
+print("Example Coffea Analysis with Work Queue Executor")
+print("------------------------------------------------")
+
+import getpass
+
+wq_manager_name = "coffea-wq-{}".format(getpass.getuser())
+wq_port = 9123
+
+print("Manager Name: -M " + wq_manager_name)
+print("------------------------------------------------")
+
+
+###############################################################################
+# Define a custom Coffea processor
+###############################################################################
+
+from coffea import processor
+from coffea.nanoevents.methods import candidate
+import hist
+from collections import defaultdict
+import awkward as ak
+
+# register our candidate behaviors
+ak.behavior.update(candidate.behavior)
+
+
+class MyProcessor(processor.ProcessorABC):
+    @property
+    def accumulator(self):
+        return {
+            "sumw": defaultdict(float),
+            "mass": hist.Hist(
+                hist.axis.StrCategory([], name="dataset", label="Dataset"),
+                hist.axis.Regular(
+                    60, 60, 120, name="mass", label=r"$m_{\mu\mu}$ [GeV]"
+                ),
+                name="Events",
+            ),
+        }
+
+    def process(self, events):
+        # Note: This is required to ensure that behaviors are registered
+        # when running this code in a remote task.
+        ak.behavior.update(candidate.behavior)
+
+        output = self.accumulator
+
+        dataset = events.metadata["dataset"]
+        muons = ak.zip(
+            {
+                "pt": events.Muon_pt,
+                "eta": events.Muon_eta,
+                "phi": events.Muon_phi,
+                "mass": events.Muon_mass,
+                "charge": events.Muon_charge,
+            },
+            with_name="PtEtaPhiMCandidate",
+        )
+
+        cut = (ak.num(muons) == 2) & (ak.sum(muons.charge) == 0)
+        # add first and second muon in every event together
+        dimuon = muons[cut][:, 0] + muons[cut][:, 1]
+
+        output["sumw"][dataset] += len(events)
+        output["mass"].fill(
+            dataset=dataset,
+            mass=dimuon.mass,
+        )
+
+        return output
+
+    def postprocess(self, accumulator):
+        return accumulator
+
+
+###############################################################################
+# Sample data sources come from CERN opendata.
+###############################################################################
+
+fileset = {
+    "DoubleMuon": [
+        "root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012B_DoubleMuParked.root",
+        "root://eospublic.cern.ch//eos/root-eos/cms_opendata_2012_nanoaod/Run2012C_DoubleMuParked.root",
+    ],
+}
+
+
+###############################################################################
+# Configuration of the Work Queue Executor
+###############################################################################
+
+# secret passed between manager and workers for authentication
+my_password_file = "password.txt"
+with open(my_password_file, "w") as f:
+    f.write("my_secret_password")
+
+work_queue_executor_args = {
+    # Automatically allocate cores, memory and disk to tasks. Adjusts to
+    # maximum values measured. Initially, tasks use whole workers.
+    "resources_mode": "auto",
+    # Split a processing task in half according to its chunksize when it
+    # exhausts the resources allocated to it.
+    "split_on_exhaustion": True,
+    # Options to control how workers find this manager.
+    "master_name": wq_manager_name,
+    # Port for manager to listen on: if zero, will choose automatically.
+    "port": wq_port,
+    # Secret passed between manager and workers
+    "password_file": my_password_file,
+    # The named conda environment tarball will be transferred to each worker,
+    # and activated. This is useful when coffea is not installed in the remote
+    # machines. conda enviroments are created with conda-pack, and should at
+    # least include coffea, ndcctools (both from conda-forge channel)
+    # and their dependencies.
+    #
+    # "environment_file": "coffea-env.tar.gz",
+    # Debugging: Display notes about each task submitted/complete.
+    "verbose": True,
+    # Debugging: Display output of task if not empty.
+    "print_stdout": False,
+    # Debugging: Produce a lot at the manager side of things.
+    "debug_log": "coffea-wq.log",
+}
+
+executor = WorkQueueExecutor(**work_queue_executor_args)
+
+
+###############################################################################
+# Run the analysis using local Work Queue workers
+###############################################################################
+
+import time
+
+tstart = time.time()
+
+workers = wq.Factory(
+    # local runs:
+    batch_type="local",
+    manager_host_port="localhost:{}".format(wq_port)
+    # with a batch system, e.g., condor.
+    # (If coffea not at the installation site, then a conda
+    # environment_file should be defined in the work_queue_executor_args.)
+    # batch_type="condor", manager_name=wq_manager_name
+)
+
+workers.max_workers = 2
+workers.min_workers = 1
+workers.cores = 2
+workers.memory = 1000  # MB
+workers.disk = 2000  # MB
+workers.password = my_password_file
+
+# Instead of declaring the python environment per task, you can set it in
+# the factory directly. This is useful if you are going to run a workflow
+# several times using the same set of workers. It also ensures that the worker
+# itself executes in a friendly environment.
+# workers.python_package = "coffea-env.tar.gz"
+#
+# The factory tries to write temporary files to $TMPDIR (usually /tmp). When
+# this is not available, or causes errors, this scracth directory can be
+# manually set.
+# workers.scratch_dir = "./my-scratch-dir"
+
+with workers:
+    # define the Runner instance
+    run_fn = Runner(
+        executor=executor,
+        chunksize=100000,
+        maxchunks=4,  # change this to None for a large run
+    )
+    # execute the analysis on the given dataset
+    hists = run_fn(fileset, "Events", MyProcessor())
+
+elapsed = time.time() - tstart
+
+
+print(hists)
+print(hists["mass"])
+
+# (assert only valid when using maxchunks=4)
+assert hists["sumw"]["DoubleMuon"] == 400224
+
+
+

When executing this example, +you should see that Coffea begins to run, and a progress bar +shows the creation of tasks. Workers are created locally using the factory +declared.

+

You can also launch workers outside python. For testing purposes, you can start +a single worker on the same machine, and direct it to connect to your manager +process, like this:

+
work_queue_worker -P password.txt <hostname> 9123
+
+
+

Or:

+
work_queue_worker -P password.txt -M coffea-wq-${USER}
+
+
+

With a single worker, the process will be gradual as it completes +one task (or a few tasks) at a time. The output will be similar to this:

+
------------------------------------------------
+Example Coffea Analysis with Work Queue Executor
+------------------------------------------------
+Manager Name: -M coffea-wq-btovar
+------------------------------------------------
+Listening for work queue workers on port 9123.
+submitted preprocessing task id 1 item pre_0, with 1 file
+submitted preprocessing task id 2 item pre_1, with 1 file
+preprocessing task id 2 item pre_1 with 1 events on localhost. return code 0 (success)
+allocated cores: 2.0, memory: 1000 MB, disk 2000 MB, gpus: 0.0
+measured cores: 0.3, memory: 120 MB, disk 6 MB, gpus: 0.0, runtime 3.1 s
+preprocessing task id 1 item pre_0 with 1 events on localhost. return code 0 (success)
+allocated cores: 2.0, memory: 1000 MB, disk 2000 MB, gpus: 0.0
+measured cores: 0.3, memory: 120 MB, disk 6 MB, gpus: 0.0, runtime 2.9 s
+submitted processing task id 3 item p_2, with 100056 event
+submitted processing task id 4 item p_3, with 100056 event
+submitted processing task id 5 item p_4, with 100056 event
+submitted processing task id 6 item p_5, with 100056 event
+Preprocessing 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━      2/2 [ 0:00:06 < 0:00:00 | 0.3  file/s ]
+    Submitted   0%                                  0/400224 [ 0:00:00 < -:--:-- | ?   event/s ]
+    Processed   0%                                  0/400224 [ 0:00:00 < -:--:-- | ?   event/s ]
+    Accumulated 0%                                       0/1 [ 0:00:00 < -:--:-- | ?   tasks/s ]
+
+
+

To run at larger scale, you will need to run a large number +of workers on a cluster or other infrastructure. For example, +to submit 32 workers to an HTCondor pool:

+
condor_submit_workers -M coffea-wq-${USER} -P password.txt 1
+
+
+

Similarly, you can run the worker’s factory outside the manager. In that way, +you can have the manager and the factory running on different machines:

+
work_queue_factory -T condor -M coffea-wq-${USER} -P password.txt --max-workers 10 --cores 8 --python-env=env.tar.gz
+
+
+

For more information on starting and managing workers +on various batch systems and clusters, see the +Work Queue documentation

+
+ + +
+
+
+ +
+ +
+

© Copyright 2019, Fermi National Accelerator Laboratory.

+
+ + Built with Sphinx using a + theme + provided by Read the Docs. + + +
+
+
+
+
+ + + + \ No newline at end of file