nansencenter / DAPPER

Data Assimilation with Python: a Package for Experimental Research

Home Page:https://nansencenter.github.io/DAPPER

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

De-indent level 1 of HMM print

patnr opened this issue · comments

To much whitespace is being used when printing HMMs

Would add printopts improve the representation? Am I missing your point?

diff --git a/dapper/mods/__init__.py b/dapper/mods/__init__.py
index fd965bb..ea7addc 100644
--- a/dapper/mods/__init__.py
+++ b/dapper/mods/__init__.py
@@ -181,7 +181,7 @@ class HiddenMarkovModel(struct_tools.NicePrint):
     @property
     def Ny(self): return self.Obs.M

-    printopts = {'ordering': ['Dyn', 'Obs', 't', 'X0']}
+    printopts = {'ordering': ['Dyn', 'Obs', 't', 'X0'], "indent": 0}

     def simulate(self, desc='Truth & Obs'):
         """Generate synthetic truth and observations."""

Previously:

>>> from dapper.mods.Lorenz63.sakov2012 import HMM
>>> HMM
HiddenMarkovModel({
                            'Dyn': Operator({
                                                  'M': 3,
                                              'model': rk4 integration of <function dapper.mods.Lorenz63.dxdt(x)>()
                                                        <NamedFunc of step>,
                                              'noise': GaussRV({
                                                                'mu': array([0., 0., 0.]),
                                                                 'M': 3,
                                                                 'C': 0
                                                               }),
                                             'linear': <function dstep_dx at 0x7f5ec1bd90d0>
                                            }),
                            'Obs': Operator({
                                                     'M': 3,
                                                 'model': <function partial_Id_Obs.<locals>.model at 0x7f5ec1bd9280>,
                                                 'noise': GaussRV({
                                                                    'C': <CovMat>
                                                                               M: 3
                                                                            kind: 'diag'
                                                                           trunc: 1.0
                                                                              rk: 3
                                                                            full:
                                                                              [[2. 0. 0.]
                                                                               [0. 2. 0.]
                                                                               [0. 0. 2.]]
                                                                            diag:
                                                                               [2. 2. 2.],
                                                                   'mu': array([0., 0., 0.]),
                                                                    'M': 3
                                                                  }),
                                                'linear': <function partial_Id_Obs.<locals>.linear at 0x7f5ec1bd9310>,
                                             'localizer': <function no_localization.<locals>.localization_now at
                                                           0x7f5ec1b7ac10>
                                            }),
                              't': <Chronology>
                                     -      K: 25025
                                     -   KObs: 1000
                                     -      T: 250.25
                                     - BurnIn: 16.0
                                     -  dtObs: 0.25
                                     -     dt: 0.01,
                             'X0': GaussRV({
                                             'C': <CovMat>
                                                        M: 3
                                                     kind: 'diag'
                                                    trunc: 1.0
                                                       rk: 3
                                                     full:
                                                       [[2. 0. 0.]
                                                        [0. 2. 0.]
                                                        [0. 0. 2.]]
                                                     diag:
                                                        [2. 2. 2.],
                                            'mu': array([ 1.509, -1.531, 25.46 ]),
                                             'M': 3
                                           }),
                   'liveplotters': [(1, <class 'dapper.tools.liveplotting.correlations'>), (1, <function
                                    sliding_marginals.<locals>.init at 0x7f5ec1b7aca0>), (1, <function
                                    phase_particles.<locals>.init at 0x7f5ec1b7ad30>)],
                        'sectors': {},
                           'name': 'Lorenz63/sakov2012.py'
                  })
>>> print(HMM)

  -          Dyn:   -      M: 3
                ¦   -  model: rk4 integration of <function dapper.mods.Lorenz63.dxdt(x)>()
                ¦   -  noise:   - mu: [0. 0. 0.]
                ¦           ¦   -  M: 3
                ¦           ¦   -  C: 0
                ¦   - linear: <function dstep_dx at 0x7f5ec1bd90d0>
  -          Obs:   -         M: 3
                ¦   -     model: <function partial_Id_Obs.<locals>.model at 0x7f5ec1bd9280>
                ¦   -     noise:   -  C: <CovMat>
                ¦              ¦       ¦       M: 3
                ¦              ¦       ¦    kind: 'diag'
                ¦              ¦       ¦   trunc: 1.0
                ¦              ¦       ¦      rk: 3
                ¦              ¦       ¦    full:
                ¦              ¦       ¦      [[2. 0. 0.]
                ¦              ¦       ¦       [0. 2. 0.]
                ¦              ¦       ¦       [0. 0. 2.]]
                ¦              ¦       ¦    diag:
                ¦              ¦       ¦       [2. 2. 2.]
                ¦              ¦   - mu: [0. 0. 0.]
                ¦              ¦   -  M: 3
                ¦   -    linear: <function partial_Id_Obs.<locals>.linear at 0x7f5ec1bd9310>
                ¦   - localizer: <function no_localization.<locals>.localization_now at 0x7f5ec1b7ac10>
  -            t:   -      K: 25025
                ¦   -   KObs: 1000
                ¦   -      T: 250.25
                ¦   - BurnIn: 16.0
                ¦   -  dtObs: 0.25
                ¦   -     dt: 0.01
  -           X0:   -  C: <CovMat>
                ¦       ¦       M: 3
                ¦       ¦    kind: 'diag'
                ¦       ¦   trunc: 1.0
                ¦       ¦      rk: 3
                ¦       ¦    full:
                ¦       ¦      [[2. 0. 0.]
                ¦       ¦       [0. 2. 0.]
                ¦       ¦       [0. 0. 2.]]
                ¦       ¦    diag:
                ¦       ¦       [2. 2. 2.]
                ¦   - mu: [ 1.509 -1.531 25.46 ]
                ¦   -  M: 3
  - liveplotters: [(1, <class 'dapper.tools.liveplotting.correlations'>), (1, <function sliding_marginals.<locals>.init
                ¦  at 0x7f5ec1b7aca0>), (1, <function phase_particles.<locals>.init at 0x7f5ec1b7ad30>)]
  -      sectors: {}
  -         name: Lorenz63/sakov2012.py

Now:

>>> from dapper.mods.Lorenz63.sakov2012 import HMM
>>> HMM
HiddenMarkovModel({
                   'Dyn':
                    Operator({
                                   'M': 3,
                               'model': rk4 integration of <function dapper.mods.Lorenz63.dxdt(x)>() <NamedFunc of
                                         step>,
                               'noise': GaussRV({
                                                 'mu': array([0., 0., 0.]),
                                                  'M': 3,
                                                  'C': 0
                                                }),
                              'linear': <function dstep_dx at 0x7f97eb5990d0>
                             }),
                   'Obs':
                    Operator({
                                      'M': 3,
                                  'model': <function partial_Id_Obs.<locals>.model at 0x7f97eb599280>,
                                  'noise': GaussRV({
                                                     'C': <CovMat>
                                                                M: 3
                                                             kind: 'diag'
                                                            trunc: 1.0
                                                               rk: 3
                                                             full:
                                                               [[2. 0. 0.]
                                                                [0. 2. 0.]
                                                                [0. 0. 2.]]
                                                             diag:
                                                                [2. 2. 2.],
                                                    'mu': array([0., 0., 0.]),
                                                     'M': 3
                                                   }),
                                 'linear': <function partial_Id_Obs.<locals>.linear at 0x7f97eb599310>,
                              'localizer': <function no_localization.<locals>.localization_now at 0x7f97eb540c10>
                             }),
                   't':
                    <Chronology>
                      -      K: 25025
                      -   KObs: 1000
                      -      T: 250.25
                      - BurnIn: 16.0
                      -  dtObs: 0.25
                      -     dt: 0.01,
                   'X0':
                    GaussRV({
                              'C': <CovMat>
                                         M: 3
                                      kind: 'diag'
                                     trunc: 1.0
                                        rk: 3
                                      full:
                                        [[2. 0. 0.]
                                         [0. 2. 0.]
                                         [0. 0. 2.]]
                                      diag:
                                         [2. 2. 2.],
                             'mu': array([ 1.509, -1.531, 25.46 ]),
                              'M': 3
                            }),
                   'liveplotters':
                    [(1, <class 'dapper.tools.liveplotting.correlations'>), (1, <function
                     sliding_marginals.<locals>.init at 0x7f97eb540ca0>), (1, <function
                     phase_particles.<locals>.init at 0x7f97eb540d30>)],
                   'sectors': {},
                   'name': 'Lorenz63/sakov2012.py'
                  })
>>> print(HMM)

  - Dyn:
    ¦  -      M: 3
    ¦  -  model: rk4 integration of <function dapper.mods.Lorenz63.dxdt(x)>()
    ¦  -  noise:   - mu: [0. 0. 0.]
    ¦          ¦   -  M: 3
    ¦          ¦   -  C: 0
    ¦  - linear: <function dstep_dx at 0x7f97eb5990d0>
  - Obs:
    ¦  -         M: 3
    ¦  -     model: <function partial_Id_Obs.<locals>.model at 0x7f97eb599280>
    ¦  -     noise:   -  C: <CovMat>
    ¦             ¦       ¦       M: 3
    ¦             ¦       ¦    kind: 'diag'
    ¦             ¦       ¦   trunc: 1.0
    ¦             ¦       ¦      rk: 3
    ¦             ¦       ¦    full:
    ¦             ¦       ¦      [[2. 0. 0.]
    ¦             ¦       ¦       [0. 2. 0.]
    ¦             ¦       ¦       [0. 0. 2.]]
    ¦             ¦       ¦    diag:
    ¦             ¦       ¦       [2. 2. 2.]
    ¦             ¦   - mu: [0. 0. 0.]
    ¦             ¦   -  M: 3
    ¦  -    linear: <function partial_Id_Obs.<locals>.linear at 0x7f97eb599310>
    ¦  - localizer: <function no_localization.<locals>.localization_now at 0x7f97eb540c10>
  - t:
    ¦  -      K: 25025
    ¦  -   KObs: 1000
    ¦  -      T: 250.25
    ¦  - BurnIn: 16.0
    ¦  -  dtObs: 0.25
    ¦  -     dt: 0.01
  - X0:
    ¦  -  C: <CovMat>
    ¦      ¦       M: 3
    ¦      ¦    kind: 'diag'
    ¦      ¦   trunc: 1.0
    ¦      ¦      rk: 3
    ¦      ¦    full:
    ¦      ¦      [[2. 0. 0.]
    ¦      ¦       [0. 2. 0.]
    ¦      ¦       [0. 0. 2.]]
    ¦      ¦    diag:
    ¦      ¦       [2. 2. 2.]
    ¦  - mu: [ 1.509 -1.531 25.46 ]
    ¦  -  M: 3
  - liveplotters:
    ¦[(1, <class 'dapper.tools.liveplotting.correlations'>), (1, <function sliding_marginals.<locals>.init
    ¦ at 0x7f97eb540ca0>), (1, <function phase_particles.<locals>.init at 0x7f97eb540d30>)]
  - sectors: {}
  - name: Lorenz63/sakov2012.py

Here is a __repr__ function to de-indent level 1 HMM without change struct_tools.

def __repr__(self):
        s = struct_tools.NicePrint.__repr__(self)
        s = s.split("\n")
        len_level_one = min(len(s_element) - len(s_element.lstrip()) for s_element in s[1:])
        s = [s[0]] + [s_element[len_level_one :] for s_element in s[1:]]
        return "\n".join(s)

Result:

HiddenMarkovModel({
 'Dyn':
  Operator({
                 'M': 3,
             'model': rk4 integration of <function dapper.mods.Lorenz63.dxdt(x)>() <NamedFunc of
                       step>,
             'noise': GaussRV({
                               'mu': array([0., 0., 0.]),
                                'M': 3,
                                'C': 0
                              }),
            'linear': <function dstep_dx at 0x7fc265aaae50>
           }),
 'Obs':
  Operator({
                    'M': 3,
                'model': <function partial_Id_Obs.<locals>.model at 0x7fc265aaaf70>,
                'noise': GaussRV({
                                   'C': <CovMat>
                                              M: 3
                                           kind: 'diag'
                                          trunc: 1.0
                                             rk: 3
                                           full:
                                             [[2. 0. 0.]
                                              [0. 2. 0.]
                                              [0. 0. 2.]]
                                           diag:
                                              [2. 2. 2.],
                                  'mu': array([0., 0., 0.]),
                                   'M': 3
                                 }),
               'linear': <function partial_Id_Obs.<locals>.linear at 0x7fc265ab9040>,
            'localizer': <function no_localization.<locals>.localization_now at 0x7fc265a60af0>
           }),
 't':
  <Chronology>
    -      K: 25025
    -   KObs: 1000
    -      T: 250.25
    - BurnIn: 16.0
    -  dtObs: 0.25
    -     dt: 0.01,
 'X0':
  GaussRV({
            'C': <CovMat>
                       M: 3
                    kind: 'diag'
                   trunc: 1.0
                      rk: 3
                    full:
                      [[2. 0. 0.]
                       [0. 2. 0.]
                       [0. 0. 2.]]
                    diag:
                       [2. 2. 2.],
           'mu': array([ 1.509, -1.531, 25.46 ]),
            'M': 3
          }),
 'liveplotters':
  [(1, <class 'dapper.tools.liveplotting.correlations'>), (1, <function
   sliding_marginals.<locals>.init at 0x7fc265a60b80>), (1, <function
   phase_particles.<locals>.init at 0x7fc265a60c10>)],
 'sectors': {},
 'name': 'Lorenz63/sakov2012.py'
})

Yes, precisely. The first suggestion looks great.

I don't know what you mean about

without change struct_tools.

since you just set the printopts in the first suggestion.

Sorry for the clarity issue.

repr is controlled by NicePrint. Here I simply add one repr function for HMM and does not change anything in NicePrint.

I think I got that. But in your first suggestion you didn't change NicePrint either, right? You just set printopts.

I didn't change NicePrint in my first comment. My first comment doesn't change anything but the printopts and the first level indentation is kept.
The second comment modifies the __repr__, which results in the de-indentation of the first levels.

Ok, well, then I think the first suggestion is all that is needed. It looks great!

And sorry that (once again) I was not sufficiently verbose in stating the issue.

Thanks. Since it is a minor change, I won't create a pull request for this. 😄

You're still committing this somewhere, right?

No, I didn't commit this change.

Ok, I'll add it then

BTW, I finally understood the effect of your 2nd suggestion :-)

However, I think I will change struct-tools instead.

BTW, I finally understood the effect of your 2nd suggestion :-)

However, I think I will change struct-tools instead.

That's good. The 2nd comment was mainly for the large space of repr due to the long name of HiddenMarkovModel. Looking at the output, I think the issue perhaps also appears for the Operator.

If you'd like to modify struct-tools, which is not public after you group them into another package, I think, maybe it would be better to give a max-length for the indentation, instead of relying completely on the length of the key of the dictionary.

Latest commit requires re-install (since struct-tools was upgraded).

I've added your suggestion as a Todo for struct-tools, but don't quite have time for it now. I suspect I will open-source it soon though.