#! /bin/bash # invoke gnuplot to compare crop output from WEPS generated runs. # invocation: cropstack [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-#] # columns are stacked in the order they are entered, and a seperate graph is created for each separate file listing # set up column and title correspondence mincol=5 maxcol=42 coltitle[5]=`echo "5) Heat Unit Index"` coltitle[6]=`echo "6) Standing Stem Mass (kg/m^2)"` coltitle[7]=`echo "7) Standing Leaf Mass (kg/m^2)"` coltitle[8]=`echo "8) Standing Store Mass (kg/m^2)"` coltitle[9]=`echo "9) Flat Stem Mass (kg/m^2)"` coltitle[10]=`echo "10) Flat Leaf Mass (kg/m^2)"` coltitle[11]=`echo "11) Flat Store Mass (kg/m^2)"` coltitle[12]=`echo "12) Root Store Mass (kg/m^2)"` coltitle[13]=`echo "13) Root Fiber Mass (kg/m^2)"` coltitle[14]=`echo "14) Below Ground Stem Mass (kg/m^2)"` coltitle[15]=`echo "15) Total Stem Mass (kg/m^2)"` coltitle[16]=`echo "16) Total Leaf Mass (kg/m^2)"` coltitle[17]=`echo "17) Plant Height (meters)"` coltitle[18]=`echo "18) Number of Stems"` coltitle[19]=`echo "19) Whole field area based Leaf Area Index (traditional)"` coltitle[20]=`echo "20) Effective Leaf Area Index"` coltitle[21]=`echo "21) Root Depth (meters)"` coltitle[22]=`echo "22) Reproductive Mass Grain Fraction"` coltitle[23]=`echo "23) Temperature Stress Factor"` coltitle[24]=`echo "24) Water Stress Factor"` coltitle[25]=`echo "25) Frost Damage Factor"` coltitle[26]=`echo "26) Fraction Loss of Live Leaf Mass (scenescence)"` coltitle[27]=`echo "27) Fraction Loss of Total Leaf Mass (weathering)"` coltitle[28]=`echo "28) Photosynthetically Active Radiation (MJ/m2)"` coltitle[29]=`echo "29) Intercepted Photosynthetically Active Radiation (MJ/m2)"` coltitle[30]=`echo "30) Increment in Potential Dry Matter (kg/plant)"` coltitle[31]=`echo "31) Fibrous Root Partitioning Ratio"` coltitle[32]=`echo "32) Stem Partitioning Ratio"` coltitle[33]=`echo "33) Leaf Partitioning Ratio"` coltitle[34]=`echo "34) Reproductive Partitioning Ratio"` coltitle[35]=`echo "35) Stem Mass Fraction Allocated To Standing Stems (Rem. Goes Flat)"` coltitle[36]=`echo "36) Plant canopy diameter (or reach)(m/plant)"` coltitle[37]=`echo "37) Plant canopy coverage area (m^2/plant)"` coltitle[38]=`echo "38) Plant canopy diameter fraction (plant diameter / max diameter)"` coltitle[39]=`echo "39) Plant canopy coverage area fraction (m^2/m^2)"` coltitle[40]=`echo "40) Heat Unit Delay factor (1-no delay, 0-full delay)"` coltitle[41]=`echo "41) Stem area index (m^2/m^2)"` coltitle[42]=`echo "42) Representative stem diameter (m)"` # short column titles shortcoltitle[5]=`echo "HUI"` shortcoltitle[6]=`echo "S Stem"` shortcoltitle[7]=`echo "S Leaf"` shortcoltitle[8]=`echo "S Store"` shortcoltitle[9]=`echo "F Stem"` shortcoltitle[10]=`echo "F Leaf"` shortcoltitle[11]=`echo "F Store"` shortcoltitle[12]=`echo "R Store"` shortcoltitle[13]=`echo "R Fiber"` shortcoltitle[14]=`echo "BG Stem"` shortcoltitle[15]=`echo "T Stem"` shortcoltitle[16]=`echo "T Leaf"` shortcoltitle[17]=`echo "Height"` shortcoltitle[18]=`echo "# Stems"` shortcoltitle[19]=`echo "LAI"` shortcoltitle[20]=`echo "Eff LAI"` shortcoltitle[21]=`echo "R Depth"` shortcoltitle[22]=`echo "GRF"` shortcoltitle[23]=`echo "T Stress"` shortcoltitle[24]=`echo "W Stress"` shortcoltitle[25]=`echo "F Damage"` shortcoltitle[26]=`echo "Senes"` shortcoltitle[27]=`echo "Weath"` shortcoltitle[28]=`echo "PAR"` shortcoltitle[29]=`echo "I PAR"` shortcoltitle[30]=`echo "iDM"` shortcoltitle[31]=`echo "Root P"` shortcoltitle[32]=`echo "Stem P"` shortcoltitle[33]=`echo "Leaf P"` shortcoltitle[34]=`echo "Repr P"` shortcoltitle[35]=`echo "Stand F"` shortcoltitle[36]=`echo "Reach"` shortcoltitle[37]=`echo "Coverage"` shortcoltitle[38]=`echo "Reach R"` shortcoltitle[39]=`echo "Coverage R"` shortcoltitle[40]=`echo "HU Delay"` shortcoltitle[41]=`echo "SAI"` shortcoltitle[42]=`echo "Rep Stem D"` # set up column groupings tgroups=12 colgroupnum[5]=1 colgroupnum[6]=2 colgroupnum[7]=2 colgroupnum[8]=2 colgroupnum[9]=2 colgroupnum[10]=2 colgroupnum[11]=2 colgroupnum[12]=2 colgroupnum[13]=2 colgroupnum[14]=2 colgroupnum[15]=2 colgroupnum[16]=2 colgroupnum[17]=3 colgroupnum[18]=4 colgroupnum[19]=5 colgroupnum[20]=5 colgroupnum[21]=3 colgroupnum[22]=1 colgroupnum[23]=1 colgroupnum[24]=1 colgroupnum[25]=1 colgroupnum[26]=1 colgroupnum[27]=1 colgroupnum[28]=6 colgroupnum[29]=6 colgroupnum[30]=7 colgroupnum[31]=8 colgroupnum[32]=8 colgroupnum[33]=8 colgroupnum[34]=8 colgroupnum[35]=8 colgroupnum[36]=9 colgroupnum[37]=10 colgroupnum[38]=1 colgroupnum[39]=1 colgroupnum[40]=1 colgroupnum[41]=11 colgroupnum[42]=12 # group y axis labels grouplabel[1]=`echo "Fraction (0-1)"` grouplabel[2]=`echo "Mass (kg/m^2)"` grouplabel[3]=`echo "meters"` grouplabel[4]=`echo "count per m^2"` grouplabel[5]=`echo "m^2 leaf per m^2"` grouplabel[6]=`echo "Radiation (MJ/m^2)"` grouplabel[7]=`echo "kg per plant"` grouplabel[8]=`echo "Partitioning Ratio"` grouplabel[9]=`echo "meters per plant"` grouplabel[10]=`echo "m^2 per plant"` grouplabel[11]=`echo "m^2 per m^2"` grouplabel[12]=`echo "meters"` # 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: cropstack [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 and number and serial pairings for ncol in $( seq 1 ${tcolfile[tfiles]} ) do let index=(tcols-tcolfile[tfiles])+ncol # write serial number colfileser[index]=${ncol} # write file name 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 # find number of index blocks in this file linecount=`wc -l < ${ufilename[tfiles-1]}` lineswithnumbers=`grep -c '\.' < ${ufilename[tfiles-1]}` let fileindex=(linecount-lineswithnumbers-1)/2 #echo "fileindex = ${fileindex}" # check to use minimum of all files numindex=`echo "$fileindex $numindex" | stats min` #echo "numindex now equal to $numindex" 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: cropstack [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: cropstack [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 column 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: cropstack [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]} ${colfilenum[num]} ${colfileser[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 # Find the number of unique crops in each file numcrops[1]=`cut -c 315-400 < ${ufilename[1]} | uniq | grep '[:print:]' | sort -u | wc -l` #echo "${ufilename[1]} has ${numcrops[1]} unique crops" for num in $( seq 2 ${tfiles} ) do numcrops[num]=`cut -c 315-400 < ${ufilename[num]} | uniq | grep '[:print:]' | sort -u | wc -l` #echo "${ufilename[num]} has ${numcrops[num]} unique crop(s)" if [[ numcrops[num] -ne numcrops[1] ]] then # for multiple file plots, the number of unique crops must be equal echo "Different number of unique crops for two files" echo "Check and try again" fi done # Find maximum values for each unique crop year # all files have the same number of crop years for idx in $( seq 1 ${numcrops[1]} ) do for num in $( seq 1 ${tfiles} ) do # extract unique crop names in order cropname=`cut -c 315-400 < ${ufilename[num]} | uniq | grep '[:print:]' | linex ${idx} | sed 's/ $//'` echo "Crop name: ${cropname} :end" # Find maximum column value for x axis "day after planting" column 4 for just the lines containing the crop name cropmaxdap[idx]=`grep "${cropname}" < ${ufilename[num]} | dm "if x4>0 then x4 else SKIP" | stats max` echo "cropmaxdap: ${cropmaxdap[idx]}" # set maximum across all files afcropmaxdap[idx]=`echo "${cropmaxdap[idx]} ${afcropmaxdap[idx]}" | stats max` echo "afcropmaxdap: ${afcropmaxdap[idx]}" # find maximum for each stack for just the lines containing the crop name for idy in $(seq 1 $tcols) do if [[ colfilenum[idy] -eq ${num} ]] then # add column number to dm string if [[ colfileser[idy] -eq 1 ]] then summedcol="x${colnum[idy]}" else summedcol="${summedcol}+x${colnum[idy]}" fi fi done stackmaxval[idx]=`grep "${cropname}" < ${ufilename[num]} | dm "if x1>0 then ${summedcol} else SKIP" | stats max` echo "Stack ${summedcol} maximum is ${stackmaxval[idx]}" # set maximum across all files afstackmaxval[idx]=`echo "${stackmaxval[idx]} ${afstackmaxval[idx]}" | stats max` echo "afstackmaxval: ${afstackmaxval[idx]}" done done # find maximum column value for x axis "day after planting" column 4 for all input files #for num in $( seq 1 ${tfiles} ) #do # # Check for maximum days after planting for one file # filemaxdap=`dm "if x4>0 then x4 else SKIP" < ${ufilename[num]} | stats max` # # Check for maximum days after planting for all file # allmaxdap=`echo "$filemaxdap $allmaxdap" | stats max` # echo "maximum day after planting now equal to $allmaxdap" #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]}]}" #done # Find stack maximum value by summing all columns #for idy in $( seq 1 $tfiles ) #do # for num in $(seq 1 $tcols) # do # if [[ colfilenum[num] -eq ${idy} ]] # then # # add column number to dm string # if [[ colfileser[num] -eq 1 ]] # then # summedcol="x${colnum[num]}" # else # summedcol="${summedcol}+x${colnum[num]}" # fi # fi # done # stackmaxval[idy]=`dm "if x1>0 then ${summedcol} else SKIP" < ${ufilename[idy]} | stats max` # echo "Stack ${summedcol} maximum is ${stackmaxval[idy]}" #done # rather than loop within gnuplot, create specific plot lines # for each file so parameters can be added to the # titles of the graphs. # create text for graph title, using file names for num in $( seq 1 ${tfiles} ) do graphtitle[num]=`echo "${ufilename[num]}"` done # Set up plot sizes for multiple plots (ie. groups) if [[ $tfiles -gt 1 ]] then # plot sizes for each file psizebase=$( echo "scale=4; 0.9/${tfiles}" | bc -l ) for num in $( seq 1 $tfiles ) do # create coordinates # y size for plot (x is 1.0) if [[ $num -eq $tfiles ]] then # increase the size of the last plot (both title and axis) psize[num]=$( echo "scale=4; ${psizebase}+0.1" | bc -l ) porigin[num]=0 else # other plots have just title psize[num]=${psizebase} # place plots from the top down in the order specified porigin[num]=$( echo "scale=4; 0.1+($tfiles-$num)*${psizebase}" | bc -l ) fi done fi # write single instance lines top plot file #--- start pdf --- echo "set terminal pdf" > temp.plt echo "set output 'cropstack.pdf'" >> temp.plt view_pause=0 #--- end pdf --- #--- start emf --- # create temporary directory for files if needed #tempdir="htemp" #mkdir -p ${tempdir} ## clear any files #rm ${tempdir}/*.emf #echo "set terminal emf monochrome dashed" > temp.plt #view_pause=0 #echo "set line style 1 lt 1 lw 1" >> temp.plt #echo "set line style 2 lt 2 lw 1" >> temp.plt #echo "set line style 3 lt 3 lw 1" >> temp.plt #echo "set line style 4 lt 4 lw 1" >> temp.plt #echo "set line style 5 lt 5 lw 1" >> temp.plt #echo "set line style 6 lt 1 lw 3" >> temp.plt #echo "set line style 7 lt 2 lw 3" >> temp.plt #echo "set line style 8 lt 3 lw 3" >> temp.plt #echo "set line style 9 lt 4 lw 3" >> temp.plt #echo "set line style 10 lt 5 lw 3" >> temp.plt #echo "set line style 11 lt 1 lw 5" >> temp.plt #--- end emf --- #--- start screen --- #view_pause=-1 #echo "" > temp.plt #--- end screen --- # set legend location echo "set key left top" >> temp.plt for year in $(seq $numindex) do echo "crop year = ${year}" # # --- emf output files --- # echo "set output '${tempdir}/${year}.emf'" >> temp.plt # set the crop that is growing cropnumyr=$( echo "(${year} - 1) % ${numcrops[1]}" | bc ) let cropnumyr++ # echo "${cropnumyr}" # set so that graphs use same total days and maximum values for that crop echo "set xrange [0:${afcropmaxdap[cropnumyr]}]" >> temp.plt echo "set yrange [0:${afstackmaxval[cropnumyr]}]" >> temp.plt # set up single or multiple plot windows if [[ $tfiles -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 file for idy in $( seq 1 $tfiles ) do # create graph title line echo "set title 'Crop Yr ${year}, ${graphtitle[idy]}'" >> temp.plt # remove x axis from all but last graph if [[ $idy -lt $tfiles ]] then # remove x axis labels echo "set format x ''" >> temp.plt echo "set xlabel ''" >> temp.plt else # format x axis labels echo "set format x '% g'" >> temp.plt echo "set xlabel 'Days After Planting'" >> temp.plt fi # individual sizes for multiplots if [[ $tfiles -gt 1 ]] then # set plot size echo "set size 1.0, ${psize[idy]}" >> temp.plt echo "set origin 0.0, ${porigin[idy]}" >> temp.plt fi # create plot lines for each column in this file index=0 for num in $(seq 1 $tcols) do if [[ colfilenum[num] -eq ${idy} ]] then for idx in $(seq 1 ${colfileser[num]}) do # set the index local to the file name let locindex=(num-colfileser[num])+idx if [[ idx -eq 1 ]] then # set axis labels echo "set ylabel '${grouplabel[${colgroup[num]}]}'" >> temp.plt # initialize column sums summedcol="(\$${colnum[locindex]}" else # add all previous column numbers to list to be summed for plot summedcol="${summedcol}+${colnum[locindex]}" fi done summedcol="${summedcol})" summedcol=`echo $summedcol | sed 's/+/+\$/g'` let index+=1 let yearm=year-1 plotline[index]="'${filename[num]}' index ${yearm} using 4:${summedcol} with lines title '${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 [[ $tfiles -gt 1 ]] then # this command necessary to display all plots on some terminals echo "unset multiplot" >> temp.plt fi echo "pause ${view_pause}" >> temp.plt done gnuplot temp.plt #rm temp.plt exit