prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Update code for when Engine metric qubits are formatted differently
  There is currently code in calibration.py that looks at qubit ids that start with `q` and removes this `q` before getting the grid qubit.  If the API no longer returns `q` prefixed code this should be removed, otherwise if we are going to continue to support this we should add it to `grid_qubit_from_proto`.
  
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `cirq/google/engine/calibration.py`
  Content:
  ```
  1 # Copyright 2019 The Cirq Developers
  2 #
  3 # Licensed under the Apache License, Version 2.0 (the "License");
  4 # you may not use this file except in compliance with the License.
  5 # You may obtain a copy of the License at
  6 #
  7 #     https://www.apache.org/licenses/LICENSE-2.0
  8 #
  9 # Unless required by applicable law or agreed to in writing, software
  10 # distributed under the License is distributed on an "AS IS" BASIS,
  11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12 # See the License for the specific language governing permissions and
  13 # limitations under the License.
  14 """Calibration wrapper for calibrations returned from the Quantum Engine."""
  15 
  16 from collections import abc, defaultdict
  17 import datetime
  18 
  19 from typing import Any, Dict, Iterator, Optional, Tuple, TYPE_CHECKING
  20 
  21 from cirq import devices, vis
  22 from cirq.google.api import v2
  23 
  24 if TYPE_CHECKING:
  25     import cirq
  26 
  27 
  28 class Calibration(abc.Mapping):
  29     """A convenience wrapper for calibrations that acts like a dictionary.
  30 
  31     Calibrations act as dictionaries whose keys are the names of the metric,
  32     and whose values are the metric values.  The metric values themselves are
  33     represented as a dictionary.  These metric value dictionaries have
  34     keys that are tuples of `cirq.GridQubit`s and values that are lists of the
  35     metric values for those qubits. If a metric acts globally and is attached
  36     to no specified number of qubits, the map will be from the empty tuple
  37     to the metrics values.
  38 
  39     Calibrations act just like a python dictionary. For example you can get
  40     a list of all of the metric names using
  41 
  42         `calibration.keys()`
  43 
  44     and query a single value by looking up the name by index:
  45 
  46         `calibration['t1']`
  47 
  48     Attributes:
  49         timestamp: The time that this calibration was run, in milliseconds since
  50             the epoch.
  51     """
  52 
  53     def __init__(self, calibration: v2.metrics_pb2.MetricsSnapshot) -> None:
  54         self.timestamp = calibration.timestamp_ms
  55         self._metric_dict = self._compute_metric_dict(calibration.metrics)
  56 
  57     def _compute_metric_dict(
  58             self, metrics: v2.metrics_pb2.MetricsSnapshot
  59     ) -> Dict[str, Dict[Tuple['cirq.GridQubit', ...], Any]]:
  60         results: Dict[str, Dict[Tuple[devices.
  61                                       GridQubit, ...], Any]] = defaultdict(dict)
  62         for metric in metrics:
  63             name = metric.name
  64             # Flatten the values to a list, removing keys containing type names
  65             # (e.g. proto version of each value is {<type>: value}).
  66             flat_values = [
  67                 getattr(v, v.WhichOneof('val')) for v in metric.values
  68             ]
  69             if metric.targets:
  70                 targets = [
  71                     t[1:] if t.startswith('q') else t for t in metric.targets
  72                 ]
  73                 # TODO: Remove when calibrations don't prepend this.
  74                 # Github issue: https://github.com/quantumlib/Cirq/issues/2963
  75                 qubits = tuple(v2.grid_qubit_from_proto_id(t) for t in targets)
  76                 results[name][qubits] = flat_values
  77             else:
  78                 assert len(results[name]) == 0, (
  79                     'Only one metric of a given name can have no targets. '
  80                     'Found multiple for key {}'.format(name))
  81                 results[name][()] = flat_values
  82         return results
  83 
  84     def __getitem__(self, key: str) -> Dict[Tuple['cirq.GridQubit', ...], Any]:
  85         """Supports getting calibrations by index.
  86 
  87         Calibration may be accessed by key:
  88 
  89             `calibration['t1']`.
  90 
  91         This returns a map from tuples of `cirq.GridQubit`s to a list of the
  92         values of the metric. If there are no targets, the only key will only
  93         be an empty tuple.
  94         """
  95         if not isinstance(key, str):
  96             raise TypeError(
  97                 'Calibration metrics only have string keys. Key was {}'.format(
  98                     key))
  99         if key not in self._metric_dict:
  100             raise KeyError('Metric named {} not in calibration'.format(key))
  101         return self._metric_dict[key]
  102 
  103     def __iter__(self) -> Iterator:
  104         return iter(self._metric_dict)
  105 
  106     def __len__(self) -> int:
  107         return len(self._metric_dict)
  108 
  109     def __str__(self) -> str:
  110 
  111         return 'Calibration(keys={})'.format(list(sorted(self.keys())))
  112 
  113     def timestamp_str(self,
  114                       tz: Optional[datetime.tzinfo] = None,
  115                       timespec: str = 'auto') -> str:
  116         """Return a string for the calibration timestamp.
  117 
  118         Args:
  119             tz: The timezone for the string. If None, the method uses the
  120                 platform's local date and time.
  121             timespec: See datetime.isoformat for valid values.
  122 
  123         Returns:
  124             The string in ISO 8601 format YYYY-MM-DDTHH:MM:SS.ffffff.
  125         """
  126         dt = datetime.datetime.fromtimestamp(self.timestamp / 1000, tz)
  127         dt += datetime.timedelta(microseconds=self.timestamp % 1000000)
  128         return dt.isoformat(sep=' ', timespec=timespec)
  129 
  130     def heatmap(self, key: str) -> vis.Heatmap:
  131         """Return a heatmap for metrics that target single qubits.
  132 
  133         Args:
  134             key: The metric key to return a heatmap for.
  135 
  136         Returns:
  137             A `cirq.Heatmap` for the metric.
  138 
  139         Raises:
  140             AssertionError if the heatmap is not for single qubits or the metric
  141             values are not single floats.
  142         """
  143         metrics = self[key]
  144         assert all(len(k) == 1 for k in metrics.keys()), (
  145             'Heatmaps are only supported if all the targets in a metric'
  146             ' are single qubits.')
  147         assert all(len(k) == 1 for k in metrics.values()), (
  148             'Heatmaps are only supported if all the values in a metric'
  149             ' are single metric values.')
  150         value_map = {qubit: value for (qubit,), (value,) in metrics.items()}
  151         return vis.Heatmap(value_map)
  152
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/cirq/google/engine/calibration.py b/cirq/google/engine/calibration.py
  --- a/cirq/google/engine/calibration.py
  +++ b/cirq/google/engine/calibration.py
  @@ -67,12 +67,8 @@
                   getattr(v, v.WhichOneof('val')) for v in metric.values
               ]
               if metric.targets:
  -                targets = [
  -                    t[1:] if t.startswith('q') else t for t in metric.targets
  -                ]
  -                # TODO: Remove when calibrations don't prepend this.
  -                # Github issue: https://github.com/quantumlib/Cirq/issues/2963
  -                qubits = tuple(v2.grid_qubit_from_proto_id(t) for t in targets)
  +                qubits = tuple(
  +                    v2.grid_qubit_from_proto_id(t) for t in metric.targets)
                   results[name][qubits] = flat_values
               else:
                   assert len(results[name]) == 0, (
  
verification_info: {"golden_diff": "diff --git a/cirq/google/engine/calibration.py b/cirq/google/engine/calibration.py\n--- a/cirq/google/engine/calibration.py\n+++ b/cirq/google/engine/calibration.py\n@@ -67,12 +67,8 @@\n                 getattr(v, v.WhichOneof('val')) for v in metric.values\n             ]\n             if metric.targets:\n-                targets = [\n-                    t[1:] if t.startswith('q') else t for t in metric.targets\n-                ]\n-                # TODO: Remove when calibrations don't prepend this.\n-                # Github issue: https://github.com/quantumlib/Cirq/issues/2963\n-                qubits = tuple(v2.grid_qubit_from_proto_id(t) for t in targets)\n+                qubits = tuple(\n+                    v2.grid_qubit_from_proto_id(t) for t in metric.targets)\n                 results[name][qubits] = flat_values\n             else:\n                 assert len(results[name]) == 0, (\n", "issue": "Update code for when Engine metric qubits are formatted differently\nThere is currently code in calibration.py that looks at qubit ids that start with `q` and removes this `q` before getting the grid qubit.  If the API no longer returns `q` prefixed code this should be removed, otherwise if we are going to continue to support this we should add it to `grid_qubit_from_proto`.\r\n\r\n\n", "before_files": [{"content": "# Copyright 2019 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Calibration wrapper for calibrations returned from the Quantum Engine.\"\"\"\n\nfrom collections import abc, defaultdict\nimport datetime\n\nfrom typing import Any, Dict, Iterator, Optional, Tuple, TYPE_CHECKING\n\nfrom cirq import devices, vis\nfrom cirq.google.api import v2\n\nif TYPE_CHECKING:\n    import cirq\n\n\nclass Calibration(abc.Mapping):\n    \"\"\"A convenience wrapper for calibrations that acts like a dictionary.\n\n    Calibrations act as dictionaries whose keys are the names of the metric,\n    and whose values are the metric values.  The metric values themselves are\n    represented as a dictionary.  These metric value dictionaries have\n    keys that are tuples of `cirq.GridQubit`s and values that are lists of the\n    metric values for those qubits. If a metric acts globally and is attached\n    to no specified number of qubits, the map will be from the empty tuple\n    to the metrics values.\n\n    Calibrations act just like a python dictionary. For example you can get\n    a list of all of the metric names using\n\n        `calibration.keys()`\n\n    and query a single value by looking up the name by index:\n\n        `calibration['t1']`\n\n    Attributes:\n        timestamp: The time that this calibration was run, in milliseconds since\n            the epoch.\n    \"\"\"\n\n    def __init__(self, calibration: v2.metrics_pb2.MetricsSnapshot) -> None:\n        self.timestamp = calibration.timestamp_ms\n        self._metric_dict = self._compute_metric_dict(calibration.metrics)\n\n    def _compute_metric_dict(\n            self, metrics: v2.metrics_pb2.MetricsSnapshot\n    ) -> Dict[str, Dict[Tuple['cirq.GridQubit', ...], Any]]:\n        results: Dict[str, Dict[Tuple[devices.\n                                      GridQubit, ...], Any]] = defaultdict(dict)\n        for metric in metrics:\n            name = metric.name\n            # Flatten the values to a list, removing keys containing type names\n            # (e.g. proto version of each value is {<type>: value}).\n            flat_values = [\n                getattr(v, v.WhichOneof('val')) for v in metric.values\n            ]\n            if metric.targets:\n                targets = [\n                    t[1:] if t.startswith('q') else t for t in metric.targets\n                ]\n                # TODO: Remove when calibrations don't prepend this.\n                # Github issue: https://github.com/quantumlib/Cirq/issues/2963\n                qubits = tuple(v2.grid_qubit_from_proto_id(t) for t in targets)\n                results[name][qubits] = flat_values\n            else:\n                assert len(results[name]) == 0, (\n                    'Only one metric of a given name can have no targets. '\n                    'Found multiple for key {}'.format(name))\n                results[name][()] = flat_values\n        return results\n\n    def __getitem__(self, key: str) -> Dict[Tuple['cirq.GridQubit', ...], Any]:\n        \"\"\"Supports getting calibrations by index.\n\n        Calibration may be accessed by key:\n\n            `calibration['t1']`.\n\n        This returns a map from tuples of `cirq.GridQubit`s to a list of the\n        values of the metric. If there are no targets, the only key will only\n        be an empty tuple.\n        \"\"\"\n        if not isinstance(key, str):\n            raise TypeError(\n                'Calibration metrics only have string keys. Key was {}'.format(\n                    key))\n        if key not in self._metric_dict:\n            raise KeyError('Metric named {} not in calibration'.format(key))\n        return self._metric_dict[key]\n\n    def __iter__(self) -> Iterator:\n        return iter(self._metric_dict)\n\n    def __len__(self) -> int:\n        return len(self._metric_dict)\n\n    def __str__(self) -> str:\n\n        return 'Calibration(keys={})'.format(list(sorted(self.keys())))\n\n    def timestamp_str(self,\n                      tz: Optional[datetime.tzinfo] = None,\n                      timespec: str = 'auto') -> str:\n        \"\"\"Return a string for the calibration timestamp.\n\n        Args:\n            tz: The timezone for the string. If None, the method uses the\n                platform's local date and time.\n            timespec: See datetime.isoformat for valid values.\n\n        Returns:\n            The string in ISO 8601 format YYYY-MM-DDTHH:MM:SS.ffffff.\n        \"\"\"\n        dt = datetime.datetime.fromtimestamp(self.timestamp / 1000, tz)\n        dt += datetime.timedelta(microseconds=self.timestamp % 1000000)\n        return dt.isoformat(sep=' ', timespec=timespec)\n\n    def heatmap(self, key: str) -> vis.Heatmap:\n        \"\"\"Return a heatmap for metrics that target single qubits.\n\n        Args:\n            key: The metric key to return a heatmap for.\n\n        Returns:\n            A `cirq.Heatmap` for the metric.\n\n        Raises:\n            AssertionError if the heatmap is not for single qubits or the metric\n            values are not single floats.\n        \"\"\"\n        metrics = self[key]\n        assert all(len(k) == 1 for k in metrics.keys()), (\n            'Heatmaps are only supported if all the targets in a metric'\n            ' are single qubits.')\n        assert all(len(k) == 1 for k in metrics.values()), (\n            'Heatmaps are only supported if all the values in a metric'\n            ' are single metric values.')\n        value_map = {qubit: value for (qubit,), (value,) in metrics.items()}\n        return vis.Heatmap(value_map)\n", "path": "cirq/google/engine/calibration.py"}], "after_files": [{"content": "# Copyright 2019 The Cirq Developers\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#     https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\"\"\"Calibration wrapper for calibrations returned from the Quantum Engine.\"\"\"\n\nfrom collections import abc, defaultdict\nimport datetime\n\nfrom typing import Any, Dict, Iterator, Optional, Tuple, TYPE_CHECKING\n\nfrom cirq import devices, vis\nfrom cirq.google.api import v2\n\nif TYPE_CHECKING:\n    import cirq\n\n\nclass Calibration(abc.Mapping):\n    \"\"\"A convenience wrapper for calibrations that acts like a dictionary.\n\n    Calibrations act as dictionaries whose keys are the names of the metric,\n    and whose values are the metric values.  The metric values themselves are\n    represented as a dictionary.  These metric value dictionaries have\n    keys that are tuples of `cirq.GridQubit`s and values that are lists of the\n    metric values for those qubits. If a metric acts globally and is attached\n    to no specified number of qubits, the map will be from the empty tuple\n    to the metrics values.\n\n    Calibrations act just like a python dictionary. For example you can get\n    a list of all of the metric names using\n\n        `calibration.keys()`\n\n    and query a single value by looking up the name by index:\n\n        `calibration['t1']`\n\n    Attributes:\n        timestamp: The time that this calibration was run, in milliseconds since\n            the epoch.\n    \"\"\"\n\n    def __init__(self, calibration: v2.metrics_pb2.MetricsSnapshot) -> None:\n        self.timestamp = calibration.timestamp_ms\n        self._metric_dict = self._compute_metric_dict(calibration.metrics)\n\n    def _compute_metric_dict(\n            self, metrics: v2.metrics_pb2.MetricsSnapshot\n    ) -> Dict[str, Dict[Tuple['cirq.GridQubit', ...], Any]]:\n        results: Dict[str, Dict[Tuple[devices.\n                                      GridQubit, ...], Any]] = defaultdict(dict)\n        for metric in metrics:\n            name = metric.name\n            # Flatten the values to a list, removing keys containing type names\n            # (e.g. proto version of each value is {<type>: value}).\n            flat_values = [\n                getattr(v, v.WhichOneof('val')) for v in metric.values\n            ]\n            if metric.targets:\n                qubits = tuple(\n                    v2.grid_qubit_from_proto_id(t) for t in metric.targets)\n                results[name][qubits] = flat_values\n            else:\n                assert len(results[name]) == 0, (\n                    'Only one metric of a given name can have no targets. '\n                    'Found multiple for key {}'.format(name))\n                results[name][()] = flat_values\n        return results\n\n    def __getitem__(self, key: str) -> Dict[Tuple['cirq.GridQubit', ...], Any]:\n        \"\"\"Supports getting calibrations by index.\n\n        Calibration may be accessed by key:\n\n            `calibration['t1']`.\n\n        This returns a map from tuples of `cirq.GridQubit`s to a list of the\n        values of the metric. If there are no targets, the only key will only\n        be an empty tuple.\n        \"\"\"\n        if not isinstance(key, str):\n            raise TypeError(\n                'Calibration metrics only have string keys. Key was {}'.format(\n                    key))\n        if key not in self._metric_dict:\n            raise KeyError('Metric named {} not in calibration'.format(key))\n        return self._metric_dict[key]\n\n    def __iter__(self) -> Iterator:\n        return iter(self._metric_dict)\n\n    def __len__(self) -> int:\n        return len(self._metric_dict)\n\n    def __str__(self) -> str:\n\n        return 'Calibration(keys={})'.format(list(sorted(self.keys())))\n\n    def timestamp_str(self,\n                      tz: Optional[datetime.tzinfo] = None,\n                      timespec: str = 'auto') -> str:\n        \"\"\"Return a string for the calibration timestamp.\n\n        Args:\n            tz: The timezone for the string. If None, the method uses the\n                platform's local date and time.\n            timespec: See datetime.isoformat for valid values.\n\n        Returns:\n            The string in ISO 8601 format YYYY-MM-DDTHH:MM:SS.ffffff.\n        \"\"\"\n        dt = datetime.datetime.fromtimestamp(self.timestamp / 1000, tz)\n        dt += datetime.timedelta(microseconds=self.timestamp % 1000000)\n        return dt.isoformat(sep=' ', timespec=timespec)\n\n    def heatmap(self, key: str) -> vis.Heatmap:\n        \"\"\"Return a heatmap for metrics that target single qubits.\n\n        Args:\n            key: The metric key to return a heatmap for.\n\n        Returns:\n            A `cirq.Heatmap` for the metric.\n\n        Raises:\n            AssertionError if the heatmap is not for single qubits or the metric\n            values are not single floats.\n        \"\"\"\n        metrics = self[key]\n        assert all(len(k) == 1 for k in metrics.keys()), (\n            'Heatmaps are only supported if all the targets in a metric'\n            ' are single qubits.')\n        assert all(len(k) == 1 for k in metrics.values()), (\n            'Heatmaps are only supported if all the values in a metric'\n            ' are single metric values.')\n        value_map = {qubit: value for (qubit,), (value,) in metrics.items()}\n        return vis.Heatmap(value_map)\n", "path": "cirq/google/engine/calibration.py"}]}