XML Import/Export#
[1]:
# NB: python -m pip install pyhf[xmlio]
import pyhf
[2]:
!ls -lavh ../../../validation/xmlimport_input
total 1752
drwxr-xr-x 7 kratsg staff 238B Oct 16 22:20 .
drwxr-xr-x 21 kratsg staff 714B Apr 4 14:26 ..
drwxr-xr-x 6 kratsg staff 204B Feb 27 17:13 config
drwxr-xr-x 7 kratsg staff 238B Feb 27 23:41 data
-rw-r--r-- 1 kratsg staff 850K Oct 16 22:20 log
drwxr-xr-x 17 kratsg staff 578B Nov 15 12:24 results
-rw-r--r-- 1 kratsg staff 21K Oct 16 22:20 scan.pdf
Importing#
In order to convert HistFactory XML+ROOT to the pyhf JSON spec for likelihoods, you need to point the command-line interface pyhf xml2json
at the top-level XML file. Additionally, as the HistFactory XML specification often uses relative paths, you might need to specify the base directory --basedir
from which all other files are located, as specified in the top-level XML. The command will be of the format
pyhf xml2json {top-level XML} --basedir {base directory}
This will print the JSON representation of the XML+ROOT specified. If you wish to store this as a JSON file, you simply need to redirect it
pyhf xml2json {top-level XML} --basedir {base directory} > spec.json
[3]:
!pyhf xml2json --hide-progress ../../../validation/xmlimport_input/config/example.xml --basedir ../../../validation/xmlimport_input | tee xml_importexport.json
{
"channels": [
{
"name": "channel1",
"samples": [
{
"data": [
20.0,
10.0
],
"modifiers": [
{
"data": {
"hi": 1.05,
"lo": 0.95
},
"name": "syst1",
"type": "normsys"
},
{
"data": null,
"name": "SigXsecOverSM",
"type": "normfactor"
}
],
"name": "signal"
},
{
"data": [
100.0,
0.0
],
"modifiers": [
{
"data": null,
"name": "lumi",
"type": "lumi"
},
{
"data": [
5.000000074505806,
0.0
],
"name": "staterror_channel1",
"type": "staterror"
},
{
"data": {
"hi": 1.05,
"lo": 0.95
},
"name": "syst2",
"type": "normsys"
}
],
"name": "background1"
},
{
"data": [
0.0,
100.0
],
"modifiers": [
{
"data": null,
"name": "lumi",
"type": "lumi"
},
{
"data": [
0.0,
10.0
],
"name": "staterror_channel1",
"type": "staterror"
},
{
"data": {
"hi": 1.05,
"lo": 0.95
},
"name": "syst3",
"type": "normsys"
}
],
"name": "background2"
}
]
}
],
"data": {
"channel1": [
122.0,
112.0
]
},
"toplvl": {
"measurements": [
{
"config": {
"parameters": [
{
"auxdata": [
1.0
],
"bounds": [
[
0.5,
1.5
]
],
"fixed": true,
"inits": [
1.0
],
"name": "lumi",
"sigmas": [
0.1
]
},
{
"fixed": true,
"name": "alpha_syst1"
}
],
"poi": "SigXsecOverSM"
},
"name": "GaussExample"
},
{
"config": {
"parameters": [
{
"auxdata": [
1.0
],
"bounds": [
[
0.5,
1.5
]
],
"fixed": true,
"inits": [
1.0
],
"name": "lumi",
"sigmas": [
0.1
]
},
{
"fixed": true,
"name": "alpha_syst1"
}
],
"poi": "SigXsecOverSM"
},
"name": "GammaExample"
},
{
"config": {
"parameters": [
{
"auxdata": [
1.0
],
"bounds": [
[
0.5,
1.5
]
],
"fixed": true,
"inits": [
1.0
],
"name": "lumi",
"sigmas": [
0.1
]
},
{
"fixed": true,
"name": "alpha_syst1"
}
],
"poi": "SigXsecOverSM"
},
"name": "LogNormExample"
},
{
"config": {
"parameters": [
{
"auxdata": [
1.0
],
"bounds": [
[
0.5,
1.5
]
],
"fixed": true,
"inits": [
1.0
],
"name": "lumi",
"sigmas": [
0.1
]
},
{
"fixed": true,
"name": "alpha_syst1"
}
],
"poi": "SigXsecOverSM"
},
"name": "ConstExample"
}
],
"resultprefix": "./results/example"
}
}
Exporting#
In order to convert the pyhf JSON to the HistFactory XML+ROOT spec for likelihoods, you need to point the command-line interface pyhf json2xml
at the JSON file you want to convert. As everything is specified in a single file, there is no need to deal with base directories or looking up additional files. This will produce output XML+ROOT in the --output-dir=./
directory (your current working directory), storing XML configs under --specroot=config
and the data file under
--dataroot=data
. The XML configs are prefixed with --resultprefix=FitConfig
by default, so that the top-level XML file will be located at {output dir}/{prefix}.xml
. The command will be of the format
pyhf json2xml {JSON spec}
Note that the output directory must already exist.
[4]:
!mkdir -p output
!pyhf json2xml xml_importexport.json --output-dir output
!ls -lavh output/*
/Users/jovyan/pyhf/src/pyhf/writexml.py:120: RuntimeWarning: invalid value encountered in true_divide
attrs['HistoName'], np.divide(modifierspec['data'], sampledata).tolist()
-rw-r--r-- 1 kratsg staff 822B Apr 9 09:36 output/FitConfig.xml
output/config:
total 8
drwxr-xr-x 3 kratsg staff 102B Apr 9 09:36 .
drwxr-xr-x 5 kratsg staff 170B Apr 9 09:36 ..
-rw-r--r-- 1 kratsg staff 1.0K Apr 9 09:36 FitConfig_channel1.xml
output/data:
total 96
drwxr-xr-x 3 kratsg staff 102B Apr 9 09:36 .
drwxr-xr-x 5 kratsg staff 170B Apr 9 09:36 ..
-rw-r--r-- 1 kratsg staff 46K Apr 9 09:36 data.root
[5]:
!rm xml_importexport.json
!rm -rf output/