#!/bin/bash # --------------------------------------------------------------------------- # # matrix.comp Compare output of matrix for two model versions. # # # # Intended for interactive running only. # # # # Hendrik L. Tolman # # Updated by Yukino Nagai # # June 2017 # # # # Copyright 2013 National Weather Service (NWS), # # National Oceanic and Atmospheric Administration. All rights # # reserved. WAVEWATCH III is a trademark of the NWS. # # No unauthorized use without permission. # # # # --------------------------------------------------------------------------- # # This script takes in one argument: the name of a test directory or 'all' # # 1. Set up function isbinary { # Check if file is binary [or text] # # Uses `file` command to check if a file is binary or text by inspecting # the MIME type of file. # # `file -i ` will return `text/` if file is a text file. # Anything else can be considered a binary file. # # If your version of `file` does not accept the -i or --mime flag, you # can also just run `file` with no flags and use `grep -i text`. # # The mime checking version is a bit more robust though. file -i $1 | grep -vq "text/" } # 1.a Computer/ user dependent set up if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ] then printf "\n ERROR ABORTING \n" printf "\n matrix.comp requires 3 arguments: " printf " 1: test type (eg, all or test-name), 2: base directory and 3: reference directory. \n" printf "\n Usage:" printf " ./bin/matrix.comp all basedir compdir \n\n" exit fi ctest=$1 base_dir=$2 comp_dir=$3 home_dir=`pwd` rm -rf $home_dir/output rm -f $home_dir/matrixDiff.txt # 1.b Flags to do course selection - - - - - - - - - - - - - - - - - - - - - - # 1.c Output to ID script - - - - - - - - - - - - - - - - - - - - - - - - - - echo ' ' > $home_dir/header.tmp echo ' ******************************************************' >> $home_dir/header.tmp echo ' *** compare WAVEWATCH III matrix of regression tests ***' >> $home_dir/header.tmp echo ' ******************************************************' >> $home_dir/header.tmp echo ' ' >> $home_dir/header.tmp echo ' ' > $home_dir/isIdenticalList.tmp echo '**********************************************************************' >> $home_dir/isIdenticalList.tmp echo '************************ identical cases *****************************' >> $home_dir/isIdenticalList.tmp echo '**********************************************************************' >> $home_dir/isIdenticalList.tmp echo ' ' > $home_dir/notIdenticalList.tmp echo '**********************************************************************' >> $home_dir/notIdenticalList.tmp echo '********************* non-identical cases ****************************' >> $home_dir/notIdenticalList.tmp echo '**********************************************************************' >> $home_dir/notIdenticalList.tmp echo ' ' > $home_dir/summary.tmp echo '**********************************************************************' >> $home_dir/summary.tmp echo '******************** summary of comparison ***************************' >> $home_dir/summary.tmp echo '********** only results of non-identical cases are listed ************' >> $home_dir/summary.tmp echo '****** if less than 10 files differ for a case, they are listed ******' >> $home_dir/summary.tmp echo '**********************************************************************' >> $home_dir/summary.tmp echo ' ' > $home_dir/fulldiff.tmp echo '**********************************************************************' >> $home_dir/fulldiff.tmp echo '******************* full output of comparison ************************' >> $home_dir/fulldiff.tmp echo '**********************************************************************' >> $home_dir/fulldiff.tmp if [ "$ctest" = 'all' ] ; then ctest=`ls -d ww3_tp1.? ww3_tp2.? ww3_ts? ww3_tbt1.? ww3_tbt2.? ww3_tic1.? ww3_tic2.? ww3_tig1.? ww3_tp2.1? ww3_tp2.2? ww3_ta? ww3_tr? ww3_tnc? mww3_test_0? ww3_ufs1.?` ; fi echo "base directory : $base_dir" >> $home_dir/header.tmp echo "comp directory : $comp_dir" >> $home_dir/header.tmp echo "test(s) : " >> $home_dir/header.tmp echo $ctest >> $home_dir/header.tmp echo " " >> $home_dir/header.tmp cat $home_dir/header.tmp if [ ! -d $base_dir ] ; then echo " directory $base_dir not found." ; exit 2 ; fi if [ ! -d $comp_dir ] ; then echo " directory $comp_dir not found." ; exit 2 ; fi # --------------------------------------------------------------------------- # # 2. Looping over tests # # --------------------------------------------------------------------------- # for tst in $ctest do cd $home_dir ; cd $base_dir if [ ! -d $tst ] then echo "cannot find $tst in $base_dir, skipped" >> $home_dir/header.tmp else cd $home_dir ; cd $comp_dir if [ ! -d $tst ] then echo "cannot find $tst in $comp_dir, skipped" >> $home_dir/header.tmp else cd $tst return_comp=`pwd` cd $home_dir ; cd $base_dir ; cd $tst return_base=`pwd` # --------------------------------------------------------------------------- # # 3. Looping over work directories # # --------------------------------------------------------------------------- # cases=$(find . -maxdepth 1 -type d -name "work*" ) for run in $cases do echo 'run : ' $run output="$home_dir/output/$tst/$run" numDiff=0 numSame=0 numSkipped=0 numNotInComp=0 numInCompOnly=0 isIdentical=1 diffFiles="" if [ ! -d $run ] then echo "cannot find $run in $base_dir/$run, skipped" >> $home_dir/header.tmp; isIdentical=2 else cd $return_comp if [ ! -d $run ] then echo "cannot find $run in $comp_dir/$run, skipped" >> $home_dir/header.tmp; isIdentical=2 else echo " testing case: $tst; run: $run" echo "" >> $home_dir/fulldiff.tmp echo "* test case: $tst; test run: $run" >> $home_dir/fulldiff.tmp echo "*********************************************************" >> $home_dir/fulldiff.tmp # --------------------------------------------------------------------------- # # 4. Check for files, generate lists of files # # --------------------------------------------------------------------------- # cd $return_base ; cd $run rm -f diff_tempfile files_0=`ls` files_1="" for file in $files_0 do if [[ -d $file ]]; then if [[ $file == build* ]] || [[ $file == exe* ]] || [[ $file == *oasis3-mct* ]] || [[ $file == toy* ]]; then : # skip else #add files: files_dir=`ls $file` for file1 in $files_dir do files_1="$files_1 $file/$file1" done fi else files_1="$files_1 $file" fi done #Generate list of files to skip skipfiles="ww3_shel.out ww3_multi.out prf.*.mww3 finished ww3_systrk.out gmon.out time_count.txt oasis_make.out oasis_clean.out toy_model toy_make.out toy_clean.out build.log" nf_1=`echo $files_1 | wc -w | awk '{print $1}'` echo " found $nf_1 files in base directory" >> $home_dir/fulldiff.tmp cd $return_comp ; cd $run rm -f diff_tempfile files_0=`ls` files_2="" for file in $files_0 do if [[ -d $file ]]; then if [[ $file == build* ]] || [[ $file == exe* ]] || [[ $file == *oasis3-mct* ]] || [[ $file == toy* ]]; then : # skip else #add files: files_dir=`ls $file` for file1 in $files_dir do files_2="$files_1 $file/$file1" done fi else files_2="$files_2 $file" fi done nf_2=`echo $files_2 | wc -w | awk '{print $1}'` echo " found $nf_2 files in compare directory" >> $home_dir/fulldiff.tmp cd $return_base ; cd $run # --------------------------------------------------------------------------- # # 5. Loop over all files in base directory # # --------------------------------------------------------------------------- # for file in $files_1 do # 5.a Check for buddy file, identify file type escapedfilename=`echo ${file/\./\\\.}` if [ ! -f $return_comp/$run/$file ] then isIdentical=0; let "numNotInComp += 1" echo " $file not in compare directory" >> $home_dir/fulldiff.tmp else files_2=`echo "$files_2" | sed "s#\b$escapedfilename\b##g" | sed "s# # #g"` if [[ $skipfiles =~ (^|[[:space:]])"$file"($|[[:space:]]) ]] then filetype="skip" elif [[ $file == log.* ]] || [[ $file == "output.ww3" ]] then filetype="log" elif isbinary $file then filetype="binary" else filetype="file" fi # 5.a Assign action based on file type case "$filetype" in log ) form='f' ; do='y' ; drop='y' ;; skip ) form='f' ; do='-' ; drop='-' ;; binary ) form='u' ; do='y' ; drop='-' ;; file ) form='f' ; do='y' ; drop='-' ;; * ) form='f' ; do='-' ; drop='-' ;; esac if [ "$drop" = 'y' ] then filter=' (filtered)' else filter= fi if [ "$do" = 'y' ] then # 5.b Formatted file, use diff and exclude lines if [ "$form" = 'f' ] then if [ "$drop" = 'y' ] then diff $file $return_comp/$run/$file | \ sed -n '/version/!p' | \ sed -n '/date :/!p' | \ sed -n '/time :/!p' | \ sed -n '/Elapsed/!p' | \ sed -n '/calculating for/!p' | \ sed -n '/computation loop at/!p' > diff_tempfile else diff $file $return_comp/$run/$file > diff_tempfile fi if [ -f diff_tempfile ] then size_1=`wc -l diff_tempfile | awk '{ print $1}'` size_2=`grep '\-\-\-' diff_tempfile | wc -l | awk '{ print $1}'` size_1=$(($size_1 - $size_2)) if [ "$size_1" = "$size_2" ] || [ "$size_1" = '0' ] then rm -f diff_tempfile fi fi if [ -f diff_tempfile ] then basename="$(basename $file)" mkdir -p $output cat $file > $output/${basename}_base.txt cat $return_comp/$run/$file > $output/${basename}_comp.txt cat diff_tempfile > $output/${basename}_diff.txt echo " $file differ. " >> $home_dir/fulldiff.tmp diffFiles=`echo "$diffFiles $file"` isIdentical=0 let "numDiff += 1" rm -f diff_tempfile else echo " $file are identical$filter" >> $home_dir/fulldiff.tmp let "numSame += 1" fi # 5.c Unformatted file, use ncdump and diff else cmp=`cmp $file -s $return_comp/$run/$file # > diff_tempfile 2> dev/null` case $? in 0) echo " $file are identical (binary)" >> $home_dir/fulldiff.tmp ; let "numSame += 1" ;; 1) extension="$(echo ${file##*.})" if [ "$extension" = "nc" ] ; then mkdir -p $output basename="$(basename $file)" ncdump $file > $output/${basename}_base.txt ncdump $return_comp/$run/$file > $output/${basename}_comp.txt diff $output/${basename}_base.txt $output/${basename}_comp.txt > $output/${basename}_diff.txt if [[ $basename == rmp_* ]]; then grep -v "history" $output/${basename}_diff.txt > $output/${basename}_diff.txt fi size_1=`wc -l $output/${basename}_diff.txt | awk '{ print $1}'` if [ "$size_1" = '0' ] then rm $output/${basename}_diff.txt $output/${basename}_base.txt $output/${basename}_comp.txt echo " $file are identical (binary)" >> $home_dir/fulldiff.tmp ; let "numSame += 1" else echo " $file differ (binary)" >> $home_dir/fulldiff.tmp ; isIdentical=0; let "numDiff += 1" diffFiles=`echo "$diffFiles $file (binary)"` fi else echo " $file differ (binary)" >> $home_dir/fulldiff.tmp ; isIdentical=0; let "numDiff += 1" diffFiles=`echo "$diffFiles $file (binary)"` fi ;; *) echo " $file error in binary compare" >> $home_dir/fulldiff.tmp ; isIdentical=0 ;; esac # ... End of 5.a/b/c if tests fi else echo " skipped $file" >> $home_dir/fulldiff.tmp let "numSkipped += 1" fi fi # ... End of file loop # echo "files_2 = [$files_2]" done # 5.d Files in compare directory only for file in $files_2 do echo " $file in comp directory only" >> $home_dir/fulldiff.tmp; isIdentical=0 ; let "numInCompOnly += 1" done # --------------------------------------------------------------------------- # # 6. End of all loops outside of 'do' test # # --------------------------------------------------------------------------- # cd .. fi fi totBase=$(( $numDiff + $numSame + $numSkipped + $numNotInComp )) totComp=$(( $numDiff + $numSame + $numSkipped + $numInCompOnly )) if [[ $isIdentical -eq 1 ]] && [[ $nf_1 -ne $totBase ]] then isIdentical=3 fi case $isIdentical in 0)echo "$tst/$run ($numDiff files differ)" >> $home_dir/notIdenticalList.tmp echo "" >> $home_dir/summary.tmp echo "* test case: $tst; test run: $run" >> $home_dir/summary.tmp echo "*********************************************************" >> $home_dir/summary.tmp echo " found $nf_1 files in base directory" >> $home_dir/summary.tmp echo " found $nf_2 files in compare directory" >> $home_dir/summary.tmp echo " $numSame files are identical" >> $home_dir/summary.tmp #Clean up summary output echo " $numSkipped files skipped" >> $home_dir/summary.tmp echo " $numNotInComp files in base directory only" >> $home_dir/summary.tmp echo " $numInCompOnly files in comp directory only" >> $home_dir/summary.tmp echo " $numDiff files differ" >> $home_dir/summary.tmp [[ $numDiff -lt 10 ]] && echo $diffFiles >> $home_dir/summary.tmp ;; 1)echo "$tst/$run" >> $home_dir/isIdenticalList.tmp ;; 2)echo "$tst/$run (directory not found)" >> $home_dir/notIdenticalList.tmp ;; 3)echo "$tst/$run (file count does not match)" >> $home_dir/notIdenticalList.tmp echo "" >> $home_dir/summary.tmp echo "* test case: $tst; test run: $run" >> $home_dir/summary.tmp echo "*********************************************************" >> $home_dir/summary.tmp echo " found $nf_1 files in base directory" >> $home_dir/summary.tmp echo " found $nf_2 files in compare directory" >> $home_dir/summary.tmp echo " $numDiff files differ" >> $home_dir/summary.tmp #This needs to be copied to case 3 as well echo " $numSame files are identical" >> $home_dir/summary.tmp #Clean up summary output echo " $numSkipped files skipped" >> $home_dir/summary.tmp echo " $numNotInComp files in base directory only" >> $home_dir/summary.tmp echo " $numInCompOnly files in comp directory only" >> $home_dir/summary.tmp ;; *) esac done fi fi done # --------------------------------------------------------------------------- # # 7. End of script output # # --------------------------------------------------------------------------- # cat $home_dir/header.tmp > $home_dir/matrixCompFull.txt cat $home_dir/notIdenticalList.tmp >> $home_dir/matrixCompFull.txt cat $home_dir/isIdenticalList.tmp >> $home_dir/matrixCompFull.txt cat $home_dir/fulldiff.tmp >> $home_dir/matrixCompFull.txt cat $home_dir/header.tmp > $home_dir/matrixCompSummary.txt cat $home_dir/notIdenticalList.tmp >> $home_dir/matrixCompSummary.txt cat $home_dir/isIdenticalList.tmp >> $home_dir/matrixCompSummary.txt cat $home_dir/summary.tmp >> $home_dir/matrixCompSummary.txt for file in $(find $home_dir/output -name "*diff*") do echo "***" >> $home_dir/matrixDiff.txt echo $file >> $home_dir/matrixDiff.txt echo "***" >> $home_dir/matrixDiff.txt cat $file >> $home_dir/matrixDiff.txt echo "" >> $home_dir/matrixDiff.txt echo "" >> $home_dir/matrixDiff.txt echo "" >> $home_dir/matrixDiff.txt done rm -f $home_dir/header.tmp rm -f $home_dir/isIdenticalList.tmp rm -f $home_dir/notIdenticalList.tmp rm -f $home_dir/summary.tmp rm -f $home_dir/fulldiff.tmp echo ' ' echo " Saved summary to $home_dir/matrixCompSummary.txt" echo " Saved full output to $home_dir/matrixCompFull.txt" echo " Saved diff output to $home_dir/matrixDiff.txt" echo ' ' echo ' ' echo ' *************************************************************' echo ' *** end of WAVEWATCH III compare matrix of regression tests ***' echo ' *************************************************************' echo ' ' # --------------------------------------------------------------------------- # # End to matrix.comp # # --------------------------------------------------------------------------- #