Issues (587)

mutis/flares/bayblocks.py (120 issues)

1
""" Flare analysis """
2
3
import logging
4
5
import numpy as np
0 ignored issues
show
Unable to import 'numpy'
Loading history...
6
import scipy as sp
0 ignored issues
show
Unused scipy imported as sp
Loading history...
Unable to import 'scipy'
Loading history...
7
import pandas as pd
0 ignored issues
show
Unused pandas imported as pd
Loading history...
Unable to import 'pandas'
Loading history...
8
9
import matplotlib as mplt
0 ignored issues
show
Unused matplotlib imported as mplt
Loading history...
Unable to import 'matplotlib'
Loading history...
10
import matplotlib.pyplot as plt
0 ignored issues
show
Unable to import 'matplotlib.pyplot'
Loading history...
11
12
import sys
0 ignored issues
show
The import sys seems to be unused.
Loading history...
standard import "import sys" should be placed before "import numpy as np"
Loading history...
13
import os
0 ignored issues
show
standard import "import os" should be placed before "import numpy as np"
Loading history...
The import os seems to be unused.
Loading history...
14
import glob
0 ignored issues
show
standard import "import glob" should be placed before "import numpy as np"
Loading history...
The import glob seems to be unused.
Loading history...
15
16
import re
0 ignored issues
show
The import re seems to be unused.
Loading history...
standard import "import re" should be placed before "import numpy as np"
Loading history...
17
from datetime import datetime
0 ignored issues
show
standard import "from datetime import datetime" should be placed before "import numpy as np"
Loading history...
Unused datetime imported from datetime
Loading history...
18
19
from astropy.stats import bayesian_blocks
0 ignored issues
show
Unable to import 'astropy.stats'
Loading history...
20
21
import warnings 
0 ignored issues
show
standard import "import warnings" should be placed before "import numpy as np"
Loading history...
The import warnings seems to be unused.
Loading history...
Trailing whitespace
Loading history...
22
23
import mutis.flares.flare as flare
24
25
log = logging.getLogger(__name__)
26
27
class BayesianBlocks:
28
    """ Return a Bayesian Block representation of the signal
29
    
0 ignored issues
show
Trailing whitespace
Loading history...
30
    Attributes
31
    ----------
32
    edges: list
33
            list of edges defining the blocks.
34
    values: list
35
            list of values defining the height of the blocks.
36
    signal: mutis.Signal
37
            the mutis.Signal() instance that this BayesianBlocks() represents.
38
    inflare: list
39
            list of boolean representing whether a block is in flare or not.
40
    """
41
42
    def __init__(self, signal, p=0.1):
43
        edges = bayesian_blocks(signal.times, signal.values, signal.dvalues, fitness='measures', p0=p)
0 ignored issues
show
This line is too long as per the coding-style (102/100).

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

Loading history...
44
        
0 ignored issues
show
Trailing whitespace
Loading history...
45
        values = list()
46
        for i in range( len(edges)-1 ):
0 ignored issues
show
No space allowed before bracket
Loading history...
No space allowed after bracket
Loading history...
47
            msk = (edges[i] < signal.times) & (signal.times < edges[i+1])
48
            if np.sum(msk) > 0:
49
                value = np.average( signal.values[msk], weights=1/signal.dvalues[msk] )
0 ignored issues
show
No space allowed after bracket
Loading history...
No space allowed before bracket
Loading history...
50
                values.append( value )
0 ignored issues
show
No space allowed after bracket
Loading history...
No space allowed before bracket
Loading history...
51
            else:
52
                values.append( 0 )
0 ignored issues
show
No space allowed after bracket
Loading history...
No space allowed before bracket
Loading history...
53
            
0 ignored issues
show
Trailing whitespace
Loading history...
54
        self.edges = np.array(edges)
55
        self.values = np.array(values)
56
        self.signal = signal
57
        
0 ignored issues
show
Trailing whitespace
Loading history...
58
        self.inflare = None
59
    
0 ignored issues
show
Trailing whitespace
Loading history...
60
    def plot(self, style='color.strict', ax=None, **kwargs):
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...
61
        """ Plot the bayesian block representation
62
        
0 ignored issues
show
Trailing whitespace
Loading history...
63
        E.g:
64
        >>> signal = mutis.Signal(data['jyear'], data['Flux'], data['Flux_err'])
65
        >>> BayesianBlocks(signal).plot(color='k')
66
67
        """
68
        
0 ignored issues
show
Trailing whitespace
Loading history...
69
        ax = plt.gca() if ax is None else ax
70
        
0 ignored issues
show
Trailing whitespace
Loading history...
71
        #self.signal.plot()
72
        
0 ignored issues
show
Trailing whitespace
Loading history...
73
        x = self.edges
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...
74
        y = self.values[np.r_[0:len(self.values),-1]]
0 ignored issues
show
Exactly one space required after comma
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...
75
76
            
0 ignored issues
show
Trailing whitespace
Loading history...
77
        if self.inflare is None or style == 'none':
78
            
0 ignored issues
show
Trailing whitespace
Loading history...
79
            ax.step(x, y, 'k', where='post', **kwargs)
80
            
0 ignored issues
show
Trailing whitespace
Loading history...
81
        else:
82
            
0 ignored issues
show
Trailing whitespace
Loading history...
83
            if style == 'area':
84
                
0 ignored issues
show
Trailing whitespace
Loading history...
85
                ax.step(x, y, 'k', where='post')
86
                for i in range(len(self.inflare)):
87
                    if self.inflare[i]:
88
                        ax.axvspan(x[i], x[i+1], facecolor='r', edgecolor=None, alpha=0.2, **kwargs)
89
                        
0 ignored issues
show
Trailing whitespace
Loading history...
90
            elif style == 'color.simple':
91
                
0 ignored issues
show
Trailing whitespace
Loading history...
92
                for i in range(len(self.edges)-2):
93
                    ax.step(self.edges[[i,i+1]], self.values[[i,i+1]], 'r' if self.inflare[i] else 'k', where='post', **kwargs)
0 ignored issues
show
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...
Exactly one space required after comma
Loading history...
94
                ax.step(self.edges[[-2,-1]], self.values[[-1,-1]], 'r' if self.inflare[-1] else 'k', where='post', **kwargs)
0 ignored issues
show
This line is too long as per the coding-style (124/100).

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

Loading history...
Exactly one space required after comma
Loading history...
95
                
0 ignored issues
show
Trailing whitespace
Loading history...
96
            elif style == 'color.loose':
97
                
0 ignored issues
show
Trailing whitespace
Loading history...
98
                for i in range(len(self.edges)-2):
99
                    ax.step(self.edges[[i,i+1]], self.values[[i,i]], 'r' if self.inflare[i] else 'k', where='post', **kwargs)
0 ignored issues
show
This line is too long as per the coding-style (125/100).

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

Loading history...
Exactly one space required after comma
Loading history...
100
                    ax.step(self.edges[[i+1,i+1]], self.values[[i,i+1]], 'r' if self.inflare[i] or self.inflare[i+1] else 'k', where='post', **kwargs)
0 ignored issues
show
Exactly one space required after comma
Loading history...
This line is too long as per the coding-style (150/100).

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

Loading history...
101
                ax.step(self.edges[[-2,-1]], self.values[[-1,-1]], 'r' if self.inflare[-1] else 'k', where='post', **kwargs)
0 ignored issues
show
Exactly one space required after comma
Loading history...
This line is too long as per the coding-style (124/100).

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

Loading history...
102
                
0 ignored issues
show
Trailing whitespace
Loading history...
103
            elif style == 'color.strict':
104
                
0 ignored issues
show
Trailing whitespace
Loading history...
105
                for i in range(len(self.edges)-2):
106
                    ax.step(self.edges[[i,i+1]], self.values[[i,i]], 'r' if self.inflare[i] else 'k', where='post', **kwargs)
0 ignored issues
show
Exactly one space required after comma
Loading history...
This line is too long as per the coding-style (125/100).

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

Loading history...
107
                    ax.step(self.edges[[i+1,i+1]], self.values[[i,i+1]], 'r' if self.inflare[i] and self.inflare[i+1] else 'k', where='post', **kwargs)
0 ignored issues
show
Exactly one space required after comma
Loading history...
This line is too long as per the coding-style (151/100).

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

Loading history...
108
                ax.step(self.edges[[-2,-1]], self.values[[-1,-1]], 'r' if self.inflare[-1] else 'k', where='post', **kwargs)
0 ignored issues
show
Exactly one space required after comma
Loading history...
This line is too long as per the coding-style (124/100).

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

Loading history...
109
                
0 ignored issues
show
Trailing whitespace
Loading history...
110
            else:
111
                raise Exception("Unknown style. Available styles are 'none', 'area', 'color.simple', 'color.strict', 'color.loose'.")
0 ignored issues
show
This line is too long as per the coding-style (133/100).

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

Loading history...
112
113
                
0 ignored issues
show
Trailing whitespace
Loading history...
114
        
0 ignored issues
show
Trailing whitespace
Loading history...
115
    def get_flares(self, thresh=1):
116
        """ Get a list of flares following the algorithm proposed in 
0 ignored issues
show
Trailing whitespace
Loading history...
117
[Meyer, Scargle, Blandford (2019)]
118
(https://iopscience.iop.org/article/10.3847/1538-4357/ab1651/pdf):
119
        
0 ignored issues
show
Trailing whitespace
Loading history...
120
```There is no generally accepted consensus on the best way to
121
determine which data points belong to a flaring state and which
122
characterize the quiescent level. Nalewajko (2013)suggested
123
the simple definition that a flare is a continuous time interval
124
associated with a flux peak in which the flux is larger than half
125
the peak flux value. This definition is intuitive, however, and it
126
is unclear how to treat overlapping flares and identify flux
127
peaks in an objective way. Here we use a simple two-step
128
procedure tailored to the block representation: (1)identify a
129
block that is higher than both the previous and subsequent
130
blocks as a peak, and (2)proceed downward from the peak in
131
both directions as long as the blocks are successively lower.```
132
        """
133
        di_max = 5
134
        
0 ignored issues
show
Trailing whitespace
Loading history...
135
        # get list of local maxima
136
        # bad beheaviour at 0 and -1:
137
        #imaxL = sp.signal.argrelextrema(self.values, np.greater)[0]
138
        imaxL = list()
0 ignored issues
show
Coding Style Naming introduced by
Variable name "imaxL" 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...
139
        for i in range(0,len(self.values)):
0 ignored issues
show
Exactly one space required after comma
Loading history...
140
            if i == 0 and thresh*self.values[0] > self.values[1]:
141
                imaxL.append(i)
142
            elif i == len(self.values)-1 and self.values[i-1] < thresh*self.values[i]:
143
                imaxL.append(i)
144
            elif self.values[i-1] < thresh*self.values[i] > self.values[i+1]:
145
                imaxL.append(i)
146
        imaxL = np.array(imaxL)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "imaxL" 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...
147
        
0 ignored issues
show
Trailing whitespace
Loading history...
148
        
0 ignored issues
show
Trailing whitespace
Loading history...
149
        inflareL = np.full(self.values.shape, False)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "inflareL" 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...
150
        
0 ignored issues
show
Trailing whitespace
Loading history...
151
        # get list of local maxima over a threshold (flare peaks)
152
        for imax in imaxL:
153
            inflare = True
154
            
0 ignored issues
show
Trailing whitespace
Loading history...
155
            if imax == 0:
156
                pass
157
            elif not (self.values[imax-1] < thresh*self.values[imax]):
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after not.
Loading history...
158
                inflare = False
159
            
0 ignored issues
show
Trailing whitespace
Loading history...
160
            
0 ignored issues
show
Trailing whitespace
Loading history...
161
            if imax == len(self.values)-1:
162
                pass
163
            elif  not (thresh*self.values[imax] > self.values[imax+1]):
0 ignored issues
show
Unused Code Coding Style introduced by
There is an unnecessary parenthesis after not.
Loading history...
164
                inflare = False
165
                
0 ignored issues
show
Trailing whitespace
Loading history...
166
            inflareL[imax] = inflare
167
           
0 ignored issues
show
Trailing whitespace
Loading history...
168
        # extend the flare to adyacent blocks
169
        for imax in np.argwhere(inflareL):
170
            
0 ignored issues
show
Trailing whitespace
Loading history...
171
            if imax == 0:
172
                pass
173
            else:
174
                di = 1
0 ignored issues
show
Coding Style Naming introduced by
Variable name "di" 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...
175
                stop = False
176
                while not stop and di < di_max:
177
                    if imax-di-1 < 0:
178
                        break
179
                    
0 ignored issues
show
Trailing whitespace
Loading history...
180
                    if self.values[imax-di-1] < thresh*self.values[imax-di]:
181
                        inflareL[imax-di] = True
182
                    else:
183
                        stop = True
184
                    
0 ignored issues
show
Trailing whitespace
Loading history...
185
                    
0 ignored issues
show
Trailing whitespace
Loading history...
186
                    di = di + 1
0 ignored issues
show
Coding Style Naming introduced by
Variable name "di" 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...
187
                   
0 ignored issues
show
Trailing whitespace
Loading history...
188
            if imax == len(self.values)-1:
189
                pass
190
            else:
191
                di = 1
0 ignored issues
show
Coding Style Naming introduced by
Variable name "di" 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...
192
                stop = False
193
                while not stop and di < di_max:
194
                    if imax+di+1 > len(self.values)-1:
195
                        break
196
                    
0 ignored issues
show
Trailing whitespace
Loading history...
197
                    if thresh*self.values[imax+di] > self.values[imax+di+1]:
198
                        inflareL[imax+di] = True
199
                    else:
200
                        stop = True
201
                    
0 ignored issues
show
Trailing whitespace
Loading history...
202
                    
0 ignored issues
show
Trailing whitespace
Loading history...
203
                    di = di + 1
0 ignored issues
show
Coding Style Naming introduced by
Variable name "di" 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...
204
         
0 ignored issues
show
Trailing whitespace
Loading history...
205
        
0 ignored issues
show
Trailing whitespace
Loading history...
206
        self.inflare = np.array(inflareL)
207
        
0 ignored issues
show
Trailing whitespace
Loading history...
208
209
    def get_flare_list(self):
210
        """ Join all flares into a list of mutis.flares.Flare() """
211
212
        groups = np.split(np.arange(len(self.inflare)), 
0 ignored issues
show
Trailing whitespace
Loading history...
213
                          np.where((np.abs(np.diff(np.asarray(self.inflare, dtype=int))) == 1))[0]+1)
0 ignored issues
show
This line is too long as per the coding-style (101/100).

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

Loading history...
214
        
0 ignored issues
show
Trailing whitespace
Loading history...
215
        # (groups contains the groups of indices of self.inflare/self.values 
0 ignored issues
show
Trailing whitespace
Loading history...
216
        # that correspond to flares or no flares)
217
        
0 ignored issues
show
Trailing whitespace
Loading history...
218
        #print(self.inflare)
219
        #print([list(grp) for grp in groups])
220
        
0 ignored issues
show
Trailing whitespace
Loading history...
221
        flareL = list()
0 ignored issues
show
Coding Style Naming introduced by
Variable name "flareL" 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...
222
        for i, grp in enumerate(groups):
0 ignored issues
show
The variable i seems to be unused.
Loading history...
223
            if np.all(self.inflare[grp]):
224
                #print(grp)
225
                tstart = self.edges[grp[0]]
226
                tstop = self.edges[grp[-1]+1] # flare ends when no flare begins
227
                
0 ignored issues
show
Trailing whitespace
Loading history...
228
                flareL.append(flare.Flare(tstart,tstop))
0 ignored issues
show
Exactly one space required after comma
Loading history...
229
        
0 ignored issues
show
Trailing whitespace
Loading history...
230
        #print(flareL)
231
        
0 ignored issues
show
Trailing whitespace
Loading history...
232
        return flareL
0 ignored issues
show
Final newline missing
Loading history...