diff --git a/data/anainfo/MC_CENTRALITY.info b/data/anainfo/MC_CENTRALITY.info
deleted file mode 100644
--- a/data/anainfo/MC_CENTRALITY.info
+++ /dev/null
@@ -1,10 +0,0 @@
-Name: MC_CENTRALITY
-Summary: Template analysis for using CentralityHistogram
-Status: UNVALIDATED
-Authors:
- - Leif Lönnblad <leif.lonnblad@thep.lu.se>
-NumEvents: 50000
-RunInfo: Any!
-Description:
-   Template analysis for using CentralityHistogram for dynamically
-   determining centrality intervals using summed eT in the forward region.
diff --git a/data/anainfo/MC_Centrality.info b/data/anainfo/MC_Centrality.info
new file mode 100644
--- /dev/null
+++ b/data/anainfo/MC_Centrality.info
@@ -0,0 +1,10 @@
+Name: MC_CENTRALITY
+Summary: Template analysis for using CentralityBinner
+Status: UNVALIDATED
+Authors:
+ - Leif Lönnblad <leif.lonnblad@thep.lu.se>
+NumEvents: 50000
+RunInfo: Any!
+Description:
+   Template analysis for using CentralityBinner for dynamically
+   determining centrality intervals using summed eT in the forward region.
diff --git a/data/anainfo/Makefile.am b/data/anainfo/Makefile.am
--- a/data/anainfo/Makefile.am
+++ b/data/anainfo/Makefile.am
@@ -1,430 +1,430 @@
 dist_pkgdata_DATA = \
   ALEPH_1991_S2435284.info \
   ALEPH_1995_I382179.info \
   ALEPH_1996_S3486095.info \
   ALEPH_1996_S3196992.info \
   ALEPH_1999_S4193598.info \
   ALEPH_2001_S4656318.info \
   ALEPH_2002_S4823664.info \
   ALEPH_2004_S5765862.info \
   ALICE_2010_S8624100.info \
   ALICE_2010_S8625980.info \
   ALICE_2010_S8706239.info \
   ALICE_2011_S8909580.info \
   ALICE_2011_S8945144.info \
   ALICE_2012_I1116147.info \
   ALICE_2012_I1181770.info \
   ALICE_2015_I1357424.info \
   ALICE_2014_I1300380.info \
   ARGUS_1993_S2653028.info \
   ARGUS_1993_S2669951.info \
   ARGUS_1993_S2789213.info \
   ATLAS_2010_S8591806.info \
   ATLAS_2010_S8817804.info \
   ATLAS_2010_S8894728.info \
   ATLAS_2010_S8914702.info \
   ATLAS_2010_S8918562.info \
   ATLAS_2010_S8919674.info \
   ATLAS_2010_CONF_2010_049.info \
   ATLAS_2011_S8924791.info \
   ATLAS_2011_S8971293.info \
   ATLAS_2011_S8983313.info \
   ATLAS_2011_S8994773.info \
   ATLAS_2011_S9002537.info \
   ATLAS_2011_S9019561.info \
   ATLAS_2011_S9041966.info \
   ATLAS_2011_S9120807.info \
   ATLAS_2011_S9126244.info \
   ATLAS_2011_S9128077.info \
   ATLAS_2011_S9131140.info \
   ATLAS_2011_S9108483.info \
   ATLAS_2011_S9212183.info \
   ATLAS_2011_I894867.info \
   ATLAS_2011_I921594.info \
   ATLAS_2011_I928289_W.info \
   ATLAS_2011_I928289_Z.info \
   ATLAS_2011_I930220.info \
   ATLAS_2011_S9035664.info \
   ATLAS_2011_I919017.info \
   ATLAS_2011_I925932.info \
   ATLAS_2011_I926145.info \
   ATLAS_2011_I929691.info \
   ATLAS_2011_I944826.info \
   ATLAS_2011_I945498.info \
   ATLAS_2011_I954993.info \
   ATLAS_2011_S9225137.info \
   ATLAS_2011_S9212353.info \
   ATLAS_2011_CONF_2011_090.info \
   ATLAS_2011_CONF_2011_098.info \
   ATLAS_2012_I943401.info \
   ATLAS_2012_I946427.info \
   ATLAS_2012_I1083318.info \
   ATLAS_2012_I1082936.info \
   ATLAS_2012_I1084540.info \
   ATLAS_2012_I1093734.info \
   ATLAS_2012_I1093738.info \
   ATLAS_2012_I1094061.info \
   ATLAS_2012_I1094564.info \
   ATLAS_2012_I1094568.info \
   ATLAS_2012_I1095236.info \
   ATLAS_2012_I1082009.info \
   ATLAS_2012_I1091481.info \
   ATLAS_2012_I1119557.info \
   ATLAS_2012_I1124167.info \
   ATLAS_2012_I1125575.info \
   ATLAS_2012_I1183818.info \
   ATLAS_2012_I1188891.info \
   ATLAS_2012_I1112263.info \
   ATLAS_2012_I1125961.info \
   ATLAS_2012_I1126136.info \
   ATLAS_2012_I1117704.info \
   ATLAS_2012_I1118269.info \
   ATLAS_2012_I1180197.info \
   ATLAS_2012_I1186556.info \
   ATLAS_2012_I1190891.info \
   ATLAS_2012_I1199269.info \
   ATLAS_2012_I1203852.info \
   ATLAS_2012_I1204447.info \
   ATLAS_2012_I1204784.info \
   ATLAS_2012_CONF_2012_001.info \
   ATLAS_2012_CONF_2012_103.info \
   ATLAS_2012_CONF_2012_104.info \
   ATLAS_2012_CONF_2012_105.info \
   ATLAS_2012_CONF_2012_109.info \
   ATLAS_2012_CONF_2012_153.info \
   ATLAS_2013_I1190187.info \
   ATLAS_2013_I1217863_W.info \
   ATLAS_2013_I1217863_W_EL.info \
   ATLAS_2013_I1217863_W_MU.info \
   ATLAS_2013_I1217863_Z.info \
   ATLAS_2013_I1217863_Z_EL.info \
   ATLAS_2013_I1217863_Z_MU.info \
   ATLAS_2013_I1217867.info \
   ATLAS_2013_I1219109.info \
   ATLAS_2013_I1219109_EL.info \
   ATLAS_2013_I1219109_MU.info \
   ATLAS_2013_I1230812.info \
   ATLAS_2013_I1230812_EL.info \
   ATLAS_2013_I1230812_MU.info \
   ATLAS_2013_I1243871.info \
   ATLAS_2013_I1263495.info \
   ATLAS_2014_I1268975.info \
   ATLAS_2014_I1279489.info \
   ATLAS_2014_I1282441.info \
   ATLAS_2014_I1298811.info \
   ATLAS_2014_I1304688.info \
   ATLAS_2014_I1307756.info \
   ATLAS_2014_I1306294.info \
   ATLAS_2014_I1306294_EL.info \
   ATLAS_2014_I1306294_MU.info \
   ATLAS_2014_I1315949.info \
   ATLAS_2014_I1325553.info \
   ATLAS_2014_I1300647.info \
   ATLAS_2014_I1288706.info \
   ATLAS_2014_I1307243.info \
   ATLAS_2014_I1312627.info \
   ATLAS_2014_I1312627_EL.info \
   ATLAS_2014_I1312627_MU.info \
   ATLAS_2014_I1306615.info \
   ATLAS_2015_I1393758.info \
   ATLAS_2015_I1364361.info \
   ATLAS_2015_I1345452.info \
   ATLAS_2015_I1351916.info \
   ATLAS_2015_I1351916_EL.info \
   ATLAS_2015_I1351916_MU.info \
   ATLAS_2013_I1216670.info \
   ATLAS_2013_I1244522.info \
   ATLAS_2014_I1282447.info \
   ATLAS_2014_I1298023.info \
   ATLAS_2014_I1319490.info \
   ATLAS_2014_I1319490_EL.info \
   ATLAS_2014_I1319490_MU.info \
   ATLAS_2014_I1326641.info \
   ATLAS_2014_I1327229.info \
   ATLAS_2015_I1387176.info \
   ATLAS_2015_CONF_2015_041.info \
   ATLAS_2015_CONF_2015_041_EL.info \
   ATLAS_2015_CONF_2015_041_MU.info \
   ATLAS_2015_I1376945.info \
   ATLAS_2015_I1390114.info \
   ATLAS_2015_I1394679.info \
   ATLAS_2015_I1397635.info \
   ATLAS_2015_I1397637.info \
   ATLAS_2015_I1408516.info \
   ATLAS_2015_I1408516_EL.info \
   ATLAS_2015_I1408516_MU.info \
   ATLAS_2015_I1404878.info \
   ATLAS_2016_I1419070.info \
   ATLAS_2016_I1419652.info \
   ATLAS_2016_I1424838.info \
   ATLAS_2016_I1426695.info \
   ATLAS_2016_I1444991.info \
   ATLAS_2016_I1452559.info \
   ATLAS_2016_I1457605.info \
   ATLAS_2016_I1458270.info \
   ATLAS_2016_I1467230.info \
   ATLAS_2016_I1467454.info \
   ATLAS_2016_I1467454_EL.info \
   ATLAS_2016_I1467454_MU.info \
   ATLAS_2016_I1468167.info \
   ATLAS_2016_I1468168.info \
   ATLAS_2016_I1479760.info \
   ATLAS_2016_CONF_2016_037.info \
   ATLAS_2016_CONF_2016_054.info \
   ATLAS_2016_CONF_2016_078.info \
   ATLAS_2016_CONF_2016_094.info \
   BABAR_2003_I593379.info \
   BABAR_2005_S6181155.info \
   BABAR_2007_S6895344.info \
   BABAR_2007_S7266081.info \
   BABAR_2013_I1116411.info \
   BABAR_2013_I1238276.info \
   BABAR_2015_I1334693.info \
   BELLE_2001_S4598261.info \
   BELLE_2008_I786560.info \
   BELLE_2011_I878990.info \
   BELLE_2013_I1216515.info \
   BELLE_2013_I1238273.info \
   BELLE_2015_I1397632.info \
   CDF_1988_S1865951.info \
   CDF_1990_S2089246.info \
   CDF_1993_S2742446.info \
   CDF_1994_S2952106.info \
   CDF_1996_S3108457.info \
   CDF_1996_S3349578.info \
   CDF_1996_S3418421.info \
   CDF_1997_S3541940.info \
   CDF_1998_S3618439.info \
   CDF_2000_S4155203.info \
   CDF_2000_S4266730.info \
   CDF_2001_S4517016.info \
   CDF_2001_S4563131.info \
   CDF_2001_S4751469.info \
   CDF_2002_S4796047.info \
   CDF_2004_S5839831.info \
   CDF_2005_S6080774.info \
   CDF_2005_S6217184.info \
   CDF_2006_S6450792.info \
   CDF_2006_S6653332.info \
   CDF_2007_S7057202.info \
   CDF_2008_S7540469.info \
   CDF_2008_S7541902.info \
   CDF_2008_S7782535.info \
   CDF_2008_S7828950.info \
   CDF_2008_S8093652.info \
   CDF_2008_S8095620.info \
   CDF_2009_S8233977.info \
   CDF_2009_NOTE_9936.info \
   CDF_2009_I856131.info \
   CDF_2009_S8436959.info \
   CDF_2010_S8591881_DY.info \
   CDF_2010_S8591881_QCD.info \
   CDF_2012_NOTE10874.info \
   CDF_2012_I1124333.info \
   CDF_2015_1388868.info \
   CLEO_2004_S5809304.info\
   CMS_2010_S8547297.info \
   CMS_2010_S8656010.info \
   CMS_2011_S8884919.info \
   CMS_2011_S9215166.info \
   CMS_2012_I941555.info \
   CMS_2011_I954992.info \
   CMS_2011_S8941262.info \
   CMS_2011_S8950903.info \
   CMS_2011_S8957746.info \
   CMS_2011_S8968497.info \
   CMS_2011_S8973270.info \
   CMS_2011_S8978280.info \
   CMS_2011_S9086218.info \
   CMS_2011_S9088458.info \
   CMS_2011_S9120041.info \
   CMS_2012_I1087342.info \
   CMS_2012_I1090423.info \
   CMS_2012_I1102908.info \
   CMS_2012_I1107658.info \
   CMS_2012_I1184941.info \
   CMS_2012_I1193338.info \
   CMS_2013_I1122847.info \
   CMS_2013_I1208923.info \
   CMS_2013_I1209721.info \
   CMS_2013_I1218372.info \
   CMS_2013_I1223519.info \
   CMS_2013_I1224539_DIJET.info \
   CMS_2013_I1224539_WJET.info \
   CMS_2013_I1224539_ZJET.info \
   CMS_2013_I1256943.info \
   CMS_2013_I1258128.info \
   CMS_2013_I1261026.info \
   CMS_2013_I1265659.info \
   CMS_2013_I1272853.info \
   CMS_2013_I1273574.info \
   CMS_2012_I1298807.info \
   CMS_2014_I1298810.info \
   CMS_2014_I1303894.info \
   CMS_2014_I1305624.info \
   CMS_2015_I1310737.info \
   CMS_2015_I1327224.info \
   CMS_2015_I1346843.info \
   CMS_2015_I1356998.info \
   CMS_2015_I1370682.info \
   CMS_2015_I1384119.info \
   CMS_2015_I1385107.info \
   CMS_2015_I1397174.info \
   CMS_2016_I1459051.info \
   CMS_2016_I1473674.info \
   CMSTOTEM_2014_I1294140.info \
   CMS_2010_PAS_QCD_10_024.info \
   CMS_2012_PAS_QCD_11_010.info \
   CMS_2012_PAS_FSQ_12_020.info \
   CMS_2016_PAS_SUS_16_14.info \
   D0_1995_I398175.info \
   D0_1996_S3214044.info \
   D0_1996_S3324664.info \
   D0_2000_S4480767.info \
   D0_2000_I499943.info  \
   D0_2001_S4674421.info \
   D0_2004_S5992206.info \
   D0_2006_S6438750.info \
   D0_2007_S7075677.info \
   D0_2008_S6879055.info \
   D0_2008_S7554427.info \
   D0_2008_S7662670.info \
   D0_2008_S7719523.info \
   D0_2008_S7837160.info \
   D0_2008_S7863608.info \
   D0_2009_S8202443.info \
   D0_2009_S8320160.info \
   D0_2009_S8349509.info \
   D0_2010_S8566488.info \
   D0_2010_S8570965.info \
   D0_2010_S8671338.info \
   D0_2010_S8821313.info \
   D0_2011_I895662.info \
   D0_2015_I1324946.info \
   D0_2000_I503361.info \
   E735_1998_S3905616.info \
   DELPHI_1995_S3137023.info \
   DELPHI_1996_S3430090.info \
   DELPHI_1999_S3960137.info \
   DELPHI_2000_S4328825.info \
   DELPHI_2002_069_CONF_603.info \
   DELPHI_2011_I890503.info \
   EXAMPLE.info \
   EXAMPLE_CUTS.info \
   EXAMPLE_SMEAR.info \
   H1_1994_S2919893.info \
   H1_1995_S3167097.info \
   H1_2000_S4129130.info \
   JADE_OPAL_2000_S4300807.info \
   JADE_1998_S3612880.info \
   LHCB_2010_S8758301.info \
   LHCB_2010_I867355.info \
   LHCB_2011_I917009.info \
   LHCB_2011_I919315.info \
   LHCB_2012_I1119400.info \
   LHCB_2012_I1208102.info \
   LHCB_2013_I1208105.info \
   LHCB_2013_I1218996.info \
   LHCB_2014_I1262703.info \
   LHCB_2014_I1281685.info \
   LHCB_2015_I1333223.info \
   LHCF_2012_I1115479.info \
-  MC_CENTRALITY.info \
+  MC_Centrality.info \
   MC_DIPHOTON.info \
   MC_ELECTRONS.info \
   MC_GENERIC.info \
   MC_HFJETS.info \
   MC_HINC.info \
   MC_HJETS.info \
   MC_HHJETS.info \
   MC_HKTSPLITTINGS.info \
   MC_IDENTIFIED.info \
   MC_JETS.info \
   MC_JETTAGS.info \
   MC_KTSPLITTINGS.info \
   MC_LEADJETUE.info \
   MC_MET.info \
   MC_MUONS.info \
   MC_PDFS.info \
   MC_PHOTONINC.info \
   MC_PHOTONJETS.info \
   MC_PHOTONKTSPLITTINGS.info \
   MC_PHOTONS.info \
   MC_PRINTEVENT.info \
   MC_QCD_PARTONS.info \
   MC_SUSY.info \
   MC_TAUS.info \
   MC_TTBAR.info \
   MC_VH2BB.info \
   MC_WINC.info \
   MC_WINC_EL.info \
   MC_WINC_MU.info \
   MC_WINC_EL_BARE.info \
   MC_WINC_MU_BARE.info \
   MC_WJETS.info \
   MC_WJETS_EL.info \
   MC_WJETS_MU.info \
   MC_WJETS_EL_BARE.info \
   MC_WJETS_MU_BARE.info \
   MC_WKTSPLITTINGS.info \
   MC_WPOL.info \
   MC_WWINC.info \
   MC_WWJETS.info \
   MC_WWKTSPLITTINGS.info \
   MC_XS.info \
   MC_ZINC.info \
   MC_ZINC_EL.info \
   MC_ZINC_MU.info \
   MC_ZINC_EL_BARE.info \
   MC_ZINC_MU_BARE.info \
   MC_ZJETS.info \
   MC_ZJETS_EL.info \
   MC_ZJETS_MU.info \
   MC_ZJETS_EL_BARE.info \
   MC_ZJETS_MU_BARE.info \
   MC_ZKTSPLITTINGS.info \
   MC_ZZINC.info \
   MC_ZZJETS.info \
   MC_ZZKTSPLITTINGS.info \
   L3_1992_I336180.info \
   L3_2004_I652683.info \
   OPAL_1993_S2692198.info \
   OPAL_1993_I342766.info \
   OPAL_1994_S2927284.info \
   OPAL_1995_S3198391.info \
   OPAL_1996_S3257789.info \
   OPAL_1997_S3396100.info \
   OPAL_1997_S3608263.info \
   OPAL_1998_S3702294.info \
   OPAL_1998_S3780481.info \
   OPAL_1998_S3749908.info \
   OPAL_2000_S4418603.info \
   OPAL_2001_S4553896.info \
   OPAL_2002_S5361494.info \
   OPAL_2003_I599181.info \
   OPAL_2004_S6132243.info \
   PDG_HADRON_MULTIPLICITIES.info \
   PDG_HADRON_MULTIPLICITIES_RATIOS.info \
   PDG_TAUS.info \
   SFM_1984_S1178091.info \
   SLD_1996_S3398250.info \
   SLD_1999_S3743934.info \
   SLD_2002_S4869273.info \
   SLD_2004_S5693039.info \
   STAR_2006_S6500200.info \
   STAR_2006_S6860818.info \
   STAR_2006_S6870392.info \
   STAR_2008_S7869363.info \
   STAR_2008_S7993412.info \
   STAR_2009_UE_HELEN.info \
   TASSO_1990_S2148048.info \
   TOTEM_2012_I1115294.info \
   TOTEM_2012_I1220862.info \
   TOTEM_2014_I1328627.info \
   ZEUS_2001_S4815815.info \
   UA1_1990_S2044935.info \
   UA5_1982_S875503.info \
   UA5_1986_S1583476.info \
   UA5_1987_S1640666.info \
   UA5_1988_S1867512.info \
   UA5_1989_S1926373.info
diff --git a/data/plotinfo/MC_CENTRALITY.plot b/data/plotinfo/MC_CENTRALITY.plot
deleted file mode 100644
--- a/data/plotinfo/MC_CENTRALITY.plot
+++ /dev/null
@@ -1,72 +0,0 @@
-# BEGIN PLOT /MC_CENTRALITY/ETfwd
-Title=Sum $E_T$ distribution
-XLabel=$\sum E_T$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\sum E_T$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaAll
-Title=Charged pseudo-rapidity distribution
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC95
-Title=Charged pseudo-rapidity distribution centrality 95-100\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC90
-Title=Charged pseudo-rapidity distribution centrality 90-95\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC80
-Title=Charged pseudo-rapidity distribution centrality 80-90\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC60
-Title=Charged pseudo-rapidity distribution centrality 60-80\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC00
-Title=Charged pseudo-rapidity distribution centrality 0-60\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC95
-Title=Charged pseudo-rapidity distribution centrality 95-100\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC90
-Title=Charged pseudo-rapidity distribution centrality 90-95\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC80
-Title=Charged pseudo-rapidity distribution centrality 80-90\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC60
-Title=Charged pseudo-rapidity distribution centrality 60-80\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
-# BEGIN PLOT /MC_CENTRALITY/EtaC00
-Title=Charged pseudo-rapidity distribution centrality 0-60\%
-XLabel=$\eta$ 
-YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
-# END PLOT
-
diff --git a/data/plotinfo/MC_Centrality.plot b/data/plotinfo/MC_Centrality.plot
new file mode 100644
--- /dev/null
+++ b/data/plotinfo/MC_Centrality.plot
@@ -0,0 +1,84 @@
+# BEGIN PLOT /MC_Centrality/ETfwd
+Title=Sum $E_T$ distribution
+XLabel=$\sum E_T$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\sum E_T$
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/ETfwd00
+Title=Sum $E_T$ distribution (0-60\%)
+XLabel=$\sum E_T$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\sum E_T$
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/ETfwd60
+Title=Sum $E_T$ distribution (60-80\%)
+XLabel=$\sum E_T$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\sum E_T$
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/ETfwd80
+Title=Sum $E_T$ distribution (80-90\%)
+XLabel=$\sum E_T$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\sum E_T$
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/ETfwd90
+Title=Sum $E_T$ distribution (90-95\%)
+XLabel=$\sum E_T$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\sum E_T$
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/ETfwd95
+Title=Sum $E_T$ distribution (95-100\%)
+XLabel=$\sum E_T$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\sum E_T$
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/EtaAll
+Title=Charged pseudo-rapidity distribution
+XLabel=$\eta$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
+LogY=0
+YMax=8
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/EtaC95
+Title=Charged pseudo-rapidity distribution (95-100\%)
+XLabel=$\eta$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
+LogY=0
+YMax=8
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/EtaC90
+Title=Charged pseudo-rapidity distribution (90-95\%)
+XLabel=$\eta$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
+LogY=0
+YMax=8
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/EtaC80
+Title=Charged pseudo-rapidity distribution (80-90\%)
+XLabel=$\eta$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
+LogY=0
+YMax=8
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/EtaC60
+Title=Charged pseudo-rapidity distribution (60-80\%)
+XLabel=$\eta$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
+LogY=0
+YMax=8
+# END PLOT
+
+# BEGIN PLOT /MC_Centrality/EtaC00
+Title=Charged pseudo-rapidity distribution (0-60\%)
+XLabel=$\eta$ 
+YLabel=$1/\sigma \; \mathrm{d}\sigma/\mathrm{d}\eta$
+LogY=0
+YMax=8
+# END PLOT
+
diff --git a/data/plotinfo/Makefile.am b/data/plotinfo/Makefile.am
--- a/data/plotinfo/Makefile.am
+++ b/data/plotinfo/Makefile.am
@@ -1,414 +1,414 @@
 dist_pkgdata_DATA = \
   ALEPH_1991_S2435284.plot \
   ALEPH_1995_I382179.plot \
   ALEPH_1996_S3486095.plot \
   ALEPH_1996_S3196992.plot \
   ALEPH_1999_S4193598.plot \
   ALEPH_2001_S4656318.plot \
   ALEPH_2002_S4823664.plot \
   ALEPH_2004_S5765862.plot \
   ALICE_2010_S8624100.plot \
   ALICE_2010_S8625980.plot \
   ALICE_2010_S8706239.plot \
   ALICE_2011_S8909580.plot \
   ALICE_2011_S8945144.plot \
   ALICE_2012_I1116147.plot \
   ALICE_2012_I1181770.plot \
   ALICE_2014_I1300380.plot \
   ALICE_2015_I1357424.plot \
   ARGUS_1993_S2653028.plot \
   ARGUS_1993_S2669951.plot \
   ARGUS_1993_S2789213.plot \
   ATLAS_2010_S8591806.plot \
   ATLAS_2010_S8817804.plot \
   ATLAS_2010_S8894728.plot \
   ATLAS_2010_S8914702.plot \
   ATLAS_2010_S8918562.plot \
   ATLAS_2010_S8919674.plot \
   ATLAS_2010_CONF_2010_049.plot \
   ATLAS_2011_S8924791.plot \
   ATLAS_2011_S8971293.plot \
   ATLAS_2011_S8994773.plot \
   ATLAS_2011_S9002537.plot \
   ATLAS_2011_S9035664.plot \
   ATLAS_2011_S9120807.plot \
   ATLAS_2011_S9126244.plot \
   ATLAS_2011_S9128077.plot \
   ATLAS_2011_S9131140.plot \
   ATLAS_2011_I894867.plot  \
   ATLAS_2011_I919017.plot  \
   ATLAS_2011_I921594.plot  \
   ATLAS_2011_I928289_W.plot \
   ATLAS_2011_I928289_Z.plot \
   ATLAS_2011_I925932.plot  \
   ATLAS_2011_I926145.plot  \
   ATLAS_2011_I929691.plot  \
   ATLAS_2011_I930220.plot  \
   ATLAS_2011_I944826.plot  \
   ATLAS_2011_I945498.plot  \
   ATLAS_2011_I954993.plot  \
   ATLAS_2011_S9225137.plot \
   ATLAS_2011_S9212183.plot \
   ATLAS_2011_S8983313.plot \
   ATLAS_2011_S9212353.plot \
   ATLAS_2011_CONF_2011_090.plot \
   ATLAS_2011_CONF_2011_098.plot \
   ATLAS_2012_I1082936.plot \
   ATLAS_2012_I1083318.plot \
   ATLAS_2012_I1084540.plot \
   ATLAS_2012_I1091481.plot \
   ATLAS_2012_I1093734.plot \
   ATLAS_2012_I1093738.plot \
   ATLAS_2012_I1094061.plot \
   ATLAS_2012_I1094564.plot \
   ATLAS_2012_I1094568.plot \
   ATLAS_2012_I1095236.plot \
   ATLAS_2012_I943401.plot \
   ATLAS_2012_I946427.plot \
   ATLAS_2012_I1119557.plot \
   ATLAS_2012_I1124167.plot \
   ATLAS_2012_I1125575.plot \
   ATLAS_2012_I1112263.plot \
   ATLAS_2012_I1125961.plot \
   ATLAS_2012_I1126136.plot \
   ATLAS_2012_I1117704.plot \
   ATLAS_2012_I1118269.plot \
   ATLAS_2012_I1180197.plot \
   ATLAS_2012_I1082009.plot \
   ATLAS_2012_I1183818.plot \
   ATLAS_2012_I1188891.plot \
   ATLAS_2012_I1186556.plot \
   ATLAS_2012_I1190891.plot \
   ATLAS_2012_I1199269.plot \
   ATLAS_2012_I1203852.plot \
   ATLAS_2012_I1204447.plot \
   ATLAS_2012_I1204784.plot \
   ATLAS_2012_CONF_2012_001.plot \
   ATLAS_2012_CONF_2012_103.plot \
   ATLAS_2012_CONF_2012_104.plot \
   ATLAS_2012_CONF_2012_105.plot \
   ATLAS_2012_CONF_2012_109.plot \
   ATLAS_2012_CONF_2012_153.plot \
   ATLAS_2013_I1190187.plot \
   ATLAS_2013_I1219109.plot \
   ATLAS_2013_I1219109_EL.plot \
   ATLAS_2013_I1219109_MU.plot \
   ATLAS_2013_I1217863_W.plot \
   ATLAS_2013_I1217863_W_EL.plot \
   ATLAS_2013_I1217863_W_MU.plot \
   ATLAS_2013_I1217863_Z.plot \
   ATLAS_2013_I1217863_Z_EL.plot \
   ATLAS_2013_I1217863_Z_MU.plot \
   ATLAS_2013_I1217867.plot \
   ATLAS_2013_I1216670.plot \
   ATLAS_2013_I1230812.plot \
   ATLAS_2013_I1230812_EL.plot \
   ATLAS_2013_I1230812_MU.plot \
   ATLAS_2013_I1243871.plot \
   ATLAS_2013_I1244522.plot \
   ATLAS_2013_I1263495.plot \
   ATLAS_2014_I1268975.plot \
   ATLAS_2014_I1279489.plot \
   ATLAS_2014_I1282441.plot \
   ATLAS_2014_I1298811.plot \
   ATLAS_2014_I1304688.plot \
   ATLAS_2014_I1307756.plot \
   ATLAS_2014_I1306294.plot \
   ATLAS_2014_I1306294_EL.plot \
   ATLAS_2014_I1306294_MU.plot \
   ATLAS_2014_I1315949.plot \
   ATLAS_2014_I1325553.plot \
   ATLAS_2014_I1300647.plot \
   ATLAS_2014_I1288706.plot \
   ATLAS_2014_I1307243.plot \
   ATLAS_2014_I1312627.plot \
   ATLAS_2014_I1312627_EL.plot \
   ATLAS_2014_I1312627_MU.plot \
   ATLAS_2014_I1306615.plot \
   ATLAS_2014_I1282447.plot \
   ATLAS_2014_I1298023.plot \
   ATLAS_2014_I1319490.plot \
   ATLAS_2014_I1319490_EL.plot \
   ATLAS_2014_I1319490_MU.plot \
   ATLAS_2014_I1326641.plot \
   ATLAS_2014_I1327229.plot \
   ATLAS_2015_I1393758.plot \
   ATLAS_2015_I1387176.plot \
   ATLAS_2015_I1364361.plot \
   ATLAS_2015_I1351916.plot \
   ATLAS_2015_I1351916_EL.plot \
   ATLAS_2015_I1351916_MU.plot \
   ATLAS_2015_I1345452.plot \
   ATLAS_2015_I1376945.plot \
   ATLAS_2015_I1390114.plot \
   ATLAS_2015_I1394679.plot \
   ATLAS_2015_I1397637.plot \
   ATLAS_2015_I1397635.plot \
   ATLAS_2015_CONF_2015_041.plot \
   ATLAS_2015_CONF_2015_041_EL.plot \
   ATLAS_2015_CONF_2015_041_MU.plot \
   ATLAS_2015_I1408516.plot \
   ATLAS_2015_I1408516_EL.plot \
   ATLAS_2015_I1408516_MU.plot \
   ATLAS_2015_I1404878.plot \
   ATLAS_2016_I1419070.plot \
   ATLAS_2016_I1419652.plot \
   ATLAS_2016_I1424838.plot \
   ATLAS_2016_I1426695.plot \
   ATLAS_2016_I1444991.plot \
   ATLAS_2016_I1457605.plot \
   ATLAS_2016_I1468168.plot \
   ATLAS_2016_I1467230.plot \
   ATLAS_2016_I1467454.plot \
   ATLAS_2016_I1468167.plot \
   ATLAS_2016_I1479760.plot \
   BABAR_2003_I593379.plot \
   BABAR_2005_S6181155.plot \
   BABAR_2007_S6895344.plot \
   BABAR_2007_S7266081.plot \
   BABAR_2013_I1116411.plot \
   BABAR_2013_I1238276.plot \
   BABAR_2015_I1334693.plot \
   BELLE_2001_S4598261.plot \
   BELLE_2008_I786560.plot \
   BELLE_2011_I878990.plot \
   BELLE_2013_I1216515.plot \
   BELLE_2013_I1238273.plot \
   BELLE_2015_I1397632.plot \
   CDF_1988_S1865951.plot \
   CDF_1990_S2089246.plot \
   CDF_1993_S2742446.plot \
   CDF_1994_S2952106.plot \
   CDF_1996_S3108457.plot \
   CDF_1996_S3349578.plot \
   CDF_1996_S3418421.plot \
   CDF_1997_S3541940.plot \
   CDF_1998_S3618439.plot \
   CDF_2000_S4155203.plot \
   CDF_2000_S4266730.plot \
   CDF_2001_S4517016.plot \
   CDF_2001_S4563131.plot \
   CDF_2001_S4751469.plot \
   CDF_2002_S4796047.plot \
   CDF_2004_S5839831.plot \
   CDF_2005_S6080774.plot \
   CDF_2005_S6217184.plot \
   CDF_2006_S6450792.plot \
   CDF_2006_S6653332.plot \
   CDF_2007_S7057202.plot \
   CDF_2008_S7540469.plot \
   CDF_2008_S7541902.plot \
   CDF_2008_S7782535.plot \
   CDF_2008_S7828950.plot \
   CDF_2008_S8093652.plot \
   CDF_2008_S8095620.plot \
   CDF_2009_S8233977.plot \
   CDF_2009_NOTE_9936.plot \
   CDF_2009_I856131.plot \
   CDF_2009_S8436959.plot \
   CDF_2010_S8591881_DY.plot \
   CDF_2010_S8591881_QCD.plot \
   CDF_2012_NOTE10874.plot \
   CDF_2012_I1124333.plot \
   CDF_2015_1388868.plot \
   CLEO_2004_S5809304.plot \
   CMS_2010_S8547297.plot \
   CMS_2010_S8656010.plot \
   CMS_2011_S8884919.plot \
   CMS_2011_S8941262.plot \
   CMS_2011_S8950903.plot \
   CMS_2011_S8957746.plot \
   CMS_2011_S8968497.plot \
   CMS_2011_S8973270.plot \
   CMS_2011_S8978280.plot \
   CMS_2011_S9086218.plot \
   CMS_2011_S9088458.plot \
   CMS_2011_S9120041.plot \
   CMS_2011_S9215166.plot \
   CMS_2012_I941555.plot \
   CMS_2011_I954992.plot \
   CMS_2012_I1087342.plot \
   CMS_2012_I1090423.plot \
   CMS_2012_I1102908.plot \
   CMS_2012_I1107658.plot \
   CMS_2012_I1184941.plot \
   CMS_2012_I1193338.plot \
   CMS_2013_I1122847.plot \
   CMS_2013_I1208923.plot \
   CMS_2013_I1209721.plot \
   CMS_2013_I1218372.plot \
   CMS_2013_I1224539_DIJET.plot \
   CMS_2013_I1224539_WJET.plot \
   CMS_2013_I1224539_ZJET.plot \
   CMS_2013_I1256943.plot \
   CMS_2013_I1258128.plot \
   CMS_2013_I1261026.plot \
   CMS_2013_I1265659.plot \
   CMS_2013_I1272853.plot \
   CMS_2013_I1273574.plot \
   CMS_2012_I1298807.plot \
   CMS_2014_I1298810.plot \
   CMS_2014_I1303894.plot \
   CMS_2014_I1305624.plot \
   CMS_2015_I1310737.plot \
   CMS_2015_I1327224.plot \
   CMS_2015_I1346843.plot \
   CMS_2015_I1356998.plot \
   CMS_2015_I1370682.plot \
   CMS_2015_I1384119.plot \
   CMS_2015_I1385107.plot \
   CMS_2015_I1397174.plot \
   CMS_2016_I1459051.plot \
   CMS_2016_I1473674.plot \
   CMS_2010_PAS_QCD_10_024.plot \
   CMS_2012_PAS_QCD_11_010.plot \
   CMS_2012_PAS_FSQ_12_020.plot \
   CMSTOTEM_2014_I1294140.plot \
   D0_1995_I398175.plot \
   D0_1996_S3214044.plot \
   D0_1996_S3324664.plot \
   D0_2000_S4480767.plot \
   D0_2000_I499943.plot \
   D0_2001_S4674421.plot \
   D0_2004_S5992206.plot \
   D0_2006_S6438750.plot \
   D0_2007_S7075677.plot \
   D0_2008_S6879055.plot \
   D0_2008_S7554427.plot \
   D0_2008_S7662670.plot \
   D0_2008_S7719523.plot \
   D0_2008_S7837160.plot \
   D0_2008_S7863608.plot \
   D0_2009_S8202443.plot \
   D0_2009_S8320160.plot \
   D0_2009_S8349509.plot \
   D0_2010_S8566488.plot \
   D0_2010_S8570965.plot \
   D0_2010_S8671338.plot \
   D0_2010_S8821313.plot \
   D0_2011_I895662.plot \
   D0_2015_I1324946.plot \
   D0_2000_I503361.plot \
   E735_1998_S3905616.plot \
   DELPHI_1995_S3137023.plot \
   DELPHI_1996_S3430090.plot \
   DELPHI_1999_S3960137.plot \
   DELPHI_2000_S4328825.plot \
   DELPHI_2002_069_CONF_603.plot \
   DELPHI_2011_I890503.plot \
   EXAMPLE.plot \
   H1_1994_S2919893.plot \
   H1_1995_S3167097.plot \
   H1_2000_S4129130.plot \
   JADE_OPAL_2000_S4300807.plot \
   JADE_1998_S3612880.plot \
   L3_1992_I336180.plot \
   L3_2004_I652683.plot \
   LHCB_2010_S8758301.plot \
   LHCB_2010_I867355.plot \
   LHCB_2011_I917009.plot \
   LHCB_2011_I919315.plot \
   LHCB_2012_I1119400.plot \
   LHCB_2012_I1208102.plot \
   LHCB_2013_I1208105.plot \
   LHCB_2013_I1218996.plot \
   LHCB_2014_I1262703.plot \
   LHCB_2014_I1281685.plot \
   LHCB_2015_I1333223.plot \
   LHCF_2012_I1115479.plot \
-  MC_CENTRALITY.plot \
+  MC_Centrality.plot \
   MC_DIPHOTON.plot \
   MC_ELECTRONS.plot \
   MC_GENERIC.plot \
   MC_HFJETS.plot \
   MC_HINC.plot \
   MC_HJETS.plot \
   MC_HHJETS.plot \
   MC_HKTSPLITTINGS.plot \
   MC_IDENTIFIED.plot \
   MC_JETS.plot \
   MC_JETTAGS.plot \
   MC_KTSPLITTINGS.plot \
   MC_LEADJETUE.plot \
   MC_MET.plot \
   MC_MUONS.plot \
   MC_PDFS.plot \
   MC_PHOTONINC.plot \
   MC_PHOTONJETS.plot \
   MC_PHOTONKTSPLITTINGS.plot \
   MC_PHOTONS.plot \
   MC_QCD_PARTONS.plot \
   MC_SUSY.plot \
   MC_TAUS.plot \
   MC_TTBAR.plot \
   MC_VH2BB.plot \
   MC_WINC.plot \
   MC_WINC_EL.plot \
   MC_WINC_MU.plot \
   MC_WINC_EL_BARE.plot \
   MC_WINC_MU_BARE.plot \
   MC_WJETS.plot \
   MC_WJETS_EL.plot \
   MC_WJETS_MU.plot \
   MC_WJETS_EL_BARE.plot \
   MC_WJETS_MU_BARE.plot \
   MC_WKTSPLITTINGS.plot \
   MC_WPOL.plot \
   MC_WWINC.plot \
   MC_WWJETS.plot \
   MC_WWKTSPLITTINGS.plot \
   MC_XS.plot \
   MC_ZINC.plot \
   MC_ZINC_EL.plot \
   MC_ZINC_MU.plot \
   MC_ZINC_EL_BARE.plot \
   MC_ZINC_MU_BARE.plot \
   MC_ZJETS.plot \
   MC_ZJETS_EL.plot \
   MC_ZJETS_MU.plot \
   MC_ZJETS_EL_BARE.plot \
   MC_ZJETS_MU_BARE.plot \
   MC_ZKTSPLITTINGS.plot \
   MC_ZZINC.plot \
   MC_ZZJETS.plot \
   MC_ZZKTSPLITTINGS.plot \
   OPAL_1993_S2692198.plot \
   OPAL_1993_I342766.plot \
   OPAL_1994_S2927284.plot \
   OPAL_1995_S3198391.plot \
   OPAL_1996_S3257789.plot \
   OPAL_1997_S3396100.plot \
   OPAL_1997_S3608263.plot \
   OPAL_1998_S3702294.plot \
   OPAL_1998_S3749908.plot \
   OPAL_1998_S3780481.plot \
   OPAL_2000_S4418603.plot \
   OPAL_2001_S4553896.plot \
   OPAL_2002_S5361494.plot \
   OPAL_2003_I599181.plot \
   OPAL_2004_S6132243.plot \
   PDG_HADRON_MULTIPLICITIES.plot \
   PDG_HADRON_MULTIPLICITIES_RATIOS.plot \
   PDG_TAUS.plot \
   SFM_1984_S1178091.plot \
   SLD_1996_S3398250.plot \
   SLD_1999_S3743934.plot \
   SLD_2002_S4869273.plot \
   SLD_2004_S5693039.plot \
   STAR_2006_S6500200.plot \
   STAR_2006_S6860818.plot \
   STAR_2006_S6870392.plot \
   STAR_2008_S7869363.plot \
   STAR_2008_S7993412.plot \
   STAR_2009_UE_HELEN.plot \
   TASSO_1990_S2148048.plot \
   TOTEM_2012_I1115294.plot \
   TOTEM_2012_I1220862.plot \
   TOTEM_2014_I1328627.plot \
   ZEUS_2001_S4815815.plot \
   UA1_1990_S2044935.plot \
   UA5_1982_S875503.plot \
   UA5_1986_S1583476.plot \
   UA5_1987_S1640666.plot \
   UA5_1988_S1867512.plot \
   UA5_1989_S1926373.plot
diff --git a/include/Rivet/Makefile.am b/include/Rivet/Makefile.am
--- a/include/Rivet/Makefile.am
+++ b/include/Rivet/Makefile.am
@@ -1,157 +1,156 @@
 ## Internal headers - not to be installed
 nobase_dist_noinst_HEADERS =
 ## Public headers - to be installed
 nobase_pkginclude_HEADERS =
 
 
 ## Rivet interface
 nobase_pkginclude_HEADERS += \
   Rivet.hh \
   Run.hh \
   Event.hh \
   ParticleBase.hh \
   Particle.fhh Particle.hh \
   Jet.fhh Jet.hh \
   Projection.fhh Projection.hh \
   ProjectionApplier.hh \
   ProjectionHandler.hh \
   Analysis.hh \
   AnalysisHandler.hh \
   AnalysisInfo.hh \
   AnalysisBuilder.hh \
   AnalysisLoader.hh
 
 
 ## Build config stuff
 nobase_pkginclude_HEADERS += \
   Config/RivetCommon.hh \
   Config/RivetConfig.hh \
   Config/BuildOptions.hh
 
 
 ## Projections
 nobase_pkginclude_HEADERS += \
   Projections/AxesDefinition.hh \
   Projections/Beam.hh \
   Projections/BeamThrust.hh \
   Projections/CentralEtHCM.hh \
-  Projections/CentralityEstimator.hh \
   Projections/ChargedFinalState.hh \
   Projections/ChargedLeptons.hh \
   Projections/ConstLossyFinalState.hh \
   Projections/DISFinalState.hh \
   Projections/DISKinematics.hh \
   Projections/DISLepton.hh \
   Projections/DressedLeptons.hh \
   Projections/FastJets.hh \
   Projections/FinalPartons.hh \
   Projections/FinalState.hh \
   Projections/FoxWolframMoments.hh \
   Projections/FParameter.hh \
   Projections/HadronicFinalState.hh \
   Projections/HeavyHadrons.hh \
   Projections/Hemispheres.hh \
   Projections/IdentifiedFinalState.hh \
   Projections/InitialQuarks.hh \
   Projections/InvMassFinalState.hh \
   Projections/JetAlg.hh \
   Projections/JetShape.hh \
   Projections/LeadingParticlesFinalState.hh \
   Projections/LossyFinalState.hh \
   Projections/MergedFinalState.hh \
   Projections/MissingMomentum.hh \
   Projections/NeutralFinalState.hh \
   Projections/NonHadronicFinalState.hh \
   Projections/NonPromptFinalState.hh \
   Projections/ParisiTensor.hh \
   Projections/ParticleFinder.hh \
   Projections/PartonicTops.hh \
   Projections/PrimaryHadrons.hh \
   Projections/PromptFinalState.hh \
   Projections/SmearedParticles.hh \
   Projections/SmearedJets.hh \
   Projections/SmearedMET.hh \
   Projections/Sphericity.hh \
   Projections/Spherocity.hh \
   Projections/TauFinder.hh \
   Projections/Thrust.hh \
   Projections/TriggerCDFRun0Run1.hh \
   Projections/TriggerCDFRun2.hh \
   Projections/TriggerUA5.hh \
   Projections/UnstableFinalState.hh \
   Projections/VetoedFinalState.hh \
   Projections/VisibleFinalState.hh \
   Projections/WFinder.hh \
   Projections/ZFinder.hh
 ## Meta-projection convenience headers
 nobase_pkginclude_HEADERS +=   \
   Projections/FinalStates.hh \
   Projections/Smearing.hh
 
 
 ## Analysis base class headers
 nobase_pkginclude_HEADERS += \
   Analyses/MC_ParticleAnalysis.hh \
   Analyses/MC_JetAnalysis.hh \
   Analyses/MC_JetSplittings.hh
 
 
 ## Tools
 nobase_pkginclude_HEADERS += \
   Tools/BeamConstraint.hh \
   Tools/BinnedHistogram.hh \
-  Tools/CentralityHistogram.hh \
+  Tools/CentralityBinner.hh \
   Tools/Cmp.fhh \
   Tools/Cmp.hh \
   Tools/Cutflow.hh \
   Tools/Cuts.fhh \
   Tools/Cuts.hh \
   Tools/Exceptions.hh \
   Tools/JetUtils.hh \
   Tools/Logging.hh  \
   Tools/ParticleBaseUtils.hh \
   Tools/ParticleIdUtils.hh \
   Tools/ParticleUtils.hh \
   Tools/ParticleName.hh \
   Tools/PrettyPrint.hh \
   Tools/RivetPaths.hh \
   Tools/RivetSTL.hh \
   Tools/RivetFastJet.hh \
   Tools/RivetHepMC.hh \
   Tools/RivetYODA.hh \
   Tools/RivetMT2.hh \
   Tools/SmearingFunctions.hh \
   Tools/TypeTraits.hh \
   Tools/Utils.hh
 nobase_dist_noinst_HEADERS += \
   Tools/osdir.hh
 
 
 ## Maths
 nobase_pkginclude_HEADERS += \
   Math/Matrices.hh \
   Math/Vector3.hh \
   Math/VectorN.hh \
   Math/MatrixN.hh \
   Math/MatrixDiag.hh \
   Math/MathHeader.hh \
   Math/Vectors.hh \
   Math/LorentzTrans.hh \
   Math/Matrix3.hh \
   Math/MathUtils.hh \
   Math/Vector4.hh \
   Math/Math.hh \
   Math/Units.hh \
   Math/Constants.hh \
   Math/eigen/util.h \
   Math/eigen/regressioninternal.h \
   Math/eigen/regression.h \
   Math/eigen/vector.h \
   Math/eigen/ludecompositionbase.h \
   Math/eigen/ludecomposition.h \
   Math/eigen/linearsolver.h \
   Math/eigen/linearsolverbase.h \
   Math/eigen/matrix.h \
   Math/eigen/vectorbase.h \
   Math/eigen/projective.h \
   Math/eigen/matrixbase.h
diff --git a/include/Rivet/Projections/CentralityEstimator.hh b/include/Rivet/Projections/CentralityEstimator.hh
deleted file mode 100644
--- a/include/Rivet/Projections/CentralityEstimator.hh
+++ /dev/null
@@ -1,80 +0,0 @@
-// -*- C++ -*-
-#ifndef RIVET_CentralityEstimator_HH
-#define RIVET_CentralityEstimator_HH
-
-#include "Rivet/Projection.hh"
-#include "Rivet/Projections/FinalState.hh"
-#include "Rivet/Event.hh"
-#include "HepMC/GenEvent.h"
-
-namespace Rivet {
-
-
-  /**
-    @brief Base class for projections giving the value of an
-    observable sensitive to the centrality of a collision.
-
-    @author Leif Lönnblad
-
-    The centrality of a collision is not really an observable, but the
-    concept is anyway often used in the heavy ion community as if it
-    were just that.
-
-    This base class can be used to provide a an estimator for the
-    centrality by projecting down to a single number which then canbe
-    used by a CentralityGroup object to select a histogram to be
-    filled with another observable depending on centrality percentile.
-
-    The eztimate() should be a non-negative number with large values
-    indicating a higher overlap than small ones. A negative value
-    indicates that the centrality estimate could not be calculated.
-
-    In the best of all worlds the centrality estimator should be a
-    proper hadron-level observable corrected for detector effects,
-    however, this base class only returns the inverse of the
-    impact_parameter member of the GenHeavyIon object in an GenEvent
-    if present and zero otherwise.
-   */
-  class CentralityEstimator : public Projection {
-  public:
-
-    /// Constructor.
-    CentralityEstimator()
-      : _estimate(-1.0) {}
-
-    /// Clone on the heap.
-    DEFAULT_RIVET_PROJ_CLONE(CentralityEstimator);
-
-  protected:
-
-    /// Perform the projection on the Event
-    void project(const Event& e) {
-      _estimate = -1.0;
-      const HepMC::HeavyIon * hi = e.genEvent()->heavy_ion();
-      if ( hi ) _estimate = hi->impact_parameter() > 0.0?
-                  1.0/hi->impact_parameter(): numeric_limits<double>::max();
-    }
-
-    /// Compare projections
-    int compare(const Projection& p) const {
-      return mkNamedPCmp(p, "CentEst");
-    }
-
-
-  public:
-
-    /// The value of the centrality estimate.
-    double estimate() const { return _estimate; }
-
-
-  protected:
-
-    /// The value of the centrality estimate.
-    double _estimate;
-
-  };
-
-}
-
-#endif
-
diff --git a/include/Rivet/Tools/CentralityBinner.hh b/include/Rivet/Tools/CentralityBinner.hh
new file mode 100644
--- /dev/null
+++ b/include/Rivet/Tools/CentralityBinner.hh
@@ -0,0 +1,782 @@
+// -*- C++ -*-
+#ifndef RIVET_CENTRALITYBINNER_HH
+#define RIVET_CENTRALITYBINNER_HH
+#include <tuple>
+#include "Rivet/Config/RivetCommon.hh"
+#include "Rivet/Tools/RivetYODA.hh"
+
+namespace Rivet {
+
+/**
+   @brief Base class for projections giving the value of an
+   observable sensitive to the centrality of a collision.
+
+   @author Leif Lönnblad
+
+   The centrality of a collision is not really an observable, but the
+   concept is anyway often used in the heavy ion community as if it
+   were just that.
+
+   This base class can be used to provide a an estimator for the
+   centrality by projecting down to a single number which then canbe
+   used by a CentralityGroup object to select a histogram to be
+   filled with another observable depending on centrality percentile.
+
+   The eztimate() should be a non-negative number with large values
+   indicating a higher overlap than small ones. A negative value
+   indicates that the centrality estimate could not be calculated.
+
+   In the best of all worlds the centrality estimator should be a
+   proper hadron-level observable corrected for detector effects,
+   however, this base class only returns the inverse of the
+   impact_parameter member of the GenHeavyIon object in an GenEvent
+   if present and zero otherwise.
+*/
+class CentralityEstimator : public Projection {
+public:
+
+  /// Constructor.
+  CentralityEstimator(): _estimate(-1.0) {}
+
+  /// Clone on the heap.
+  DEFAULT_RIVET_PROJ_CLONE(CentralityEstimator);
+
+protected:
+
+  /// Perform the projection on the Event
+  void project(const Event& e) {
+    _estimate = -1.0;
+    const HepMC::HeavyIon * hi = e.genEvent()->heavy_ion();
+    if ( hi ) _estimate = hi->impact_parameter() > 0.0?
+                1.0/hi->impact_parameter(): numeric_limits<double>::max();
+  }
+
+  /// Compare projections
+  int compare(const Projection& p) const {
+    return mkNamedPCmp(p, "CentEst");
+  }
+
+
+public:
+
+  /// The value of the centrality estimate.
+  double estimate() const { return _estimate; }
+
+
+protected:
+
+  /// The value of the centrality estimate.
+  double _estimate;
+
+};
+
+
+/// This is a traits class describing how to handle object handles by
+/// CentralityBinner. The default implementation basically describes
+/// what to do with Histo1DPtr.
+template <typename T>
+struct CentralityBinTraits {
+
+  /// Make a clone of the given object.
+  static T clone(const T & t) {
+    return T(t->newclone());
+  }
+
+  /// Add the contents of @a o to @a t.
+  static void add(T & t, const T & o) {
+    *t += *o;
+  }
+
+  /// Scale the contents of a given object.
+  static void scale(T & t, double f) {
+    t->scaleW(f);
+  }
+
+  /// Normalize the AnalysisObject to the sum of weights in a
+  /// centrality bin.
+  static void normalize(T & t, double sumw) {
+    t->normalize(t->sumW()/sumw);
+  }
+
+  /// Return the path of an AnalysisObject.
+  static string path(T t) {
+    return t->path();
+  }
+
+};
+
+/// The sole purpose of the MergeDistance class is to provide a
+/// "distance" for a potential merging of two neighboring bins in a
+/// CentralityBinner.
+struct MergeDistance {
+
+  /// This function should return a generalized distance between two
+  /// adjecent centrality bins to be merged. CentralityBinner will
+  /// always try to merge bins with the smallest distance. @a cestLo
+  /// and @cestHi are the lower and upper edges of resulting bin. @a
+  /// weight is the resulting sum of event weights in the bin. @a
+  /// centLo and @a centHi are the lower and upper prcentile limits
+  /// where the two bins currently resides. The two last arguments are
+  /// the total number of events in the two bins and the total number
+  /// of previous mergers repectively.
+  static double dist(double cestLo, double cestHi, double weight,
+                     double clo, double chi, double, double) {
+    return (cestHi - cestLo)*weight/(cestHi*(chi - clo));
+  }
+};    
+
+
+/**
+ * CentralityBinner contains a series of AnalysisObject of the same
+ * quantity each in a different percentiles of another quantity.  For
+ * example, a CentralityBinner may e.g. contain histograms of the
+ * cross section differential in \f$ p_T \f$ in different centrality
+ * regions for heavy ion collisions based on forward energy flow..
+ **/
+template <typename T = Histo1DPtr, typename MDist = MergeDistance>
+class CentralityBinner: public ProjectionApplier {
+  public:
+
+  /// Create a new empty CentralityBinner. @a maxbins is the maximum
+  /// number of bins used by the binner. Default is 1000, which is
+  /// typically enough. @a wlim is the mximum allowed error allowed
+  /// for the centrality limits before a warning is emitted.
+  CentralityBinner(int maxbins = 200, double wlim = 0.02)
+    : _currentCEst(-1.0), _maxBins(maxbins), _warnlimit(wlim), _weightsum(0.0) {
+    _percentiles.insert(0.0);
+    _percentiles.insert(1.0);
+  }
+
+  /// Set the centrality projection to be used. Note that this
+  /// projection must have already been declared to Rivet.
+  void setProjection(const CentralityEstimator & p, string pname) {
+    declare(p, pname);
+    _estimator = pname;
+  }
+
+  /// Return the class name.
+  virtual std::string name() const {
+    return "Rivet::CentralityBinner";
+  }
+
+  /// Add an AnalysisObject in the region between @a cmin and @a cmax to
+  /// this set of CentralityBinners. The range represent
+  /// percentiles and must be between 0 and 100. No overlaping bins
+  /// are allowed.
+
+  /// Note that (cmin=0, cmax=5), means the five percent LEAST
+  /// central events.
+
+  /// Optionally supply corresponding limits @a cestmin and @a cestmax
+  /// of the centrality extimator.
+
+  void add(T t, double cmin, double cmax,
+           double cestmin = -1.0, double cestmax = -1.0 ) {
+    _percentiles.insert(max(cmin/100.0, 0.0));
+    _percentiles.insert(min(cmax/100.0, 1.0));
+    if ( cestmin < 0.0 )
+      _unfilled.push_back(Bin(t, cmin/100.0, cmax/100.0));
+    else 
+      _ready[t] = Bin(t, cmin/100.0, cmax/100.0, cestmin, cestmax);
+  }
+
+  /// Return one of the AnalysisObjects in the CentralityBinner for the
+  /// given @a event. This version requires that a CentralityEstimator
+  /// object has been assigned that can compute the value of the
+  /// centrality estimator from the @a event. Optionally the @a weight
+  /// of the event is given. This should be the weight that will be
+  /// used to fill the AnalysisObject.
+  T select(const Event & event, double weight = 1.0) {
+    return select(applyProjection<CentralityEstimator>
+		  (event, _estimator).estimate(), weight);
+  }
+
+  /// Return one of the AnalysisObjecsts in the Setup the
+  /// CentralityBinner depending on the value of the centrality
+  /// estimator, @a cest. Optionally the @a weight of the event is
+  /// given. This should be the weight that will be used to fill the
+  /// AnalysisObject.
+  T select(double cest, double weight = 1.0);
+
+  /// At the end of the run, calculate the percentiles and fill the
+  /// AnalysisObjectss provided with the add() function. This is
+  /// typically called from the finalize method in an Analysis, but
+  /// can also be called earlier in which case the the select
+  /// functions can be continued to run as before with the edges
+  /// between the centrality regions now fixed.
+  void finalize();
+
+  /// Normalize each AnalysisObjects to the sum of event weights in the
+  /// corresponding centrality bin.
+  void normalizePerEvent() {
+    for ( auto & b : _ready ) b.second.normalizePerEvent();
+  }
+
+  /// Return a map bin edges of the centrality extimator indexed by
+  /// the corresponing percentile.
+  map<double,double> edges() const {
+    map<double,double> ret;
+    for ( auto & b : _ready ) {
+      ret[b.second._centLo] = b.second._cestLo;
+      ret[b.second._centHi] = b.second._cestHi;
+    }
+    return ret;
+  }
+
+  /// Return the current AnalysisObject from the latest call to select().
+  const T & current() const {
+    return _currenT;
+  }
+
+  /// Return the value of the centrality estimator set in the latest
+  /// call to select().
+  double estimator() const {
+    return _currentCEst;
+  }
+
+  vector<T> allObjects() {
+    vector<T> ret;
+    for ( auto & fb : _flexiBins ) ret.push_back(fb._t);
+    if ( !ret.empty() ) return ret;
+    for ( auto b : _ready ) ret.push_back(b.second._t);
+    return ret;
+  }
+
+private:
+
+  /// A flexible bin struct to be used to store temporary AnalysisObjects.
+  struct FlexiBin {
+
+    /// Construct with an initial centrality estimate and an event
+    /// weight.
+    FlexiBin(T & t, double cest = 0.0, double weight = 0.0)
+      : _t(t), _cestLo(cest), _cestHi(cest), _weightsum(weight), _n(1), _m(0) {}
+
+    /// Construct a temporary FlexiBin for finding a bin in a set.
+    FlexiBin(double cest)
+      : _cestLo(cest), _cestHi(cest), _weightsum(0.0), _n(0), _m(0) {}
+
+    /// Merge in the contents of another FlexiBin into this. 
+    void merge(const FlexiBin & fb) {
+      _cestLo = min(_cestLo, fb._cestLo);
+      _cestHi = max(_cestHi, fb._cestHi);
+      _weightsum += fb._weightsum;
+      CentralityBinTraits<T>::add(_t, fb._t);
+      _n += fb._n;
+      _m += fb._m + 1;
+    }
+
+    /// Comparisons for containers.
+    bool operator< (const FlexiBin & fb) const {
+      return _cestLo < fb._cestLo;
+    }
+
+    /// Return true if the given centrality estimate is in the range
+    /// of this bin.
+    bool inRange(double cest) const {
+      return cest == _cestLo || ( _cestLo < cest && cest < _cestHi );
+    }
+
+    /// The associated AnalysisObject.
+    T _t;
+
+    /// Current lower and upper edge of the centrality estimator for
+    /// the fills in the associated AnalysiObject.
+    double _cestLo, _cestHi;
+
+    /// The sum of weights for all events entering the associated
+    /// AnalysisObject.
+    mutable double _weightsum;
+
+    /// The number of times this bin has been selected.
+    mutable int _n;
+
+    /// The number of times this bin has been merged.
+    mutable int _m;
+
+  };
+
+  struct Bin {
+
+    /// Construct a completely empty bin.
+    Bin()
+      : _centLo(-1.0), _centHi(-1.0), _cestLo(-1.0), _cestHi(-1.0),
+	_weightsum(0.0), _underflow(0.0), _overflow(0.0),
+        _ambiguous(0), _ambweight(0.0) {}
+
+    /// Constructor taking an AnalysisObject and centrality interval
+    /// as argument. Optionally the interval in the estimator can be
+    /// given, in which case this bin is considered to be
+    /// "final".
+    Bin(T t, double centLo, double centHi,
+            double cestLo = -1.0, double cestHi = -1.0)
+      : _t(t), _centLo(centLo), _centHi(centHi),
+        _cestLo(cestLo), _cestHi(cestHi),
+	_weightsum(0.0), _underflow(0.0), _overflow(0.0),
+        _ambiguous(0.0), _ambweight(0.0) {}
+
+    /// Return true if the given centrality estimate is in the range
+    /// of this AnalysisObject.
+    bool inRange(double cest) const {
+      return _cestLo >= 0 && _cestLo <= cest &&
+        ( _cestHi < 0.0 || cest <= _cestHi );
+    }
+
+    /// Normalise the AnalysisObject to the tital cross section.
+    void normalizePerEvent() {
+      CentralityBinTraits<T>::normalize(_t, _weightsum);
+    }
+
+    /// The AnalysisObject.
+    T _t;
+
+    /// The range in centrality.
+    double _centLo, _centHi;
+
+    /// The corresponding range in the centrality estimator.
+    double _cestLo, _cestHi;
+
+    /// The sum of event weights for this bin;
+    double _weightsum;
+
+    /// The weight in a final AnalysisObject that contains events
+    /// below the centrality limit.
+    double _underflow;
+
+    /// The weight in a final AnalysisObject that contain events above
+    /// the centrality limit.
+    double _overflow;
+
+    /// Number of ambiguous events in this bin.
+    double _ambiguous;
+
+    /// Sum of abmiguous weights.
+    double _ambweight;
+
+  };
+
+protected:
+
+  /// Convenient typedefs.
+  typedef set<FlexiBin> FlexiBinSet;
+  
+  /// Find a bin corresponding to a given value of the centrality
+  /// estimator.
+  typename FlexiBinSet::iterator _findBin(double cest) {
+    if ( _flexiBins.empty() ) return _flexiBins.end();
+    auto it = _flexiBins.lower_bound(FlexiBin(cest));
+    if ( it->_cestLo == cest ) return it;
+    if ( it != _flexiBins.begin() ) --it;
+    if ( it->_cestLo < cest && cest < it->_cestHi ) return it;
+    return _flexiBins.end();
+  }
+
+  /// The name of the CentralityEstimator projection to be used.
+  string _estimator;
+
+  /// The current temporary AnalysisObject selected for the centrality
+  /// estimator calculated from the event presented in setup().
+  T _currenT;
+
+  /// The current value of the centrality estimator.
+  double _currentCEst;
+
+  /// The oversampling of centrality bins. For each requested
+  /// centrality bin this number of dynamic bins will be used.
+  int _maxBins;
+
+  /// If the fraction of events in a bin that comes from adjecent
+  /// centrality bins exceeds this, emit a warning.
+  double _warnlimit;
+
+  /// The unfilled AnalysisObjectss where the esimator edges has not yet
+  /// been determined.
+  vector<Bin> _unfilled;
+
+  /// The dynamic bins for ranges of centrality estimators.
+  FlexiBinSet _flexiBins;
+
+  /// The sum of all event weights so far.
+  double _weightsum;
+
+  /// The requested percentile limits.
+  set<double> _percentiles;
+  
+  /// The filled histograms where the estimator edges has been determined.
+  map<T, Bin> _ready;
+
+public:
+
+  /// Print out the _flexiBins to cerr.
+  void debug();
+  void fulldebug();
+
+};
+
+
+/// Traits specialization for Profile histograms.
+template <>
+struct CentralityBinTraits<Profile1DPtr> {
+
+  typedef Profile1DPtr T;
+
+  /// Make a clone of the given object.
+  static T clone(const T & t) {
+    return Profile1DPtr(t->newclone());
+  }
+
+  /// Add the contents of @a o to @a t.
+  static void add(T & t, const T & o) {
+    *t += *o;
+  }
+
+  /// Scale the contents of a given object.
+  static void scale(T & t, double f) {
+    t->scaleW(f);
+  }
+
+  static void normalize(T & t, double sumw) {}
+
+  /// Return the path of an AnalysisObject.
+  static string path(T t) {
+    return t->path();
+  }
+
+};
+
+
+/// Traits specialization for Profile histograms.
+template <>
+struct CentralityBinTraits<Profile2DPtr> {
+
+  typedef Profile2DPtr T;
+
+  /// Make a clone of the given object.
+  static T clone(const T & t) {
+    return Profile2DPtr(t->newclone());
+  }
+
+  /// Add the contents of @a o to @a t.
+  static void add(T & t, const T & o) {
+    *t += *o;
+  }
+
+  /// Scale the contents of a given object.
+  static void scale(T & t, double f) {
+    t->scaleW(f);
+  }
+
+  static void normalize(T & t, double sumw) {}
+
+  /// Return the name of an AnalysisObject.
+  static string path(T t) {
+    return t->path();
+  }
+
+};
+
+template <typename T>
+struct CentralityBinTraits< vector<T> > {
+
+  /// Make a clone of the given object.
+  static vector<T> clone(const vector<T> & tv) {
+    vector<T> rtv;
+    for ( auto t : tv ) rtv.push_back(CentralityBinTraits<T>::clone(t));
+    return rtv;
+  }
+
+  /// Add the contents of @a o to @a t.
+  static void add(vector<T> & tv, const vector<T> & ov) {
+    for ( int i = 0, N = tv.size(); i < N; ++i )
+      CentralityBinTraits::add(tv[i], ov[i]);
+  }
+
+  /// Scale the contents of a given object.
+  static void scale(vector<T> & tv, double f) {
+    for ( auto t : tv ) CentralityBinTraits<T>::scale(t, f);
+  }
+
+  static void normalize(vector<T> & tv, double sumw) {
+    for ( auto t : tv ) CentralityBinTraits<T>::normalize(t, sumw);
+  }
+
+  /// Return the path of an AnalysisObject.
+  static string path(const vector<T> & tv) {
+    string ret = "(vector:";
+    for ( auto t : tv ) {
+      ret += " ";
+      ret += CentralityBinTraits<T>::path(t);
+    }
+    ret += ")";
+    return ret;
+  }
+
+};
+
+template <size_t I, typename... Types>
+struct TupleCentralityBinTraitsHelper {
+
+  typedef tuple<Types...> Tuple;
+  typedef typename tuple_element<I-1,Tuple>::type T;
+
+  static void clone(Tuple & ret, const Tuple & tup) {
+    get<I-1>(ret) = CentralityBinTraits<T>::clone(get<I-1>(tup));
+    TupleCentralityBinTraitsHelper<I-1,Types...>::clone(ret, tup);
+  }
+
+  static void add(Tuple & tup, const Tuple & otup) {
+    CentralityBinTraits<T>::add(get<I-1>(tup),get<I-1>(otup));
+    TupleCentralityBinTraitsHelper<I-1,Types...>::add(tup, otup);
+  }
+
+  static void scale(Tuple & tup, double f) {
+    CentralityBinTraits<T>::scale(get<I-1>(tup), f);
+    TupleCentralityBinTraitsHelper<I-1,Types...>::scale(tup, f);
+  }
+
+  static void normalize(Tuple & tup, double sumw) {
+    CentralityBinTraits<T>::normalize(get<I-1>(tup), sumw);
+    TupleCentralityBinTraitsHelper<I-1,Types...>::normalize(tup, sumw);
+  }
+
+  static string path(const Tuple & tup) {
+    return " " + CentralityBinTraits<T>::path(get<I-1>(tup))
+      + TupleCentralityBinTraitsHelper<I-1,Types...>::path(tup);
+  }
+};
+
+template <typename... Types>
+struct TupleCentralityBinTraitsHelper<0,Types...> {
+
+  typedef tuple<Types...> Tuple;
+
+  static void clone(Tuple &, const Tuple &) {}
+  static void add(Tuple & tup, const Tuple & otup) {}
+  static void scale(Tuple & tup, double f) {}
+  static void normalize(Tuple & tup, double sumw) {}
+  static string path(const Tuple & tup) {return "";}
+
+};
+
+template <typename... Types>
+struct CentralityBinTraits< tuple<Types...> > {
+
+  typedef tuple<Types...> Tuple;
+  static const size_t N = tuple_size<Tuple>::value;
+
+  /// Make a clone of the given object.
+  static Tuple clone(const Tuple & tup) {
+    Tuple ret;
+    TupleCentralityBinTraitsHelper<N,Types...>::clone(ret, tup);
+    return ret;
+  }
+
+  /// Add the contents of @a o to @a t.
+  static void add(Tuple & tup, const Tuple & otup) {
+    TupleCentralityBinTraitsHelper<N,Types...>::add(tup, otup);    
+  }
+
+  /// Scale the contents of a given object.
+  static void scale(Tuple & tup, double f) {
+    TupleCentralityBinTraitsHelper<N,Types...>::scale(tup, f);    
+  }
+
+  static void normalize(Tuple & tup, double sumw) {
+    TupleCentralityBinTraitsHelper<N,Types...>::normalize(tup, sumw);    
+  }
+
+  /// Return the path of an AnalysisObject.
+  static string path(const Tuple & tup) {
+    string ret = "(tuple:";
+    ret += TupleCentralityBinTraitsHelper<N,Types...>::path(tup);
+    ret += ")";
+    return ret;
+  }
+
+};
+
+template <typename T, typename MDist>
+T CentralityBinner<T,MDist>::select(double cest, double weight) {
+  _currenT = T();
+  _currentCEst = cest;
+  _weightsum += weight;
+  
+  // If estimator is negative, something has gone wrong.
+  if ( _currentCEst < 0.0 ) return _currenT;
+
+  // If we already have finalized the limits on the centrality
+  // estimator, we just add the weights to their bins and return the
+  // corresponding AnalysisObject.
+  for ( auto & b : _ready ) if ( b.second.inRange(_currentCEst) ) {
+      b.second._weightsum += weight;
+      return b.second._t;
+    }
+
+  auto it = _findBin(cest);
+  if ( it == _flexiBins.end() ) {
+    _currenT = CentralityBinTraits<T>::clone(_unfilled.begin()->_t);
+    it = _flexiBins.insert(FlexiBin(_currenT, _currentCEst, weight)).first;
+  } else {
+    it->_weightsum += weight;
+    ++(it->_n);
+    _currenT = it->_t;
+  }
+
+  if ( _flexiBins.size() <= _maxBins ) return _currenT;
+
+
+  set<double>::iterator citn = _percentiles.begin();
+  set<double>::iterator cit0 = citn++;
+  auto selectit = _flexiBins.end();
+  double mindist = -1.0;
+  double acc = 0.0;
+  auto next = _flexiBins.begin();
+  auto prev = next++;
+  for ( ; next != _flexiBins.end(); prev = next++ ) {
+    acc += prev->_weightsum/_weightsum;
+    if ( acc > *citn ) {
+      cit0 = citn++;
+      continue;
+    }
+    if ( acc + next->_weightsum/_weightsum > *citn ) continue;
+    double dist = MDist::dist(prev->_cestLo, next->_cestHi,
+                              next->_weightsum + prev->_weightsum,
+                              *cit0, *citn, next->_n + prev->_n,
+                              next->_m + prev->_m);
+    if ( mindist < 0.0 || dist < mindist ) {
+      selectit = prev;
+      mindist = dist;
+    }
+  }
+
+  if ( selectit == _flexiBins.end() ) return _currenT;
+  auto mergeit = selectit++;
+  FlexiBin merged = *mergeit;
+  merged.merge(*selectit);
+  if ( merged.inRange(cest) || selectit->inRange(cest) )
+    _currenT = merged._t;
+  _flexiBins.erase(mergeit);
+  _flexiBins.erase(selectit);
+  _flexiBins.insert(merged);
+
+  return _currenT;
+
+}
+
+
+template <typename T, typename MDist>
+void CentralityBinner<T,MDist>::finalize() {
+
+  // Take the contents of the dynamical binning and fill the original
+  // AnalysisObjects.
+
+  double clo = 0.0;
+  for ( const FlexiBin & fb : _flexiBins ) {
+    double chi = min(clo + fb._weightsum/_weightsum, 1.0);
+    for ( Bin & bin : _unfilled ) {
+      double olo = bin._centLo;
+      double ohi = bin._centHi;
+      if ( clo > ohi || chi <= olo ) continue;
+      // If we only have partial overlap we need to scale
+      double lo = max(olo, clo);
+      double hi = min(ohi, chi);
+      T t = CentralityBinTraits<T>::clone(fb._t);
+      double frac = (hi - lo)/(chi - clo);
+      CentralityBinTraits<T>::scale(t, frac);
+      CentralityBinTraits<T>::add(bin._t, t);
+      bin._weightsum += fb._weightsum*frac;
+      if ( clo <= olo ) bin._cestLo = fb._cestLo +
+                          (fb._cestHi - fb._cestLo)*(olo - clo)/(chi - clo);
+      if ( clo < olo ) {
+        bin._underflow = clo;
+        bin._ambiguous += fb._n*frac;
+        bin._ambweight += fb._weightsum*frac*(1.0 - frac);
+      }
+      if ( chi > ohi ) {
+        bin._cestHi =
+          fb._cestLo + (fb._cestHi - fb._cestLo)*(ohi - clo)/(chi - clo);
+	bin._overflow = chi;
+        bin._ambiguous += fb._n*frac;
+        bin._ambweight += fb._weightsum*frac*(1.0 - frac);
+      }
+    }
+    clo = chi;
+  }
+  _flexiBins.clear();
+  for ( Bin & bin : _unfilled ) {
+    if ( bin._overflow == 0.0 ) bin._overflow = 1.0;
+    _ready[bin._t] = bin;
+    if ( bin._ambweight/bin._weightsum >_warnlimit )
+      MSG_WARNING("Analysis object \"" << CentralityBinTraits<T>::path(bin._t)
+                  << "\", contains events with centralities between "
+		  << bin._underflow*100.0
+		  << " and " << bin._overflow*100.0 << "% ("
+                  << int(bin._ambiguous + 0.5)
+                  << " ambiguous events with effectively "
+                  << 100.0*bin._ambweight/bin._weightsum
+                  << "% of the weights)."
+		  << "Consider increasing the number of bins.");
+
+  }
+  _unfilled.clear();
+
+}
+
+template <typename T, typename MDist>
+void CentralityBinner<T,MDist>::fulldebug() {
+  cerr <<  endl;
+  double acc = 0.0;
+  set<double>::iterator citn = _percentiles.begin();
+  set<double>::iterator cit0 = citn++;
+  int i = 0;
+  for ( auto it = _flexiBins.begin(); it != _flexiBins.end(); ) {
+    ++i;
+    auto curr = it++;
+    double w = curr->_weightsum/_weightsum;
+    acc += w;
+    if ( curr == _flexiBins.begin() || it == _flexiBins.end() || acc > *citn )
+      cerr << "*";
+    else
+      cerr << " ";
+    if ( acc > *citn ) cit0 = citn++;
+    cerr << setw(6) << i
+         << setw(12) << acc - w
+	 << setw(12) << acc
+	 << setw(8) << curr->_n
+	 << setw(8) << curr->_m
+	 << setw(12) << curr->_cestLo
+	 << setw(12) << curr->_cestHi << endl; 
+  }
+  cerr << "Number of sampler bins: " << _flexiBins.size() << endl;
+}
+
+template <typename T, typename MDist>
+void CentralityBinner<T,MDist>::debug() {
+  cerr <<  endl;
+  double acc = 0.0;
+  int i = 0;
+  set<double>::iterator citn = _percentiles.begin();
+  set<double>::iterator cit0 = citn++;
+  for ( auto it = _flexiBins.begin(); it != _flexiBins.end(); ) {
+    auto curr = it++;
+    ++i; 
+    double w = curr->_weightsum/_weightsum;
+    acc += w;
+    if ( curr == _flexiBins.begin() || it == _flexiBins.end() || acc > *citn ) {
+      if ( acc > *citn ) cit0 = citn++;
+      cerr << setw(6) << i
+           << setw(12) << acc - w
+	   << setw(12) << acc
+	   << setw(8) << curr->_n
+	   << setw(8) << curr->_m
+	   << setw(12) << curr->_cestLo
+	   << setw(12) << curr->_cestHi << endl;
+      
+    }
+  }
+  cerr << "Number of sampler bins: " << _flexiBins.size() << endl;
+}
+
+}
+
+#endif
diff --git a/include/Rivet/Tools/CentralityHistogram.hh b/include/Rivet/Tools/CentralityHistogram.hh
deleted file mode 100644
--- a/include/Rivet/Tools/CentralityHistogram.hh
+++ /dev/null
@@ -1,231 +0,0 @@
-// -*- C++ -*-
-#ifndef RIVET_CENTRALITYHISTOGRAM_HH
-#define RIVET_CENTRALITYHISTOGRAM_HH
-#include "Rivet/Config/RivetCommon.hh"
-#include "Rivet/Tools/RivetYODA.hh"
-#include "Rivet/Projections/CentralityEstimator.hh"
-namespace Rivet {
-
-class Analysis;
-
-
-/**
- * CentralityHistogram contains a series of histograms of the same
- * quantity each in a different percentiles of a second quantity.
- * For example, a CentralityHistogram may contain histograms of the
- * cross section differential in \f$ p_T \f$ in different centrality
- * regions for heavy ion collisions.
- **/
-class CentralityHistogram: public ProjectionApplier {
-  public:
-
-  /// Create a new empty CentralityHistogram. As an optional
-  /// argument a CentralityProjector may be supplied. This will then
-  /// be responsible for calculating a centrality estimate for each
-  /// event.
-  CentralityHistogram()
-    : _currentHist(Histo1DPtr()), _currentCEst(-1.0),
-      _overSamplingFactor(10), _weightsum(0.0) {
-    _percentiles.insert(0.0);
-    _percentiles.insert(1.0);
-  }
-
-  /// Set the centrality projection to be used. Note that this
-  /// projection must have already been declared to Rivet.
-  void setProjection(string pname) {
-    _estimator = pname;
-  }
-
-  /// Return the class name.
-  std::string name() const {
-    return "Rivet::CentralityHistogram";
-  }
-  
-
-  /// Add a histogram in the region between @a cmin and @a cmax to
-  /// this set of CentralityHistograms. The range represent
-  /// percentiles and must be between 0 and 100. No overlaping bins
-  /// are allowed.
-
-  /// Note that (cmin=0, cmax=5), means the five percent LEAST
-  /// central events.
-  void add(Histo1DPtr hist, double cmin, double cmax,
-           double cestmin = -1.0, double cestmax = -1.0 );
-
-  /// Setup the CentralityHistogram for the given event. Must be
-  /// called for every event before any fill. Optionally an explicit
-  /// value of the centrality estimator can be given, Otherwise a
-  /// CentralityEstimator must have been provided beforehand. 
-  void setup(const Event & ev, double cest = -1.0);
-
-  /// Fill the histogram that lies in the same region as @a bin with the value
-  /// @a x of weight @a weight.
-  void fill(double x, double weight = 1.0) {
-    if ( _currentHist ) _currentHist->fill(x, weight);
-    for ( auto h : _ready )
-      if ( h.second.inRange(_currentCEst) )
-        h.second._hist->fill(x, weight);
-  }
-
-  /// Fill histo bin i with the given weight
-  void fillBin(size_t i, double weight = 1.0) {
-    if ( _currentHist ) _currentHist->fill(i, weight);
-    for ( auto h : _ready )
-      if ( h.second.inRange(_currentCEst) )
-        h.second._hist->fill(i, weight);
-  }
-
-  /// At the end of the run, calculate the percentiles and fill the
-  /// histograms provided with addHistogram(). This is typically
-  /// called from the finalize method in a Analysis, but can also be
-  /// called earlier in which case the the fill function can be
-  /// continued to run as before.
-  void finalize();
-
-  /// Normalize each histogram to the sum of event weights in the
-  /// corresponding centrality bin.
-  void normalizePerEvent();
-
-  /// Return a map bin edges of the centrality extimator indexed by
-  /// the corresponing percentile.
-  map<double,double> edges() const;
-
-protected:
-
-  /// Create a copy of the first original histogram to be used in
-  /// the dynamical binning of centrality.
-  Histo1DPtr _newSamplerHist();
-
-  /// Take the sampler histogram which is furthest away from a
-  /// centrality limit and merging it into the closest one and clear
-  /// it and return it to be used for another dynamic bin.
-  Histo1DPtr _purgeSamplers();
-    
-
-private:
-
-  /// A flexible bin struct to be used to store temporary histograms.
-  struct FlexiBin {
-
-    /// Construct with an initial centrality estimate and an event
-    /// weight.
-    FlexiBin(Histo1DPtr hist, double cest = 0.0, double weight = 0.0)
-      : _hist(hist), _cestLo(cest), _cestHi(cest), _weightsum(weight) {}
-
-    /// Construct a temporary FlexiBin for finding a bin in a set.
-    FlexiBin(double cest)
-      : _cestLo(cest), _cestHi(cest), _weightsum(0.0) {}
-
-    /// Merge in the contents of another FlexiBin into this. 
-    void merge(const FlexiBin & fb) {
-      _cestLo = min(_cestLo, fb._cestLo);
-      _cestHi = max(_cestHi, fb._cestHi);
-      _weightsum += fb._weightsum;
-      *_hist += *fb._hist;
-    }
-
-    /// Comparisons for containers.
-    bool operator< (const FlexiBin & fb) const {
-      return ( _cestLo < fb._cestLo ||
-               ( _cestLo == fb._cestLo && _cestLo < fb._cestHi ) );
-    }
-
-    /// The associated histogram.
-    Histo1DPtr _hist;
-
-    /// Current lower and upper edge of the centrality estimator for
-    /// the fills in the associated histogram.
-    double _cestLo, _cestHi;
-
-    /// The sum of weights for all events entering the associated
-    /// histogram.
-    mutable double _weightsum;
-
-  };
-
-  struct HistBin {
-
-    /// Construct a completely empty bin.
-    HistBin()
-      : _centLo(-1.0), _centHi(-1.0),
-        _cestLo(-1.0), _cestHi(-1.0), _weightsum(0.0) {}
-
-    /// Constructor taking a histogram and centrality interval as
-    /// argument. Optionally the interval in the estimator can be
-    /// given, in which case this histogram is considered to be
-    /// "final".
-    HistBin(Histo1DPtr h, double centLo, double centHi,
-            double cestLo = -1.0, double cestHi = -1.0)
-      : _hist(h), _centLo(centLo), _centHi(centHi),
-        _cestLo(cestLo), _cestHi(cestHi), _weightsum(0.0) {}
-
-    /// Return true if the given centrality estimate is in the range
-    /// of this histogram.
-    bool inRange(double cest) const {
-      return _cestHi > 0 && _cestLo < cest && cest <= _cestHi;
-    }
-
-    /// Normalise the histogram to the tital cross section.
-    void normalizePerEvent() {
-      if ( _weightsum > 0.0 ) _hist->normalize(1.0/_weightsum);
-    }
-
-    /// The histogram.
-    Histo1DPtr _hist;
-
-    /// The range in centrality.
-    double _centLo, _centHi;
-
-    /// The corresponding range in the centrality estimator.
-    double _cestLo, _cestHi;
-
-    /// The sum of event weights for this bin;
-    double _weightsum;
-
-  };
-
-  /// Convenient typedefs.
-  typedef set<FlexiBin> FlexiBinSet;
-  
-  /// Find a bin corresponding to a given value of the centrality
-  /// estimator.
-  FlexiBinSet::iterator _findBin(double cest) const;
-
-  /// The name of the CentralityEstimator projection to be used.
-  string _estimator;
-
-  /// The current temporary histogram selected for the centrality
-  /// estimator calculated from the event presented in setup().
-  Histo1DPtr _currentHist;
-
-  /// THe current value of the centrality estimator.
-  double _currentCEst;
-
-  /// The oversampling of centrality bins. For each requested
-  /// centrality bin this number of dynamic bins will be used.
-  int _overSamplingFactor;
-
-  /// The unfilled histograms where the esimator edges has not yet
-  /// been determined.
-  vector<HistBin> _unfilled;
-
-  /// The dynamic bins for ranges of centrality estimators.
-  FlexiBinSet _flexiBins;
-
-  /// The sum of all event weights so far.
-  double _weightsum;
-
-  /// The sum of weights per original histogram.
-  map<Histo1DPtr, double> _histWeightSum;
-
-  /// Percentile limits.
-  set<double> _percentiles;
-
-  /// The filled histograms where the estimator edges has been determined.
-  map<Histo1DPtr, HistBin> _ready;
-
-};
-
-}
-
-#endif
diff --git a/src/Analyses/MC_CENTRALITY.cc b/src/Analyses/MC_CENTRALITY.cc
deleted file mode 100644
--- a/src/Analyses/MC_CENTRALITY.cc
+++ /dev/null
@@ -1,192 +0,0 @@
-// -*- C++ -*-
-#include "Rivet/Analysis.hh"
-#include "Rivet/Projections/FinalState.hh"
-#include "Rivet/Projections/ChargedFinalState.hh"
-#include "Rivet/Tools/CentralityHistogram.hh"
-
-namespace Rivet {
-
-/// Example of CentralityEstimator projection that uses summed Et in
-/// the forward region.
-class SumETFwdCentrality: public CentralityEstimator {
-
-public:
-
-  /// Constructor.
-  SumETFwdCentrality() {
-    declare(FinalState(3.2, 4.9, 100*MeV), "FSSumETFwdCentrality");
-  }
-
-protected:
-
-  /// Perform the projection on the Event
-  void project(const Event& e) {
-    const FinalState & fsfwd =
-      apply<FinalState>(e, "FSSumETFwdCentrality");
-    _estimate = 0.0;
-    for ( const Particle & p : fsfwd.particles() ) {
-      _estimate += p.Et();
-    }
-  }
-};
-    
-
-  /// Generic analysis looking at various distributions of final state particles
-  class MC_CENTRALITY : public Analysis {
-  public:
-
-    /// Constructor
-    MC_CENTRALITY() : Analysis("MC_CENTRALITY") {}
-
-
-  public:
-
-    /// @name Analysis methods
-    //@{
-
-    /// Book histograms and initialise projections before the run
-    void init() {
-
-      // Projections
-      declare(ChargedFinalState(-2.5, 2.5, 500*MeV), "CFScent");
-      declare(FinalState(3.2, 4.9, 100*MeV), "FSfwd");
-      
-
-      // Histograms
-      // The sum Et in the forward region.
-      _histETfwd  = bookHisto1D("ETfwd", 100, 0.0, 500.0);
-      
-      // The overall charged multiplicity distribution as a function
-      // of eta.
-      _histEtaAll = bookHisto1D("EtaAll", 50, -2.5, 2.5);
-
-      // Multiplicity distribution for different centrality intervals.
-      // The notation is that the maximum centrality is 100% and the
-      // lowest is 0%. THe _cent object will dynamically decide how to
-      // cluster fills to the histogram together.
-      _cent.add(_histEtaC95 = bookHisto1D("EtaC95", 50, -2.5, 2.5),
-                95.0, 100.0);
-      _cent.add(_histEtaC90 = bookHisto1D("EtaC90", 50, -2.5, 2.5),
-                90.0,  95.0);
-      _cent.add(_histEtaC80 = bookHisto1D("EtaC80", 50, -2.5, 2.5),
-                80.0,  90.0);
-      _cent.add(_histEtaC60 = bookHisto1D("EtaC60", 50, -2.5, 2.5),
-                60.0,  80.0);
-      _cent.add(_histEtaC00 = bookHisto1D("EtaC00", 50, -2.5, 2.5),
-                 0.0,  60.0);
-
-      // Try also the facility of using a CentralityEstimator
-      // projection.
-      declare(SumETFwdCentrality(), "SumETFwdCentrality");
-      _cent2.setProjection("SumETFwdCentrality");
-      _cent2.add(_histEta2C95 = bookHisto1D("Eta2C95", 50, -2.5, 2.5),
-                95.0, 100.0);
-      _cent2.add(_histEta2C90 = bookHisto1D("Eta2C90", 50, -2.5, 2.5),
-                90.0,  95.0);
-      _cent2.add(_histEta2C80 = bookHisto1D("Eta2C80", 50, -2.5, 2.5),
-                80.0,  90.0);
-      _cent2.add(_histEta2C60 = bookHisto1D("Eta2C60", 50, -2.5, 2.5),
-                60.0,  80.0);
-      _cent2.add(_histEta2C00 = bookHisto1D("Eta2C00", 50, -2.5, 2.5),
-                 0.0,  60.0);
-
-      /// Finally also try the case where we know the centrality bin
-      /// edges beforehand.
-      _cent3.setProjection("SumETFwdCentrality");
-      _cent3.add(_histEta3C95 = bookHisto1D("Eta3C95", 50, -2.5, 2.5),
-                 95.0, 100.0, 22.55, 1.0e20);
-      _cent3.add(_histEta3C90 = bookHisto1D("Eta3C90", 50, -2.5, 2.5),
-                 90.0,  95.0, 16.11, 22.55);
-      _cent3.add(_histEta3C80 = bookHisto1D("Eta3C80", 50, -2.5, 2.5),
-                 80.0,  90.0, 9.611, 16.11);
-      _cent3.add(_histEta3C60 = bookHisto1D("Eta3C60", 50, -2.5, 2.5),
-                 60.0,  80.0, 3.921, 9.611);
-      _cent3.add(_histEta3C00 = bookHisto1D("Eta3C00", 50, -2.5, 2.5),
-                 0.0,  60.0, 0.0, 3.921);
-
-
-
-    }
-
-    /// Perform the per-event analysis
-    void analyze(const Event& event) {
-      const double weight = event.weight();
-
-      // First calculate the centrality estimator. In this case the
-      // sumed transverse enegry in a forward region of the event, and
-      // initialize the centrality bin.
-      const FinalState & fsfwd = apply<FinalState>(event, "FSfwd");
-      double sumet = 0.0;
-      for ( const Particle & p : fsfwd.particles() ) {
-        sumet += p.Et();
-      }
-      _cent.setup(event, sumet);
-      _histETfwd->fill(sumet, weight);
-
-      // Also setup the other centrality binner.
-      _cent2.setup(event);
-
-      // Then fill the selected centrality histogram.
-      const ChargedFinalState & cfscent =
-        apply<ChargedFinalState>(event, "CFScent");
-      for ( const Particle & p : cfscent.particles() ) {
-        _cent.fill(p.eta(), weight);
-        _cent2.fill(p.eta(), weight);
-        _cent3.fill(p.eta(), weight);
-      }
-    }
-
-
-    /// Finalize
-    void finalize() {
-      normalize(_histETfwd, 1.0/sumOfWeights());
-      _cent.finalize();
-      _cent2.finalize();
-      _cent3.finalize(); // This should be a noop.
-      _cent.normalizePerEvent();
-      _cent2.normalizePerEvent();
-      _cent3.normalizePerEvent();
-      _histEtaAll->normalize(1.0/sumOfWeights());
-
-      map<double,double> edges1 = _cent.edges();
-      map<double,double> edges2 = _cent2.edges();
-      map<double,double> edges3 = _cent3.edges();
-      MSG_INFO("Cross check of centalty edges:"
-               << setw(10) << "%" << setw(10) << "1"
-               << setw(10) << "2" << setw(10) << "3");
-      for ( auto e : edges3 ) {
-        MSG_INFO(""
-                 << setw(10) << e.first << setw(10) << e.second << setw(10) 
-                 << edges1[e.first] << setw(10) << edges2[e.first]);
-      }
-      
-
-    }
-
-    //@}
-
-
-  private:
-
-    /// @name Histograms
-    //@{
-    Histo1DPtr _histETfwd;
-    Histo1DPtr _histEtaAll;
-    Histo1DPtr _histEtaC95, _histEtaC90, _histEtaC80, _histEtaC60, _histEtaC00;
-    CentralityHistogram _cent;
-    Histo1DPtr _histEta2C95, _histEta2C90, _histEta2C80,
-    _histEta2C60, _histEta2C00;
-    CentralityHistogram _cent2;
-    Histo1DPtr _histEta3C95, _histEta3C90, _histEta3C80,
-    _histEta3C60, _histEta3C00;
-    CentralityHistogram _cent3;
-    //@}
-
-
-  };
-
-
-  // The hook for the plugin system
-  DECLARE_RIVET_PLUGIN(MC_CENTRALITY);
-
-}
diff --git a/src/Analyses/MC_Centrality.cc b/src/Analyses/MC_Centrality.cc
new file mode 100644
--- /dev/null
+++ b/src/Analyses/MC_Centrality.cc
@@ -0,0 +1,198 @@
+// -*- C++ -*-
+#include "Rivet/Analysis.hh"
+#include "Rivet/Projections/FinalState.hh"
+#include "Rivet/Projections/ChargedFinalState.hh"
+#include "Rivet/Tools/CentralityBinner.hh"
+
+namespace Rivet {
+
+/// Example of CentralityEstimator projection that uses summed Et in
+/// the forward region.
+class SumETFwdCentrality: public CentralityEstimator {
+
+public:
+
+  /// Constructor.
+  SumETFwdCentrality() {
+    declare(FinalState(3.2, 4.9, 100*MeV), "FSSumETFwdCentrality");
+  }
+
+    /// Clone on the heap.
+    DEFAULT_RIVET_PROJ_CLONE(SumETFwdCentrality);
+
+protected:
+
+  /// Perform the projection on the Event
+  void project(const Event& e) {
+    const FinalState & fsfwd =
+      apply<FinalState>(e, "FSSumETFwdCentrality");
+    _estimate = 0.0;
+    for ( const Particle & p : fsfwd.particles() ) {
+      _estimate += p.Et();
+    }
+  }
+  
+  /// Compare projections
+  int compare(const Projection& p) const {
+    return mkNamedPCmp(p, "FSSumETFwdCentrality");
+  }
+
+};
+    
+
+  /// Generic analysis looking at various distributions of final state particles
+  class MC_Centrality : public Analysis {
+  public:
+
+    /// Constructor
+    MC_Centrality() : Analysis("MC_Centrality"), _cent(200, 0.02) {}
+
+
+  public:
+
+    /// @name Analysis methods
+    //@{
+
+    /// Book histograms and initialise projections before the run
+    void init() {
+
+      // Just testing
+      CentralityBinner< tuple<Histo1DPtr,Histo2DPtr,Profile1DPtr,Profile2DPtr> >
+        testbinner;
+
+      // Projections
+      declare(ChargedFinalState(-2.5, 2.5, 500*MeV), "CFScent");
+      declare(FinalState(3.2, 4.9, 100*MeV), "FSfwd");
+      
+
+      // Histograms
+      // The sum Et in the forward region.
+      _histETfwd  = bookHisto1D("ETfwd", 200, 0.0, 100.0);
+      
+      // The overall charged multiplicity distribution as a function
+      // of eta.
+      _histEtaAll = bookHisto1D("EtaAll", 50, -2.5, 2.5);
+
+      // Multiplicity distribution for different centrality intervals.
+      // The notation is that the maximum centrality is 100% and the
+      // lowest is 0%. The _cent1 object will dynamically decide how to
+      // cluster fills to the histogram together.
+      _histETfwdC95 = bookHisto1D("ETfwdC95", 200, 0.0, 100.0);
+      _histETfwdC90 = bookHisto1D("ETfwdC90", 200, 0.0, 100.0);
+      _histETfwdC80 = bookHisto1D("ETfwdC80", 200, 0.0, 100.0);
+      _histETfwdC60 = bookHisto1D("ETfwdC60", 200, 0.0, 100.0);
+      _histETfwdC00 = bookHisto1D("ETfwdC00", 200, 0.0, 100.0);
+      _histEtaC95 = bookHisto1D("EtaC95", 50, -2.5, 2.5);
+      _histEtaC90 = bookHisto1D("EtaC90", 50, -2.5, 2.5);
+      _histEtaC80 = bookHisto1D("EtaC80", 50, -2.5, 2.5);
+      _histEtaC60 = bookHisto1D("EtaC60", 50, -2.5, 2.5);
+      _histEtaC00 = bookHisto1D("EtaC00", 50, -2.5, 2.5);
+      _cent.add(make_tuple(_histETfwdC95, _histEtaC95), 95.0, 100.0);
+      _cent.add(make_tuple(_histETfwdC90, _histEtaC90), 90.0,  95.0);
+      _cent.add(make_tuple(_histETfwdC80, _histEtaC80), 80.0,  90.0);
+      _cent.add(make_tuple(_histETfwdC60, _histEtaC60), 60.0,  80.0);
+      _cent.add(make_tuple(_histETfwdC00, _histEtaC00),  0.0,  60.0);
+
+      _centrue.clear();
+
+    }
+
+    /// Perform the per-event analysis
+    void analyze(const Event& event) {
+      const double weight = event.weight();
+
+      // First calculate the centrality estimator. In this case the
+      // sumed transverse enegry in a forward region of the event, and
+      // initialize the centrality bin.
+      const FinalState & fsfwd = apply<FinalState>(event, "FSfwd");
+      double sumet = 0.0;
+      for ( const Particle & p : fsfwd.particles() ) {
+        sumet += p.Et();
+      }
+
+      _histETfwd->fill(sumet, weight);
+      _centrue.insert(make_pair(sumet, weight));
+
+
+      // Also setup other centrality binners.
+      auto ch = _cent.select(sumet, weight);
+      std::get<0>(ch)->fill(sumet, weight);
+
+     // Then fill the selected centrality histogram.
+      const ChargedFinalState & cfscent =
+        apply<ChargedFinalState>(event, "CFScent");
+      for ( const Particle & p : cfscent.particles() ) {
+        std::get<1>(ch)->fill(p.eta(), weight);
+	_histEtaAll->fill(p.eta(), weight);
+      }
+
+    }
+
+
+    /// Finalize
+    void finalize() {
+        
+      normalize(_histETfwd, _histETfwd->sumW()/sumOfWeights());
+      normalize(_histEtaAll, _histEtaAll->sumW()/sumOfWeights());
+
+      _cent.finalize();
+      _cent.normalizePerEvent();
+
+      map<double,double> edges = _cent.edges();
+      map<double,double> edges0 = edges;
+
+      auto curr = edges0.begin();
+      curr->second = 0.0;
+      ++curr;
+      pair<double,double> prev = *_centrue.begin();
+      double acc = 0.0;
+      for ( auto next: _centrue ) {
+	double del = next.second/sumOfWeights();
+	if ( acc + del > curr->first ) {
+	  curr->second = prev.first + (curr->first - acc)*(next.first - prev.first)/del;
+	  ++curr;
+	}
+	prev = next;
+	acc += del;
+      }
+
+
+      MSG_INFO("Cross check of centalty edges:\n");
+      MSG_INFO("" << setw(10) << "%" << setw(10) << "true"
+               << setw(10) << "estimate");
+      for ( auto e : edges0 ) {
+        MSG_INFO(""
+		 << setw(10) << e.first << setw(10) << e.second
+		 << setw(10) << edges[e.first]);
+      }
+      
+
+    }
+
+    //@}
+
+
+  private:
+
+    /// @name Histograms
+    //@{
+    Histo1DPtr _histETfwd;
+    Histo1DPtr _histEtaAll;
+    Histo1DPtr _histETfwdC95, _histETfwdC90, _histETfwdC80,
+      _histETfwdC60, _histETfwdC00;
+    Histo1DPtr _histEtaC95, _histEtaC90, _histEtaC80,
+      _histEtaC60, _histEtaC00;
+    CentralityBinner< tuple<Histo1DPtr,Histo1DPtr> > _cent;
+    //@}
+
+    /// Keep track of the actually generated centralities.
+    multimap<double, double> _centrue;
+
+
+  };
+
+
+  // The hook for the plugin system
+  DECLARE_RIVET_PLUGIN(MC_Centrality);
+
+}
diff --git a/src/Analyses/Makefile.am b/src/Analyses/Makefile.am
--- a/src/Analyses/Makefile.am
+++ b/src/Analyses/Makefile.am
@@ -1,624 +1,624 @@
 AUTOMAKE_OPTIONS = -Wno-portability
 
 ## Flags for building all plugins
 AM_LDFLAGS = $(LDFLAGS) -module -avoid-version -L$(FASTJETLIBPATH)
 LIBS = $(FASTJETCONFIGLIBADD)
 lib_LTLIBRARIES =
 
 BUILT_SOURCES =
 DISTCLEANFILES =
 
 EXTRA_DIST = cat_with_lines
 
 noinst_LTLIBRARIES = libRivetAnalysisTools.la
 libRivetAnalysisTools_la_SOURCES = \
     MC_ParticleAnalysis.cc \
     MC_JetAnalysis.cc \
     MC_JetSplittings.cc
 
 %__all.cc :
 	$(srcdir)/cat_with_lines $^ > $@
 
 if ENABLE_ANALYSES
 
 lib_LTLIBRARIES += RivetALICEAnalyses.la
 
 nodist_RivetALICEAnalyses_la_SOURCES = ALICE__all.cc
 BUILT_SOURCES += ALICE__all.cc
 DISTCLEANFILES += ALICE__all.cc
 
 ALICE__all.cc : $(ALICE_ALL)
 
 EXTRA_DIST += $(ALICE_ALL)
 
 ALICE_ALL = \
     ALICE_2010_S8624100.cc \
     ALICE_2010_S8625980.cc \
     ALICE_2010_S8706239.cc \
     ALICE_2011_S8909580.cc \
     ALICE_2011_S8945144.cc \
     ALICE_2012_I1116147.cc \
     ALICE_2012_I1181770.cc \
     ALICE_2014_I1300380.cc \
     ALICE_2015_I1357424.cc
 
 
 lib_LTLIBRARIES += RivetATLASAnalyses.la
 
 nodist_RivetATLASAnalyses_la_SOURCES = ATLAS_1__all.cc ATLAS_2__all.cc
 BUILT_SOURCES += ATLAS_1__all.cc ATLAS_2__all.cc
 DISTCLEANFILES += ATLAS_1__all.cc ATLAS_2__all.cc
 
 ATLAS_1__all.cc : $(ATLAS_ALL_1)
 ATLAS_2__all.cc : $(ATLAS_ALL_2)
 
 EXTRA_DIST += $(ATLAS_ALL_1) $(ATLAS_ALL_2)
 
 ATLAS_ALL_1 = \
     ATLAS_2010_S8591806.cc \
     ATLAS_2010_S8817804.cc \
     ATLAS_2010_S8894728.cc \
     ATLAS_2010_S8914702.cc \
     ATLAS_2010_S8918562.cc \
     ATLAS_2010_S8919674.cc \
     ATLAS_2011_S8924791.cc \
     ATLAS_2011_S8971293.cc \
     ATLAS_2011_S8994773.cc \
     ATLAS_2011_S8983313.cc \
     ATLAS_2011_S9002537.cc \
     ATLAS_2011_S9120807.cc \
     ATLAS_2011_S9126244.cc \
     ATLAS_2011_S9128077.cc \
     ATLAS_2011_S9131140.cc \
     ATLAS_2011_S9212183.cc \
     ATLAS_2011_S9225137.cc \
     ATLAS_2011_S9019561.cc \
     ATLAS_2011_I894867.cc \
     ATLAS_2011_I919017.cc \
     ATLAS_2011_I921594.cc \
     ATLAS_2011_I925932.cc \
     ATLAS_2011_I926145.cc \
     ATLAS_2011_I929691.cc \
     ATLAS_2011_I930220.cc \
     ATLAS_2011_I944826.cc \
     ATLAS_2011_I945498.cc \
     ATLAS_2011_I954993.cc \
     ATLAS_2011_I928289_W.cc \
     ATLAS_2011_I928289_Z.cc \
     ATLAS_2011_S9035664.cc \
     ATLAS_2012_I943401.cc \
     ATLAS_2012_I1082009.cc \
     ATLAS_2012_I1082936.cc \
     ATLAS_2012_I1083318.cc \
     ATLAS_2012_I1084540.cc \
     ATLAS_2012_I1091481.cc \
     ATLAS_2012_I1093734.cc \
     ATLAS_2012_I1093738.cc \
     ATLAS_2012_I1094564.cc \
     ATLAS_2012_I1094568.cc \
     ATLAS_2012_I1112263.cc \
     ATLAS_2012_I1117704.cc \
     ATLAS_2012_I1118269.cc \
     ATLAS_2012_I1119557.cc \
     ATLAS_2012_I1124167.cc \
     ATLAS_2012_I1125575.cc \
     ATLAS_2012_I1125961.cc \
     ATLAS_2012_I1183818.cc \
     ATLAS_2012_I1188891.cc \
     ATLAS_2012_I1199269.cc \
     ATLAS_2012_I1203852.cc \
     ATLAS_2012_I1204447.cc \
     ATLAS_2012_I1204784.cc \
     ATLAS_2013_I1190187.cc \
     ATLAS_2013_I1217867.cc \
     ATLAS_2013_I1219109.cc \
     ATLAS_2013_I1230812.cc \
     ATLAS_2013_I1243871.cc \
     ATLAS_2013_I1263495.cc \
     ATLAS_2014_I1268975.cc \
     ATLAS_2014_I1279489.cc \
     ATLAS_2014_I1282441.cc \
     ATLAS_2014_I1298811.cc \
     ATLAS_2014_I1304688.cc \
     ATLAS_2014_I1307756.cc \
     ATLAS_2014_I1306294.cc \
     ATLAS_2014_I1315949.cc \
     ATLAS_2014_I1325553.cc \
     ATLAS_2014_I1300647.cc \
     ATLAS_2014_I1288706.cc \
     ATLAS_2014_I1307243.cc \
     ATLAS_2014_I1312627.cc
 
 ATLAS_ALL_2 = \
     ATLAS_2013_I1217863_W.cc \
     ATLAS_2013_I1217863_Z.cc \
     ATLAS_2014_I1306615.cc \
     ATLAS_2013_I1216670.cc \
     ATLAS_2013_I1244522.cc \
     ATLAS_2014_I1282447.cc \
     ATLAS_2014_I1298023.cc \
     ATLAS_2014_I1319490.cc \
     ATLAS_2014_I1326641.cc \
     ATLAS_2014_I1327229.cc \
     ATLAS_2015_I1345452.cc \
     ATLAS_2015_I1351916.cc \
     ATLAS_2015_I1364361.cc \
     ATLAS_2015_I1376945.cc \
     ATLAS_2015_I1387176.cc \
     ATLAS_2015_I1390114.cc \
     ATLAS_2015_I1393758.cc \
     ATLAS_2015_I1394679.cc \
     ATLAS_2015_I1397635.cc \
     ATLAS_2015_I1397637.cc \
     ATLAS_2015_I1404878.cc \
     ATLAS_2015_I1408516.cc \
     ATLAS_2016_I1419070.cc \
     ATLAS_2016_I1419652.cc \
     ATLAS_2016_I1424838.cc \
     ATLAS_2016_I1426695.cc \
     ATLAS_2016_I1444991.cc \
     ATLAS_2016_I1452559.cc \
     ATLAS_2016_I1457605.cc \
     ATLAS_2016_I1458270.cc \
     ATLAS_2016_I1468168.cc \
     ATLAS_2016_I1467230.cc \
     ATLAS_2016_I1467454.cc \
     ATLAS_2016_I1468167.cc \
     ATLAS_2016_I1479760.cc
 
 # PRELIMINARY / OBSOLETE
 ATLAS_ALL_2 += \
     ATLAS_2012_CONF_2012_001.cc \
     ATLAS_2010_CONF_2010_049.cc \
     ATLAS_2011_CONF_2011_090.cc \
     ATLAS_2011_CONF_2011_098.cc \
     ATLAS_2012_CONF_2012_103.cc \
     ATLAS_2012_CONF_2012_104.cc \
     ATLAS_2012_CONF_2012_105.cc \
     ATLAS_2012_CONF_2012_109.cc \
     ATLAS_2012_CONF_2012_153.cc \
     ATLAS_2015_CONF_2015_041.cc \
     ATLAS_2016_CONF_2016_037.cc \
     ATLAS_2016_CONF_2016_054.cc \
     ATLAS_2016_CONF_2016_078.cc \
     ATLAS_2016_CONF_2016_094.cc \
     ATLAS_2011_S9041966.cc \
     ATLAS_2011_S9212353.cc \
     ATLAS_2012_I946427.cc
 # UNVALIDATED
 ATLAS_ALL_2 += \
     ATLAS_2011_S9108483.cc \
     ATLAS_2012_I1095236.cc \
     ATLAS_2012_I1126136.cc \
     ATLAS_2012_I1180197.cc \
     ATLAS_2012_I1186556.cc \
     ATLAS_2012_I1190891.cc
 
 
 lib_LTLIBRARIES += RivetCMSAnalyses.la
 
 nodist_RivetCMSAnalyses_la_SOURCES = CMS__all.cc
 BUILT_SOURCES += CMS__all.cc
 DISTCLEANFILES += CMS__all.cc
 
 CMS__all.cc : $(CMS_ALL)
 
 EXTRA_DIST += $(CMS_ALL)
 
 
 
 CMS_ALL = \
     CMS_2010_S8547297.cc \
     CMS_2010_S8656010.cc \
     CMS_2011_S8884919.cc \
     CMS_2011_S8941262.cc \
     CMS_2011_S8950903.cc \
     CMS_2011_S8957746.cc \
     CMS_2011_S8968497.cc \
     CMS_2011_S8973270.cc \
     CMS_2011_S8978280.cc \
     CMS_2011_S9086218.cc \
     CMS_2011_S9088458.cc \
     CMS_2011_S9120041.cc \
     CMS_2011_S9215166.cc \
     CMS_2012_I941555.cc  \
     CMS_2011_I954992.cc  \
     CMS_2012_I1087342.cc \
     CMS_2012_I1090423.cc \
     CMS_2012_I1102908.cc \
     CMS_2012_I1107658.cc \
     CMS_2012_I1184941.cc \
     CMS_2012_I1193338.cc \
     CMS_2013_I1122847.cc \
     CMS_2013_I1208923.cc \
     CMS_2013_I1209721.cc \
     CMS_2013_I1218372.cc \
     CMS_2013_I1223519.cc \
     CMS_2013_I1224539_DIJET.cc \
     CMS_2013_I1224539_WJET.cc \
     CMS_2013_I1224539_ZJET.cc \
     CMS_2013_I1256943.cc \
     CMS_2013_I1258128.cc \
     CMS_2013_I1261026.cc \
     CMS_2013_I1265659.cc \
     CMS_2013_I1272853.cc \
     CMS_2013_I1273574.cc \
     CMS_2012_I1298807.cc \
     CMS_2014_I1298810.cc \
     CMS_2014_I1303894.cc \
     CMS_2014_I1305624.cc \
     CMS_2015_I1310737.cc \
     CMS_2015_I1327224.cc \
     CMS_2015_I1346843.cc \
     CMS_2015_I1356998.cc \
     CMS_2015_I1370682.cc \
     CMS_2015_I1384119.cc \
     CMS_2015_I1385107.cc \
     CMS_2015_I1397174.cc \
     CMS_2016_I1459051.cc \
     CMS_2016_I1473674.cc \
     CMSTOTEM_2014_I1294140.cc \
     TOTEM_2014_I1328627.cc
 # PRELIMINARY
 CMS_ALL += \
     CMS_2010_PAS_QCD_10_024.cc \
     CMS_2012_PAS_QCD_11_010.cc \
     CMS_2012_PAS_FSQ_12_020.cc \
     CMS_2016_PAS_SUS_16_14.cc
 
 
 lib_LTLIBRARIES += RivetLHCbAnalyses.la
 
 nodist_RivetLHCbAnalyses_la_SOURCES = LHCb__all.cc
 BUILT_SOURCES += LHCb__all.cc
 DISTCLEANFILES += LHCb__all.cc
 
 LHCb__all.cc : $(LHCb_ALL)
 
 EXTRA_DIST += $(LHCb_ALL)
 
 LHCb_ALL = \
     LHCB_2010_I867355.cc \
     LHCB_2010_S8758301.cc \
     LHCB_2011_I917009.cc \
     LHCB_2011_I919315.cc \
     LHCB_2012_I1119400.cc \
     LHCB_2012_I1208102.cc \
     LHCB_2013_I1218996.cc \
     LHCB_2013_I1208105.cc \
     LHCB_2014_I1262703.cc \
     LHCB_2014_I1281685.cc \
     LHCB_2015_I1333223.cc
 
 
 lib_LTLIBRARIES += RivetLHCfAnalyses.la
 RivetLHCfAnalyses_la_SOURCES = \
     LHCF_2012_I1115479.cc
 
 
 lib_LTLIBRARIES += RivetTOTEMAnalyses.la
 RivetTOTEMAnalyses_la_SOURCES = \
     TOTEM_2012_I1115294.cc \
     TOTEM_2012_I1220862.cc
 
 
 lib_LTLIBRARIES += RivetCDFAnalyses.la
 
 nodist_RivetCDFAnalyses_la_SOURCES = CDF__all.cc
 BUILT_SOURCES += CDF__all.cc
 DISTCLEANFILES += CDF__all.cc
 
 CDF__all.cc : $(CDF_ALL)
 
 EXTRA_DIST += $(CDF_ALL)
 
 
 
 CDF_ALL = \
     CDF_1988_S1865951.cc \
     CDF_1990_S2089246.cc \
     CDF_1994_S2952106.cc \
     CDF_1996_S3418421.cc \
     CDF_1998_S3618439.cc \
     CDF_2000_S4155203.cc \
     CDF_2000_S4266730.cc \
     CDF_2001_S4517016.cc \
     CDF_2001_S4751469.cc \
     CDF_2002_S4796047.cc \
     CDF_2004_S5839831.cc \
     CDF_2005_S6080774.cc \
     CDF_2005_S6217184.cc \
     CDF_2006_S6450792.cc \
     CDF_2006_S6653332.cc \
     CDF_2007_S7057202.cc \
     CDF_2008_S7540469.cc \
     CDF_2008_S7541902.cc \
     CDF_2008_S7782535.cc \
     CDF_2008_S7828950.cc \
     CDF_2008_S8093652.cc \
     CDF_2008_S8095620.cc \
     CDF_2009_S8233977.cc \
     CDF_2009_I856131.cc \
     CDF_2009_S8436959.cc \
     CDF_2010_S8591881_DY.cc \
     CDF_2010_S8591881_QCD.cc \
     CDF_2012_I1124333.cc \
     CDF_2015_1388868.cc
 # PRELIMINARY
 CDF_ALL += \
     CDF_2009_NOTE_9936.cc \
     CDF_2012_NOTE10874.cc
 # UNVALIDATED
 CDF_ALL += \
     CDF_1993_S2742446.cc \
     CDF_1996_S3108457.cc \
     CDF_1996_S3349578.cc \
     CDF_1997_S3541940.cc \
     CDF_2001_S4563131.cc
 
 
 lib_LTLIBRARIES += RivetD0Analyses.la
 
 nodist_RivetD0Analyses_la_SOURCES = D0__all.cc
 BUILT_SOURCES += D0__all.cc
 DISTCLEANFILES += D0__all.cc
 
 D0__all.cc : $(D0_ALL)
 
 EXTRA_DIST += $(D0_ALL)
 
 
 
 D0_ALL = \
     D0_1995_I398175.cc \
     D0_2000_I499943.cc \
     D0_2000_S4480767.cc \
     D0_2001_S4674421.cc \
     D0_2004_S5992206.cc \
     D0_2006_S6438750.cc \
     D0_2007_S7075677.cc \
     D0_2008_S6879055.cc \
     D0_2008_S7554427.cc \
     D0_2008_S7662670.cc \
     D0_2008_S7719523.cc \
     D0_2008_S7837160.cc \
     D0_2008_S7863608.cc \
     D0_2009_S8202443.cc \
     D0_2009_S8320160.cc \
     D0_2009_S8349509.cc \
     D0_2010_S8566488.cc \
     D0_2010_S8570965.cc \
     D0_2010_S8671338.cc \
     D0_2010_S8821313.cc \
     D0_2011_I895662.cc \
     D0_2015_I1324946.cc \
     D0_2000_I503361.cc
 # UNVALIDATED
 D0_ALL += \
     D0_1996_S3214044.cc \
     D0_1996_S3324664.cc
 
 
 lib_LTLIBRARIES += RivetHERAAnalyses.la
 
 nodist_RivetHERAAnalyses_la_SOURCES = HERA__all.cc
 BUILT_SOURCES += HERA__all.cc
 DISTCLEANFILES += HERA__all.cc
 
 HERA__all.cc : $(HERA_ALL)
 
 EXTRA_DIST += $(HERA_ALL)
 
 
 
 HERA_ALL = \
     H1_1994_S2919893.cc \
     H1_2000_S4129130.cc
 # UNVALIDATED
 HERA_ALL += \
     H1_1995_S3167097.cc \
     ZEUS_2001_S4815815.cc
 
 
 lib_LTLIBRARIES += RivetPetraAnalyses.la
 RivetPetraAnalyses_la_SOURCES = \
     JADE_1998_S3612880.cc \
     TASSO_1990_S2148048.cc
 
 lib_LTLIBRARIES += RivetLEPAnalyses.la
 
 nodist_RivetLEPAnalyses_la_SOURCES = LEP__all.cc
 BUILT_SOURCES += LEP__all.cc
 DISTCLEANFILES += LEP__all.cc
 
 LEP__all.cc : $(LEP_ALL)
 
 EXTRA_DIST += $(LEP_ALL)
 
 
 
 LEP_ALL = \
     ALEPH_1991_S2435284.cc \
     ALEPH_1995_I382179.cc \
     ALEPH_1996_S3486095.cc \
     ALEPH_1996_S3196992.cc \
     ALEPH_1999_S4193598.cc \
     ALEPH_2001_S4656318.cc \
     ALEPH_2002_S4823664.cc \
     ALEPH_2004_S5765862.cc \
     DELPHI_1995_S3137023.cc \
     DELPHI_1996_S3430090.cc \
     DELPHI_1999_S3960137.cc \
     DELPHI_2000_S4328825.cc \
     DELPHI_2011_I890503.cc \
     L3_1992_I336180.cc \
     L3_2004_I652683.cc \
     OPAL_1993_I342766.cc \
     OPAL_1994_S2927284.cc \
     OPAL_1995_S3198391.cc \
     OPAL_1996_S3257789.cc \
     OPAL_1997_S3396100.cc \
     OPAL_1997_S3608263.cc \
     OPAL_1998_S3702294.cc \
     OPAL_1998_S3749908.cc \
     OPAL_1998_S3780481.cc \
     OPAL_2000_S4418603.cc \
     OPAL_2001_S4553896.cc \
     OPAL_2002_S5361494.cc \
     OPAL_2003_I599181.cc \
     OPAL_2004_S6132243.cc \
     SLD_1996_S3398250.cc \
     SLD_1999_S3743934.cc \
     SLD_2002_S4869273.cc \
     SLD_2004_S5693039.cc
 # UNVALIDATED
 LEP_ALL += \
     OPAL_1993_S2692198.cc
 # OBSOLETE
 LEP_ALL += \
     DELPHI_2002_069_CONF_603.cc
 
 
 lib_LTLIBRARIES += RivetRHICAnalyses.la
 
 nodist_RivetRHICAnalyses_la_SOURCES = RHIC__all.cc
 BUILT_SOURCES += RHIC__all.cc
 DISTCLEANFILES += RHIC__all.cc
 
 RHIC__all.cc : $(RHIC_ALL)
 
 EXTRA_DIST += $(RHIC_ALL)
 
 
 
 RHIC_ALL = \
     STAR_2006_S6500200.cc \
     STAR_2006_S6860818.cc \
     STAR_2006_S6870392.cc
 # PRELIMINARY
 RHIC_ALL += \
     STAR_2009_UE_HELEN.cc
 # UNVALIDATED
 RHIC_ALL += \
     STAR_2008_S7869363.cc \
     STAR_2008_S7993412.cc
 
 
 lib_LTLIBRARIES += RivetSPSAnalyses.la
 
 nodist_RivetSPSAnalyses_la_SOURCES = SPS__all.cc
 BUILT_SOURCES += SPS__all.cc
 DISTCLEANFILES += SPS__all.cc
 
 SPS__all.cc : $(SPS_ALL)
 
 EXTRA_DIST += $(SPS_ALL)
 
 
 
 SPS_ALL = \
     UA1_1990_S2044935.cc \
     UA5_1982_S875503.cc \
     UA5_1986_S1583476.cc \
     UA5_1987_S1640666.cc \
     UA5_1988_S1867512.cc \
     UA5_1989_S1926373.cc
 
 
 lib_LTLIBRARIES += RivetMiscAnalyses.la
 
 nodist_RivetMiscAnalyses_la_SOURCES = Misc__all.cc
 BUILT_SOURCES += Misc__all.cc
 DISTCLEANFILES += Misc__all.cc
 
 Misc__all.cc : $(Misc_ALL)
 
 EXTRA_DIST += $(Misc_ALL)
 
 
 
 Misc_ALL = \
     E735_1998_S3905616.cc \
     PDG_HADRON_MULTIPLICITIES.cc \
     PDG_HADRON_MULTIPLICITIES_RATIOS.cc \
     PDG_TAUS.cc \
     JADE_OPAL_2000_S4300807.cc \
     ARGUS_1993_S2653028.cc \
     ARGUS_1993_S2669951.cc \
     ARGUS_1993_S2789213.cc \
     BABAR_2003_I593379.cc \
     BABAR_2005_S6181155.cc \
     BABAR_2007_S6895344.cc \
     BABAR_2007_S7266081.cc \
     BABAR_2013_I1116411.cc \
     BABAR_2013_I1238276.cc \
     BABAR_2015_I1334693.cc \
     BELLE_2001_S4598261.cc \
     BELLE_2008_I786560.cc \
     BELLE_2011_I878990.cc \
     BELLE_2013_I1216515.cc \
     BELLE_2013_I1238273.cc \
     BELLE_2015_I1397632.cc \
     CLEO_2004_S5809304.cc
 # UNVALIDATED
 Misc_ALL += \
     SFM_1984_S1178091.cc
 
 
 lib_LTLIBRARIES += RivetMCAnalyses.la
 
 nodist_RivetMCAnalyses_la_SOURCES = MC__all.cc
 BUILT_SOURCES += MC__all.cc
 DISTCLEANFILES += MC__all.cc
 
 MC__all.cc : $(MC_ALL)
 
 EXTRA_DIST += $(MC_ALL)
 
 
 
 MC_ALL = \
     EXAMPLE.cc \
     EXAMPLE_CUTS.cc \
     EXAMPLE_SMEAR.cc \
     MC_QCD_PARTONS.cc \
-    MC_CENTRALITY.cc \
+    MC_Centrality.cc \
     MC_DIPHOTON.cc \
     MC_ELECTRONS.cc \
     MC_GENERIC.cc \
     MC_HINC.cc \
     MC_HJETS.cc \
     MC_HHJETS.cc \
     MC_HKTSPLITTINGS.cc \
     MC_IDENTIFIED.cc \
     MC_JETS.cc \
     MC_JETTAGS.cc \
     MC_HFJETS.cc \
     MC_LEADJETUE.cc \
     MC_MET.cc \
     MC_MUONS.cc \
     MC_PDFS.cc \
     MC_PHOTONINC.cc \
     MC_PHOTONJETS.cc \
     MC_PHOTONKTSPLITTINGS.cc \
     MC_PHOTONS.cc \
     MC_PRINTEVENT.cc \
     MC_SUSY.cc \
     MC_TTBAR.cc \
     MC_VH2BB.cc \
     MC_WINC.cc \
     MC_WJETS.cc \
     MC_WKTSPLITTINGS.cc \
     MC_WPOL.cc \
     MC_WWINC.cc \
     MC_WWJETS.cc \
     MC_WWKTSPLITTINGS.cc \
     MC_XS.cc \
     MC_ZINC.cc \
     MC_ZJETS.cc \
     MC_ZKTSPLITTINGS.cc \
     MC_ZZINC.cc \
     MC_ZZJETS.cc \
     MC_ZZKTSPLITTINGS.cc
 
 endif
diff --git a/src/Tools/CentralityHistogram.cc b/src/Tools/CentralityHistogram.cc
deleted file mode 100644
--- a/src/Tools/CentralityHistogram.cc
+++ /dev/null
@@ -1,173 +0,0 @@
-// -*- C++ -*-
-#include "Rivet/Tools/CentralityHistogram.hh"
-#include "Rivet/Tools/RivetYODA.hh"
-#include "Rivet/Analysis.hh"
-
-namespace Rivet {
-
-void CentralityHistogram::add(Histo1DPtr hist, double cmin, double cmax,
-                              double cestmin, double cestmax) {
-  if ( cestmax < 0.0 )
-    _unfilled.push_back(HistBin(hist, cmin/100.0, cmax/100.0));
-  else 
-    _ready[hist] = HistBin(hist, cmin/100.0, cmax/100.0, cestmin, cestmax);
-  _percentiles.insert(cmin/100.0);
-  _percentiles.insert(cmax/100.0);
-}
-
-
-CentralityHistogram::FlexiBinSet::iterator
-CentralityHistogram::_findBin(double cest) const {
-  FlexiBinSet::iterator it = _flexiBins.upper_bound(FlexiBin(cest));
-  if ( it != _flexiBins.end() && it != _flexiBins.begin() ) {
-    --it;
-    if ( it->_cestLo == cest ||
-         ( it->_cestLo < cest && cest < it->_cestHi ) )
-      return it;
-  }
-  return _flexiBins.end();
-}
-
-void CentralityHistogram::setup(const Event & ev, double centin) {
-
-  // Get the estimator value from the associated projection.
-  _currentCEst = centin >= 0.0? centin:
-    applyProjection<CentralityEstimator>(ev, _estimator).estimate();
-  _weightsum += ev.weight();
-  for ( auto h : _ready )
-    if ( h.second.inRange(_currentCEst) )
-      h.second._weightsum += ev.weight();
-
-  // If estimator is negative, something has gone wrong.
-  if ( _currentCEst < 0.0 ) {
-    _currentHist = Histo1DPtr();
-    return;
-  }
-
-  // If the current value of the centrality estimator is already in
-  // use, just return the corresponding histogram.
-  FlexiBinSet::iterator sit = _findBin(_currentCEst);
-  if ( sit != _flexiBins.end() ) {
-    sit->_weightsum += ev.weight();
-    return;
-  }
-
-  if ( _flexiBins.size() >= _unfilled.size()*_overSamplingFactor )
-    _currentHist = _purgeSamplers(); // Purge the histogram furthest
-                                     // away from a centrality limit.
-  else
-    _currentHist = _newSamplerHist(); // Create a new sampler
-                                      // histogram
-
-  _flexiBins.insert(FlexiBin(_currentHist, _currentCEst, ev.weight()));
-
-}
-
-Histo1DPtr CentralityHistogram::_newSamplerHist() {
-  // This is an error;
-  if ( _unfilled.empty() ) return Histo1DPtr();
-
-  Histo1DPtr hist(_unfilled.begin()->_hist->newclone());
-  hist->reset();
-  return hist;
-
-}
-
-Histo1DPtr CentralityHistogram::_purgeSamplers() {
-
-  set<double>::iterator citn = _percentiles.begin();
-  set<double>::iterator cit0 = citn++;
-
-  FlexiBinSet::iterator selectit = _flexiBins.begin();
-  int selectdist = 0;
-  int counter = 0;
-
-  FlexiBinSet::iterator midit = selectit;
-  int idist = 0;
-  double totweight = _weightsum;
-  double accweight = 0.0;
-  
-  for ( auto curr = _flexiBins.begin(); curr != _flexiBins.end(); ++curr ) {
-    accweight += curr->_weightsum;
-    if ( accweight > (*citn)*totweight ) {
-      if ( idist > selectdist ) {
-        selectdist = idist;
-        selectit = midit;
-      }
-      idist = 0;
-      midit = curr;
-      cit0 = citn++;
-      counter = 0;
-    } else {
-       ++counter;
-      // Note that for the first centrality bin we always merge the
-      // bin closest to 0, and for the last bin always the one closest
-      // to 100%, for all the rest we choose the middle bin.
-      if ( *cit0 == 0.0 || *citn == 1.0 || counter%2 ) ++idist;
-      if ( *citn == 1.0 || counter%2 ) ++midit;
-    }
-  }
-
-  FlexiBinSet::iterator mergeit = selectit;
-  if ( selectit == _flexiBins.begin() ) ++selectit;
-  else --mergeit;
-
-  FlexiBin merged = *mergeit;
-  FlexiBin selected = *selectit;
-  merged.merge(*selectit);
-  _flexiBins.erase(mergeit);
-  _flexiBins.erase(selectit);
-  _flexiBins.insert(merged);
-
-  return selected._hist;
-  
-}
-
-void CentralityHistogram::finalize() {
-
-  // Take the contents of the dynamical binning and fill the original
-  // histograms.
-
-  double clo = 0.0;
-  for ( const FlexiBin & fb : _flexiBins ) {
-    double chi = clo + fb._weightsum/_weightsum;
-    for ( HistBin & hbin : _unfilled ) {
-      double olo = hbin._centLo;
-      double ohi = hbin._centHi;
-      if ( clo > ohi || chi <= olo ) continue;
-      // If we only have partial overlap we need to scale
-      double lo = max(olo, clo);
-      double hi = min(ohi, chi);
-      Histo1D h = fb._hist->clone();
-      h.scaleW((hi - lo)/(chi - clo));
-      *(hbin._hist) += h;
-      hbin._weightsum += fb._weightsum*(hi - lo)/(chi - clo);
-      if ( clo <= olo )
-        hbin._cestLo =
-          fb._cestLo + (fb._cestHi - fb._cestHi)*(olo - clo)/(chi - clo);
-      if ( chi > ohi )
-        hbin._cestHi =
-          fb._cestLo + (fb._cestHi - fb._cestHi)*(ohi - clo)/(chi - clo);
-    }
-  }
-  _flexiBins.clear();
-  for ( HistBin & hbin : _unfilled ) _ready[hbin._hist] = hbin;
-  _unfilled.clear();
-
-}
-
-void CentralityHistogram::normalizePerEvent() {
-  for ( auto h : _ready ) h.second.normalizePerEvent();
-}
-
-map<double,double> CentralityHistogram::edges() const {
-  map<double,double> ret;
-  for ( auto hbin : _ready ) {
-    ret[hbin.second._centLo] = hbin.second._cestLo;
-    ret[hbin.second._centHi] = hbin.second._cestHi;
-  }
-  return ret;
-}
-
-
-}
diff --git a/src/Tools/Makefile.am b/src/Tools/Makefile.am
--- a/src/Tools/Makefile.am
+++ b/src/Tools/Makefile.am
@@ -1,20 +1,19 @@
 noinst_LTLIBRARIES = libRivetTools.la
 
 libRivetTools_la_SOURCES = \
   BinnedHistogram.cc \
-  CentralityHistogram.cc \
   Cuts.cc \
   JetUtils.cc \
   Logging.cc \
   ParticleUtils.cc \
   ParticleName.cc \
   RivetYODA.cc \
   RivetMT2.cc \
   RivetPaths.cc \
   Utils.cc \
   binreloc.c \
   mt2_bisect.cc
 
 dist_noinst_HEADERS = binreloc.h mt2_bisect.hh
 
 libRivetTools_la_CPPFLAGS = $(AM_CPPFLAGS) -DENABLE_BINRELOC -DDEFAULTDATADIR=\"$(datadir)\" -DDEFAULTLIBDIR=\"$(libdir)\"