NCCOOS Trac Projects: Top | Web | Platforms | Processing | Viz | Sprints | Sandbox | (Wind)

root/proc2plot/trunk/proc2plot/stones_avp_plot.py

Revision 329 (checked in by haines, 14 years ago)

import first verison proc2plot

  • Property svn:executable set to
Line 
1 #!/usr/bin/env python
2 # Last modified:  Time-stamp: <2009-01-20 19:40:57 haines>
3 """stones_avp_plot"""
4
5 import os, sys
6 import datetime, time, dateutil, dateutil.tz
7 import pycdf
8 import numpy
9
10 sys.path.append('/home/haines/nccoos/raw2proc')
11 del(sys)
12
13 os.environ["MPLCONFIGDIR"]="/home/haines/.matplotlib/"
14
15 from pylab import figure, twinx, savefig, setp, getp, cm, colorbar
16 from matplotlib.dates import DayLocator, HourLocator, MinuteLocator, DateFormatter, date2num, num2date
17 import procutil
18
19 print 'stones_avp_plot ...'
20 prev_month, this_month, next_month = procutil.find_months(procutil.this_month())
21 # ncFile1='/seacoos/data/nccoos/level1/stones/avp/stones_avp_2008_01.nc'
22 # ncFile2='/seacoos/data/nccoos/level1/stones/avp/stones_avp_2008_02.nc'
23 ncFile1='/seacoos/data/nccoos/level1/stones/avp/stones_avp_'+prev_month.strftime('%Y_%m')+'.nc'
24 ncFile2='/seacoos/data/nccoos/level1/stones/avp/stones_avp_'+this_month.strftime('%Y_%m')+'.nc'
25
26 have_ncFile1 = os.path.exists(ncFile1)
27 have_ncFile2 = os.path.exists(ncFile2)
28
29 print ' ... loading data for graph from ...'
30 print ' ... ... ' + ncFile1 + ' ... ' + str(have_ncFile1)
31 print ' ... ... ' + ncFile2 + ' ... ' + str(have_ncFile2)
32
33 if have_ncFile1 and have_ncFile2:
34     nc = pycdf.CDFMF((ncFile1, ncFile2))
35 elif not have_ncFile1 and have_ncFile2:
36     nc = pycdf.CDFMF((ncFile2,))
37 elif have_ncFile1 and not have_ncFile2:
38     nc = pycdf.CDFMF((ncFile1,))
39 else:
40     print ' ... both files do not exist -- NO DATA LOADED'
41     exit()
42
43 ncvars = nc.variables()
44 # print ncvars
45 es = nc.var('time')[:]
46 units = nc.var('time').units
47 dt = [procutil.es2dt(e) for e in es]
48 # set timezone info to UTC (since data from level1 should be in UTC!!)
49 dt = [e.replace(tzinfo=dateutil.tz.tzutc()) for e in dt]
50 # return new datetime based on computer local
51 dt_local = [e.astimezone(dateutil.tz.tzlocal()) for e in dt]
52 dn = date2num(dt)
53 wd = nc.var('wd')[:]
54
55 data={}
56 data['ses'] = nc.var('stime')[:]
57 data['z'] = nc.var('z')[:]
58 data['wtemp'] = nc.var('wtemp')[:]
59 data['salin'] = nc.var('salin')[:]
60 data['turb'] = nc.var('turb')[:]
61 data['ph'] = nc.var('ph')[:]
62 data['do'] = nc.var('do')[:]
63 data['chl'] = nc.var('chl')[:]
64 nc.close()
65
66 # bin_size = sensor_info['bin_size'] # Bin Size (meters)
67 # nominal_depth = platform_info['water_depth']  # Mean sea level at station (meters) or nominal water depth
68 bin_size = 0.1 # 10cm or 0.1m
69 nominal_depth = 4.0 # m
70 z = numpy.arange(0, -1*nominal_depth, -1*bin_size, dtype=float)
71
72 nbins = len(z)
73 N = len(es)
74
75 #
76 gd = {}
77 gd['wtemp'] = numpy.ma.array(numpy.ones((N,nbins), dtype=float)*numpy.nan)
78 gd['salin'] = numpy.ma.array(numpy.ones((N,nbins), dtype=float)*numpy.nan)
79 gd['turb'] = numpy.ma.array(numpy.ones((N,nbins), dtype=float)*numpy.nan)
80 gd['ph'] = numpy.ma.array(numpy.ones((N,nbins), dtype=float)*numpy.nan)
81 gd['chl'] = numpy.ma.array(numpy.ones((N,nbins), dtype=float)*numpy.nan)
82 gd['do'] = numpy.ma.array(numpy.ones((N,nbins), dtype=float)*numpy.nan)
83 Ns = numpy.array(numpy.ones((N,nbins), dtype=float)*numpy.nan)
84
85 varlist = ['wtemp', 'salin', 'turb', 'ph', 'chl', 'do']
86
87
88 print ' ... gridding data ...'
89
90 for i in range(nbins):
91     ibin = ((z[i]<=data['z'])*(data['z']>z[i]-bin_size))
92     #
93     nsamp = numpy.nansum(ibin, axis=1)
94     #  can be used if want to have a minimum number of samples per bin
95     Ns[:,i] = nsamp
96     #
97     for v in varlist:
98         ta = data[v] # ta = data['wtemp']
99         inan = numpy.isnan(ta)
100         # mask out either Nan or no in bin to get mean of samples within bin
101         ta = numpy.ma.masked_where(inan|~ibin, ta)
102         # ta = numpy.ma.masked_invalid(ta) # not this version of numpy.ma
103         # gd['wtemp'][:,i] = ta.mean(axis=1).data
104         gd[v][:,i] = ta.mean(axis=1)
105         gd[v].set_fill_value = numpy.nan
106         del(ta)
107        
108     # reset any exact zeros from averaging to NaN
109     # gd[v][gd[v]==0] = numpy.nan
110
111 #
112
113 wtm = gd['wtemp']
114 sam = gd['salin']
115 tum = gd['turb']
116 phm = gd['ph']
117 chm = gd['chl']
118 dom = gd['do']
119
120 # last dt in data for labels
121 dt1 = dt[-1]
122 dt2 = dt_local[-1]
123
124 diff = abs(dt1 - dt2)
125 if diff.days>0:
126     last_dt_str = dt1.strftime("%H:%M %Z on %b %d, %Y") + ' (' + dt2.strftime("%H:%M %Z, %b %d") + ')'
127 else:
128     last_dt_str = dt1.strftime("%H:%M %Z") + ' (' + dt2.strftime("%H:%M %Z") + ')' \
129               + dt2.strftime(" on %b %d, %Y")
130 # add a couple of inches to length of page for 6 subplots (5 subs in 8 inches, 6 subs in 10)
131 fig = figure(figsize=(10, 10))
132 fig.subplots_adjust(left=0.1, bottom=0.1, right=0.9, top=0.9, wspace=0.1, hspace=0.1)
133
134 #######################################
135 # Last 30 days
136 #######################################
137 print ' ... Last 30 days'
138 ax = fig.add_subplot(6,1,1)
139 axs = [ax]
140
141 # use masked array to hide NaN's on plot
142 # wtm = numpy.ma.masked_where(numpy.isnan(wtemp), wtemp)
143 # range for pcolor plots
144 cmin = numpy.floor(wtm.min())
145 cmax = cmin+8.
146 # print "%s : %g %g \n" % ('Temp', cmin, cmax)
147 # cmin, cmax = (15., 35.)
148 # plot pcolor
149 pc = ax.pcolor(dn, z, wtm.T, cmap=cm.get_cmap('jet'), vmin=cmin, vmax=cmax)
150
151 # setup colorbar axes instance.
152 l,b,w,h = ax.get_position()
153 cax = fig.add_axes([l+0.04, b+0.02, 0.25*w, 0.03])
154
155 cb = colorbar(pc, cax=cax, orientation='horizontal') # draw colorbar
156 cb.set_label('Water Temperature (deg C)')
157 cb.ax.xaxis.set_label_position('top')
158 cb.ax.set_xticks([0.1, 0.3, 0.5, 0.7, 0.9])
159 # make tick labels for 10 posns set and round to one decimal place
160 xtl = numpy.round(numpy.linspace(cmin, cmax, 10), decimals=1)
161 # but only select one at set_xticks
162 cb.ax.set_xticklabels([xtl[1], xtl[3], xtl[5], xtl[7], xtl[9]])
163
164 # ax.plot returns a list of lines, so unpack tuple
165 # l1, = ax.plot_date(dt, wd, fmt='k-')
166 # l1.set_label('Water Level')
167
168 ax.set_ylabel('Depth (m)')
169 ax.set_ylim(-4.,0.)
170 # ax.set_xlim(dt[0], dt[-1]) # first to last regardless of what 
171 ax.set_xlim(date2num(dt[-1])-30, date2num(dt[-1])) # last minus 30 days to last
172 ax.xaxis.set_major_locator( DayLocator(range(2,32,2)) )
173 ax.xaxis.set_minor_locator( HourLocator(range(0,25,12)) )
174 ax.set_xticklabels([])
175
176 # this only moves the label not the tick labels
177 ax.xaxis.set_label_position('top')
178 ax.set_xlabel('Stones Bay AVP -- Last 30 days from ' + last_dt_str)
179
180 # right-hand side scale
181 ax2 = twinx(ax)
182 ax2.yaxis.tick_right()
183 # convert (lhs) meters to (rhs) feet
184 feet = [procutil.meters2feet(val) for val in ax.get_ylim()]
185 ax2.set_ylim(feet)
186 ax2.set_ylabel('Depth (ft)')
187
188 # legend
189 # ls1 = l1.get_label()
190 # leg = ax.legend((l1,), (ls1,), loc='upper left')
191 # ltext  = leg.get_texts()  # all the text.Text instance in the legend
192 # llines = leg.get_lines()  # all the lines.Line2D instance in the legend
193 # frame  = leg.get_frame()  # the patch.Rectangle instance surrounding the legend
194 # frame.set_facecolor('0.80')      # set the frame face color to light gray
195 # frame.set_alpha(0.5)             # set alpha low to see through
196 # setp(ltext, fontsize='small')    # the legend text fontsize
197 # setp(llines, linewidth=1.5)      # the legend linewidth
198 # leg.draw_frame(False)           # don't draw the legend frame
199
200 #######################################
201 #
202 ax = fig.add_subplot(6,1,2)
203 axs.append(ax)
204
205 # use masked array to hide NaN's on plot
206 # sam = numpy.ma.masked_where(numpy.isnan(salin), salin)
207 # range for pcolor plots
208 cmin = numpy.floor(sam.mean()-2*sam.std())
209 cmax = cmin+10.
210 # print "%s : %g %g \n" % ('Salin', cmin, cmax)
211 # cmin, cmax = (0., 50.)
212 pc = ax.pcolor(dn, z, sam.T, cmap=cm.get_cmap('Blues_r'), vmin=cmin, vmax=cmax)
213
214 # setup colorbar axes instance.
215 l,b,w,h = ax.get_position()
216 cax = fig.add_axes([l+0.04, b+0.02, 0.25*w, 0.03])
217
218 cb = colorbar(pc, cax=cax, orientation='horizontal') # draw colorbar
219 cb.set_label('Salinity (PSU)')
220 cb.ax.xaxis.set_label_position('top')
221 cb.ax.set_xticks([0.1, 0.3, 0.5, 0.7, 0.9])
222 xtl = numpy.round(numpy.linspace(cmin, cmax, 10), decimals=1)
223 cb.ax.set_xticklabels([xtl[1], xtl[3], xtl[5], xtl[7], xtl[9]])
224 # cb.ax.set_xticklabels([12., 16., 20., 24., 28.])
225
226 # ax.plot returns a list of lines, so unpack tuple
227 # l1, = ax.plot_date(dt, wd, fmt='k-')
228 # l1.set_label('Water Level')
229
230 ax.set_ylabel('Depth (m)')
231 ax.set_ylim(-4.,0.)
232 # first to last regardless of what
233 # ax.set_xlim(dt[0], dt[-1])
234 # last minus 30 days,
235 ax.set_xlim(date2num(dt[-1])-30, date2num(dt[-1]))
236 ax.xaxis.set_major_locator( DayLocator(range(2,32,2)) )
237 ax.xaxis.set_minor_locator( HourLocator(range(0,25,12)) )
238
239 # right-hand side scale
240 ax2 = twinx(ax)
241 ax2.yaxis.tick_right()
242 # convert (lhs) meters to (rhs) feet
243 feet = [procutil.meters2feet(val) for val in ax.get_ylim()]
244 ax2.set_ylim(feet)
245 ax2.set_ylabel('Depth (ft)')
246
247 # legend
248 # ls1 = l1.get_label()
249 # leg = ax.legend((l1,), (ls1,), loc='upper left')
250 # ltext  = leg.get_texts()  # all the text.Text instance in the legend
251 # llines = leg.get_lines()  # all the lines.Line2D instance in the legend
252 # frame  = leg.get_frame()  # the patch.Rectangle instance surrounding the legend
253 # frame.set_facecolor('0.80')      # set the frame face color to light gray
254 # frame.set_alpha(0.5)             # set alpha low to see through
255 # setp(ltext, fontsize='small')    # the legend text fontsize
256 # setp(llines, linewidth=1.5)      # the legend linewidth
257 # leg.draw_frame(False)           # don't draw the legend frame
258
259 #######################################
260 #
261 ax = fig.add_subplot(6,1,3)
262 axs.append(ax)
263
264 # use masked array to hide NaN's on plot
265 # tum = numpy.ma.masked_where(numpy.isnan(turb), turb)
266 # range for pcolor plots
267 cmin, cmax = (0., 10.)
268 pc = ax.pcolor(dn, z, tum.T, cmap=cm.get_cmap('YlOrBr'), vmin=cmin, vmax=cmax)
269
270 # setup colorbar axes instance.
271 l,b,w,h = ax.get_position()
272 cax = fig.add_axes([l+0.04, b+0.02, 0.25*w, 0.03])
273
274 cb = colorbar(pc, cax=cax, orientation='horizontal') # draw colorbar
275 cb.set_label('Turbidity (NTU)')
276 cb.ax.xaxis.set_label_position('top')
277 cb.ax.set_xticks([0.1, 0.3, 0.5, 0.7, 0.9])
278 xtl = numpy.round(numpy.linspace(cmin, cmax, 10), decimals=0)
279 cb.ax.set_xticklabels([xtl[1], xtl[3], xtl[5], xtl[7], xtl[9]])
280 # cb.ax.set_xticklabels([12., 16., 20., 24., 28.])
281
282 # ax.plot returns a list of lines, so unpack tuple
283 # l1, = ax.plot_date(dt, wd, fmt='k-')
284 # l1.set_label('Water Level')
285
286 ax.set_ylabel('Depth (m)')
287 ax.set_ylim(-4.,0.)
288 # first to last regardless of what
289 # ax.set_xlim(dt[0], dt[-1])
290 # last minus 30 days,
291 ax.set_xlim(date2num(dt[-1])-30, date2num(dt[-1]))
292 ax.xaxis.set_major_locator( DayLocator(range(2,32,2)) )
293 ax.xaxis.set_minor_locator( HourLocator(range(0,25,12)) )
294
295 # right-hand side scale
296 ax2 = twinx(ax)
297 ax2.yaxis.tick_right()
298 # convert (lhs) meters to (rhs) feet
299 feet = [procutil.meters2feet(val) for val in ax.get_ylim()]
300 ax2.set_ylim(feet)
301 ax2.set_ylabel('Depth (ft)')
302
303 #######################################
304 #
305 ax = fig.add_subplot(6,1,4)
306 axs.append(ax)
307
308 # use masked array to hide NaN's on plot
309 # cm = numpy.ma.masked_where(numpy.isnan(chl), chl)
310 # range for pcolor plots
311 cmin = numpy.floor(chm.min())
312 cmax = cmin+15.
313 # cmin, cmax = (0., 100.)
314 pc = ax.pcolor(dn, z, chm.T, cmap=cm.get_cmap('BuGn'), vmin=cmin, vmax=cmax)
315
316 # setup colorbar axes instance.
317 l,b,w,h = ax.get_position()
318 cax = fig.add_axes([l+0.04, b+0.02, 0.25*w, 0.03])
319
320 cb = colorbar(pc, cax=cax, orientation='horizontal') # draw colorbar
321 cb.set_label('Chlorophyll (ug l-1)')
322 cb.ax.xaxis.set_label_position('top')
323 cb.ax.set_xticks([0.1, 0.3, 0.5, 0.7, 0.9])
324 xtl = numpy.round(numpy.linspace(cmin, cmax, 10), decimals=1)
325 cb.ax.set_xticklabels([xtl[1], xtl[3], xtl[5], xtl[7], xtl[9]])
326 # cb.ax.set_xticklabels([12., 16., 20., 24., 28.])
327
328 # ax.plot returns a list of lines, so unpack tuple
329 # l1, = ax.plot_date(dt, wd, fmt='k-')
330 # l1.set_label('Water Level')
331
332 ax.set_ylabel('Depth (m)')
333 ax.set_ylim(-4.,0.)
334 # first to last regardless of what
335 # ax.set_xlim(dt[0], dt[-1])
336 # last minus 30 days,
337 ax.set_xlim(date2num(dt[-1])-30, date2num(dt[-1]))
338 ax.xaxis.set_major_locator( DayLocator(range(2,32,2)) )
339 ax.xaxis.set_minor_locator( HourLocator(range(0,25,12)) )
340
341 # right-hand side scale
342 ax2 = twinx(ax)
343 ax2.yaxis.tick_right()
344 # convert (lhs) meters to (rhs) feet
345 feet = [procutil.meters2feet(val) for val in ax.get_ylim()]
346 ax2.set_ylim(feet)
347 ax2.set_ylabel('Depth (ft)')
348
349 #######################################
350 #
351 ax = fig.add_subplot(6,1,5)
352 axs.append(ax)
353
354 # use masked array to hide NaN's on plot
355 # dom = numpy.ma.masked_where(numpy.isnan(do), do)
356 # range for pcolor plots
357 cmin, cmax = (0., 15.)
358 pc = ax.pcolor(dn, z, dom.T, cmap=cm.get_cmap('PiYG'), vmin=cmin, vmax=cmax)
359
360 # setup colorbar axes instance.
361 l,b,w,h = ax.get_position()
362 cax = fig.add_axes([l+0.04, b+0.02, 0.25*w, 0.03])
363
364 cb = colorbar(pc, cax=cax, orientation='horizontal') # draw colorbar
365 cb.set_label('Dissolved Oxygen (mg l-1)')
366 cb.ax.xaxis.set_label_position('top')
367 cb.ax.set_xticks([0.1, 0.3, 0.5, 0.7, 0.9])
368 xtl = numpy.round(numpy.linspace(cmin, cmax, 10), decimals=0)
369 cb.ax.set_xticklabels([xtl[1], xtl[3], xtl[5], xtl[7], xtl[9]])
370 # cb.ax.set_xticklabels([12., 16., 20., 24., 28.])
371
372 # ax.plot returns a list of lines, so unpack tuple
373 # l1, = ax.plot_date(dt, wd, fmt='k-')
374 # l1.set_label('Water Level')
375
376 ax.set_ylabel('Depth (m)')
377 ax.set_ylim(-4.,0.)
378 # first to last regardless of what
379 # ax.set_xlim(dt[0], dt[-1])
380 # last minus 30 days,
381 ax.set_xlim(date2num(dt[-1])-30, date2num(dt[-1]))
382 ax.xaxis.set_major_locator( DayLocator(range(2,32,2)) )
383 ax.xaxis.set_minor_locator( HourLocator(range(0,25,12)) )
384
385 # right-hand side scale
386 ax2 = twinx(ax)
387 ax2.yaxis.tick_right()
388 # convert (lhs) meters to (rhs) feet
389 feet = [procutil.meters2feet(val) for val in ax.get_ylim()]
390 ax2.set_ylim(feet)
391 ax2.set_ylabel('Depth (ft)')
392
393 #######################################
394 #
395 ax = fig.add_subplot(6,1,6)
396 axs.append(ax)
397
398 # use masked array to hide NaN's on plot
399 # phm = numpy.ma.masked_where(numpy.isnan(ph), ph)
400 # range for pcolor plots
401 # cmin, cmax = numpy.round([sm.min(), sm.max()], decimals=0)
402 # cmin = cmin-1
403 # cmax = cmax+1
404 # print "%s : %g %g \n" % ('pH', cmin, cmax)
405 cmin, cmax = (6., 8.)
406 pc = ax.pcolor(dn, z, phm.T, cmap=cm.get_cmap('cool'), vmin=cmin, vmax=cmax)
407
408 # setup colorbar axes instance.
409 l,b,w,h = ax.get_position()
410 cax = fig.add_axes([l+0.04, b+0.02, 0.25*w, 0.03])
411
412 cb = colorbar(pc, cax=cax, orientation='horizontal') # draw colorbar
413 cb.set_label('pH')
414 cb.ax.xaxis.set_label_position('top')
415 cb.ax.set_xticks([0.1, 0.3, 0.5, 0.7, 0.9])
416 xtl = numpy.round(numpy.linspace(cmin, cmax, 10), decimals=1)
417 cb.ax.set_xticklabels([xtl[1], xtl[3], xtl[5], xtl[7], xtl[9]])
418 # cb.ax.set_xticklabels([12., 16., 20., 24., 28.])
419
420 # ax.plot returns a list of lines, so unpack tuple
421 # l1, = ax.plot_date(dt, wd, fmt='k-')
422 # l1.set_label('Water Level')
423
424 ax.set_ylabel('Depth (m)')
425 ax.set_ylim(-4.,0.)
426 # first to last regardless of what
427 # ax.set_xlim(dt[0], dt[-1])
428 # last minus 30 days,
429 ax.set_xlim(date2num(dt[-1])-30, date2num(dt[-1]))
430 ax.xaxis.set_major_locator( DayLocator(range(2,32,2)) )
431 ax.xaxis.set_minor_locator( HourLocator(range(0,25,12)) )
432 ax.xaxis.set_major_formatter( DateFormatter('%m/%d') )
433
434 ax.set_xlabel('Stones Bay AVP -- Last 30 days from ' + last_dt_str)
435
436 # right-hand side scale
437 ax2 = twinx(ax)
438 ax2.yaxis.tick_right()
439 # convert (lhs) meters to (rhs) feet
440 feet = [procutil.meters2feet(val) for val in ax.get_ylim()]
441 ax2.set_ylim(feet)
442 ax2.set_ylabel('Depth (ft)')
443
444 # save figure
445 savefig('/home/haines/rayleigh/img/stones_avp_last30days.png')
446
447 #######################################
448 # Last 7 days
449 #######################################
450
451 print ' ... Last 7 days'
452 for i in [0, 1, 2, 3, 4]:
453     ax = axs[i]
454     ax.set_xlim(date2num(dt[-1])-7, date2num(dt[-1]))
455     ax.xaxis.set_major_locator( DayLocator(range(1,32,1)) )
456     ax.xaxis.set_minor_locator( HourLocator(range(0,25,6)) )
457     ax.set_xticklabels([])
458     if i==0:
459         ax.set_xlabel('Stones Bay AVP -- Last 7 days from ' + last_dt_str)
460 #
461
462 ax = axs[5]
463 ax.set_xlim(date2num(dt[-1])-7, date2num(dt[-1]))
464 ax.xaxis.set_major_locator( DayLocator(range(1,32,1)) )
465 ax.xaxis.set_minor_locator( HourLocator(range(0,25,6)) )
466 ax.xaxis.set_major_formatter( DateFormatter('%m/%d') )
467 ax.set_xlabel('Stones Bay AVP -- Last 7 days from ' + last_dt_str)
468
469 savefig('/home/haines/rayleigh/img/stones_avp_last07days.png')
470
471 #######################################
472 # Last 1 day (24hrs)
473 #######################################
474
475 print ' ... Last 1 days'
476
477 for i in [0, 1, 2, 3, 4]:
478     ax = axs[i]
479     ax.set_xlim(date2num(dt[-1])-1, date2num(dt[-1]))
480     ax.xaxis.set_major_locator( HourLocator(range(0,25,1)) )
481     ax.xaxis.set_minor_locator( MinuteLocator(range(0,61,30)) )
482     ax.set_xticklabels([])
483     if i==0:
484         ax.set_xlabel('Stones Bay AVP -- Last 24 hours from ' + last_dt_str)
485
486 ax = axs[5]
487 ax.set_xlim(date2num(dt[-1])-1, date2num(dt[-1]))
488 ax.xaxis.set_major_locator( HourLocator(range(0,25,1)) )
489 ax.xaxis.set_minor_locator( MinuteLocator(range(0,61,30)) )
490 ax.xaxis.set_major_formatter( DateFormatter('%H') )
491 ax.set_xlabel('Stones Bay AVP -- Last 24 hours from ' + last_dt_str)
492
493 savefig('/home/haines/rayleigh/img/stones_avp_last01days.png')
494
Note: See TracBrowser for help on using the browser.