Passed
Pull Request — main (#25)
by
unknown
01:55
created

mutis.astro   F

Complexity

Total Complexity 95

Size/Duplication

Total Lines 903
Duplicated Lines 10.3 %

Importance

Changes 0
Metric Value
eloc 495
dl 93
loc 903
rs 2
c 0
b 0
f 0
wmc 95

9 Functions

Rating   Name   Duplication   Size   Complexity  
A KnotsIdReadCSV() 0 44 4
F KnotsIdAuto() 0 115 20
F KnotsId2dGUI() 47 284 28
A KnotsIdSaveMod() 0 2 1
A pol_angle_reshape() 0 20 4
F KnotsIdGUI() 46 241 26
A KnotsIdSaveCSV() 0 46 3
A KnotsIdReadMod() 0 56 4
A get_output() 0 16 2

3 Methods

Rating   Name   Duplication   Size   Complexity  
A plain_printer.clear_output() 0 3 1
A plain_printer.append_stdout() 0 3 1
A plain_printer.display_output() 0 3 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like mutis.astro 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
"""Utils specific to the field of astrophysics"""
3
4
import logging
5
6
import numpy as np
0 ignored issues
show
introduced by
Unable to import 'numpy'
Loading history...
7
import pandas as pd
0 ignored issues
show
introduced by
Unable to import 'pandas'
Loading history...
8
9
import matplotlib as mplt
0 ignored issues
show
introduced by
Unable to import 'matplotlib'
Loading history...
Unused Code introduced by
Unused matplotlib imported as mplt
Loading history...
10
import matplotlib.pyplot as plt
0 ignored issues
show
introduced by
Unable to import 'matplotlib.pyplot'
Loading history...
11
12
import glob
0 ignored issues
show
introduced by
standard import "import glob" should be placed before "import numpy as np"
Loading history...
13
import re
0 ignored issues
show
introduced by
standard import "import re" should be placed before "import numpy as np"
Loading history...
14
from datetime import datetime
0 ignored issues
show
introduced by
standard import "from datetime import datetime" should be placed before "import numpy as np"
Loading history...
15
16
from astropy.time import Time
0 ignored issues
show
introduced by
Unable to import 'astropy.time'
Loading history...
17
18
19
__all__ = ["Astro"]
0 ignored issues
show
Bug introduced by
Undefined variable name 'Astro' in __all__
Loading history...
20
21
log = logging.getLogger(__name__)
22
23
#############################################################################
24
### Output compatible with IPython widgets and with plain python console: ###
25
#
26
# With this we can follow follow a commen scheme:
27
#
28
# def someGUIfunction():
29
#     out = get_output()
30
#     ... gui things...
31
#         out.clear_output()
32
#         out.append_stdout('some msg')
33
#     out.display_output()
34
#
35
class plain_printer:
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
Coding Style Naming introduced by
Class name "plain_printer" doesn't conform to PascalCase naming style ('[^\\W\\da-z][^\\W_]+$' 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...
36
    @staticmethod
37
    def append_stdout(msg):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
38
        print(msg, end='')
39
    @staticmethod
40
    def clear_output():
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
41
        print('\n')
42
    @staticmethod
43
    def display_output():
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
44
        pass
45
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
46
def get_output():
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
47
    try:
48
        get_ipython().__class__.__name__
0 ignored issues
show
Unused Code Bug introduced by
The expression get_ipython().__class__.__name__ does not seem to have sideeffects and its result is not used.

If a expression has no sideeffects (any lasting effect after it has been called) and its return value is not used, this usually means that this code can be removed or that an assignment is missing.

Loading history...
Comprehensibility Best Practice introduced by
Undefined variable 'get_ipython'
Loading history...
Comprehensibility Best Practice introduced by
The variable get_ipython does not seem to be defined.
Loading history...
49
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
50
        import ipywidgets
0 ignored issues
show
introduced by
Import outside toplevel (ipywidgets)
Loading history...
introduced by
Unable to import 'ipywidgets'
Loading history...
51
        class pretty_printer(ipywidgets.Output):
0 ignored issues
show
introduced by
Missing class docstring
Loading history...
Coding Style Naming introduced by
Class name "pretty_printer" doesn't conform to PascalCase naming style ('[^\\W\\da-z][^\\W_]+$' 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...
52
            def __init__(self, *args, **kwargs):
0 ignored issues
show
introduced by
Useless super delegation in method '__init__'
Loading history...
53
                super().__init__(*args, **kwargs)
54
            def display_output(self):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
55
                display(self)
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable display does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
Undefined variable 'display'
Loading history...
56
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
57
        out = pretty_printer(layout={'border': '1px solid black'})
58
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
59
        return out
60
    except:
0 ignored issues
show
Coding Style Best Practice introduced by
General except handlers without types should be used sparingly.

Typically, you would use general except handlers when you intend to specifically handle all types of errors, f.e. when logging. Otherwise, such general error handlers can mask errors in your application that you want to know of.

Loading history...
61
        return plain_printer
62
#############################################################################
63
   
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
64
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
65
def pol_angle_reshape(s):
0 ignored issues
show
Coding Style Naming introduced by
Argument name "s" 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...
66
    """
67
        Reshape a signal as a polarization angle: shifting by 180 degrees in a way it varies as smoothly as possible.
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (117/100).

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

Loading history...
68
    """
69
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
70
    s = np.array(s)
71
    s = np.mod(s,180) # s % 180
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
72
73
    sn = np.empty(s.shape)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "sn" 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
    for i in range(1,len(s)):
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
75
        #if t[i]-t[i-1] < 35:
76
        d = 181
0 ignored issues
show
Coding Style Naming introduced by
Variable name "d" 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...
77
        n = 0
0 ignored issues
show
Coding Style Naming introduced by
Variable name "n" 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...
78
        for m in range(0,100):
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
Coding Style Naming introduced by
Variable name "m" 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...
79
            m2 = (-1)**(m+1)*np.floor((m+1)/2)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "m2" 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...
80
            if np.abs(s[i]+180*m2-sn[i-1]) < d:
81
                d = np.abs(s[i]+180*m2-sn[i-1])
0 ignored issues
show
Coding Style Naming introduced by
Variable name "d" 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...
82
                n = m2
0 ignored issues
show
Coding Style Naming introduced by
Variable name "n" 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
        sn[i] = s[i]+180*n
84
    return sn 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
85
86
87
88
89
90
91
#########################################
92
################# Knots #################
93
#########################################
94
95
96
97
def  KnotsIdAuto(mod):
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (18/15).
Loading history...
Coding Style Naming introduced by
Function name "KnotsIdAuto" 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...
98
    """
99
       Identify the knots appearing in several epochs giving them names, based on their position.
100
       
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
101
        Parameters:
102
        -----------
103
         mod : :pd.DataFrame:
104
             pandas.DataFrame containing every knot, with 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
105
             at least columns 'label', 'date', 'X', 'Y', 'Flux (Jy)'.
106
       
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
107
        Returns: mod
108
        --------
109
         mod : :pd.DataFrame:
110
             pandas.DataFrame containing every knot with their altered labels, with 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
111
             at least columns 'label', 'date', 'X', 'Y', 'Flux (Jy)'.
112
         
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
113
    """
114
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
115
    mod_date_dict = dict(list((mod.groupby('date'))))
116
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
117
    mod_dates = list(Time(list(mod_date_dict.keys())).datetime)
118
    mod_dates_str = list(Time(list(mod_date_dict.keys())).strftime('%Y-%m-%d'))
119
    mod_data = list(mod_date_dict.values())
120
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
121
    Bx = [[]]*len(mod_dates)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "Bx" 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...
122
    By = [[]]*len(mod_dates)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "By" 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...
123
    B = [[]]*len(mod_dates)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "B" 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...
124
125
126
    thresh = 0.03 #0.062
127
128
    news = 0
129
130
    for i, (date, data) in enumerate(zip(mod_dates, mod_data)):
0 ignored issues
show
Unused Code introduced by
The variable date seems to be unused.
Loading history...
unused-code introduced by
Too many nested blocks (6/5)
Loading history...
131
        log.debug(f'Analysing epoch i {i:3d} ({mod_dates_str[i]})')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
132
133
        if not len(data.index) > 0:
134
            log.error(' -> Error, no components found')
135
            break
136
137
        log.debug(f' it has {len(data.index)} components')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
138
139
        Bx[i] = np.ravel(data['X'])
140
        By[i] = np.ravel(data['Y'])
141
        B[i] = np.full(len(data.index), fill_value=None)
142
143
        # if first epoch, just give them new names...:
144
        if i == 0:
145
            log.debug(' first epoch, giving names...')
146
147
            for n in range(0,len(mod_data[i].index)):
0 ignored issues
show
Coding Style Naming introduced by
Variable name "n" 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 introduced by
Exactly one space required after comma
Loading history...
148
                if data['Flux (Jy)'].iloc[n] < 0.001:
149
                    log.debug('  skipping, too weak')
150
                    break
151
                if n == 0:
152
                    B[i][n] = 'A0'
153
                else:
154
                    news = news + 1
155
                    B[i][n] = f'B{news}'
156
            log.debug(f' -> FOUND: {B[i]}\n')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
157
            continue
158
159
        # if not first epoch...:
160
161
        for n in range(0,len(mod_data[i].index)):
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
Coding Style Naming introduced by
Variable name "n" 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...
162
            if data['Flux (Jy)'].iloc[n] < 0.001:
163
                    log.debug('  skipping, too weak')
0 ignored issues
show
Coding Style introduced by
The indentation here looks off. 16 spaces were expected, but 20 were found.
Loading history...
164
                    break
0 ignored issues
show
Coding Style introduced by
The indentation here looks off. 16 spaces were expected, but 20 were found.
Loading history...
165
            if n == 0:
166
                B[i][n] = 'A0'
167
            else:
168
                log.debug(f' -> id component {n}...')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
169
170
                close = None
171
172
                a = 0
0 ignored issues
show
Coding Style Naming introduced by
Variable name "a" 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...
173
                while ( i - a >= 0 and a < 4 and close is None):
0 ignored issues
show
Coding Style introduced by
No space allowed after bracket
Loading history...
174
                    a = a + 1
0 ignored issues
show
Coding Style Naming introduced by
Variable name "a" 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
176
                    if not len(Bx[i-a])>0:
0 ignored issues
show
Coding Style introduced by
Exactly one space required around comparison
Loading history...
177
                        break
178
179
                    dist = ( (Bx[i-a]-Bx[i][n]) ** 2 + (By[i-a]-By[i][n]) ** 2 ) ** 0.5
0 ignored issues
show
Coding Style introduced by
No space allowed after bracket
Loading history...
Coding Style introduced by
No space allowed before bracket
Loading history...
180
181
                    for m in range(len(dist)):
0 ignored issues
show
unused-code introduced by
Consider using enumerate instead of iterating with range and len
Loading history...
Coding Style Naming introduced by
Variable name "m" 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...
182
                        if B[i-a][m] in B[i]:
183
                            dist[m] = np.inf
184
185
                    if np.amin(dist) < thresh*a**1.5:
186
                        close = np.argmin(dist)
187
188
                    if B[i-a][close] in B[i]:
189
                            close = None
0 ignored issues
show
Coding Style introduced by
The indentation here looks off. 24 spaces were expected, but 28 were found.
Loading history...
190
191
192
                if close is None:
193
                    news = news + 1
194
                    B[i][n] = f'B{news}'
195
                    log.debug(f'   component {n} is new, naming it {B[i][n]}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
196
                else:
197
                    log.debug(f'   component {n} is close to {B[i-a][close]} of previous epoch ({a} epochs before)')
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (116/100).

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

Loading history...
introduced by
Use lazy % formatting in logging functions
Loading history...
198
                    B[i][n] = B[i-a][close]
199
200
201
        log.debug(f' -> FOUND: {B[i]}\n')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
202
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
203
                 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
204
    for i, (date, data) in enumerate(zip(mod_dates, mod_data)):
205
        data['label'] = B[i]
206
         
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
207
    mod = pd.concat(mod_data, ignore_index=True)
208
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
209
    log.debug('Finito!')
210
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
211
    return mod
212
213
214
215
def KnotsId2dGUI(mod, use_arrows=False, arrow_pos=1.0):
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (34/15).
Loading history...
Coding Style Naming introduced by
Function name "KnotsId2dGUI" 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...
216
    """
217
        Prompt a GUI to select identified knots and alter their label, reprenting their 2D
218
        spatial distribution in different times.
219
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
220
        It can be used inside jupyter notebooks, using '%matplotlib widget' first.
221
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
222
        Parameters:
223
        -----------
224
         mod : :pd.DataFrame:
225
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
226
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
227
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
228
        Returns:
229
        --------
230
         mod : :pd.DataFrame:
231
             pandas.DataFrame containing every knot with their altered labels, with 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
232
             at least columns 'label', 'date', 'X', 'Y', 'Flux (Jy)'.
233
    """
234
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
235
    mod = mod.copy()
236
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
237
    knots = dict(tuple(mod.groupby('label')))
238
    knots_names = list(knots.keys())
239
    knots_values = list(knots.values())
240
    knots_jyears = {k:Time(knots[k]['date'].to_numpy()).jyear for k in knots}
241
    knots_X = {k:knots[k]['X'].to_numpy() for k in knots}
0 ignored issues
show
Coding Style Naming introduced by
Variable name "knots_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...
242
    knots_Y = {k:knots[k]['Y'].to_numpy() for k in knots}
0 ignored issues
show
Coding Style Naming introduced by
Variable name "knots_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...
243
244
245
    from matplotlib.widgets import Slider, Button, TextBox, RectangleSelector
0 ignored issues
show
introduced by
Import outside toplevel (matplotlib.widgets.Slider, matplotlib.widgets.Button, matplotlib.widgets.TextBox, matplotlib.widgets.RectangleSelector)
Loading history...
introduced by
Unable to import 'matplotlib.widgets'
Loading history...
Unused Code introduced by
Unused Button imported from matplotlib.widgets
Loading history...
246
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
247
    out = get_output()
248
249
    fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8,8))
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...
Coding Style introduced by
Exactly one space required after comma
Loading history...
250
251
    lineas = list()
252
    flechas = list()
253
    textos = list()
254
255
    def draw_all(val=2008):
256
        nonlocal lineas, flechas, textos
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable lineas does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable flechas does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable textos does not seem to be defined.
Loading history...
257
258
        # instead of clearing the whole axis, remove artists
259
        for linea in lineas:
260
            if linea is not None:
261
                linea.remove()
262
        for texto in textos:
263
            if texto is not None:
264
                texto.remove()
265
        for flecha in flechas:
266
            if flecha is not None:
267
                flecha.remove()
268
        ax.set_prop_cycle(None)
269
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
270
        lineas = list()
271
        flechas = list()
272
        textos = list()
273
274
        xlim, ylim = ax.get_xlim(), ax.get_ylim()
275
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
276
        #ax.clear() # either clear the whole axis or remove every artist separetly
277
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
278
        for i, label in enumerate(knots_names):
279
            years = knots_jyears[label]
280
            idx = (val-1.5 < years) & (years < val)
281
            x = knots_X[label][idx]
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...
282
            y = knots_Y[label][idx]
0 ignored issues
show
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...
283
284
            lineas.append(ax.plot(x, y, '.-', linewidth=0.6, alpha=0.4, label=label)[0])
285
286
            if use_arrows:
287
                if len(x) > 1:
288
                    flechas.append(ax.quiver(x[:-1], 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
289
                               y[:-1], 
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 14 spaces).
Loading history...
Coding Style introduced by
Trailing whitespace
Loading history...
290
                               arrow_pos*(x[1:] - x[:-1]), 
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 14 spaces).
Loading history...
Coding Style introduced by
Trailing whitespace
Loading history...
291
                               arrow_pos*(y[1:] - y[:-1]), 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
Coding Style introduced by
Wrong continued indentation (add 14 spaces).
Loading history...
292
                               scale_units='xy', angles='xy', scale=1, 
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 14 spaces).
Loading history...
Coding Style introduced by
Trailing whitespace
Loading history...
293
                               width=0.0015, headwidth=10, headlength=10, headaxislength=6,
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 14 spaces).
Loading history...
294
                               alpha=0.5, color=lineas[i].get_color()))
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 14 spaces).
Loading history...
295
                else:
296
                    flechas.append(None)
297
298
            if len(x) > 0:
299
                #textos.append(ax.annotate(label, (x[0], y[0]), (-28,-10), textcoords='offset points', color=lineas[i].get_color(), fontsize=14))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (145/100).

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

Loading history...
300
                textos.append(ax.text(x[-1]+0.015, y[-1]+0.015, label, {'color':lineas[i].get_color(), 'fontsize':14}))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (119/100).

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

Loading history...
301
            else:
302
                textos.append(None)
303
304
        ax.set_xlim(xlim)
305
        ax.set_ylim(ylim)
306
        ax.set_aspect('equal')
307
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
308
        fig.canvas.draw_idle() # if removed every artist separately instead of ax.clear()
309
310
    draw_all()
311
312
    def update(val):
313
        nonlocal lineas, flechas, textos
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable flechas does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable textos does not seem to be defined.
Loading history...
314
315
        for i, label in enumerate(knots_names):
316
            years = knots_jyears[label]
317
            idx = (val-1.5 < years) & (years < val)
318
            x = knots_X[label][idx]
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...
319
            y = knots_Y[label][idx]
0 ignored issues
show
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...
320
321
            lineas[i].set_xdata(x)
322
            lineas[i].set_ydata(y)
323
324
            if textos[i] is not None:
325
                if len(x) > 0:    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
326
                    textos[i].set_position((x[-1]+0.015, y[-1]+0.015))
327
                    textos[i].set_text(label)
328
                else:
329
                    textos[i].remove()
330
                    textos[i] = None
331
                    #textos[i].set_position((10, 10))
332
            else:
333
                if len(x) > 0:    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
334
                    textos[i] = ax.text(x[-1]+0.02, y[-1]+0.02, label, {'color':lineas[i].get_color(), 'fontsize':14})
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (118/100).

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

Loading history...
335
336
            if use_arrows:
337
                if flechas[i] is not None:
338
                    flechas[i].remove()
339
                    flechas[i] = None
340
341
                flechas[i] = ax.quiver(x[:-1], 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
342
                                   y[:-1], 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
Coding Style introduced by
Wrong continued indentation (add 4 spaces).
Loading history...
343
                                   arrow_pos*(x[1:] - x[:-1]), 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
Coding Style introduced by
Wrong continued indentation (add 4 spaces).
Loading history...
344
                                   arrow_pos*(y[1:] - y[:-1]), 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
Coding Style introduced by
Wrong continued indentation (add 4 spaces).
Loading history...
345
                                   scale_units='xy', angles='xy', scale=1, 
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 4 spaces).
Loading history...
Coding Style introduced by
Trailing whitespace
Loading history...
346
                                   width=0.0015, headwidth=10, headlength=10, headaxislength=6, 
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 4 spaces).
Loading history...
Coding Style introduced by
Trailing whitespace
Loading history...
347
                                   alpha=0.5, color=lineas[i].get_color())
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 4 spaces).
Loading history...
348
349
        fig.canvas.draw_idle()
350
351
352
353
    selected_knot = None
354
    selected_ind = None
355
    selected_x = None
356
    selected_y = None
357
358
359 View Code Duplication
    def submit_textbox(text):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
360
        nonlocal mod, knots, knots_names, knots_values, knots_jyears, knots_X, knots_Y
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable knots_Y does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots_jyears does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots_names does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots_X does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots_values does not seem to be defined.
Loading history...
361
362
        log.debug('Submited with:')
363
        log.debug(f'   selected_knot {selected_knot}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
364
        log.debug(f'   selected_ind {selected_ind}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
365
        log.debug(f'   selected_x {selected_x}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
366
        log.debug(f'   selected_y {selected_y}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
367
368
        if selected_knot is not None:        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
369
            mod.loc[selected_ind, 'label'] = text.upper()
370
371
            knots = dict(tuple(mod.groupby('label')))
372
            knots_names = list(knots.keys())
373
            knots_values = list(knots.values())
374
            knots_jyears = {k:Time(knots[k]['date'].to_numpy()).jyear for k in knots}
375
            knots_X = {k:knots[k]['X'].to_numpy() for k in knots}
0 ignored issues
show
Coding Style Naming introduced by
Variable name "knots_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...
376
            knots_Y = {k:knots[k]['Y'].to_numpy() for k in knots}
0 ignored issues
show
Coding Style Naming introduced by
Variable name "knots_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...
377
378
            log.debug(f"Updated index {selected_ind} to {text.upper()}")
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
379
        else:
380
            pass
381
382
        draw_all(slider_date.val)
383
384
385
    def line_select_callback(eclick, erelease):
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (17/15).
Loading history...
386
        nonlocal selected_knot,selected_x, selected_y, selected_ind
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable selected_knot does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable selected_y does not seem to be defined.
Loading history...
Coding Style introduced by
Exactly one space required after comma
Loading history...
Comprehensibility Best Practice introduced by
The variable selected_x does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable selected_ind does not seem to be defined.
Loading history...
387
388
        # 1 eclick and erelease are the press and release events
389
        x1, y1 = eclick.xdata, eclick.ydata
0 ignored issues
show
Coding Style Naming introduced by
Variable name "x1" 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 "y1" 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...
390
        x2, y2 = erelease.xdata, erelease.ydata
0 ignored issues
show
Coding Style Naming introduced by
Variable name "y2" 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 "x2" 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...
391
        log.debug("GUI: (%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
0 ignored issues
show
Coding Style Best Practice introduced by
Use lazy % formatting in logging functions
Loading history...
392
        log.debug("GUI:  The button you used were: %s %s" % (eclick.button, erelease.button))
0 ignored issues
show
Coding Style Best Practice introduced by
Use lazy % formatting in logging functions
Loading history...
393
394
        selected_knot = None
395
        selected_x = None
396
        selected_y = None
397
        selected_ind = None
398
399
        for i, label in enumerate(knots_names):
0 ignored issues
show
Unused Code introduced by
The variable i seems to be unused.
Loading history...
400
            years = knots_jyears[label]
401
            idx = (slider_date.val-1.5 < years) & (years < slider_date.val)
402
403
            if np.sum(idx) == 0:
404
                continue # we did not select any component from this component, next one
405
406
            x = np.array(knots_X[label])
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...
407
            y = np.array(knots_Y[label])
0 ignored issues
show
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...
408
409
            # get points iside current rectangle for current date
410
            rect_idx = (x1 < x) & ( x < x2) & (y1 < y) & ( y < y2) & idx 
0 ignored issues
show
Coding Style introduced by
No space allowed after bracket
Loading history...
Coding Style introduced by
Trailing whitespace
Loading history...
411
412 View Code Duplication
            if np.sum(rect_idx) > 0:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
Unused Code introduced by
Unnecessary "else" after "break"
Loading history...
413
                textbox.set_val(label)
414
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
415
                selected_knot = label
416
                selected_x = x[rect_idx].ravel()
417
                selected_y = y[rect_idx].ravel()
418
                selected_ind = knots[label].index[rect_idx]
419
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
420
                log.debug(f'Selected {label} points  rect_idx {rect_idx} x {x[rect_idx]}, y {y[rect_idx]} with indices {selected_ind}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
Coding Style introduced by
This line is too long as per the coding-style (135/100).

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

Loading history...
421
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
422
                textbox.begin_typing(None)
423
                break # if we find selected components in this epoch, continue with renaming
424
            else:
425
                pass
426
427
        # print epoch of selected points:
428
        if selected_knot is not None:
429
            out.clear_output()
430
            out.append_stdout('Selected:\n')
431
            for idx in selected_ind:
432
                #print(f"Selected {mod.loc[idx, 'label']} {mod.loc[idx, 'date']}")
433
                out.append_stdout(f" -> {mod.loc[idx, 'label']} {mod.loc[idx, 'date'].strftime('%Y-%m-%d')}\n")
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (111/100).

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

Loading history...
434
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
435
        update(slider_date.val)
436
437
438 View Code Duplication
    def toggle_selector(event):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
439
        log.debug('GUI: Key pressed.')
440
        if event.key in ['Q', 'q'] and toggle_selector.RS.active:
441
            log.debug('Selector deactivated.')
442
            toggle_selector.RS.set_active(False)
443
        if event.key in ['S', 's'] and not toggle_selector.RS.active:
444
            log.debug('Selector activated.')
445
            toggle_selector.RS.set_active(True)
446
        if event.key in ['R', 'r']:
447
            log.debug('Selector deactivated.')
448
            toggle_selector.RS.set_active(False)
449
            textbox.begin_typing(None)
450
            #textbox.set_val('')
451
452
453
    toggle_selector.RS = RectangleSelector(ax, line_select_callback,
454
                                           drawtype='box', useblit=True,
455
                                           button=[1, 3],  # don't use middle button
456
                                           minspanx=0, minspany=0,
457
                                           spancoords='data',
458
                                           interactive=False)
459
460
461
    #plt.connect('key_press_event', toggle_selector)
462
    fig.canvas.mpl_connect('key_press_event', toggle_selector)
463
464
465
466
    from mpl_toolkits.axes_grid1 import make_axes_locatable
0 ignored issues
show
introduced by
Unable to import 'mpl_toolkits.axes_grid1'
Loading history...
introduced by
Import outside toplevel (mpl_toolkits.axes_grid1.make_axes_locatable)
Loading history...
467
468
    divider_slider = make_axes_locatable(ax)
469
    slider_ax = divider_slider.append_axes("top", size="3%", pad="4%")  
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
470
    slider_date = Slider(ax=slider_ax, label="Date", valmin=2007, valmax=2020, valinit=2008, valstep=0.2, orientation="horizontal")
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (131/100).

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

Loading history...
471
    slider_date.on_changed(update)
472
473
    #divider_textbox = make_axes_locatable(ax)
474
    #textbox_ax = divider_textbox.append_axes("bottom", size="3%", pad="4%") 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
475
    textbox_ax = fig.add_axes([0.3,0.015,0.5,0.05])
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
476
    textbox = TextBox(textbox_ax, 'Knot name:', initial='None')
477
    textbox.on_submit(submit_textbox)
478
479
480
481
    ax.set_xlim([-1.0, +1.0])
482
    ax.set_ylim([-1.0, +1.0])
483
    ax.set_aspect('equal')
484
485
    fig.suptitle('S to select, R to rename, Q to deactivate selector')
486
487
    print('Usage:',
488
          '-> S to select, R to rename, Q to deactivate selector',
489
          '-> To delete the knot, name it with a whitespace', 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
490
          '-> You can select points from one component at a time',
491
          '-> If you use the zoom or movement tools, remember to unselect them',
492
          sep='\n')
493
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
494
    plt.show()
495
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
496
    out.display_output()
497
  
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
498
    return mod
499
500
501
502
503
504
505
def KnotsIdGUI(mod):
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (28/15).
Loading history...
Coding Style Naming introduced by
Function name "KnotsIdGUI" 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...
506
    """
507
        Prompt a GUI to select identified knots and alter their label, reprenting their
508
        time evolution.
509
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
510
        It can be used inside jupyter notebooks, using '%matplotlib widget' first.
511
       
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
512
        Parameters:
513
        -----------
514
         mod : :pd.DataFrame:
515
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
516
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
517
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
518
        Returns:
519
        --------
520
         mod : :pd.DataFrame:
521
             pandas.DataFrame containing every knot with their altered labels, with 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
522
             at least columns 'label', 'date', 'X', 'Y', 'Flux (Jy)'.
523
    """
524
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
525
    mod = mod.copy()
526
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
527
    knots = dict(tuple(mod.groupby('label')))
528
    knots_names = list(knots.keys())
529
    knots_values = list(knots.values())
530
    knots_jyears = {k:Time(knots[k]['date'].to_numpy()).jyear for k in knots}
531
    knots_dates = {k:knots[k]['date'].to_numpy() for k in knots}
532
    knots_fluxes = {k:knots[k]['Flux (Jy)'].to_numpy() for k in knots}
533
534
    from matplotlib.widgets import TextBox, RectangleSelector
0 ignored issues
show
introduced by
Import outside toplevel (matplotlib.widgets.TextBox, matplotlib.widgets.RectangleSelector)
Loading history...
introduced by
Unable to import 'matplotlib.widgets'
Loading history...
535
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
536
    out = get_output()
537
538
    fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8,5))
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
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...
539
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
540
    lineas = list()
541
    textos = list()
542
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
543
    def draw_all():
544
        nonlocal lineas, textos
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable textos does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable lineas does not seem to be defined.
Loading history...
545
546
        for linea in lineas:
547
            if linea is not None:
548
                linea.remove()
549
        for texto in textos:
550
            if texto is not None:
551
                texto.remove()
552
553
        ax.set_prop_cycle(None)
554
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
555
        lineas = list()
556
        textos = list()
557
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
558
        #ax.clear() # either clear the whole axis or remove every artist separetly
559
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
560
        for i, label in enumerate(knots_names):
561
            x, y = knots_jyears[label], knots_fluxes[label]
0 ignored issues
show
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...
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...
562
563
            if len(x) > 0:
564
                lineas.append(ax.plot(x, y, '.-', linewidth=0.8, alpha=0.5, label=label)[0])
565
            else:
566
                lineas.append(None)
567
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
568
            if len(x) > 0:
569
                #textos.append(ax.annotate(label, (x[0], y[0]), (-28,-10), textcoords='offset points', color=lineas[i].get_color(), fontsize=14))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (145/100).

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

Loading history...
570
                textos.append(ax.text(x[0], y[0], label, {'color':lineas[i].get_color(), 'fontsize':14}))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (105/100).

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

Loading history...
571
            else:
572
                textos.append(None)
573
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
574
        fig.canvas.draw_idle() # if removed every artist separately instead of ax.clear()
575
576
577
    def update():
578
        nonlocal lineas, textos
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable lineas does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable textos does not seem to be defined.
Loading history...
579
580
        for i, label in enumerate(knots_names):   
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
581
            x, y = knots_jyears[label], knots_fluxes[label]
0 ignored issues
show
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...
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...
582
583
            if lineas[i] is not None:
584
                if len(x) > 0:
585
                    lineas[i].set_xdata(x)
586
                    lineas[i].set_ydata(y)
587
                else:
588
                    lineas[i].remove()
589
                    lineas[i] = None
590
            else:
591
                if len(x) > 0:    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
592
                    lineas[i] = ax.plot(x, y, '.-', linewidth=0.8, alpha=0.5, label=label)[0]
593
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
594
            if textos[i] is not None:
595
                if len(x) > 0:    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
596
                    textos[i].set_position((x[0], y[0]))
597
                    textos[i].set_text(label)
598
                else:
599
                    textos[i].remove()
600
                    textos[i] = None
601
                    #textos[i].set_position((10, 10))
602
            else:
603
                if len(x) > 0:    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
604
                    #textos[i] = ax.annotate(label, (x[0], y[0]), (-24,-10), textcoords='offset points', color=lineas[i].get_color(), fontsize=15)
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (146/100).

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

Loading history...
605
                    textos[i] = ax.text(x[0], y[0], label, {'color':lineas[i].get_color(), 'fontsize':14})
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...
606
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
607
        fig.canvas.draw_idle()    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
608
   
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
609
610
    selected_knot = None
611
    selected_ind = None
612
    selected_date = None
613
    selected_flux = None
614
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
615 View Code Duplication
    def submit_textbox(text):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
616
        nonlocal mod, knots, knots_names, knots_values, knots_jyears, knots_dates, knots_fluxes
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable knots_names does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots_jyears does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots_values does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots_dates does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable knots_fluxes does not seem to be defined.
Loading history...
617
618
        log.debug('Submited with:')
619
        log.debug(f'   selected_knot {selected_knot}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
620
        log.debug(f'   selected_ind {selected_ind}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
621
        log.debug(f'   selected_flux {selected_flux}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
622
        log.debug(f'   selected_date {selected_date}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
623
624
        if selected_knot is not None:        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
625
            mod.loc[selected_ind, 'label'] = text.upper()
626
627
            knots = dict(tuple(mod.groupby('label')))
628
            knots_names = list(knots.keys())
629
            knots_values = list(knots.values())
630
            knots_jyears = {k:Time(knots[k]['date'].to_numpy()).jyear for k in knots}
631
            knots_dates = {k:knots[k]['date'].to_numpy() for k in knots}
632
            knots_fluxes = {k:knots[k]['Flux (Jy)'].to_numpy() for k in knots}
633
634
            print(f"Updated index {selected_ind} to {text.upper()}")
635
        else:
636
            pass
637
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
638
        draw_all()
639
640
    def line_select_callback(eclick, erelease):
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (20/15).
Loading history...
641
        nonlocal selected_knot,selected_date, selected_flux, selected_ind
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable selected_flux does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable selected_date does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable selected_ind does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable selected_knot does not seem to be defined.
Loading history...
Coding Style introduced by
Exactly one space required after comma
Loading history...
642
643
        # 1 eclick and erelease are the press and release events
644
        x1, y1 = eclick.xdata, eclick.ydata
0 ignored issues
show
Coding Style Naming introduced by
Variable name "y1" 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 "x1" 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...
645
        x2, y2 = erelease.xdata, erelease.ydata
0 ignored issues
show
Coding Style Naming introduced by
Variable name "x2" 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 "y2" 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...
646
        log.debug("GUI: (%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
0 ignored issues
show
Coding Style Best Practice introduced by
Use lazy % formatting in logging functions
Loading history...
647
        log.debug("GUI:  The button you used were: %s %s" % (eclick.button, erelease.button))
0 ignored issues
show
Coding Style Best Practice introduced by
Use lazy % formatting in logging functions
Loading history...
648
649
        selected_knot = None
650
        selected_date = None
651
        selected_flux = None
652
        selected_ind = None
653
654
        for i, label in enumerate(knots_names):
0 ignored issues
show
Unused Code introduced by
The variable i seems to be unused.
Loading history...
655
            years = knots_jyears[label]
656
            fluxes = knots_fluxes[label]
657
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
658
            # get points iside current rectangle for current date
659
            rect_idx = (x1 < years) & ( years < x2) & (y1 < fluxes) & ( fluxes < y2) 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
Coding Style introduced by
No space allowed after bracket
Loading history...
660
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
661
            if np.sum(rect_idx) == 0:
662
                continue # we did not select any component from this component, next one
663
664
            x = np.array(years)
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...
665
            y = np.array(fluxes)
0 ignored issues
show
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...
666
667 View Code Duplication
            if np.sum(rect_idx) > 0:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
Unused Code introduced by
Unnecessary "else" after "break"
Loading history...
668
                textbox.set_val(label)
669
                selected_knot = label
670
                selected_x = x[rect_idx].ravel()
0 ignored issues
show
Unused Code introduced by
The variable selected_x seems to be unused.
Loading history...
671
                selected_y = y[rect_idx].ravel()
0 ignored issues
show
Unused Code introduced by
The variable selected_y seems to be unused.
Loading history...
672
                selected_ind = knots[label].index[rect_idx]
673
                log.debug(f'Selected {label} points  rect_idx {rect_idx} date {x[rect_idx]}, flux {y[rect_idx]} with indices {selected_ind}')
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (141/100).

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

Loading history...
introduced by
Use lazy % formatting in logging functions
Loading history...
674
                break # if we find selected components in this epoch, continue with renaming
675
            else:
676
                pass
677
678
        # print epoch of selected points:
679
        if selected_knot is not None:
680
            out.clear_output()
681
            out.append_stdout('Selected:\n')
682
            for idx in selected_ind:
683
                #print(f"Selected {mod.loc[idx, 'label']} {mod.loc[idx, 'date']}")
684
                out.append_stdout(f" -> {mod.loc[idx, 'label']} {mod.loc[idx, 'date'].strftime('%Y-%m-%d')}\n")
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (111/100).

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

Loading history...
685
           
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
686
        update()
687
688
689 View Code Duplication
    def toggle_selector(event):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
690
        log.debug('GUI: Key pressed.')
691
        if event.key in ['Q', 'q'] and toggle_selector.RS.active:
692
            log.debug('Selector deactivated.')
693
            toggle_selector.RS.set_active(False)
694
        if event.key in ['S', 's'] and not toggle_selector.RS.active:
695
            log.debug('Selector activated.')
696
            toggle_selector.RS.set_active(True)
697
        if event.key in ['R', 'r']:
698
            log.debug('Selector deactivated.')
699
            toggle_selector.RS.set_active(False)
700
            textbox.begin_typing(None)
701
            #textbox.set_val('')
702
703
704
    toggle_selector.RS = RectangleSelector(ax, line_select_callback,
705
                                           drawtype='box', useblit=True,
706
                                           button=[1, 3],  # don't use middle button
707
                                           minspanx=0, minspany=0,
708
                                           spancoords='data',
709
                                           interactive=False)
710
711
712
    fig.canvas.mpl_connect('key_press_event', toggle_selector)
713
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
714
    from mpl_toolkits.axes_grid1 import make_axes_locatable
0 ignored issues
show
introduced by
Import outside toplevel (mpl_toolkits.axes_grid1.make_axes_locatable)
Loading history...
introduced by
Unable to import 'mpl_toolkits.axes_grid1'
Loading history...
715
716
    divider_textbox = make_axes_locatable(ax)
717
    textbox_ax = divider_textbox.append_axes("bottom", size="10%", pad="15%") 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
718
    #textbox_ax = fig.add_axes([0.3,0,0.5,0.05])
719
    textbox = TextBox(textbox_ax, 'Knot name:', initial='None')
720
    textbox.on_submit(submit_textbox)
721
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
722
    draw_all()
723
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
724
    #ax.autoscale()
725
    ax.set_xlabel('date (year)')
726
    ax.set_ylabel('Flux (Jy)')
727
    ax.set_title('Flux from each component')
728
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
729
    xlims = Time(np.amin(mod['date'])).jyear, Time(np.amax(mod['date'])).jyear
730
    ax.set_xlim((xlims[0]-0.03*np.abs(xlims[1]-xlims[0]), xlims[1]+0.03*np.abs(xlims[1]-xlims[0])))
731
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
732
    fig.suptitle('S to select, R to rename, Q to deactivate selector')
733
734
    print('Usage:',
735
          '-> S to select, R to rename, Q to deactivate selector',
736
          '-> To delete the knot, name it with a whitespace', 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
737
          '-> You can select points from one component at a time',
738
          '-> If you use the zoom or movement tools, remember to unselect them',
739
          sep='\n')
740
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
741
    plt.show()
742
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
743
    out.display_output()
744
745
    return mod
746
747
748
749
def KnotsIdReadMod(path=None, file_list=None):
0 ignored issues
show
Coding Style Naming introduced by
Function name "KnotsIdReadMod" 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...
Unused Code introduced by
The argument file_list seems to be unused.
Loading history...
750
    """
751
        Read *_mod.mod files as printed by diffmap, return a dataframe containing all information ready
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...
752
        to be worked on for labelling and to be used with these GUIs.
753
   
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
754
        Parameters:
755
        -----------
756
         path : :str:
757
             string indicating the path to the mod files to be used, their names must end in the format
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...
758
             '%Y-%m-%d_mod.mod', for example, path = 'vlbi/ftree/*/*_mod.mod'.
759
             
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
760
        Returns:
761
        -----------
762
         mod : :pd.DataFrame:
763
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
764
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
765
    """
766
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
767
    mod_dates_str = list()
768
    mod_dates = list()
769
    mod_data = list()
770
771
    for f in glob.glob(f'{path}'):
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...
772
        match = re.findall(r'([0-9]{4}-[0-9]{2}-[0-9]{2})_mod.mod', f)
773
        if not len(match) > 0:
774
            continue
775
776
        date_str = match[0]
777
        date = datetime.strptime(date_str, '%Y-%m-%d')
778
779
        mod_dates_str.append(date_str)
780
        mod_dates.append(date)
781
        mod_data.append(pd.read_csv(f, sep='\s+', comment='!', names=['Flux (Jy)', 'Radius (mas)', 'Theta (deg)', 'Major FWHM (mas)', 'Axial ratio', 'Phi (deg)', 'T', 'Freq (Hz)', 'SpecIndex']))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (194/100).

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

Loading history...
Bug introduced by
A suspicious escape sequence \s was found. Did you maybe forget to add an r prefix?

Escape sequences in Python are generally interpreted according to rules similar to standard C. Only if strings are prefixed with r or R are they interpreted as regular expressions.

The escape sequence that was used indicates that you might have intended to write a regular expression.

Learn more about the available escape sequences. in the Python documentation.

Loading history...
782
783
    # sort by date    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
784
    idx = np.argsort(mod_dates)
785
    mod_dates_str = list(np.array(mod_dates_str, dtype=object)[idx])
786
    mod_dates = list(np.array(mod_dates, dtype=object)[idx])
787
    mod_data = list(np.array(mod_data, dtype=object)[idx])
788
789
    # fix stupid 'v' in columns, insert a label field, add X, Y columns
790
    for i in range(len(mod_dates)):
0 ignored issues
show
unused-code introduced by
Consider using enumerate instead of iterating with range and len
Loading history...
791
        mod_data[i].insert(0, 'label', value=None)
792
        mod_data[i].insert(1, 'date', value=mod_dates[i])
793
794
        mod_data[i]['Flux (Jy)'] = mod_data[i]['Flux (Jy)'].str.strip('v').astype(float)
795
        mod_data[i]['Radius (mas)'] = mod_data[i]['Radius (mas)'].str.strip('v').astype(float)
796
        mod_data[i]['Theta (deg)'] = mod_data[i]['Theta (deg)'].str.strip('v').astype(float)
797
798
        mod_data[i].insert(5, 'X', mod_data[i]['Radius (mas)']*np.cos(np.pi/180*(mod_data[i]['Theta (deg)']-90)))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (113/100).

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

Loading history...
799
        mod_data[i].insert(6, 'Y', mod_data[i]['Radius (mas)']*np.sin(np.pi/180*(mod_data[i]['Theta (deg)']-90)))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (113/100).

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

Loading history...
800
801
     
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
802
    mod = pd.concat(mod_data, ignore_index=True)
803
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
804
    return mod
805
806
807
def KnotsIdSaveMod(mod, path=None):
0 ignored issues
show
Coding Style Naming introduced by
Function name "KnotsIdSaveMod" 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...
Unused Code introduced by
The argument path seems to be unused.
Loading history...
introduced by
Missing function or method docstring
Loading history...
Unused Code introduced by
The argument mod seems to be unused.
Loading history...
808
    pass
809
810
def KnotsIdReadCSV(path=None):
0 ignored issues
show
Coding Style Naming introduced by
Function name "KnotsIdReadCSV" 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...
811
    """
812
        Read Knots data to .csv files (as done by Svetlana? ##)
813
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
814
        Each knot label has its own {label}.csv. To be compatible with Svetlana's format, 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
815
        columns should be modified to:
816
        'Date' (jyear), 'MJD', 'X(mas)', 'Y(mas)', 'Flux(Jy)'
817
        These columns are derived from the ones in `mod`, old ones are removed.
818
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
819
        Parameters:
820
        -----------
821
         path: :str:
822
             string containing the path to read files from eg:
823
             path = 'myknows/*.csv'
824
        Returns:
825
        --------
826
         mod : :pd.DataFrame:
827
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
828
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
829
    """
830
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
831
    if path is None:
832
        log.error('Path not specified')
833
        raise Exception('Path not specified')
834
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
835
    dataL = list()
0 ignored issues
show
Coding Style Naming introduced by
Variable name "dataL" 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...
836
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
837
    for f in glob.glob(f'{path}'):
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...
838
        match = re.findall(r'/(.*).csv', f)
839
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
840
        if not len(match) > 0:
841
            continue
842
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
843
        knot_name = match[0]
844
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
845
        log.debug(f'Loading {knot_name} from {f}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
846
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
847
        knot_data = pd.read_csv(f, parse_dates=['date'], date_parser=pd.to_datetime)
848
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
849
        dataL.append((knot_name, knot_data))
850
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
851
    mod = pd.concat(dict(dataL), ignore_index=True)
852
853
    return mod
854
855
856
857
def KnotsIdSaveCSV(mod, path=None):
0 ignored issues
show
Coding Style Naming introduced by
Function name "KnotsIdSaveCSV" 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...
858
    """
859
        Save Knots data to .csv files (as done by Svetlana? ##)
860
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
861
        Each knot label has its own {label}.csv. To be compatible with Svetlana's format, 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
862
        columns should be modified to:
863
        'Date' (jyear), 'MJD', 'X(mas)', 'Y(mas)', 'Flux(Jy)'
864
        These columns are derived from the ones in `mod`, old ones are removed.
865
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
866
        Parameters:
867
        -----------
868
         mod : :pd.DataFrame:
869
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
870
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
871
         path: :str:
872
             string containing the path to which the files are to be saved, eg:
873
             path = 'my_knots/'
874
             
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
875
        Returns:
876
        --------
877
         None
878
    """
879
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
880
    if path is None:
881
        log.error('Path not specified')
882
        raise Exception('Path not specified')
883
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
884
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
885
    mod = mod.copy()
886
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
887
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
888
    mod_dict = dict(list(mod.groupby('label')))
889
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
890
    for label, data in mod_dict.items():
891
        data = data.copy()
892
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
893
        #data.insert(0, 'Date', Time(data['date']).jyear)
894
        #data.insert(1, 'MJD', Time(data['date']).mjd)
895
        #data = data.rename(columns={'X': 'X (mas)', 'Y': 'Y (mas)'})
896
        #data = data.drop(columns=['date'])
897
        #data = data.drop(columns=['label'])
898
        #if 'Radius (mas)' in data.columns:
899
        #    data = data.rename(columns={'Radius (mas)':'R(mas)'})
900
        #data.columns = data.columns.str.replace(' ', '')
901
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
902
        data.to_csv(f'{path}/{label}.csv', index=False) 
0 ignored issues
show
Coding Style introduced by
Final newline missing
Loading history...