We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add FAQ RE: how to use xml2json CLI tool
# Description

Add a section to the FAQ RE: how to install the `xmlimport` optional dependencies and how to use the `xml2json` CLI tool.

This could also be an entire example Jupyter notebook on using the CLI and then have the FAQ be just on how to install the `xmlimport` dependencies.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `pyhf/commandline.py`
Content:
```
1 import logging
2 
3 import click
4 import json
5 import os
6 import jsonpatch
7 import sys
8 
9 from . import writexml
10 from .utils import hypotest
11 from .pdf import Model
12 from .version import __version__
13 
14 logging.basicConfig()
15 log = logging.getLogger(__name__)
16 
17 # This is only needed for Python 2/3 compatibility
18 def ensure_dirs(path):
19     try:
20         os.makedirs(path, exist_ok=True)
21     except TypeError:
22         if not os.path.exists(path):
23             os.makedirs(path)
24 
25 
26 @click.group(context_settings=dict(help_option_names=['-h', '--help']))
27 @click.version_option(version=__version__)
28 def pyhf():
29     pass
30 
31 
32 @pyhf.command()
33 @click.argument('entrypoint-xml', type=click.Path(exists=True))
34 @click.option(
35     '--basedir',
36     help='The base directory for the XML files to point relative to.',
37     type=click.Path(exists=True),
38     default=os.getcwd(),
39 )
40 @click.option(
41     '--output-file',
42     help='The location of the output json file. If not specified, prints to screen.',
43     default=None,
44 )
45 @click.option('--track-progress/--hide-progress', default=True)
46 def xml2json(entrypoint_xml, basedir, output_file, track_progress):
47     """ Entrypoint XML: The top-level XML file for the PDF definition. """
48     try:
49         import uproot
50 
51         assert uproot
52     except ImportError:
53         log.error(
54             "xml2json requires uproot, please install pyhf using the "
55             "xmlimport extra: pip install pyhf[xmlimport] or install uproot "
56             "manually: pip install uproot"
57         )
58     from . import readxml
59 
60     spec = readxml.parse(entrypoint_xml, basedir, track_progress=track_progress)
61     if output_file is None:
62         print(json.dumps(spec, indent=4, sort_keys=True))
63     else:
64         with open(output_file, 'w+') as out_file:
65             json.dump(spec, out_file, indent=4, sort_keys=True)
66         log.debug("Written to {0:s}".format(output_file))
67     sys.exit(0)
68 
69 
70 @pyhf.command()
71 @click.argument('workspace', default='-')
72 @click.option('--output-dir', type=click.Path(exists=True), default='.')
73 @click.option('--specroot', default='config')
74 @click.option('--dataroot', default='data')
75 @click.option('--resultprefix', default='FitConfig')
76 def json2xml(workspace, output_dir, specroot, dataroot, resultprefix):
77     ensure_dirs(output_dir)
78     with click.open_file(workspace, 'r') as specstream:
79         d = json.load(specstream)
80         ensure_dirs(os.path.join(output_dir, specroot))
81         ensure_dirs(os.path.join(output_dir, dataroot))
82         with click.open_file(
83             os.path.join(output_dir, '{0:s}.xml'.format(resultprefix)), 'w'
84         ) as outstream:
85             outstream.write(
86                 writexml.writexml(
87                     d,
88                     os.path.join(output_dir, specroot),
89                     os.path.join(output_dir, dataroot),
90                     resultprefix,
91                 ).decode('utf-8')
92             )
93 
94     sys.exit(0)
95 
96 
97 @pyhf.command()
98 @click.argument('workspace', default='-')
99 @click.option(
100     '--output-file',
101     help='The location of the output json file. If not specified, prints to screen.',
102     default=None,
103 )
104 @click.option('--measurement', default=None)
105 @click.option('-p', '--patch', multiple=True)
106 @click.option('--testpoi', default=1.0)
107 def cls(workspace, output_file, measurement, patch, testpoi):
108     with click.open_file(workspace, 'r') as specstream:
109         d = json.load(specstream)
110     measurements = d['toplvl']['measurements']
111     measurement_names = [m['name'] for m in measurements]
112     measurement_index = 0
113 
114     log.debug('measurements defined:\n\t{0:s}'.format('\n\t'.join(measurement_names)))
115     if measurement and measurement not in measurement_names:
116         log.error(
117             'no measurement by name \'{0:s}\' exists, pick from one of the valid ones above'.format(
118                 measurement
119             )
120         )
121         sys.exit(1)
122     else:
123         if not measurement and len(measurements) > 1:
124             log.warning('multiple measurements defined. Taking the first measurement.')
125             measurement_index = 0
126         elif measurement:
127             measurement_index = measurement_names.index(measurement)
128 
129         log.debug(
130             'calculating CLs for measurement {0:s}'.format(
131                 measurements[measurement_index]['name']
132             )
133         )
134         spec = {
135             'channels': d['channels'],
136             'parameters': d['toplvl']['measurements'][measurement_index]['config'].get(
137                 'parameters', []
138             ),
139         }
140 
141         for p in patch:
142             with click.open_file(p, 'r') as read_file:
143                 p = jsonpatch.JsonPatch(json.loads(read_file.read()))
144             spec = p.apply(spec)
145         p = Model(spec, poiname=measurements[measurement_index]['config']['poi'])
146         observed = sum((d['data'][c] for c in p.config.channels), []) + p.config.auxdata
147         result = hypotest(testpoi, observed, p, return_expected_set=True)
148         result = {
149             'CLs_obs': result[0].tolist()[0],
150             'CLs_exp': result[-1].ravel().tolist(),
151         }
152         if output_file is None:
153             print(json.dumps(result, indent=4, sort_keys=True))
154         else:
155             with open(output_file, 'w+') as out_file:
156                 json.dump(result, out_file, indent=4, sort_keys=True)
157             log.debug("Written to {0:s}".format(output_file))
158         sys.exit(0)
159
```

Path: `setup.py`
Content:
```
1 #!/usr/bin/env python
2 
3 from setuptools import setup, find_packages
4 from os import path
5 import sys
6 
7 this_directory = path.abspath(path.dirname(__file__))
8 if sys.version_info.major < 3:
9     from io import open
10 with open(path.join(this_directory, 'README.md'), encoding='utf-8') as readme_md:
11     long_description = readme_md.read()
12 
13 extras_require = {
14     'tensorflow': [
15         'tensorflow~=1.13',
16         'tensorflow-probability~=0.5',
17         'numpy<=1.14.5,>=1.14.0',  # Lower of 1.14.0 instead of 1.13.3 to ensure doctest pass
18         'setuptools<=39.1.0',
19     ],
20     'torch': ['torch~=1.0'],
21     'mxnet': ['mxnet~=1.0', 'requests~=2.18.4', 'numpy<1.15.0,>=1.8.2'],
22     # 'dask': [
23     #     'dask[array]'
24     # ],
25     'xmlimport': ['uproot'],
26     'minuit': ['iminuit'],
27     'develop': [
28         'pyflakes',
29         'pytest~=3.5',
30         'pytest-cov>=2.5.1',
31         'pytest-mock',
32         'pytest-benchmark[histogram]',
33         'pytest-console-scripts',
34         'python-coveralls',
35         'coverage>=4.0',  # coveralls
36         'matplotlib',
37         'jupyter',
38         'nbdime',
39         'uproot~=3.3',
40         'papermill~=0.16',
41         'graphviz',
42         'bumpversion',
43         'sphinx',
44         'sphinxcontrib-bibtex',
45         'sphinxcontrib-napoleon',
46         'sphinx_rtd_theme',
47         'nbsphinx',
48         'sphinx-issues',
49         'm2r',
50         'jsonpatch',
51         'ipython<7',  # jupyter_console and ipython clash in dependency requirement -- downgrade ipython for now
52         'pre-commit',
53         'black;python_version>="3.6"',  # Black is Python3 only
54         'twine',
55     ],
56 }
57 extras_require['complete'] = sorted(set(sum(extras_require.values(), [])))
58 
59 setup(
60     name='pyhf',
61     version='0.0.16',
62     description='(partial) pure python histfactory implementation',
63     long_description=long_description,
64     long_description_content_type='text/markdown',
65     url='https://github.com/diana-hep/pyhf',
66     author='Lukas Heinrich',
67     author_email='lukas.heinrich@cern.ch',
68     license='Apache',
69     keywords='physics fitting numpy scipy tensorflow pytorch mxnet dask',
70     classifiers=[
71         "Programming Language :: Python :: 2",
72         "Programming Language :: Python :: 2.7",
73         "Programming Language :: Python :: 3",
74         "Programming Language :: Python :: 3.6",
75         "Programming Language :: Python :: 3.7",
76     ],
77     packages=find_packages(),
78     include_package_data=True,
79     python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*",
80     install_requires=[
81         'scipy',  # requires numpy, which is required by pyhf, tensorflow, and mxnet
82         'click>=6.0',  # for console scripts,
83         'tqdm',  # for readxml
84         'six',  # for modifiers
85         'jsonschema>=v3.0.0a2',  # for utils, alpha-release for draft 6
86         'jsonpatch',
87     ],
88     extras_require=extras_require,
89     entry_points={'console_scripts': ['pyhf=pyhf.commandline:pyhf']},
90     dependency_links=[],
91 )
92
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/pyhf/commandline.py b/pyhf/commandline.py
--- a/pyhf/commandline.py
+++ b/pyhf/commandline.py
@@ -52,7 +52,7 @@
     except ImportError:
         log.error(
             "xml2json requires uproot, please install pyhf using the "
-            "xmlimport extra: pip install pyhf[xmlimport] or install uproot "
+            "xmlio extra: pip install pyhf[xmlio] or install uproot "
             "manually: pip install uproot"
         )
     from . import readxml
@@ -74,6 +74,17 @@
 @click.option('--dataroot', default='data')
 @click.option('--resultprefix', default='FitConfig')
 def json2xml(workspace, output_dir, specroot, dataroot, resultprefix):
+    try:
+        import uproot
+
+        assert uproot
+    except ImportError:
+        log.error(
+            "json2xml requires uproot, please install pyhf using the "
+            "xmlio extra: pip install pyhf[xmlio] or install uproot "
+            "manually: pip install uproot"
+        )
+
     ensure_dirs(output_dir)
     with click.open_file(workspace, 'r') as specstream:
         d = json.load(specstream)
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@
     # 'dask': [
     #     'dask[array]'
     # ],
-    'xmlimport': ['uproot'],
+    'xmlio': ['uproot'],
     'minuit': ['iminuit'],
     'develop': [
         'pyflakes',

{"golden_diff": "diff --git a/pyhf/commandline.py b/pyhf/commandline.py\n--- a/pyhf/commandline.py\n+++ b/pyhf/commandline.py\n@@ -52,7 +52,7 @@\n     except ImportError:\n         log.error(\n             \"xml2json requires uproot, please install pyhf using the \"\n-            \"xmlimport extra: pip install pyhf[xmlimport] or install uproot \"\n+            \"xmlio extra: pip install pyhf[xmlio] or install uproot \"\n             \"manually: pip install uproot\"\n         )\n     from . import readxml\n@@ -74,6 +74,17 @@\n @click.option('--dataroot', default='data')\n @click.option('--resultprefix', default='FitConfig')\n def json2xml(workspace, output_dir, specroot, dataroot, resultprefix):\n+    try:\n+        import uproot\n+\n+        assert uproot\n+    except ImportError:\n+        log.error(\n+            \"json2xml requires uproot, please install pyhf using the \"\n+            \"xmlio extra: pip install pyhf[xmlio] or install uproot \"\n+            \"manually: pip install uproot\"\n+        )\n+\n     ensure_dirs(output_dir)\n     with click.open_file(workspace, 'r') as specstream:\n         d = json.load(specstream)\ndiff --git a/setup.py b/setup.py\n--- a/setup.py\n+++ b/setup.py\n@@ -22,7 +22,7 @@\n     # 'dask': [\n     #     'dask[array]'\n     # ],\n-    'xmlimport': ['uproot'],\n+    'xmlio': ['uproot'],\n     'minuit': ['iminuit'],\n     'develop': [\n         'pyflakes',\n", "issue": "Add FAQ RE: how to use xml2json CLI tool\n# Description\r\n\r\nAdd a section to the FAQ RE: how to install the `xmlimport` optional dependencies and how to use the `xml2json` CLI tool.\r\n\r\nThis could also be an entire example Jupyter notebook on using the CLI and then have the FAQ be just on how to install the `xmlimport` dependencies.\r\n\n", "before_files": [{"content": "import logging\n\nimport click\nimport json\nimport os\nimport jsonpatch\nimport sys\n\nfrom . import writexml\nfrom .utils import hypotest\nfrom .pdf import Model\nfrom .version import __version__\n\nlogging.basicConfig()\nlog = logging.getLogger(__name__)\n\n# This is only needed for Python 2/3 compatibility\ndef ensure_dirs(path):\n    try:\n        os.makedirs(path, exist_ok=True)\n    except TypeError:\n        if not os.path.exists(path):\n            os.makedirs(path)\n\n\n@click.group(context_settings=dict(help_option_names=['-h', '--help']))\n@click.version_option(version=__version__)\ndef pyhf():\n    pass\n\n\n@pyhf.command()\n@click.argument('entrypoint-xml', type=click.Path(exists=True))\n@click.option(\n    '--basedir',\n    help='The base directory for the XML files to point relative to.',\n    type=click.Path(exists=True),\n    default=os.getcwd(),\n)\n@click.option(\n    '--output-file',\n    help='The location of the output json file. If not specified, prints to screen.',\n    default=None,\n)\n@click.option('--track-progress/--hide-progress', default=True)\ndef xml2json(entrypoint_xml, basedir, output_file, track_progress):\n    \"\"\" Entrypoint XML: The top-level XML file for the PDF definition. \"\"\"\n    try:\n        import uproot\n\n        assert uproot\n    except ImportError:\n        log.error(\n            \"xml2json requires uproot, please install pyhf using the \"\n            \"xmlimport extra: pip install pyhf[xmlimport] or install uproot \"\n            \"manually: pip install uproot\"\n        )\n    from . import readxml\n\n    spec = readxml.parse(entrypoint_xml, basedir, track_progress=track_progress)\n    if output_file is None:\n        print(json.dumps(spec, indent=4, sort_keys=True))\n    else:\n        with open(output_file, 'w+') as out_file:\n            json.dump(spec, out_file, indent=4, sort_keys=True)\n        log.debug(\"Written to {0:s}\".format(output_file))\n    sys.exit(0)\n\n\n@pyhf.command()\n@click.argument('workspace', default='-')\n@click.option('--output-dir', type=click.Path(exists=True), default='.')\n@click.option('--specroot', default='config')\n@click.option('--dataroot', default='data')\n@click.option('--resultprefix', default='FitConfig')\ndef json2xml(workspace, output_dir, specroot, dataroot, resultprefix):\n    ensure_dirs(output_dir)\n    with click.open_file(workspace, 'r') as specstream:\n        d = json.load(specstream)\n        ensure_dirs(os.path.join(output_dir, specroot))\n        ensure_dirs(os.path.join(output_dir, dataroot))\n        with click.open_file(\n            os.path.join(output_dir, '{0:s}.xml'.format(resultprefix)), 'w'\n        ) as outstream:\n            outstream.write(\n                writexml.writexml(\n                    d,\n                    os.path.join(output_dir, specroot),\n                    os.path.join(output_dir, dataroot),\n                    resultprefix,\n                ).decode('utf-8')\n            )\n\n    sys.exit(0)\n\n\n@pyhf.command()\n@click.argument('workspace', default='-')\n@click.option(\n    '--output-file',\n    help='The location of the output json file. If not specified, prints to screen.',\n    default=None,\n)\n@click.option('--measurement', default=None)\n@click.option('-p', '--patch', multiple=True)\n@click.option('--testpoi', default=1.0)\ndef cls(workspace, output_file, measurement, patch, testpoi):\n    with click.open_file(workspace, 'r') as specstream:\n        d = json.load(specstream)\n    measurements = d['toplvl']['measurements']\n    measurement_names = [m['name'] for m in measurements]\n    measurement_index = 0\n\n    log.debug('measurements defined:\\n\\t{0:s}'.format('\\n\\t'.join(measurement_names)))\n    if measurement and measurement not in measurement_names:\n        log.error(\n            'no measurement by name \\'{0:s}\\' exists, pick from one of the valid ones above'.format(\n                measurement\n            )\n        )\n        sys.exit(1)\n    else:\n        if not measurement and len(measurements) > 1:\n            log.warning('multiple measurements defined. Taking the first measurement.')\n            measurement_index = 0\n        elif measurement:\n            measurement_index = measurement_names.index(measurement)\n\n        log.debug(\n            'calculating CLs for measurement {0:s}'.format(\n                measurements[measurement_index]['name']\n            )\n        )\n        spec = {\n            'channels': d['channels'],\n            'parameters': d['toplvl']['measurements'][measurement_index]['config'].get(\n                'parameters', []\n            ),\n        }\n\n        for p in patch:\n            with click.open_file(p, 'r') as read_file:\n                p = jsonpatch.JsonPatch(json.loads(read_file.read()))\n            spec = p.apply(spec)\n        p = Model(spec, poiname=measurements[measurement_index]['config']['poi'])\n        observed = sum((d['data'][c] for c in p.config.channels), []) + p.config.auxdata\n        result = hypotest(testpoi, observed, p, return_expected_set=True)\n        result = {\n            'CLs_obs': result[0].tolist()[0],\n            'CLs_exp': result[-1].ravel().tolist(),\n        }\n        if output_file is None:\n            print(json.dumps(result, indent=4, sort_keys=True))\n        else:\n            with open(output_file, 'w+') as out_file:\n                json.dump(result, out_file, indent=4, sort_keys=True)\n            log.debug(\"Written to {0:s}\".format(output_file))\n        sys.exit(0)\n", "path": "pyhf/commandline.py"}, {"content": "#!/usr/bin/env python\n\nfrom setuptools import setup, find_packages\nfrom os import path\nimport sys\n\nthis_directory = path.abspath(path.dirname(__file__))\nif sys.version_info.major < 3:\n    from io import open\nwith open(path.join(this_directory, 'README.md'), encoding='utf-8') as readme_md:\n    long_description = readme_md.read()\n\nextras_require = {\n    'tensorflow': [\n        'tensorflow~=1.13',\n        'tensorflow-probability~=0.5',\n        'numpy<=1.14.5,>=1.14.0',  # Lower of 1.14.0 instead of 1.13.3 to ensure doctest pass\n        'setuptools<=39.1.0',\n    ],\n    'torch': ['torch~=1.0'],\n    'mxnet': ['mxnet~=1.0', 'requests~=2.18.4', 'numpy<1.15.0,>=1.8.2'],\n    # 'dask': [\n    #     'dask[array]'\n    # ],\n    'xmlimport': ['uproot'],\n    'minuit': ['iminuit'],\n    'develop': [\n        'pyflakes',\n        'pytest~=3.5',\n        'pytest-cov>=2.5.1',\n        'pytest-mock',\n        'pytest-benchmark[histogram]',\n        'pytest-console-scripts',\n        'python-coveralls',\n        'coverage>=4.0',  # coveralls\n        'matplotlib',\n        'jupyter',\n        'nbdime',\n        'uproot~=3.3',\n        'papermill~=0.16',\n        'graphviz',\n        'bumpversion',\n        'sphinx',\n        'sphinxcontrib-bibtex',\n        'sphinxcontrib-napoleon',\n        'sphinx_rtd_theme',\n        'nbsphinx',\n        'sphinx-issues',\n        'm2r',\n        'jsonpatch',\n        'ipython<7',  # jupyter_console and ipython clash in dependency requirement -- downgrade ipython for now\n        'pre-commit',\n        'black;python_version>=\"3.6\"',  # Black is Python3 only\n        'twine',\n    ],\n}\nextras_require['complete'] = sorted(set(sum(extras_require.values(), [])))\n\nsetup(\n    name='pyhf',\n    version='0.0.16',\n    description='(partial) pure python histfactory implementation',\n    long_description=long_description,\n    long_description_content_type='text/markdown',\n    url='https://github.com/diana-hep/pyhf',\n    author='Lukas Heinrich',\n    author_email='lukas.heinrich@cern.ch',\n    license='Apache',\n    keywords='physics fitting numpy scipy tensorflow pytorch mxnet dask',\n    classifiers=[\n        \"Programming Language :: Python :: 2\",\n        \"Programming Language :: Python :: 2.7\",\n        \"Programming Language :: Python :: 3\",\n        \"Programming Language :: Python :: 3.6\",\n        \"Programming Language :: Python :: 3.7\",\n    ],\n    packages=find_packages(),\n    include_package_data=True,\n    python_requires=\">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*\",\n    install_requires=[\n        'scipy',  # requires numpy, which is required by pyhf, tensorflow, and mxnet\n        'click>=6.0',  # for console scripts,\n        'tqdm',  # for readxml\n        'six',  # for modifiers\n        'jsonschema>=v3.0.0a2',  # for utils, alpha-release for draft 6\n        'jsonpatch',\n    ],\n    extras_require=extras_require,\n    entry_points={'console_scripts': ['pyhf=pyhf.commandline:pyhf']},\n    dependency_links=[],\n)\n", "path": "setup.py"}], "after_files": [{"content": "import logging\n\nimport click\nimport json\nimport os\nimport jsonpatch\nimport sys\n\nfrom . import writexml\nfrom .utils import hypotest\nfrom .pdf import Model\nfrom .version import __version__\n\nlogging.basicConfig()\nlog = logging.getLogger(__name__)\n\n# This is only needed for Python 2/3 compatibility\ndef ensure_dirs(path):\n    try:\n        os.makedirs(path, exist_ok=True)\n    except TypeError:\n        if not os.path.exists(path):\n            os.makedirs(path)\n\n\n@click.group(context_settings=dict(help_option_names=['-h', '--help']))\n@click.version_option(version=__version__)\ndef pyhf():\n    pass\n\n\n@pyhf.command()\n@click.argument('entrypoint-xml', type=click.Path(exists=True))\n@click.option(\n    '--basedir',\n    help='The base directory for the XML files to point relative to.',\n    type=click.Path(exists=True),\n    default=os.getcwd(),\n)\n@click.option(\n    '--output-file',\n    help='The location of the output json file. If not specified, prints to screen.',\n    default=None,\n)\n@click.option('--track-progress/--hide-progress', default=True)\ndef xml2json(entrypoint_xml, basedir, output_file, track_progress):\n    \"\"\" Entrypoint XML: The top-level XML file for the PDF definition. \"\"\"\n    try:\n        import uproot\n\n        assert uproot\n    except ImportError:\n        log.error(\n            \"xml2json requires uproot, please install pyhf using the \"\n            \"xmlio extra: pip install pyhf[xmlio] or install uproot \"\n            \"manually: pip install uproot\"\n        )\n    from . import readxml\n\n    spec = readxml.parse(entrypoint_xml, basedir, track_progress=track_progress)\n    if output_file is None:\n        print(json.dumps(spec, indent=4, sort_keys=True))\n    else:\n        with open(output_file, 'w+') as out_file:\n            json.dump(spec, out_file, indent=4, sort_keys=True)\n        log.debug(\"Written to {0:s}\".format(output_file))\n    sys.exit(0)\n\n\n@pyhf.command()\n@click.argument('workspace', default='-')\n@click.option('--output-dir', type=click.Path(exists=True), default='.')\n@click.option('--specroot', default='config')\n@click.option('--dataroot', default='data')\n@click.option('--resultprefix', default='FitConfig')\ndef json2xml(workspace, output_dir, specroot, dataroot, resultprefix):\n    try:\n        import uproot\n\n        assert uproot\n    except ImportError:\n        log.error(\n            \"json2xml requires uproot, please install pyhf using the \"\n            \"xmlio extra: pip install pyhf[xmlio] or install uproot \"\n            \"manually: pip install uproot\"\n        )\n\n    ensure_dirs(output_dir)\n    with click.open_file(workspace, 'r') as specstream:\n        d = json.load(specstream)\n        ensure_dirs(os.path.join(output_dir, specroot))\n        ensure_dirs(os.path.join(output_dir, dataroot))\n        with click.open_file(\n            os.path.join(output_dir, '{0:s}.xml'.format(resultprefix)), 'w'\n        ) as outstream:\n            outstream.write(\n                writexml.writexml(\n                    d,\n                    os.path.join(output_dir, specroot),\n                    os.path.join(output_dir, dataroot),\n                    resultprefix,\n                ).decode('utf-8')\n            )\n\n    sys.exit(0)\n\n\n@pyhf.command()\n@click.argument('workspace', default='-')\n@click.option(\n    '--output-file',\n    help='The location of the output json file. If not specified, prints to screen.',\n    default=None,\n)\n@click.option('--measurement', default=None)\n@click.option('-p', '--patch', multiple=True)\n@click.option('--testpoi', default=1.0)\ndef cls(workspace, output_file, measurement, patch, testpoi):\n    with click.open_file(workspace, 'r') as specstream:\n        d = json.load(specstream)\n    measurements = d['toplvl']['measurements']\n    measurement_names = [m['name'] for m in measurements]\n    measurement_index = 0\n\n    log.debug('measurements defined:\\n\\t{0:s}'.format('\\n\\t'.join(measurement_names)))\n    if measurement and measurement not in measurement_names:\n        log.error(\n            'no measurement by name \\'{0:s}\\' exists, pick from one of the valid ones above'.format(\n                measurement\n            )\n        )\n        sys.exit(1)\n    else:\n        if not measurement and len(measurements) > 1:\n            log.warning('multiple measurements defined. Taking the first measurement.')\n            measurement_index = 0\n        elif measurement:\n            measurement_index = measurement_names.index(measurement)\n\n        log.debug(\n            'calculating CLs for measurement {0:s}'.format(\n                measurements[measurement_index]['name']\n            )\n        )\n        spec = {\n            'channels': d['channels'],\n            'parameters': d['toplvl']['measurements'][measurement_index]['config'].get(\n                'parameters', []\n            ),\n        }\n\n        for p in patch:\n            with click.open_file(p, 'r') as read_file:\n                p = jsonpatch.JsonPatch(json.loads(read_file.read()))\n            spec = p.apply(spec)\n        p = Model(spec, poiname=measurements[measurement_index]['config']['poi'])\n        observed = sum((d['data'][c] for c in p.config.channels), []) + p.config.auxdata\n        result = hypotest(testpoi, observed, p, return_expected_set=True)\n        result = {\n            'CLs_obs': result[0].tolist()[0],\n            'CLs_exp': result[-1].ravel().tolist(),\n        }\n        if output_file is None:\n            print(json.dumps(result, indent=4, sort_keys=True))\n        else:\n            with open(output_file, 'w+') as out_file:\n                json.dump(result, out_file, indent=4, sort_keys=True)\n            log.debug(\"Written to {0:s}\".format(output_file))\n        sys.exit(0)\n", "path": "pyhf/commandline.py"}, {"content": "#!/usr/bin/env python\n\nfrom setuptools import setup, find_packages\nfrom os import path\nimport sys\n\nthis_directory = path.abspath(path.dirname(__file__))\nif sys.version_info.major < 3:\n    from io import open\nwith open(path.join(this_directory, 'README.md'), encoding='utf-8') as readme_md:\n    long_description = readme_md.read()\n\nextras_require = {\n    'tensorflow': [\n        'tensorflow~=1.13',\n        'tensorflow-probability~=0.5',\n        'numpy<=1.14.5,>=1.14.0',  # Lower of 1.14.0 instead of 1.13.3 to ensure doctest pass\n        'setuptools<=39.1.0',\n    ],\n    'torch': ['torch~=1.0'],\n    'mxnet': ['mxnet~=1.0', 'requests~=2.18.4', 'numpy<1.15.0,>=1.8.2'],\n    # 'dask': [\n    #     'dask[array]'\n    # ],\n    'xmlio': ['uproot'],\n    'minuit': ['iminuit'],\n    'develop': [\n        'pyflakes',\n        'pytest~=3.5',\n        'pytest-cov>=2.5.1',\n        'pytest-mock',\n        'pytest-benchmark[histogram]',\n        'pytest-console-scripts',\n        'python-coveralls',\n        'coverage>=4.0',  # coveralls\n        'matplotlib',\n        'jupyter',\n        'nbdime',\n        'uproot~=3.3',\n        'papermill~=0.16',\n        'graphviz',\n        'bumpversion',\n        'sphinx',\n        'sphinxcontrib-bibtex',\n        'sphinxcontrib-napoleon',\n        'sphinx_rtd_theme',\n        'nbsphinx',\n        'sphinx-issues',\n        'm2r',\n        'jsonpatch',\n        'ipython<7',  # jupyter_console and ipython clash in dependency requirement -- downgrade ipython for now\n        'pre-commit',\n        'black;python_version>=\"3.6\"',  # Black is Python3 only\n        'twine',\n    ],\n}\nextras_require['complete'] = sorted(set(sum(extras_require.values(), [])))\n\nsetup(\n    name='pyhf',\n    version='0.0.16',\n    description='(partial) pure python histfactory implementation',\n    long_description=long_description,\n    long_description_content_type='text/markdown',\n    url='https://github.com/diana-hep/pyhf',\n    author='Lukas Heinrich',\n    author_email='lukas.heinrich@cern.ch',\n    license='Apache',\n    keywords='physics fitting numpy scipy tensorflow pytorch mxnet dask',\n    classifiers=[\n        \"Programming Language :: Python :: 2\",\n        \"Programming Language :: Python :: 2.7\",\n        \"Programming Language :: Python :: 3\",\n        \"Programming Language :: Python :: 3.6\",\n        \"Programming Language :: Python :: 3.7\",\n    ],\n    packages=find_packages(),\n    include_package_data=True,\n    python_requires=\">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*\",\n    install_requires=[\n        'scipy',  # requires numpy, which is required by pyhf, tensorflow, and mxnet\n        'click>=6.0',  # for console scripts,\n        'tqdm',  # for readxml\n        'six',  # for modifiers\n        'jsonschema>=v3.0.0a2',  # for utils, alpha-release for draft 6\n        'jsonpatch',\n    ],\n    extras_require=extras_require,\n    entry_points={'console_scripts': ['pyhf=pyhf.commandline:pyhf']},\n    dependency_links=[],\n)\n", "path": "setup.py"}]}