@@ -0,0 +1,430 | |||||
|
1 | """ | |||
|
2 | The TIME_CONVERSIONS.py module gathers classes and functions for time system transformations | |||
|
3 | (e.g. between seconds from 1970 to datetime format). | |||
|
4 | ||||
|
5 | MODULES CALLED: | |||
|
6 | NUMPY, TIME, DATETIME, CALENDAR | |||
|
7 | ||||
|
8 | MODIFICATION HISTORY: | |||
|
9 | Created by Ing. Freddy Galindo (frederickgalindo@gmail.com). ROJ Aug 13, 2009. | |||
|
10 | """ | |||
|
11 | ||||
|
12 | import numpy | |||
|
13 | import time | |||
|
14 | from datetime import datetime as dt | |||
|
15 | import calendar | |||
|
16 | ||||
|
17 | class Time: | |||
|
18 | """ | |||
|
19 | time(year,month,dom,hour,min,secs) | |||
|
20 | ||||
|
21 | An object represents a date and time of certain event.. | |||
|
22 | ||||
|
23 | Parameters | |||
|
24 | ---------- | |||
|
25 | YEAR = Number of the desired year. Year must be valid values from the civil calendar. | |||
|
26 | Years B.C.E must be represented as negative integers. Years in the common era are repre- | |||
|
27 | sented as positive integers. In particular, note that there is no year 0 in the civil | |||
|
28 | calendar. 1 B.C.E. (-1) is followed by 1 C.E. (1). | |||
|
29 | ||||
|
30 | MONTH = Number of desired month (1=Jan, ..., 12=December). | |||
|
31 | ||||
|
32 | DOM = Number of day of the month. | |||
|
33 | ||||
|
34 | HOUR = Number of the hour of the day. By default hour=0 | |||
|
35 | ||||
|
36 | MINS = Number of the minute of the hour. By default min=0 | |||
|
37 | ||||
|
38 | SECS = Number of the second of the minute. By default secs=0. | |||
|
39 | ||||
|
40 | Examples | |||
|
41 | -------- | |||
|
42 | time_info = time(2008,9,30,12,30,00) | |||
|
43 | ||||
|
44 | time_info = time(2008,9,30) | |||
|
45 | """ | |||
|
46 | ||||
|
47 | def __init__(self, year=None, month=None, dom=None, hour=0, mins=0, secs=0): | |||
|
48 | # If one the first three inputs are not defined, it takes the current date. | |||
|
49 | date = time.localtime() | |||
|
50 | if year==None:year=date[0] | |||
|
51 | if month==None:month=date[1] | |||
|
52 | if dom==None:dom=date[2] | |||
|
53 | ||||
|
54 | # Converting to arrays | |||
|
55 | year = numpy.array([year]); month = numpy.array([month]); dom = numpy.array([dom]) | |||
|
56 | hour = numpy.array([hour]); mins = numpy.array([mins]); secs = numpy.array([secs]) | |||
|
57 | ||||
|
58 | # Defining time information object. | |||
|
59 | self.year = numpy.atleast_1d(year) | |||
|
60 | self.month = numpy.atleast_1d(month) | |||
|
61 | self.dom = numpy.atleast_1d(dom) | |||
|
62 | self.hour = numpy.atleast_1d(hour) | |||
|
63 | self.mins = numpy.atleast_1d(mins) | |||
|
64 | self.secs = numpy.atleast_1d(secs) | |||
|
65 | ||||
|
66 | def change2julday(self): | |||
|
67 | """ | |||
|
68 | Converts a datetime to Julian days. | |||
|
69 | """ | |||
|
70 | ||||
|
71 | # Defining constants | |||
|
72 | greg = 2299171 # incorrect Julian day for Oct, 25, 1582. | |||
|
73 | min_calendar = -4716 | |||
|
74 | max_calendar = 5000000 | |||
|
75 | ||||
|
76 | min_year = numpy.nanmin(self.year) | |||
|
77 | max_year = numpy.nanmax(self.year) | |||
|
78 | if (min_year<min_calendar) or (max_year>max_calendar): | |||
|
79 | print ("Value of Julian date is out of allowed range") | |||
|
80 | return -1 | |||
|
81 | ||||
|
82 | noyear = numpy.sum(self.year==0) | |||
|
83 | if noyear>0: | |||
|
84 | print ("There is no year zero in the civil calendar") | |||
|
85 | return -1 | |||
|
86 | ||||
|
87 | # Knowing if the year is less than 0. | |||
|
88 | bc = self.year<0 | |||
|
89 | ||||
|
90 | # Knowing if the month is less than March. | |||
|
91 | inJanFeb = self.month<=2 | |||
|
92 | ||||
|
93 | jy = self.year + bc - inJanFeb | |||
|
94 | jm = self.month + (1 + 12*inJanFeb) | |||
|
95 | ||||
|
96 | # Computing Julian days. | |||
|
97 | jul= numpy.floor(365.25*jy) + numpy.floor(30.6001*jm) + (self.dom+1720995.0) | |||
|
98 | ||||
|
99 | # Test whether to change to Gregorian Calendar | |||
|
100 | if numpy.min(jul) >= greg: | |||
|
101 | ja = numpy.int32(0.01*jy) | |||
|
102 | jul = jul + 2 - ja + numpy.int32(0.25*ja) | |||
|
103 | else: | |||
|
104 | gregchange = numpy.where(jul >= greg) | |||
|
105 | if gregchange[0].size>0: | |||
|
106 | ja = numpy.int32(0.01 + jy[gregchange]) | |||
|
107 | jy[gregchange] = jy[gregchange] + 2 - ja + numpy.int32(0.25*ja) | |||
|
108 | ||||
|
109 | # Determining machine-specific parameters affecting floating-point. | |||
|
110 | eps = 0.0 # Replace this line for a function to get precision. | |||
|
111 | eps = abs(jul)*0.0 > eps | |||
|
112 | ||||
|
113 | jul = jul + (self.hour/24. -0.5) + (self.mins/1440.) + (self.secs/86400.) + eps | |||
|
114 | ||||
|
115 | return jul[0] | |||
|
116 | ||||
|
117 | def change2secs(self): | |||
|
118 | """ | |||
|
119 | Converts datetime to number of seconds respect to 1970. | |||
|
120 | """ | |||
|
121 | ||||
|
122 | dtime = dt(self.year, self.month, self.dom) | |||
|
123 | return (dtime-dt(1970, 1, 1)).total_seconds() | |||
|
124 | ||||
|
125 | year = self.year | |||
|
126 | if year.size>1: year = year[0] | |||
|
127 | ||||
|
128 | month = self.month | |||
|
129 | if month.size>1: month = month[0] | |||
|
130 | ||||
|
131 | dom = self.dom | |||
|
132 | if dom.size>1: dom = dom[0] | |||
|
133 | ||||
|
134 | # Resizing hour, mins and secs if it was necessary. | |||
|
135 | hour = self.hour | |||
|
136 | if hour.size>1:hour = hour[0] | |||
|
137 | if hour.size==1:hour = numpy.resize(hour,year.size) | |||
|
138 | ||||
|
139 | mins = self.mins | |||
|
140 | if mins.size>1:mins = mins[0] | |||
|
141 | if mins.size==1:mins = numpy.resize(mins,year.size) | |||
|
142 | ||||
|
143 | secs = self.secs | |||
|
144 | if secs.size>1:secs = secs[0] | |||
|
145 | if secs.size==1:secs = numpy.resize(secs,year.size) | |||
|
146 | ||||
|
147 | # Using time.mktime to compute seconds respect to 1970. | |||
|
148 | secs1970 = numpy.zeros(year.size) | |||
|
149 | for ii in numpy.arange(year.size): | |||
|
150 | secs1970[ii] = time.mktime((int(year[ii]),int(month[ii]),int(dom[ii]),\ | |||
|
151 | int(hour[ii]),int(mins[ii]),int(secs[ii]),0,0,0)) | |||
|
152 | ||||
|
153 | secs1970 = numpy.int32(secs1970 - time.timezone) | |||
|
154 | ||||
|
155 | return secs1970 | |||
|
156 | ||||
|
157 | def change2strdate(self,mode=1): | |||
|
158 | """ | |||
|
159 | change2strdate method converts a date and time of certain event to date string. The | |||
|
160 | string format is like localtime (e.g. Fri Oct 9 15:00:19 2009). | |||
|
161 | ||||
|
162 | Parameters | |||
|
163 | ---------- | |||
|
164 | None. | |||
|
165 | ||||
|
166 | Return | |||
|
167 | ------ | |||
|
168 | ||||
|
169 | Modification History | |||
|
170 | -------------------- | |||
|
171 | Created by Freddy R. Galindo, ROJ, 09 October 2009. | |||
|
172 | ||||
|
173 | """ | |||
|
174 | ||||
|
175 | secs = numpy.atleast_1d(self.change2secs()) | |||
|
176 | strdate = [] | |||
|
177 | for ii in numpy.arange(numpy.size(secs)): | |||
|
178 | secs_tmp = time.localtime(secs[ii] + time.timezone) | |||
|
179 | if mode==1: | |||
|
180 | strdate.append(time.strftime("%d-%b-%Y (%j) %H:%M:%S",secs_tmp)) | |||
|
181 | elif mode==2: | |||
|
182 | strdate.append(time.strftime("%d-%b-%Y (%j)",secs_tmp)) | |||
|
183 | ||||
|
184 | strdate = numpy.array(strdate) | |||
|
185 | ||||
|
186 | return strdate | |||
|
187 | ||||
|
188 | ||||
|
189 | class Secs: | |||
|
190 | """ | |||
|
191 | secs(secs): | |||
|
192 | ||||
|
193 | An object represents the number of seconds respect to 1970. | |||
|
194 | ||||
|
195 | Parameters | |||
|
196 | ---------- | |||
|
197 | ||||
|
198 | SECS = A scalar or array giving the number of seconds respect to 1970. | |||
|
199 | ||||
|
200 | Example: | |||
|
201 | -------- | |||
|
202 | secs_info = secs(1251241373) | |||
|
203 | ||||
|
204 | secs_info = secs([1251241373,1251241383,1251241393]) | |||
|
205 | """ | |||
|
206 | def __init__(self,secs): | |||
|
207 | self.secs = secs | |||
|
208 | ||||
|
209 | def change2julday(self): | |||
|
210 | """ | |||
|
211 | Convert seconds from 1970 to Julian days. | |||
|
212 | """ | |||
|
213 | ||||
|
214 | secs_1970 = time(1970,1,1,0,0,0).change2julday() | |||
|
215 | ||||
|
216 | julian = self.secs/86400.0 + secs_1970 | |||
|
217 | ||||
|
218 | return julian | |||
|
219 | ||||
|
220 | def change2time(self): | |||
|
221 | """ | |||
|
222 | Converts seconds from 1970 to datetime. | |||
|
223 | """ | |||
|
224 | ||||
|
225 | secs1970 = numpy.atleast_1d(self.secs) | |||
|
226 | ||||
|
227 | datetime = numpy.zeros((9,secs1970.size)) | |||
|
228 | for ii in numpy.arange(secs1970.size): | |||
|
229 | tuple = time.gmtime(secs1970[ii]) | |||
|
230 | datetime[0,ii] = tuple[0] | |||
|
231 | datetime[1,ii] = tuple[1] | |||
|
232 | datetime[2,ii] = tuple[2] | |||
|
233 | datetime[3,ii] = tuple[3] | |||
|
234 | datetime[4,ii] = tuple[4] | |||
|
235 | datetime[5,ii] = tuple[5] | |||
|
236 | datetime[6,ii] = tuple[6] | |||
|
237 | datetime[7,ii] = tuple[7] | |||
|
238 | datetime[8,ii] = tuple[8] | |||
|
239 | ||||
|
240 | datetime = numpy.int32(datetime) | |||
|
241 | ||||
|
242 | return datetime | |||
|
243 | ||||
|
244 | ||||
|
245 | class Julian: | |||
|
246 | """ | |||
|
247 | julian(julian): | |||
|
248 | ||||
|
249 | An object represents julian days. | |||
|
250 | ||||
|
251 | Parameters | |||
|
252 | ---------- | |||
|
253 | ||||
|
254 | JULIAN = A scalar or array giving the julina days. | |||
|
255 | ||||
|
256 | Example: | |||
|
257 | -------- | |||
|
258 | julian_info = julian(2454740) | |||
|
259 | ||||
|
260 | julian_info = julian([2454740,2454760,2454780]) | |||
|
261 | """ | |||
|
262 | def __init__(self,julian): | |||
|
263 | self.julian = numpy.atleast_1d(julian) | |||
|
264 | ||||
|
265 | def change2time(self): | |||
|
266 | """ | |||
|
267 | change2time method converts from julian day to calendar date and time. | |||
|
268 | ||||
|
269 | Return | |||
|
270 | ------ | |||
|
271 | year = An array giving the year of the desired julian day. | |||
|
272 | month = An array giving the month of the desired julian day. | |||
|
273 | dom = An array giving the day of the desired julian day. | |||
|
274 | hour = An array giving the hour of the desired julian day. | |||
|
275 | mins = An array giving the minute of the desired julian day. | |||
|
276 | secs = An array giving the second of the desired julian day. | |||
|
277 | ||||
|
278 | Examples | |||
|
279 | -------- | |||
|
280 | >> jd = 2455119.0 | |||
|
281 | >> [yy,mo,dd,hh,mi,ss] = TimeTools.julian(jd).change2time() | |||
|
282 | >> print [yy,mo,dd,hh,mi,ss] | |||
|
283 | [2009] [10] [ 14.] [ 12.] [ 0.] [ 0.] | |||
|
284 | ||||
|
285 | Modification history | |||
|
286 | -------------------- | |||
|
287 | Translated from "Numerical Recipies in C", by William H. Press, Brian P. Flannery, | |||
|
288 | Saul A. Teukolsky, and William T. Vetterling. Cambridge University Press, 1988. | |||
|
289 | Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009. | |||
|
290 | """ | |||
|
291 | ||||
|
292 | min_julian = -1095 | |||
|
293 | max_julian = 1827933925 | |||
|
294 | if (numpy.min(self.julian) < min_julian) or (numpy.max(self.julian) > max_julian): | |||
|
295 | print ('Value of Julian date is out of allowed range.') | |||
|
296 | return None | |||
|
297 | ||||
|
298 | # Beginning of Gregorian calendar | |||
|
299 | igreg = 2299161 | |||
|
300 | julLong = numpy.floor(self.julian + 0.5) | |||
|
301 | minJul = numpy.min(julLong) | |||
|
302 | ||||
|
303 | if (minJul >= igreg): | |||
|
304 | # All are Gregorian | |||
|
305 | jalpha = numpy.int32(((julLong - 1867216) - 0.25)/36524.25) | |||
|
306 | ja = julLong + 1 + jalpha - numpy.int32(0.25*jalpha) | |||
|
307 | else: | |||
|
308 | ja = julLong | |||
|
309 | gregChange = numpy.where(julLong >= igreg) | |||
|
310 | if gregChange[0].size>0: | |||
|
311 | jalpha = numpy.int32(((julLong[gregChange]-1867216) - 0.25)/36524.25) | |||
|
312 | ja[gregChange] = julLong[gregChange]+1+jalpha-numpy.int32(0.25*jalpha) | |||
|
313 | ||||
|
314 | # clear memory. | |||
|
315 | jalpha = -1 | |||
|
316 | ||||
|
317 | jb = ja + 1524 | |||
|
318 | jc = numpy.int32(6680. + ((jb-2439870)-122.1)/365.25) | |||
|
319 | jd = numpy.int32(365.*jc + (0.25*jc)) | |||
|
320 | je = numpy.int32((jb - jd)/30.6001) | |||
|
321 | ||||
|
322 | dom = jb - jd - numpy.int32(30.6001*je) | |||
|
323 | month = je - 1 | |||
|
324 | month = ((month - 1) % 12) + 1 | |||
|
325 | month = numpy.atleast_1d(month) | |||
|
326 | year = jc - 4715 | |||
|
327 | year = year - (month > 2)*1 | |||
|
328 | year = year - (year <= 0)*1 | |||
|
329 | year = numpy.atleast_1d(year) | |||
|
330 | ||||
|
331 | # Getting hours, minutes, seconds | |||
|
332 | fraction = self.julian + 0.5 - julLong | |||
|
333 | eps_0 = dom*0.0 + 1.0e-12 | |||
|
334 | eps_1 = 1.0e-12*numpy.abs(julLong) | |||
|
335 | eps = (eps_0>eps_1)*eps_0 + (eps_0<=eps_1)*eps_1 | |||
|
336 | ||||
|
337 | hour_0 = dom*0 + 23 | |||
|
338 | hour_2 = dom*0 + 0 | |||
|
339 | hour_1 = numpy.floor(fraction*24.0 + eps) | |||
|
340 | hour = ((hour_1>hour_0)*23) + ((hour_1<=hour_0)*hour_1) | |||
|
341 | hour = ((hour_1<hour_2)*0) + ((hour_1>=hour_2)*hour_1) | |||
|
342 | ||||
|
343 | fraction = fraction - (hour/24.0) | |||
|
344 | mins_0 = dom*0 + 59 | |||
|
345 | mins_2 = dom*0 + 0 | |||
|
346 | mins_1 = numpy.floor(fraction*1440.0 + eps) | |||
|
347 | mins = ((mins_1>mins_0)*59) + ((mins_1<=mins_0)*mins_1) | |||
|
348 | mins = ((mins_1<mins_2)*0) + ((mins_1>=mins_2)*mins_1) | |||
|
349 | ||||
|
350 | secs_2 = dom*0 + 0 | |||
|
351 | secs_1 = (fraction - mins/1440.0)*86400.0 | |||
|
352 | secs = ((secs_1<secs_2)*0) + ((secs_1>=secs_2)*secs_1) | |||
|
353 | ||||
|
354 | return year,month,dom,hour,mins,secs | |||
|
355 | ||||
|
356 | def change2secs(self): | |||
|
357 | """ | |||
|
358 | Converts from Julian days to seconds from 1970. | |||
|
359 | """ | |||
|
360 | ||||
|
361 | jul_1970 = Time(1970,1,1,0,0,0).change2julday() | |||
|
362 | ||||
|
363 | secs = numpy.int32((self.julian - jul_1970)*86400) | |||
|
364 | ||||
|
365 | return secs | |||
|
366 | ||||
|
367 | def change2lst(self,longitude=-76.8667): | |||
|
368 | """ | |||
|
369 | CT2LST converts from local civil time to local mean sideral time | |||
|
370 | ||||
|
371 | longitude = The longitude in degrees (east of Greenwich) of the place for which | |||
|
372 | the local sideral time is desired, scalar. The Greenwich mean sideral time (GMST) | |||
|
373 | can be found by setting longitude=0. | |||
|
374 | """ | |||
|
375 | ||||
|
376 | # Useful constants, see Meus, p. 84 | |||
|
377 | c = numpy.array([280.46061837, 360.98564736629, 0.000387933, 38710000.0]) | |||
|
378 | jd2000 = 2451545.0 | |||
|
379 | t0 = self.julian - jd2000 | |||
|
380 | t = t0/36525. | |||
|
381 | ||||
|
382 | # Computing GST in seconds | |||
|
383 | theta = c[0] + (c[1]*t0) + (t**2)*(c[2]-t/c[3]) | |||
|
384 | ||||
|
385 | # Computing LST in hours | |||
|
386 | lst = (theta + longitude)/15.0 | |||
|
387 | neg = numpy.where(lst < 0.0) | |||
|
388 | if neg[0].size>0:lst[neg] = 24.0 + (lst[neg] % 24) | |||
|
389 | lst = lst % 24.0 | |||
|
390 | ||||
|
391 | return lst | |||
|
392 | ||||
|
393 | ||||
|
394 | class date2doy: | |||
|
395 | def __init__(self,year,month,day): | |||
|
396 | self.year = year | |||
|
397 | self.month = month | |||
|
398 | self.day = day | |||
|
399 | ||||
|
400 | def change2doy(self): | |||
|
401 | if calendar.isleap(self.year) == True: | |||
|
402 | tfactor = 1 | |||
|
403 | else: | |||
|
404 | tfactor = 2 | |||
|
405 | ||||
|
406 | day = self.day | |||
|
407 | month = self.month | |||
|
408 | ||||
|
409 | doy = numpy.floor((275*month)/9.0) - (tfactor*numpy.floor((month+9)/12.0)) + day - 30 | |||
|
410 | ||||
|
411 | return numpy.int32(doy) | |||
|
412 | ||||
|
413 | ||||
|
414 | class Doy2Date: | |||
|
415 | def __init__(self,year,doy): | |||
|
416 | self.year = year | |||
|
417 | self.doy = doy | |||
|
418 | ||||
|
419 | def change2date(self): | |||
|
420 | months = numpy.arange(12) + 1 | |||
|
421 | ||||
|
422 | first_dem = date2doy(self.year,months,1) | |||
|
423 | first_dem = first_dem.change2doy() | |||
|
424 | ||||
|
425 | imm = numpy.where((self.doy - first_dem) > 0) | |||
|
426 | ||||
|
427 | month = imm[0].size | |||
|
428 | dom = self.doy -first_dem[month - 1] + 1 | |||
|
429 | ||||
|
430 | return month, dom |
1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 |
@@ -0,0 +1,99 | |||||
|
1 | 0000 13.00 | |||
|
2 | 0015 13.00 | |||
|
3 | 0030 13.00 | |||
|
4 | 0045 13.00 | |||
|
5 | 0060 13.00 | |||
|
6 | 0075 12.50 | |||
|
7 | 0090 12.50 | |||
|
8 | 0105 12.50 | |||
|
9 | 0120 11.50 | |||
|
10 | 0135 11.00 | |||
|
11 | 0150 10.50 | |||
|
12 | 0165 10.00 | |||
|
13 | 0180 10.00 | |||
|
14 | 0195 10.00 | |||
|
15 | 0210 9.00 | |||
|
16 | 0225 8.50 | |||
|
17 | 0240 8.50 | |||
|
18 | 0255 8.50 | |||
|
19 | 0270 8.50 | |||
|
20 | 0285 8.00 | |||
|
21 | 0300 8.00 | |||
|
22 | 0315 8.50 | |||
|
23 | 0330 9.00 | |||
|
24 | 0345 10.00 | |||
|
25 | 0360 11.00 | |||
|
26 | 0375 12.50 | |||
|
27 | 0390 14.50 | |||
|
28 | 0405 17.00 | |||
|
29 | 0420 18.00 | |||
|
30 | 0435 17.00 | |||
|
31 | 0450 15.50 | |||
|
32 | 0465 15.00 | |||
|
33 | 0480 14.00 | |||
|
34 | 0495 12.50 | |||
|
35 | 0510 11.00 | |||
|
36 | 0525 10.00 | |||
|
37 | 0540 9.50 | |||
|
38 | 0555 9.00 | |||
|
39 | 0570 23.00 | |||
|
40 | 0585 8.00 | |||
|
41 | 0600 10.00 | |||
|
42 | 0615 10.50 | |||
|
43 | 0630 10.00 | |||
|
44 | 0645 9.00 | |||
|
45 | 0660 8.50 | |||
|
46 | 0675 9.00 | |||
|
47 | 0690 10.00 | |||
|
48 | 0705 11.00 | |||
|
49 | 0720 12.00 | |||
|
50 | 0735 12.50 | |||
|
51 | 0750 13.50 | |||
|
52 | 0765 13.00 | |||
|
53 | 0780 13.00 | |||
|
54 | 0795 13.00 | |||
|
55 | 0810 13.00 | |||
|
56 | 0825 12.50 | |||
|
57 | 0840 12.00 | |||
|
58 | 0855 12.50 | |||
|
59 | 0870 13.00 | |||
|
60 | 0885 14.00 | |||
|
61 | 0900 15.00 | |||
|
62 | 0915 17.00 | |||
|
63 | 0930 18.00 | |||
|
64 | 0945 17.50 | |||
|
65 | 0960 16.50 | |||
|
66 | 0975 16.50 | |||
|
67 | 0990 17.00 | |||
|
68 | 0990 17.00 | |||
|
69 | 1005 17.00 | |||
|
70 | 1020 20.00 | |||
|
71 | 1035 26.00 | |||
|
72 | 1050 30.00 | |||
|
73 | 1065 36.00 | |||
|
74 | 1080 47.00 | |||
|
75 | 1095 71.00 | |||
|
76 | 1102 60.00 | |||
|
77 | 1110 77.00 | |||
|
78 | 1115 87.00 | |||
|
79 | 1120 83.00 | |||
|
80 | 1130 60.00 | |||
|
81 | 1140 50.00 | |||
|
82 | 1155 35.00 | |||
|
83 | 1170 28.00 | |||
|
84 | 1185 21.00 | |||
|
85 | 1200 18.00 | |||
|
86 | 1215 16.00 | |||
|
87 | 1237 15.50 | |||
|
88 | 1260 15.00 | |||
|
89 | 1275 15.50 | |||
|
90 | 1290 16.00 | |||
|
91 | 1305 15.50 | |||
|
92 | 1320 15.00 | |||
|
93 | 1335 14.50 | |||
|
94 | 1350 14.00 | |||
|
95 | 1365 13.00 | |||
|
96 | 1380 12.00 | |||
|
97 | 1395 12.50 | |||
|
98 | 1410 13.00 | |||
|
99 | 1425 12.50 |
@@ -0,0 +1,188 | |||||
|
1 | ||||
|
2 | import os | |||
|
3 | import time | |||
|
4 | import numpy | |||
|
5 | import scipy | |||
|
6 | import base64 | |||
|
7 | from io import BytesIO | |||
|
8 | import scipy.interpolate | |||
|
9 | from matplotlib.figure import Figure | |||
|
10 | ||||
|
11 | from utils import TimeTools | |||
|
12 | ||||
|
13 | def skyNoise(jd, ut=-5.0, longitude=-76.87, filename='/app/utils/galaxy.txt'): | |||
|
14 | """ | |||
|
15 | hydrapos returns RA and Dec provided by Bill Coles (Oct 2003). | |||
|
16 | ||||
|
17 | Parameters | |||
|
18 | ---------- | |||
|
19 | jd = The julian date of the day (and time), scalar or vector. | |||
|
20 | ||||
|
21 | dec_cut = A scalar giving the declination to get a cut of the skynoise over Jica- | |||
|
22 | marca. The default value is -11.95. | |||
|
23 | filename = A string to specify name the skynoise file. The default value is skynoi- | |||
|
24 | se_jro.dat | |||
|
25 | ||||
|
26 | Return | |||
|
27 | ------ | |||
|
28 | maxra = The maximum right ascension to the declination used to get a cut. | |||
|
29 | ra = The right ascension. | |||
|
30 | ||||
|
31 | Examples | |||
|
32 | -------- | |||
|
33 | >> [maxra,ra] = skynoise_jro() | |||
|
34 | >> print maxra, ra | |||
|
35 | 139.45 -12.0833333333 | |||
|
36 | ||||
|
37 | Modification history | |||
|
38 | -------------------- | |||
|
39 | Converted to Python by Freddy R. Galindo, ROJ, 06 October 2009. | |||
|
40 | """ | |||
|
41 | ||||
|
42 | # Defining date to compute SkyNoise. | |||
|
43 | [year, month, dom, hour, mis, secs] = TimeTools.Julian(jd).change2time() | |||
|
44 | is_dom = (month==9) & (dom==21) | |||
|
45 | if is_dom: | |||
|
46 | tmp = jd | |||
|
47 | jd = TimeTools.Time(year,9,22).change2julian() | |||
|
48 | dom = 22 | |||
|
49 | ||||
|
50 | # Reading SkyNoise | |||
|
51 | ||||
|
52 | g = os.getcwd() | |||
|
53 | ||||
|
54 | f = open(filename) | |||
|
55 | ||||
|
56 | lines = f.read() | |||
|
57 | f.close() | |||
|
58 | ||||
|
59 | nlines = 99 | |||
|
60 | lines = lines.split('\n') | |||
|
61 | data = numpy.zeros((2,nlines))*numpy.float32(0.) | |||
|
62 | for ii in numpy.arange(nlines): | |||
|
63 | line = numpy.array([lines[ii][0:6],lines[ii][6:]]) | |||
|
64 | data[:,ii] = numpy.float32(line) | |||
|
65 | ||||
|
66 | # Getting SkyNoise to the date desired. | |||
|
67 | otime = data[0,:]*60.0 | |||
|
68 | opowr = data[1,:] | |||
|
69 | ||||
|
70 | hour = numpy.array([0,23]) | |||
|
71 | mins = numpy.array([0,59]) | |||
|
72 | secs = numpy.array([0,59]) | |||
|
73 | LTrange = TimeTools.Time(year,month,dom,hour,mins,secs).change2julday() | |||
|
74 | LTtime = LTrange[0] + numpy.arange(1440)*((LTrange[1] - LTrange[0])/(1440.-1)) | |||
|
75 | lst = TimeTools.Julian(LTtime + (-3600.*ut/86400.)).change2lst() | |||
|
76 | ||||
|
77 | ipowr = lst*0.0 | |||
|
78 | # Interpolating using scipy (inside max and min "x") | |||
|
79 | otime = otime/3600. | |||
|
80 | val = numpy.where((lst>numpy.min(otime)) & (lst<numpy.max(otime))); val = val[0] | |||
|
81 | tck = scipy.interpolate.interp1d(otime,opowr) | |||
|
82 | ipowr[val] = tck(lst[val]) | |||
|
83 | ||||
|
84 | # Extrapolating above maximum time data (23.75). | |||
|
85 | uval = numpy.where(lst>numpy.max(otime)) | |||
|
86 | if uval[0].size>0: | |||
|
87 | ii = numpy.min(uval[0]) | |||
|
88 | m = (ipowr[ii-1] - ipowr[ii-2])/(lst[ii-1] - lst[ii-2]) | |||
|
89 | b = ipowr[ii-1] - m*lst[ii-1] | |||
|
90 | ipowr[uval] = m*lst[uval] + b | |||
|
91 | ||||
|
92 | if is_dom: | |||
|
93 | lst = numpy.roll(lst,4) | |||
|
94 | ipowr = numpy.roll(ipowr,4) | |||
|
95 | ||||
|
96 | new_lst = numpy.int32(lst*3600.) | |||
|
97 | new_pow = ipowr | |||
|
98 | ||||
|
99 | return ipowr, LTtime, lst | |||
|
100 | ||||
|
101 | def skynoise_plot(year, month, day): | |||
|
102 | """ | |||
|
103 | getPlot method creates a skynoise map over Jicamarca for a desired day. Additionally | |||
|
104 | save a PNG file of this plot. | |||
|
105 | ||||
|
106 | Examples | |||
|
107 | -------- | |||
|
108 | >> SkyNoisePlot(skypower,skytime,skytime_lst).getPlot() | |||
|
109 | ||||
|
110 | Modification history | |||
|
111 | -------------------- | |||
|
112 | Created by Freddy R. Galindo, ROJ, 18 October 2009. | |||
|
113 | """ | |||
|
114 | ||||
|
115 | # Working with the time before to plot the SkyNoise | |||
|
116 | ||||
|
117 | julian = TimeTools.Time(year, month, day).change2julday() | |||
|
118 | power, tm, time_lst = skyNoise(julian) | |||
|
119 | ||||
|
120 | secs = TimeTools.Julian(tm).change2secs() | |||
|
121 | secs_lst = time_lst*1. | |||
|
122 | if time_lst.argmin()>0: | |||
|
123 | secs_lst[time_lst.argmin():] = secs_lst[time_lst.argmin():] + 24. | |||
|
124 | secs_lst = secs_lst*3600. | |||
|
125 | ||||
|
126 | label_secs = time.localtime(secs[power.argmax()] + time.timezone) | |||
|
127 | label_secs_lst = time.localtime(secs_lst[power.argmax()] + time.timezone) | |||
|
128 | ||||
|
129 | # Creating labels for main x-labelticks (Local Time): | |||
|
130 | snow = TimeTools.Time(year, month, day, 0, 0, 0).change2secs() | |||
|
131 | today = secs - snow | |||
|
132 | xticks_dpos = [] | |||
|
133 | xticks_dval = [] | |||
|
134 | for ix in [0,120,240,360,480,600,720,840,960,1080,1200,1320,1439]: | |||
|
135 | xticks_dpos.append(today[ix]) | |||
|
136 | time_tuple = time.localtime(today[ix] + time.timezone) | |||
|
137 | xticks_dval.append(time.strftime('%H:%M',time_tuple)) | |||
|
138 | if ix==1439:xticks_dval[12] = '' | |||
|
139 | ||||
|
140 | # Creating labels for secondary x-labelticks (Sidereal Time): | |||
|
141 | xticks_upos = [secs_lst[0],secs_lst[-1]] | |||
|
142 | xticks_uval = ['',''] | |||
|
143 | for ix in [0,120,240,360,480,600,720,840,960,1080,1200,1320]: | |||
|
144 | index = numpy.argmin(numpy.abs(time_lst - (ix/60. + 1.))) | |||
|
145 | xticks_upos.append(secs_lst[index]) | |||
|
146 | time_tuple = time.localtime(secs_lst[index] + time.timezone) | |||
|
147 | if time_tuple[4]==59: | |||
|
148 | tmp_list = list(time_tuple) | |||
|
149 | tmp_list[4] = 0 | |||
|
150 | tmp_list[3] = tmp_list[3] + 1 | |||
|
151 | time_tuple = tuple(tmp_list) | |||
|
152 | xticks_uval.append(time.strftime('%H:%M',time_tuple)) | |||
|
153 | ||||
|
154 | # Creating SkyNoise Map. | |||
|
155 | fig = Figure() | |||
|
156 | fig.subplots_adjust(top=0.80) | |||
|
157 | ||||
|
158 | main_mesg = "SKY BRIGHTNESS AT 50Mhz - Date: " | |||
|
159 | main_mesg = main_mesg + time.strftime("%d-%b-%Y (%j)",label_secs) | |||
|
160 | main_mesg = main_mesg + "\nGalaxy Pass at " + time.strftime("%H:%M:%S LT",label_secs) | |||
|
161 | main_mesg = main_mesg + time.strftime(" (%H:%M:%S LST)",label_secs_lst) | |||
|
162 | ||||
|
163 | fig.suptitle(main_mesg, fontsize=12) | |||
|
164 | axl = fig.add_subplot(1,1,1) | |||
|
165 | ||||
|
166 | axl.plot(today,power,'b-') | |||
|
167 | axr = axl.twinx() | |||
|
168 | axl.set_xlabel('Local Time (Hours)') | |||
|
169 | axl.set_ylabel('Signal Strengh (mA)') | |||
|
170 | axr.set_ylabel('Temperature [K]x10^3') | |||
|
171 | axl.set_xlim(0,24) | |||
|
172 | axl.set_ylim(0,115) | |||
|
173 | axr.set_ylim(0,50) | |||
|
174 | axl.set_xticks(xticks_dpos) | |||
|
175 | axl.set_xticklabels(xticks_dval, fontsize=8) | |||
|
176 | axl.grid() | |||
|
177 | ||||
|
178 | axt = axl.twiny() | |||
|
179 | axt.set_xlabel('Local Sidereal Time (Hours)') | |||
|
180 | axt.set_xlim(secs_lst[0],secs_lst[-1]) | |||
|
181 | axt.set_xticks(xticks_upos) | |||
|
182 | axt.set_xticklabels(xticks_uval, fontsize=8) | |||
|
183 | ||||
|
184 | buf = BytesIO() | |||
|
185 | fig.savefig(buf, format="png") | |||
|
186 | ||||
|
187 | return buf | |||
|
188 |
@@ -18,12 +18,12 | |||||
18 | aria-hidden="true"></i></span> |
|
18 | aria-hidden="true"></i></span> | |
19 | </div> |
|
19 | </div> | |
20 | <input type="text" class="form-control" id="skynoise-date" placeholder="dd/mm/yy" |
|
20 | <input type="text" class="form-control" id="skynoise-date" placeholder="dd/mm/yy" | |
21 |
aria-describedby="validationTooltipSkynoiseDate" value="{% now ' |
|
21 | aria-describedby="validationTooltipSkynoiseDate" value="{% now 'd-m-Y' %}" required> | |
22 | <div class="invalid-tooltip"> |
|
22 | <div class="invalid-tooltip"> | |
23 | Please enter a valid date. |
|
23 | Please enter a valid date. | |
24 | </div> |
|
24 | </div> | |
25 | <a class="btn btn-primary" data-toggle="modal" href="#toolModal" data-title="Sky Noise" |
|
25 | <a class="btn btn-primary" data-toggle="modal" href="#toolModal" data-title="Sky Noise" | |
26 | data-image="http://jro-app.igp.gob.pe/programs/skynoise/cgi-bin/sky_noise.pl?">Go</a> |
|
26 | data-image="{% url 'url_skynoise' %}">Go</a> | |
27 | </div> |
|
27 | </div> | |
28 | </div> |
|
28 | </div> | |
29 | </div> |
|
29 | </div> | |
@@ -69,8 +69,8 | |||||
69 | var image = $(e.relatedTarget).data('image'); |
|
69 | var image = $(e.relatedTarget).data('image'); | |
70 |
|
70 | |||
71 | if (image.indexOf('skynoise') > 0) { |
|
71 | if (image.indexOf('skynoise') > 0) { | |
72 |
var dt = $('#skynoise-date').val() |
|
72 | var dt = $('#skynoise-date').val(); | |
73 | image += 'month=' + dt[0] + '&dom=' + dt[1] + '&year=' + dt[2]; |
|
73 | image += '?date=' + dt; | |
74 | } |
|
74 | } | |
75 |
|
75 | |||
76 | //populate values |
|
76 | //populate values |
@@ -1,10 +1,11 | |||||
1 | from django.conf.urls import url |
|
1 | from django.conf.urls import url | |
2 | from .views import main, plot, tools, reports |
|
2 | from .views import main, plot, tools, plot_skynoise, reports | |
3 |
|
3 | |||
4 |
|
4 | |||
5 | urlpatterns = [ |
|
5 | urlpatterns = [ | |
6 | url(r'^$', main, name='url_main'), |
|
6 | url(r'^$', main, name='url_main'), | |
7 | url(r'^tools/$', tools, name='url_tools'), |
|
7 | url(r'^tools/$', tools, name='url_tools'), | |
|
8 | url(r'^tools/skynoise.png$', plot_skynoise, name='url_skynoise'), | |||
8 | url(r'^reports/$', reports, name='url_reports'), |
|
9 | url(r'^reports/$', reports, name='url_reports'), | |
9 | url(r'^(?P<code>[0-9]+)/(?P<plot>[-\w]+)/$', plot, name='url-plot'), |
|
10 | url(r'^(?P<code>[0-9]+)/(?P<plot>[-\w]+)/$', plot, name='url-plot'), | |
10 | ] |
|
11 | ] |
@@ -10,11 +10,14 from django import forms | |||||
10 | from django.contrib import messages |
|
10 | from django.contrib import messages | |
11 | from django.utils.safestring import mark_safe |
|
11 | from django.utils.safestring import mark_safe | |
12 | from django.shortcuts import render |
|
12 | from django.shortcuts import render | |
|
13 | from django.http import HttpResponse | |||
13 |
|
14 | |||
14 | import mongoengine |
|
15 | import mongoengine | |
15 |
|
16 | |||
16 | from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData |
|
17 | from plotter.models import Experiment, ExpDetail, PlotMeta, PlotData | |
17 |
|
18 | |||
|
19 | from utils.plots import skynoise_plot | |||
|
20 | ||||
18 | host = os.environ.get('HOST_MONGO', 'localhost') |
|
21 | host = os.environ.get('HOST_MONGO', 'localhost') | |
19 | mongoengine.connect('dbplots', host=host, port=27017) |
|
22 | mongoengine.connect('dbplots', host=host, port=27017) | |
20 |
|
23 | |||
@@ -168,4 +171,15 def plot(request, code=None, plot=None): | |||||
168 | else: |
|
171 | else: | |
169 | return render(request, 'home.html', {}) |
|
172 | return render(request, 'home.html', {}) | |
170 |
|
173 | |||
171 | No newline at end of file |
|
174 | def plot_skynoise(request): | |
|
175 | ||||
|
176 | date = request.GET.get('date', None) | |||
|
177 | if date is None: | |||
|
178 | date = datetime.now() | |||
|
179 | else: | |||
|
180 | date = datetime.strptime(date, '%d-%m-%Y') | |||
|
181 | ||||
|
182 | data = skynoise_plot(date.year, date.month, date.day) | |||
|
183 | response = HttpResponse(data.getvalue(), content_type='image/png') | |||
|
184 | ||||
|
185 | return response |
General Comments 0
You need to be logged in to leave comments.
Login now