mutis.correlation   C
last analyzed

Complexity

Total Complexity 54

Size/Duplication

Total Lines 502
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 54
eloc 309
dl 0
loc 502
rs 6.4799
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A Correlation.__init__() 0 43 1
A Correlation.gen_synth() 0 16 1
B Correlation.peak_find() 0 37 5
A Correlation.plot_times() 0 50 3
B Correlation.plot_corr() 0 62 8
F Correlation.gen_corr() 0 187 29
A Correlation.gen_times() 0 38 5
A Correlation.plot_signals() 0 27 2

How to fix   Complexity   

Complexity

Complex classes like mutis.correlation often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# Licensed under a 3-clause BSD style license - see LICENSE
2
"""Analysis of correlation of light curves."""
3
4
import logging
5
6
import matplotlib.pyplot as plt
0 ignored issues
show
introduced by
Unable to import 'matplotlib.pyplot'
Loading history...
7
import numpy as np
0 ignored issues
show
introduced by
Unable to import 'numpy'
Loading history...
8
import scipy as sp
0 ignored issues
show
introduced by
Unable to import 'scipy'
Loading history...
9
10
from mutis.lib.correlation import *
0 ignored issues
show
Unused Code introduced by
get_grid was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
ndcf was imported with wildcard, but is not used.
Loading history...
Coding Style introduced by
The usage of wildcard imports like mutis.lib.correlation should generally be avoided.
Loading history...
Unused Code introduced by
guvectorize was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
vectorize was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
float64 was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
jit was imported with wildcard, but is not used.
Loading history...
11
12
from mutis.lib.utils import interp_smooth_curve
13
14
15
__all__ = ["Correlation"]
16
17
log = logging.getLogger(__name__)
18
19
20
class Correlation:
0 ignored issues
show
best-practice introduced by
Too many instance attributes (22/7)
Loading history...
21
    """Analysis of the correlation of two signals.
22
23
    Parameters
24
    ----------
25
    signal1 : :class:`~mutis.signal.Signal`
26
        Values of the time axis.
27
    signal2 : :class:`~mutis.signal.Signal`
28
        Values of the signal axis.
29
    fcorr : :py:class:`~str`
30
        Method used to correlate the signals.
31
    """
32
33
    def __init__(self, signal1, signal2, fcorr):
34
        self.signal1 = signal1
35
        self.signal2 = signal2
36
        self.fcorr = fcorr
37
38
        self.times = np.array([])
39
        self.dts = np.array([])
40
        self.nb = np.array([])
0 ignored issues
show
Coding Style Naming introduced by
Attribute name "nb" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
41
        self.values = None
42
43
        # TODO: have a much smaller set of attributes
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
44
        self.samples = None
45
        # storage of the significance limits of the correlation
46
        self.l1s = None
47
        self.l2s = None
48
        self.l3s = None
49
        # storage of the uncertainties of the correlation
50
        self.s1s = None
51
        self.s2s = None
52
        self.s3s = None
53
54
        # attributes indicating the ranges where the correlations are defined
55
        t1, t2 = self.signal1.times, self.signal2.times
0 ignored issues
show
Coding Style Naming introduced by
Variable name "t2" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Variable name "t1" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
56
        self.tmin_full = t2.min() - t1.max()
57
        self.tmax_full = t2.max() - t1.min()
58
        self.t0_full = (self.tmax_full + self.tmin_full) / 2
59
        self.tmin_same = -(np.max([t1.max() - t1.min(), t2.max() - t2.min()])) / 2 + self.t0_full
60
        self.tmax_same = (np.max([t1.max() - t1.min(), t2.max() - t2.min()])) / 2 + self.t0_full
61
        self.tmin_valid = (
62
            -(
63
                np.max([t1.max() - t1.min(), t2.max() - t2.min()])
64
                - np.min([t1.max() - t1.min(), t2.max() - t2.min()])
65
            )
66
            / 2
67
            + self.t0_full
68
        )
69
        self.tmax_valid = (
70
            +(
71
                np.max([t1.max() - t1.min(), t2.max() - t2.min()])
72
                - np.min([t1.max() - t1.min(), t2.max() - t2.min()])
73
            )
74
            / 2
75
            + self.t0_full
76
        )
77
78
    def peak_find(self, smooth=False, smooth_std=None, Ninterp=1000):
0 ignored issues
show
Coding Style Naming introduced by
Argument name "Ninterp" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Comprehensibility introduced by
This function exceeds the maximum number of variables (23/15).
Loading history...
79
        """Find the peaks of the correlation, optionally smoothing with a kernel of standard deviation `s`.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (107/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
80
        Returns dict with peak positions and significances, ordered from closest to farthest from zero.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (103/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
81
        """
82
        x, y = self.times, self.values
0 ignored issues
show
Coding Style Naming introduced by
Variable name "x" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Variable name "y" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
83
84
        if smooth_std is None:
85
            dt1 = np.mean(self.signal1.times[1:]-self.signal1.times[:-1])
86
            std1 = np.std(self.signal1.times[1:]-self.signal1.times[:-1])
0 ignored issues
show
Unused Code introduced by
The variable std1 seems to be unused.
Loading history...
87
            dt2 = np.mean(self.signal2.times[1:]-self.signal2.times[:-1])
88
            std2 = np.std(self.signal2.times[1:]-self.signal2.times[:-1])
0 ignored issues
show
Unused Code introduced by
The variable std2 seems to be unused.
Loading history...
89
90
            smooth_std = 1*np.max([dt1,dt2])
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
91
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
92
        if smooth:
93
            xs, ys = interp_smooth_curve(x, y, smooth_std, Ninterp)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "ys" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Variable name "xs" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
94
        else:
95
            xs, ys = x, y
0 ignored issues
show
Coding Style Naming introduced by
Variable name "ys" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Variable name "xs" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
96
97
        idx, props = sp.signal.find_peaks(ys)
0 ignored issues
show
Unused Code introduced by
The variable props seems to be unused.
Loading history...
98
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
99
        if smooth:
100
            s1s_x, s1s_y = interp_smooth_curve(x, self.l1s[1], smooth_std, Ninterp)
0 ignored issues
show
Unused Code introduced by
The variable s1s_x seems to be unused.
Loading history...
101
        else:
102
            s1s_x, s1s_y = x, self.l1s[1]
103
104
        peak_idx = idx[np.argsort(np.abs(xs[idx]))]
105
        peak_x = xs[peak_idx]
106
        peak_y = ys[peak_idx]
107
        peak_signf1s = ys[peak_idx]/s1s_y[peak_idx]
108
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
109
        peak_signif_percent = list()
110
        for i in range(len(peak_x)):
0 ignored issues
show
unused-code introduced by
Consider using enumerate instead of iterating with range and len
Loading history...
111
            f = sp.interpolate.interp1d(self.times, self.mc_corr, axis=-1)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "f" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
112
            peak_signif_percent.append( sp.stats.percentileofscore(f(peak_x[i]), peak_y[i], kind='strict') )
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (108/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
Coding Style introduced by
No space allowed after bracket
Loading history...
Coding Style introduced by
No space allowed before bracket
Loading history...
113
114
        return {'x':peak_x, 's':smooth_std, 'y':peak_y, 'signf1s':peak_signf1s, 'signif_percent':np.array(peak_signif_percent)}
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (127/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
115
116
    def gen_synth(self, samples):
117
        """Generates the synthetic light curves.
118
119
        Generates the specified number `samples` of synthetic light
120
        curves for each signal, to be used to compute the significance
121
        the correlation.
122
123
        Parameters
124
        ----------
125
        samples : :py:class:`~int`
126
            Number of synthetic light curves to be generated for each signal.
127
        """
128
129
        self.samples = samples
130
        self.signal1.gen_synth(samples)
131
        self.signal2.gen_synth(samples)
132
133
    def gen_corr(self, uncert=True, dsamples=500):
134
        """Generates the correlation of the signals.
135
136
        Generates the correlation of the signals, and computes their
137
        confidence level from the synthetic light curves, which must
138
        have been generated before.
139
        """
140
141
        if uncert and self.signal1.dvalues is None:
142
            log.error(
143
                "uncert is True but no uncertainties for Signal 1 were specified, setting uncert to False"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
144
            )
145
            uncert = False
146
        if uncert and self.signal2.dvalues is None:
147
            log.error(
148
                "uncert is True but no uncertainties for Signal 2 were specified, setting uncert to False"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
149
            )
150
            uncert = False
151
152
        if len(self.times) == 0 or len(self.dts) == 0:
153
            raise Exception(
154
                "You need to define the times on which to calculate the correlation."
155
                "Please use gen_times() or manually set them."
156
            )
157
158
        # TODO: refactor if/elif with a helper function
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
159
        mc_corr = np.empty((self.samples, self.times.size))
160
        if uncert:
161
            mc_sig = np.empty((dsamples, self.times.size))
162
163
        if self.fcorr == "welsh":
164
            for idx in range(self.samples):
165
                mc_corr[idx] = welsh(
166
                    self.signal1.times,
167
                    self.signal1.synth[idx],
168
                    self.signal2.times,
169
                    self.signal2.synth[idx],
170
                    self.times,
171
                    self.dts,
172
                )
173
            if uncert:
174
                for idx in range(dsamples):
175
                    mc_sig[idx] = welsh(
176
                        self.signal1.times,
177
                        self.signal1.values
178
                        + self.signal1.dvalues * np.random.randn(self.signal1.values.size),
179
                        self.signal2.times,
180
                        self.signal2.values
181
                        + self.signal2.dvalues * np.random.randn(self.signal2.values.size),
182
                        self.times,
183
                        self.dts,
184
                    )
185
            self.values = welsh(
186
                self.signal1.times,
187
                self.signal1.values,
188
                self.signal2.times,
189
                self.signal2.values,
190
                self.times,
191
                self.dts,
192
            )
193
        elif self.fcorr == "kroedel":
194
            for idx in range(self.samples):
195
                mc_corr[idx] = kroedel(
196
                    self.signal1.times,
197
                    self.signal1.synth[idx],
198
                    self.signal2.times,
199
                    self.signal2.synth[idx],
200
                    self.times,
201
                    self.dts,
202
                )
203
            if uncert:
204
                for idx in range(dsamples):
205
                    mc_sig[idx] = kroedel(
206
                        self.signal1.times,
207
                        self.signal1.values
208
                        + self.signal1.dvalues * np.random.randn(self.signal1.values.size),
209
                        self.signal2.times,
210
                        self.signal2.values
211
                        + self.signal2.dvalues * np.random.randn(self.signal2.values.size),
212
                        self.times,
213
                        self.dts,
214
                    )
215
            self.values = kroedel(
216
                self.signal1.times,
217
                self.signal1.values,
218
                self.signal2.times,
219
                self.signal2.values,
220
                self.times,
221
                self.dts,
222
            )
223
        elif self.fcorr == "welsh_old": # should produce the exactly same results, but we keep it for debugs and testcov
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (120/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
224
            for idx in range(self.samples):
225
                mc_corr[idx] = welsh_old(
226
                    self.signal1.times,
227
                    self.signal1.synth[idx],
228
                    self.signal2.times,
229
                    self.signal2.synth[idx],
230
                    self.times,
231
                    self.dts,
232
                )
233
            if uncert:
234
                for idx in range(dsamples):
235
                    mc_sig[idx] = welsh_old(
236
                        self.signal1.times,
237
                        self.signal1.values
238
                        + self.signal1.dvalues * np.random.randn(self.signal1.values.size),
239
                        self.signal2.times,
240
                        self.signal2.values
241
                        + self.signal2.dvalues * np.random.randn(self.signal2.values.size),
242
                        self.times,
243
                        self.dts,
244
                    )
245
            self.values = welsh_old(
246
                self.signal1.times,
247
                self.signal1.values,
248
                self.signal2.times,
249
                self.signal2.values,
250
                self.times,
251
                self.dts,
252
            )
253
        elif self.fcorr == "kroedel_old": # should produce the exactly same results, but we keep it for debugs and testcov
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (122/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
254
            for idx in range(self.samples):
255
                mc_corr[idx] = kroedel_old(
256
                    self.signal1.times,
257
                    self.signal1.synth[idx],
258
                    self.signal2.times,
259
                    self.signal2.synth[idx],
260
                    self.times,
261
                    self.dts,
262
                )
263
            if uncert:
264
                for idx in range(dsamples):
265
                    mc_sig[idx] = kroedel_old(
266
                        self.signal1.times,
267
                        self.signal1.values
268
                        + self.signal1.dvalues * np.random.randn(self.signal1.values.size),
269
                        self.signal2.times,
270
                        self.signal2.values
271
                        + self.signal2.dvalues * np.random.randn(self.signal2.values.size),
272
                        self.times,
273
                        self.dts,
274
                    )
275
            self.values = kroedel_old(
276
                self.signal1.times,
277
                self.signal1.values,
278
                self.signal2.times,
279
                self.signal2.values,
280
                self.times,
281
                self.dts,
282
            )
283
        elif self.fcorr == "numpy":
284
            for idx in range(self.samples):
285
                mc_corr[idx] = nindcf(
286
                    self.signal1.times,
287
                    self.signal1.synth[idx],
288
                    self.signal2.times,
289
                    self.signal2.synth[idx],
290
                )
291
            if uncert:
292
                for idx in range(dsamples):
293
                    mc_sig[idx] = nindcf(
294
                        self.signal1.times,
295
                        self.signal1.values
296
                        + self.signal1.dvalues * np.random.randn(self.signal1.values.size),
297
                        self.signal2.times,
298
                        self.signal2.values
299
                        + self.signal2.dvalues * np.random.randn(self.signal2.values.size),
300
                    )
301
            self.values = nindcf(
302
                self.signal1.times,
303
                self.signal1.values,
304
                self.signal2.times,
305
                self.signal2.values,
306
            )
307
        else:
308
            raise Exception("Unknown method " + self.fcorr + " for correlation.")
309
310
        self.l3s = np.percentile(mc_corr, [0.135, 99.865], axis=0)
311
        self.l2s = np.percentile(mc_corr, [2.28, 97.73], axis=0)
312
        self.l1s = np.percentile(mc_corr, [15.865, 84.135], axis=0)
313
314
        self.mc_corr = mc_corr # save them to be able to compute exact significance later...
0 ignored issues
show
Coding Style introduced by
The attribute mc_corr was defined outside __init__.

It is generally a good practice to initialize all attributes to default values in the __init__ method:

class Foo:
    def __init__(self, x=None):
        self.x = x
Loading history...
315
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
316
        if uncert:
317
            self.s3s = np.percentile(mc_sig, [0.135, 99.865], axis=0)
0 ignored issues
show
introduced by
The variable mc_sig does not seem to be defined in case uncert on line 160 is False. Are you sure this can never be the case?
Loading history...
318
            self.s2s = np.percentile(mc_sig, [2.28, 97.73], axis=0)
319
            self.s1s = np.percentile(mc_sig, [15.865, 84.135], axis=0)
320
321
    def gen_times(self, ftimes="canopy", *args, **kwargs):
0 ignored issues
show
introduced by
Keyword argument before variable positional arguments list in the definition of gen_times function
Loading history...
322
        """Sets times and bins using the method defined by ftimes parameter.
323
324
        Parameters
325
        ----------
326
        ftimes : :py:class:`~str`
327
            Method used to bin the time interval of the correlation.
328
            Possible values are:
329
            - "canopy": Computes a binning as dense as possible, with
330
            variable bin width and (with a minimum and a maximum
331
            resolution) and a minimum statistic.
332
            - "rawab": Computes a binning with variable bin width,
333
            a given step, maximum bin size and a minimum statistic.
334
            - "uniform": Computes a binning with uniform bin width
335
            and a minimum statistic.
336
            - "numpy": Computes a binning suitable for method='numpy'.
337
        """
338
        if ftimes == "canopy":
339
            self.times, self.dts, self.nb = gen_times_canopy(
340
                self.signal1.times, self.signal2.times, *args, **kwargs
341
            )
342
        elif ftimes == "rawab":
343
            self.times, self.dts, self.nb = gen_times_rawab(
344
                self.signal1.times, self.signal2.times, *args, **kwargs
345
            )
346
        elif ftimes == "uniform":
347
            self.times, self.dts, self.nb = gen_times_uniform(
348
                self.signal1.times, self.signal2.times, *args, **kwargs
349
            )
350
        elif ftimes == "numpy":
351
            t1, t2 = self.signal1.times, self.signal1.times
0 ignored issues
show
Coding Style Naming introduced by
Variable name "t2" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Variable name "t1" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
352
            dt = np.max([(t1.max() - t1.min()) / t1.size, (t2.max() - t2.min()) / t2.size])
0 ignored issues
show
Coding Style Naming introduced by
Variable name "dt" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
353
            n1 = int(np.ptp(t1) / dt * 10.0)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "n1" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
354
            n2 = int(np.ptp(t1) / dt * 10.0)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "n2" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
355
            self.times = np.linspace(self.tmin_full, self.tmax_full, n1 + n2 - 1)
356
            self.dts = np.full(self.times.size, (self.tmax_full - self.tmin_full) / (n1 + n2))
357
        else:
358
            raise Exception("Unknown method " + ftimes + ", please indicate how to generate times.")
359
360
    def plot_corr(self, uncert=True, ax=None, legend=False):
0 ignored issues
show
Coding Style Naming introduced by
Argument name "ax" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
361
        """Plots the correlation of the signals.
362
363
        Plots the correlation of the signal, and the confidence limits
364
        computed from the synthetic curves.
365
366
        Parameters
367
        ----------
368
        ax : :class:`matplotlib.axes.Axes`
369
            Axes to be used (default None, it creates a new axes).
370
        legend : :py:class:`~bool`
371
            Whether to add a legend indicating the confidence levels.
372
        """
373
374
        # TODO: develop a plotting object for plots
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
375
        #       this will considerably shorten the
376
        #       number of attributes of this class
377
378
        if uncert and self.signal1.dvalues is None:
379
            log.error(
380
                "uncert is True but no uncertainties for Signal 1 were specified, setting uncert to False"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
381
            )
382
            uncert = False
383
        if uncert and self.signal2.dvalues is None:
384
            log.error(
385
                "uncert is True but no uncertainties for Signal 2 were specified, setting uncert to False"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
386
            )
387
            uncert = False
388
389
        # plt.figure()
390
        if ax is None:
391
            ax = plt.gca()
392
393
        ax.plot(self.times, self.l1s[0], "c-.")
394
        ax.plot(self.times, self.l1s[1], "c-.", label=r"$1\sigma$")
395
        ax.plot(self.times, self.l2s[0], "k--")
396
        ax.plot(self.times, self.l2s[1], "k--", label=r"$2\sigma$")
397
        ax.plot(self.times, self.l3s[0], "r-")
398
        ax.plot(self.times, self.l3s[1], "r-", label=r"$3\sigma$")
399
        ax.plot(self.times, self.values, "b.--", lw=1)
400
401
        # full limit
402
        ax.axvline(x=self.tmin_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
403
        ax.axvline(x=self.tmax_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
404
        # same limit
405
        ax.axvline(x=self.tmin_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
406
        ax.axvline(x=self.tmax_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
407
        # valid limit
408
        ax.axvline(x=self.tmin_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
409
        ax.axvline(x=self.tmax_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
410
411
        if uncert:
412
            ax.fill_between(x=self.times, y1=self.s1s[0], y2=self.s1s[1], color="b", alpha=0.5)
413
            ax.fill_between(x=self.times, y1=self.s2s[0], y2=self.s2s[1], color="b", alpha=0.3)
414
            ax.fill_between(x=self.times, y1=self.s3s[0], y2=self.s3s[1], color="b", alpha=0.1)
415
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
416
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
417
        if legend:
418
            ax.legend()
419
420
        # plt.show()
421
        return ax
422
423
    def plot_times(self, rug=False):
424
        """Plots the time binning generated previously.
425
426
        Plots the number of total bins, their distribution and the
427
        number of points in each bin for the generated time binning,
428
        previously generated with Correlation().gen_times(...).
429
430
        Parameters
431
        ----------
432
        rug : :py:class:`~bool`
433
            Whether to make a rug plot just below the binning, to make
434
            it easier to visually understand the density and distribution
435
            of the generated bins.
436
437
        """
438
439
        # TODO: develop a plotting object for plots
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
440
        #       this will considerably shorten the
441
        #       number of attributes of this class
442
443
        fig, ax = plt.subplots(nrows=2, ncols=1, sharex=True)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "ax" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
444
        tab, dtab, nab = self.times, self.dts, self.nb
445
446
        fig.suptitle("Total bins: {:d}".format(self.times.size))
447
        ax[0].plot(tab, nab, "b.")
448
        ax[0].errorbar(x=tab, y=nab, xerr=dtab / 2, fmt="none")
449
        ax[0].set_ylabel("$n_i$")
450
        ax[0].grid()
451
        ax[0].axvline(x=self.tmin_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
452
        ax[0].axvline(x=self.tmax_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
453
        ax[0].axvline(x=self.tmin_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
454
        ax[0].axvline(x=self.tmax_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
455
        ax[0].axvline(x=self.tmin_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
456
        ax[0].axvline(x=self.tmax_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
457
        ax[1].plot(tab, dtab, "b.")
458
        ax[1].set_ylabel("$dt_i$")
459
        # ax[1].grid()
460
        ax[1].axvline(x=self.tmin_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
461
        ax[1].axvline(x=self.tmax_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
462
        ax[1].axvline(x=self.tmin_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
463
        ax[1].axvline(x=self.tmax_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
464
        ax[1].axvline(x=self.tmin_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
465
        ax[1].axvline(x=self.tmax_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
466
467
        if rug:
468
            for time in self.times:
469
                ax[1].axvline(x=time, ymin=0, ymax=0.2, color="black", linewidth=0.8, alpha=1.0)
470
            # ax[1].plot(self.t, ax[1].get_ylim()[0]+np.zeros(self.t.size), 'k|', alpha=0.8, lw=1)
471
472
        ax[1].grid()
473
        # fig.show()
474
475
    def plot_signals(self, ax=None):
0 ignored issues
show
Coding Style Naming introduced by
Argument name "ax" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
476
        """Plots the signals involved in this correlation.
477
478
        Plots the signals involved in this correlation, in the same window
479
        but with different twin y-axes and different colors.
480
481
        Parameters
482
        ----------
483
        ax : :py:class:`~matplotlib.axes.Axes`
484
            Axes to be used for plotting.
485
        """
486
487
        # TODO: develop a plotting object for plots
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
488
        #       this will considerably shorten the
489
        #       number of attributes of this class
490
491
        if ax is None:
492
            ax = plt.gca()
493
494
        ax.plot(self.signal1.times, self.signal1.values, "b.-", lw=1, alpha=0.4)
495
        ax.tick_params(axis="y", labelcolor="b")
496
        ax.set_ylabel("sig 1", color="b")
497
498
        ax2 = ax.twinx()
499
        ax2.plot(self.signal2.times, self.signal2.values, "r.-", lw=1, alpha=0.4)
500
        ax2.tick_params(axis="y", labelcolor="r")
501
        ax2.set_ylabel("sig 2", color="r")
502