Passed
Pull Request — main (#25)
by
unknown
07:44
created

mutis.astro   F

Complexity

Total Complexity 130

Size/Duplication

Total Lines 1101
Duplicated Lines 10.81 %

Importance

Changes 0
Metric Value
eloc 588
dl 119
loc 1101
rs 2
c 0
b 0
f 0
wmc 130

10 Functions

Rating   Name   Duplication   Size   Complexity  
B KnotsIdReadMod_from_diffmap() 0 60 5
A KnotsIdReadCSV() 0 44 4
F KnotsIdAuto() 0 115 20
F KnotsId2dGUI() 60 302 41
C KnotsIdSaveMod() 0 84 11
A pol_angle_reshape() 0 20 4
F KnotsIdGUI() 59 247 30
A KnotsIdSaveCSV() 0 46 3
B KnotsIdReadMod() 0 80 7
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
0 ignored issues
show
coding-style introduced by
Too many lines in module (1100/1000)
Loading history...
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"]
20
21
log = logging.getLogger(__name__)
22
23
# TODO: to be able to save previous labels in _mod.mod and be kepto after processing with diffmap
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
24
25
#############################################################################
26
### Output compatible with IPython widgets and with plain python console: ###
27
#
28
# With this we can follow follow a commen scheme:
29
#
30
# def someGUIfunction():
31
#     out = get_output()
32
#     ... gui things...
33
#         out.clear_output()
34
#         out.append_stdout('some msg')
35
#     out.display_output()
36
#
37
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...
38
    @staticmethod
39
    def append_stdout(msg):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
40
        print(msg, end='')
41
    @staticmethod
42
    def clear_output():
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
43
        print('\n')
44
    @staticmethod
45
    def display_output():
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
46
        pass
47
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
48
def get_output():
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
49
    try:
50
        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...
51
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
52
        import ipywidgets
0 ignored issues
show
introduced by
Import outside toplevel (ipywidgets)
Loading history...
introduced by
Unable to import 'ipywidgets'
Loading history...
53
        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...
54
            def __init__(self, *args, **kwargs):
0 ignored issues
show
introduced by
Useless super delegation in method '__init__'
Loading history...
55
                super().__init__(*args, **kwargs)
56
            def display_output(self):
0 ignored issues
show
introduced by
Missing function or method docstring
Loading history...
57
                display(self)
0 ignored issues
show
Comprehensibility Best Practice introduced by
Undefined variable 'display'
Loading history...
Comprehensibility Best Practice introduced by
The variable display does not seem to be defined.
Loading history...
58
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
59
        out = pretty_printer(layout={'border': '1px solid black'})
60
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
61
        return out
62
    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...
63
        return plain_printer
64
#############################################################################
65
   
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
66
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
67
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...
68
    """
69
        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...
70
    """
71
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
72
    s = np.array(s)
73
    s = np.mod(s,180) # s % 180
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
74
75
    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...
76
    for i in range(1,len(s)):
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
77
        #if t[i]-t[i-1] < 35:
78
        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...
79
        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...
80
        for m in range(0,100):
0 ignored issues
show
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...
Coding Style introduced by
Exactly one space required after comma
Loading history...
81
            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...
82
            if np.abs(s[i]+180*m2-sn[i-1]) < d:
83
                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...
84
                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...
85
        sn[i] = s[i]+180*n
86
    return sn 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
87
88
89
90
91
92
93
#########################################
94
################# Knots #################
95
#########################################
96
97
98
99
def  KnotsIdAuto(mod):
0 ignored issues
show
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...
Comprehensibility introduced by
This function exceeds the maximum number of variables (18/15).
Loading history...
100
    """
101
       Identify the knots appearing in several epochs giving them names, based on their position.
102
       
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
103
        Parameters:
104
        -----------
105
         mod : :pd.DataFrame:
106
             pandas.DataFrame containing every knot, with 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
107
             at least columns 'label', 'date', 'X', 'Y', 'Flux (Jy)'.
108
       
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
109
        Returns: mod
110
        --------
111
         mod : :pd.DataFrame:
112
             pandas.DataFrame containing every knot with their altered labels, with 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
113
             at least columns 'label', 'date', 'X', 'Y', 'Flux (Jy)'.
114
         
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
115
    """
116
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
117
    mod_date_dict = dict(list((mod.groupby('date'))))
118
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
119
    mod_dates = list(Time(list(mod_date_dict.keys())).datetime)
120
    mod_dates_str = list(Time(list(mod_date_dict.keys())).strftime('%Y-%m-%d'))
121
    mod_data = list(mod_date_dict.values())
122
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
123
    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...
124
    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...
125
    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...
126
127
128
    thresh = 0.03 #0.062
129
130
    news = 0
131
132
    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...
133
        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...
134
135
        if not len(data.index) > 0:
136
            log.error(' -> Error, no components found')
137
            break
138
139
        log.debug(f' it has {len(data.index)} components')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
140
141
        Bx[i] = np.ravel(data['X'])
142
        By[i] = np.ravel(data['Y'])
143
        B[i] = np.full(len(data.index), fill_value=None)
144
145
        # if first epoch, just give them new names...:
146
        if i == 0:
147
            log.debug(' first epoch, giving names...')
148
149
            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...
150
                if data['Flux (Jy)'].iloc[n] < 0.001:
151
                    log.debug('  skipping, too weak')
152
                    break
153
                if n == 0:
154
                    B[i][n] = 'A0'
155
                else:
156
                    news = news + 1
157
                    B[i][n] = f'B{news}'
158
            log.debug(f' -> FOUND: {B[i]}\n')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
159
            continue
160
161
        # if not first epoch...:
162
163
        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...
164
            if data['Flux (Jy)'].iloc[n] < 0.001:
165
                    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...
166
                    break
0 ignored issues
show
Coding Style introduced by
The indentation here looks off. 16 spaces were expected, but 20 were found.
Loading history...
167
            if n == 0:
168
                B[i][n] = 'A0'
169
            else:
170
                log.debug(f' -> id component {n}...')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
171
172
                close = None
173
174
                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...
175
                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...
176
                    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...
177
178
                    if not len(Bx[i-a])>0:
0 ignored issues
show
Coding Style introduced by
Exactly one space required around comparison
Loading history...
179
                        break
180
181
                    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...
182
183
                    for m in range(len(dist)):
0 ignored issues
show
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...
unused-code introduced by
Consider using enumerate instead of iterating with range and len
Loading history...
184
                        if B[i-a][m] in B[i]:
185
                            dist[m] = np.inf
186
187
                    if np.amin(dist) < thresh*a**1.5:
188
                        close = np.argmin(dist)
189
190
                    if B[i-a][close] in B[i]:
191
                            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...
192
193
194
                if close is None:
195
                    news = news + 1
196
                    B[i][n] = f'B{news}'
197
                    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...
198
                else:
199
                    log.debug(f'   component {n} is close to {B[i-a][close]} of previous epoch ({a} epochs before)')
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 (116/100).

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

Loading history...
200
                    B[i][n] = B[i-a][close]
201
202
203
        log.debug(f' -> FOUND: {B[i]}\n')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
204
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
205
                 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
206
    for i, (date, data) in enumerate(zip(mod_dates, mod_data)):
207
        data['label'] = B[i]
208
         
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
209
    mod = pd.concat(mod_data, ignore_index=True)
210
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
211
    log.debug('Finito!')
212
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
213
    return mod
214
215
216
217
def KnotsId2dGUI(mod, twidth=0.75, use_arrows=False, arrow_pos=1.0):
0 ignored issues
show
Comprehensibility introduced by
This function exceeds the maximum number of variables (35/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...
218
    """
219
        Prompt a GUI to select identified knots and alter their label, reprenting their 2D
220
        spatial distribution in different times.
221
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
222
        It can be used inside jupyter notebooks, using '%matplotlib widget' first.
223
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
224
        Parameters:
225
        -----------
226
         mod : :pd.DataFrame:
227
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
228
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
229
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
230
        Returns:
231
        --------
232
         mod : :pd.DataFrame:
233
             pandas.DataFrame containing every knot with their altered labels, with 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
234
             at least columns 'label', 'date', 'X', 'Y', 'Flux (Jy)'.
235
    """
236
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
237
    mod = mod.copy()
238
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
239
    knots = dict(tuple(mod.groupby('label')))
240
    knots_names = list(knots.keys())
241
    knots_values = list(knots.values())
242
    knots_jyears = {k:Time(knots[k]['date'].to_numpy()).jyear for k in knots}
243
    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...
244
    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...
245
246
247
    from matplotlib.widgets import Slider, Button, TextBox, RectangleSelector
0 ignored issues
show
introduced by
Unable to import 'matplotlib.widgets'
Loading history...
Unused Code introduced by
Unused Button imported from matplotlib.widgets
Loading history...
introduced by
Import outside toplevel (matplotlib.widgets.Slider, matplotlib.widgets.Button, matplotlib.widgets.TextBox, matplotlib.widgets.RectangleSelector)
Loading history...
248
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
249
    out = get_output()
250
251
    fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(8,8))
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...
252
253
    lineas = list()
254
    flechas = list()
255
    textos = list()
256
257
    def draw_all(val=2008):
258
        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...
259
260
        # instead of clearing the whole axis, remove artists
261
        for linea in lineas:
262
            if linea is not None:
263
                linea.remove()
264
        for texto in textos:
265
            if texto is not None:
266
                texto.remove()
267
        for flecha in flechas:
268
            if flecha is not None:
269
                flecha.remove()
270
        ax.set_prop_cycle(None)
271
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
272
        lineas = list()
273
        flechas = list()
274
        textos = list()
275
276
        xlim, ylim = ax.get_xlim(), ax.get_ylim()
277
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
278
        #ax.clear() # either clear the whole axis or remove every artist separetly
279
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
280
        for i, label in enumerate(knots_names):
281
            years = knots_jyears[label]
282
            idx = (val-twidth < years) & (years < val)
283
            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...
284
            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...
285
286
            if len(x) > 0:
287
                if label == '' or label == 'None': # if it is unlabelled, do not connect it.
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "label in ('', 'None')"
Loading history...
288
                    lineas.append(ax.plot(x, y, '.', linewidth=0.6, alpha=0.4, label=label, color='black')[0])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (110/100).

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

Loading history...
289
                else:
290
                    lineas.append(ax.plot(x, y, '.-', linewidth=0.6, alpha=0.4, label=label)[0])
291
            else:
292
                lineas.append(None)
293
294
            if use_arrows:
295
                if len(x) > 1 and label != '' and label != 'None':
296
                    flechas.append(ax.quiver(x[:-1], 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
297
                               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...
298
                               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 14 spaces).
Loading history...
299
                               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...
300
                               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...
301
                               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...
302
                               alpha=0.5, color=lineas[i].get_color()))
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 14 spaces).
Loading history...
303
                else:
304
                    flechas.append(None)
305
306
            if len(x) > 0:
307
                #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...
308
                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...
309
            else:
310
                textos.append(None)
311
312
        ax.set_xlim(xlim)
313
        ax.set_ylim(ylim)
314
        ax.set_aspect('equal')
315
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
316
        fig.canvas.draw_idle() # if removed every artist separately instead of ax.clear()
317
318
    draw_all()
319
320
    def update(val):
321
        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 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...
322
323
        for i, label in enumerate(knots_names):
324
            years = knots_jyears[label]
325
            idx = (val-twidth < years) & (years < val)
326
            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...
327
            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...
328
329 View Code Duplication
            if lineas[i] is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
330
                if len(x) > 0:
331
                    lineas[i].set_xdata(x)
332
                    lineas[i].set_ydata(y)
333
                else:
334
                    lineas[i].remove()
335
                    lineas[i] = None
336
            else:
337
                if len(x) > 0:
338
                    if label == '' or label == 'None': # if it is unlabelled, do not connect it.
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "label in ('', 'None')"
Loading history...
339
                        lineas[i] = ax.plot(x, y, '.', linewidth=0.8, alpha=0.5, label=label, color='black')[0]
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...
340
                    else:
341
                        lineas[i] = ax.plot(x, y, '.-', linewidth=0.8, alpha=0.5, label=label)[0]
342
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
343
344
            if textos[i] is not None:
345
                if len(x) > 0:    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
346
                    textos[i].set_position((x[-1]+0.015, y[-1]+0.015))
347
                    textos[i].set_text(label)
348
                else:
349
                    textos[i].remove()
350
                    textos[i] = None
351
                    #textos[i].set_position((10, 10))
352
            else:
353
                if len(x) > 0:    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
354
                    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...
355
356
            if use_arrows:
357
                if flechas[i] is not None:
358
                    flechas[i].remove()
359
                    flechas[i] = None
360
                if len(x) > 1 and label != '' and label != 'None':
361
                    flechas[i] = ax.quiver(x[:-1], 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
362
                                       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...
363
                                       arrow_pos*(x[1:] - x[:-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...
364
                                       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...
365
                                       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...
366
                                       width=0.0015, headwidth=10, headlength=10, headaxislength=6, 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
Coding Style introduced by
Wrong continued indentation (add 4 spaces).
Loading history...
367
                                       alpha=0.5, color=lineas[i].get_color())
0 ignored issues
show
Coding Style introduced by
Wrong continued indentation (add 4 spaces).
Loading history...
368
369
        fig.canvas.draw_idle()
370
371
372
373
    selected_knot = None
374
    selected_ind = None
375
    selected_x = None
376
    selected_y = None
377
378
379 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...
380
        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 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_names 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_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...
381
382
        log.debug('Submited with:')
383
        log.debug(f'   selected_knot {selected_knot}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
384
        log.debug(f'   selected_ind {selected_ind}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
385
        log.debug(f'   selected_x {selected_x}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
386
        log.debug(f'   selected_y {selected_y}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
387
388
        if selected_knot is not None:        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
389
            mod.loc[selected_ind, 'label'] = text.upper().strip(' ')
390
391
            knots = dict(tuple(mod.groupby('label')))
392
            knots_names = list(knots.keys())
393
            knots_values = list(knots.values())
394
            knots_jyears = {k:Time(knots[k]['date'].to_numpy()).jyear for k in knots}
395
            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...
396
            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...
397
398
            log.debug(f"Updated index {selected_ind} to {text.upper()}")
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
399
        else:
400
            pass
401
402
        draw_all(slider_date.val)
403
404
405
    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...
406
        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_ind does not seem to be defined.
Loading history...
Comprehensibility Best Practice introduced by
The variable selected_x does not seem to be defined.
Loading history...
407
408
        # 1 eclick and erelease are the press and release events
409
        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...
410
        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...
411
        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...
412
        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...
413
414
        selected_knot = None
415
        selected_x = None
416
        selected_y = None
417
        selected_ind = None
418
419
        for i, label in enumerate(knots_names):
0 ignored issues
show
Unused Code introduced by
The variable i seems to be unused.
Loading history...
420
            years = knots_jyears[label]
421
            idx = (slider_date.val-twidth < years) & (years < slider_date.val)
422
423
            if np.sum(idx) == 0:
424
                continue # we did not select any component from this component, next one
425
426
            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...
427
            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...
428
429
            # get points iside current rectangle for current date
430
            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...
431
432 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...
433
                textbox.set_val(label)
434
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
435
                selected_knot = label
436
                selected_x = x[rect_idx].ravel()
437
                selected_y = y[rect_idx].ravel()
438
                selected_ind = knots[label].index[rect_idx]
439
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
440
                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
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...
introduced by
Use lazy % formatting in logging functions
Loading history...
441
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
442
                textbox.begin_typing(None)
443
                break # if we find selected components in this epoch, continue with renaming
444
            else:
445
                pass
446
447
        # print epoch of selected points:
448
        if selected_knot is not None:
449
            out.clear_output()
450
            out.append_stdout('Selected:\n')
451
            for idx in selected_ind:
452
                #print(f"Selected {mod.loc[idx, 'label']} {mod.loc[idx, 'date']}")
453
                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...
454
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
455
        update(slider_date.val)
456
457
458 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...
459
        log.debug('GUI: Key pressed.')
460
        if event.key in ['Q', 'q'] and toggle_selector.RS.active:
461
            log.debug('Selector deactivated.')
462
            toggle_selector.RS.set_active(False)
463
        if event.key in ['S', 's'] and not toggle_selector.RS.active:
464
            log.debug('Selector activated.')
465
            toggle_selector.RS.set_active(True)
466
        if event.key in ['R', 'r']:
467
            log.debug('Selector deactivated.')
468
            toggle_selector.RS.set_active(False)
469
            textbox.begin_typing(None)
470
            #textbox.set_val('')
471
472
473
    toggle_selector.RS = RectangleSelector(ax, line_select_callback,
474
                                           drawtype='box', useblit=True,
475
                                           button=[1, 3],  # don't use middle button
476
                                           minspanx=0, minspany=0,
477
                                           spancoords='data',
478
                                           interactive=False)
479
480
481
    #plt.connect('key_press_event', toggle_selector)
482
    fig.canvas.mpl_connect('key_press_event', toggle_selector)
483
484
485
486
    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...
487
488
    divider_slider = make_axes_locatable(ax)
489
    slider_ax = divider_slider.append_axes("top", size="3%", pad="4%")  
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
490
    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...
491
    slider_date.on_changed(update)
492
493
    #divider_textbox = make_axes_locatable(ax)
494
    #textbox_ax = divider_textbox.append_axes("bottom", size="3%", pad="4%") 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
495
    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...
496
    textbox = TextBox(textbox_ax, 'Knot name:', initial='None')
497
    textbox.on_submit(submit_textbox)
498
499
500
501
    ax.set_xlim([-1.0, +1.0])
502
    ax.set_ylim([-1.0, +1.0])
503
    ax.set_aspect('equal')
504
505
    fig.suptitle('S to select, R to rename, Q to deactivate selector')
506
507
    print('Usage:',
508
          '-> S to select, R to rename, Q to deactivate selector',
509
          '-> To delete the knot, name it with a whitespace', 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
510
          '-> You can select points from one component at a time',
511
          '-> If you use the zoom or movement tools, remember to unselect them',
512
          sep='\n')
513
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
514
    plt.show()
515
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
516
    out.display_output()
517
  
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
518
    return mod
519
520
521
522
523
524
525
def KnotsIdGUI(mod):
0 ignored issues
show
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...
Comprehensibility introduced by
This function exceeds the maximum number of variables (28/15).
Loading history...
526
    """
527
        Prompt a GUI to select identified knots and alter their label, reprenting their
528
        time evolution.
529
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
530
        It can be used inside jupyter notebooks, using '%matplotlib widget' first.
531
       
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
532
        Parameters:
533
        -----------
534
         mod : :pd.DataFrame:
535
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
536
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
537
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
538
        Returns:
539
        --------
540
         mod : :pd.DataFrame:
541
             pandas.DataFrame containing every knot with their altered labels, with 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
542
             at least columns 'label', 'date', 'X', 'Y', 'Flux (Jy)'.
543
    """
544
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
545
    mod = mod.copy()
546
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
547
    knots = dict(tuple(mod.groupby('label')))
548
    knots_names = list(knots.keys())
549
    knots_values = list(knots.values())
550
    knots_jyears = {k:Time(knots[k]['date'].to_numpy()).jyear for k in knots}
551
    knots_dates = {k:knots[k]['date'].to_numpy() for k in knots}
552
    knots_fluxes = {k:knots[k]['Flux (Jy)'].to_numpy() for k in knots}
553
554
    from matplotlib.widgets import TextBox, RectangleSelector
0 ignored issues
show
introduced by
Unable to import 'matplotlib.widgets'
Loading history...
introduced by
Import outside toplevel (matplotlib.widgets.TextBox, matplotlib.widgets.RectangleSelector)
Loading history...
555
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
556
    out = get_output()
557
558
    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...
559
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
560
    lineas = list()
561
    textos = list()
562
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
563
    def draw_all():
564
        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...
565
566
        for linea in lineas:
567
            if linea is not None:
568
                linea.remove()
569
        for texto in textos:
570
            if texto is not None:
571
                texto.remove()
572
573
        ax.set_prop_cycle(None)
574
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
575
        lineas = list()
576
        textos = list()
577
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
578
        #ax.clear() # either clear the whole axis or remove every artist separetly
579
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
580
        for i, label in enumerate(knots_names):
581
            x, y = knots_jyears[label], knots_fluxes[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...
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...
582
583
            if len(x) > 0:
584
                if label == '' or label == 'None': # if it is unlabelled, do not connect it.
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "label in ('', 'None')"
Loading history...
585
                    lineas.append(ax.plot(x, y, '.', linewidth=0.8, alpha=0.5, label=label, color='black')[0])
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (110/100).

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

Loading history...
586
                else:
587
                    lineas.append(ax.plot(x, y, '.-', linewidth=0.8, alpha=0.5, label=label)[0])
588
            else:
589
                lineas.append(None)
590
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
591
            if len(x) > 0:
592
                #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...
593
                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...
594
            else:
595
                textos.append(None)
596
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
597
        fig.canvas.draw_idle() # if removed every artist separately instead of ax.clear()
598
599
600
    def update():
601
        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...
602
603
        for i, label in enumerate(knots_names):   
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
604
            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...
605
606 View Code Duplication
            if lineas[i] is not None:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
607
                if len(x) > 0:
608
                    lineas[i].set_xdata(x)
609
                    lineas[i].set_ydata(y)
610
                else:
611
                    lineas[i].remove()
612
                    lineas[i] = None
613
            else:
614
                if len(x) > 0:
615
                    if label == '' or label == 'None': # if it is unlabelled, do not connect it.
0 ignored issues
show
Unused Code introduced by
Consider merging these comparisons with "in" to "label in ('', 'None')"
Loading history...
616
                        lineas[i] = ax.plot(x, y, '.', linewidth=0.8, alpha=0.5, label=label, color='black')[0]
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...
617
                    else:
618
                        lineas[i] = ax.plot(x, y, '.-', linewidth=0.8, alpha=0.5, label=label)[0]
619
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
620
            if textos[i] is not None:
621
                if len(x) > 0:    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
622
                    textos[i].set_position((x[0], y[0]))
623
                    textos[i].set_text(label)
624
                else:
625
                    textos[i].remove()
626
                    textos[i] = None
627
                    #textos[i].set_position((10, 10))
628
            else:
629
                if len(x) > 0:    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
630
                    #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...
631
                    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...
632
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
633
        fig.canvas.draw_idle()    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
634
   
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
635
636
    selected_knot = None
637
    selected_ind = None
638
    selected_date = None
639
    selected_flux = None
640
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
641 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...
642
        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 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_fluxes 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_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...
643
644
        log.debug('Submited with:')
645
        log.debug(f'   selected_knot {selected_knot}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
646
        log.debug(f'   selected_ind {selected_ind}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
647
        log.debug(f'   selected_flux {selected_flux}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
648
        log.debug(f'   selected_date {selected_date}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
649
650
        if selected_knot is not None:        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
651
            mod.loc[selected_ind, 'label'] = text.upper().strip(' ')
652
653
            knots = dict(tuple(mod.groupby('label')))
654
            knots_names = list(knots.keys())
655
            knots_values = list(knots.values())
656
            knots_jyears = {k:Time(knots[k]['date'].to_numpy()).jyear for k in knots}
657
            knots_dates = {k:knots[k]['date'].to_numpy() for k in knots}
658
            knots_fluxes = {k:knots[k]['Flux (Jy)'].to_numpy() for k in knots}
659
660
            print(f"Updated index {selected_ind} to {text.upper()}")
661
        else:
662
            pass
663
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
664
        draw_all()
665
666
    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...
667
        nonlocal selected_knot,selected_date, selected_flux, selected_ind
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
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_knot does not seem to be defined.
Loading history...
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_ind does not seem to be defined.
Loading history...
668
669
        # 1 eclick and erelease are the press and release events
670
        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...
671
        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...
672
        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...
673
        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...
674
675
        selected_knot = None
676
        selected_date = None
677
        selected_flux = None
678
        selected_ind = None
679
680
        for i, label in enumerate(knots_names):
0 ignored issues
show
Unused Code introduced by
The variable i seems to be unused.
Loading history...
681
            years = knots_jyears[label]
682
            fluxes = knots_fluxes[label]
683
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
684
            # get points iside current rectangle for current date
685
            rect_idx = (x1 < years) & ( years < x2) & (y1 < fluxes) & ( fluxes < y2) 
0 ignored issues
show
Coding Style introduced by
No space allowed after bracket
Loading history...
Coding Style introduced by
Trailing whitespace
Loading history...
686
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
687
            if np.sum(rect_idx) == 0:
688
                continue # we did not select any component from this component, next one
689
690
            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...
691
            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...
692
693 View Code Duplication
            if np.sum(rect_idx) > 0:
0 ignored issues
show
Unused Code introduced by
Unnecessary "else" after "break"
Loading history...
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
694
                textbox.set_val(label)
695
                selected_knot = label
696
                selected_x = x[rect_idx].ravel()
0 ignored issues
show
Unused Code introduced by
The variable selected_x seems to be unused.
Loading history...
697
                selected_y = y[rect_idx].ravel()
0 ignored issues
show
Unused Code introduced by
The variable selected_y seems to be unused.
Loading history...
698
                selected_ind = knots[label].index[rect_idx]
699
                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
introduced by
Use lazy % formatting in logging functions
Loading history...
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...
700
                break # if we find selected components in this epoch, continue with renaming
701
            else:
702
                pass
703
704
        # print epoch of selected points:
705
        if selected_knot is not None:
706
            out.clear_output()
707
            out.append_stdout('Selected:\n')
708
            for idx in selected_ind:
709
                #print(f"Selected {mod.loc[idx, 'label']} {mod.loc[idx, 'date']}")
710
                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...
711
           
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
712
        update()
713
714
715 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...
716
        log.debug('GUI: Key pressed.')
717
        if event.key in ['Q', 'q'] and toggle_selector.RS.active:
718
            log.debug('Selector deactivated.')
719
            toggle_selector.RS.set_active(False)
720
        if event.key in ['S', 's'] and not toggle_selector.RS.active:
721
            log.debug('Selector activated.')
722
            toggle_selector.RS.set_active(True)
723
        if event.key in ['R', 'r']:
724
            log.debug('Selector deactivated.')
725
            toggle_selector.RS.set_active(False)
726
            textbox.begin_typing(None)
727
            #textbox.set_val('')
728
729
730
    toggle_selector.RS = RectangleSelector(ax, line_select_callback,
731
                                           drawtype='box', useblit=True,
732
                                           button=[1, 3],  # don't use middle button
733
                                           minspanx=0, minspany=0,
734
                                           spancoords='data',
735
                                           interactive=False)
736
737
738
    fig.canvas.mpl_connect('key_press_event', toggle_selector)
739
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
740
    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...
741
742
    divider_textbox = make_axes_locatable(ax)
743
    textbox_ax = divider_textbox.append_axes("bottom", size="10%", pad="15%") 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
744
    #textbox_ax = fig.add_axes([0.3,0,0.5,0.05])
745
    textbox = TextBox(textbox_ax, 'Knot name:', initial='None')
746
    textbox.on_submit(submit_textbox)
747
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
748
    draw_all()
749
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
750
    #ax.autoscale()
751
    ax.set_xlabel('date (year)')
752
    ax.set_ylabel('Flux (Jy)')
753
    ax.set_title('Flux from each component')
754
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
755
    xlims = Time(np.amin(mod['date'])).jyear, Time(np.amax(mod['date'])).jyear
756
    ax.set_xlim((xlims[0]-0.03*np.abs(xlims[1]-xlims[0]), xlims[1]+0.03*np.abs(xlims[1]-xlims[0])))
757
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
758
    fig.suptitle('S to select, R to rename, Q to deactivate selector')
759
760
    print('Usage:',
761
          '-> S to select, R to rename, Q to deactivate selector',
762
          '-> To delete the knot, name it with a whitespace', 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
763
          '-> You can select points from one component at a time',
764
          '-> If you use the zoom or movement tools, remember to unselect them',
765
          sep='\n')
766
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
767
    plt.show()
768
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
769
    out.display_output()
770
771
    return mod
772
773
774
775
def KnotsIdReadMod_from_diffmap(path=None):
0 ignored issues
show
Coding Style Naming introduced by
Function name "KnotsIdReadMod_from_diffmap" 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...
776
    """
777
        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...
778
        to be worked on for labelling and to be used with these GUIs.
779
   
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
780
        Parameters:
781
        -----------
782
         path : :str:
783
             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...
784
             '%Y-%m-%d_mod.mod', for example, path = 'vlbi/ftree/*/*_mod.mod'.
785
             
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
786
        Returns:
787
        -----------
788
         mod : :pd.DataFrame:
789
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
790
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
791
    """
792
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
793
    if path is None:
794
        log.error('Path not specified')
795
        raise Exception('Path not specified')
796
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
797
    mod_dates_str = list()
798
    mod_dates = list()
799
    mod_data = list()
800
801
    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...
802
        match = re.findall(r'([0-9]{4}-[0-9]{2}-[0-9]{2})_mod.mod', f)
803
        if not len(match) > 0:
804
            continue
805
806
        date_str = match[0]
807
        date = datetime.strptime(date_str, '%Y-%m-%d')
808
809
        mod_dates_str.append(date_str)
810
        mod_dates.append(date)
811
        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
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...
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...
812
813
    # sort by date    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
814
    idx = np.argsort(mod_dates)
815
    mod_dates_str = list(np.array(mod_dates_str, dtype=object)[idx])
816
    mod_dates = list(np.array(mod_dates, dtype=object)[idx])
817
    mod_data = list(np.array(mod_data, dtype=object)[idx])
818
819
    # fix stupid 'v' in columns, insert a label field, add X, Y columns
820
    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...
821
        mod_data[i].insert(0, 'label', value=None)
822
        mod_data[i].insert(1, 'date', value=mod_dates[i])
823
824
        mod_data[i]['Flux (Jy)'] = mod_data[i]['Flux (Jy)'].str.strip('v').astype(float)
825
        mod_data[i]['Radius (mas)'] = mod_data[i]['Radius (mas)'].str.strip('v').astype(float)
826
        mod_data[i]['Theta (deg)'] = mod_data[i]['Theta (deg)'].str.strip('v').astype(float)
827
828
        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...
829
        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...
830
831
     
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
832
    mod = pd.concat(mod_data, ignore_index=True)
833
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
834
    return mod
835
836
837
838
def KnotsIdSaveMod(mod, path=None, rewrite=False, drop_blanks=False):
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...
839
    """
840
        Save Knots data to *_mod.mod files ready to be re-proccessed with diffmap.
841
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
842
        Actually only useful to remove stupid knots and fit it again with diffmap.
843
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
844
        Parameters:
845
        -----------
846
         mod : :pd.DataFrame:
847
             pandas.DataFrame containing every knot
848
         path: :str:
849
             string containing the path to which the files are to be saved, eg:
850
             path = 'my_knots/'
851
         rewrite: :bool:
852
             If rewrite is True, path is interpreted as a regex for which files
853
             to overwrite.
854
         drop_blanks: :bool:
855
             If True, knots without label (or whose label is a whitspace) are dropped.
856
             If False (default), they are saved without label.
857
             
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
858
        Returns:
859
        --------
860
         None
861
    """
862
863
    if path is None:
864
        log.error('Path not specified')
865
        raise Exception('Path not specified')
866
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
867
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
868
    mod = mod.copy()
869
870
871
    if drop_blanks:
872
        mod = mod.drop(mod[mod['label'].str.strip('') == ''].index)
873
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
874
875
    mod_dict = dict(list(mod.groupby('date')))
876
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
877
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
878
    if rewrite:
879
        file_list = list()
880
        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...
881
            match = re.findall(r'([0-9]{4}-[0-9]{2}-[0-9]{2})_mod.mod', f)
882
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
883
            if not len(match) > 0:
884
                continue
885
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
886
            date = datetime.strptime(match[0], '%Y-%m-%d')
887
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
888
            if date not in mod_dict:
889
                raise Exception('Specified regex includes files for which there are no knots')
890
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
891
            file_list.append(f)
892
893
        if len(file_list) != len(mod_dict):
894
            raise Exception(f'Specified files by path regex does not match the number of epochs ({len(file_list)} vs {len(mod_dict)})')
0 ignored issues
show
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...
895
    else:
896
        file_list = list()
897
        for date in mod_dict.keys():
898
               file_list.append(f"{path}/{date.strftime('%Y-%m-%d')}_mod.mod")
0 ignored issues
show
Coding Style introduced by
The indentation here looks off. 12 spaces were expected, but 15 were found.
Loading history...
899
  
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
900
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
901
    for fname, (date, data) in zip(file_list, mod_dict.items()):
902
        data = data.copy()
903
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
904
        #data = data.drop(columns=['label'])
905
        #data = data.drop(columns=['X'])
906
        #data = data.drop(columns=['Y'])
907
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
908
        data['Flux (Jy)'] = data['Flux (Jy)'].astype(str) + 'v'
909
        data['Radius (mas)'] = data['Radius (mas)'].astype(str) + 'v'
910
        data['Theta (deg)'] = data['Theta (deg)'].astype(str) + 'v'
911
912
        ## add previous labels in comments (so diffmap does not get stuck with it)
913
        data['label'] = '!' + data['label']
914
915
        with open(fname, 'w') as f:
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...
916
            f.write("! Generated by mutis\n"
917
                    "! Columns\n"
918
                    "! 'Flux (Jy)', 'Radius (mas)', 'Theta (deg)', 'Major FWHM (mas)', 'Axial ratio', 'Phi (deg)', 'T', 'Freq (Hz)', 'SpecIndex', '!label'\n")
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (158/100).

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

Loading history...
919
            data.to_csv(f,
920
                        columns=['Flux (Jy)', 'Radius (mas)', 'Theta (deg)', 'Major FWHM (mas)', 'Axial ratio', 'Phi (deg)', 'T', 'Freq (Hz)', 'SpecIndex', 'label'],
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (165/100).

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

Loading history...
921
                        index=False, sep=' ', header=None)
922
923
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
924
925
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...
926
    """
927
        Read Knots data to .csv files (as done by Svetlana? ##)
928
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
929
        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...
930
        columns should be modified to:
931
        'Date' (jyear), 'MJD', 'X(mas)', 'Y(mas)', 'Flux(Jy)'
932
        These columns are derived from the ones in `mod`, old ones are removed.
933
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
934
        Parameters:
935
        -----------
936
         path: :str:
937
             string containing the path to read files from eg:
938
             path = 'myknows/*.csv'
939
        Returns:
940
        --------
941
         mod : :pd.DataFrame:
942
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
943
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
944
    """
945
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
946
    if path is None:
947
        log.error('Path not specified')
948
        raise Exception('Path not specified')
949
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
950
    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...
951
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
952
    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...
953
        match = re.findall(r'/(.*).csv', f)
954
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
955
        if not len(match) > 0:
956
            continue
957
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
958
        knot_name = match[0]
959
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
960
        log.debug(f'Loading {knot_name} from {f}')
0 ignored issues
show
introduced by
Use lazy % formatting in logging functions
Loading history...
961
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
962
        knot_data = pd.read_csv(f, parse_dates=['date'], date_parser=pd.to_datetime)
963
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
964
        dataL.append((knot_name, knot_data))
965
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
966
    mod = pd.concat(dict(dataL), ignore_index=True)
967
968
    return mod
969
970
971
972
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...
973
    """
974
        Save Knots data to .csv files (as done by Svetlana? ##)
975
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
976
        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...
977
        columns should be modified to:
978
        'Date' (jyear), 'MJD', 'X(mas)', 'Y(mas)', 'Flux(Jy)'
979
        These columns are derived from the ones in `mod`, old ones are removed.
980
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
981
        Parameters:
982
        -----------
983
         mod : :pd.DataFrame:
984
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
985
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
986
         path: :str:
987
             string containing the path to which the files are to be saved, eg:
988
             path = 'my_knots/'
989
             
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
990
        Returns:
991
        --------
992
         None
993
    """
994
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
995
    if path is None:
996
        log.error('Path not specified')
997
        raise Exception('Path not specified')
998
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
999
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1000
    mod = mod.copy()
1001
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1002
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1003
    mod_dict = dict(list(mod.groupby('label')))
1004
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1005
    for label, data in mod_dict.items():
1006
        data = data.copy()
1007
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1008
        #data.insert(0, 'Date', Time(data['date']).jyear)
1009
        #data.insert(1, 'MJD', Time(data['date']).mjd)
1010
        #data = data.rename(columns={'X': 'X (mas)', 'Y': 'Y (mas)'})
1011
        #data = data.drop(columns=['date'])
1012
        #data = data.drop(columns=['label'])
1013
        #if 'Radius (mas)' in data.columns:
1014
        #    data = data.rename(columns={'Radius (mas)':'R(mas)'})
1015
        #data.columns = data.columns.str.replace(' ', '')
1016
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1017
        data.to_csv(f'{path}/{label}.csv', index=False)
1018
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1019
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1020
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1021
def KnotsIdReadMod(path=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...
1022
    """
1023
        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...
1024
        to be worked on for labelling and to be used with these GUIs.
1025
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1026
        It detects whether the file was generated by mutis. If it was then 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1027
        it searchs for a hidden label column to load previous label names (unnamed labels
1028
   
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1029
        Parameters:
1030
        -----------
1031
         path : :str:
1032
             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...
1033
             '%Y-%m-%d_mod.mod', for example, path = 'vlbi/ftree/*/*_mod.mod'.
1034
             
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1035
        Returns:
1036
        -----------
1037
         mod : :pd.DataFrame:
1038
             pandas.DataFrame containing every knot, with at least columns 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1039
             'label', 'date', 'X', 'Y', 'Flux (Jy)'.
1040
    """
1041
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1042
    if path is None:
1043
        log.error('Path not specified')
1044
        raise Exception('Path not specified')
1045
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1046
    mod_dates_str = list()
1047
    mod_dates = list()
1048
    mod_data = list()
1049
1050
    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...
1051
        match = re.findall(r'([0-9]{4}-[0-9]{2}-[0-9]{2})_mod.mod', f)
1052
        if not len(match) > 0:
1053
            continue
1054
1055
        date_str = match[0]
1056
        date = datetime.strptime(date_str, '%Y-%m-%d')
1057
1058
        mod_dates_str.append(date_str)
1059
        mod_dates.append(date)
1060
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1061
        with open(f) as fobj:
1062
            firstline = fobj.readline()
1063
            if firstline == '! Generated by mutis\n':
0 ignored issues
show
Unused Code introduced by
The if statement can be replaced with 'var = bool(test)'
Loading history...
1064
                generated_by_mutis = True
1065
            else:
1066
                generated_by_mutis = False
1067
                
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1068
        if generated_by_mutis:
1069
            data = pd.read_csv(f, sep='\s+', 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
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...
1070
                               skiprows=3, 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1071
                               #converters={'label':(lambda l: '' if l == '' else l)}, 
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1072
                               dtype={'label':str},
1073
                               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 (160/100).

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

Loading history...
1074
                                      'label'])
1075
            data['label'] = data['label'].str.strip('!')
1076
        else:
1077
            data = 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
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...
Coding Style introduced by
This line is too long as per the coding-style (188/100).

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

Loading history...
1078
            #data.insert(0, 'label', value=None)
1079
            data.insert(0, 'label', value='')
1080
1081
        data.insert(1, 'date', value=date)
1082
1083
        data['Flux (Jy)'] = data['Flux (Jy)'].str.strip('v').astype(float)
1084
        data['Radius (mas)'] = data['Radius (mas)'].str.strip('v').astype(float)
1085
        data['Theta (deg)'] = data['Theta (deg)'].str.strip('v').astype(float)
1086
1087
        data.insert(5, 'X', data['Radius (mas)']*np.cos(np.pi/180*(data['Theta (deg)']-90)))
1088
        data.insert(6, 'Y', data['Radius (mas)']*np.sin(np.pi/180*(data['Theta (deg)']-90)))
1089
1090
        mod_data.append(data)
1091
             
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1092
    # sort by date    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1093
    idx = np.argsort(mod_dates)
1094
    mod_dates_str = list(np.array(mod_dates_str, dtype=object)[idx])
1095
    mod_dates = list(np.array(mod_dates, dtype=object)[idx])
1096
    mod_data = list(np.array(mod_data, dtype=object)[idx])
1097
     
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1098
    mod = pd.concat(mod_data, ignore_index=True)
1099
    
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
1100
    return mod
0 ignored issues
show
Coding Style introduced by
Final newline missing
Loading history...