1 |
/* |
2 |
* selstuff.c (to be linked from) ~rick/src/util |
3 |
* |
4 |
* library of miscellaneous utility functions for extracting a target data |
5 |
* set from a series by selecting on parameters, and for extracting |
6 |
* parameter values from a dataset selection |
7 |
* |
8 |
* key_params_from_dspec() |
9 |
* select_dataset_from_time_interval() |
10 |
* select_dataset_from_time_range() |
11 |
* |
12 |
* Bugs: |
13 |
* Lots of checking is skipped |
14 |
* select_dataset_from_time_interval() should just call |
15 |
* select_dataset_from_time_range(), or vice-versa |
16 |
* The record selection based on Carrington rotation and longitude gives |
17 |
* incomplete or screwy results sometimes, especially with HMI data |
18 |
* Unconditionally uses geocentric ephemeris for Carrington times |
19 |
* |
20 |
* Revision history is at end of file |
21 |
*/ |
22 |
|
23 |
#include "earth_ephem.c" |
24 |
|
25 |
static int key_params_from_dspec (const char *dspec) { |
26 |
/* |
27 |
* Establish whether target times are determined from dataset specifier |
28 |
* assume that if a bracket is found in the dataset specifier it is a |
29 |
* set of well-specified records containing a properly ordered input dataset; |
30 |
* otherwise, a dataseries to be queried |
31 |
*/ |
32 |
int n, nt = strlen (dspec); |
33 |
|
34 |
for (n = 0; n < nt; n++) if (dspec[n] == '[') return 1; |
35 |
return 0; |
36 |
} |
37 |
|
38 |
DRMS_RecordSet_t *select_dataset_from_time_range (const char *series, |
39 |
char *tstrt_str, char *tstop_str) { |
40 |
/* |
41 |
* Select a dataset from a series based on specification of target times |
42 |
* for start and stop |
43 |
* The target times may be specified as either date_time strings or as CR:CL |
44 |
*/ |
45 |
DRMS_RecordSet_t *ds = NULL; |
46 |
TIME tstrt, tstop; |
47 |
double strt_cl, stop_cl; |
48 |
int strt_cr, stop_cr; |
49 |
int status; |
50 |
char rec_query[DRMS_MAXQUERYLEN]; |
51 |
/* get required series info from first record in series */ |
52 |
/* platform, cadence, phase */ |
53 |
/* not currently implemented */ |
54 |
/* |
55 |
snprintf (rec_query, DRMS_MAXQUERYLEN, "%s[#^]", series); |
56 |
if (!(ds = drms_open_records (drms_env, rec_query, &status))) { |
57 |
fprintf (stderr, "Error: unable to open input data set %s\n", rec_query); |
58 |
fprintf (stderr, " status = %d\n", status); |
59 |
} |
60 |
rec = ds->records[0]; |
61 |
drms_close_records (ds, DRMS_FREE_RECORD); |
62 |
*/ |
63 |
if (sscanf (tstrt_str, "%d:%lf", &strt_cr, &strt_cl) == 2) { |
64 |
/* tstrt specified as CR:CL : need ephemeris info */ |
65 |
if (sscanf (tstop_str, "%d:%lf", &stop_cr, &stop_cl) != 2) { |
66 |
fprintf (stderr, "Error: start and stop times must be specified in same format\n"); |
67 |
fprintf (stderr, " either Date_Time or CR:CL\n"); |
68 |
return ds; |
69 |
} |
70 |
/* |
71 |
if (strt_cr == stop_cr) { |
72 |
snprintf (rec_query, DRMS_MAXQUERYLEN, |
73 |
"%s[?CAR_ROT = %d and CRLN_OBS <= %f and CRLN_OBS >= %f?]", series, |
74 |
strt_cr, strt_cl, stop_cl); |
75 |
} else if ((stop_cr - strt_cr) > 1) { |
76 |
snprintf (rec_query, DRMS_MAXQUERYLEN, |
77 |
"%s[?(%s > %d and %s < %d) or (%s = %d and %s <= %f) or (%s = %d and %s >= %f?)]", |
78 |
series, "CAR_ROT", strt_cr, "CAR_ROT", stop_cr, |
79 |
"CAR_ROT", strt_cr, "CRLN_OBS", strt_cl, |
80 |
"CAR_ROT", stop_cr, "CRLN_OBS", stop_cl); |
81 |
} else { |
82 |
snprintf (rec_query, DRMS_MAXQUERYLEN, |
83 |
"%s[?(%s = %d and %s <= %f) or (%s = %d and %s >= %f)?]", |
84 |
series, "CAR_ROT", strt_cr, "CRLN_OBS", strt_cl, |
85 |
"CAR_ROT", stop_cr, "CRLN_OBS", stop_cl); |
86 |
} |
87 |
*/ |
88 |
tstrt = earth_meridian_crossing (strt_cl, strt_cr); |
89 |
tstop = earth_meridian_crossing (stop_cl, stop_cr); |
90 |
} else { |
91 |
tstrt = sscan_time (tstrt_str); |
92 |
tstop = sscan_time (tstop_str); |
93 |
if (time_is_invalid (tstrt) || time_is_invalid (tstop)) { |
94 |
fprintf (stderr, "Error: start and stop times must be specified in same format\n"); |
95 |
fprintf (stderr, " either Date_Time or CR:CL\n"); |
96 |
return ds; |
97 |
} |
98 |
} |
99 |
snprintf (rec_query, 256, "%s[?%s >= %13.6e and %s <= %13.6e?]", series, |
100 |
/* |
101 |
trec_key, tstrt - t_eps, trec_key, tstop + t_eps); |
102 |
*/ |
103 |
"T_REC", tstrt, "T_REC", tstop); |
104 |
if (!(ds = drms_open_records (drms_env, rec_query, &status))) { |
105 |
fprintf (stderr, "Error: unable to open input data set %s\n", rec_query); |
106 |
fprintf (stderr, " status = %d\n", status); |
107 |
} |
108 |
return ds; |
109 |
} |
110 |
|
111 |
DRMS_RecordSet_t *select_dataset_from_time_interval (const char *series, |
112 |
char *tmid_str, double intrvl) { |
113 |
/* |
114 |
* Select a dataset from a series based on specification of a target time |
115 |
* and interval length |
116 |
* The target time may be specified as either a date_time string or as CR:CL |
117 |
* In the former case, the length specification is expected to be in seconds; |
118 |
* in the latter case it is expected to be in degrees of Carrington rotation |
119 |
* NO, this doesn't yet work; need to specify intrvl in seconds |
120 |
*/ |
121 |
DRMS_RecordSet_t *ds = NULL; |
122 |
DRMS_Record_t *rec; |
123 |
TIME tmid, tstrt, tstop; |
124 |
double tmid_cl, tstrt_cl, tstop_cl; |
125 |
int tmid_cr, tstrt_cr, tstop_cr; |
126 |
int status; |
127 |
char rec_query[DRMS_MAXQUERYLEN]; |
128 |
char time_str[64]; |
129 |
/* get required series info from first record in series */ |
130 |
/* platform, cadence, phase */ |
131 |
/* not currently implemented */ |
132 |
/* |
133 |
snprintf (rec_query, DRMS_MAXQUERYLEN, "%s[#^]", series); |
134 |
if (!(ds = drms_open_records (drms_env, rec_query, &status))) { |
135 |
fprintf (stderr, "Error: unable to open input data set %s\n", rec_query); |
136 |
fprintf (stderr, " status = %d\n", status); |
137 |
} |
138 |
rec = ds->records[0]; |
139 |
drms_close_records (ds, DRMS_FREE_RECORD); |
140 |
*/ |
141 |
if (sscanf (tmid_str, "%d:%lf", &tmid_cr, &tmid_cl) == 2) { |
142 |
/* tmid specified as CR:CL */ |
143 |
tmid = earth_meridian_crossing (tmid_cl, tmid_cr); |
144 |
tstrt_cr = tstop_cr = tmid_cr; |
145 |
tstrt_cl = tmid_cl + 0.5 * intrvl; |
146 |
while (tstrt_cl > 360.0) { |
147 |
tstrt_cl -= 360.0; |
148 |
tstrt_cr--; |
149 |
} |
150 |
tstop_cl = tmid_cl - 0.5 * intrvl; |
151 |
while (tstop_cl < 0.0) { |
152 |
tstop_cl += 360.0; |
153 |
tstop_cr++; |
154 |
} |
155 |
tstrt = earth_meridian_crossing (tstrt_cl, tstrt_cr); |
156 |
tstop = earth_meridian_crossing (tstop_cl, tstop_cr); |
157 |
/* |
158 |
if (stop_cl >= 0.0 && strt_cl <= 360.0) { |
159 |
snprintf (rec_query, DRMS_MAXQUERYLEN, |
160 |
"%s[?CAR_ROT = %d and CRLN_OBS <= %f and CRLN_OBS >= %f?]", series, |
161 |
tmid_cr, strt_cl, stop_cl); |
162 |
} else { |
163 |
int strt_cr, stop_cr; |
164 |
strt_cr = stop_cr = tmid_cr; |
165 |
while (strt_cl > 360.0) { |
166 |
strt_cl -= 360.0; |
167 |
strt_cr--; |
168 |
} |
169 |
while (stop_cl < 0.0) { |
170 |
stop_cl += 360.0; |
171 |
stop_cr++; |
172 |
} |
173 |
if ((stop_cr - strt_cr) > 1) { |
174 |
snprintf (rec_query, DRMS_MAXQUERYLEN, |
175 |
"%s[?(%s > %d and %s < %d) or (%s = %d and %s <= %f) or (%s = %d and %s >= %f?)]", |
176 |
series, "CAR_ROT", strt_cr, "CAR_ROT", stop_cr, |
177 |
"CAR_ROT", strt_cr, "CRLN_OBS", strt_cl, |
178 |
"CAR_ROT", stop_cr, "CRLN_OBS", stop_cl); |
179 |
} else { |
180 |
snprintf (rec_query, DRMS_MAXQUERYLEN, |
181 |
"%s[?(%s = %d and %s <= %f) or (%s = %d and %s >= %f)?]", |
182 |
series, "CAR_ROT", strt_cr, "CRLN_OBS", strt_cl, |
183 |
"CAR_ROT", stop_cr, "CRLN_OBS", stop_cl); |
184 |
} |
185 |
} |
186 |
*/ |
187 |
} else { |
188 |
/* tmid specified as normal date-time string */ |
189 |
tmid = sscan_time (tmid_str); |
190 |
tstrt = tmid - 0.5 * intrvl; |
191 |
tstop = tmid + 0.5 * intrvl; |
192 |
} |
193 |
snprintf (rec_query, 256, "%s[?%s >= %17.10e and %s <= %17.10e?]", series, |
194 |
/* |
195 |
trec_key, tstrt - t_eps, trec_key, tstop + t_eps); |
196 |
*/ |
197 |
"T_REC", tstrt, "T_REC", tstop); |
198 |
if (!(ds = drms_open_records (drms_env, rec_query, &status))) { |
199 |
fprintf (stderr, "Error: unable to open input data set %s\n", rec_query); |
200 |
fprintf (stderr, " status = %d\n", status); |
201 |
} |
202 |
return ds; |
203 |
} |
204 |
|
205 |
/* |
206 |
* Revision History (all mods by Rick Bogart unless otherwise noted) |
207 |
* |
208 |
* 10.04.27 created this file from routines already in mtrack and |
209 |
* rdcover |
210 |
* 10.05.03 added function select_dataset_from_time_range |
211 |
* 10.08.19 extended precision of time query in |
212 |
* select_dataset_from_time_interval |
213 |
* |
214 |
*/ |