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

spedas / pyspedas / 25391193746

05 May 2026 05:15PM UTC coverage: 76.027% (+19.6%) from 56.446%
25391193746

push

github

jameswilburlewis
Restore Cluster tests -- CSA seems to be back online

37244 of 48988 relevant lines covered (76.03%)

2.41 hits per line

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

88.12
/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
4✔
10
import pyspedas
4✔
11
from pyspedas.tplot_tools import store_data, get_data, tnames, time_float, time_string, tplot_copy
4✔
12
import numpy as np
4✔
13
import copy
4✔
14

15
def time_clip(
4✔
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:
4✔
69
        logging.warning('time_clip: no valid tplot variables specified')
3✔
70
        return
3✔
71

72
    old_names = tnames(names)
4✔
73

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

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

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

88
    if len(n_names) != len(old_names):
4✔
89
        logging.warning('time_clip: new names and input names have different lengths, using suffixes instead')
3✔
90
        n_names = [s + suffix for s in old_names]
3✔
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):
4✔
95
        time_start_str = time_start
4✔
96
        time_start_float = time_float(time_start)
4✔
97
    else:
98
        time_start_str = time_string(time_start)
3✔
99
        time_start_float = time_start
3✔
100

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

108

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

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

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

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

127

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

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

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

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

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

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

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

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

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

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

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

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

183
        try:
4✔
184
            if 'v1' in tmp_q.coords.keys() and\
4✔
185
                'v2' in tmp_q.coords.keys() and\
186
                    'v3' in tmp_q.coords.keys():
187
                store_data(n_names[j], data={
×
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\
4✔
193
                    'v2' in tmp_q.coords.keys():
194
                store_data(n_names[j], data={
4✔
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():
4✔
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():
4✔
205
                store_data(n_names[j], data={
4✔
206
                    'x': time[cond],
207
                    'y': data[cond, :],
208
                    'v': v_data}, attr_dict=metadata)
209
            elif 'v' in tmp_q.coords.keys():
4✔
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:
4✔
215
                store_data(n_names[j], data={
4✔
216
                    'x': time[cond],
217
                    'y': data[cond]},
218
                    attr_dict=metadata)
219
            else:
220
                store_data(n_names[j], data={
4✔
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])
4✔
230

231
    return n_names
4✔
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