• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

spedas / pyspedas / 25194239086

26 Apr 2026 08:07PM UTC coverage: 61.697% (-28.8%) from 90.54%
25194239086

push

github

jameswilburlewis
Added test for loading Cluster CODIF differential energy flux

0 of 7 new or added lines in 1 file covered. (0.0%)

19460 existing lines in 418 files now uncovered.

30204 of 48955 relevant lines covered (61.7%)

1.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.1
/pyspedas/tplot_tools/tplot_math/time_clip.py
1
"""
2
Time clip of data.
3

4
Notes
5
-----
6
Similar to tclip.pro in IDL SPEDAS.
7

8
"""
9
import logging
3✔
10
import pyspedas
3✔
11
from pyspedas.tplot_tools import store_data, get_data, tnames, time_float, time_string, tplot_copy
3✔
12
import numpy as np
3✔
13
import copy
3✔
14

15
def time_clip(
3✔
16
        names,
17
        time_start,
18
        time_end,
19
        newname=None,
20
        suffix='-tclip',
21
        overwrite=False,
22
        interior_clip=False
23
):
24
    """
25
    Clip data from time_start to time_end.
26

27
    Parameters
28
    ----------
29
    names: str/list of str
30
        List of tplot variable names to time clip (wildcards accepted)
31
    time_start : float or string
32
        Start time.
33
    time_end : float or string
34
        End time.
35
    newname: str/list of str, optional
36
        List of new names for tplot variables.
37
        Default: None. If not given, then a suffix is applied or the variables are overwritten
38
    suffix: str, optional
39
        A suffix to apply.
40
        Default: '-tclip'
41
    overwrite: bool, optional
42
        If true, overwrite the existing tplot variable.
43
        Default: False
44
    interior_clip: bool, optional
45
        If true, reverse sense of operation and clip out times within the start/end range, for example,
46
        when manually despiking data.
47
        Default: False
48

49
    Returns
50
    -------
51
    list of str
52
        Returns a list of tplot variables created or changed
53

54
    Example
55
    -------
56
        >>> # Clip time
57
        >>> import pyspedas
58
        >>> x1 = [0, 4, 8, 12, 16]
59
        >>> time1 = [pyspedas.time_float("2020-01-01") + i for i in x1]
60
        >>> pyspedas.store_data("a", data={"x": time1, "y": [[1, 2, 3],[2, 3, 4],[3, 4, 5],[4, 5, 6],[5, 6,7]]})
61
        >>> time_start=time1[0]
62
        >>> time_end=time1[2]
63
        >>> pyspedas.time_clip('a',time_start,time_end)
64
        >>> ac = pyspedas.get_data('a-tclip')
65
        >>> print(ac)
66

67
    """
68
    if len(names) < 1:
3✔
69
        logging.warning('time_clip: no valid tplot variables specified')
1✔
70
        return
1✔
71

72
    old_names = tnames(names)
3✔
73

74
    if len(old_names) < 1:
3✔
UNCOV
75
        logging.warning('time_clip: No valid tplot variables matching '+str(names))
1✔
UNCOV
76
        return
1✔
77

78
    if overwrite:
3✔
79
        n_names = old_names
3✔
80
    elif (newname is None) or (len(newname) < 1) or (newname == ''):
3✔
81
        n_names = [s + suffix for s in old_names]
3✔
82
    else:
UNCOV
83
        n_names = newname
1✔
84

85
    if isinstance(n_names, str):
3✔
UNCOV
86
        n_names = [n_names]
1✔
87

88
    if len(n_names) != len(old_names):
3✔
UNCOV
89
        logging.warning('time_clip: new names and input names have different lengths, using suffixes instead')
1✔
UNCOV
90
        n_names = [s + suffix for s in old_names]
1✔
91

92
    # We want the start/end times as both strings (for log messages) and floats (for comparisons)
93

94
    if isinstance(time_start, str):
3✔
95
        time_start_str = time_start
3✔
96
        time_start_float = time_float(time_start)
3✔
97
    else:
UNCOV
98
        time_start_str = time_string(time_start)
2✔
UNCOV
99
        time_start_float = time_start
2✔
100

101
    if isinstance(time_end, str):
3✔
102
        time_end_str = time_end
3✔
103
        time_end_float = time_float(time_end)
3✔
104
    else:
UNCOV
105
        time_end_str = time_string(time_end)
2✔
UNCOV
106
        time_end_float = time_end
2✔
107

108

109
    if time_start_float > time_end_float:
3✔
UNCOV
110
        logging.error('time_clip: Start time ' + time_start_str +' is larger than end time ' + time_end_str)
1✔
UNCOV
111
        return
1✔
112

113
    for j in range(len(old_names)):
3✔
114
        if old_names[j] != n_names[j]:
3✔
UNCOV
115
            tplot_copy(old_names[j], n_names[j])
1✔
116

117
        alldata = get_data(n_names[j])
3✔
118
        metadata = copy.deepcopy(get_data(n_names[j], metadata=True))
3✔
119

120
        if not isinstance(alldata, tuple): # NRV variable
3✔
121
            continue
3✔
122
            
123
        time = alldata[0]
3✔
124
        data = alldata[1]
3✔
125
        input_count = len(time)
3✔
126

127

128
        if input_count < 1:
3✔
129
            logging.info('time_clip found empty data for variable '+old_names[j])
×
130
            continue
×
131

132
        new_time = np.array(time_float(time))
3✔
133

134
        if interior_clip:
3✔
135
            # Invert sense of default comparison
UNCOV
136
            cond = (new_time < time_start_float) | (new_time > time_end_float)
×
137
        else:
138
            cond = (new_time >= time_start_float) & (new_time <= time_end_float)
3✔
139

140
        count = np.count_nonzero(cond)
3✔
141

142
        if count == 0:
3✔
UNCOV
143
            logging.warning('time_clip: '+ old_names[j] + ' has no data in requested range')
2✔
UNCOV
144
            continue
2✔
145

146
        if count == input_count:
3✔
147
            logging.debug('Time clip returns full data set for variable '+old_names[j])
3✔
148
            continue
3✔
149

150
        tmp_q = pyspedas.tplot_tools.data_quants[n_names[j]]
3✔
151

152
        if 'v1' in tmp_q.coords.keys():
3✔
153
            if len(tmp_q.coords['v1'].values.shape) == 2:
3✔
154
                v1_data = tmp_q.coords['v1'].values[cond, :]
3✔
155
            else:
UNCOV
156
                v1_data = tmp_q.coords['v1'].values
1✔
157

158
        if 'v2' in tmp_q.coords.keys():
3✔
159
            if len(tmp_q.coords['v2'].values.shape) == 2:
3✔
UNCOV
160
                v2_data = tmp_q.coords['v2'].values[cond, :]
×
161
            else:
162
                v2_data = tmp_q.coords['v2'].values
3✔
163

164
        if 'v3' in tmp_q.coords.keys():
3✔
165
            if len(tmp_q.coords['v3'].values.shape) == 2:
1✔
166
                v3_data = tmp_q.coords['v3'].values[cond, :]
1✔
167
            else:
168
                v3_data = tmp_q.coords['v3'].values
1✔
169

170
        if 'v' in tmp_q.coords.keys():
3✔
171
            if len(tmp_q.coords['v'].values.shape) == 2:
3✔
UNCOV
172
                v_data = tmp_q.coords['v'].values[cond, :]
2✔
173
            else:
174
                v_data = tmp_q.coords['v'].values
3✔
175

176
        if 'spec_bins' in tmp_q.coords.keys():
3✔
177
            if len(tmp_q.coords['spec_bins'].values.shape) == 2:
3✔
UNCOV
178
                v_data = tmp_q.coords['spec_bins']\
2✔
179
                    .values[cond, :]
180
            else:
181
                v_data = tmp_q.coords['spec_bins'].values
3✔
182

183
        try:
3✔
184
            if 'v1' in tmp_q.coords.keys() and\
3✔
185
                'v2' in tmp_q.coords.keys() and\
186
                    'v3' in tmp_q.coords.keys():
187
                store_data(n_names[j], data={
1✔
188
                    'x': time[cond],
189
                    'y': data[cond, :, :, :],
190
                    'v1': v1_data, 'v2': v2_data, 'v3': v3_data},
191
                    attr_dict=metadata)
192
            elif 'v1' in tmp_q.coords.keys() and\
3✔
193
                    'v2' in tmp_q.coords.keys():
194
                store_data(n_names[j], data={
3✔
195
                    'x': time[cond],
196
                    'y': data[cond, :, :],
197
                    'v1': v1_data, 'v2': v2_data},
198
                    attr_dict=metadata)
199
            elif 'v1' in tmp_q.coords.keys():
3✔
200
                store_data(n_names[j], data={
×
201
                    'x': time[cond],
202
                    'y': data[cond, :],
203
                    'v1': v1_data}, attr_dict=metadata)
204
            elif 'spec_bins' in tmp_q.coords.keys():
3✔
205
                store_data(n_names[j], data={
3✔
206
                    'x': time[cond],
207
                    'y': data[cond, :],
208
                    'v': v_data}, attr_dict=metadata)
209
            elif 'v' in tmp_q.coords.keys():
3✔
210
                store_data(n_names[j], data={
×
211
                    'x': time[cond],
212
                    'y': data[cond, :],
213
                    'v': v_data}, attr_dict=metadata)
214
            elif data.ndim == 1:
3✔
215
                store_data(n_names[j], data={
3✔
216
                    'x': time[cond],
217
                    'y': data[cond]},
218
                    attr_dict=metadata)
219
            else:
220
                store_data(n_names[j], data={
3✔
221
                    'x': time[cond],
222
                    'y': data[cond]},
223
                    attr_dict=metadata)
224
        except Exception as e:
×
225
            logging.error('Problem time clipping: ' + n_names[j])
×
226
            logging.error('Exception:'+str(e))
×
227
            continue
×
228

229
        logging.debug('Time clip was applied to: ' + n_names[j])
3✔
230

231
    return n_names
3✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc