#!/usr/bin/perl # # webdata.cgi for outputting O3 graphs of CMDL's Dobson data # # this file lives at /cmdl/www/ozwv/cgi-bin on vortex.cmdl.noaa.gov # # by: Mark Clark, January - May 2001 # June 2001 - added graph-only output # July 2001 - switched layout to new web format - EJH # November 2001 - added Marcapomacocha and adapted program to partial year data # Dec 10, 2001 - changed stations to a 2-column format # Dec 11, 2001 - got ready for the new year (in perpetuity(?)) # -> Jan 03, 2002 - check! # Jan 22, 2002 - added dobson_o3_plasmagraph.gif for Hack's plasma page # Feb 1, 2002 - defined default color for single-station graphs to 1 (black) # Oct 24, 2002 - added links to the stations # Mar 14, 2003 - allowed all stations to be on webdata.cgi page use CGI::Pretty qw( :all ); use CGI::Carp qw( fatalsToBrowser ); use PGPLOT; $ENV{PGPLOT_FONT} = '/usr/lib/pgplot/grfont.dat'; $ENV{PGPLOT_BACKGROUND} = 'white'; $ENV{PGPLOT_FOREGROUND} = 'black'; $title = 'Near Real-Time Total Ozone Data Graphing'; # get time of the starting of the page $now = localtime; @time = localtime(time); $now_year = $time[5] + 1900; # start html; print header; if (param) { # check incoming parameters # the one parameter/no value case if (param('keywords')) { ${param('keywords')} = 1 ; #print param('keywords'), " => ", ${param('keywords')}, '
'; } else { foreach $name (param) { if (param($name) eq '') { $$name = 1 ; #print '1 '; } else { $$name = param($name) ; #print 'non-null'; } #print "param $name ", param($name), " => $$name
"; } } if (defined $connect) { if ($connect) { $disconnect = 0 } else { $disconnect = 1 } } if (defined $pic) { unless ($type) { $type = 'current' } unless (defined $disconnect) { $disconnect = 0 } unless ($average) { $average = 1 } unless ($envelope) { $envelope = 1 } } if (defined $plasma) { $type = 'last'; $disconnect = 0; $average = 1; $envelope = 1; } unless ($type) { $type = 'current' } #unless (defined $average) { $average = 1 } #unless (defined $envelope) { $envelope = 1 } unless (defined $disconnect) { $disconnect = 0 } } else { # no parameters #set default values for parameters $type = 'current'; $average = 1; $envelope = 1; $disconnect = 0; } @stats = qw/ams bdr bis bna brw car fbk hnx ldr mlo mpo ohp pth smo tal wai/; # check program name to see if we should run in test mode. :^) if ( $0 =~ /webdata/ ) { $web = 1 } else { $test = 1 } # check IP of caller and deal with it... $rem = remote_addr; if ($rem =~ /^137\.229\./) { $fbk = 1 } # generate a list of stations from the CGI parameters $default_stat = 1; foreach $stat (@stats) { if (param($stat) && defined $stat) { $$stat = 1 } if ($$stat) { push @stations, $stat; $default_stat = 0; } } if ($default_stat) { $bdr = 1 } unless (@stations) { # set parameters for graphs if ($fbk) { @stations = qw(fbk) } else { @stations = qw(bdr) } } if ((!$pic && !$plasma) && ($test || $web || $fbk)) { # normal start # print start_html(-title=> $title, # -author=>'Mark Clark', # -base=>'true', # -bgcolor=>'#FFFFFF', # -meta=>{'keywords'=>'ozone Dobson Spectrophotometer graphing data near real-time # Amundsen-Scott South Pole Station # Boulder Colorado # Barrow Poker Flats Fairbanks University Alaska # Marcapomacocha Huancayo PERU # NIWA Lauder NEW ZEALAND # Mauna Loa Observatory Hawaii # Observatoire Haute Provence FRANCE # Perth Western AUSTRALIA # Pago Pago American Samoa # Tallahassee Florida # NASA Wallops Island Flight Facility # National Weather Service # Bismarck North Dakota # Caribou Maine # Hanford Fresno California # Nashville Tennessee', # 'description'=>'The NOAA/CMDL/OZWV - near Real-Time Total Ozone Graphing page.'}, # -head=>[ Link({-rel=>'shortcut icon', -href=>'../dobson/gifs/o3_icon.ico'}), # Link({-rel=>'icon', -href=>'../dobson/gifs/o3_icon.png', -type=>'image/png'}) # ]); open (FILE, "header.html"); @header = (); close (FILE); print @header; } @mon = qw(- Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); # high and low values for graphing - subject to change later $high = 500.; $low = 100.; # number of days per normal month $nd[1]=$nd[3]=$nd[5]=$nd[7]=$nd[8]=$nd[10]=$nd[12]=31; $nd[4]=$nd[6]=$nd[9]=$nd[11]=30; # $nd[2] is determined elsewhere - deals with the Leap averageaverage problem. # months in the year @mos = qw(- January February March April May June July August September October November December); # number of cumulative days per month in a normal year $td[1] = 31; $td[2] = 59; $td[3] = 90; $td[4] = 120; $td[5] = 151; $td[6] = 181; $td[7] = 212; $td[8] = 243; $td[9] = 273; $td[10] = 304; $td[11] = 334; $td[12] = 365; %yrs = ( ams => [1963, $now_year], bdr => [1966, $now_year], bis => [1962, $now_year], bna => [1962, $now_year], brw => [1973, $now_year], car => [1962, $now_year], fbk => [1984, $now_year], hnx => [1983, $now_year], mpo => [1964, $now_year], ldr => [1987, $now_year], mlo => [1963, $now_year], ohp => [1983, $now_year], pth => [1984, $now_year], smo => [1975, $now_year], tal => [1964, $now_year], wai => [1967, $now_year], ); # setup the list of names available from the web #if ($test) { # for 'testdata.cgi' access %names = ( ams => 'South Pole Station, ANTARCTICA', bdr => 'Boulder, Colorado', bis => 'Bismarck, North Dakota', bna => 'Nashville, Tennessee', brw => 'Barrow, Alaska', car => 'Caribou, Maine', fbk => 'Fairbanks, Alaska', hnx => 'Hanford, California', ldr => 'Lauder, NEW ZEALAND', mlo => 'Mauna Loa Observatory, Hawaii', mpo => 'Marcapomacocha, PERU', ohp => 'Observatoire de Haute Provence, FRANCE', pth => 'Perth, Western Australia, AUSTRALIA', smo => 'Cape Matatula, American Samoa', tal => 'Tallahassee, Florida', wai => 'Wallops Island, Virginia', ); #} #else { # for 'webdata.cgi' access # %names = ( bdr => 'Boulder, Colorado', ); #} # determine the earliest and latest dates available foreach $k (keys %names) { # determine most recent data year if ($yrs{$k}[1] >= $rec_year) { $rec_year = $yrs{$k}[1]; } # determine earliest data year if ($early_year) { if ($yrs{$k}[0] <= $early_year) { $early_year = $yrs{$k}[0] } } else { $early_year = $yrs{$k}[0] } } # build the rows of data for each station #if ($test) { # testdata.cgi $Th = "th('   '), th('Station'), th('Earliest Data'), th('   '), th('   '), th('Station'), th('Earliest Data')", #} #else { # webdata.cgi # $Th = "th('Station'), th('Start Year'), th('End Year')," #} $http = 'http://thunder.cmdl.noaa.gov/gmd/ozwv/dobson/'; # prefix for URLs @snames = sort keys %names; $l = @snames; # get a count of the names in %names $mid = int $l/2; for $i (0 .. $mid-1) { $a = $snames[$i]; $b = $snames[$i+$mid]; if ($$a) { $on = 1 } else { $on = 0 } if ($$b) { $son = 1 } else { $son = 0 } # links to station pages ($h1, $h2) = split ',', $names{$snames[$i]}; $ha = a({-href=>"$http$a.html"}, $h1) . ", $h2"; ($h3, $h4) = split ',', $names{$snames[$i+$mid]}; $hb = a({-href=>"$http$b.html"}, $h3) . ", $h4"; # the excessive use of quote here allows me to add and comment out lines for testing $Tr .= " Tr ( {-valign=>TOP}, " . " td ( checkbox( -name => '$snames[$i]', -on => '$on', -value => 1, -label => '')), " . " td ( {-align=>LEFT},'$ha'), " . " td ( {-align=>CENTER}, $yrs{$snames[$i]}[0] ), " . " td ('   '), " . " td ( checkbox( -name => '$snames[$i+$mid]', -on => '$son', -value => 1, -label => '')), " . " td ( {-align=>LEFT}, '$hb'), " . " td ( {-align=>CENTER}, $yrs{$snames[$i+$mid]}[0] ), " . " ),"; } unless ($l%2 == 0) { $a = $snames[$l-1]; if ($$a) { $on = 1 } else { $on = 0 } $Tr .= " Tr ( {-valign=>TOP}, td ( checkbox( -name => '$snames[$l-1]', -on => '$on', -value => 1, -label => '$names{$snames[$l-1]}')), td ( {-align=>CENTER}, $yrs{$snames[$l-1]}[0] ), td ( {-align=>CENTER}, $yrs{$snames[$l-1]}[1] ), )"; } # build the columns for the 'type' table %radio_label = ('all' => 'All - a graph of all available data', 'current' => 'Current - this year\'s data', 'some' => 'Some - a subset of the available data', 'last' => 'Last year - previous full year of data', ); @radio = radio_group(-name=>'type', -values=>['current', 'last', 'all', 'some',], -default=>'current', -labels=>\%radio_label, -linebreak=>1, ); # generate the graphs %colors = ( ams => 1, # black bdr => 2, # red smo => 3, # green bis => 4, # blue bna => 5, # light blue-green brw => 6, # fuscia car => 7, # yellow fbk => 8, # reddish brown hnx => 9, # light green ldr =>10, # mlo =>11, # mpo =>12, # ohp =>13, # pth =>14, # tal =>15, # gray wai =>16 # gray ); # setup for graphing the average values and std devs for a single station if (@stations == 1) { $ave_file = $stations[0]."dailyaverage.csv"; if (-e "./data/$ave_file") { # check to see if Bob has given me the .csv file... :^) open IN, "./data/$ave_file" or die "couldn't open $ave_file - $!

\n"; while () { ($do, $oz, $dv) = split ','; if ($do =~ /\d/) { $mid{$do} = $oz; $env{$do} = $dv; } } close IN; } } if ( $type eq 'all' ) { $all = 1; $start = $early_year; $end = $rec_year; } elsif ( $type eq 'current' ) { $current = 1; $start = 1900 + (localtime)[5]; $end = $start + 1; } elsif ( $type eq 'last' ) { $last = 1; $start = 1900 - 1 + (localtime)[5]; $end = $start + 1; } elsif ( $type eq 'some' ) { $some = 1; $start = param('start'); $end = param('end'); # fix the endpoints of the graph if ( $start == $end ) {$end++} if ( $start > $end ) { ($start, $end) = ($end, $start) } } # get directory information #$main_dir = '/ftp/dobson/'; $main_dir = '/data/webdata/ozwv/dobson/ozone/'; $data_dir = '/data/webdata/ozwv/cgi-bin/data/'; foreach $stat (@stations) { # initialize the data arrays @ozone = (); $statdate = $stat.'date'; $last_yr = $last_doy = 0; # get data from the SELECT files # main station data file @dfile = $main_dir.$stat.'/'.$stat.'_sel.txt'; print "$dfile[0]
"; # set up for stations that have split data if ($stat eq 'fbk') { unshift @dfile, $main_dir.$stat.'/pok_sel.txt' } if ($stat eq 'hnx') { unshift @dfile, $main_dir.$stat.'/fat_sel.txt' } if ($stat eq 'mpo') { unshift @dfile, $main_dir.$stat.'/hua_sel.txt' } foreach $dfile (@dfile) { # usually only one file - exceptions: fbk, hnx, mpo (above) open IN, $dfile or die "couldn't open $dfile - $! \n"; while () { @line = split ''; #print "$_
"; # $sss = join '', @line[ 0.. 2]; # station number $c = $line[ 3 ]; # line number #print "c = $c
"; # don't process the comment lines - You FOOL! if ($c == 5) { next } $mm = join '', @line[ 4.. 5]; # month of the year $yy = join '', @line[ 6.. 7]; # year #print "mm = $mm, yy = $yy
"; if ($yy > 50) { $yy+= 1900 } else { $yy += 2000 } if ($some && ($yy < $start || $yy > $end)) { next } if ($current && ($yy < $rec_year)) { next } $ooo[1] = join '', @line[14..16]; # ozone in DU $ooo[2] = join '', @line[23..25]; $ooo[3] = join '', @line[32..34]; $ooo[4] = join '', @line[41..43]; $ooo[5] = join '', @line[50..52]; $ooo[6] = join '', @line[59..61]; $ooo[7] = join '', @line[68..70]; $ooo[8] = join '', @line[77..79]; # @hh[1] = join '', @line[ 8.. 9]; # nothing or a '*' for questionable data # @hh[2] = join '', @line[17..18]; @hh[3] = join '', @line[26..27]; # @hh[4] = join '', @line[35..36]; @hh[5] = join '', @line[44..45]; # @hh[6] = join '', @line[53..54]; @hh[7] = join '', @line[62..63]; # @hh[8] = join '', @line[71..72]; # @gg[1] = join '', @line[10..11]; # nearest GMT hour # @gg[2] = join '', @line[19..20]; @gg[3] = join '', @line[28..29]; # @gg[4] = join '', @line[37..38]; @gg[5] = join '', @line[46..47]; # @gg[6] = join '', @line[55..56]; @gg[7] = join '', @line[64..65]; # @gg[8] = join '', @line[73..74]; # @l[1] = @line[12 ]; # wavelengths used # @l[2] = @line[21 ]; @l[3] = @line[30 ]; # @l[4] = @line[39 ]; @l[5] = @line[48 ]; # @l[6] = @line[57 ]; @l[7] = @line[66 ]; # @l[8] = @line[75 ]; # @s[1] = @line[13 ]; # kind of observation # @s[2] = @line[22 ]; @s[3] = @line[31 ]; # @s[4] = @line[40 ]; @s[5] = @line[49 ]; # @s[6] = @line[58 ]; @s[7] = @line[67 ]; # @s[8] = @line[76 ]; if ( !($yy%400) ) { $nd[2] = 28; $ly = 0; $days = 365 } # this block addresses the elsif ( !($yy%4) ) { $nd[2] = 29; $ly = 1; $days = 366 } # Leap Year problem else { $nd[2] = 28; $ly = 0; $days = 365 } for $ct (1..8) { $dom = ($c-1)*8 + $ct; # day of month #print "dom = $dom "; unless ($dom > 31) { $doy = $td[$mm-1] + $dom; # day of year $dec_yr = $yy + $doy/$days; $o3 = $ooo[$ct]; #print "o3 = $o3 "; if ($o3 > 0) { # autoranging of graph Y-values if ($o3 > $high) { until ($high > $o3) { $high += 20 } } elsif ($o3 < $low) { until ($low < $o3) { $low -= 20 } } # generate the arrays to be graphed push @$stat, $o3; push @$statdate, $dec_yr; # set the most recent information... if ($mr{$stat} < $dec_yr) { $o_mr{$stat} = $o3; # last data point - to be circled $mrdate = "$mos[$mm] $dom, $yy"; # most recent date $mr{$stat} = $dec_yr; # most recent date (decimal) $mro = $o3; # most recent ozone value } } # set account for partial years overlapping preliminary data in .obs files $last_yr = $yy; $last_doy = $doy; } } } close IN; } # read in the recent data from .obs file(s) $file = "$data_dir$stat\.obs"; open IN, $file or die "can't open $file - $!\n"; while () { unless (/^\W*$/) { # ignore blank lines! ($date, $doy, $obtype, $o3) = split; # autoranging of graph Y-values if ($o3 > $high) { until ($high > $o3) { $high += 20 } } elsif ($o3 < $low) { until ($low < $o3) { $low -= 20 } } if ($date =~ /-/) { ($mo, $day, $yy) = split '-', $date } else { ($mo, $day, $yy) = split '/', $date } if ( !($yy%400) ) { $days = 365 } # this block addresses the elsif ( !($yy%4) ) { $days = 366 } # Leap Year problem else { $days = 365 } # $tdoy = $yy + $doy/$days; # check for existing data from the SELECT files before adding .obs data if ($yy > $last_yr || ($yy == $last_yr && $doy > $last_doy) ) { push @$stat, $o3; push @$statdate, $tdoy; $disclaim = 1; # set up the most recent information... if ($mr{$stat} < $tdoy) { $mrdate = "$mos[$mo] $day, $yy"; $mr{$stat} = $tdoy; $o_mr{$stat} = $o3; $mro = $o3; } } $prelim = $yy; } } close IN; } # housekeeping - remove old plots $wd = qx/pwd/; $dir = '.'; $gifdir = '/data/webdata/ozwv/dobson/gifs'; chdir $gifdir or die "couldn't chdir $gifdir- $!

\n"; opendir DIR, $dir or die "couldn't opendir $dir - $!

\n"; foreach (readdir DIR) { $div = 0.05; # $time = int (3600 * $div); # 3600 * 0.05 = 3 hours if (/plot/ && -M $_ > $div) { # should remove both .gif and .ps files :^) qx/rm $_/; } } # get a 'unique' name for the file chdir '../../cgi-bin' or die "couldn't chdir $wd - $!

\n"; $file = ''; until ($file) { $file = "/data/webdata/ozwv/dobson/gifs/plot".(int rand 99999); if (-e $file) # check for existence of the file already { $file = '' # reset filename if it already exists } } # Start PGPLOT $outgif = $file.'.gif/GIF'; $outps = $file.'.ps/CPS'; foreach $out ($outgif, $outps) { if ($plasma && ($out eq $outps)) { next } # don't generate PS for 'plasma' option if ( pgbeg(0, $out, 1, 1) == 1 ) { # # Generate the graph. pgsci(1); pgvstd; pgqch($char_ht); pgsch(0.75); } # # if ($type eq 'all') { # $early_year = $rec_year - 1; # foreach $s (@stations) { # if ($early_year > $yrs{$s}[0] ) { $early_year = $yrs{$s}[0]} # } # pgswin($early_year, $rec_year+1, $low, $high); # pgbox( 'ABCNST', # X options # 0, # Xtick # 0, # NXsub # 'ABCNSTV', # Yopt # 0, 0); # Ytick, NYsub # $title_type = ucfirst $type. " data for: "; # } # elsif ($type eq 'some') { # $diff = $end - $start; # pgswin($start, $end, $low, $high); # # # put months under the graph for a single year's worth of data # if ($diff == 1) { # $xtick = 1; # $nxsub = 12; # $mon = 0; # foreach (@mon) { # if ($mon) { # pgptxt($start+(($mon-0.5)/12), # X # $low - 25, # Y # 0, # Angle # 0.5, # Fjust # $_); # Text # } # $mon++; # } # } # elsif ($diff < 10) { $xtick = 1; $nxsub = 4 } # elsif ($diff < 20) { $xtick = 2; $nxsub = 2 } # else { $xtick = 4; $nxsub = 4 } # pgbox( 'ABCNST', # X options # $xtick, # Xtick # $nxsub, # NXsub # 'ABCNSTV', # Yopt # 0, 0); # Ytick, NYsub # $title_type = "Data from $start to $end for: "; # } # elsif ($type eq 'last') { # pgswin($start, $start+1, $low, $high); # pgbox( 'ABCNST', # X options # 1, # Xtick # 12, # NXsub # 'ABCNSTV', # Yopt # 0.0, 0.0); # Ytick, NYsub # $mon = 0; # foreach (@mon) { # if ($mon) { # pgptxt($start+(($mon-0.5)/12), # X # $low - 25, # Y # 0, # Angle # 0.5, # Fjust # $_); # Text # } # $mon++; # } # $title_type = "$start data for: "; # } # else { # 'Current' # pgswin($rec_year, $rec_year+1, $low, $high); # pgbox( 'ABCNST', # X options # 1, # Xtick # 12, # NXsub # 'ABCNSTV', # Yopt # 0.0, 0.0); # Ytick, NYsub # $mon = 0; # foreach (@mon) { # if ($mon) { # pgptxt($rec_year+(($mon-0.5)/12), # X # $low - 25, # Y # 0, # Angle # 0.5, # Fjust # $_); # Text # } # $mon++; # } # $title_type = "$rec_year data for: "; # $start = $rec_year; # } # # # Label the graph # pgsch($char_ht); # set character height # pgmtxt('T', # Top # 2.2, # Displacement from top of viewport # # 0.0, # Start at lefthand side of edge # 0.5, # Start at 1/2 way along edge # # 1.0, # Start at righthand side of edge # 0.5, # Center from middle # $title_type); # pgmtxt('L', # Left side # 2.5, # Displacement from top of viewport # 0.5, # Start at 1/2 way along edge # 0.5, # Center from middle # 'Ozone (DU)'); # # pgsch($char_ht); # # # set up labels for station names # if (@stations == 1) { # single stations get long names # pgmtxt('T', # 0.8, # 0.5, # 0.5, # $names{$stations[0]}); # } # else { # multiple stations get abbreviated and concatenated # $commas = $len = 0; # foreach (@stations) { # pgsci($colors{$_}); # $b = uc $_; # $coord = 0.5 - (0.5 * ( ($#stations)/18)); # pgmtxt('T', 0.8, $coord, 0.5, (' ' x $len) . $b); # $len += (length $b) + 1; # if ($_ eq 'bdr') { $len++ } # unless ($commas == $#stations) { # $commas++; # pgsci(1); # pgmtxt('T', 0.8, $coord, 0.5, (' ' x $len) . ','); # $len += 5; # } # } # } # # # generate the envelope for Bob # if ( $#stations == 0 ) { # for single stations only # if ( $average || $envelope ) { # @ozone = @date = @top = @bot = @dev_date = (); # foreach $y ($start..$end) { # $days = 365; # if ( !($y%400) ) { $days = 365 } # this block addresses the # elsif ( !($y%4) ) { $days = 366 } # Leap Year problem # # pgsci(15); # foreach $d (sort {$a <=> $b} keys %env) { # $ozone = $mid{$d}; # # $dec_day = $y + $d/$days; # unless ($dec_day > ($y + 1)) { # if ($ozone > 0 && $days > 0) { # push @ozone, $ozone; # push @date, $dec_day; # } # elsif ($average) { # pgline ($#ozone+1, \@date, \@ozone); # @ozone = @date = (); # } # # $dev = $env{$d}; # $top = $ozone + $dev; # $bot = $ozone - $dev; # if ($dev > 0 && $days > 0) { # push @top, $top; # push @bot, $bot; # push @dev_date, $dec_day; # } # elsif ($envelope) { # pgline ($#top+1, \@dev_date, \@top); # pgline ($#bot+1, \@dev_date, \@bot); # @top = @bot = @dev_date = (); # } # } # } # if ($envelope) { # pgline ($#top+1, \@dev_date, \@top); # pgline ($#bot+1, \@dev_date, \@bot); # } # if ($average) { # pgline ($#ozone+1, \@date, \@ozone); # } # } # } # } # # # Output the date/ozone pairs # foreach $stat (@stations) { # $statdate = $stat."date"; # # if (@stations > 1) { # use multiple colors for multiple stations # if ($colors{$stat}) { $color = $colors{$stat} } # else { $color++ } # } # else { $color = 1 } # else use BLACK # pgsci($color); # # pgpt($#$stat+1, \@$statdate, \@$stat, 20); # # unless ($disconnect) { # pgline($#$stat+1, \@$statdate, \@$stat) # } # # # output a larger circle for the last datum # @o_mr = $o_mr{$stat}; # @mr = $mr{$stat}; # pgsci(1); # black circle around most recent point # pgpt(1, \@mr, \@o_mr, 23); # } # # pgsch(0.5); # pgsci(1); # # # put in disclaimer as appropriate (when preliminary data is used) # if ($current || $all || $end > $prelim) { # pgsfs(2); # 2 => outline style rectangle # # if ($all) { # horizontal fudge factor # $fuj1 = $rec_year - $early_year + 1; # $left = $early_year; # } # elsif ($some) { # $fuj1 = $end - $start; # $left = $start; # } # else { # $fuj1 = 1; # $left = $start; # } # $fuj2 = ($high-$low); # vertical fudge factor # # if ($disclaim) { # $x1 = $left + $fuj1*(2/3); # $x2 = $left + $fuj1*(5/6); # $y1 = $low + $fuj2 * 381/400; # 381 = 481 minus original $low (100) # $y2 = $low + $fuj2 * 392/400; # 392 = 492 minus original $low # # pgrect($x1, $x2, $y1, $y2); # pgmtxt('T', # Top # -2.5, # Displacement from top of viewport in units of char height # 0.75, # Start at 3/4 way along edge # 0.5, # Center from middle # "$prelim Data is Preliminary"); # } # # if ($#stations == 0 && $mro) { # output box with most recent data # unless ($stations[0] eq 'ams') { # put the data box above the ozone trace # $disp = -4; $mult = 1; # $tb = 'B'; # $y1 = $low + $fuj2 * 10/400; # 10 = 110 minus original $low (100) # $y2 = $low + $fuj2 * 50/400; # 50 = 150 minus original $low # } # else { # put the data box below the ozone trace # $disp = -2.5; $mult = -1; # $tb = 'T'; # $y1 = $high - $fuj2 * 50/400; # 10 = 110 minus original $low (100) # $y2 = $high - $fuj2 * 10/400; # 50 = 150 minus original $low # } # $x1 = $left + $fuj1 * 0.15; # $x2 = $left + $fuj1 * 0.35; # pgrect($x1, $x2, $y1, $y2); # # pgsch(0.75); # pgmtxt($tb, # Bottom # $disp, # Displacement from top of viewport in units of char height # 0.25, # Start at 1/4 way along edge # 0.5, # Center from middle # 'Total Ozone for'); # pgmtxt($tb, # Bottom # $disp + $mult * 1, # Displacement from top of viewport in units of char height # 0.25, # Start at 1/4 way along edge # 0.5, # Center from middle # "$mrdate"); # pgmtxt($tb, # Bottom # $disp + $mult * 2, # Displacement from top of viewport in units of char height # 0.25, # Start at 1/4 way along edge # 0.5, # Center from middle # "$mro DU"); # } # } # # # Put in ownership tags # pgsch(0.5); # pgmtxt('B', # Bottom # 7.5, # Displacement from top of viewport in units of char height # 0.75, # Start at 3/4 way along edge # 0.5, # Center from middle # "(Generated courtesy of NOAA/CMDL - $now)"); # # # Stop PGPLOT # pgend; # # if ($out eq $outgif) { # # show image # unless ($pic || $plasma) { print center(p) } # # print center (img( {-src=>"$file.gif", # -align=>'center', # -border=>'1', # -alt=>'CMDL Dobson data'} )); # print qx "cp $file.gif ../dobson/gifs/dobson_o3_plasmagraph.gif"; # } # else { # unless ($plasma) { # print br, # center( # h3( # a( {-href=>"$file.ps"}, 'Download a postscript file of this image') # ) # ); # } # unless ($pic || $plasma) { # if (@stations == 1) { # print h4( blockquote("The dots are daily total column ozone # amounts. The most recent value is circled and the numerical amount is # given in the box on the left.", p, "Total column ozone, the amount of ozone # from the surface to the top of the atmosphere, is reported in # Dobson units (DU). This unit is used for both surface based and # satellite observations.") ) # } # else { # print h4( blockquote("The dots are daily total column ozone amounts. The most # recent values are circled.", p, "Total column ozone, the amount of ozone # from the surface to the top of the atmosphere, is reported in # Dobson units (DU). This unit is used for both surface based and # satellite observations.") ) # } # } # } # } # else { # print "

an error has occurred - unable to PGBEG!

\n"; # } } # select stations for graphing... unless ($pic || $plasma) { print center( blockquote(hr), h3('You may choose new parameters for another graph'), p, start_form(), table( Tr( {-align=>CENTER,-valign=>TOP}, eval $Th), eval $Tr), ), # select type of graph you prefer blockquote( h3('What type of graph would you like?'), table (Tr ( td ($radio[0]) ), Tr ( td ($radio[1]) ), Tr ( td ($radio[2]) ), Tr ( td ($radio[3]), td ( popup_menu ( -name=>'start', -values=>[$early_year...$rec_year]) ), td ( popup_menu ( -name=>'end', -values=>[reverse $early_year+1..$rec_year+1]) ), ) ), h3('Options:'), checkbox( -name => 'disconnect', -on => $disconnect, # "s are very important here! -value => 1, -label => 'Scatter Graph - disconnect the data points'), p, blockquote( h4('Available for single station graphs:'), checkbox( -name => 'average', -on => '$average', # "s are very important here! -value => 1, -label => 'Average - Show the station\'s longterm average ozone amounts'), br, checkbox( -name => 'envelope', -on => '$envelope', # "s are very important here! -value => 1, -label => 'Envelope - Show lines above and below the average that will contain most \'typical\' ozone amounts') ), ), # end of form center( submit('New Graph'), reset, end_form, blockquote(hr), 'Data for particular stations are available by clicking on the station name/link in the table above.', p, 'If you have questions or comments about this page, please contact: ', a({-href => 'mailto:Gloria.Carbaugh@NOAA.gov'}, 'Gloria Carbaugh'), br, p ); } open (FILE, "footer.html") or print "cant open footer file"; @header = (); close (FILE); print @header; # end of html #print end_html;