Repository: gwastro/pycbc

Issue:
Latest numpy (1.14) breaks some recarray usage in inference code
Recent Travis tests, e.g. reported by @spxiwh, have been failing on inference tests with errors like this:
```
Traceback (most recent call last):
  File "test/test_inference.py", line 175, in test_sampler
    s.set_p0()
  File "/home/travis/build/pycbc-build/environment/lib/python2.7/site-packages/PyCBC-9ed561-py2.7.egg/pycbc/inference/sampler_base.py", line 377, in set_p0
    prior=prior)
  File "/home/travis/build/pycbc-build/environment/lib/python2.7/site-packages/PyCBC-9ed561-py2.7.egg/pycbc/inference/likelihood.py", line 353, in prior_rvs
    p0 = prior.rvs(size=size)
  File "/home/travis/build/pycbc-build/environment/lib/python2.7/site-packages/PyCBC-9ed561-py2.7.egg/pycbc/distributions/joint.py", line 186, in rvs
    out[n] = vals
  File "/home/travis/build/pycbc-build/environment/lib/python2.7/site-packages/PyCBC-9ed561-py2.7.egg/pycbc/io/record.py", line 819, in __setitem__
    fields = item.split('.')
AttributeError: 'int' object has no attribute 'split'
```
Such tests appear to be using numpy 1.14. I tracked the error down to a recent change in how recarray indexing works. The following code works on previous numpy versions:
```
In [2]: x = np.recarray(10, dtype=[('a', float), ('b', float)])
In [3]: x
Out[3]:
rec.array([(  6.90659896e-310,   4.67261138e-310),
 (  6.90659011e-310,   6.90659011e-310),
 (  6.90659026e-310,   6.90659011e-310),
 (  6.90659011e-310,   6.90659010e-310),
 (  6.90659010e-310,   6.90659010e-310),
 (  6.90659010e-310,   6.90659010e-310),
 (  6.90659010e-310,   6.90659010e-310),
 (  6.90659010e-310,   6.90659010e-310),
 (  2.12199579e-314,   1.63041663e-322),
 (  4.67261128e-310,   6.90659896e-310)],
          dtype=[('a', '<f8'), ('b', '<f8')])
In [4]: x[0] = np.array([10, 10], dtype=float)
In [5]: x
Out[5]:
rec.array([(  1.00000000e+001,   1.00000000e+001),
 (  6.90659011e-310,   6.90659011e-310),
 (  6.90659026e-310,   6.90659011e-310),
 (  6.90659011e-310,   6.90659010e-310),
 (  6.90659010e-310,   6.90659010e-310),
 (  6.90659010e-310,   6.90659010e-310),
 (  6.90659010e-310,   6.90659010e-310),
 (  6.90659010e-310,   6.90659010e-310),
 (  2.12199579e-314,   1.63041663e-322),
 (  4.67261128e-310,   6.90659896e-310)],
          dtype=[('a', '<f8'), ('b', '<f8')])
```
With numpy 1.14, I get instead:
```
In [4]: x = np.recarray(10, dtype=[('a', float), ('b', float)])
In [5]: x
Out[5]:
rec.array([(6.91248473e-310, 1.61123977e-316),
           (6.91248356e-310, 6.91248444e-310),
           (6.91248357e-310, 6.91248539e-310),
           (6.91248540e-310, 6.91248539e-310),
           (6.91248539e-310, 6.91248536e-310),
           (6.91248102e-310, 6.91248102e-310),
           (6.91248102e-310, 6.91248536e-310),
           (6.91248538e-310, 6.91248540e-310),
           (6.91248540e-310, 6.91248540e-310),
           (6.91248540e-310, 6.91248381e-310)],
          dtype=[('a', '<f8'), ('b', '<f8')])
In [6]: x[0] = np.array([10, 10], dtype=float)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-6-30234bdfd18a> in <module>()
----> 1 x[0] = np.array([10, 10], dtype=float)
ValueError: setting an array element with a sequence.
```
The ValueError causes the logic in `FieldArray.__setitem__` to be incorrect.


Discussion:
However, using a tuple instead of a numpy array continues to work: `x[0] = (10., 10.)`.

Resolving patch:
diff --git a/pycbc/inference/sampler_mcmc.py b/pycbc/inference/sampler_mcmc.py
--- a/pycbc/inference/sampler_mcmc.py
+++ b/pycbc/inference/sampler_mcmc.py
@@ -161,7 +161,8 @@ def run(self, niterations):
             blob = self._lastblob
 
         self._chain = numpy.empty(niterations,dtype=self.dtype)
-        self._chain[start] = start_sample
+        # numpy >=1.14 only accepts tuples
+        self._chain[start] = tuple(start_sample)
         self._blobs = [None]*niterations
         self._blobs[start] = blob
 
diff --git a/pycbc/io/record.py b/pycbc/io/record.py
--- a/pycbc/io/record.py
+++ b/pycbc/io/record.py
@@ -811,6 +811,9 @@ def __setitem__(self, item, values):
         """Wrap's recarray's setitem to allow attribute-like indexing when
         setting values.
         """
+        if type(item) is int and type(values) is numpy.ndarray:
+            # numpy >=1.14 only accepts tuples
+            values = tuple(values)
         try:
             return super(FieldArray, self).__setitem__(item, values)
         except ValueError:


Test patch: