We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Different ordering of channels between model.config.channels and mode.config.channel_nbins
# Description

We've recently observed that the ordering of channels outputted from `model.config.channels` differs from the order obtained with `model.config.channel_nbins`. This isn't really a bug, but more a quirk which we thought would be worth bringing to the attention of the developers. We ran into some issues when breaking up the `expected_data` list into individual channels by looping through the `model.config.channel_nbins` ordering, rather than the `model.config.channels` ordering (the `model.config.channels` order matches that of the model). Hopefully this issue helps save another user some time in the future, at very least. 

# Expected Behavior

We expected that the order of the channels in the two dictionaries from `model.config.channels` and `model.config.channel_nbins` would be the same. 

# Actual Behavior

The ordering of the channels is different. As an example, we are generating workspaces using two categories, and we're separating our data by year (2016, 2017, and 2018). This gives us six channels total. The outputs are: 
```
(Pdb) model.config.channels
['vbf_channel_16_high_cat', 'vbf_channel_16_low_cat', 'vbf_channel_17_high_cat', 'vbf_channel_17_low_cat', 'vbf_channel_18_high_cat', 'vbf_channel_18_low_cat']

(Pdb) model.config.channel_nbins
{'vbf_channel_16_low_cat': 12, 'vbf_channel_16_high_cat': 18, 'vbf_channel_17_low_cat': 12, 'vbf_channel_17_high_cat': 18, 'vbf_channel_18_low_cat': 12, 'vbf_channel_18_high_cat': 18}
```
I believe that `model.config.channels` is possibly re-ordering the channels so that the names are in alphabetical order. I have not confirmed this, though. The workspace .json file is filled with the ordering produced by `model.config.channel_nbins`. 

# Steps to Reproduce

I'm using pyhf version 0.6.2 along with python 3.8.8. 
I can make a dummy workspace for this issue, but I thought that since this is a pretty small issue, it might be overkill. Please let me know if this would be helpful, though. 

# Checklist

- [ ] Run `git fetch` to get the most up to date version of `master`
- [X] Searched through existing Issues to confirm this is not a duplicate issue
- [X] Filled out the Description, Expected Behavior, Actual Behavior, and Steps to Reproduce sections above or have edited/removed them in a way that fully describes the issue


Thanks! -Rachel 


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/pyhf/mixins.py`
Content:
```
1 import logging
2 
3 log = logging.getLogger(__name__)
4 
5 
6 class _ChannelSummaryMixin:
7     """
8     A mixin that provides summary data of the provided channels.
9 
10     This mixin will forward all other information to other classes defined in the Child class.
11 
12     Args:
13       **channels: A list of channels to provide summary information about. Follows the `defs.json#/definitions/channel` schema.
14     """
15 
16     def __init__(self, *args, **kwargs):
17         channels = kwargs.pop('channels')
18         super().__init__(*args, **kwargs)
19         self.channels = []
20         self.samples = []
21         self.parameters = []
22         self.modifiers = []
23         # keep track of the width of each channel (how many bins)
24         self.channel_nbins = {}
25         # need to keep track in which order we added the constraints
26         # so that we can generate correctly-ordered data
27         for channel in channels:
28             self.channels.append(channel['name'])
29             self.channel_nbins[channel['name']] = len(channel['samples'][0]['data'])
30             for sample in channel['samples']:
31                 self.samples.append(sample['name'])
32                 for modifier_def in sample['modifiers']:
33                     self.parameters.append(modifier_def['name'])
34                     self.modifiers.append(
35                         (
36                             modifier_def['name'],  # mod name
37                             modifier_def['type'],  # mod type
38                         )
39                     )
40 
41         self.channels = sorted(list(set(self.channels)))
42         self.samples = sorted(list(set(self.samples)))
43         self.parameters = sorted(list(set(self.parameters)))
44         self.modifiers = sorted(list(set(self.modifiers)))
45 
46         self.channel_slices = {}
47         begin = 0
48         for c in self.channels:
49             end = begin + self.channel_nbins[c]
50             self.channel_slices[c] = slice(begin, end)
51             begin = end
52
```
--- 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/src/pyhf/mixins.py b/src/pyhf/mixins.py
--- a/src/pyhf/mixins.py
+++ b/src/pyhf/mixins.py
@@ -42,6 +42,9 @@
         self.samples = sorted(list(set(self.samples)))
         self.parameters = sorted(list(set(self.parameters)))
         self.modifiers = sorted(list(set(self.modifiers)))
+        self.channel_nbins = {
+            channel: self.channel_nbins[channel] for channel in self.channels
+        }
 
         self.channel_slices = {}
         begin = 0

{"golden_diff": "diff --git a/src/pyhf/mixins.py b/src/pyhf/mixins.py\n--- a/src/pyhf/mixins.py\n+++ b/src/pyhf/mixins.py\n@@ -42,6 +42,9 @@\n         self.samples = sorted(list(set(self.samples)))\n         self.parameters = sorted(list(set(self.parameters)))\n         self.modifiers = sorted(list(set(self.modifiers)))\n+        self.channel_nbins = {\n+            channel: self.channel_nbins[channel] for channel in self.channels\n+        }\n \n         self.channel_slices = {}\n         begin = 0\n", "issue": "Different ordering of channels between model.config.channels and mode.config.channel_nbins\n# Description\r\n\r\nWe've recently observed that the ordering of channels outputted from `model.config.channels` differs from the order obtained with `model.config.channel_nbins`. This isn't really a bug, but more a quirk which we thought would be worth bringing to the attention of the developers. We ran into some issues when breaking up the `expected_data` list into individual channels by looping through the `model.config.channel_nbins` ordering, rather than the `model.config.channels` ordering (the `model.config.channels` order matches that of the model). Hopefully this issue helps save another user some time in the future, at very least. \r\n\r\n# Expected Behavior\r\n\r\nWe expected that the order of the channels in the two dictionaries from `model.config.channels` and `model.config.channel_nbins` would be the same. \r\n\r\n# Actual Behavior\r\n\r\nThe ordering of the channels is different. As an example, we are generating workspaces using two categories, and we're separating our data by year (2016, 2017, and 2018). This gives us six channels total. The outputs are: \r\n```\r\n(Pdb) model.config.channels\r\n['vbf_channel_16_high_cat', 'vbf_channel_16_low_cat', 'vbf_channel_17_high_cat', 'vbf_channel_17_low_cat', 'vbf_channel_18_high_cat', 'vbf_channel_18_low_cat']\r\n\r\n(Pdb) model.config.channel_nbins\r\n{'vbf_channel_16_low_cat': 12, 'vbf_channel_16_high_cat': 18, 'vbf_channel_17_low_cat': 12, 'vbf_channel_17_high_cat': 18, 'vbf_channel_18_low_cat': 12, 'vbf_channel_18_high_cat': 18}\r\n```\r\nI believe that `model.config.channels` is possibly re-ordering the channels so that the names are in alphabetical order. I have not confirmed this, though. The workspace .json file is filled with the ordering produced by `model.config.channel_nbins`. \r\n\r\n# Steps to Reproduce\r\n\r\nI'm using pyhf version 0.6.2 along with python 3.8.8. \r\nI can make a dummy workspace for this issue, but I thought that since this is a pretty small issue, it might be overkill. Please let me know if this would be helpful, though. \r\n\r\n# Checklist\r\n\r\n- [ ] Run `git fetch` to get the most up to date version of `master`\r\n- [X] Searched through existing Issues to confirm this is not a duplicate issue\r\n- [X] Filled out the Description, Expected Behavior, Actual Behavior, and Steps to Reproduce sections above or have edited/removed them in a way that fully describes the issue\r\n\r\n\r\nThanks! -Rachel \r\n\n", "before_files": [{"content": "import logging\n\nlog = logging.getLogger(__name__)\n\n\nclass _ChannelSummaryMixin:\n    \"\"\"\n    A mixin that provides summary data of the provided channels.\n\n    This mixin will forward all other information to other classes defined in the Child class.\n\n    Args:\n      **channels: A list of channels to provide summary information about. Follows the `defs.json#/definitions/channel` schema.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        channels = kwargs.pop('channels')\n        super().__init__(*args, **kwargs)\n        self.channels = []\n        self.samples = []\n        self.parameters = []\n        self.modifiers = []\n        # keep track of the width of each channel (how many bins)\n        self.channel_nbins = {}\n        # need to keep track in which order we added the constraints\n        # so that we can generate correctly-ordered data\n        for channel in channels:\n            self.channels.append(channel['name'])\n            self.channel_nbins[channel['name']] = len(channel['samples'][0]['data'])\n            for sample in channel['samples']:\n                self.samples.append(sample['name'])\n                for modifier_def in sample['modifiers']:\n                    self.parameters.append(modifier_def['name'])\n                    self.modifiers.append(\n                        (\n                            modifier_def['name'],  # mod name\n                            modifier_def['type'],  # mod type\n                        )\n                    )\n\n        self.channels = sorted(list(set(self.channels)))\n        self.samples = sorted(list(set(self.samples)))\n        self.parameters = sorted(list(set(self.parameters)))\n        self.modifiers = sorted(list(set(self.modifiers)))\n\n        self.channel_slices = {}\n        begin = 0\n        for c in self.channels:\n            end = begin + self.channel_nbins[c]\n            self.channel_slices[c] = slice(begin, end)\n            begin = end\n", "path": "src/pyhf/mixins.py"}], "after_files": [{"content": "import logging\n\nlog = logging.getLogger(__name__)\n\n\nclass _ChannelSummaryMixin:\n    \"\"\"\n    A mixin that provides summary data of the provided channels.\n\n    This mixin will forward all other information to other classes defined in the Child class.\n\n    Args:\n      **channels: A list of channels to provide summary information about. Follows the `defs.json#/definitions/channel` schema.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        channels = kwargs.pop('channels')\n        super().__init__(*args, **kwargs)\n        self.channels = []\n        self.samples = []\n        self.parameters = []\n        self.modifiers = []\n        # keep track of the width of each channel (how many bins)\n        self.channel_nbins = {}\n        # need to keep track in which order we added the constraints\n        # so that we can generate correctly-ordered data\n        for channel in channels:\n            self.channels.append(channel['name'])\n            self.channel_nbins[channel['name']] = len(channel['samples'][0]['data'])\n            for sample in channel['samples']:\n                self.samples.append(sample['name'])\n                for modifier_def in sample['modifiers']:\n                    self.parameters.append(modifier_def['name'])\n                    self.modifiers.append(\n                        (\n                            modifier_def['name'],  # mod name\n                            modifier_def['type'],  # mod type\n                        )\n                    )\n\n        self.channels = sorted(list(set(self.channels)))\n        self.samples = sorted(list(set(self.samples)))\n        self.parameters = sorted(list(set(self.parameters)))\n        self.modifiers = sorted(list(set(self.modifiers)))\n        self.channel_nbins = {\n            channel: self.channel_nbins[channel] for channel in self.channels\n        }\n\n        self.channel_slices = {}\n        begin = 0\n        for c in self.channels:\n            end = begin + self.channel_nbins[c]\n            self.channel_slices[c] = slice(begin, end)\n            begin = end\n", "path": "src/pyhf/mixins.py"}]}