From 7666a1f20dd913fa1971acf136c8866dfe1b23c1 Mon Sep 17 00:00:00 2001
From: "valentin.emiya" <valentin.emiya@lif.univ-mrs.fr>
Date: Tue, 12 Jun 2018 15:41:48 +0200
Subject: [PATCH] minor updates in mad_array class and tutorial

---
 doc/_notebooks/mad_array.ipynb | 38 +++++++++++++++++++++--
 madarrays/mad_array.py         | 55 +++++++++++++++++++++-------------
 2 files changed, 71 insertions(+), 22 deletions(-)

diff --git a/doc/_notebooks/mad_array.ipynb b/doc/_notebooks/mad_array.ipynb
index b380e7d..3914bec 100644
--- a/doc/_notebooks/mad_array.ipynb
+++ b/doc/_notebooks/mad_array.ipynb
@@ -70,8 +70,8 @@
     "\n",
     "The masking of data differs according to the type of entries:\n",
     "\n",
-    "* if the entries are *int* or *float*, the masking is done exclusively by giving aa boolean array of the same size of the data as argument `mask`, each entry indicating if the corresponding entry in the data array is missing or not\n",
-    "* if the entries are *complex*, the masking can be done as previously, or by giving boolean arrays of the same size of the data as arguments `mask_amplitude` and `mask_phase`, each entry indicating respectively if the magnitude and the phase of the corresponding entry is missing or not."
+    "* if the data entries are not *complex* (e.g., *int* or *float*), argument `mask` must be exclusively a boolean array with the same shape as the data array, each entry indicating if the corresponding entry in the data array is missing or not;\n",
+    "* if the data entries are *complex*, the masking can be done as previously, or by setting argument `complex_masking` to `true` and by giving two boolean arrays `mask_magnitude` and `mask_phase` with the same size with the same shape as the data array, each entry indicating respectively if the magnitude and the phase of the corresponding entry is missing or not."
    ]
   },
   {
@@ -163,6 +163,31 @@
     "print('{} - {}'.format(str(Am3), repr(Am3)))"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "For complex data:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import madarrays\n",
+    "complex_data = np.random.rand(4, 6) + 1j * np.random.rand(4, 6)\n",
+    "mask_mag = np.random.random(data.shape) < 0.5\n",
+    "mask_pha = np.random.random(data.shape) < 0.5\n",
+    "A_cpx1 = MadArray(complex_data, mask)\n",
+    "A_cpx2 = MadArray(complex_data, mask_magnitude=mask_mag, mask_phase=mask_pha, complex_masking=True)\n",
+    "print('{} - {}'.format(str(A_cpx1), repr(A_cpx1)))\n",
+    "print('{} - {}'.format(str(A_cpx2), repr(A_cpx2)))\n",
+    "print('Magnitude mask', mask_mag)\n",
+    "print('Phase mask', mask_pha)"
+   ]
+  },
   {
    "cell_type": "markdown",
    "metadata": {
@@ -345,6 +370,15 @@
     "print(np.mean(A))\n",
     "print(np.mean(Am))"
    ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
   }
  ],
  "metadata": {
diff --git a/madarrays/mad_array.py b/madarrays/mad_array.py
index 5555a5e..543b61a 100644
--- a/madarrays/mad_array.py
+++ b/madarrays/mad_array.py
@@ -50,8 +50,9 @@ import numpy as np
 
 
 def _merge_masks(ma1, ma2):
-    """Merge the masks of two MadArray objects and return the arguments used
-    for initialisation of the resulting MadArray.
+    """Merge the masks of two :class:`MadArray` objects and return the
+    arguments used for initialisation of the resulting :class:`MadArray`
+    object.
 
     Parameters
     ----------
@@ -63,7 +64,8 @@ def _merge_masks(ma1, ma2):
     Returns
     -------
     dict
-        Arguments to be used for the initialisation of a MadArray.
+        Arguments to be used for the initialisation of a :class:`MadArray`
+        object.
     """
     if ma1._complex_masking or ma2._complex_masking:
 
@@ -134,24 +136,28 @@ class MadArray(np.ndarray):
         * *3* if the magnitude and the phase are masked (unknown magnitude and
           phase).
 
-      This mode is selected by setting :paramref:`complex_masking` to True.
-      Entries are converted to a complex type.
+      This mode is selected by setting :paramref:`complex_masking` to `True`.
+      Entries are converted to a complex type. If entries are complex values
+      and paramref:`complex_masking` is `False`, both the magnitude and
+      phase are masked.
 
     .. _indexing_madarray:
 
-    **Indexing**: two different mode to index a MadArray are implemented:
+    **Indexing**: two different modes to index a :class:`MadArray` object are
+    implemented:
 
-    * a MadArray array of shape corresponding to the indices is returned, with
-      both the data matrix and the mask properly indexed. This is the default
-      mode;
-    * a MadArray with the shape unchanged is returned, where non-indexed
-      entries are set as masked. This mode is selected by setting the parameter
-      :paramref:`masked_indexing` to True.
+    * a :class:`MadArray` object with shape corresponding to the indices is
+    returned, with both the data matrix and the mask properly indexed. This
+    is the default mode;
+    * a :class:`MadArray` object with unchanged shape is returned,
+    where non-indexed entries are set as masked. This mode is selected by
+    setting the parameter :paramref:`masked_indexing` to True.
 
     .. _numpy_behaviour_madarray:
 
     **Numpy behaviour**: it is possible to use standard operations (+, -, /,
-    //, \*, T) between two :class:`MadArray`, likewise operations between numpy
+    //, \*, T) between two :class:`MadArray` objects, likewise operations
+    between numpy
     arrays. The resulting object has a mask consisting of the union of the
     operands. It is also possible to use pickle operations to jointly store the
     data and the mask.
@@ -190,10 +196,10 @@ class MadArray(np.ndarray):
     Notes
     -----
     This class implements an alternative masked array different from
-    np.ma.MadArray. The reason of this choice is that it is only used as a
-    container of a ndarray and a mask. No masked operations are needed.
+    :class:`np.ma.MaskedArray`. The reason of this choice is that it is only
+    used as a container of a ndarray and a mask. No masked operations are
+    needed.
     """
-
     def __new__(cls, data, mask=None, mask_magnitude=None, mask_phase=None,
                 masked_indexing=None, complex_masking=None, **kwargs):
 
@@ -703,11 +709,20 @@ class MadArray(np.ndarray):
         if np.issubdtype(self.dtype, np.integer):
             arr_str = arr_str.replace('.', '')
 
-        string = 'MadArray, dtype={}, {} missing entries ({:.1f}%)\n{}'
+        if self._complex_masking:
+            string = 'MadArray, dtype={0},' \
+                     '{1[0]} missing magnitudes ({2[0]:.1%}) ' \
+                     'and {1[1]} missing phases ({2[1]:.1%})\n{3}'
+            return string.format(self.dtype,
+                                 self.n_missing_data,
+                                 self.ratio_missing_data,
+                                 arr_str)
+        else:
+            string = 'MadArray, dtype={}, {} missing entries ({:.1%})\n{}'
 
-        return string.format(self.dtype,
-                             self.n_missing_data,
-                             100 * self.ratio_missing_data, arr_str)
+            return string.format(self.dtype,
+                                 self.n_missing_data,
+                                 self.ratio_missing_data, arr_str)
 
     def __repr__(self):
         string = '<MadArray at {}>'
-- 
GitLab