#! /bin/bash # invoke gnuplot to compare volumetric soil water content profiles # from WEPS generated runs. (hlayers.out or a file with the same format) # files are checked for matching day, month and year and then plotted # on individual days. # invocation: profileplothydro [Col_num-1 Col_num-2 ... Colnum-# file-1] [Col_num-1 Col_num-2 ... Colnum-# file-2] ... [Col_num-1 Col_num-2 ... Colnum-# file-#] # set up column and title correspondence mincol=6 maxcol=20 coltitle[6]=`echo "6) Volumetric Water Content (m/m)"` coltitle[7]=`echo "7) Saturated Vol Water Cont (m/m)"` coltitle[8]=`echo "8) Field Capacity Vol Water Cont (m/m)"` coltitle[9]=`echo "9) Permanent Wilting Point Vol Water Cont (m/m)"` coltitle[10]=`echo "10) Residual Vol Water Cont (m/m)"` coltitle[11]=`echo "11) Fraction Crop Available Water"` coltitle[12]=`echo "12) Saturation Ratio"` coltitle[13]=`echo "13) Soil Temperature (C)"` coltitle[14]=`echo "14) Unsaturated hydraulic Conductivity (m/s)"` coltitle[15]=`echo "15) Matric Potential (m)"` coltitle[16]=`echo "16) Soil Relative Humidity (fraction)"` coltitle[17]=`echo "17) Bulk Density (Mg/m^3)"` coltitle[18]=`echo "18) Air Entry Potential (m)"` coltitle[19]=`echo "19) Brooks and Corey Exponent b =(1/lambda)"` coltitle[20]=`echo "20) Saturated Hydraulic Conductivity (m/s)"` shortcoltitle[6]=`echo "Wat"` shortcoltitle[7]=`echo "Sat"` shortcoltitle[8]=`echo "FC"` shortcoltitle[9]=`echo "WP"` shortcoltitle[10]=`echo "Res"` shortcoltitle[11]=`echo "PAW"` shortcoltitle[12]=`echo "SatRat"` shortcoltitle[13]=`echo "T(C)"` shortcoltitle[14]=`echo "Cond"` shortcoltitle[15]=`echo "Pot"` shortcoltitle[16]=`echo "Hum"` shortcoltitle[17]=`echo "Den"` shortcoltitle[18]=`echo "Air"` shortcoltitle[19]=`echo "Ex b"` shortcoltitle[20]=`echo "SatCon"` # set up column groupings tgroups=7 colgroupnum[6]=1 colgroupnum[7]=1 colgroupnum[8]=1 colgroupnum[9]=1 colgroupnum[10]=1 colgroupnum[11]=2 colgroupnum[12]=2 colgroupnum[13]=3 colgroupnum[14]=4 colgroupnum[15]=5 colgroupnum[16]=2 colgroupnum[17]=6 colgroupnum[18]=5 colgroupnum[19]=7 colgroupnum[20]=4 # grab and count command arguments let ncmdarg=0 for ncmd in $* do let ncmdarg=ncmdarg+1 cmdarg[ncmdarg]="$ncmd" # echo "Command argument $ncmdarg = ${cmdarg[ncmdarg]}" done # check command argument count, zero means none if [[ ncmdarg -eq 0 ]] then echo 'invocation: profileplothydro [Col_num-1 Col_num-2 ... Colnum-# file-1] [Col_num-1 Col_num-2 ... Colnum-# file-2] ... [Col_num-1 Col_num-2 ... Colnum-# file-#]' echo 'Valid Column Numbers are:' for num in $( seq $mincol $maxcol ) do echo ${coltitle[num]} done exit fi # parse command arguments checking for numbers and when not a number checking for a valid file name # initialize total number of columns parsed tcols=0 # initialize total number of valid file names parsed (must assume one when column numbers preceed file names) tfiles=1 # initialize column count for first file name tcolfile[tfiles]=0 for ncmd in $( seq 1 $ncmdarg ) do # test if it is an integer number echo "${cmdarg[ncmd]}" | grep [^0-9] > /dev/null 2>&1 if [ "$?" -eq "0" ] then # not a column number, check for file name if [ -e "${cmdarg[ncmd]}" ] then # valid file name, check for preceeding columns if [[ tcolfile[tfiles] -gt 0 ]] then # columns are listed in front of this name # back fill column file name pairings for ncol in $( seq 1 ${tcolfile[tfiles]} ) do # write file name let index=(tcols-tcolfile[tfiles])+ncol filename[index]="${cmdarg[ncmd]}" done # add file name to unique file names list ufilename[tfiles]="${cmdarg[ncmd]}" # Increment file number counter let tfiles+=1 fi else # not a valid file name, show error message and exit echo \'"${cmdarg[ncmd]}"\' is not valid file name. exit fi else # it is an integer number, check for valid column number if [[ ${cmdarg[ncmd]} -lt $mincol ]] then echo \'"${cmdarg[ncmd]}"\' is a Bad Column Number echo 'invocation: profileplothydro [Col_num-1 Col_num-2 ... Colnum-# file-1] [Col_num-1 Col_num-2 ... Colnum-# file-2] ... [Col_num-1 Col_num-2 ... Colnum-# file-#]' echo 'Valid Column Numbers are:' for num in $( seq $mincol $maxcol ) do echo ${coltitle[num]} done exit elif [[ ${cmdarg[ncmd]} -gt $maxcol ]] then echo \'"${cmdarg[ncmd]}"\' is a Bad Column Number echo 'invocation: profileplothydro [Col_num-1 Col_num-2 ... Colnum-# file-1] [Col_num-1 Col_num-2 ... Colnum-# file-2] ... [Col_num-1 Col_num-2 ... Colnum-# file-#]' echo 'Valid Column Numbers are:' for num in $( seq $mincol $maxcol ) do echo ${coltitle[num]} done exit fi # valid column number, add into colum number array and increment indexes let tcols+=1 let tcolfile[tfiles]+=1 colnum[tcols]="${cmdarg[ncmd]}" # set column group number colgroup[tcols]=${colgroupnum[${colnum[tcols]}]} # set column file number colfilenum[tcols]=${tfiles} fi done # screen for terminating valid file name if [ ! -e "${filename[tcols]}" ] then echo "No terminating file name." echo 'invocation: profileplothydro [Col_num-1 Col_num-2 ... Colnum-# file-1] [Col_num-1 Col_num-2 ... Colnum-# file-2] ... [Col_num-1 Col_num-2 ... Colnum-# file-#]' fi # set tfiles to the correct count let tfiles-=1 # echo the resulting arrays of column numbers and file names # echo "The input command line results in the following columns and file names:" # for num in $( seq 1 ${tcols} ) # do # echo "${colnum[num]} ${colgroup[num]} ${filename[num]}" # done # exit # set up graph to column group correspondence # sort group list (result is zero reference array) colgroupsort=(`echo ${colgroup[@]} | transpose | sort | transpose`) # total number of column groups to be plotted tgroups=1 # list of groups represented groupnum[1]=${colgroupsort[0]} let tindex=tcols-1 for num in $( seq 1 ${tindex} ) do let index=num-1 if [[ ${colgroupsort[num]} -ne ${colgroupsort[index]} ]] then let tgroups+=1 groupnum[tgroups]=${colgroupsort[num]} fi done # show groups # echo "unique group numbers" # echo ${groupnum[@]} # exit # determine number of years in each file for nfile in $( seq 1 $tfiles ) do echo -n "checking year count: ${ufilename[nfile]} : " # find number of year blocks (output has years separated by 2 blank lines making these index blocks as well) fileindex=`uniq -d ${ufilename[nfile]} | wc -l` #fileindex=`dm "if x3>0 then x3 else SKIP" < ${ufilename[nfile]} | dm y2 x1 | dm "if x1=x2 then SKIP else 1" | stats sum` echo "${fileindex} years" # check to use minimum of all files numindex=`echo "$fileindex $numindex" | stats min` #echo "numindex now equal to $numindex" done # find maximum column value for each column and assign that to the maximum for the group for num in $( seq 1 $tcols ) do echo -n " Find maximum value: column ${colnum[num]} in ${filename[num]} : " # find selected column maximum value for this file filemaxval=`dm "if x${colnum[num]}>0 then x${colnum[num]} else SKIP" < ${filename[num]} | stats max` echo "${filemaxval}" # check for maximum for this column group for all files groupmaxval[${colgroup[num]}]=`echo "$filemaxval ${groupmaxval[${colgroup[num]}]}" | stats max` echo "groupmaxval(${colgroup[num]}) now equal to ${groupmaxval[${colgroup[num]}]}" if [[ ${colnum[num]} -eq 13 ]] then # column 13 group echo -n " Find minimum value: column ${colnum[num]} in ${filename[num]} : " # find selected column minimum value for this file fileminval=`dm "if x${colnum[num]}<${groupmaxval[${colgroup[num]}]} then x${colnum[num]} else SKIP" < ${filename[num]} | stats min` echo "${fileminval}" # check for minimum for this column group for all files groupminval[${colgroup[num]}]=`echo "$fileminval ${groupminval[${colgroup[num]}]}" | stats min` echo "groupminval(${colgroup[num]}) now equal to ${groupminval[${colgroup[num]}]}" elif [[ ${colnum[num]} -eq 14 || ${colnum[num]} -eq 15 ]] then # column 14 or 15 group echo -n " Find minimum value: column ${colnum[num]} in ${filename[num]} : " # find selected column minimum value for this file fileminval=`dm "if x${colnum[num]}>0 then x${colnum[num]} else SKIP" "if x${colnum[num]}<${groupmaxval[${colgroup[num]}]} then x${colnum[num]} else SKIP" < ${filename[num]} | stats min` echo "${fileminval}" # check for minimum for this column group for all files groupminval[${colgroup[num]}]=`echo "$fileminval ${groupminval[${colgroup[num]}]}" | stats min` echo "groupminval(${colgroup[num]}) now equal to ${groupminval[${colgroup[num]}]}" fi done # create text for graph title, using file names graphtitle="Files: " for num in $( seq 1 ${tfiles} ) do graphtitle=`echo "${graphtitle} ${num}) ${ufilename[num]} "` done # Set up plot sizes for multiple plots (ie. groups) if [[ $tgroups -gt 1 ]] then # plot sizes for each group for num in $( seq 1 $tgroups ) do # create coordinates # x size for plot (y is 1.0) psize[num]=$( echo "scale=4; 0.9/${tgroups}" | bc -l ) # increase the size of the first plot if [[ $num -eq 1 ]] then psize[num]=$( echo "scale=4; ${psize[num]}+0.1" | bc -l ) porigin[num]=0 else # x origin for plot (y is zero) porigin[num]=$( echo "scale=4; 0.1+($num-1)*${psize[num]}" | bc -l ) fi done fi # creates file for each day, looping through year and day blocks # the commands for each day are written to the plot file # create temporary directory for files if needed tempdir="htemp" mkdir -p ${tempdir} # clear any files rm ${tempdir}/*.png # start with zero file graph name index gidx=0 # year loop adjust numindex to reflect zero indexing in gnuplot let numindex-=1 for year in $( seq 0 ${numindex} ) do # day loop for yday in $( seq 0 364 ) do # clears plot file if it exists echo 'reset' > temp.plt #increment graphics file name index let gidx+=1 # on screen progress indicator echo "Creating Entry: ${gidx}.png" # set up terminal type #--- start png --- echo "set terminal png size 640,480" >> temp.plt set ouput file name echo "set output '${tempdir}/${gidx}.png'" >> temp.plt view_pause=0 #--- end png --- #--- start screen --- # view_pause=-1 #--- end screen --- # write single instance lines top first plot file #echo "set yrange [:] reverse" >> temp.plt # for just the surface layers echo "set yrange [:] reverse" >> temp.plt echo "set pointsize 1.2" >> temp.plt echo "set xlabel 'water content (m/m)'" >> temp.plt echo "set ylabel 'depth (mm)'" >> temp.plt # set graph title echo "set title '${graphtitle}'" >> temp.plt # set legend location echo "set key right bottom" >> temp.plt # set up single or multiple plot windows if [[ $tgroups -gt 1 ]] then echo "multiple plots" echo "set size 1.0, 1.0" >> temp.plt echo "set origin 0.0, 0.0" >> temp.plt echo "set multiplot" >> temp.plt fi # create plot commands for each group for idx in $( seq 1 $tgroups ) do # only print title once, above first graph if [[ $idx -gt 1 ]] then # insert space to reserve title space (ie. line y axis' position across graphs) echo "set title ' '" >> temp.plt # remove y axis labels echo "set format y ''" >> temp.plt fi # individual sizes for multiplots if [[ $tgroups -gt 1 ]] then # set plot size echo "set size ${psize[idx]}, 1.0" >> temp.plt echo "set origin ${porigin[idx]}, 0.0" >> temp.plt fi # set axis scales if [[ ${groupnum[idx]} -eq 4 || ${groupnum[idx]} -eq 5 ]] then # column 14 or column 15 group echo "set logscale x" >> temp.plt echo "unset xrange" >> temp.plt echo "set xrange [${groupminval[${groupnum[idx]}]}:${groupmaxval[${groupnum[idx]}]}]" >> temp.plt elif [[ ${groupnum[idx]} -eq 3 ]] then # column 13 group (soil temperature) echo "unset logscale x" >> temp2.plt echo "set xrange [${groupminval[${groupnum[idx]}]}:${groupmaxval[${groupnum[idx]}]}]" >> temp.plt else echo "unset logscale x" >> temp.plt echo "set xrange [0:${groupmaxval[${groupnum[idx]}]}]" >> temp.plt fi # create plot lines for each column and file in this group index=0 for num in $(seq 1 $tcols) do if [[ colgroup[num] -eq groupnum[idx] ]] then let index+=1 plotline[index]="'${filename[num]}' index ${year} every :::${yday}::${yday} using ${colnum[num]}:5 with linespoints lt -1 title '${colfilenum[num]}) ${shortcoltitle[${colnum[num]}]}', \\" fi done # add plot command to first plotline plotline[1]=`echo "${plotline[1]}" | sed -e 's/^.*/plot &/'` # strip last plotline of 3 extra characters plotline[index]=`echo "${plotline[index]}" | sed -e 's/...$//'` # write out plot lines to file for num in $(seq 1 $index) do echo ${plotline[num]} >> temp.plt done done # check multiple plots if [[ $tgroups -gt 1 ]] then # this command necessary to display all plots on some terminals echo "unset multiplot" >> temp.plt fi echo "print \"Creating Graph: ${gidx}.png\"" >> temp.plt echo "pause ${view_pause}" >> temp.plt gnuplot temp.plt # end day loop done # end year loop done #rm temp.plt