Repository: mne-tools/mne-python

Issue:
plotting power topomaps: ValueError: trans must be a Transform between head<->meg, got None
(MNE 0.20.dev0)

I get an error when trying to plot power topomaps for tfrs computed with `mne.time_frequency.tfr_morlet`: 

```
 File "/home/sh254795/anaconda3/lib/python3.7/site-packages/mne/transforms.py", line 428, in _ensure_trans
    raise ValueError('%s None' % err_str)

ValueError: trans must be a Transform between head<->meg, got None
```

I traced it down to transforms.py, line 427 (in def _ensure_trans), where apparently my existing trans is not recognised as such: 

```
not isinstance(this_trans, Transform)
True

this_trans
{'from': 1, 'to': 4, 'trans': array([[ 0.99812019, -0.06127739, -0.00142468,  0.00122047],
       [ 0.06122039,  0.99779153, -0.02579   ,  0.01071874],
       [ 0.00300188,  0.02565429,  0.99966681,  0.03850674],
       [ 0.        ,  0.        ,  0.        ,  1.        ]])}

```

Why is the trans not recognized?
I can share the file if you need.

Thanks!


Discussion:
Yes please share the file. It's probably an issue that we write out the `Transform` (which h5io will turn into 
 a dict) but do not cast it back to a `Transform` on read.
You are right, it comes from the saving & reading. Directly after computing the tfr, I can plot the topo. I sent you a download link for the file per email (no other option here).

Here is what I do to save / read:
```
power.save('TMP-tfr.h5', overwrite=True)
power = mne.time_frequency.read_tfrs('TMP-tfr.h5')
power = power.pop()
```
I'm thinking that we'll want to start a `_dict_to_info` function that can be used any time there is an `info` object save-loaded round-trip using h5io. So far the only thing it would need to do is:
```
def _dict_to_info(info):
    info = Info(info)
    if info['dev_head_t'] is not None:
         info['dev_head_t'] = Transform(**info['dev_head_t'])
    return info
```
@SophieHerbst can you see if this would fix your problem if you put this function in `mne/io/meas_info.py` and import and use it in the right place in `mne/time_frequency/tfr.py`?
It gives me an error: 
> Transform(**info['dev_head_t'])
> *** TypeError: __init__() got an unexpected keyword argument 'from'

Okay you'll have to dig in a bit. Maybe do:
```
orig = info['dev_head_t']
info['dev_head_t'] = Transform(orig['from'], orig['to'], orig['trans'])
```
This might not work either, though, and require further work. I was mostly just trying to give you hints to get you enough to get started -- but if you don't want to debug this let me know and I can work on a PR directly
I don't think I have sufficient understanding of the transform function to debug this quickly, so it would be great if you could have a look. 
Here is the code that produces the error (@agramfort asked for it):

```
import mne

power = mne.time_frequency.read_tfrs('TMP-tfr.h5')
power = power.pop()

power.plot_topomap()
```

Resolving patch:
diff --git a/mne/io/meas_info.py b/mne/io/meas_info.py
--- a/mne/io/meas_info.py
+++ b/mne/io/meas_info.py
@@ -530,6 +530,12 @@ class Info(dict, MontageMixin):
             The helium level meas date.
     """
 
+    def __init__(self, *args, **kwargs):
+        super(Info, self).__init__(*args, **kwargs)
+        t = self.get('dev_head_t', None)
+        if t is not None and not isinstance(t, Transform):
+            self['dev_head_t'] = Transform(t['from'], t['to'], t['trans'])
+
     def copy(self):
         """Copy the instance.
 


Test patch:
diff --git a/mne/tests/test_docstring_parameters.py b/mne/tests/test_docstring_parameters.py
--- a/mne/tests/test_docstring_parameters.py
+++ b/mne/tests/test_docstring_parameters.py
@@ -63,6 +63,7 @@ def _func_name(func, cls=None):
     'mne.externals',
     'mne.fixes',
     'mne.io.write',
+    'mne.io.meas_info.Info',
 }
 char_limit = 800  # XX eventually we should probably get this lower
 tab_ignores = [
diff --git a/mne/time_frequency/tests/test_tfr.py b/mne/time_frequency/tests/test_tfr.py
--- a/mne/time_frequency/tests/test_tfr.py
+++ b/mne/time_frequency/tests/test_tfr.py
@@ -9,7 +9,8 @@
 import matplotlib.pyplot as plt
 
 import mne
-from mne import Epochs, read_events, pick_types, create_info, EpochsArray
+from mne import (Epochs, read_events, pick_types, create_info, EpochsArray,
+                 Info, Transform)
 from mne.io import read_raw_fif
 from mne.utils import (_TempDir, run_tests_if_main, requires_h5py,
                        requires_pandas, grand_average)
@@ -413,6 +414,8 @@ def test_io():
                      nave=20, comment='test', method='crazy-tfr')
     tfr.save(fname)
     tfr2 = read_tfrs(fname, condition='test')
+    assert isinstance(tfr2.info, Info)
+    assert isinstance(tfr2.info['dev_head_t'], Transform)
 
     assert_array_equal(tfr.data, tfr2.data)
     assert_array_equal(tfr.times, tfr2.times)