1 """
2 This module allows to calculate the altitude and airmass of an object in the sky, to determine whether it is 'observable' during day or night time,
3 and to get the separation to the moon.
4
5 Examples:
6
7 Plot the visibility of an object for 10 days, every 10 minutes.
8
9 >>> eph = Ephemeris()
10 >>> eph.set_objects(objects=['HD50230'])
11 >>> eph.set_date(startdate='2011/09/27 12:00:00.0',dt=10.,days=10)
12 >>> eph.set_site(sitename='lapalma')
13 >>> eph.visibility()
14 >>> eph.plot(fmt='bo')
15
16 ]]include figure]]severalnightsvisibility.png]
17
18 You can get the same behaviour in less commands:
19
20 >>> eph = Ephemeris(objects=['HD50230'],startdate='2011/09/27 12:00:00.0',dt=10.,days=10,sitename='lapalma')
21 >>> eph.visibility()
22
23 Or, equivalently,
24
25 >>> eph = Ephemeris()
26 >>> eph.visibility(objects=['HD50230'],startdate='2011/09/27 12:00:00.0',dt=10.,days=10)
27
28 Get the visibility of 2 objects and the moon only for a certain date:
29
30 >>> eph = Ephemeris(objects=['HD163506','HD143454'])
31 >>> eph.visibility(startdate=2456084.01922,days=1,sitename='palomar')
32 >>> eph.plot(moon=True,lw=2)
33
34 ]]include figure]]nightvisibility.png]
35
36 One can also get the visibility of an object in a random capital at the middle of the night throughout the year:
37
38 >>> eph = Ephemeris(objects=['V* V441 Her'])
39 >>> eph.visibility(midnight=True,sitename='Paris')
40 >>> eph.plot(moon=False)
41
42 ]]include figure]]yearvisibility.png]
43
44 Calculate visibility for a list of objects, sites and times:
45
46 >>> eph = Ephemeris()
47 >>> days = np.array([2456084.0,2456085.02,2456085.29,2456085.55,2456095.6321])
48 >>> objectnames = np.array(['HD163506','HD163506','HD163506','HD143454','HD143454'])
49 >>> sitenames = np.array(['lapalma','lapalma','palomar','palomar','lapalma'])
50 >>> eph.visibility(multiple=True,startdate=days,objects=objectnames,sitename=sitenames)
51 >>> eph.plot(moon=True)
52
53 ]]include figure]]multiple1.png]
54
55 Note that only the last point is plotted, this is because the other given times correspond to day time. This can be deduced from the color ordering of the day
56 (yellow) and night (grey) which are plotted nevertheless.
57 Mixing sites can result in ugly plots quite rapidly. So we can also just keep the site fixed (also works for the objects and times):
58
59 >>> eph = Ephemeris()
60 >>> days = np.array([2456084.73,2456085.58,2456085.69,2456085.74,2456095.8321,2456132.978])
61 >>> objectnames = np.array(['HD163506','HD163506','HD163506','HD143454','HD143454','HD163506'])
62 >>> eph.visibility(multiple=True,startdate=days,objects=objectnames,sitename='palomar')
63 >>> eph.plot(moon=True)
64
65 ]]include figure]]multiple2.png]
66
67 Note that in this case, the last point is not plotted although the color coding says it corresponds to night time. Logically, this is because the object is simply
68 below the horizon.
69
70 """
71 import pylab as pl
72 from matplotlib.dates import date2num,num2date,DayLocator,HourLocator,DateFormatter
73 import numpy as np
74 from numpy import sqrt,pi,cos,sin
75 import sys
76 import time
77 import pytz
78 import logging
79 import ephem
80
81 from ivs.units import conversions
82 from ivs.catalogs import sesame
83 from ivs.observations import airmass as obs_airmass
84 from ivs.aux import decorators
85
86 logger = logging.getLogger("OBS.VIS")
91 """
92 Initialize an Ephemeris object.
93
94 You can set the site, date and objects via the keyword arguments of the functions 'set_objects', 'set_site' and 'set_date'.
95 Defaults are 'no objects', 'la palma' and 'the current time'.
96
97 You can also give the same information when calling 'visibility'.
98 """
99 self.set_site(**kwargs)
100 self.set_date(**kwargs)
101 self.set_objects(**kwargs)
102
104 """
105 Retrieve coordinates for an object in 'ephem'-style.
106 """
107 try:
108 jpos = sesame.search(objectname,db='S')['jpos']
109 logger.info('Found object %s at %s'%(objectname,jpos))
110 except KeyError:
111 logger.warning('Object %s not found in SIMBAD, trying NED.'%(objectname))
112 try:
113 jpos = sesame.search(objectname,db='N')['jpos']
114 except KeyError:
115 logger.warning('Object %s not found in NED either.'%(objectname))
116 raise IOError, 'No coordinates retrieved for object %s.'%(objectname)
117 myobject = ephem.readdb("%s,f|M|A0,%s,8.0,2000"%(objectname,','.join(jpos.split())))
118 return myobject
119
120
121 @decorators.filter_kwargs
123 """
124 Initializes a list of objects by searching their coordinates on SIMBAD or NED.
125
126 @keyword objects: a list of object names, resolved by SIMBAD or NED.
127 @type objects: iterable
128 """
129 if objects is not None:
130 objects = [self.__set_object(name) for name in objects]
131 self.objects = objects
132
134 """
135 Return the names of the objects.
136 """
137 return [member.name for member in self.objects]
138
139 @decorators.filter_kwargs
140 - def set_site(self,sitename='lapalma',sitelat=None,sitelong=None,siteelev=None):
141 """
142 Set the observing site.
143
144 Supported are: 'lapalma', 'lasilla', 'palomar' and a bunch of capitals defined in pyephem.
145 The other keywords allow to manually define a site or change one or more of the parameters of a manually defined site (always enter a sitename though!).
146 If sitename is None, the site is left unchanged.
147
148 @keyword sitename: the name of the site or city
149 @keyword sitelong: longitude (EAST) of site
150 @type sitelong: string
151 @keyword sitelat: latitude (NORTH) of site
152 @type sitelat: string
153 @keyword siteelev: site elevation above sea level (m)
154 @type siteelev: integer or float
155 """
156
157 if hasattr(self,'thesite'):
158 date = self.thesite.date
159 else:
160 date = time.strftime('%Y/%m/%d %H:%M:%S',time.gmtime())
161
162 if sitename == None:
163 mysite = self.thesite
164 elif sitename == 'lapalma':
165
166 mysite = ephem.Observer()
167
168 mysite.long = '342.1184'
169 mysite.lat = '28:%.3f'%(45+44/60.)
170 mysite.elevation = 2326
171 mysite.name = sitename
172 elif sitename == 'lasilla':
173 mysite = ephem.Observer()
174 mysite.long = '-70:43.8'
175 mysite.lat = '-29:15.4'
176 mysite.elevation = 2347
177 mysite.name = sitename
178 elif sitename == 'palomar':
179 mysite = ephem.Observer()
180 mysite.long = '-116:51:46.80'
181 mysite.lat = '33:21:21.6'
182 mysite.elevation = 1706
183 mysite.name = sitename
184 else:
185 try:
186 mysite = ephem.city(sitename)
187 except:
188 logger.critical('Site %s not known, using user definitions'%(sitename))
189 if hasattr(self,'thesite'):
190 mysite = self.thesite
191 logger.critical('Previous site edited with new values!')
192 else:
193 mysite = ephem.Observer()
194 logger.critical('No site previously defined, so all keywords needed!')
195 if sitename != None:
196 mysite.name = sitename
197 logger.info('Site name set to %s'%(sitename))
198 if siteelevation != None:
199 mysite.elevation = siteelev
200 logger.info('Site elevation set to %s'%(sitename))
201 if sitelat != None:
202 mysite.lat = sitelat
203 logger.info('Site latitude set to %s'%(sitename))
204 if sitelong != None:
205 mysite.long = sitelong
206 logger.info('Site longitude set to %s'%(sitename))
207 self.thesite = mysite
208 self.thesite.date = ephem.Date(date)
209 logger.info('Set site to %s (long=%s EAST, lat=%s NORTH, elev=%s m)'%(mysite.name,mysite.long,mysite.lat,mysite.elevation))
210
211 @decorators.filter_kwargs
212 - def set_date(self,startdate='today',days=20,dt=10.):
213 """
214 Set the start date for ephemeris calculations.
215
216 'startdate' can take the following formats:
217 Format 1: Calendar date: '2010/08/16 12:00:00.0' ,
218 Format 2: Julian Date: 2455832.25 ,
219 Format 3: None: no change, or 'today': the current date (=default)
220
221 Careful: all times are UTC, they do not take care of time zones.
222 default values are also set in UTC (gmtime)
223
224 @keyword startdate: the exact time of the first visibility calculation
225 @type startdate: string or float
226 @keyword days: total number of days on which to calculate visibilities (if visibility keyword 'multiple' = False)
227 @type days: float
228 @keyword dt: sampling time in minutes
229 @type dt: float
230
231 """
232 if startdate is None:
233 startdate = self.thesite.date
234 elif startdate is 'today':
235 startdate = time.strftime('%Y/%m/%d %H:%M:%S',time.gmtime())
236 elif not isinstance(startdate,str):
237 YYYY,MM,DD = conversions.convert('JD','CD',startdate)
238 DD,frac = np.floor(DD),DD-np.floor(DD)
239 hh = frac*24.
240 hh,frac = np.floor(hh),hh-np.floor(hh)
241 mm = frac*60.
242 mm,frac = np.floor(mm),mm - np.floor(mm)
243 ss = frac*60.
244 ss,frac = np.floor(ss),ss - np.floor(ss)
245 startdate = '%4d/%02d/%02d %02d:%02d:%.1f'%(YYYY,MM,DD,hh,mm,ss)
246 if days is None:
247 days = self.days
248 if dt is None:
249 dt = self.dt
250 self.thesite.date = ephem.Date(startdate)
251 self.dt = dt
252 self.days = days
253
254 if self.dt is None and self.days is None:
255 logger.info('Set start date to %s'%(startdate))
256 else:
257 logger.info('Set start date to %s, covering %d days per %d minutes'%(startdate,days,dt))
258
260 """
261 Return the currently set date at the currently set site.
262 """
263 return self.thesite.date
264
265
266
267
269 """
270 Return the ephem object(s) (in a list) corresponding to the rows defined by indexes in the arrays of the "vis" dictionary.
271 """
272 return self.objects[self._objectIndices[index]]
273
275 """
276 Return the object names (in an array) corresponding to the rows defined by indexes in the arrays of the "vis" dictionary.
277 """
278 return array([member.name for member in get_out_objects(indexes)])
279
281 """
282 Return the ephem site(s) (in a list) corresponding to the rows defined by indexes in the arrays of the "vis" dictionary.
283 """
284 return self._uniqueSites[self._siteIndices[indexes]]
285
287 """
288 Return the names of the sites (in an array) corresponding to the rows defined by indexes in the arrays of the "vis" dictionary.
289 """
290 return array([site.name for site in get_out_sites(indexes)])
291
292
293
294
295
296 - def visibility(self,multiple=False,midnight=None,airmassmodel='Pickering2002',**kwargs):
297 """
298 Calculate ephemeri.
299
300 *If 'multiple' = False, a single site definition and startdate (and/or values for the days and dt keywords) are expected. If one (or more) of these
301 keywords is not given a value, it is assumed that it should not change its current value.
302 If several astrophysical objects are given, ephemeri will be given for each object at the defined site and times.
303 If 'midnight' is not None, ephemeri are calculated in the middle of each night, for the whole year.
304
305 *If 'multiple' = True, a list/array of site names and startdates can be given. Note: the length of keywords 'sitename', 'startdate' and 'objects'
306 can be either N or 1 and should be in the same format as previously. In this case, ephemeri are only calculated at the times given in 'startdate',
307 and thus the keywords 'days', 'dt' and 'midnight' are not used. Sites are currently only accessible throught the keyword 'sitename'.
308
309 The result of this function is an attribute 'vis', a dictionary containing:
310 - MJDs: Modified Julian Dates
311 - dates calendar dates (Format 1)
312 - alts: altitudes
313 - moon_alts: altitudes of the moon
314 - airmass
315 - moon_airmass: airmasses of the moon
316 - moon_separation: separation to moon
317 - during_night: night time / day time (boolean 1-0)
318 - sun_prevrise: time of previous sun rise
319 - sun_nextrise: time of next sun rise
320 - sun_prevset: time of previous sun set
321 - sun_nextset: time of next sun set
322
323 NOTE: use the 'get_out_objects', 'get_out_objectnames', 'get_out_sites' and 'get_out_sitenames' functions to retrieve the object, name of the object,
324 site and name of the site corresponding to a particular row in each of the arrays 'vis' contains.
325
326 """
327
328 kwargs.setdefault('sitename',None)
329 kwargs.setdefault('startdate',None)
330 kwargs.setdefault('dt',None)
331 kwargs.setdefault('days',None)
332
333
334 sun = ephem.Sun()
335 moon = ephem.Moon()
336
337
338 if not multiple:
339
340 self.set_site(**kwargs)
341 self.set_date(**kwargs)
342 self.set_objects(**kwargs)
343
344
345 timestep_minutes = self.dt
346 total_days = self.days
347 if midnight is None:
348 total_minutes = int(total_days*24*60./timestep_minutes)
349 else:
350 total_minutes = 365
351
352
353 alts = np.zeros((len(self.objects),total_minutes))
354 rawdates = np.zeros(total_minutes)
355 during_night = np.zeros(total_minutes,int)
356 moon_separation = np.zeros((len(self.objects),total_minutes))
357 moon_alts = np.zeros(total_minutes)
358 sun_prevrise = np.zeros(total_minutes)
359 sun_prevset = np.zeros(total_minutes)
360 sun_nextrise = np.zeros(total_minutes)
361 sun_nextset = np.zeros(total_minutes)
362
363
364 if midnight is None:
365 for i in range(total_minutes):
366 sun_prevset[i] = float(self.thesite.previous_setting(sun))
367 sun_prevrise[i] = float(self.thesite.previous_rising(sun))
368 sun_nextset[i] = float(self.thesite.next_setting(sun))
369 sun_nextrise[i] = float(self.thesite.next_rising(sun))
370 rawdates[i] = float(self.thesite.date)
371
372 moon.compute(self.thesite)
373 moon_alts[i] = float(moon.alt)
374 if (sun_prevrise[i]<=sun_prevset[i]):
375 during_night[i] = 1
376 for j,star in enumerate(self.objects):
377 star.compute(self.thesite)
378 alts[j,i] = float(star.alt)
379 moon_separation[j,i] = ephem.separation(moon,star)
380 self.thesite.date += ephem.minute*timestep_minutes
381
382 else:
383 i = 0
384 while i<365:
385 sun_nextrise[i] = float(self.thesite.next_rising(sun))
386 sun_prevset[i] = float(self.thesite.previous_setting(sun))
387 sun_prevrise[i] = float(self.thesite.previous_rising(sun))
388 sun_nextset[i] = float(self.thesite.next_setting(sun))
389 if sun_prevrise[i]<=sun_prevset[i]:
390 self.thesite.date = ephem.Date((sun_nextrise[i]+sun_prevset[i])/2.)
391 else:
392
393 self.thesite.date += ephem.minute*60*4
394 continue
395 rawdates[i] = float(self.thesite.date)
396 during_night[i] = 1
397 for j,star in enumerate(self.objects):
398 star.compute(self.thesite)
399 alts[j,i] = float(star.alt)
400 i += 1
401
402 self.thesite.date += ephem.minute*60*24
403
404 alts = alts.ravel()
405 rawdates = np.outer(np.ones(len(self.objects)),rawdates).ravel()
406 during_night = np.outer(np.ones(len(self.objects),int),during_night).ravel()
407 moon_separation = moon_separation.ravel()
408 moon_alts = np.outer(np.ones(len(self.objects)),moon_alts).ravel()
409 sun_nextrise = np.outer(np.ones(len(self.objects)),sun_nextrise).ravel()
410 sun_prevrise = np.outer(np.ones(len(self.objects)),sun_prevrise).ravel()
411 sun_nextset = np.outer(np.ones(len(self.objects)),sun_nextset).ravel()
412 sun_prevset = np.outer(np.ones(len(self.objects)),sun_prevset).ravel()
413
414 self._objectIndices = np.outer(np.arange(len(self.objects)),np.ones(total_minutes)).ravel()
415 self._siteIndices = np.zeros_like(alts)
416 self._uniqueSites = [self.thesite]
417
418 else:
419 startdate = kwargs.get('startdate',None)
420 sitename = kwargs.get('sitename','lapalma')
421 objects = kwargs.get('objects',None)
422 if objects is None:
423 objects = self.get_objectnames()
424
425
426 if not type(startdate) == np.ndarray: startdate = np.array([startdate])
427 if not type(sitename) == np.ndarray: sitename = np.array([sitename])
428 if not type(objects) == np.ndarray: objects = np.array([objects]).ravel()
429
430 uniqueObjectNames = np.unique(objects)
431 uniqueSiteNames = np.unique(sitename)
432 self.set_objects(uniqueObjectNames)
433 self._objectIndices = np.zeros_like(objects,int)
434 self._siteIndices = np.zeros_like(sitename,int)
435 self._uniqueSites = []
436 for i in range(len(uniqueObjectNames)):
437 self._objectIndices = np.where(objects == uniqueObjectNames[i],i,self._objectIndices)
438 for i in range(len(uniqueSiteNames)):
439 self._siteIndices = np.where(sitename == uniqueSiteNames[i],i,self._siteIndices)
440 self.set_site(uniqueSiteNames[i])
441 self._uniqueSites.append(self.thesite)
442
443
444 it = np.broadcast(startdate,self._siteIndices,self._objectIndices)
445
446
447 alts = np.zeros(it.shape[0])
448 rawdates = np.zeros(it.shape[0])
449 during_night = np.zeros(it.shape[0],int)
450 moon_separation = np.zeros(it.shape[0])
451 moon_alts = np.zeros(it.shape[0])
452 sun_prevrise = np.zeros(it.shape[0])
453 sun_prevset = np.zeros(it.shape[0])
454 sun_nextrise = np.zeros(it.shape[0])
455 sun_nextset = np.zeros(it.shape[0])
456
457
458 for i,element in enumerate(it):
459
460 self.thesite = self._uniqueSites[element[1]]
461 self.set_date(startdate=element[0],days=None,dt=None)
462
463 sun_prevset[i] = float(self.thesite.previous_setting(sun))
464 sun_prevrise[i] = float(self.thesite.previous_rising(sun))
465 sun_nextset[i] = float(self.thesite.next_setting(sun))
466 sun_nextrise[i] = float(self.thesite.next_rising(sun))
467 if (sun_prevrise[i]<=sun_prevset[i]):
468 during_night[i] = 1
469 rawdates[i] = float(self.thesite.date)
470
471 moon.compute(self.thesite)
472 moon_alts[i] = float(moon.alt)
473
474 star = self.objects[element[2]]
475 star.compute(self.thesite)
476 alts[i] = float(star.alt)
477 moon_separation[i] = ephem.separation(moon,star)
478
479
480 airmass = obs_airmass.airmass(90-alts/pi*180,model=airmassmodel)
481 moon_airmass = obs_airmass.airmass(90-moon_alts/pi*180,model=airmassmodel)
482
483
484 self._plotdates = np.array([date2num(ephem.Date(h).datetime()) for h in rawdates])
485 self._sun_prevset = np.array([date2num(ephem.Date(h).datetime()) for h in sun_prevset])
486 self._sun_prevrise = np.array([date2num(ephem.Date(h).datetime()) for h in sun_prevrise])
487 self._sun_nextset = np.array([date2num(ephem.Date(h).datetime()) for h in sun_nextset])
488 self._sun_nextrise = np.array([date2num(ephem.Date(h).datetime()) for h in sun_nextrise])
489 dates = np.array([str(ephem.Date(h).datetime()) for h in rawdates])
490 MJDs = rawdates+15019.499999
491
492
493 self.vis = dict(MJDs=MJDs,dates=dates,alts=alts,airmass=airmass,during_night=during_night,moon_alts=moon_alts,moon_airmass=moon_airmass,moon_separation=moon_separation)
494 self.vis.update(dict(sun_prevrise=np.array(num2date(self._sun_prevrise),dtype='|S19'),sun_prevset=np.array(num2date(self._sun_prevset),dtype='|S19'),sun_nextrise=np.array(num2date(self._sun_nextrise),dtype='|S19'),sun_nextset=np.array(num2date(self._sun_nextset),dtype='|S19')))
495 for i,obj in enumerate(self.objects):
496 keep = (self._objectIndices == i) & (during_night==1) & (0<=airmass) & (airmass<=2.5)
497 logger.info('Object %s: %s visible during night time (%.1f<airmass<%.1f)'%(obj.name,~np.any(keep) and 'not' or '',sum(keep) and airmass[keep].min() or np.nan,sum(keep) and airmass[keep].max() or np.nan))
498
499
500 - def plot(self,plot_daynight=True,**kwargs):
501 """
502 Make a plot of the result of 'visibility'.
503 """
504
505 moon = kwargs.pop('moon',True)
506 alts = self.vis['alts']
507 airmass = self.vis['airmass']
508 moon_airmass = self.vis['moon_airmass']
509 during_night = self.vis['during_night']
510 yaxis = kwargs.pop('yaxis','airmass')
511
512 factor = (yaxis=='alts') and 180./pi or 1.
513
514
515
516 fmt = kwargs.pop('fmt',False)
517 plotcolors = ['b','g','r','c','m','k']
518 plotsymbols = ['o','s','p','*','h','H','d','v','+','^','<','>','.']
519
520 pl.figure(figsize=(16,8))
521
522
523 for i in range(len(self.objects)):
524 for j in range(len(self._uniqueSites)):
525
526 keep = (self._objectIndices == i) & (self._siteIndices == j) & (during_night==1) & (0<=airmass) & (airmass<=3.5)
527
528
529 ifmt = fmt and fmt or plotsymbols[np.fmod(i,14)]+plotcolors[np.fmod(j,6)]
530 ilabel = len(self._uniqueSites)-1 and self.objects[i].name + '@' + self._uniqueSites[j].name or self.objects[i].name
531
532 pl.plot_date(self._plotdates[keep],self.vis[yaxis][keep]*factor,xdate=True,tz=pytz.utc,fmt=ifmt,label=ilabel,**kwargs)
533
534 if moon:
535 keep = (self._objectIndices == i) & (during_night==1) & (0<=moon_airmass) & (moon_airmass<=3.5)
536
537
538 if keep.sum():
539 index = np.argmin(self.vis['moon_separation'][keep]*factor)
540 closest = (self.vis['moon_separation'][keep]*factor)[index]
541 if closest<40.:
542 t = self._plotdates[keep][index]
543 time_closest = pytz.datetime.datetime.fromordinal(int(t)) + pytz.datetime.timedelta(days=t-int(t))
544 logger.warning('Object-moon distance is %.1f deg at %s'%(closest,time_closest))
545
546 if moon:
547 for j in range(len(self._uniqueSites)):
548 keep = (self._siteIndices == j) & (during_night==1) & (0<=moon_airmass) & (moon_airmass<=3.5)
549 if len(self._uniqueSites) > 1:
550 ifmt = 'D' + plotcolors[np.fmod(j,6)]
551 else:
552 ifmt = 'yD'
553 ilabel = len(self._uniqueSites)-1 and 'Moon@'+self._uniqueSites[j].name or 'Moon'
554 pl.plot_date(self._plotdates[keep],self.vis['moon_'+yaxis][keep]*factor,xdate=True,tz=pytz.utc,fmt=ifmt,label=ilabel)
555
556
557 if yaxis=='airmass':
558 pl.ylabel('Airmass')
559 pl.ylim((3.5,0.6))
560 ymin,ymax = 1.0,3.5
561 elif yaxis=='alts':
562 pl.ylabel('Altitude (degrees)')
563 pl.ylim((0.,108.))
564 ymin,ymax = 0.,90.
565
566
567 if plot_daynight:
568 indices1 = np.where(np.diff(np.array(self._sun_prevset,int)) != 0)[0]
569 indices2 = np.where(np.diff(np.array(self._sun_prevrise,int)) != 0)[0]
570 indices = np.unique(np.concatenate((indices1,indices1+1,indices2,indices2+1)))
571 indices = np.concatenate((indices,np.array([0,len(self._sun_prevset)-1])))
572
573 for prevset,prevrise,nextset,nextrise in zip(self._sun_prevset[indices],self._sun_prevrise[indices],self._sun_nextset[indices],self._sun_nextrise[indices]):
574 if prevset<prevrise:
575
576
577
578 pl.axvspan(prevset,prevrise,color='k',alpha=0.35)
579 pl.axvspan(prevrise,nextset,color='y',alpha=0.25)
580 pl.axvspan(nextset,nextrise,color='k',alpha=0.35)
581 else:
582
583
584
585 pl.axvspan(prevrise,prevset,color='y',alpha=0.25)
586 pl.axvspan(prevset,nextrise,color='k',alpha=0.35)
587 pl.axvspan(nextrise,nextset,color='y',alpha=0.25)
588
589
590 pl.grid()
591 nrlegendcolumns = len(self._uniqueSites)-1 and 5 or 8
592 pl.legend(loc='upper right',numpoints=1,borderpad=0.2,labelspacing=0.2,handlelength=0.2,ncol=nrlegendcolumns,columnspacing=0.25)
593
594
595 pl.gca().xaxis.set_major_formatter(DateFormatter("%d %b '%y %H:%M"))
596 pl.gcf().autofmt_xdate()
597 pl.xlabel('time (UTC)')
598
599
600
601
602 if __name__=="__main__":
603 if len(sys.argv)<2:
604 import doctest
605 doctest.testmod()
606 pl.show()
607 else:
608 from ivs.aux import loggers
609 logger = loggers.get_basic_logger()
610
611 eph = Ephemeris(objects=sys.argv[1].split(','))
612 eph.visibility()
613 eph.plot()
614 pl.show()
615