#!/usr/bin/env perl -w # -*- perl -*- # Graph the (science) data from a file # Version: $Id: ar_trend_graph,v 1.1 2008/09/12 19:53:41 goeke Exp goeke $ # Assume data is from lf_hist in form # Channel D1 D2 D3 D4 D5 D6 # ######################################################################## # initial constants ######################################################################## # $DIR = $ENV{CRATERTOOLS}; # needed to find stuff $TEMPFILE = "plot.dat"; # if data comes from STDIN, we need # this for a temp spool file $OUTFILE = "cplot.ps"; # default output print file @House = ( 'V28bus', 'V5digital', 'V5plus', 'V5neg', 'I28bus', 'BiasCurrentD1', 'BiasCurrentD2', 'BiasCurrentD3', 'BiasCurrentD4', 'BiasCurrentD5', 'BiasCurrentD6', 'BiasVoltThin', 'BiasVoltThick', 'CalAmp', 'LLDThin', 'LLDThick', 'Ttelescope', 'Tanalog', 'Tdigital', 'Tpower', 'Tref', 'RadHighSens', 'RadMedSens', 'RadLowSens', 'Tprt', # 'Purge' # ); # @SecSci = ( # 'LastValue', # Last command value 'DiscThin', # LowLevel Discriminator for Thin Detectors 'DiscThick', # LowLevel Discriminator for Thick Detectors # 'Mask', # Coincidence Mask High Word # 'Mask2', # Coincidence Mask next word # 'Mask3', # Coincidence Mask next word # 'Mask4', # Coincidence Mask next word 'Single1', # Singles rates 'Single2', 'Single3', 'Single4', 'Single5', 'Single6', 'Good', # Stall Counter 'Reject', # Reject Counter 'Total', # Total Event Counter # ); # @SC = ( 'BusVoltage', 'BusCurrent', 'BusPower' # 'BusCmd' ); ######################################################################## # Main program ######################################################################## &Setup; &Acquire; &Display; &Shutdown; exit 0; ######################################################################## # Subroutines follow ######################################################################## ######################################################################## # Aquire the specified data elements from $File ######################################################################## sub Acquire { my ($epoch,$foo,$hex,$time,$value,@line); my $out = ""; @line = split(" ",); # first line has id info if ($line[0] =~ /^\#/) { $Title = sprintf("\\nData starts %s %s %s", $line[4],$line[5],$line[6]); } else { $Title = "\\nUnknown Data Source"; } my $kk = 1; # keeps track of # plot items while() { if ($_ =~ /^Time/) { ($foo,$time) = split(" "); next if ($kk == 1); # keep updating $time if (!defined($epoch)) { $epoch = $time ; # first time /is/ epoch } else { print TEMPFILE "$out\n"; # write previous line of data } # NB this starts a new output line $out = $time - $epoch; # label time on graph from 0 $kk = 1; # first plot data in column 1 next; } if ($_ =~ /^$Pattern/) { ($foo,$value,$hex,$eng) = split(" "); if (defined($eng)) { $value = $eng; } $out = $out . "\t" . $value ; $Label[$kk++] = $foo; # save the label } } $FinalTime = $time - $epoch; # save this to scale display close(SOURCE); close(TEMPFILE); } ######################################################################## # Display Results # First line of the data determines how many columns we have; # so even if it is an info line, it needs to have the right count # The first line may also have the serial number and time embedded # but it is discarded after reading, even if it was data # We set up gnuplot, generate the print file first, then replot to xterm ######################################################################## sub Display { my ($ii,$jj,@line); # NB gnuplot starts with terminal set to console display; i.e. x11 # $Log $GNU_Header = " set title \"$Title\" set xlabel \"Seconds\" set xrange [0:$FinalTime] set ylabel \"Eng. Value\" set grid "; print DISP $GNU_Header; print DISP "set terminal x11 \nplot "; # After "plot" and first data set must insert comma before # each subsequent set, but not at the end! for ($howmany=1; $howmany<=$#Label; $howmany++) { printf DISP "%s \"%s\" using 1:%d title \"%s\" with lines", $howmany>1?',':'', $TEMPFILE, $howmany+1, "$Label[$howmany]"; } print DISP "\nset terminal postscript landscape $PC\n"; print DISP "replot\n"; # this puts plot into PS file print DISP "q\n"; # and quit gnuplot close DISP; my ($size,$name) = split(" ",`ls -s $PSOut`); # Consistency check if ($size) { print ">>> Writing Postscript for printing to \"$PSOut\"\n"; print ">>> Hit \"q\" in the xterm window to close it\n"; } else { print "\n>>> *** No non-zero data to plot ***\n\n"; } } ######################################################################## # Give Help ######################################################################## sub Help { print "Usage: $0 [-h] [-t Title] [-v] -p mnemonic file_name\n"; if ($Verbose) { print " flags: -h gets full help message -p mnemonic of housekeeping data (required) multiple -p flags allowed -t use following words as title [time of data start] -v makes the output verbose (to STDERR) file_nmae read data from this file (required) Graphs housekeeping data to an X window display. Input data is taken from a (single) binary packet file. Valid mnemonics: "; for ($ii=0; $ii<=$#House; ) { print "$House[$ii] "; print "\n" if (!(++$ii%5)); } } } ######################################################################## # Do the setup ######################################################################## sub Setup { my ($foo,$bar,$linearX); my $gnuflags = ''; # default is no flags to gnuplot $PSOut = $OUTFILE; # default plot file name $Display = 1; # default is to generate X display output $PC = 'monochrome'; # default is to print in monochrome # $Log = 'set logscale'; # default is log-log scale INPUT: while ($foo = shift(@ARGV)) { if ($foo =~ /^-[hH]/) { $Verbose++; &Help; exit 0; } if ($foo =~ /^-[pP]/) { $bar = shift(@ARGV); if (!defined($Pattern)) { $Pattern = "(" . $bar . ")"; } else { $Pattern = $Pattern . "|(" . $bar . ")"; } for(my $ii=0; $ii<=$#House; $ii++) { goto INPUT if ($bar eq "$House[$ii]"); } print STDERR "Invalid mnemonic supplied: \"$bar\"\n"; $Verbose++; &Help; exit 2; } if ($foo =~ /^-tT/) { # Provide a graph title $Title = shift(@ARGV); # get the detector set if (!defined($Title) || $Title =~ /^-/) { print STDERR "Flag $foo requires a following string\n"; &Help; exit 2; } $Title =~ s/\"//g; # strip off quotes, if present next; } if ($foo =~ /^-[vV]/) { # verbose $Verbose++; next; } if ($foo =~ /^-/) { print STDERR "Unknown flag: $foo\n"; &Help; exit 1; } if ($File) { print STDERR "Too many input file names provided: $File \& $foo\n"; &Help; exit 1; } else { $File = $foo; next; } } if (!defined($File)) { print STDERR "Require input file name\n"; &Help; exit 2; } open(FILE,"$File") || die "$File failed the existence check"; close(FILE); print "Using $File as input source\n" if $Verbose; print "Using \"$Pattern\" as match\n" if $Verbose; open(SOURCE,"rtlm -a -r $File | calcurve |"); # NB opening a pipe never fails, even if it fails (so no die) open(TEMPFILE,">$TEMPFILE") || die "Could not open $TEMPFILE for temporary storage"; # NB although "persist" exists as a "set" option in gnuplot-4 # it must be a command line option in 3.7 (and must come first!) $foo = `which gnuplot`; if ($foo =~ /(^\/)|(^.\/)/) { $gnuflags .= " 2>/dev/null" if (!$Verbose); open(DISP,"| gnuplot -persist - $gnuflags >$PSOut"); # NB pipes do not return error on error, hence no die } else { printf STDERR "Sorry, but could not find \"gnuplot\"\n"; printf STDERR " We looked in $ENV{PATH}\n"; exit 5; } } ######################################################################## # Clean up any mess -- remove spool file if used # NB there would be a problem unlinking this file if the writes in # &Display haven't completed. So instead of using a non-buffered # output up there, we explicity close the pipe, which does a flush # before returning and coming down here (it seems). ######################################################################## sub Shutdown { # unlink $TEMPFILE || die $!; # doesn't actually care if $INFILE exists } ######################################################################## # Pod follows ######################################################################## =for html CRaTER -- ar_trend_graph =head2 NAME B -- Generate plot of selected housekeeping data =head2 USAGE ar_trend_graph [-h] [-t Title] [-v] -p mnemonic file_name =head2 FLAGS -h gets full help message -p mnemonic of housekeeping data (required); multiple -p flags allowed -t prefix default title information (s/n & date) with Title -T replace default title information with Title -v makes the output verbose (to STDERR) file_name read data from this file (required) =head2 DESCRIPTION We read data from a single CRaTER binary packet file, extract the selected mnemonics, and plots these as a function of time. The program generates a Postscript file for printing in parallel with displaying the plot in a separate X-window. By default the graph title is formed from the first line in the packet file, specifying the time at which data acquisition started. =head2 ENVIRONMENT perl5.002 Minimum version of Perl interpreter required gnuplot This script works with version 3.7 and 4.0 CRATERTOOLS Environment variable containing path to CRaTER utilities =head2 BUGS The plot data and the Postscript file are written to the current directory, rather than /tmp. =head2 SEE ALSO c_graph, gnuplot =head2 AUTHOR Bob Goeke =head2 RCS Information $Id: ar_trend_graph,v 1.1 2008/09/12 19:53:41 goeke Exp goeke $ =cut ######################################################################## # history follows ######################################################################## # $Log: ar_trend_graph,v $ # Revision 1.1 2008/09/12 19:53:41 goeke # Initial revision #