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

spedas / pyspedas / 16972251084

14 Aug 2025 05:28PM UTC coverage: 89.527% (+0.01%) from 89.515%
16972251084

push

github

jameswilburlewis
Tweaked wording and formatting for readthedocs

40100 of 44791 relevant lines covered (89.53%)

0.9 hits per line

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

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

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

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

53
    Returns
54
    -------
55
    list of str
56
        Returns a list of tplot variables created or changed
57

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

71
    """
72
    if len(names) < 1:
1✔
73
        logging.warning('time_clip: no valid tplot variables specified')
1✔
74
        return
1✔
75

76
    # new_names is deprecated
77
    if new_names is not None:
1✔
78
        logging.info("time_clip: The new_names parameter is deprecated. Please use newname instead.")
×
79
        newname = new_names
×
80

81
    old_names = tnames(names)
1✔
82

83
    if len(old_names) < 1:
1✔
84
        logging.warning('time_clip: No valid tplot variables matching '+str(names))
1✔
85
        return
1✔
86

87
    if overwrite:
1✔
88
        n_names = old_names
1✔
89
    elif (newname is None) or (len(newname) < 1) or (newname == ''):
1✔
90
        n_names = [s + suffix for s in old_names]
1✔
91
    else:
92
        n_names = newname
1✔
93

94
    if isinstance(n_names, str):
1✔
95
        n_names = [n_names]
1✔
96

97
    if len(n_names) != len(old_names):
1✔
98
        logging.warning('time_clip: new_names and old_names have different lengths, using suffixes instead')
1✔
99
        n_names = [s + suffix for s in old_names]
1✔
100

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

103
    if isinstance(time_start, str):
1✔
104
        time_start_str = time_start
1✔
105
        time_start_float = time_float(time_start)
1✔
106
    else:
107
        time_start_str = time_string(time_start)
1✔
108
        time_start_float = time_start
1✔
109

110
    if isinstance(time_end, str):
1✔
111
        time_end_str = time_end
1✔
112
        time_end_float = time_float(time_end)
1✔
113
    else:
114
        time_end_str = time_string(time_end)
1✔
115
        time_end_float = time_end
1✔
116

117

118
    if time_start_float > time_end_float:
1✔
119
        logging.error('time_clip: Start time ' + time_start_str +' is larger than end time ' + time_end_str)
1✔
120
        return
1✔
121

122
    for j in range(len(old_names)):
1✔
123
        if old_names[j] != n_names[j]:
1✔
124
            tplot_copy(old_names[j], n_names[j])
1✔
125

126
        alldata = get_data(n_names[j])
1✔
127
        metadata = copy.deepcopy(get_data(n_names[j], metadata=True))
1✔
128

129
        if not isinstance(alldata, tuple): # NRV variable
1✔
130
            continue
1✔
131
            
132
        time = alldata[0]
1✔
133
        data = alldata[1]
1✔
134
        input_count = len(time)
1✔
135

136

137
        if input_count < 1:
1✔
138
            logging.info('time_clip found empty data for variable '+old_names[j])
×
139
            continue
×
140

141
        new_time = np.array(time_float(time))
1✔
142

143
        if interior_clip:
1✔
144
            # Invert sense of default comparison
145
            cond = (new_time < time_start_float) | (new_time > time_end_float)
1✔
146
        else:
147
            cond = (new_time >= time_start_float) & (new_time <= time_end_float)
1✔
148

149
        count = np.count_nonzero(cond)
1✔
150

151
        if count == 0:
1✔
152
            logging.warning('time_clip: '+ old_names[j] + ' has no data in requested range')
1✔
153
            continue
1✔
154

155
        if count == input_count:
1✔
156
            logging.debug('Time clip returns full data set for variable '+old_names[j])
1✔
157
            continue
1✔
158

159
        tmp_q = pyspedas.pytplot.data_quants[n_names[j]]
1✔
160

161
        if 'v1' in tmp_q.coords.keys():
1✔
162
            if len(tmp_q.coords['v1'].values.shape) == 2:
1✔
163
                v1_data = tmp_q.coords['v1'].values[cond, :]
1✔
164
            else:
165
                v1_data = tmp_q.coords['v1'].values
1✔
166

167
        if 'v2' in tmp_q.coords.keys():
1✔
168
            if len(tmp_q.coords['v2'].values.shape) == 2:
1✔
169
                v2_data = tmp_q.coords['v2'].values[cond, :]
1✔
170
            else:
171
                v2_data = tmp_q.coords['v2'].values
1✔
172

173
        if 'v3' in tmp_q.coords.keys():
1✔
174
            if len(tmp_q.coords['v3'].values.shape) == 2:
1✔
175
                v3_data = tmp_q.coords['v3'].values[cond, :]
1✔
176
            else:
177
                v3_data = tmp_q.coords['v3'].values
1✔
178

179
        if 'v' in tmp_q.coords.keys():
1✔
180
            if len(tmp_q.coords['v'].values.shape) == 2:
1✔
181
                v_data = tmp_q.coords['v'].values[cond, :]
1✔
182
            else:
183
                v_data = tmp_q.coords['v'].values
1✔
184

185
        if 'spec_bins' in tmp_q.coords.keys():
1✔
186
            if len(tmp_q.coords['spec_bins'].values.shape) == 2:
1✔
187
                v_data = tmp_q.coords['spec_bins']\
1✔
188
                    .values[cond, :]
189
            else:
190
                v_data = tmp_q.coords['spec_bins'].values
1✔
191

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

238
        logging.debug('Time clip was applied to: ' + n_names[j])
1✔
239

240
    return n_names
1✔
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