/tags/1.0/LICENSE.pdf |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/pdf |
Property changes: |
Added: svn:mime-type |
+application/pdf |
\ No newline at end of property |
/tags/1.0/bin/lagranto |
---|
0,0 → 1,869 |
#!/bin/csh |
# --------------------------------------------------------------------- |
# Usage |
# --------------------------------------------------------------------- |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL} |
# Write usage information |
if ( (${#argv} == 0) ) then |
echo |
${LAGRANTO}/bin/lagrantohelp lagranto short |
echo |
exit 0 |
endif |
# Check whether LAGRANTO was set with setenv |
set test = `setenv | grep LAGRANTO` |
if ( "${test}" == "" ) then |
echo "---------------------------------------------------------------------" |
echo "Please set environmental variable <LAGRANTO> to your source directory" |
echo 'csh > setenv LAGRANTO ${TO_YOUR_LAGRANTO_INSTALLATION}' |
echo "---------------------------------------------------------------------" |
exit 1 |
endif |
# --------------------------------------------------------------------- |
# Set some general parameters |
# --------------------------------------------------------------------- |
# Set the prefix of the primary and secondary data files |
set charp = 'P' |
set chars = 'S' |
# Set the name of the run script |
set runscript = "runscript" |
# Remember the calling directory |
set calldir = $PWD |
# --------------------------------------------------------------------- |
# Parameter handling |
# --------------------------------------------------------------------- |
# Write title |
echo |
echo '=========================================================' |
echo ' *** START OF LAGRANTO *** ' |
echo |
# Save the complete argument list |
set lagranto_call = "$*" |
echo '---- HANDLE ARGUMENTS -----------------------------------' |
echo |
# Get fixed arguments |
if (${#argv} == 1) then |
set mode = '-open' |
set caseid = "$1" |
shift |
else if (${#argv} == 2) then |
set mode = "$1" |
set caseid = "$2" |
shift |
shift |
else |
set caseid = "$1" |
set startdate = "$2" |
set enddate = "$3" |
set startf = "$4" |
set select = "$5" |
set mode = "runlagranto" |
shift |
shift |
shift |
shift |
shift |
endif |
# Split <caseid> into base and appendix |
set casebase = `(echo $caseid | awk -F "." '{print $1}')` |
set appendix = `(echo $caseid | awk -F "." '{print $2}')` |
if ( "${appendix}" != "" ) then |
set appendix = ".${appendix}" |
endif |
# Set the directories (depending on <caseid>) |
if ( "${casebase}" == "local" ) then |
set cdfdir = $PWD |
set tradir = $PWD |
else if ( "${casebase}" == "interim" ) then |
set cdfdir = /net/dansgaard/atmosdyn/erainterim/cdf/ |
set tradir = $PWD |
else if ( "${casebase}" == "analysis" ) then |
set cdfdir = 'TO_BE_SPECIFIED' |
set tradir = $PWD |
echo "ERROR: caseid (analysis) not yet implemented" |
exit 1 |
else if ( "${casebase}" == "forecast" ) then |
set cdfdir = 'TO_BE_SPECIFIED' |
set tradir = $PWD |
echo "ERROR: caseid (forecast) not yet implemented" |
exit 1 |
else |
set cdfdir = ${HOME}/cdf/${casebase} |
set tradir = ${HOME}/tra/${casebase} |
endif |
# Change to the run directory if requested |
if ( "${mode}" == "-open" ) then |
set count = 0 |
foreach folder ( ${tradir}/ntr_*_${caseid}_* ) |
@ count = ${count} + 1 |
echo "[${count}] ${folder}" |
end |
echo |
echo "Please select directory [0...${count}]" |
set id = $< |
set count = 0 |
foreach folder ( ${tradir}/ntr_*_${caseid}_* ) |
@ count = ${count} + 1 |
if ( "${count}" == "${id}" ) then |
cd ${folder} |
xterm & |
endif |
end |
exit 0 |
endif |
# Remove the whole run directory if requested |
if ( "${mode}" == "-remove" ) then |
set count = 0 |
foreach folder ( ${tradir}/ntr_*_${caseid}_* ) |
@ count = ${count} + 1 |
echo "[${count}] ${folder}" |
end |
echo |
echo "Please select directory [0...${count}, all]" |
set id = $< |
set count = 0 |
foreach folder ( ${tradir}/ntr_*_${caseid}_* ) |
@ count = ${count} + 1 |
if ( ( "${count}" == "${id}" ) | ( "${id}" == "all" ) ) then |
\rm -r ${folder} |
endif |
end |
exit 0 |
endif |
# Show the trajectory file |
if ( "${mode}" == "-show" ) then |
set count = 0 |
foreach folder ( ${tradir}/ntr_*_${caseid}_* ) |
@ count = ${count} + 1 |
echo "[${count}] ${folder}" |
end |
echo |
echo "Please select directory [0...${count}]" |
set id = $< |
set count = 0 |
foreach folder ( ${tradir}/ntr_*_${caseid}_* ) |
@ count = ${count} + 1 |
if ( "${count}" == "${id}" ) then |
cd ${folder} |
set filename = ` sed -ne '9,9p' runscript.sh | cut -c 2-` |
${LAGRANTO}/goodies/trainfo.sh ${filename} list | less |
endif |
end |
exit 0 |
endif |
# Decide whether <select> is a file or an explicit criterion |
set flag_select = 'file' |
set test = `echo ${select} | grep ':' | wc -c` |
if ( "${test}" != "0" ) then |
set flag_select = 'criterion' |
endif |
# Decide whether <startf> is a file or an explicit criterion |
set flag_startf = 'file' |
set test = `echo ${startf} | grep ' ' | wc -c` |
if ( "${test}" != "0" ) then |
set flag_startf = 'point' |
endif |
set test = `echo ${startf} | grep '@' | wc -c` |
if ( "${test}" != "0" ) then |
set flag_startf = 'criterion' |
endif |
# Write some status information |
echo " Case ID : ${caseid}" |
echo " Start date : ${startdate}" |
echo " End date : ${enddate}" |
if ( "${flag_startf}" == "criterion" ) then |
echo " Start file : ${startf} [criterion] -> startf.criterion [file]" |
else if ( "${flag_startf}" == "file" ) then |
echo " Start points : ${startf} [file]" |
else if ( "${flag_startf}" == "point" ) then |
echo " Start points : ${startf} [point] -> startf [file]" |
endif |
if ( "${flag_select}" == "criterion" ) then |
echo " Selection : ${select} [criterion] -> selectf.criterion [file]" |
else |
echo " Selection : ${select} [file]" |
endif |
echo |
# Set defaults for flags |
set jumpflag = "" |
set tracefile = "tracevars" |
set outfile = "lsl_${startdate}" |
set keepflag = "" |
set prepflag = "" |
set logfile = "${runscript}.logfile" |
set regionf = "regionf" |
set changet = "false" |
# Handle flags |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
echo $argv[1] |
case -j |
set jumpflag = "-j" |
echo " Flag '-j [jump]' -> True " |
echo |
breaksw |
case -prep |
set prepflag = "prep" |
echo " Flag '-prep [prepare only]' -> ${prepflag} " |
echo |
breaksw |
case -noclean |
set keepflag = "keep" |
echo " Flag '-noclean [no cleaning]' -> ${keepflag} " |
echo |
breaksw |
case -o |
set outfile = $argv[2] |
echo " Flag '-o [output]' -> ${outfile} " |
echo |
breaksw |
case -v |
set tracefile = $argv[2] |
echo " Flag '-v [tracevars]' -> ${tracefile} " |
echo |
shift |
breaksw |
case -r |
set regionfile = $argv[2] |
echo " Flag '-r [regionfile]' -> ${regionfile} " |
echo |
shift |
breaksw |
case -log |
set logfile = "/dev/stdout" |
echo " Flag '-v [log]' -> ${logfile} " |
breaksw |
case -changet |
set changet = "true" |
echo " Flag '-changet [change times]'-> True " |
echo |
breaksw |
endsw |
shift; |
end |
# Decide whether a tracevars file is given or not |
if ( -f ${tradir}/${tracefile} ) then |
set flag_tracevars = 'file' |
else |
set flag_tracevars = 'nil' |
endif |
echo |
if ( "${flag_tracevars}" == "file" ) then |
echo " Trace Vars : ${tracefile} [file]" |
else |
echo " Trace Vars : [no fields are traced]" |
endif |
echo |
# Set the name of the run directory (forward/backward distinction) |
set dir = 'f' |
set range = `${LAGRANTO}/bin/gettidiff.sh ${enddate} ${startdate}` |
if ( ${range} < 0 ) then |
set dir = 'b' |
set range = `${LAGRANTO}/bin/gettidiff.sh ${startdate} ${enddate}` |
endif |
set rundir = ${tradir}/ntr_${startdate}_${dir}${range}_${caseid} |
if ( "${flag_startf}" == "criterion" ) then |
set rundir = "${rundir}_startf" |
else if ( "${flag_startf}" == "point" ) then |
set rundir = "${rundir}_startf" |
else if ( "${flag_startf}" == "file" ) then |
set rundir = "${rundir}_${startf}" |
endif |
if ( "${flag_select}" != "file" ) then |
set rundir = "${rundir}_selectf" |
else |
set rundir = "${rundir}_${select}" |
endif |
# Write directory names |
echo '---- DIRECTORIES ----------------------------------------' |
echo |
echo " CDF = ${cdfdir}" |
echo " TRA = ${tradir}" |
echo " RUN = ${rundir}" |
# Check whether CDF and TRA directories exist |
if ( ! -d ${cdfdir} ) then |
echo 'Cannot find CDF directory ... Stop' |
exit 1 |
endif |
if ( ! -d ${tradir} ) then |
echo 'Cannot find TRA directory ... Stop' |
exit 1 |
endif |
# Create the run directory |
if ( ! -d ${rundir} ) then |
mkdir ${rundir} |
endif |
if ( ! -d ${rundir} ) then |
echo 'Cannot create RUN directory ... Stop' |
exit 1 |
endif |
# --------------------------------------------------------------------- |
# Handle the time specifier - startdate, enddate |
# --------------------------------------------------------------------- |
echo |
echo '---- TIME RANGE -----------------------------------------' |
echo |
# Check format of start and end date - must be the same |
set ns=`echo $startdate | sed -e 's/_[0-9]*//' | wc -c` |
set ne=`echo $enddate | sed -e 's/_[0-9]*//' | wc -c` |
if ( $ns != $ne ) then |
echo " ERROR: start and end date must be in the same format ***" |
exit 1 |
endif |
if ( $ns != 9 ) then |
echo " ERROR: Date format must be yyyymmdd ***" |
exit 1 |
endif |
set ns=`echo $startdate | sed -e 's/[0-9]*_//' | wc -c` |
set ne=`echo $enddate | sed -e 's/[0-9]*_//' | wc -c` |
if ( $ns != $ne ) then |
echo " ERROR: start and end date must be in the same format ***" |
exit 1 |
endif |
if ( ( $ns != 5 ) & ( $ns != 3 ) ) then |
echo " ERROR: Time format must be hh(mm) ***" |
exit 1 |
endif |
# Split the start and end date into <yymmdd_hh and mm> |
set startdate_ymdh = `echo $startdate | cut -c 1-11` |
set startdate_min = `echo $startdate | cut -c 12-13` |
if ( $startdate_min == "" ) set startdate_min = 00 |
set enddate_ymdh = `echo $enddate | cut -c 1-11` |
set enddate_min = `echo $enddate | cut -c 12-13` |
if ( $enddate_min == "" ) set enddate_min = 00 |
# Get the time difference between <start_ymdh> and <end_ymdh> date |
# Decide whether trajectoriesare forward or backward |
set timediff_hh = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${startdate_ymdh}` |
if ( $timediff_hh == 0 ) then |
if ( $enddate_min > $startdate_min ) then |
set direction = f |
set idir = 1 |
else |
set direction = b |
set idir = -1 |
endif |
else if ( $timediff_hh > 0 ) then |
set direction = f |
set idir = 1 |
else |
set direction = b |
set idir = -1 |
@ timediff_hh = $idir * $timediff_hh |
endif |
# Get also minutes for time difference, if <start_min> or <end_min> != 0 |
set timediff_mm= |
if ( $startdate_min != 00 || $enddate_min != 00 ) then |
@ min = ( $enddate_min - $startdate_min ) |
if ( $min == 0 ) then |
set timediff_mm= |
else if ( $min > 0 ) then |
if ( $idir == 1 ) then |
set timediff_mm=$min |
else |
@ timediff_hh -- |
@ timediff_mm = 60 - $min |
endif |
else |
if ( $idir == 1 ) then |
@ timediff_hh -- |
@ timediff_mm = 60 + $min |
else |
@ timediff_mm = 0 - $min |
endif |
endif |
endif |
# Set the reference date equal to the startdate |
set refdate=${startdate} |
# Write status information |
echo "Time range : ${startdate} -> ${enddate}" |
if ( ${timediff_mm} != "" ) then |
echo "Time difference : ${timediff_hh} h ${timediff_mm} min" |
else |
echo "Time difference : ${timediff_hh} h" |
endif |
echo "Direction : ${direction} (${idir})" |
echo "Reference date : ${refdate}" |
# --------------------------------------------------------------------- |
# Decide which files are needed and check availability |
# --------------------------------------------------------------------- |
echo |
echo '---- INPUT FILES ----------------------------------------' |
echo |
# Change to input data (cdf) directory |
cd ${cdfdir} |
echo |
# Take the time increment from flag list ('nil', if not defined) |
set timeinc = 'nil' |
# Find a first data file (if possible corresponding to start/end date |
# If starttime is not a data time, take the first file in the direectory |
if ( $direction == "f" ) then |
set file=${charp}${startdate_ymdh} |
else |
set file=${charp}${enddate_ymdh} |
endif |
if ( ! -f $file ) then |
set file=`ls ${charp}[0-9_]*[0-9] | head -1 | sed -e 's/@//'` |
endif |
# Determine timeinc (the time difference in hours between two data file) |
# if not already defined with option -i |
if ( ${timeinc} == "nil" ) then |
set date1=`echo $file | cut -c 2-12` |
set n=`ls ${charp}[0-9_]*[0-9] | grep -n $date1 | awk -F: '{print $1}'` |
@ n ++ |
set date2=`ls ${charp}[0-9_]*[0-9] | head -$n | tail -1 | cut -c 2-12` |
set timeinc=`${LAGRANTO}/goodies/gettidiff $date2 $date1` |
endif |
if ( $timeinc == 0 ) then |
echo " ERROR: cannot set the time increment between input files ***" |
exit 1 |
endif |
# Search the first file to use |
set flag=0 |
set td= |
foreach i ( ${charp}????????_?? ) |
set date = `echo $i | cut -c 2-12` |
set td1 = `${LAGRANTO}/goodies/gettidiff ${startdate_ymdh} ${date}` |
set td2 = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${date}` |
if (( $td1 < $timeinc || $td2 < $timeinc ) && ( $td1 >= 0 || $td2 >= 0 )) then |
set datfiles=$date |
if ( $td1 < $timeinc ) set td=$td1 |
if ( $td2 < $timeinc ) set td=$td2 |
if ( ( $startdate_min > 0 ) || ( $enddate_min > 0 ) ) @ td ++ |
goto label2 |
endif |
end |
# if no P/T-files are available for the specified time period, then $td is |
# still undefined |
if ( $td == "" ) then |
echo " ERROR: no data files available for the specified time period" |
exit 1 |
endif |
# Everything is fine so far: proceed |
label2: |
# Calculate the number of further files |
@ num = ( $timediff_hh + $td ) / $timeinc + 1 |
@ dum1 = ( $num - 1 ) * $timeinc |
@ dum2 = $timediff_hh + $td |
if ( $dum1 != $dum2 ) @ num ++ |
# Get a list of all needed files |
set numfiles=$num |
set sfiles=1 |
while ( $num > 1 ) |
set date=`${LAGRANTO}/goodies/newtime $date $timeinc` |
if ( ! -f ${charp}${date} ) then |
echo " ERROR: file with primary data is missing for $date" |
exit 1 |
else if ( ! -f ${chars}${date} ) then |
set sfiles=0 |
set datfiles=`echo $datfiles $date` |
else |
set datfiles=`echo $datfiles $date` |
endif |
@ num -- |
end |
# Write some status information |
echo "Primary file prefix : ${charp}" |
echo "Secondary file prefix : ${chars}" |
echo "Time increment for input files : ${timeinc}" |
echo "# input files : ${numfiles}" |
echo "${charp} files availability : 1" |
echo "${chars} files availability : ${sfiles}" |
echo "First input file : $datfiles[1] " |
echo "Last input file : $datfiles[$numfiles] " |
# --------------------------------------------------------------------- |
# Prepare run directory - copy all needed files |
# --------------------------------------------------------------------- |
echo |
echo '---- PREPARE RUN DIRECTORY ------------------------------' |
echo |
# Change to run directory |
cd ${rundir} |
echo |
# Link cdf input files |
foreach date ( $datfiles ) |
if ( -f ${cdfdir}/${charp}${date} ) then |
if ( ! -f ${charp}${date} ) then |
ln -s ${cdfdir}/${charp}${date} ${charp}${date} |
echo "Linking ${date} " |
else |
echo "Existing ${date} " |
endif |
endif |
if ( -f ${cdfdir}/${chars}${date} ) then |
if ( ! -f ${chars}${date} ) then |
ln -sf ${cdfdir}/${chars}${date} ${chars}${date} |
endif |
endif |
end |
# Change times on netCDF files relative to reference date |
if ( "${changet}" == "true" ) then |
echo |
foreach i ( $datfiles ) |
${LAGRANTO}/goodies/changet.sh ${refdate} ${charp}${i} |
end |
if ( ${sfiles} == 1 ) then |
echo |
foreach i ( $datfiles ) |
${LAGRANTO}/goodies/changet.sh ${refdate} ${chars}${i} |
end |
endif |
endif |
# Get the constants file for each file |
set first = 1 |
foreach date ( $datfiles ) |
set cstname = `ncdump -h ${charp}${date} | grep constants_file_name` |
set cstname = `echo \'${cstname}\' | awk -F\" '{print $2}'` |
if ( -f ${cdfdir}/${cstname} ) then |
if ( ! -f ${cstname} ) then |
ln -s ${cdfdir}/${cstname} ${cstname} |
echo "Linking constants file ${cstname}" |
set first = 0 |
else if ( "${first}" == "1" ) then |
echo "Existing constants file ${cstname}" |
set first = 0 |
endif |
endif |
end |
# Copy the tracevars file |
if ( "${flag_tracevars}" == "file" ) then |
if ( -f ${tradir}/${tracefile} ) then |
\cp ${tradir}/${tracefile} . |
endif |
endif |
# Copy the start file/criterion |
if ( "${flag_startf}" == "criterion" ) then |
\rm -f startf.criterion |
echo ${startf} > startf.criterion |
set startf = "startf.criterion" |
else if ( "${flag_startf}" == "file" ) then |
if ( -f ${tradir}/${startf} ) then |
\cp ${tradir}/${startf} . |
endif |
else if ( "${flag_startf}" == "point" ) then |
\rm -f startf |
echo ${startf} > startf |
set startf = "startf" |
set flag_startf = "file" |
endif |
# Copy the select file/criterion |
if ( "${flag_select}" == "criterion" ) then |
\rm -f select.criterion |
echo ${select} > select.criterion |
set select = "select.criterion" |
else |
if ( -f ${tradir}/${select} ) then |
\cp ${tradir}/${select} . |
endif |
endif |
# --------------------------------------------------------------------- |
# Prepare the run script |
# --------------------------------------------------------------------- |
echo |
echo '---- PREPARE RUN SCRIPT ---------------------------------' |
echo |
# Remove runscript if it already exists |
if ( -f ${runscript}.sh ) then |
\rm -f ${runscript}.sh |
endif |
# Write header |
echo '#\!/bin/csh' >! ${runscript}.sh |
echo "#" >> ${runscript}.sh |
echo "#----- Calling command" >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
echo "# lagranto ${lagranto_call} " >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
echo "#----- Output file " >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
echo "# ${outfile} " >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
# Decide whether <create_startf> has to be run |
if ( "${flag_startf}" == "criterion" ) then |
echo "#------ Run <create_startf>" >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
echo ${LAGRANTO}/bin/create_startf.sh ${startdate} startf \"`cat startf.criterion`\" -t ${tracefile} -regionf ${regionf} >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
set startf = "startf" |
endif |
# Check whether startfile is ready |
cat >> ${runscript}.sh <<EOF |
#------ Abort if no startf is available |
# |
if ( ! -f ${startf} ) then |
echo " ERROR: no start file available .... Stop" |
exit 1 |
endif |
EOF |
# Decide wich intermediate format is used (needed for efficient communication between different programs) |
set iform1 = "" |
set iform2 = "" |
if ( "${tracefile}" != "" ) set iform1 = ".4" |
if ( "${select}" != "nil" ) set iform2 = ".4" |
# Remove all trajectory files which might already be there |
cat >> ${runscript}.sh <<EOF |
# |
#------ Remove existing trajectory files |
# |
if ( -f ${outfile}${iform1} ) then |
\rm -f ${outfile}${iform1} |
endif |
if ( -f ${outfile}${iform2} ) then |
\rm -f ${outfile}${iform2} |
endif |
if ( -f ${outfile} ) then |
\rm -f ${outfile} |
endif |
EOF |
# Write call to <caltra> into runscript |
echo "#" >> ${runscript}.sh |
echo "#------ Run <caltra>" >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
echo ${LAGRANTO}/bin/caltra.sh ${startdate} ${enddate} startf ${outfile}${iform1} ${jumpflag} >> ${runscript}.sh |
# Check whether caltra was successful |
cat >> ${runscript}.sh <<EOF |
# |
#------ Abort if caltra was not successful |
# |
if ( ! -f ${outfile}${iform1} ) then |
echo " ERROR: caltra failed .... Stop" |
exit 1 |
endif |
EOF |
# Decide whether <trace> has to be run |
if ( "${tracefile}" != "" ) then |
echo "#" >> ${runscript}.sh |
echo "#------ Run <trace>" >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
echo ${LAGRANTO}/bin/trace.sh ${outfile}${iform1} ${outfile}${iform2} -v ${tracefile} >> ${runscript}.sh |
endif |
# Check whether trace was successful |
cat >> ${runscript}.sh <<EOF |
# |
#------ Abort if trace was not successful |
# |
if ( ! -f ${outfile}${iform2} ) then |
echo " ERROR: trace failed .... Stop" |
exit 1 |
endif |
EOF |
# Decide whether <select> has to be run |
if ( "${select}" != "nil" ) then |
echo "#" >> ${runscript}.sh |
echo "#------ Run <select>" >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
echo ${LAGRANTO}/bin/select.sh ${outfile}${iform2} ${outfile} \"`cat ${select}`\" -regionf ${regionf} >> ${runscript}.sh |
echo "#" >> ${runscript}.sh |
endif |
# Show runscript on screen |
more ${runscript}.sh |
# Change runscript to executable |
chmod u+x ${runscript}.sh |
# Decide whether to stop at this place (only preparation for Lagranto run) |
if ( "${prepflag}" == "prep" ) then |
echo |
echo '---- READY TO RUN ----- ---------------------------------' |
echo |
echo " Would you like to change to the rundirectory [y/n] " |
set id = $< |
if ( ( "${id}" == "y" ) | ( "${id}" == "Y" ) ) then |
cd ${rundir} |
xterm & |
endif |
exit 0 |
endif |
# Define environment variable for the case |
echo |
echo '---- REMEMBER MOST RECENT CALL --------------------------' |
echo |
cd ${calldir} |
if ( -f lagranto.param ) \rm lagranto.param |
echo "${rundir}" >! lagranto.param |
echo "${outfile}" >> lagranto.param |
cd ${rundir} |
echo |
echo " run directory + output file -> lagranto.param" |
# --------------------------------------------------------------------- |
# Run lagranto |
# --------------------------------------------------------------------- |
echo |
echo '---- RUN LAGRANTO ---------------------------------------' |
echo |
if ( "${logfile}" != "/dev/stdout" ) then |
echo "log goes to ${logfile}" |
endif |
# Remove logfile |
if ( "${logfile}" != "/dev/stdout" ) then |
\rm -f ${logfile} |
endif |
# Run it |
${rundir}/${runscript}.sh > ${logfile} |
# Check for errors in logfile |
if ( "${logfile}" != "/dev/stdout" ) then |
grep ERROR ${logfile} |
endif |
# --------------------------------------------------------------------- |
# Make clean and finish lagranto run |
# --------------------------------------------------------------------- |
# Remove unneeded files |
\rm -f fort.9 |
# Remove files if requested |
if ( "${keepflag}" != "keep" ) then |
echo |
echo '---- MAKING CLEAN ---------------------------------------' |
echo |
cd ${rundir} |
set runscript = "${runscript}.sh" |
foreach file ( `\ls -L1` ) |
set id = "0" |
if ( "${file}" == "${outfile}" ) set id="1" |
if ( "${file}" == "${runscript}" ) set id="1" |
if ( "${file}" == "${logfile}" ) set id="1" |
if ( "${id}" == "0" ) \rm -f ${file} |
end |
endif |
# Everything is fine! |
echo |
echo ' *** END OF LAGRANTO *** ' |
echo '=========================================================' |
echo |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/bin/lagrantohelp |
---|
0,0 → 1,102 |
#!/bin/csh |
# --------------------------------------------------------------------------- |
# Set parameters - handle arguments |
# --------------------------------------------------------------------------- |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL} |
set dir = ${LAGRANTO}/docu/ |
set viewer = okular |
set nargv = ${#argv} |
if ( (${#argv} == 0) ) then |
nroff -man ${dir}/man/lagrantohelp.0 | less |
exit 0 |
endif |
if ( "${nargv}" == "1" ) then |
set mode = "$1" |
set verb = "long" |
else if ( "${nargv}" == "2" ) then |
set mode = "$1" |
set verb = "$2" |
endif |
# --------------------------------------------------------------------------- |
# Tutorial, Reference, Presentation, Future Plans |
# --------------------------------------------------------------------------- |
if ( "$mode" == "future" ) then |
nroff -man ${dir}/man/futureplans.0 | less |
exit 0 |
endif |
if ( "$mode" == "tutorial" ) then |
${viewer} ${dir}/tutorial/tutorial.pdf |
exit 0 |
endif |
if ( "$mode" == "reference" ) then |
${viewer} ${dir}/reference/reference.pdf |
exit 0 |
endif |
if ( "$mode" == "presentation" ) then |
${viewer} ${dir}/presentation/presentation.pdf |
exit 0 |
endif |
# --------------------------------------------------------------------------- |
# Manual |
# --------------------------------------------------------------------------- |
if ( "${verb}" == "long" ) then |
nroff -man ${dir}/man/${mode}.0 | less |
exit 0 |
endif |
if ( "${verb}" == "short" ) then |
echo |
nroff -man ${dir}/man/${mode}.0 | grep -A 1 SYNOPSIS |
echo |
set i0 = `nroff -man ${dir}/man/${mode}.0 | grep -n EXAMPLES | awk -F ":" '{print $1}'` |
set i1 = `nroff -man ${dir}/man/${mode}.0 | grep -n AUTHOR | awk -F ":" '{print $1}'` |
set i1 = `echo "$i1 - 1" | bc` |
if ( ( "$i0" != "" ) & ( "$i1" != "" ) ) then |
nroff -man ${dir}/man/${mode}.0 | sed -ne ${i0},${i1}p |
endif |
endif |
if ( "${verb}" == "synopsis" ) then |
echo |
nroff -man ${dir}/man/${mode}.0 | grep -A 1 SYNOPSIS |
echo |
exit 0 |
endif |
if ( "${verb}" == "parameter" ) then |
set i0 = `nroff -man ${dir}/man/${mode}.0 | grep -n PARAMETERS | awk -F ":" '{print $1}'` |
set i1 = `nroff -man ${dir}/man/${mode}.0 | grep -n EXAMPLES | awk -F ":" '{print $1}'` |
set i1 = `echo "$i1 - 1" | bc` |
echo $i0 |
echo $i1 |
if ( ( "$i0" != "" ) & ( "$i1" != "" ) ) then |
nroff -man ${dir}/man/${mode}.0 | sed -ne ${i0},${i1}p |
endif |
exit 0 |
endif |
if ( "${verb}" == "examples" ) then |
set i0 = `nroff -man ${dir}/man/${mode}.0 | grep -n EXAMPLES | awk -F ":" '{print $1}'` |
set i1 = `nroff -man ${dir}/man/${mode}.0 | grep -n AUTHOR | awk -F ":" '{print $1}'` |
set i1 = `echo "$i1 - 1" | bc` |
if ( ( "$i0" != "" ) & ( "$i1" != "" ) ) then |
nroff -man ${dir}/man/${mode}.0 | sed -ne ${i0},${i1}p |
endif |
exit 0 |
endif |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/caltra/caltra.f |
---|
0,0 → 1,943 |
PROGRAM caltra |
C ******************************************************************** |
C * * |
C * Calculates trajectories * |
C * * |
C * Heini Wernli first version: April 1993 * |
C * Michael Sprenger major upgrade: 2008-2009 * |
C * * |
C ******************************************************************** |
implicit none |
c -------------------------------------------------------------------- |
c Declaration of parameters |
c -------------------------------------------------------------------- |
c Maximum number of levels for input files |
integer nlevmax |
parameter (nlevmax=100) |
c Maximum number of input files (dates, length of trajectories) |
integer ndatmax |
parameter (ndatmax=500) |
c Numerical epsilon (for float comparison) |
real eps |
parameter (eps=0.001) |
c Distance in m between 2 lat circles |
real deltay |
parameter (deltay=1.112E5) |
c Numerical method for the integration (0=iterative Euler, 1=Runge-Kutta) |
integer imethod |
parameter (imethod=1) |
c Number of iterations for iterative Euler scheme |
integer numit |
parameter (numit=3) |
c Input and output format for trajectories (see iotra.f) |
integer inpmode |
integer outmode |
c Filename prefix (typically 'P') |
character*1 prefix |
parameter (prefix='P') |
c -------------------------------------------------------------------- |
c Declaration of variables |
c -------------------------------------------------------------------- |
c Input parameters |
integer fbflag ! Flag for forward/backward mode |
integer numdat ! Number of input files |
character*11 dat(ndatmax) ! Dates of input files |
real timeinc ! Time increment between input files |
real per ! Periodicity (=0 if none) |
integer ntra ! Number of trajectories |
character*80 cdfname ! Name of output files |
real ts ! Time step |
real tst,ten ! Shift of start and end time relative to first data file |
integer deltout ! Output time interval (in minutes) |
integer jflag ! Jump flag (if =1 ground-touching trajectories reenter atmosphere) |
real wfactor ! Factor for vertical velocity field |
character*80 strname ! File with start positions |
character*80 timecheck ! Either 'yes' or 'no' |
c Trajectories |
integer ncol ! Number of columns for insput trajectories |
real,allocatable, dimension (:,:,:) :: trainp ! Input start coordinates (ntra,1,ncol) |
real,allocatable, dimension (:,:,:) :: traout ! Output trajectories (ntra,ntim,4) |
integer reftime(6) ! Reference date |
character*80 vars(200) ! Field names |
real,allocatable, dimension (:) :: xx0,yy0,pp0 ! Position of air parcels |
integer,allocatable, dimension (:) :: leftflag ! Flag for domain-leaving |
real xx1,yy1,pp1 ! Updated position of air parcel |
integer leftcount ! Number of domain leaving trajectories |
integer ntim ! Number of output time steps |
c Meteorological fields |
real,allocatable, dimension (:) :: spt0,spt1 ! Surface pressure |
real,allocatable, dimension (:) :: uut0,uut1 ! Zonal wind |
real,allocatable, dimension (:) :: vvt0,vvt1 ! Meridional wind |
real,allocatable, dimension (:) :: wwt0,wwt1 ! Vertical wind |
real,allocatable, dimension (:) :: p3t0,p3t1 ! 3d-pressure |
c Grid description |
real pollon,pollat ! Longitude/latitude of pole |
real ak(nlevmax) ! Vertical layers and levels |
real bk(nlevmax) |
real xmin,xmax ! Zonal grid extension |
real ymin,ymax ! Meridional grid extension |
integer nx,ny,nz ! Grid dimensions |
real dx,dy ! Horizontal grid resolution |
integer hem ! Flag for hemispheric domain |
real mdv ! Missing data value |
c Auxiliary variables |
real delta,rd |
integer itm,iloop,i,j,k,filo,lalo |
integer ierr,stat |
integer cdfid,fid |
real tstart,time0,time1,time |
real reltpos0,reltpos1 |
real xind,yind,pind,pp,sp,stagz |
character*80 filename,varname |
integer reftmp(6) |
character ch |
real frac,tload |
integer itim |
integer wstep |
real x1,y1 |
c Externals |
real int_index4 |
external int_index4 |
c -------------------------------------------------------------------- |
c Start of program, Read parameters |
c -------------------------------------------------------------------- |
c Write start message |
print*,'=========================================================' |
print*,' *** START OF PROGRAM CALTRA ***' |
print* |
c Open the parameter file |
open(9,file='caltra.param') |
c Read flag for forward/backward mode (fbflag) |
read(9,*) fbflag |
c Read number of input files (numdat) |
read(9,*) numdat |
if (numdat.gt.ndatmax) then |
print*,' ERROR: too many input files ',numdat,ndatmax |
goto 993 |
endif |
c Read list of input dates (dat, sort depending on forward/backward mode) |
if (fbflag.eq.1) then |
do itm=1,numdat |
read(9,'(a11)') dat(itm) |
enddo |
else |
do itm=numdat,1,-1 |
read(9,'(a11)') dat(itm) |
enddo |
endif |
c Read time increment between input files (timeinc) |
read(9,*) timeinc |
C Read if data domain is periodic and its periodicity |
read(9,*) per |
c Read the number of trajectories and name of position file |
read(9,*) strname |
read(9,*) ntra |
read(9,*) ncol |
if (ntra.eq.0) goto 991 |
C Read the name of the output trajectory file and set the constants file |
read(9,*) cdfname |
C Read the timestep for trajectory calculation (convert from minutes to hours) |
read(9,*) ts |
ts=ts/60. |
C Read shift of start and end time relative to first data file |
read(9,*) tst |
read(9,*) ten |
C Read output time interval (in minutes) |
read(9,*) deltout |
C Read jumpflag (if =1 ground-touching trajectories reenter the atmosphere) |
read(9,*) jflag |
C Read factor for vertical velocity field |
read(9,*) wfactor |
c Read the reference time and the time range |
read(9,*) reftime(1) ! year |
read(9,*) reftime(2) ! month |
read(9,*) reftime(3) ! day |
read(9,*) reftime(4) ! hour |
read(9,*) reftime(5) ! min |
read(9,*) reftime(6) ! time range (in min) |
c Read flag for 'no time check' |
read(9,*) timecheck |
c Close the input file |
close(9) |
c Calculate the number of output time steps |
ntim = abs(reftime(6)/deltout) + 1 |
c Set the formats of the input and output files |
call mode_tra(inpmode,strname) |
call mode_tra(outmode,cdfname) |
if (outmode.eq.-1) outmode=1 |
c Write some status information |
print*,'---- INPUT PARAMETERS -----------------------------------' |
print* |
print*,' Forward/Backward : ',fbflag |
print*,' #input files : ',numdat |
print*,' First/last input file : ',trim(dat(1)),' ... ', |
> trim(dat(numdat)) |
print*,' time increment : ',timeinc |
print*,' Output file : ',trim(cdfname) |
print*,' Time step (min) : ',60.*ts |
write(*,'(a27,f7.2,f7.2)') ' Time shift (start,end) : ',tst,ten |
print*,' Output time interval : ',deltout |
print*,' Jump flag : ',jflag |
print*,' Vertical wind (scale) : ',wfactor |
print*,' Trajectory pos file : ',trim(strname) |
print*,' # of trajectories : ',ntra |
print*,' # of output timesteps : ',ntim |
if ( inpmode.eq.-1) then |
print*,' Input format : (lon,lat,p)-list' |
else |
print*,' Input format : ',inpmode |
endif |
print*,' Output format : ',outmode |
print*,' Periodicity : ',per |
print*,' Time check : ',trim(timecheck) |
print* |
print*,'---- FIXED NUMERICAL PARAMETERS -------------------------' |
print* |
print*,' Numerical scheme : ',imethod |
print*,' Number of iterations : ',numit |
print*,' Filename prefix : ',prefix |
print*,' Missing data value : ',mdv |
print* |
c -------------------------------------------------------------------- |
c Read grid parameters, checks and allocate memory |
c -------------------------------------------------------------------- |
c Read the constant grid parameters (nx,ny,nz,xmin,xmax,ymin,ymax,pollon,pollat) |
c The negative <-fid> of the file identifier is used as a flag for parameter retrieval |
filename = prefix//dat(1) |
varname = 'U' |
nx = 1 |
ny = 1 |
nz = 1 |
tload = -tst |
call input_open (fid,filename) |
call input_grid (-fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tload,pollon,pollat,rd,rd,nz,rd,rd,rd,timecheck) |
call input_close(fid) |
C Check if the number of levels is too large |
if (nz.gt.nlevmax) goto 993 |
C Set logical flag for periodic data set (hemispheric or not) |
hem = 0 |
if (per.eq.0.) then |
delta=xmax-xmin-360. |
if (abs(delta+dx).lt.eps) then ! Program aborts: arrays must be closed |
goto 992 |
else if (abs(delta).lt.eps) then ! Periodic and hemispheric |
hem=1 |
per=360. |
endif |
else ! Periodic and hemispheric |
hem=1 |
endif |
C Allocate memory for some meteorological arrays |
allocate(spt0(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array spt0 ***' ! Surface pressure |
allocate(spt1(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array spt1 ***' |
allocate(uut0(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array uut0 ***' ! Zonal wind |
allocate(uut1(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array uut1 ***' |
allocate(vvt0(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array vvt0 ***' ! Meridional wind |
allocate(vvt1(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array vvt1 ***' |
allocate(wwt0(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array wwt0 ***' ! Vertical wind |
allocate(wwt1(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array wwt1 ***' |
allocate(p3t0(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t0 ***' ! Pressure |
allocate(p3t1(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t1 ***' |
C Get memory for trajectory arrays |
allocate(trainp(ntra,1,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array trainp ***' ! Input start coordinates |
allocate(traout(ntra,ntim,4),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array traout ***' ! Output trajectories |
allocate(xx0(ntra),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array xx0 ***' ! X position (longitude) |
allocate(yy0(ntra),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array yy0 ***' ! Y position (latitude) |
allocate(pp0(ntra),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array pp0 ***' ! Pressure |
allocate(leftflag(ntra),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array leftflag ***' ! Leaving-domain flag |
c Write some status information |
print*,'---- CONSTANT GRID PARAMETERS ---------------------------' |
print* |
print*,' xmin,xmax : ',xmin,xmax |
print*,' ymin,ymax : ',ymin,ymax |
print*,' dx,dy : ',dx,dy |
print*,' pollon,pollat : ',pollon,pollat |
print*,' nx,ny,nz : ',nx,ny,nz |
print*,' per, hem : ',per,hem |
print* |
c -------------------------------------------------------------------- |
c Initialize the trajectory calculation |
c -------------------------------------------------------------------- |
c Read start coordinates from file - Format (lon,lat,lev) |
if (inpmode.eq.-1) then |
open(fid,file=strname) |
do i=1,ntra |
read(fid,*) xx0(i),yy0(i),pp0(i) |
enddo |
close(fid) |
c Read start coordinates from trajectory file - check consistency of ref time |
else |
call ropen_tra(cdfid,strname,ntra,1,ncol,reftmp,vars,inpmode) |
call read_tra (cdfid,trainp,ntra,1,ncol,inpmode) |
do i=1,ntra |
time = trainp(i,1,1) |
xx0(i) = trainp(i,1,2) |
yy0(i) = trainp(i,1,3) |
pp0(i) = trainp(i,1,4) |
enddo |
call close_tra(cdfid,inpmode) |
if ( ( reftime(1).ne.reftmp(1) ).or. |
> ( reftime(2).ne.reftmp(2) ).or. |
> ( reftime(3).ne.reftmp(3) ).or. |
> ( reftime(4).ne.reftmp(4) ).or. |
> ( reftime(5).ne.reftmp(5) ) ) |
> then |
print*,' WARNING: Inconsistent reference times' |
write(*,'(5i8)') (reftime(i),i=1,5) |
write(*,'(5i8)') (reftmp (i),i=1,5) |
print*,'Enter a key to proceed...' |
stop |
endif |
endif |
c Set sign of time range |
reftime(6) = fbflag * reftime(6) |
c Write some status information |
print*,'---- REFERENCE DATE---------- ---------------------------' |
print* |
print*,' Reference time (year) :',reftime(1) |
print*,' (month) :',reftime(2) |
print*,' (day) :',reftime(3) |
print*,' (hour) :',reftime(4) |
print*,' (min) :',reftime(5) |
print*,' Time range :',reftime(6),' min' |
print* |
C Save starting positions |
itim = 1 |
do i=1,ntra |
traout(i,itim,1) = 0. |
traout(i,itim,2) = xx0(i) |
traout(i,itim,3) = yy0(i) |
traout(i,itim,4) = pp0(i) |
enddo |
c Init the flag and the counter for trajectories leaving the domain |
leftcount=0 |
do i=1,ntra |
leftflag(i)=0 |
enddo |
C Convert time shifts <tst,ten> from <hh.mm> into fractional time |
call hhmm2frac(tst,frac) |
tst = frac |
call hhmm2frac(ten,frac) |
ten = frac |
c Check that all starting positions are above topography |
varname = 'P' |
filename = prefix//dat(1) |
call input_open (fid,filename) |
call input_grid |
> (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck) |
call input_close(fid) |
do i=1,ntra |
C Interpolate surface pressure to actual position (from first input file) |
x1 = xx0(i) |
y1 = yy0(i) |
call get_index4 (xind,yind,pind,x1,y1,1050.,0., |
> p3t1,p3t1,spt1,spt1,3, |
> nx,ny,nz,xmin,ymin,dx,dy,mdv) |
sp = int_index4 (spt1,spt1,nx,ny,1,xind,yind,1.,0.,mdv) |
c Decide whether to keep the trajectory |
if ( pp0(i).gt.sp ) then |
write(*,'(a30,4f10.2)') |
> 'WARNING: starting point below topography ', |
> xx0(i),yy0(i),pp0(i),sp |
leftflag(i) = 1 |
endif |
enddo |
c ----------------------------------------------------------------------- |
c Loop to calculate trajectories |
c ----------------------------------------------------------------------- |
c Write some status information |
print* |
print*,'---- TRAJECTORIES ----------- ---------------------------' |
print* |
C Set the time for the first data file (depending on forward/backward mode) |
if (fbflag.eq.1) then |
tstart = -tst |
else |
tstart = tst |
endif |
c Set the minute counter for output |
wstep = 0 |
c Read wind fields and vertical grid from first file |
filename = prefix//dat(1) |
call frac2hhmm(tstart,tload) |
write(*,'(a16,a20,f7.2)') ' (file,time) : ', |
> trim(filename),tload |
call input_open (fid,filename) |
varname='U' ! U |
call input_wind |
> (fid,varname,uut1,tload,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
varname='V' ! V |
call input_wind |
> (fid,varname,vvt1,tload,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
varname='OMEGA' ! OMEGA |
call input_wind |
> (fid,varname,wwt1,tload,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_grid ! GRID |
> (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck) |
call input_close(fid) |
c Loop over all input files (time step is <timeinc>) |
do itm=1,numdat-1 |
c Calculate actual and next time |
time0 = tstart+real(itm-1)*timeinc*fbflag |
time1 = time0+timeinc*fbflag |
c Copy old velocities and pressure fields to new ones |
do i=1,nx*ny*nz |
uut0(i)=uut1(i) |
vvt0(i)=vvt1(i) |
wwt0(i)=wwt1(i) |
p3t0(i)=p3t1(i) |
enddo |
do i=1,nx*ny |
spt0(i)=spt1(i) |
enddo |
c Read wind fields and surface pressure at next time |
filename = prefix//dat(itm+1) |
call frac2hhmm(time1,tload) |
write(*,'(a16,a20,f7.2)') ' (file,time) : ', |
> trim(filename),tload |
call input_open (fid,filename) |
varname='U' ! U |
call input_wind |
> (fid,varname,uut1,tload,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
varname='V' ! V |
call input_wind |
> (fid,varname,vvt1,tload,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
varname='OMEGA' ! OMEGA |
call input_wind |
> (fid,varname,wwt1,tload,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_grid ! GRID |
> (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz,timecheck) |
call input_close(fid) |
C Determine the first and last loop indices |
if (numdat.eq.2) then |
filo = nint(tst/ts)+1 |
lalo = nint((timeinc-ten)/ts) |
elseif ( itm.eq.1 ) then |
filo = nint(tst/ts)+1 |
lalo = nint(timeinc/ts) |
else if (itm.eq.numdat-1) then |
filo = 1 |
lalo = nint((timeinc-ten)/ts) |
else |
filo = 1 |
lalo = nint(timeinc/ts) |
endif |
c Split the interval <timeinc> into computational time steps <ts> |
do iloop=filo,lalo |
C Calculate relative time position in the interval timeinc (0=beginning, 1=end) |
reltpos0 = ((real(iloop)-1.)*ts)/timeinc |
reltpos1 = real(iloop)*ts/timeinc |
c Timestep for all trajectories |
do i=1,ntra |
C Check if trajectory has already left the data domain |
if (leftflag(i).ne.1) then |
c Iterative Euler timestep (x0,y0,p0 -> x1,y1,p1) |
if (imethod.eq.1) then |
call euler( |
> xx1,yy1,pp1,leftflag(i), |
> xx0(i),yy0(i),pp0(i),reltpos0,reltpos1, |
> ts*3600,numit,jflag,mdv,wfactor,fbflag, |
> spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1, |
> xmin,ymin,dx,dy,per,hem,nx,ny,nz) |
c Runge-Kutta timestep (x0,y0,p0 -> x1,y1,p1) |
else if (imethod.eq.2) then |
call runge( |
> xx1,yy1,pp1,leftflag(i), |
> xx0(i),yy0(i),pp0(i),reltpos0,reltpos1, |
> ts*3600,numit,jflag,mdv,wfactor,fbflag, |
> spt0,spt1,p3t0,p3t1,uut0,uut1,vvt0,vvt1,wwt0,wwt1, |
> xmin,ymin,dx,dy,per,hem,nx,ny,nz) |
endif |
c Update trajectory position, or increase number of trajectories leaving domain |
if (leftflag(i).eq.1) then |
leftcount=leftcount+1 |
if ( leftcount.lt.10 ) then |
print*,' -> Trajectory ',i,' leaves domain' |
elseif ( leftcount.eq.10 ) then |
print*,' -> N>=10 trajectories leave domain' |
endif |
else |
xx0(i)=xx1 |
yy0(i)=yy1 |
pp0(i)=pp1 |
endif |
c Trajectory has already left data domain (mark as <mdv>) |
else |
xx0(i)=mdv |
yy0(i)=mdv |
pp0(i)=mdv |
endif |
enddo |
C Save positions only every deltout minutes |
delta = aint(iloop*60*ts/deltout)-iloop*60*ts/deltout |
if (abs(delta).lt.eps) then |
c wstep = wstep + abs(ts) |
c if ( mod(wstep,deltout).eq.0 ) then |
time = time0+reltpos1*timeinc*fbflag |
itim = itim + 1 |
do i=1,ntra |
call frac2hhmm(time,tload) |
traout(i,itim,1) = tload |
traout(i,itim,2) = xx0(i) |
traout(i,itim,3) = yy0(i) |
traout(i,itim,4) = pp0(i) |
enddo |
endif |
enddo |
enddo |
c Write trajectory file |
vars(1) ='time' |
vars(2) ='lon' |
vars(3) ='lat' |
vars(4) ='p' |
call wopen_tra(cdfid,cdfname,ntra,ntim,4,reftime,vars,outmode) |
call write_tra(cdfid,traout,ntra,ntim,4,outmode) |
call close_tra(cdfid,outmode) |
c Write some status information, and end of program message |
print* |
print*,'---- STATUS INFORMATION --------------------------------' |
print* |
print*,' #leaving domain ', leftcount |
print*,' #staying in domain ', ntra-leftcount |
print* |
print*,' *** END OF PROGRAM CALTRA ***' |
print*,'=========================================================' |
stop |
c ------------------------------------------------------------------ |
c Exception handling |
c ------------------------------------------------------------------ |
991 write(*,*) '*** ERROR: all start points outside the data domain' |
call exit(1) |
992 write(*,*) '*** ERROR: close arrays on files (prog. closear)' |
call exit(1) |
993 write(*,*) '*** ERROR: problems with array size' |
call exit(1) |
end |
c ******************************************************************* |
c * Time step : either Euler or Runge-Kutta * |
c ******************************************************************* |
C Time-step from (x0,y0,p0) to (x1,y1,p1) |
C |
C (x0,y0,p0) input coordinates (long,lat,p) for starting point |
C (x1,y1,p1) output coordinates (long,lat,p) for end point |
C deltat input timestep in seconds |
C numit input number of iterations |
C jump input flag (=1 trajectories don't enter the ground) |
C left output flag (=1 if trajectory leaves data domain) |
c ------------------------------------------------------------------- |
c Iterative Euler time step |
c ------------------------------------------------------------------- |
subroutine euler(x1,y1,p1,left,x0,y0,p0,reltpos0,reltpos1, |
> deltat,numit,jump,mdv,wfactor,fbflag, |
> spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,wwt0,wwt1, |
> xmin,ymin,dx,dy,per,hem,nx,ny,nz) |
implicit none |
c Declaration of subroutine parameters |
integer nx,ny,nz |
real x1,y1,p1 |
integer left |
real x0,y0,p0 |
real reltpos0,reltpos1 |
real deltat |
integer numit |
integer jump |
real wfactor |
integer fbflag |
real spt0(nx*ny) ,spt1(nx*ny) |
real uut0(nx*ny*nz),uut1(nx*ny*nz) |
real vvt0(nx*ny*nz),vvt1(nx*ny*nz) |
real wwt0(nx*ny*nz),wwt1(nx*ny*nz) |
real p3d0(nx*ny*nz),p3d1(nx*ny*nz) |
real xmin,ymin,dx,dy |
real per |
integer hem |
real mdv |
c Numerical and physical constants |
real deltay |
parameter (deltay=1.112E5) ! Distance in m between 2 lat circles |
real pi |
parameter (pi=3.1415927) ! Pi |
c Auxiliary variables |
real xmax,ymax |
real xind,yind,pind |
real u0,v0,w0,u1,v1,w1,u,v,w,sp |
integer icount |
character ch |
c Externals |
real int_index4 |
external int_index4 |
c Reset the flag for domain-leaving |
left=0 |
c Set the esat-north bounray of the domain |
xmax = xmin+real(nx-1)*dx |
ymax = ymin+real(ny-1)*dy |
C Interpolate wind fields to starting position (x0,y0,p0) |
call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0, |
> p3d0,p3d1,spt0,spt1,3, |
> nx,ny,nz,xmin,ymin,dx,dy,mdv) |
u0 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos0,mdv) |
v0 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos0,mdv) |
w0 = int_index4(wwt0,wwt1,nx,ny,nz,xind,yind,pind,reltpos0,mdv) |
c Force the near-surface wind to zero |
if (pind.lt.1.) w0=w0*pind |
C For first iteration take ending position equal to starting position |
x1=x0 |
y1=y0 |
p1=p0 |
C Iterative calculation of new position |
do icount=1,numit |
C Calculate new winds for advection |
call get_index4 (xind,yind,pind,x1,y1,p1,reltpos1, |
> p3d0,p3d1,spt0,spt1,3, |
> nx,ny,nz,xmin,ymin,dx,dy,mdv) |
u1 = int_index4(uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos1,mdv) |
v1 = int_index4(vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos1,mdv) |
w1 = int_index4(wwt0,wwt1,nx,ny,nz,xind,yind,pind,reltpos1,mdv) |
c Force the near-surface wind to zero |
if (pind.lt.1.) w1=w1*pind |
c Get the new velocity in between |
u=(u0+u1)/2. |
v=(v0+v1)/2. |
w=(w0+w1)/2. |
C Calculate new positions |
x1 = x0 + fbflag*u*deltat/(deltay*cos(y0*pi/180.)) |
y1 = y0 + fbflag*v*deltat/deltay |
p1 = p0 + fbflag*wfactor*w*deltat/100. |
c Handle pole problems (crossing and near pole trajectory) |
if ((hem.eq.1).and.(y1.gt.90.)) then |
y1=180.-y1 |
x1=x1+per/2. |
endif |
if ((hem.eq.1).and.(y1.lt.-90.)) then |
y1=-180.-y1 |
x1=x1+per/2. |
endif |
if (y1.gt.89.99) then |
y1=89.99 |
endif |
c Handle crossings of the dateline |
if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then |
x1=xmin+amod(x1-xmin,per) |
endif |
if ((hem.eq.1).and.(x1.lt.xmin)) then |
x1=xmin+per+amod(x1-xmin,per) |
endif |
C Interpolate surface pressure to actual position |
call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1, |
> p3d0,p3d1,spt0,spt1,3, |
> nx,ny,nz,xmin,ymin,dx,dy,mdv) |
sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1.,reltpos1,mdv) |
c Handle trajectories which cross the lower boundary (jump flag) |
if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10. |
C Check if trajectory leaves data domain |
if ( ( (hem.eq.0).and.(x1.lt.xmin) ).or. |
> ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or. |
> (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) ) |
> then |
left=1 |
goto 100 |
endif |
enddo |
c Exit point for subroutine |
100 continue |
return |
end |
c ------------------------------------------------------------------- |
c Runge-Kutta (4th order) time-step |
c ------------------------------------------------------------------- |
subroutine runge(x1,y1,p1,left,x0,y0,p0,reltpos0,reltpos1, |
> deltat,numit,jump,mdv,wfactor,fbflag, |
> spt0,spt1,p3d0,p3d1,uut0,uut1,vvt0,vvt1,wwt0,wwt1, |
> xmin,ymin,dx,dy,per,hem,nx,ny,nz) |
implicit none |
c Declaration of subroutine parameters |
integer nx,ny,nz |
real x1,y1,p1 |
integer left |
real x0,y0,p0 |
real reltpos0,reltpos1 |
real deltat |
integer numit |
integer jump |
real wfactor |
integer fbflag |
real spt0(nx*ny) ,spt1(nx*ny) |
real uut0(nx*ny*nz),uut1(nx*ny*nz) |
real vvt0(nx*ny*nz),vvt1(nx*ny*nz) |
real wwt0(nx*ny*nz),wwt1(nx*ny*nz) |
real p3d0(nx*ny*nz),p3d1(nx*ny*nz) |
real xmin,ymin,dx,dy |
real per |
integer hem |
real mdv |
c Numerical and physical constants |
real deltay |
parameter (deltay=1.112E5) ! Distance in m between 2 lat circles |
real pi |
parameter (pi=3.1415927) ! Pi |
c Auxiliary variables |
real xmax,ymax |
real xind,yind,pind |
real u0,v0,w0,u1,v1,w1,u,v,w,sp |
integer icount,n |
real xs,ys,ps,xk(4),yk(4),pk(4) |
real reltpos |
c Externals |
real int_index4 |
external int_index4 |
c Reset the flag for domain-leaving |
left=0 |
c Set the esat-north bounray of the domain |
xmax = xmin+real(nx-1)*dx |
ymax = ymin+real(ny-1)*dy |
c Apply the Runge Kutta scheme |
do n=1,4 |
c Get intermediate position and relative time |
if (n.eq.1) then |
xs=0. |
ys=0. |
ps=0. |
reltpos=reltpos0 |
else if (n.eq.4) then |
xs=xk(3) |
ys=yk(3) |
ps=pk(3) |
reltpos=reltpos1 |
else |
xs=xk(n-1)/2. |
ys=yk(n-1)/2. |
ps=pk(n-1)/2. |
reltpos=(reltpos0+reltpos1)/2. |
endif |
C Calculate new winds for advection |
call get_index4 (xind,yind,pind,x0+xs,y0+ys,p0+ps,reltpos, |
> p3d0,p3d1,spt0,spt1,3, |
> nx,ny,nz,xmin,ymin,dx,dy,mdv) |
u = int_index4 (uut0,uut1,nx,ny,nz,xind,yind,pind,reltpos,mdv) |
v = int_index4 (vvt0,vvt1,nx,ny,nz,xind,yind,pind,reltpos,mdv) |
w = int_index4 (wwt0,wwt1,nx,ny,nz,xind,yind,pind,reltpos,mdv) |
c Force the near-surface wind to zero |
if (pind.lt.1.) w1=w1*pind |
c Update position and keep them |
xk(n)=fbflag*u*deltat/(deltay*cos(y0*pi/180.)) |
yk(n)=fbflag*v*deltat/deltay |
pk(n)=fbflag*w*deltat*wfactor/100. |
enddo |
C Calculate new positions |
x1=x0+(1./6.)*(xk(1)+2.*xk(2)+2.*xk(3)+xk(4)) |
y1=y0+(1./6.)*(yk(1)+2.*yk(2)+2.*yk(3)+yk(4)) |
p1=p0+(1./6.)*(pk(1)+2.*pk(2)+2.*pk(3)+pk(4)) |
c Handle pole problems (crossing and near pole trajectory) |
if ((hem.eq.1).and.(y1.gt.90.)) then |
y1=180.-y1 |
x1=x1+per/2. |
endif |
if ((hem.eq.1).and.(y1.lt.-90.)) then |
y1=-180.-y1 |
x1=x1+per/2. |
endif |
if (y1.gt.89.99) then |
y1=89.99 |
endif |
c Handle crossings of the dateline |
if ((hem.eq.1).and.(x1.gt.xmin+per-dx)) then |
x1=xmin+amod(x1-xmin,per) |
endif |
if ((hem.eq.1).and.(x1.lt.xmin)) then |
x1=xmin+per+amod(x1-xmin,per) |
endif |
C Interpolate surface pressure to actual position |
call get_index4 (xind,yind,pind,x1,y1,1050.,reltpos1, |
> p3d0,p3d1,spt0,spt1,3, |
> nx,ny,nz,xmin,ymin,dx,dy,mdv) |
sp = int_index4 (spt0,spt1,nx,ny,1,xind,yind,1,reltpos,mdv) |
c Handle trajectories which cross the lower boundary (jump flag) |
if ((jump.eq.1).and.(p1.gt.sp)) p1=sp-10. |
C Check if trajectory leaves data domain |
if ( ( (hem.eq.0).and.(x1.lt.xmin) ).or. |
> ( (hem.eq.0).and.(x1.gt.xmax-dx) ).or. |
> (y1.lt.ymin).or.(y1.gt.ymax).or.(p1.gt.sp) ) |
>then |
left=1 |
goto 100 |
endif |
c Exit point fdor subroutine |
100 continue |
return |
end |
/tags/1.0/caltra/caltra.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = caltra.o ${LAGRANTO}/lib/times.a ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/ioinp.a ${LAGRANTO}/lib/inter.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
caltra: $(OBJS) |
${F77} -o caltra $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/caltra/caltra.sh |
---|
0,0 → 1,601 |
#!/bin/csh |
# --------------------------------------------------------------------- |
# Usage, parameter settings |
# --------------------------------------------------------------------- |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( (${#argv} == 0) | (${#argv} < 4) ) then |
echo |
${LAGRANTO}/bin/lagrantohelp caltra short |
echo |
exit 0 |
endif |
# Write title |
echo |
echo '=========================================================' |
echo ' *** START OF PREPROCESSOR CALTRA *** ' |
echo |
# Get the arguments |
set startdate = $1 |
set enddate = $2 |
set startf = $3 |
set outfile = $4 |
if ( ${#argv} > 4 ) then |
set flags = $5 |
else |
set flags= |
endif |
# Set base directories (run+prog) |
set cdfdir=${PWD} |
set tradir=${PWD} |
# Set program paths and filenames |
set parfile = ${tradir}/caltra.param |
# Set the prefix of the primary and secondary data files |
set charp = 'P' |
set chars = 'S' |
echo '---- DIRECTORIES AND PROGRAMS ---------------------------' |
echo |
echo "CDF directory : ${cdfdir}" |
echo "TRA directory : ${tradir}" |
echo "PROGRAM CALTRA : ${LAGRANTO}/caltra/caltra" |
echo "PARAMETER file : ${parfile}" |
echo |
# --------------------------------------------------------------------- |
# Set optional flags |
# --------------------------------------------------------------------- |
echo '---- OPTIONAL FLAGS -------------------------------------' |
echo |
# Set some default values ("nil" must be set according to input files) |
set flag_j = "nil" |
set flag_i = "nil" |
set flag_t = "nil" |
set flag_o = "nil" |
set flag_p = "nil" |
set changet = 'false' |
set noclean = 'false' |
set timecheck = 'no' |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -j |
set flag_j=1 |
echo "Flag '-j' -> ${flag_j} (user defined)" |
breaksw |
case -i |
set flag_i=$argv[2] |
echo "Flag '-i' -> ${flag_i} (user defined)" |
shift; |
breaksw |
case -t |
set flag_t=$argv[2] |
echo "Flag '-t' -> ${flag_t} (user defined)" |
shift; |
breaksw |
case -o |
set flag_o=$argv[2] |
echo "Flag '-o' -> ${flag_o} (user defined)" |
shift; |
breaksw |
case -p |
set flag_p=1 |
echo "Flag '-p' -> ${flag_p} (user defined)" |
breaksw |
case -changet |
set changet = 'true' |
echo "changet -> true (user defined)" |
breaksw |
case -noclean |
set noclean = 'true' |
echo "noclean -> true (user defined)" |
breaksw |
case -timecheck |
set timecheck = 'yes' |
echo "timecheck -> yes (user defined)" |
breaksw |
endsw |
shift; |
end |
# No change of times necessary if no check requested |
if ( "${timecheck}" == "no" ) then |
set changet = 'false' |
endif |
# Set some defaults |
if ( "${flag_j}" == "nil" ) then |
set flag_j = 0 |
echo "Flag '-j' -> 0 (default)" |
endif |
if ( "${flag_p}" == "nil" ) then |
set flag_p = 0 |
echo "Flag '-p' -> 0 (default)" |
endif |
# --------------------------------------------------------------------- |
# Handle the time specifier - startdate, enddate |
# --------------------------------------------------------------------- |
echo |
echo '---- TIME RANGE -----------------------------------------' |
echo |
# Check format of start and end date - must be the same |
set ns=`echo $startdate | sed -e 's/_[0-9]*//' | wc -c` |
set ne=`echo $enddate | sed -e 's/_[0-9]*//' | wc -c` |
if ( $ns != $ne ) then |
echo " ERROR: start and end date must be in the same format ***" |
exit 1 |
endif |
if ( $ns != 9 ) then |
echo " ERROR: Date format must be yyyymmdd ***" |
exit 1 |
endif |
set ns=`echo $startdate | sed -e 's/[0-9]*_//' | wc -c` |
set ne=`echo $enddate | sed -e 's/[0-9]*_//' | wc -c` |
if ( $ns != $ne ) then |
echo " ERROR: start and end date must be in the same format ***" |
exit 1 |
endif |
if ( ( $ns != 5 ) & ( $ns != 3 ) ) then |
echo " ERROR: Time format must be hh(mm) ***" |
exit 1 |
endif |
# Split the start and end date into <yymmdd_hh and mm> |
set startdate_ymdh = `echo $startdate | cut -c 1-11` |
set startdate_min = `echo $startdate | cut -c 12-13` |
if ( $startdate_min == "" ) set startdate_min = 00 |
set enddate_ymdh = `echo $enddate | cut -c 1-11` |
set enddate_min = `echo $enddate | cut -c 12-13` |
if ( $enddate_min == "" ) set enddate_min = 00 |
# Get the time difference between <start_ymdh> and <end_ymdh> date |
# Decide whether trajectoriesare forward or backward |
set timediff_hh = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${startdate_ymdh}` |
if ( $timediff_hh == 0 ) then |
if ( $enddate_min > $startdate_min ) then |
set direction = f |
set idir = 1 |
else |
set direction = b |
set idir = -1 |
endif |
else if ( $timediff_hh > 0 ) then |
set direction = f |
set idir = 1 |
else |
set direction = b |
set idir = -1 |
@ timediff_hh = $idir * $timediff_hh |
endif |
# Get also minutes for time difference, if <start_min> or <end_min> != 0 |
set timediff_mm= |
if ( $startdate_min != 00 || $enddate_min != 00 ) then |
@ min = ( $enddate_min - $startdate_min ) |
if ( $min == 0 ) then |
set timediff_mm= |
else if ( $min > 0 ) then |
if ( $idir == 1 ) then |
set timediff_mm=$min |
else |
@ timediff_hh -- |
@ timediff_mm = 60 - $min |
endif |
else |
if ( $idir == 1 ) then |
@ timediff_hh -- |
@ timediff_mm = 60 + $min |
else |
@ timediff_mm = 0 - $min |
endif |
endif |
endif |
# Set the reference date equal to the satrtdate |
set refdate=${startdate} |
# Write status information |
echo "Time range : ${startdate} -> ${enddate}" |
if ( ${timediff_mm} != "" ) then |
echo "Time difference : ${timediff_hh} h ${timediff_mm} min" |
else |
echo "Time difference : ${timediff_hh} h" |
endif |
echo "Direction : ${direction} (${idir})" |
echo "Reference date : ${refdate}" |
# --------------------------------------------------------------------- |
# Check availability of input data |
# --------------------------------------------------------------------- |
echo |
echo '---- INPUT FILES ----------------------------------------' |
echo |
# Take the time increment from flag list ('nil', if not defined) |
set timeinc = ${flag_i} |
# Find a first data file (if possible corresponding to start/end date |
# If starttime is not a data time, take the first file in the direectory |
if ( $direction == "f" ) then |
set file=${charp}${startdate_ymdh} |
else |
set file=${charp}${enddate_ymdh} |
endif |
if ( ! -f $file ) then |
set file=`ls ${charp}[0-9_]*[0-9] | head -1 | sed -e 's/@//'` |
endif |
# Determine timeinc (the time difference in hours between two data file) |
# if not already defined with option -i |
if ( ${timeinc} == "nil" ) then |
set date1=`echo $file | cut -c 2-12` |
set n=`ls ${charp}[0-9_]*[0-9] | grep -n $date1 | awk -F: '{print $1}'` |
@ n ++ |
set date2=`ls ${charp}[0-9_]*[0-9] | head -$n | tail -1 | cut -c 2-12` |
set timeinc=`${LAGRANTO}/goodies/gettidiff $date2 $date1` |
endif |
if ( $timeinc == 0 ) then |
echo " ERROR: cannot set the time increment between input files ***" |
exit 1 |
endif |
# Search the first file to use: We step through all P files and see whether they are |
# good P files. Let's first do the test for the first data file found. If it's ok, we |
# take it; if not, we step through all P files and find the good one |
set flag=0 |
set td= |
set date = `echo $file | cut -c 2-12` |
set td1 = `${LAGRANTO}/goodies/gettidiff ${startdate_ymdh} ${date}` |
set td2 = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${date}` |
if (( $td1 < $timeinc || $td2 < $timeinc ) && ( $td1 >= 0 || $td2 >= 0 )) then |
set datfiles=$date |
if ( $td1 < $timeinc ) set td=$td1 |
if ( $td2 < $timeinc ) set td=$td2 |
if ( ( $startdate_min > 0 ) || ( $enddate_min > 0 ) ) @ td ++ |
goto label2 |
endif |
foreach i ( ${charp}????????_?? ) |
set date = `echo $i | cut -c 2-12` |
set td1 = `${LAGRANTO}/goodies/gettidiff ${startdate_ymdh} ${date}` |
set td2 = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${date}` |
if (( $td1 < $timeinc || $td2 < $timeinc ) && ( $td1 >= 0 || $td2 >= 0 )) then |
set datfiles=$date |
if ( $td1 < $timeinc ) set td=$td1 |
if ( $td2 < $timeinc ) set td=$td2 |
if ( ( $startdate_min > 0 ) || ( $enddate_min > 0 ) ) @ td ++ |
goto label2 |
endif |
end |
# if no P/T-files are available for the specified time period, then $td is |
# still undefined |
if ( $td == "" ) then |
echo " ERROR: no data files available for the specified time period" |
exit 1 |
endif |
# Everything is fine so far: proceed |
label2: |
# Check whether first date is ok - before or at needed dates |
if ( $direction == "f" ) then |
set tdiff0 = `${LAGRANTO}/goodies/gettidiff ${startdate_ymdh} ${date}` |
else |
set tdiff0 = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${date}` |
endif |
if ( $tdiff0 < 0 ) then |
echo " ERROR: data files missing for the specified time period" |
exit 1 |
endif |
# Calculate the number of further files |
@ num = ( $timediff_hh + $td ) / $timeinc + 1 |
@ dum1 = ( $num - 1 ) * $timeinc |
@ dum2 = $timediff_hh + $td |
if ( $dum1 != $dum2 ) @ num ++ |
# Get a list of all needed files |
set numfiles=$num |
set sfiles=1 |
echo $datfiles |
while ( $num > 1 ) |
set date=`${LAGRANTO}/goodies/newtime $date $timeinc` |
echo $date |
if ( ! -f ${charp}${date} ) then |
echo " ERROR: file with primary data is missing for $date" |
exit 1 |
else if ( ! -f ${chars}${date} ) then |
set sfiles=0 |
set datfiles=`echo $datfiles $date` |
else |
set datfiles=`echo $datfiles $date` |
endif |
@ num -- |
end |
# Write some status information |
echo "Primary file prefix : ${charp}" |
echo "Secondary file prefix : ${chars}" |
echo "Time increment for input files : ${timeinc}" |
echo "# input files : ${numfiles}" |
echo "${charp} files availability : 1" |
echo "${chars} files availability : ${sfiles}" |
echo "First input file : $datfiles[1] " |
echo "Last input file : $datfiles[$numfiles] " |
# --------------------------------------------------------------------- |
# Handle vertical wind - scaling factor |
# --------------------------------------------------------------------- |
echo |
echo '---- VERTICAL WIND SCALING ------------------------------' |
echo |
set wfactor=1. |
# Write status information |
echo "Vertical scaling factor (wfactor) : ${wfactor}" |
# --------------------------------------------------------------------- |
# Time step and output interval |
# --------------------------------------------------------------------- |
echo |
echo '---- TIME STEPS -----------------------------------------' |
echo |
# Take the time step and output step from flag list ('nil', if not defined) |
set timestep = ${flag_t} |
set deltout = ${flag_o} |
# Calculate the time step |
if ( $timestep == "nil" ) @ timestep = ( 60 * $timeinc ) / 12 |
# Take the output interval from time increment |
if ( $deltout == "nil" ) @ deltout = 60 * ${timeinc} |
# Check whether the timestep is an integer ratio of deltout |
@ flag = $deltout / $timestep |
@ flag = $deltout - ( $flag * $timestep ) |
if ( $flag != 0 ) then |
echo " ERROR: output time interval should be multiple of timestep" |
echo |
echo " $deltout min : output time interval" |
echo " $timestep min : time step" |
exit 1 |
endif |
# Calculate the start and the end time relative to the first datfile |
if ( $direction == f ) then |
set tstart = `${LAGRANTO}/goodies/gettidiff $startdate $datfiles[1]` |
set tend = `${LAGRANTO}/goodies/gettidiff $datfiles[$numfiles] $enddate` |
else |
set tstart = `${LAGRANTO}/goodies/gettidiff $datfiles[$numfiles] $startdate` |
set tend = `${LAGRANTO}/goodies/gettidiff $enddate $datfiles[1]` |
endif |
# Check whether tstart and tend are a multiple of the output time interval |
if ( $tstart != 0 ) then |
if ( `echo $tstart | grep "\."` != "" ) then |
set dum=`echo $tstart | sed -e 's/[-0-9]*\.//'` |
@ flag = $dum / $deltout |
@ flag = $dum - ( $flag * $deltout ) |
if ( $flag != 0 ) then |
echo " ERROR : the start time should be shifted relative to the first" |
echo " datafile by a multiple of the output time interval" |
echo " hint: set the latter with the option -o" |
exit 1 |
endif |
endif |
endif |
if ( `echo $tend | grep "\."` != "" ) then |
set dum=`echo $tend | sed -e 's/[-0-9]*\.//'` |
@ flag = $dum / $deltout |
@ flag = $dum - ( $flag * $deltout ) |
if ( $flag != 0 ) then |
echo " ERROR : the end time should be shifted relative to the first" |
echo " datafile by a multiple of the output time interval" |
echo " hint: set the latter with the option -o" |
exit 1 |
endif |
endif |
# Write status information |
echo "Trajectory calculation time step [min] : ${timestep}" |
echo "Output time step [min] : ${deltout}" |
if ( $direction == f ) then |
echo "Start time relative to first file : $datfiles[1] + ${tstart} " |
echo "End time relative to first file : $datfiles[$numfiles] - ${tend} " |
else |
echo "Start time relative to first file : $datfiles[$numfiles] - ${tstart} " |
echo "End time relative to last file : $datfiles[1] + ${tend} " |
endif |
# --------------------------------------------------------------------- |
# Start file |
# --------------------------------------------------------------------- |
echo |
echo '---- START FILE -----------------------------------------' |
echo |
# Check if start file is available |
if ( ! -f ${startf} ) then |
echo " ERROR : start file ${startf} is missing" |
exit 1 |
endif |
# Decide whether startfile has an explicit format specifier |
set format = "0" |
foreach app ( 1 2 3 4 5 6 7 8 9 ) |
set flag = `echo ${startf} | grep "\.${app}"` |
if ( "${flag}" != "" ) set format = "${app}" |
end |
# If format is 0, it might nevertheless be a hidden format 1 |
if ( "${format}" == "0" ) then |
set ncol = `awk "{print NF}" ${startf} | tail -1` |
if ( "${ncol}" != "3" ) then |
set format = "1" |
echo " WARNING: ${startf} is a hidden trajectory file of format 1" |
echo " it will be renamed: ${startf} -> ${startf}.1" |
echo |
ln -sf ${startf} ${startf}.1 |
set startf = "${startf}.1" |
endif |
endif |
# Get the number of trajectories |
if ( "${format}" == "0" ) then |
set ntra = `wc -l ${startf} | awk '{print $1}' ` |
set ncol = 3 |
else |
set ntra = `${LAGRANTO}/goodies/trainfo.sh ${startf} ntra` |
set ncol = `${LAGRANTO}/goodies/trainfo.sh ${startf} ncol` |
set ntim = `${LAGRANTO}/goodies/trainfo.sh ${startf} ntim` |
if ( "${ntim}" != "1" ) then |
echo " ERROR: starting trajectory file must only have one time... Stop" |
exit 1 |
endif |
endif |
# Write status information |
echo "Start file : ${startf} " |
if ( "${format}" == "0" ) then |
echo "Format : (lon,lat,p) list" |
else |
echo "Format : trajectory file (${format})" |
endif |
echo "# coordinates (lon,lat,lev) : ${ntra} " |
echo "# columns : ${ncol} " |
# --------------------------------------------------------------------- |
# Prepare input file for caltra and run it |
# --------------------------------------------------------------------- |
# Set times relative to the reference date |
if ( "${changet}" == "true" ) then |
echo |
echo '---- CHANGE TIMES ON DATA FILES ------------------------' |
echo |
foreach i ( $datfiles ) |
${LAGRANTO}/goodies/changet.sh ${refdate} ${charp}${i} |
end |
if ( ${sfiles} == 1 ) then |
foreach i ( $datfiles ) |
${LAGRANTO}/goodies/changet.sh ${refdate} ${chars}${i} |
end |
endif |
endif |
# Split the reference date |
set yyyy=`echo ${refdate} | cut -c 1-4` |
set mm=`echo ${refdate} | cut -c 5-6` |
set dd=`echo ${refdate} | cut -c 7-8` |
set hh=`echo ${refdate} | cut -c 10-11` |
set min=`echo ${refdate}00 | cut -c 12-13` |
# Get the total tiem range |
if ( ${timediff_mm} != '' ) then |
@ timerange = 60 * ${timediff_hh} + ${timediff_mm} |
else |
@ timerange = 60 * ${timediff_hh} |
endif |
# Write parameter file |
\rm -f ${parfile} |
touch ${parfile} |
\echo $idir >> $parfile |
echo $numfiles >> $parfile |
foreach i ( $datfiles ) |
echo $i >> $parfile |
end |
echo $timeinc >> $parfile |
echo $flag_p >> $parfile |
echo \"${startf}\" >> $parfile |
echo ${ntra} >> $parfile |
echo ${ncol} >> $parfile |
echo \"${outfile}\" >> $parfile |
echo $timestep >> $parfile |
echo $tstart >> $parfile |
echo $tend >> $parfile |
echo $deltout >> $parfile |
echo $flag_j >> $parfile |
echo $wfactor >> $parfile |
echo $yyyy >> $parfile |
echo $mm >> $parfile |
echo $dd >> $parfile |
echo $hh >> $parfile |
echo $min >> $parfile |
echo $timerange >> $parfile |
echo \"${timecheck}\" >> $parfile |
# Finish the preprocessor |
echo |
echo ' *** END OF PREPROCESSOR CALTRA *** ' |
echo '=========================================================' |
echo |
# Run caltra |
${LAGRANTO}/caltra/caltra |
if ( "${status}" != "0" ) then |
echo "ERROR: Program <caltra> failed" |
exit 1 |
endif |
# ---------------------------------------------------------- |
# Final tasks (make clean) |
# ---------------------------------------------------------- |
finish: |
if ( "${noclean}" == "false" ) then |
\rm -f ${parfile} |
endif |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/create_startf/create_startf.f |
---|
0,0 → 1,1735 |
PROGRAM create_startf |
c ************************************************************** |
c * Create a <startfile> for <lagrangto>. It can be chosen * |
c * whether to start from an isentropic or an isobaric * |
c * surface. The starting points are equidistantly distributed * |
c * Michael Sprenger / Autumn 2004 * |
c ************************************************************** |
implicit none |
c -------------------------------------------------------------- |
c Set parameters |
c -------------------------------------------------------------- |
c Maximum number of starting positions |
integer nmax |
parameter (nmax=1000000) |
c Maximum number of model levels |
integer nlevmax |
parameter (nlevmax=200) |
c Grid constant (distance in km corresponding to 1 deg at the equator) |
real deltat |
parameter (deltat=111.) |
c Mathematical constant (conversion degree -> radian) |
real pi180 |
parameter (pi180=3.14159/180.) |
c Numerical epsilon |
real eps |
parameter (eps=0.00001) |
c -------------------------------------------------------------- |
c Set variables |
c -------------------------------------------------------------- |
c Filenames and output format |
character*80 pfile0,pfile1 ! P filenames |
character*80 sfile0,sfile1 ! S filenames |
character*80 ofile ! Output filename |
integer oformat ! Output format |
real timeshift ! Time shift relative to data files <*0> |
real timeinc ! Time increment between input files |
c Horizontal grid |
character*80 hmode ! Horizontale mode |
real lat1,lat2,lon1,lon2 ! Lat/lon boundaries |
real ds,dlon,dlat ! Distance and lat/lon shifts |
character*80 hfile ! Filename |
integer hn ! Number of entries in lat/lon list |
real latlist(nmax) ! List of latitudes |
real lonlist(nmax) ! List of longitudes |
integer pn ! Number of entries in lat/lon poly |
real latpoly(500) ! List of polygon latitudes |
real lonpoly(500) ! List of polygon longitudes |
real loninpoly,latinpoly ! Lon/lat inside polygon |
character*80 regionf ! Region file |
integer iregion ! Region number |
real xcorner(4),ycorner(4) ! Vertices of region |
c Vertical grid |
character*80 vmode ! Vertical mode |
real lev1,lev2,levlist(nmax) ! Single levels, and list of levels |
character*80 vfile ! Filename |
integer vn ! Number of entries |
c Unit of vertical axis |
character*80 umode ! Unit of vertical axis |
c Flag for 'no time check' |
character*80 timecheck ! Either 'no' or 'yes' |
c List of all starting positions |
integer start_n ! Number of coordinates |
real start_lat(nmax) ! Latitudes |
real start_lon(nmax) ! Longitudes |
real start_lev(nmax) ! Levels (depending on vertical unit) |
real start_pre(nmax) ! Level in hPa |
integer reftime(6) ! Reference time |
character*80 vars(10) ! Name of output fields (time,lon,lat,p) |
real,allocatable, dimension (:,:,:) :: tra ! Trajectories (ntra,ntim,ncol) |
real latmin,latmax |
real lonmin,lonmax |
real premin,premax |
c Grid description |
real pollon,pollat ! Longitude/latitude of pole |
real ak(nlevmax) ! Vertical layers and levels |
real bk(nlevmax) |
real xmin,xmax ! Zonal grid extension |
real ymin,ymax ! Meridional grid extension |
integer nx,ny,nz ! Grid dimensions |
real dx,dy ! Horizontal grid resolution |
real,allocatable, dimension (:,:,:) :: pr ! 3d pressure |
real,allocatable, dimension (:,:) :: prs ! surface pressure |
real,allocatable, dimension (:,:,:) :: th ! 3d potential temperature |
real,allocatable, dimension (:,:) :: ths ! surface poential temperature |
real,allocatable, dimension (:,:,:) :: pv ! 3d potential vorticity |
real,allocatable, dimension (:,:) :: pvs ! surface potential vorticiy |
real,allocatable, dimension (:,:,:) :: in ! 3d 'dummy' array with vertical indices |
character*80 varname ! Name of input variable |
integer fid ! File identifier |
real stagz ! Vertical staggering |
real mdv ! Missing data values |
real tstart,tend ! Time on P and S file |
real rid,rjd,rkd ! Real grid position |
c Auxiliary variable |
integer i,j,k |
real lon,lat |
real rd |
integer stat,flag |
real tmp1,tmp2 |
real tfrac,frac |
real radius,dist |
character*80 string |
character*80 selectstr |
character*80 umode_save |
real,allocatable, dimension (:,:,:) :: fld0 |
real,allocatable, dimension (:,:,:) :: fld1 |
real,allocatable, dimension (:,: ) :: sfc0 |
real,allocatable, dimension (:,:) :: sfc1 |
c Externals |
real int_index3 ! 3d interpolation |
external int_index3 |
real sdis ! Speherical distance |
external sdis |
integer inregion ! In/out of region |
external inrehion |
c ------------------------------------------------------------------ |
c Start of program, Read parameters |
c ------------------------------------------------------------------ |
c Write start message |
print*,'=========================================================' |
print*,' *** START OF PROGRAM CREATE_STARTF ***' |
print* |
c Read parameter file |
open(10,file='create_startf.param') |
c Input P and S file |
read(10,*) pfile0,pfile1 |
read(10,*) sfile0,sfile1 |
read(10,*) ofile |
c Read name of region file |
read(10,*) regionf |
c Reference time |
do i=1,6 |
read(10,*) reftime(i) |
enddo |
c Time shift relative to data files <pfile0,sfile0> - format (hh.mm) |
read(10,*) timeshift |
c Read timeincrement between input files |
read(10,*) timeinc |
c Parameters for horizontal grid |
read(10,*) hmode |
if ( hmode.eq.'file' ) then ! from file |
read(10,*) hfile |
elseif ( hmode.eq.'line' ) then ! along a line |
read(10,*) lon1,lon2,lat1,lat2,hn |
elseif ( hmode.eq.'box.eqd' ) then ! box: 2d equidistant |
read(10,*) lon1,lon2,lat1,lat2,ds |
elseif ( hmode.eq.'box.grid' ) then ! box: 2d grid |
read(10,*) lon1,lon2,lat1,lat2 |
elseif ( hmode.eq.'point' ) then ! single point |
read(10,*) lon1,lat1 |
elseif ( hmode.eq.'shift' ) then ! centre + shifted |
read(10,*) lon1,lat1,dlon,dlat |
elseif ( hmode.eq.'polygon.eqd' ) then ! polygon: 2d equidistant |
read(10,*) hfile,ds |
elseif ( hmode.eq.'polygon.grid' ) then ! polygon: 2d grid |
read(10,*) hfile |
elseif ( hmode.eq.'circle.eqd' ) then ! circle: 2d equidistant |
read(10,*) lon1,lat1,radius,ds |
elseif ( hmode.eq.'circle.grid' ) then ! circle: 2d grid |
read(10,*) lon1,lat1,radius |
elseif ( hmode.eq.'region.eqd' ) then ! region: 2d equidistant |
read(10,*) iregion,ds |
elseif ( hmode.eq.'region.grid' ) then ! iregion: 2d grid |
read(10,*) iregion |
else |
print*,' ERROR: horizontal mode not supported ',trim(hmode) |
stop |
endif |
c Parameters for vertical grid |
read(10,*) vmode |
if ( vmode.eq.'file') then ! from file |
read(10,*) vfile |
elseif ( vmode.eq.'level' ) then ! single level (explicit command) |
read(10,*) lev1 |
elseif ( vmode.eq.'list') then ! a list |
read(10,*) vn |
read(10,*) (levlist(i),i=1,vn) |
elseif ( vmode.eq.'profile') then ! a profile |
read(10,*) lev1,lev2,vn |
elseif ( vmode.eq.'grid') then ! grid points |
read(10,*) lev1,lev2 |
else |
print*,' ERROR: vertical mode not supported ',trim(vmode) |
stop |
endif |
c Read units of vertical axis |
read(10,*) umode |
if ( ( umode.ne.'hPa' ).and. |
> ( umode.ne.'hPa,agl' ).and. |
> ( umode.ne.'K' ).and. |
> ( umode.ne.'PVU' ).and. |
> ( umode.ne.'INDEX' ) ) |
> then |
print*,' ERROR: unit not supported ',trim(umode) |
stop |
endif |
c Read selection criterion (dummy read) |
read(10,*) selectstr |
c Read flag for 'no time check' |
read(10,*) timecheck |
c Close parameter file |
close(10) |
c Decide which output format is used (1..4: trajectory format, -1: triple list) |
call mode_tra(oformat,ofile) |
c Decide whether all lat/lon/lev coordaintes are read from one file |
if ( (hmode.eq.'file').and.(vmode.eq.'nil') ) then |
hmode='file3' |
elseif ( (hmode.eq.'file').and.(vmode.ne.'nil') ) then |
hmode='file2' |
endif |
c Convert timeshift (hh.mm) into a fractional time shift |
call hhmm2frac(timeshift,tfrac) |
if (tfrac.gt.0.) then |
tfrac=tfrac/timeinc |
else |
tfrac=0. |
endif |
c Read the region coordinates if needed |
if ( (hmode.eq.'region.eqd' ).or. |
> (hmode.eq.'region.grid') ) then |
open(10,file=regionf) |
50 read(10,*,end=51) string |
if ( string(1:1).ne.'#' ) then |
call regionsplit(string,i,xcorner,ycorner) |
if ( i.eq.iregion ) goto 52 |
endif |
goto 50 |
51 close(10) |
print*,' ERROR: region ',iregion,' not found on ',trim(regionf) |
stop |
52 continue |
endif |
c Write some status information |
print*,'---- INPUT PARAMETERS -----------------------------------' |
print* |
if ( timeshift.gt.0. ) then |
print*,' P file : ',trim(pfile0), |
> ' ', |
> trim(pfile1) |
print*,' S file : ',trim(sfile0), |
> ' ', |
> trim(sfile1) |
else |
print*,' P file : ',trim(pfile0) |
print*,' S file : ',trim(sfile0) |
endif |
print*,' Output file : ',trim(ofile) |
print* |
if (oformat.eq.-1) then |
print*,' Output format : (lon,lat,lev)-list' |
else |
print*,' Output format : ',oformat |
endif |
print* |
print*,' Reference time (year) : ',reftime(1) |
print*,' (month) : ',reftime(2) |
print*,' (day) : ',reftime(3) |
print*,' (hour) : ',reftime(4) |
print*,' (min) : ',reftime(5) |
print*,' Time range : ',reftime(6) |
print* |
print*,' Time shift : ',timeshift,' + ', |
> trim(pfile0) |
print*,' Region file : ',trim(regionf) |
print* |
print*,' hmode : ',trim(hmode) |
if ( hmode.eq.'file2' ) then |
print*,' filename [lat/lon] : ',trim(hfile) |
elseif ( hmode.eq.'file3' ) then |
print*,' filename [lat/lon/lev] : ',trim(hfile) |
elseif ( hmode.eq.'line' ) then |
write(*,'(a30,4f10.2,i4)') |
> ' lon1,lon2,lat1,lat2,n : ',lon1,lon2,lat1,lat2,hn |
elseif ( hmode.eq.'box.eqd' ) then |
write(*,'(a30,5f10.2)') |
> ' lon1,lon2,lat1,lat2,ds : ',lon1,lon2,lat1,lat2,ds |
elseif ( hmode.eq.'box.grid' ) then |
write(*,'(a30,4f10.2)') |
> ' lon1,lon2,lat1,lat2 : ',lon1,lon2,lat1,lat2 |
elseif ( hmode.eq.'point' ) then |
print*,' lon,lat : ',lon1,lat1 |
elseif ( hmode.eq.'shift' ) then |
write(*,'(a30,4f10.2)') |
> ' lon,lat,dlon,dlat : ',lon1,lat1,dlon,dlat |
elseif ( hmode.eq.'polygon.eqd' ) then |
write(*,'(a30,a10,f10.2)') |
> ' hfile, ds : ',trim(hfile),ds |
elseif ( hmode.eq.'polygon.grid' ) then |
write(*,'(a30,a10)') |
> ' hfile : ',trim(hfile) |
elseif ( hmode.eq.'circle.eqd' ) then |
write(*,'(a30,4f10.2)') |
> ' lonc,latc,radius, ds : ',lon1,lat1,radius,ds |
elseif ( hmode.eq.'circle.grid' ) then |
write(*,'(a30,3f10.2)') |
> ' lonc,latc,radius : ',lon1,lat1,radius |
elseif ( hmode.eq.'region.eqd' ) then |
write(*,'(a30,i4,1f10.2)') |
> ' iregion, ds : ',iregion,ds |
write(*,'(a30,4f10.2)') |
> ' xcorner : ',(xcorner(i),i=1,4) |
write(*,'(a30,4f10.2)') |
> ' ycorner : ',(ycorner(i),i=1,4) |
elseif ( hmode.eq.'region.grid' ) then |
write(*,'(a30,i4)') |
> ' iregion : ',iregion |
write(*,'(a30,4f10.2)') |
> ' xcorner : ',(xcorner(i),i=1,4) |
write(*,'(a30,4f10.2)') |
> ' ycorner : ',(ycorner(i),i=1,4) |
endif |
print* |
print*,' vmode : ',trim(vmode) |
if ( vmode.eq.'file') then |
print*,' filename : ',trim(vfile) |
elseif ( vmode.eq.'level' ) then |
print*,' level : ',lev1 |
elseif ( vmode.eq.'list') then |
print*,' n : ',vn |
print*,' level(i) : ',(levlist(i),i=1,vn) |
elseif ( vmode.eq.'profile') then |
print*,' lev1,lev2,n : ',lev1,lev2,vn |
elseif ( vmode.eq.'grid') then |
print*,' lev1,lev2 : ',lev1,lev2 |
endif |
print* |
print*,' umode : ',trim(umode) |
print* |
print*,' time check : ',trim(timecheck) |
print* |
c ------------------------------------------------------------------ |
c Read grid parameters from inital files |
c ------------------------------------------------------------------ |
c Get the time of the first and second data file |
tstart = -timeshift ! Format hh.mm |
call hhmm2frac(tstart,frac) |
frac = frac + timeinc |
call frac2hhmm(frac,tend) ! Format hh.mm |
c Convert timeshift (hh.mm) into a fractional time shift |
tfrac=real(int(timeshift))+ |
> 100.*(timeshift-real(int(timeshift)))/60. |
if (tfrac.gt.0.) then |
tfrac=tfrac/timeinc |
else |
tfrac=0. |
endif |
c Read the constant grid parameters (nx,ny,nz,xmin,xmax,ymin,ymax, |
c pollon,pollat) The negative <-fid> of the file identifier is used |
c as a flag for parameter retrieval |
varname = 'U' |
nx = 1 |
ny = 1 |
nz = 1 |
call input_open (fid,pfile0) |
call input_grid (-fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tstart,pollon,pollat,rd,rd,nz,rd,rd,rd,timecheck) |
call input_close(fid) |
c Check whether region coordinates are within the domain |
if ( (hmode.eq.'region.eqd' ).or. |
> (hmode.eq.'region.grid') ) then |
do i=1,4 |
if ( (xcorner(i).lt.xmin).or. |
> (ycorner(i).lt.ymin).or. |
> (xcorner(i).gt.xmax).or. |
> (ycorner(i).gt.ymax) ) |
> then |
print*,' ERROR: region not included in data domain...' |
print*,' ',trim(string) |
print*,' ',(xcorner(j),j=1,4) |
print*,' ',(ycorner(j),j=1,4) |
stop |
endif |
enddo |
endif |
C Check if the number of levels is too large |
if (nz.gt.nlevmax) goto 993 |
c Allocate memory for 3d arrays: pressure, theta, pv |
allocate(pr(nx,ny,nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array pr ***' |
allocate(prs(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array prs **' |
allocate(th(nx,ny,nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array th ***' |
allocate(ths(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array ths **' |
allocate(pv(nx,ny,nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array pv ***' |
allocate(pvs(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array pvs **' |
allocate(in(nx,ny,nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array in ***' |
c Allocate memory for temporary arrays for time interpolation |
allocate(fld0(nx,ny,nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tmp0 ***' |
allocate(fld1(nx,ny,nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tmp1 ***' |
allocate(sfc0(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array sfc0 ***' |
allocate(sfc1(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array sfc1 ***' |
c ------ Index ----------------------------------------------------- |
c Init the dummy array with vertical index |
do i=1,nx |
do j=1,ny |
do k=1,nz |
in(i,j,k) = real(k) |
enddo |
enddo |
enddo |
c ------ Pressure -------------------------------------------------- |
c Read pressure from first data file (pfile0) on U-grid; we have to set |
c mdv explicitely, because it's not read from netCDF |
call input_open (fid,pfile0) |
varname='U' |
call input_grid |
> (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tstart,pollon,pollat,fld0,sfc0,nz,ak,bk,stagz,timecheck) |
mdv = -999.99 |
call input_close(fid) |
c Read or set pressure for second data file (pfile1) |
if ( timeshift.ne.0.) then |
call input_open (fid,pfile1) |
varname='U' |
call input_grid |
> (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tend,pollon,pollat,fld1,sfc1,nz,ak,bk,stagz,timecheck) |
call input_close(fid) |
else |
do i=1,nx |
do j=1,ny |
do k=1,nz |
fld1(i,j,k) = fld0(i,j,k) |
enddo |
sfc1(i,j) = sfc0(i,j) |
enddo |
enddo |
endif |
c Time interpolation to get the final pressure field |
do i=1,nx |
do j=1,ny |
do k=1,nz |
pr(i,j,k) = (1.-tfrac) * fld0(i,j,k) + |
> tfrac * fld1(i,j,k) |
enddo |
prs(i,j) = (1.-tfrac) * sfc0(i,j) + |
> tfrac * sfc1(i,j) |
enddo |
enddo |
c ------ Potential temperature ------------------------------------- |
if ( (umode.eq.'K').or.(umode.eq.'PVU') ) then |
c Read potential temperature from first data file <sfile0> |
call input_open (fid,sfile0) |
varname='TH' ! Theta |
call input_wind |
> (fid,varname,fld0,tstart,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_close(fid) |
c Read or set potential temperature for second data file (sfile1) |
if ( timeshift.ne.0.) then |
call input_open (fid,sfile1) |
varname='TH' |
call input_wind |
> (fid,varname,fld1,tend,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_close(fid) |
else |
do i=1,nx |
do j=1,ny |
do k=1,nz |
fld1(i,j,k) = fld0(i,j,k) |
enddo |
enddo |
enddo |
endif |
c Time interpolation to get the final potential temperature field |
do i=1,nx |
do j=1,ny |
do k=1,nz |
th(i,j,k) = (1.-tfrac) * fld0(i,j,k) + |
> tfrac * fld1(i,j,k) |
enddo |
enddo |
enddo |
c Set the surface potential temperature |
do i=1,nx |
do j=1,ny |
ths(i,j)=th(i,j,1) |
enddo |
enddo |
endif |
c ------ Potential vorticity ----------------------------------------- |
if ( (umode.eq.'PVU') ) then |
c Read potential vorticity from first data file <sfile0> |
call input_open (fid,sfile0) |
varname='PV' |
call input_wind |
> (fid,varname,fld0,tstart,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_close(fid) |
c Read or set potential vorticity for second data file (sfile1) |
if ( timeshift.ne.0.) then |
call input_open (fid,sfile1) |
varname='PV' |
call input_wind |
> (fid,varname,fld1,tend,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_close(fid) |
else |
do i=1,nx |
do j=1,ny |
do k=1,nz |
fld1(i,j,k) = fld0(i,j,k) |
enddo |
enddo |
enddo |
endif |
c Time interpolation to get the final potential vorticity field |
do i=1,nx |
do j=1,ny |
do k=1,nz |
pv(i,j,k) = (1.-tfrac) * fld0(i,j,k) + |
> tfrac * fld1(i,j,k) |
enddo |
enddo |
enddo |
c Set the surface potential vorticity |
do i=1,nx |
do j=1,ny |
pvs(i,j)=pv(i,j,1) |
enddo |
enddo |
endif |
c Write some status information |
print*,'---- CONSTANT GRID PARAMETERS ---------------------------' |
print* |
print*,' xmin,xmax : ',xmin,xmax |
print*,' ymin,ymax : ',ymin,ymax |
print*,' dx,dy : ',dx,dy |
print*,' pollon,pollat : ',pollon,pollat |
print*,' nx,ny,nz : ',nx,ny,nz |
print* |
print*,' Pressure loaded : ',trim(pfile0),' ',trim(pfile1) |
if ( (umode.eq.'K').or.(umode.eq.'PVU') ) then |
print*,' Theta loaded : ',trim(sfile0),' ',trim(sfile1) |
endif |
if ( (umode.eq.'PVU') ) then |
print*,' PV loaded : ',trim(sfile0),' ',trim(sfile1) |
endif |
print* |
c ------------------------------------------------------------------ |
c Determine the expanded list of starting coordinates |
c ------------------------------------------------------------------ |
c Write some status information |
print*,'---- EXPAND LIST OF STARTING POSITIONS -----------------' |
print* |
c ------ Read lat/lon/lev from <hfile> ----------------------------- |
if ( hmode.eq.'file3' ) then |
start_n = 0 |
open(10,file=hfile) |
100 continue |
start_n = start_n + 1 |
read(10,*,end=101) start_lon(start_n), |
> start_lat(start_n), |
> start_lev(start_n) |
goto 100 |
101 continue |
start_n = start_n - 1 |
close(10) |
goto 400 |
endif |
c ------ Get lat/lon (horizontal) coordinates --------------------- |
c Read lat/lon from <hfile> |
if ( hmode.eq.'file2' ) then |
hn = 0 |
open(10,file=hfile) |
200 continue |
hn = hn + 1 |
read(10,*,end=201) lonlist(hn), |
> latlist(hn) |
goto 200 |
201 continue |
hn = hn - 1 |
close(10) |
endif |
c Get lat/lon along a line (linear in lat/lon space) |
if ( hmode.eq.'line' ) then |
do i=1,hn |
lonlist(i) = lon1 + real(i-1)/real(hn-1)*(lon2-lon1) |
latlist(i) = lat1 + real(i-1)/real(hn-1)*(lat2-lat1) |
enddo |
endif |
c Lat/lon box: equidistant |
if ( hmode.eq.'box.eqd' ) then |
hn = 0 |
lat = lat1 |
do while ( lat.le.lat2 ) |
lon = lon1 |
do while ( lon.le.lon2 ) |
hn = hn+1 |
lonlist(hn) = lon |
latlist(hn) = lat |
lon = lon+ds/(deltat*cos(pi180*lat)) |
enddo |
lat = lat+ds/deltat |
enddo |
endif |
c Lat/lon box: grid |
if ( hmode.eq.'box.grid' ) then |
hn = 0 |
do j=1,ny |
do i=1,nx |
lon = xmin + real(i-1) * dx |
lat = ymin + real(j-1) * dy |
if ( (lon.ge.lon1).and.(lon.le.lon2).and. |
> (lat.ge.lat1).and.(lat.le.lat2) ) |
> then |
hn = hn+1 |
lonlist(hn) = lon |
latlist(hn) = lat |
endif |
enddo |
enddo |
endif |
c Get single starting point |
if ( hmode.eq.'point' ) then |
hn = 1 |
lonlist(hn) = lon1 |
latlist(hn) = lat1 |
endif |
c Get shifted and central starting point |
if ( hmode.eq.'shift' ) then |
hn = 5 |
lonlist(1) = lon1 |
latlist(1) = lat1 |
lonlist(2) = lon1+dlon |
latlist(2) = lat1 |
lonlist(3) = lon1-dlon |
latlist(3) = lat1 |
lonlist(4) = lon1 |
latlist(4) = lat1+dlat |
lonlist(5) = lon1 |
latlist(5) = lat1-dlat |
endif |
c Lat/lon polygon: grid |
if ( hmode.eq.'polygon.grid' ) then |
c Read list of polygon coordinates |
pn = 0 |
open(10,file=hfile) |
read(10,*) loninpoly,latinpoly |
210 continue |
pn = pn + 1 |
read(10,*,end=211) lonpoly(pn), |
> latpoly(pn) |
print*,pn,lonpoly(pn),latpoly(pn) |
goto 210 |
211 continue |
pn = pn - 1 |
close(10) |
c Define the polygon boundaries |
call DefSPolyBndry(latpoly,lonpoly,pn,latinpoly,loninpoly) |
c Get the grid points inside the polygon |
hn = 0 |
do j=1,ny |
do i=1,nx |
lon = xmin + real(i-1) * dx |
lat = ymin + real(j-1) * dy |
call LctPtRelBndry(lat,lon,flag) |
if ( (flag.eq.1).or.(flag.eq.2) ) then |
hn = hn+1 |
lonlist(hn) = lon |
latlist(hn) = lat |
endif |
enddo |
enddo |
endif |
c Lat/lon polygon: equidistant |
if ( hmode.eq.'polygon.eqd' ) then |
c Read list of polygon coordinates |
pn = 0 |
open(10,file=hfile) |
read(10,*) loninpoly,latinpoly |
220 continue |
pn = pn + 1 |
read(10,*,end=221) lonpoly(pn), |
> latpoly(pn) |
goto 220 |
221 continue |
pn = pn - 1 |
close(10) |
c Define the polygon boundaries |
call DefSPolyBndry(latpoly,lonpoly,pn,latinpoly,loninpoly) |
c Get the grid points inside the polygon |
hn = 0 |
lat = -90. |
do while ( lat.le.90. ) |
lon = -180. |
do while ( lon.lt.180. ) |
call LctPtRelBndry(lat,lon,flag) |
if ( (flag.eq.1).or.(flag.eq.2) ) then |
hn = hn+1 |
lonlist(hn) = lon |
latlist(hn) = lat |
endif |
lon = lon+ds/(deltat*cos(pi180*lat)) |
enddo |
lat = lat+ds/deltat |
enddo |
endif |
c Circle: equidistant |
if ( hmode.eq.'circle.eqd' ) then |
hn = 0 |
lat = ymin |
do while ( lat.le.ymax ) |
lon = xmin |
do while ( lon.le.xmax ) |
dist = sdis(lon1,lat1,lon,lat) |
if ( dist.le.radius ) then |
hn = hn+1 |
lonlist(hn) = lon |
latlist(hn) = lat |
endif |
lon = lon+ds/(deltat*cos(pi180*lat)) |
enddo |
lat = lat+ds/deltat |
enddo |
endif |
c Circle: grid |
if ( hmode.eq.'circle.grid' ) then |
hn = 0 |
do j=1,ny |
do i=1,nx |
lon = xmin + real(i-1) * dx |
lat = ymin + real(j-1) * dy |
dist = sdis(lon1,lat1,lon,lat) |
if ( dist.le.radius ) then |
hn = hn+1 |
lonlist(hn) = lon |
latlist(hn) = lat |
endif |
enddo |
enddo |
endif |
c Region: equidistant |
if ( hmode.eq.'region.eqd' ) then |
hn = 0 |
lat = ymin |
do while ( lat.le.ymax ) |
lon = xmin |
do while ( lon.le.xmax ) |
flag = inregion(lon,lat,xcorner,ycorner) |
if ( flag.eq.1 ) then |
hn = hn+1 |
lonlist(hn) = lon |
latlist(hn) = lat |
endif |
lon = lon+ds/(deltat*cos(pi180*lat)) |
enddo |
lat = lat+ds/deltat |
enddo |
endif |
c Region: grid |
if ( hmode.eq.'region.grid' ) then |
hn = 0 |
do j=1,ny |
do i=1,nx |
lon = xmin + real(i-1) * dx |
lat = ymin + real(j-1) * dy |
flag = inregion(lon,lat,xcorner,ycorner) |
if ( flag.eq.1 ) then |
hn = hn+1 |
lonlist(hn) = lon |
latlist(hn) = lat |
endif |
enddo |
enddo |
endif |
c ------ Get lev (vertical) coordinates ------------------------- |
c Read level list from file |
if ( vmode.eq.'file' ) then |
vn = 0 |
open(10,file=vfile) |
300 continue |
vn = vn + 1 |
read(10,*,end=301) levlist(vn) |
goto 300 |
301 continue |
vn = vn - 1 |
close(10) |
endif |
c Get single starting level |
if ( vmode.eq.'level' ) then |
vn = 1 |
levlist(vn) = lev1 |
endif |
c Get level profile |
if ( vmode.eq.'profile' ) then |
do i=1,vn |
levlist(i) = lev1 + real(i-1)/real(vn-1)*(lev2-lev1) |
enddo |
endif |
c Get all grid points in a layer: at the moment set the list of levels to |
c all indices from 1 to nz; later the correct subset of indices will be chosen |
if ( vmode.eq.'grid' ) then |
vn = nz |
do i=1,vn |
levlist(i) = real(i) |
enddo |
umode_save = umode |
umode = 'INDEX' |
endif |
c ------ Compile the complete list of starting positions ------ |
c Get all starting points in specified vertical coordinate system |
start_n = 0 |
do i=1,vn |
do j=1,hn |
start_n = start_n + 1 |
start_lon(start_n) = lonlist(j) |
start_lat(start_n) = latlist(j) |
start_lev(start_n) = levlist(i) |
enddo |
enddo |
c ------ Exit point of this section |
400 continue |
c Write status information |
print*,' # expanded points : ', start_n |
print* |
c ------------------------------------------------------------------ |
c Transform starting levels into pressure |
c ------------------------------------------------------------------ |
c Write some status information |
print*,'---- STARTING POSITIONS ---------------------------------' |
print* |
c Vertical mode <hPa,asl> or simply <hPa> |
if ( (umode.eq.'hPa,asl').or.(umode.eq.'hPa') ) then |
do i=1,start_n |
start_pre(i) = start_lev(i) |
enddo |
c Vertical mode <hPa,agl> |
elseif ( umode.eq.'hPa,agl' ) then |
do i=1,start_n |
call get_index3(rid,rjd,rkd,start_lon(i),start_lat(i),1050., |
> 3,pr,prs,nx,ny,nz,xmin,ymin,dx,dy) |
tmp1 = int_index3 (prs,nx,ny,1,rid,rjd,1,mdv) |
start_pre(i) = tmp1 - start_lev(i) |
enddo |
c Vertical mode <K> |
elseif ( umode.eq.'K' ) then |
do i=1,start_n |
call get_index3(rid,rjd,rkd,start_lon(i),start_lat(i), |
> start_lev(i),1,th,ths,nx,ny,nz,xmin,ymin,dx,dy) |
tmp1 = int_index3 (pr,nx,ny,nz,rid,rjd,rkd,mdv) |
start_pre(i) = tmp1 |
enddo |
c Vertical mode <PVU> |
elseif ( umode.eq.'PVU' ) then |
do i=1,start_n |
call get_index3(rid,rjd,rkd,start_lon(i),start_lat(i), |
> start_lev(i),2,pv,pvs,nx,ny,nz,xmin,ymin,dx,dy) |
tmp1 = int_index3 (pr,nx,ny,nz,rid,rjd,rkd,mdv) |
start_pre(i) = tmp1 |
enddo |
c Vertical mode <INDEX> |
elseif ( umode.eq.'INDEX' ) then |
do i=1,start_n |
call get_index3(rid,rjd,rkd,start_lon(i),start_lat(i), |
> 1050.,2,pv,pvs,nx,ny,nz,xmin,ymin,dx,dy) |
rkd = start_lev(i) |
tmp1 = int_index3 (pr,nx,ny,nz,rid,rjd,rkd,mdv) |
start_pre(i) = tmp1 |
enddo |
endif |
c ------------------------------------------------------------------ |
c Remove invalid points from the list |
c ------------------------------------------------------------------ |
c Select the correct subset if <vmode=grid>: starting points outside the layer |
c will receive a <mdv> vertical pressure and will be removed |
if ( vmode.eq.'grid' ) then |
do i=1,start_n |
c Get the pressure at the grid point |
if ( ( umode_save.eq.'hPa' ).or. |
> (umode_save.eq.'hPa,asl') ) |
> then |
call get_index3(rid,rjd,rkd,start_lon(i),start_lat(i), |
> start_pre(i),3,pr,prs,nx,ny,nz,xmin, |
> ymin,dx,dy) |
tmp1 = int_index3 (pr,nx,ny,nz,rid,rjd,rkd,mdv) |
c Get pressure AGL at grid point |
elseif ( umode_save.eq.'hPa,agl' ) then |
call get_index3(rid,rjd,rkd,start_lon(i), |
> start_lat(i),start_pre(i),3,pr,prs, |
> nx,ny,nz,xmin,ymin,dx,dy) |
tmp1 = int_index3 (pr,nx,ny,nz,rid,rjd,rkd,mdv) |
call get_index3(rid,rjd,rkd,start_lon(i), |
> start_lat(i),1050.,3,pr,prs,nx,ny, |
> nz,xmin,ymin,dx,dy) |
tmp2 = int_index3 (prs,nx,ny,1,rid,rjd,1,mdv) |
tmp1 = tmp2 - tmp1 |
c Get potential temperature at grid point |
elseif ( umode_save.eq.'K' ) then |
call get_index3(rid,rjd,rkd,start_lon(i),start_lat(i), |
> start_pre(i),3,pr,prs,nx,ny,nz, |
> xmin,ymin,dx,dy) |
tmp1 = int_index3 (th,nx,ny,nz,rid,rjd,rkd,mdv) |
c Get potential vorticity at the grid point |
elseif ( umode_save.eq.'PVU' ) then |
call get_index3(rid,rjd,rkd,start_lon(i),start_lat(i), |
> start_pre(i),3,pr,prs,nx,ny,nz,xmin, |
> ymin,dx,dy) |
tmp1 = int_index3 (pv,nx,ny,nz,rid,rjd,rkd,mdv) |
c Get vertical index at the grid point |
elseif ( umode_save.eq.'INDEX' ) then |
call get_index3(rid,rjd,rkd,start_lon(i),start_lat(i), |
> start_pre(i),3,pr,prs,nx,ny,nz, |
> xmin,ymin,dx,dy) |
tmp1 = int_index3 (in,nx,ny,nz,rid,rjd,rkd,mdv) |
endif |
c Remove points outside layer |
if ( ( tmp1.lt.lev1).or.(tmp1.gt.lev2) ) then |
start_pre(i) = mdv |
endif |
enddo |
endif |
c Check whether the starting levels are valid (in data domain) |
do i=1,start_n |
call get_index3(rid,rjd,rkd,start_lon(i),start_lat(i),1050., |
> 3,pr,prs,nx,ny,nz,xmin,ymin,dx,dy) |
tmp1 = int_index3 (prs,nx,ny, 1,rid,rjd,real( 1),mdv) ! Surface |
tmp2 = int_index3 (pr ,nx,ny,nz,rid,rjd,real(nz),mdv) ! Top of domain |
if ( (start_pre(i).gt.tmp1).or. |
> (start_pre(i).lt.tmp2).or. |
> (start_lon(i).lt.xmin).or. |
> (start_lon(i).gt.xmax).or. |
> (start_lat(i).lt.ymin).or. |
> (start_lat(i).gt.ymax) ) |
> then |
start_pre(i) = mdv |
endif |
enddo |
c Remove all starting points outside the domain |
i = 1 |
do while ( i.le.start_n ) |
if ( abs(start_pre(i)-mdv).lt.eps ) then |
if ( vmode.ne.'grid') then |
print*,' Outside ', start_lon(i),start_lat(i),start_lev(i) |
endif |
do j=i,start_n |
start_lon(j) = start_lon(j+1) |
start_lat(j) = start_lat(j+1) |
start_pre(j) = start_pre(j+1) |
start_lev(j) = start_lev(j+1) |
enddo |
start_n = start_n - 1 |
else |
i = i + 1 |
endif |
enddo |
c Write some status information |
latmin = start_lat(1) |
latmax = start_lat(1) |
lonmin = start_lon(1) |
lonmax = start_lon(1) |
premin = start_pre(1) |
premax = start_pre(1) |
do i=1,start_n |
if (start_lat(i).lt.latmin) latmin = start_lat(i) |
if (start_lat(i).gt.latmax) latmax = start_lat(i) |
if (start_lon(i).lt.lonmin) lonmin = start_lon(i) |
if (start_lon(i).gt.lonmax) lonmax = start_lon(i) |
if (start_pre(i).lt.premin) premin = start_pre(i) |
if (start_pre(i).gt.premax) premax = start_pre(i) |
enddo |
print*,' min(lat),max(lat) : ', latmin,latmax |
print*,' min(lon),max(lon) : ', lonmin,lonmax |
print*,' min(pre),max(pre) : ', premin,premax |
print* |
print*,' # starting points : ', start_n |
print* |
c ------------------------------------------------------------------ |
c Write starting positions to output file |
c ------------------------------------------------------------------ |
c Output as a trajectory file (with only one time == 0) |
if (oformat.ne.-1) then |
allocate(tra(start_n,1,5),stat=stat) |
vars(1) ='time' |
vars(2) ='lon' |
vars(3) ='lat' |
vars(4) ='p' |
vars(5) ='level' |
call wopen_tra(fid,ofile,start_n,1,5,reftime,vars,oformat) |
do i=1,start_n |
tra(i,1,1) = 0. |
tra(i,1,2) = start_lon(i) |
tra(i,1,3) = start_lat(i) |
tra(i,1,4) = start_pre(i) |
tra(i,1,5) = start_lev(i) |
enddo |
call write_tra(fid,tra,start_n,1,5,oformat) |
call close_tra(fid,oformat) |
c Output as a triple list (corresponding to <startf> file) |
else |
fid = 10 |
open(fid,file=ofile) |
do i=1,start_n |
write(fid,'(3f10.3)') start_lon(i),start_lat(i), |
> start_pre(i) |
enddo |
close(fid) |
endif |
c Write some status information, and end of program message |
print* |
print*,'---- STATUS INFORMATION --------------------------------' |
print* |
print*,'ok' |
print* |
print*,' *** END OF PROGRAM CREATE_STARTF ***' |
print*,'=========================================================' |
c ------------------------------------------------------------------ |
c Exception handling |
c ------------------------------------------------------------------ |
stop |
993 write(*,*) '*** ERROR: problems with array size' |
call exit(1) |
end |
c -------------------------------------------------------------------------- |
c Split a region string and get corners of the domain |
c -------------------------------------------------------------------------- |
subroutine regionsplit(string,iregion,xcorner,ycorner) |
c The region string comes either as <lonw,lone,lats,latn> or as <lon1,lat1, |
c lon2,lat2,lon3,lat3,lon4,lat4>: split it into ints components and get the |
c four coordinates for the region |
implicit none |
c Declaration of subroutine parameters |
character*80 string |
real xcorner(4),ycorner(4) |
integer iregion |
c Local variables |
integer i,n |
integer il,ir |
real subfloat (80) |
integer stat |
integer len |
c ------- Split the string |
i = 1 |
n = 0 |
stat = 0 |
il = 1 |
len = len_trim(string) |
100 continue |
c Find start of a substring |
do while ( stat.eq.0 ) |
if ( string(i:i).ne.' ' ) then |
stat = 1 |
il = i |
else |
i = i + 1 |
endif |
enddo |
c Find end of substring |
do while ( stat.eq.1 ) |
if ( ( string(i:i).eq.' ' ) .or. ( i.eq.len ) ) then |
stat = 2 |
ir = i |
else |
i = i + 1 |
endif |
enddo |
c Convert the substring into a number |
if ( stat.eq.2 ) then |
n = n + 1 |
read(string(il:ir),*) subfloat(n) |
stat = 0 |
endif |
if ( i.lt.len ) goto 100 |
c -------- Get the region number |
iregion = nint(subfloat(1)) |
c -------- Get the corners of the region |
if ( n.eq.5 ) then ! lonw(2),lone(3),lats(4),latn(5) |
xcorner(1) = subfloat(2) |
ycorner(1) = subfloat(4) |
xcorner(2) = subfloat(3) |
ycorner(2) = subfloat(4) |
xcorner(3) = subfloat(3) |
ycorner(3) = subfloat(5) |
xcorner(4) = subfloat(2) |
ycorner(4) = subfloat(5) |
elseif ( n.eq.9 ) then ! lon1,lat1,lon2,lat2,lon3,lon4,lat4 |
xcorner(1) = subfloat(2) |
ycorner(1) = subfloat(3) |
xcorner(2) = subfloat(4) |
ycorner(2) = subfloat(5) |
xcorner(3) = subfloat(6) |
ycorner(3) = subfloat(7) |
xcorner(4) = subfloat(8) |
ycorner(4) = subfloat(9) |
else |
print*,' ERROR: invalid region specification ' |
print*,' ',trim(string) |
stop |
endif |
end |
c -------------------------------------------------------------------------- |
c Decide whether lat/lon point is in or out of region |
c -------------------------------------------------------------------------- |
integer function inregion (lon,lat,xcorner,ycorner) |
c Decide whether point (lon/lat) is in the region specified by <xcorner(1..4), |
c ycorner(1..4). |
implicit none |
c Declaration of subroutine parameters |
real lon,lat |
real xcorner(4),ycorner(4) |
c Local variables |
integer flag |
real xmin,xmax,ymin,ymax |
integer i |
c Reset the flag |
flag = 0 |
c Set some boundaries |
xmax = xcorner(1) |
xmin = xcorner(1) |
ymax = ycorner(1) |
ymin = ycorner(1) |
do i=2,4 |
if (xcorner(i).lt.xmin) xmin = xcorner(i) |
if (xcorner(i).gt.xmax) xmax = xcorner(i) |
if (ycorner(i).lt.ymin) ymin = ycorner(i) |
if (ycorner(i).gt.ymax) ymax = ycorner(i) |
enddo |
c Do the tests - set flag=1 if all tests pased |
if (lon.lt.xmin) goto 970 |
if (lon.gt.xmax) goto 970 |
if (lat.lt.ymin) goto 970 |
if (lat.gt.ymax) goto 970 |
if ((lon-xcorner(1))*(ycorner(2)-ycorner(1))- |
> (lat-ycorner(1))*(xcorner(2)-xcorner(1)).gt.0.) goto 970 |
if ((lon-xcorner(2))*(ycorner(3)-ycorner(2))- |
> (lat-ycorner(2))*(xcorner(3)-xcorner(2)).gt.0.) goto 970 |
if ((lon-xcorner(3))*(ycorner(4)-ycorner(3))- |
> (lat-ycorner(3))*(xcorner(4)-xcorner(3)).gt.0.) goto 970 |
if ((lon-xcorner(4))*(ycorner(1)-ycorner(4))- |
> (lat-ycorner(4))*(xcorner(1)-xcorner(4)).gt.0.) goto 970 |
flag = 1 |
c Return the value |
970 continue |
inregion = flag |
return |
end |
c -------------------------------------------------------------------------- |
c Spherical distance between lat/lon points |
c -------------------------------------------------------------------------- |
real function sdis(xp,yp,xq,yq) |
c |
c calculates spherical distance (in km) between two points given |
c by their spherical coordinates (xp,yp) and (xq,yq), respectively. |
c |
real re |
parameter (re=6370.) |
real pi180 |
parameter (pi180=3.14159/180.) |
real xp,yp,xq,yq,arg |
arg=sin(pi180*yp)*sin(pi180*yq)+ |
> cos(pi180*yp)*cos(pi180*yq)*cos(pi180*(xp-xq)) |
if (arg.lt.-1.) arg=-1. |
if (arg.gt.1.) arg=1. |
sdis=re*acos(arg) |
end |
c **************************************************************** |
c * Given some spherical polygon S and some point X known to be * |
c * located inside S, these routines will determine if an arbit- * |
c * -rary point P lies inside S, outside S, or on its boundary. * |
c * The calling program must first call DefSPolyBndry to define * |
c * the boundary of S and the point X. Any subsequent call to * |
c * subroutine LctPtRelBndry will determine if some point P lies * |
c * inside or outside S, or on its boundary. (Usually * |
c * DefSPolyBndry is called once, then LctPrRelBndry is called * |
c * many times). * |
c * * |
c * REFERENCE: Bevis, M. and Chatelain, J.-L. (1989) * |
c * Maflaematical Geology, vol 21. * |
c * VERSION 1.0 * |
c **************************************************************** |
Subroutine DefSPolyBndry(vlat,vlon,nv,xlat, xlon) |
c **************************************************************** |
c * This mmn entry point is used m define ~e spheric~ polygon S * |
c * and the point X. * |
c * ARGUMENTS: * |
c * vlat,vlon (sent) ... vectors containing the latitude and * |
c * longitude of each vertex of the * |
c * spherical polygon S. The ith.vertex is * |
c * located at [vlat(i),vlon(i)]. * |
c * nv (sent) ... the number of vertices and sides in the * |
c * spherical polygon S * |
c * xlat,xlon (sent) ... latitude and longitude of some point X * |
c * located inside S. X must not be located * |
c * on any great circle that includes two * |
c * vertices of S. * |
c * * |
c * UNITS AND SIGN CONVENTION: * |
c * Latitudes and longitudes are specified in degrees. * |
c * Latitudes are positive to the north and negative to the * |
c * south. * |
c * Longitudes are positive to the east and negative to the * |
c * west. * |
c * * |
c * VERTEX ENUMERATION: * |
c * The vertices of S should be numbered sequentially around the * |
c * border of the spherical polygon. Vertex 1 lies between vertex* |
c * nv and vertex 2. Neighbouring vertices must be seperated by * |
c * less than 180 degrees. (In order to generate a polygon side * |
c * whose arc length equals or exceeds 180 degrees simply * |
c * introduce an additional (pseudo)vertex). Having chosen * |
c * vertex 1, the user may number the remaining vertices in * |
c * either direction. However if the user wishes to use the * |
c * subroutine SPA to determine the area of the polygon S (Bevis * |
c * & Cambareri, 1987, Math. Geol., v.19, p. 335-346) then he or * |
c * she must follow the convention whereby in moving around the * |
c * polygon border in the direction of increasing vertex number * |
c * clockwise bends occur at salient vertices. A vertex is * |
c * salient if the interior angle is less than 180 degrees. * |
c * (In the case of a convex polygon this convention implies * |
c * that vertices are numbered in clockwise sequence). * |
c **************************************************************** |
implicit none |
integer mxnv,nv |
c ---------------------------------------------------------------- |
c Edit next statement to increase maximum number of vertices that |
c may be used to define the spherical polygon S |
c The value of parameter mxnv in subroutine LctPtRelBndry must match |
c that of parameter mxnv in this subroutine, as assigned above. |
c ---------------------------------------------------------------- |
parameter (mxnv=500) |
real vlat(nv),vlon(nv),xlat,xlon,dellon |
real tlonv(mxnv),vlat_c(mxnv),vlon_c(mxnv),xlat_c,xlon_c |
integer i,ibndry,nv_c,ip |
data ibndry/0/ |
common/spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry |
if (nv.gt.mxnv) then |
print *,'nv exceeds maximum allowed value' |
print *,'adjust parameter mxnv in subroutine DefSPolyBndry' |
stop |
endif |
ibndry=1 ! boundary defined at least once (flag) |
nv_c=nv ! copy for named common |
xlat_c=xlat ! . . . . |
xlon_c=xlon ! |
do i=1,nv |
vlat_c(i)=vlat(i) ! " |
vlon_c(i)=vlon(i) ! |
call TrnsfmLon(xlat,xlon,vlat(i),vlon(i),tlonv(i)) |
if (i.gt.1) then |
ip=i-1 |
else |
ip=nv |
endif |
if ((vlat(i).eq.vlat(ip)).and.(vlon(i).eq.vlon(ip))) then |
print *,'DefSPolyBndry detects user error:' |
print *,'vertices ',i,' and ',ip,' are not distinct' |
print*,'lat ',i,ip,vlat(i),vlat(ip) |
print*,'lon ',i,ip,vlon(i),vlon(ip) |
stop |
endif |
if (tlonv(i).eq.tlonv(ip)) then |
print *,'DefSPolyBndry detects user error:' |
print *,'vertices ',i,' & ',ip,' on same gt. circle as X' |
stop |
endif |
if (vlat(i).eq.(-vlat(ip))) then |
dellon=vlon(i)-vlon(ip) |
if (dellon.gt.+180.) dellon=dellon-360. |
if (dellon.lt.-180.) dellon=dellon-360. |
if ((dellon.eq.+180.0).or.(dellon.eq.-180.0)) then |
print *,'DefSPolyBndry detects user error:' |
print *,'vertices ',i,' and ',ip,' are antipodal' |
stop |
endif |
endif |
enddo |
return |
end |
c **************************************************************** |
Subroutine LctPtRelBndry(plat,plon,location) |
c **************************************************************** |
c **************************************************************** |
c * This routine is used to see if some point P is located * |
c * inside, outside or on the boundary of the spherical polygon * |
c * S previously defined by a call to subroutine DefSPolyBndry. * |
c * There is a single restriction on point P: it must not be * |
c * antipodal to the point X defined in the call to DefSPolyBndry* |
c * (ie.P and X cannot be seperated by exactly 180 degrees). * |
c * ARGUMENTS: * |
c * plat,plon (sent)... the latitude and longitude of point P * |
c * location (returned)... specifies the location of P: * |
c * location=0 implies P is outside of S * |
c * location=1 implies P is inside of S * |
c * location=2 implies P on boundary of S * |
c * location=3 implies user error (P is * |
c * antipodal to X) * |
c * UNFfS AND SIGN CONVENTION: * |
c * Latitudes and longitudes are specified in degrees. * |
c * Latitudes are positive to the north and negative to the * |
c * south. * |
c * Longitudes are positive to the east and negative to the * |
c * west. * |
c **************************************************************** |
implicit none |
integer mxnv |
c ---------------------------------------------------------------- |
c The statement below must match that in subroutine DefSPolyBndry |
c ---------------------------------------------------------------- |
parameter (mxnv=500) |
real tlonv(mxnv),vlat_c(mxnv),vlon_c(mxnv),xlat_c,xlon_c |
real plat,plon,vAlat,vAlon,vBlat,vBlon,tlonA,tlonB,tlonP |
real tlon_X,tlon_P,tlon_B,dellon |
integer i,ibndry,nv_c,location,icross,ibrngAB,ibrngAP,ibrngPB |
integer ibrng_BX,ibrng_BP,istrike |
common/spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry |
if (ibndry.eq.0) then ! user has never defined the bndry |
print*,'Subroutine LctPtRelBndry detects user error:' |
print*,'Subroutine DefSPolyBndry must be called before' |
print*,'subroutine LctPtRelBndry can be called' |
stop |
endif |
if (plat.eq.(-xlat_c)) then |
dellon=plon-xlon_c |
if (dellon.lt.(-180.)) dellon=dellon+360. |
if (dellon.gt.+180.) dellon=dellon-360. |
if ((dellon.eq.+180.0).or.(dellon.eq.-180.)) then |
print*,'Warning: LctPtRelBndry detects case P antipodal |
> to X' |
print*,'location of P relative to S is undetermined' |
location=3 |
return |
endif |
endif |
location=0 ! default ( P is outside S) |
icross=0 ! initialize counter |
if ((plat.eq.xlat_c).and.(plon.eq.xlon_c)) then |
location=1 |
return |
endif |
call TrnsfmLon (xlat_c,xlon_c,plat,plon,tlonP) |
do i=1,nv_c ! start of loop over sides of S |
vAlat=vlat_c(i) |
vAlon=vlon_c(i) |
tlonA=tlonv(i) |
if (i.lt.nv_c) then |
vBlat=vlat_c(i+1) |
vBlon=vlon_c(i+1) |
tlonB=tlonv(i+1) |
else |
vBlat=vlat_c(1) |
vBlon=vlon_c(1) |
tlonB=tlonv(1) |
endif |
istrike=0 |
if (tlonP.eq.tlonA) then |
istrike=1 |
else |
call EastOrWest(tlonA,tlonB,ibrngAB) |
call EastOrWest(tlonA,tlonP,ibrngAP) |
call EastOrWest(tlonP,tlonB,ibrngPB) |
if((ibrngAP.eq.ibrngAB).and.(ibrngPB.eq.ibrngAB)) istrike=1 |
endif |
if (istrike.eq.1) then |
if ((plat.eq.vAlat).and.(plon.eq.vAlon)) then |
location=2 ! P lies on a vertex of S |
return |
endif |
call TrnsfmLon(vAlat,vAlon,xlat_c,xlon_c,tlon_X) |
call TrnsfmLon(vAlat,vAlon,vBlat,vBlon,tlon_B) |
call TrnsfmLon(vAlat,vAlon,plat,plon,tlon_P) |
if (tlon_P.eq.tlon_B) then |
location=2 ! P lies on side of S |
return |
else |
call EastOrWest(tlon_B,tlon_X,ibrng_BX) |
call EastOrWest(tlon_B,tlon_P,ibrng_BP) |
if(ibrng_BX.eq.(-ibrng_BP)) icross=icross+1 |
endif |
endif |
enddo ! end of loop over the sides of S |
c if the arc XP crosses the boundary S an even number of times then P |
c is in S |
if (mod(icross,2).eq.0) location=1 |
return |
end |
c **************************************************************** |
subroutine TrnsfmLon(plat,plon,qlat,qlon,tranlon) |
c **************************************************************** |
c * This subroutine is required by subroutines DefSPolyBndry & * |
c * LctPtRelBndry. It finds the 'longitude' of point Q in a * |
c * geographic coordinate system for which point P acts as a * |
c * 'north pole'. SENT: plat,plon,qlat,qlon, in degrees. * |
c * RETURNED: tranlon, in degrees. * |
c **************************************************************** |
implicit none |
real pi,dtr,plat,plon,qlat,qlon,tranlon,t,b |
parameter (pi=3.141592654,dtr=pi/180.0) |
if (plat.eq.90.) then |
tranlon=qlon |
else |
t=sin((qlon-plon)*dtr)*cos(qlat*dtr) |
b=sin(dtr*qlat)*cos(plat*dtr)-cos(qlat*dtr)*sin(plat*dtr) |
> *cos((qlon-plon)*dtr) |
tranlon=atan2(t,b)/dtr |
endif |
return |
end |
c **************************************************************** |
subroutine EastOrWest(clon,dlon,ibrng) |
c **************************************************************** |
c * This subroutine is required by subroutine LctPtRelBndry. * |
c * This routine determines if in travelling the shortest path * |
c * from point C (at longitude clon) to point D (at longitude * |
c * dlon) one is heading east, west or neither. * |
c * SENT: clon,dlon; in degrees. RETURNED: ibrng * |
c * (1=east,-1=west, 0=neither). * |
c **************************************************************** |
implicit none |
real clon,dlon,del |
integer ibrng |
del=dlon-clon |
if (del.gt.180.) del=del-360. |
if (del.lt.-180.) del=del+360. |
if ((del.gt.0.0).and.(del.ne.180.)) then |
ibrng=-1 ! (D is west of C) |
elseif ((del.lt.0.0).and.(del.ne.-180.)) then |
ibrng=+1 ! (D is east of C) |
else |
ibrng=0 ! (D north or south of C) |
endif |
return |
end |
/tags/1.0/create_startf/create_startf.m |
---|
0,0 → 1,30 |
% ------------------------------------------------------------------------- |
% Plot horizontal starting positions |
% ------------------------------------------------------------------------- |
% Load starting points |
[ start.lon start.lat start.p ] = textread('TEST','%f %f %f',-1); |
% Open a new figure and set the geographical projection and region |
figure(1); |
clf; |
load coast |
h=axesm('MapProjection','stereo','origin',[ 90 70 ]); |
gridm; |
h=plotm(lat,long,'Color','k','LineWidth',1.5) |
%axis([-1.5 1.5 -2 0]); |
% Plot starting points |
for i=1:length(start.lon) |
linem(start.lat(i),start.lon(i),'marker','o', ... |
'markersize',4,'color','w','MarkerEdgeColor',[.4 .4 .4], ... |
'MarkerFaceColor','b'); |
end |
% Save figure |
figname = [ 'startf.eps' ]; |
set(gcf, 'PaperPosition', [2 1 15 10]); |
print('-depsc2','-r0',figname); |
/tags/1.0/create_startf/create_startf.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = create_startf.o ${LAGRANTO}/lib/times.a ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/ioinp.a ${LAGRANTO}/lib/inter.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
create_startf: $(OBJS) |
${F77} -o create_startf $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/create_startf/create_startf.perl |
---|
0,0 → 1,208 |
#!/usr/bin/perl |
# -------------------------------------------------------- |
# Separate different commands out (delimiter @) |
# -------------------------------------------------------- |
# Get input command and remove all spaces |
$cmd = $ARGV[0]; |
$_ = $cmd;s/\s+//g;$cmd=$_; |
$len = length $cmd; |
# Split the command string according to logical operators |
$nline = 0; |
while ( $len > 0 ) |
{ |
# Get the length of the (remaining) command string |
$len = length $cmd; |
# Get the position of the next command separator |
$at = index($cmd,'@'); |
if ( $at == -1 ) |
{ $next = $len+1; } |
elsif ( $at >= 0 ) |
{ $next = $at; } |
# A logical operator is not allowed to be at position 0 |
if ( $next == 0) |
{ |
die('Invalid expression... Check @ separator position '); |
} |
# Extract the next substring |
$sub = substr($cmd,0,$next); |
$cmd = substr($cmd,$next+1,$len-$next-1); |
$len = length $cmd; |
# Save the command in a new line |
@field[$nline] = $sub; |
$nline = $nline + 1; |
} |
# Number of lines ist too large by 1 |
$nline = $nline - 1; |
# Set some defaults |
if ( $nline == 2 ) |
{ |
$nline = 3; |
@field[3] = 'nil'; |
} |
if ( $nline == 1 ) |
{ |
$nline = 3; |
@field[2] = 'hPa'; |
@field[3] = 'nil'; |
} |
if ( $nline == 0 ) |
{ |
$nline = 3; |
@field[1] = 'nil()'; |
@field[2] = 'hPa'; |
@field[3] = 'nil'; |
} |
# -------------------------------------------------------- |
# Handle each command line separately |
# -------------------------------------------------------- |
# ----- Horizontal grid ---------------------------------- |
# Now looking at the horizontal grid specifier |
$entry = @field[0]; |
# Extract the command and the parameter list |
$left = index($entry,'('); |
$right = index($entry,')'); |
if ( ($left != -1) && ($right != -1) ) |
{ |
$cmd = substr($entry,0,$left); |
$list = substr($entry,$left+1,$right-$left-1); |
$len = length $list; |
} |
else |
{ |
die('Invalid expression... Check horizontal [] separator position '); |
} |
# Now building the parametr list |
$len = length $list; |
$npar = 0; |
while ( $len > 0 ) |
{ |
$next = index($list,','); |
if ( $next != -1 ) |
{ |
@param[$npar] = substr($list,0,$next); |
$list = substr($list,$next+1,$len-$next-1); |
$len = length $list; |
$npar = $npar + 1; |
} |
else |
{ |
@param[$npar] = substr($list,0,$len); |
$len = 0; |
$npar = $npar + 1; |
} |
} |
# Check for syntax (needed number of parameters) |
if ( ($cmd eq "file") && ($npar != 1) ) |
{ die('Invalid horizontal mode[file]... Check number of parameters '); } |
if ( ($cmd eq "line") && ($npar != 5) ) |
{ die('Invalid horizontal mode[line]... Check number of parameters '); } |
if ( ($cmd eq "box.eqd") && ($npar != 5) ) |
{ die('Invalid horizontal mode[box.eqd]... Check number of parameters '); } |
if ( ($cmd eq "box.grid") && ($npar != 4) ) |
{ die('Invalid horizontal mode[box.grid]... Check number of parameters '); } |
if ( ($cmd eq "point") && ($npar != 2) ) |
{ die('Invalid horizontal mode[point]... Check number of parameters '); } |
if ( ($cmd eq "shift") && ($npar != 4) ) |
{ die('Invalid horizontal mode[shift]... Check number of parameters '); } |
if ( ($cmd eq "poly.eqd") && ($npar != 2) ) |
{ die('Invalid horizontal mode[poly.eqd]... Check number of parameters '); } |
if ( ($cmd eq "poly.grid") && ($npar != 1) ) |
{ die('Invalid horizontal mode[poly.grid]... Check number of parameters ');} |
# Write parameters |
print "\"$cmd\"\n"; |
print "@param\n"; |
# ----- Vertical grid ---------------------------------------- |
# Now looking at the vertical grid specifier |
$entry = @field[1]; |
# Extract the command and the parameter list |
$left = index($entry,'('); |
$right = index($entry,')'); |
if ( ($left != -1) && ($right != -1) ) |
{ |
$cmd = substr($entry,0,$left); |
$list = substr($entry,$left+1,$right-$left-1); |
$len = length $list; |
} |
else |
{ |
die('Invalid expression... Check vertical [] separator position '); |
} |
# Now building the parametr list |
$len = length $list; |
$npar = 0; |
while ( $len > 0 ) |
{ |
$next = index($list,','); |
if ( $next != -1 ) |
{ |
@param[$npar] = substr($list,0,$next); |
$list = substr($list,$next+1,$len-$next-1); |
$len = length $list; |
$npar = $npar + 1; |
} |
else |
{ |
@param[$npar] = substr($list,0,$len); |
$len = 0; |
$npar = $npar + 1; |
} |
} |
# Check for syntax (needed number of parameters) |
if ( ($cmd eq "file") && ($npar != 1) ) |
{ die('Invalid vertical mode[file]... Check number of parameters '); } |
if ( ($cmd eq "level") && ($npar != 1) ) |
{ die('Invalid vertical mode[level]... Check number of parameters '); } |
if ( ($cmd eq "list") && ($npar == 0) ) |
{ die('Invalid vertical mode[list]... Check number of parameters '); } |
if ( ($cmd eq "profile") && ($npar != 3) ) |
{ die('Invalid vertical mode[profile]... Check number of parameters '); } |
if ( ($cmd eq "grid") && ($npar != 2) ) |
{ die('Invalid vertical mode[grid]... Check number of parameters '); } |
# Write parameters |
print "\"$cmd\"\n"; |
if ( $cmd eq "list") { print "$npar\n"; } |
if ( $npar > 0 ) |
{ print "@param\n"; } |
# ----- Vertical coordinate system ---------------------------------- |
# Now looking at the vertical grid specifier |
$cmd = @field[2]; |
# Check for allowed coordinate axes |
if ( ($cmd ne "hPa") && ($cmd ne "hPa,agl") && ($cmd ne "K") && ($cmd ne "PVU") && ($cmd ne "INDEX") ) |
{ die('Invalid vertical axis [allowed: hPa / hPa,agl / K / PVU / INDEX] '); } |
# Write command |
print "\"$cmd\"\n"; |
# ----- Selection criteria -------------------------------------------- |
# Now looking at the selection specifier |
$cmd = @field[3]; |
# Write command |
print "$cmd\n"; |
Property changes: |
Added: svn:executable |
/tags/1.0/create_startf/create_startf.sh |
---|
0,0 → 1,347 |
#!/bin/csh |
# ----------------------------------------------------------------------------------------------------------------- |
# Usage and parameter handling |
# ----------------------------------------------------------------------------------------------------------------- |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0 ) then |
echo |
${LAGRANTO}/bin/lagrantohelp create_startf short |
echo |
exit 1 |
endif |
# ----------------------------------------------------------------------------------------------------------------- |
# Handle input parameters |
# ----------------------------------------------------------------------------------------------------------------- |
# Prefix of primary and secondary file; and set the filenames |
set charp='P' |
set chars='S' |
# Write title |
echo |
echo '=========================================================' |
echo ' *** START OF PREPROCESSOR CREATE_STARTF *** ' |
echo |
# Extract arguments and split reference date |
set refdate = $1 |
set ofile = $2 |
set specifier = `echo $3` |
shift |
shift |
shift |
# Check whether specifier is a file or whether it is explicitly written |
set flag_criterion = 'file' |
set test = `echo ${specifier} | grep '@' | wc -c` |
if ( "${test}" != "0" ) then |
set flag_criterion = 'criterion' |
endif |
# Get the criterion from the file |
if ( "${flag_criterion}" == "file" ) then |
if ( -f ${specifier} ) then |
set filename = ${specifier} |
set specifier = `cat ${specifier}` |
else |
echo " ERROR: cannot read criterion from file ${specifier}... Stop" |
exit 1 |
endif |
endif |
echo "---- INPUT PARAMETERS ----------------------------------" |
echo |
echo "Reference date : ${refdate}" |
if ( "${flag_criterion}" == "criterion" ) then |
echo "Specifier : ${specifier}" |
else |
echo "Specifier : ${specifier} [from file ${filename}]" |
endif |
echo "Output file : ${ofile}" |
echo |
# Handle optional arguments |
set tvfile = 'tracevars' |
set changet = 'false' |
set noclean = 'false' |
set regionf = 'regionf' |
set timecheck = 'no' |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -t |
set tvfile = $argv[2] |
echo "tvfile -> ${tvfile} (user defined)" |
shift; |
breaksw |
case -changet |
set changet = 'true' |
echo "changet -> true (user defined)" |
breaksw |
case -noclean |
set noclean = 'true' |
echo "noclean -> true (user defined)" |
breaksw |
case -timecheck |
set timecheck = 'yes' |
echo "timecheck -> yes (user defined)" |
breaksw |
case -regionf |
set regionf = $argv[2] |
echo "regionf -> ${regionf} (user defined)" |
shift; |
breaksw |
endsw |
shift; |
end |
# No change of times necessary if no check requested |
if ( "${timecheck}" == "no" ) then |
set changet = 'false' |
endif |
# Split the reference date |
set yyyy=`echo ${refdate} | cut -c 1-4` |
set mm=`echo ${refdate} | cut -c 5-6` |
set dd=`echo ${refdate} | cut -c 7-8` |
set hh=`echo ${refdate} | cut -c 10-11` |
set min=`echo ${refdate}00 | cut -c 12-13` |
# Set base directories (run+prog) |
set tradir=${PWD} |
# Set program paths and filenames |
set parfile=${tradir}/create_startf.param |
set crifile=${tradir}/create_startf.criterion |
# Decide whether a tracing and selection is necessary |
# If so, some intermediate file are writen (in Fortran binary) |
set flag = `${LAGRANTO}/startf/create_startf.perl "${specifier}" | tail -1` |
if ( "${flag}" != "nil" ) then |
set format1 = ".3" |
set format2 = ".3" |
else |
set format1 = "" |
set format2 = "" |
endif |
# Write status information |
echo |
echo '---- DIRECTORIES AND PROGRAMS ---------------------------' |
echo |
echo "PROGRAM CREATE_STARTF : ${LAGRANTO}/startf/create_startf" |
echo "PARAMETER file : ${parfile}" |
echo "CRITERION file : ${crifile}" |
echo "RUN directory : ${tradir}" |
echo |
# ----------------------------------------------------------------------------------------------------------------- |
# Set the primary and scecondary data files (necessary for interpolation if intermediate reference date) |
# ----------------------------------------------------------------------------------------------------------------- |
# Find a first data file (if possible corresponding to reference date) |
set file=${charp}${yyyy}${mm}${dd}_${hh} |
if ( ( -f ${file} ) && ( ${min} == 0 ) ) then |
set timeshift=0 |
set date0=${yyyy}${mm}${dd}_${hh} |
set date1=${yyyy}${mm}${dd}_${hh} |
set pfile0=${file1} |
set pfile1=${file} |
goto label3 |
else |
set file=`ls ${charp}[0-9_]*[0-9] | head -1 | sed -e 's/@//'` |
endif |
# Determine time increment (in hours) between data files |
set date1=`echo $file | cut -c 2-12` |
set n=`ls ${charp}[0-9_]*[0-9] | grep -n $date1 | awk -F: '{print $1}'` |
@ n ++ |
set date2=`ls ${charp}[0-9_]*[0-9] | head -$n | tail -1 | cut -c 2-12` |
set timeinc=`${LAGRANTO}/goodies/gettidiff $date2 $date1` |
endif |
if ( $timeinc == 0 ) then |
echo " ERROR: cannot set the time increment between input files ***" |
exit 1 |
endif |
# Search the first file to use |
set timeshift= |
foreach i ( ${charp}????????_?? ) |
set date0 = `echo $i | cut -c 2-12` |
set td1 = `${LAGRANTO}/goodies/gettidiff ${yyyy}${mm}${dd}_${hh} ${date0}` |
if ( ( $td1 >= 0 ) && ( $td1 < $timeinc ) ) then |
set timeshift=$td1 |
set pfile0=${charp}${date0} |
goto label2 |
endif |
end |
# Check if no P files are available for the specified time period |
if ( $timeshift == "" ) then |
echo " ERROR: no data files available for the specified reference date" |
exit 1 |
endif |
# Everything is fine so far: proceed |
label2: |
# Set the next date and check its availability |
if ( ( ${timeshift} != 0 ) || ( ${min} > 0 ) ) then |
set date1=`${LAGRANTO}/goodies/newtime $date0 $timeinc` |
if ( ! -f ${charp}${date1} ) then |
echo " ERROR: file with primary data is missing for $date1" |
exit 1 |
else |
set pfile1=${charp}${date1} |
endif |
else |
set date1=${date0} |
set pfile1=${pfile0} |
endif |
# Set the final timeshift |
if ( ${min} != 00 ) then |
set timeshift=${timeshift}.${min} |
endif |
# Everything is fine! |
label3: |
# Set secondary files and check their availability |
set sfile0=${chars}${date0} |
set sfile1=${chars}${date1} |
# Write status information |
echo '---- DATA FILES -----------------------------------------' |
echo |
echo "Primary files : ${pfile0}" |
echo " : ${pfile1}" |
echo "Secondary files : ${sfile0}" |
echo " : ${sfile1}" |
echo "Timeshift to first data file (hh.mm) : ${timeshift}" |
echo "Time increment of data files : ${timeinc}" |
echo |
# -------------------------------------------------------------------------------------------------------------- |
# Create the start positions (without selection) |
# ----------------------------------------------------------------------------------------------------------------- |
# Set times relative to the reference date |
if ( "${changet}" == "true" ) then |
echo '---- CHANGE TIMES ON DATA FILES ------------------------' |
echo |
${LAGRANTO}/goodies/changet.sh ${refdate} ${pfile0} |
${LAGRANTO}/goodies/changet.sh ${refdate} ${pfile1} |
if ( -f ${sfile0} ) then |
${LAGRANTO}/goodies/changet.sh ${refdate} ${sfile0} |
endif |
if ( -f ${sfile1} ) then |
${LAGRANTO}/goodies/changet.sh ${refdate} ${sfile1} |
endif |
endif |
# Write parameters to parameter file and create the starting positions |
\rm -f ${parfile} |
echo \"${pfile0}\" \"${pfile1}\" >! ${parfile} |
echo \"${sfile0}\" \"${sfile1}\" >> ${parfile} |
echo \"${ofile}${format1}\" >> ${parfile} |
echo \"${regionf}\" >> ${parfile} |
echo ${yyyy} >> ${parfile} |
echo ${mm} >> ${parfile} |
echo ${dd} >> ${parfile} |
echo ${hh} >> ${parfile} |
echo ${min} >> ${parfile} |
echo 00 >> ${parfile} |
echo ${timeshift} >> ${parfile} |
echo ${timeinc} >> ${parfile} |
# Analyse the specifier and append to parameter file |
${LAGRANTO}/startf/create_startf.perl "${specifier}" >> ${parfile} |
if ( "${status}" != "0" ) then |
echo "ERROR: Preprocessor <create_startf> failed" |
exit 1 |
endif |
# Write selection criterion to file |
\rm -f ${crifile} |
tail -1 ${parfile} >! ${crifile} |
# Write flag for no time check |
echo \"${timecheck}\" >> ${parfile} |
# Write title |
echo |
echo ' *** END OF PREPROCESSOR CREATE_STARTF ***' |
echo '=========================================================' |
echo |
# Create the startf |
cd ${tradir} |
${LAGRANTO}/startf/create_startf |
if ( "${status}" != "0" ) then |
echo "ERROR: Program <create_startf> failed" |
exit 1 |
endif |
# -------------------------------------------------------------------------------------------------------------- |
# Apply selection (first tracing then selection) |
# -------------------------------------------------------------------------------------------------------------- |
# Stop if no tracing and selection is necessary |
if ( "${flag}" == "nil" ) goto finish |
# Tracing of extra variables |
if ( -f ${ofile}${format2} ) then |
\rm -f ${ofile}${format2} |
endif |
if ( "${timecheck}" == "no" ) then |
${LAGRANTO}/trace/trace.sh ${ofile}${format1} ${ofile}${format2} -v ${tvfile} -notimecheck |
else |
${LAGRANTO}/trace/trace.sh ${ofile}${format1} ${ofile}${format2} -v ${tvfile} |
endif |
\rm -f ${ofile}${format1} |
# Selection |
if ( -f ${ofile} ) then |
\rm -f ${ofile} |
endif |
${LAGRANTO}/select/select.sh ${ofile}${format2} ${ofile} `cat ${crifile}` |
\rm -f ${ofile}${format2} |
# -------------------------------------------------------------------------------------------------------------- |
# Final tasks (make clean) |
# -------------------------------------------------------------------------------------------------------------- |
finish: |
echo $noclean |
if ( "${noclean}" == "false" ) then |
\rm -f ${crifile} |
\rm -f ${parfile} |
endif |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/data |
---|
0,0 → 1,0 |
link /data/lagranto.20cr/ |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/tags/1.0/density/density.f |
---|
0,0 → 1,1754 |
PROGRAM density |
use netcdf |
implicit none |
c --------------------------------------------------------------------- |
c Declaration of variables |
c --------------------------------------------------------------------- |
c Parameter and working arrays |
real radius |
character*80 runit |
integer nx,ny |
integer nlonlat |
real dlonlat |
real xmin,ymin,dx,dy |
real clon,clat |
integer ntime,nfield,ntra |
character*80 inpfile |
character*80 outfile |
character*80 mode |
real param |
integer opts,npts |
integer step |
character*80 gridtype |
character*80 field |
integer crefile,crevar |
real,allocatable, dimension (:,:) :: cnt,res,fld,area |
real,allocatable, dimension (:) :: traj |
real,allocatable, dimension (:) :: olon,olat,otim,ofld |
real,allocatable, dimension (:) :: nlon,nlat,ntim,nfld |
c Output format |
character*80 outformat |
c Physical and mathematical constants |
real pi180 |
parameter (pi180=3.14159/180.) |
real deltay |
parameter (deltay=111.) |
real eps |
parameter (eps=0.001) |
c Input trajectories (see iotra.f) |
integer inpmode |
real,allocatable, dimension (:,:,:) :: trainp |
integer reftime(6) |
character*80 varsinp(100) |
integer,allocatable, dimension (:) :: sel_flag |
character*80 sel_file |
character*80 sel_format |
c Auxiliary variables |
character*80 cdfname,varname |
integer i,j,k |
integer stat |
integer,allocatable, dimension (:,:) :: connect0 |
integer connectval0 |
integer,allocatable, dimension (:,:) :: connect1 |
integer connectval1 |
integer,allocatable, dimension (:,:) :: connect2 |
integer connectval2 |
real slat |
integer ipre |
real addvalue |
real xmax,ymax |
real ,allocatable, dimension (:) :: odist,ndist |
real dt |
integer fid |
integer dynamic_grid |
real ycen,xcen |
integer indx,indy |
character*80 unit |
real pollon,pollat |
real rlon0,rlat0,rlon,rlat |
real lon,lat |
real crot |
integer count |
character*80 longname, varunit |
real time |
integer ind |
integer ifield |
real hhmm,frac |
integer ierr,ncID |
c External functions |
real lmstolm,lmtolms |
real phstoph,phtophs |
external lmstolm,lmtolms,phstoph,phtophs |
real sdis |
external sdis |
c --------------------------------------------------------------------- |
c Preparations |
c --------------------------------------------------------------------- |
c Write start message |
print*,'=========================================================' |
print*,' *** START OF PROGRAM DENSITY ***' |
print* |
c Read input parameters |
open(10,file='density.param') |
read(10,*) inpfile |
read(10,*) outfile |
read(10,*) field |
read(10,*) ntime,nfield,ntra |
read(10,*) gridtype |
if ( gridtype.eq.'latlon' ) then |
read(10,*) nx,ny,xmin,ymin,dx,dy |
elseif ( gridtype.eq.'rotated') then |
read(10,*) clon,clat,nlonlat,dlonlat |
else |
print*,' ERROR: unsupported grid type ',trim(gridtype) |
stop |
endif |
read(10,*) radius,runit |
read(10,*) mode |
read(10,*) param |
read(10,*) step |
read(10,*) sel_file |
read(10,*) sel_format |
read(10,*) crefile |
read(10,*) crevar |
close(10) |
c Get the grid parameters if <crefile=0> |
if ( crefile.eq.0 ) then |
ierr = nf90_open (trim(outfile), NF90_NOWRITE , ncID) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'grid' ,gridtype ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'clon' ,clon ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'clat' ,clat ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'nlonlat',nlonlat ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'dlonlat',dlonlat ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'nx' ,nx ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'ny' ,ny ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'dx' ,dx ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'dy' ,dy ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'xmin' ,xmin ) |
ierr = nf90_get_att(ncID, NF90_GLOBAL, 'ymin' ,ymin ) |
ierr = nf90_close(ncID) |
print*,'**** GRID PARAMETERS IMPORTED ', |
> 'FROM NETCDF FILE!!!! ****' |
print* |
endif |
c Check for consistency |
if ( (step.ne.0).and.(mode.ne.'keep') ) then |
print*," ERROR: interpolation is only possible for all", |
> ' time steps... Stop' |
stop |
endif |
c Set the number of times (just code aesthetics) |
opts=ntime |
c Set grid parameters for rotated grid |
if ( gridtype.eq.'rotated' ) then |
nx = nlonlat |
ny = nlonlat |
dx = dlonlat |
dy = dlonlat |
xmin = - real(nlonlat-1)/2. * dx |
xmax = + real(nlonlat-1)/2. * dx |
ymin = - real(nlonlat-1)/2. * dy |
ymax = + real(nlonlat-1)/2. * dy |
endif |
c Set the flag for dynamic grid adjustment |
if ( (nx.eq.0).or.(ny.eq.0) ) then |
dynamic_grid = 1 |
else |
dynamic_grid = 0 |
endif |
c Print status information |
print*,'---- INPUT PARAMETERS -----------------------------------' |
print* |
print*,'Input : ',trim(inpfile) |
print*,'Output : ',trim(outfile) |
print*,'Field : ',trim(field) |
print*,'Trajectory : ',ntime,nfield,ntra |
print*,'Grid type : ',trim(gridtype) |
if ( dynamic_grid.eq.1 ) then |
print*,'Grid : dynamic (see below)' |
elseif ( gridtype.eq.'latlon' ) then |
print*,'Grid nlon,nlat : ',nx,ny |
print*,' lonmin,latmin : ',xmin,ymin |
print*,' dlon,dlat : ',dx,dy |
elseif ( gridtype.eq.'rotated' ) then |
print*,'Grid clon,clat : ',clon,clat |
print*,' nlonlat : ',nlonlat |
print*,' dlonlat : ',dlonlat |
endif |
print*,'Filter radius : ',radius,' ',trim(runit) |
print*,'Mode : ',trim(mode) |
if ( ( mode.eq.'time' ).or. |
> ( mode.eq.'space' ).or. |
> (mode.eq.'grid' ) ) |
>then |
print*,'Parameter : ',param |
endif |
if ( step.eq.0 ) then |
print*,'Time step : all' |
elseif (step.gt.0) then |
print*,'Time step : ',step |
endif |
print*,'Selection file : ',trim(sel_file) |
print*,'Selection format : ',trim(sel_file) |
print*,'Flag <crefile> : ',crefile |
print*,'Flag <crevar> : ',crevar |
c Check whether mode is valid |
if ((mode.ne.'keep' ).and. |
> (mode.ne.'time' ).and. |
> (mode.ne.'space' ).and. |
> (mode.ne.'grid' )) |
>then |
print*,' ERROR: Invalid mode ',trim(mode) |
stop |
endif |
c Allocate memory for old and new (reparameterised) trajectory |
allocate(olon(ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array olon ***' |
allocate(olat(ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array olat ***' |
allocate(otim(ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array otim ***' |
allocate(nlon(1000*ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array nlon ***' |
allocate(nlat(1000*ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array nlat ***' |
allocate(ntim(1000*ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array ntim ***' |
allocate(odist(ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array odist ***' |
allocate(ndist(1000*ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array ndist ***' |
allocate(ofld(ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array ofld ***' |
allocate(nfld(1000*ntime),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array nfld ***' |
c Allocate memory for complete trajectory set |
allocate(trainp(ntra,ntime,nfield),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array trainp ***' |
allocate(sel_flag(ntra),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array sel_flag ***' |
c Allocate memory for auxiliary fields |
allocate(traj(nfield),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array traj ***' |
c Set the format of the input file |
call mode_tra(inpmode,inpfile) |
if (inpmode.eq.-1) inpmode=1 |
c Read the input trajectory file |
call ropen_tra(fid,inpfile,ntra,ntime,nfield, |
> reftime,varsinp,inpmode) |
call read_tra (fid,trainp,ntra,ntime,nfield,inpmode) |
call close_tra(fid,inpmode) |
c Check that first four columns correspond to time,lon,lat,p |
if ( (varsinp(1).ne.'time' ).or. |
> (varsinp(2).ne.'xpos' ).and.(varsinp(2).ne.'lon' ).or. |
> (varsinp(3).ne.'ypos' ).and.(varsinp(3).ne.'lat' ).or. |
> (varsinp(4).ne.'ppos' ).and.(varsinp(4).ne.'p' ) ) |
>then |
print*,' ERROR: problem with input trajectories ...' |
stop |
endif |
varsinp(1) = 'TIME' |
varsinp(2) = 'lon' |
varsinp(3) = 'lat' |
varsinp(4) = 'p' |
c Get the index of the field (if needed) |
if ( field.ne.'nil' ) then |
ifield = 0 |
do i=1,nfield |
if ( varsinp(i).eq.field ) ifield = i |
enddo |
if ( ifield.eq.0 ) then |
print*,' ERROR: field ',trim(field),' not found... Stop' |
stop |
endif |
endif |
c Write some status information of the input trajectories |
print* |
print*,'---- INPUT TRAJECTORIES ---------------------------------' |
print* |
print*,' Reference time (year) : ',reftime(1) |
print*,' (month) : ',reftime(2) |
print*,' (day) : ',reftime(3) |
print*,' (hour) : ',reftime(4) |
print*,' (min) : ',reftime(5) |
print*,' Time range (min) : ',reftime(6) |
do i=1,nfield |
if ( i.ne.ifield ) then |
print*,' Var :',i,trim(varsinp(i)) |
else |
print*,' Var :',i,trim(varsinp(i)), |
> ' [ gridding ]' |
endif |
enddo |
print*,' List of selected times' |
do i=1,ntime |
if ( (step.eq.0).or.(step.eq.i) ) then |
print*,' ',i,' -> ',trainp(1,i,1) |
endif |
enddo |
print* |
c Select flag: all trajectories are selected |
if ( sel_file.eq.'nil' ) then |
do i=1,ntra |
sel_flag(i) = 1 |
enddo |
c Select flag: index file |
elseif ( sel_format.eq.'index' ) then |
do i=1,ntra |
sel_flag(i) = 0 |
enddo |
open(10,file=sel_file) |
142 read(10,*,end=141) ind |
sel_flag(ind) = 1 |
goto 142 |
141 continue |
close(10) |
c Select flag: boolean file |
elseif ( sel_format.eq.'boolean' ) then |
open(10,file=sel_file) |
do i=1,ntra |
read(10,*) ind |
if ( ind.eq.1 ) sel_flag(i) = ind |
enddo |
close(10) |
endif |
c Write status information |
if ( sel_file.eq.'nil' ) then |
print*,' Selected trajectories : all ',ntra |
else |
count = 0 |
do i=1,ntra |
if ( sel_flag(i).eq.1 ) count = count + 1 |
enddo |
print*,' #selected trajectories : ',count, |
> ' [ ',real(count)/real(ntra) * 100.,' % ] ' |
endif |
print* |
c --------------------------------------------------------------------- |
c Coordinate transformations and grid adjustment |
c --------------------------------------------------------------------- |
c Transform from lat/lon to rotated lat/lon, if requested |
if ( gridtype.eq.'rotated') then |
crot = 0. |
pollon=clon-180. |
if (pollon.lt.-180.) pollon=pollon+360. |
pollat=90.-clat |
do i=1,ntra |
do j=1,ntime |
if ( sel_flag(i).eq.1 ) then |
c Get lat/lon coordinates for trajectory point |
lon = trainp(i,j,2) |
lat = trainp(i,j,3) |
c First Rotation |
pollon=clon-180. |
if (pollon.lt.-180.) pollon=pollon+360. |
pollat=90.-clat |
rlon0=lmtolms(lat,lon,pollat,pollon) |
rlat0=phtophs(lat,lon,pollat,pollon) |
c Second rotation |
pollon=-180. |
pollat=90.+crot |
rlon=90.+lmtolms(rlat0,rlon0-90.,pollat,pollon) |
rlat=phtophs(rlat0,rlon0-90.,pollat,pollon) |
c Get rotated latitude and longitude |
100 if (rlon.lt.xmin) then |
rlon=rlon+360. |
goto 100 |
endif |
102 if (rlon.gt.(xmin+real(nx-1)*dx)) then |
rlon=rlon-360. |
goto 102 |
endif |
c Set the new trajectory coordinates |
trainp(i,j,2) = rlon |
trainp(i,j,3) = rlat |
endif |
enddo |
enddo |
endif |
c Dynamic grid adjustment |
if ( dynamic_grid.eq.1 ) then |
c Get the grid parameters |
xmin = 180. |
ymin = 90. |
xmax = -180. |
ymax = -90. |
do i=1,ntra |
if ( sel_flag(i).eq.1 ) then |
if ( step.eq.0 ) then |
do j=1,ntime |
if ( trainp(i,j,2).lt.xmin) xmin = trainp(i,j,2) |
if ( trainp(i,j,2).gt.xmax) xmax = trainp(i,j,2) |
if ( trainp(i,j,3).lt.ymin) ymin = trainp(i,j,3) |
if ( trainp(i,j,3).gt.ymax) ymax = trainp(i,j,3) |
enddo |
else |
if ( trainp(i,step,2).lt.xmin) xmin = trainp(i,step,2) |
if ( trainp(i,step,2).gt.xmax) xmax = trainp(i,step,2) |
if ( trainp(i,step,3).lt.ymin) ymin = trainp(i,step,3) |
if ( trainp(i,step,3).gt.ymax) ymax = trainp(i,step,3) |
endif |
endif |
enddo |
c Get first guess for "optimal" grid |
nx = 400 |
ny = 400 |
dx = (xmax - xmin)/real(nx-1) |
dy = (ymax - ymin)/real(ny-1) |
c Make the grid spacing equal in zonal and meridional direction |
if ( dx.gt.dy ) then |
dy = dx |
ny = (ymax - ymin)/dy + 1 |
if (ny.lt.nx/2) ny = nx / 2 |
if ( real(ny)*dy .ge. 180. ) ny = 180./dy + 1 |
ycen = 0.5* (ymin+ymax) |
ymin = ycen - 0.5 * real(ny/2) * dy |
if (ymin.le.-90.) ymin = -90. |
else |
dx = dy |
nx = (xmax - xmin)/dx + 1 |
if (nx.lt.ny/2) nx = ny / 2 |
if ( real(nx)*dx .ge. 360. ) nx = 360./dx + 1 |
xcen = 0.5* (xmin+xmax) |
xmin = xcen - 0.5 * real(nx/2) * dx |
if (xmin.le.-180.) xmin = -180. |
endif |
c Write information |
print* |
print*,'---- DYNAMIC GRID ADJUSTMENT', |
> ' ----------------------------' |
print* |
print*,'Grid nlon,nlat : ',nx,ny |
print*,' lonmin,latmin : ',xmin,ymin |
print*,' dlon,dlat : ',dx,dy |
print* |
c Write grid information for rotated grid (if not already done |
elseif ( gridtype.eq.'rotated') then |
print* |
print*,'---- GRID PARAMETERS -------', |
> ' ----------------------------' |
print* |
print*,'Grid nlon,nlat : ',nx,ny |
print*,' lonmin,latmin : ',xmin,ymin |
print*,' dlon,dlat : ',dx,dy |
print* |
endif |
c Set the grid boundaries |
xmax=xmin+real(nx-1)*dx |
ymax=ymin+real(ny-1)*dy |
c Allocate memory for output array and auxiliary gridding array |
allocate(cnt(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array cnt ***' |
allocate(res(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array res ***' |
allocate(fld(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array fld ***' |
allocate(area(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array area ***' |
allocate(connect0(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array connect0 ***' |
allocate(connect1(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array connect1 ***' |
allocate(connect2(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array connect2 ***' |
c Init the output array |
do i=1,nx |
do j=1,ny |
connect0(i,j) = 0 |
connect1(i,j) = 0 |
connect2(i,j) = 0 |
cnt(i,j) = 0. |
res(i,j) = 0. |
fld(i,j) = 0. |
enddo |
enddo |
c --------------------------------------------------------------------- |
c Gridding |
c --------------------------------------------------------------------- |
c Write some status information |
print*,'---- GRIDDING -------------------------------------------' |
print* |
c Loop over all entries of sampling table |
connectval0 = 0 |
connectval1 = 0 |
connectval2 = 0 |
count = 0 |
do i=1,ntra |
if (mod(i,100).eq.0) print*,i,' of ',ntra |
c Skip all trajectories which are not selected |
if ( sel_flag(i).eq.0 ) goto 300 |
c ------- Read a complete trajectory --------------------------- |
do j=1,ntime |
otim(j) = trainp(i,j,1) |
olon(j) = trainp(i,j,2) |
olat(j) = trainp(i,j,3) |
if ( field.ne.'nil' ) then |
ofld(j) =trainp(i,j,ifield) |
endif |
enddo |
c -------- Convert hh.m time into fractional time -------------- |
do j=1,ntime |
hhmm = otim(j) |
call hhmm2frac (hhmm,frac) |
otim(j) = frac |
enddo |
c -------- Interpolation --------------------------------------- |
c Keep the trajectory points as they are |
if ( ( mode.eq.'keep').and.(step.eq.0) ) then |
npts=opts |
do j=1,opts |
ntim(j)=otim(j) |
nlon(j)=olon(j) |
nlat(j)=olat(j) |
if ( field.ne.'nil' ) then |
nfld(j)=ofld(j) |
endif |
enddo |
c Select a single time step |
elseif ( ( mode.eq.'keep').and.(step.gt.0) ) then |
npts = 1 |
ntim(1) = otim(step) |
nlon(1) = olon(step) |
nlat(1) = olat(step) |
if ( field.ne.'nil' ) then |
nfld(1) = ofld(step) |
endif |
c Perform a reparameterisation in time |
else if ( (mode.eq.'time').and.(step.eq.0) ) then |
c Get the new number of trajectory points |
npts=nint(abs(otim(opts)-otim(1))/param)+1 |
c Handle date line problem |
do j=2,opts |
if ( (olon(j-1)-olon(j)).gt.180. ) then |
olon(j) = olon(j) + 360. |
else if ( (olon(j-1)-olon(j)).lt.-180. ) then |
olon(j) = olon(j) - 360. |
endif |
enddo |
c Cubic spline fitting |
call curvefit(otim,olon,opts,ntim,nlon,npts) |
call curvefit(otim,olat,opts,ntim,nlat,npts) |
if ( field.ne.'nil' ) then |
call curvefit(otim,ofld,opts,ntim,nfld,npts) |
endif |
c Reverse date line handling |
do j=1,npts |
if ( nlon(j).gt.xmax ) then |
nlon(j) = nlon(j) -360. |
else if ( nlon(j).lt.xmin ) then |
nlon(j) = nlon(j) +360. |
endif |
enddo |
c Perform a reparameterisation with equally spaced gridpoint |
elseif ( (mode.eq.'space').and.(step.eq.0) ) then |
c Calculate the distance and spacing |
odist(1) = 0. |
unit = 'km' |
do j=2,ntime |
odist(j)=odist(j-1) + |
> sdis(olon(j-1),olat(j-1),olon(j),olat(j),unit) |
enddo |
c Determine the new number of trajectory points |
npts=nint(odist(ntime)/param)+1 |
if (npts.eq.0) then |
npts=1. |
endif |
c Handle date line problem |
do j=2,opts |
if ( (olon(j-1)-olon(j)).gt.180. ) then |
olon(j) = olon(j) + 360. |
else if ( (olon(j-1)-olon(j)).lt.-180. ) then |
olon(j) = olon(j) - 360. |
endif |
enddo |
c Cubic spline fitting |
call curvefit(odist,olon,opts,ndist,nlon,npts) |
call curvefit(odist,olat,opts,ndist,nlat,npts) |
call curvefit(odist,otim,opts,ndist,ntim,npts) |
if ( field.ne.'nil' ) then |
call curvefit(odist,ofld,opts,ndist,nfld,npts) |
endif |
c Reverse date line handling |
do j=1,npts |
if ( nlon(j).gt.xmax ) then |
nlon(j) = nlon(j) -360. |
else if ( nlon(j).lt.xmin ) then |
nlon(j) = nlon(j) +360. |
endif |
enddo |
c Perform a reparameterisation with equally spaced gridpoint |
elseif ( (mode.eq.'grid').and.(step.eq.0) ) then |
c Calculate the distance and spacing |
odist(1) = 0. |
unit = 'deg' |
do j=2,ntime |
odist(j)=odist(j-1) + |
> sdis(olon(j-1),olat(j-1),olon(j),olat(j),unit) |
enddo |
c Determine the new number of trajectory points |
npts=nint(odist(ntime)/param)+1 |
if (npts.eq.0) then |
npts=1. |
endif |
c Handle date line problem |
do j=2,opts |
if ( (olon(j-1)-olon(j)).gt.180. ) then |
olon(j) = olon(j) + 360. |
else if ( (olon(j-1)-olon(j)).lt.-180. ) then |
olon(j) = olon(j) - 360. |
endif |
enddo |
c Cubic spline fitting |
call curvefit(odist,olon,opts,ndist,nlon,npts) |
call curvefit(odist,olat,opts,ndist,nlat,npts) |
call curvefit(odist,otim,opts,ndist,ntim,npts) |
if ( field.ne.'nil' ) then |
call curvefit(odist,ofld,opts,ndist,nfld,npts) |
endif |
c Reverse date line handling |
do j=1,npts |
if ( nlon(j).gt.xmax ) then |
nlon(j) = nlon(j) -360. |
else if ( nlon(j).lt.xmin ) then |
nlon(j) = nlon(j) +360. |
endif |
enddo |
endif |
c -------- Do the gridding ------------------------------------- |
c Gridding of trajectory |
do j=1,npts |
c Check whether point is in data domain |
if ( (nlon(j).gt.xmin).and.(nlon(j).lt.xmax).and. |
> (nlat(j).gt.ymin).and.(nlat(j).lt.ymax)) |
> then |
c Increase counter for gridded points |
count = count + 1 |
c ----------------- Gridding: simple count ----------------- |
connectval0 = connectval0+1 |
addvalue = 1. |
call gridding1 |
> (nlat(j),nlon(j),addvalue, |
> radius,runit,connect0,connectval0, |
> cnt,nx,ny,xmin,ymin,dx,dy) |
c ----------------- Gridding: residence time --------------- |
connectval1 = connectval1+1 |
if ( ntime.eq.1 ) then |
addvalue = 0. |
elseif ( j.eq.1 ) then |
addvalue=abs(ntim(2)-ntim(1)) |
else |
addvalue=abs(ntim(j)-ntim(j-1)) |
endif |
call gridding1 |
> (nlat(j),nlon(j),addvalue, |
> radius,runit,connect1,connectval1, |
> res,nx,ny,xmin,ymin,dx,dy) |
c --------------- Gridding: field ------------------------- |
if ( field.ne.'nil' ) then |
connectval2 = connectval2+1 |
addvalue = nfld(j) |
call gridding1 |
> (nlat(j),nlon(j),addvalue, |
> radius,runit,connect2,connectval2, |
> fld,nx,ny,xmin,ymin,dx,dy) |
endif |
endif |
enddo |
c Exit point for loop over all trajectories |
300 continue |
enddo |
c Write status information |
print* |
print*,' # gridded points : ',count |
c --------------------------------------------------------------------- |
c Unit conversions and output to netCDF file |
c --------------------------------------------------------------------- |
c Write some status information |
print* |
print*,'---- WRITE OUTPUT ---------------------------------------' |
print* |
c Area (in km^2) |
do i=1,nx |
do j=1,ny |
slat=ymin+real(j-1)*dy |
if (abs(abs(slat)-90.).gt.eps) then |
area(i,j) = dy*dx*cos(pi180*slat)*deltay**2 |
else |
area(i,j) = 0. |
endif |
enddo |
enddo |
c Normalise gridded field |
if ( field.ne.'nil' ) then |
do i=1,nx |
do j=1,ny |
if ( cnt(i,j).gt.0. ) then |
fld(i,j) = fld(i,j) / cnt(i,j) |
endif |
enddo |
enddo |
endif |
c Set the time for the output netCDF files - if a composite is |
c calculatd, then the time is set to |
if ( step.eq.0 ) then |
time = -999. |
print*,' ... COMPOSITE OVER ALL TRAJECTORY TIMES (-999)' |
print* |
else |
time = trainp(1,step,1) |
endif |
c Write output to CF netCDF |
cdfname = outfile |
varname = 'COUNT' |
longname = 'trajectory counts' |
varunit = 'counts per grid point' |
call writecdf2D_cf (cdfname,varname,longname,varunit,gridtype, |
> clon,clat,nlonlat,dlonlat,cnt,time,dx,dy,xmin,ymin,nx, |
> ny,crefile,crefile,1) |
write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') |
> ' ... ',trim(varname),' -> ',trim(cdfname), |
> ' [ time = ',time,' ]' |
varname = 'RESIDENCE' |
longname = 'residence time' |
varunit = 'hours per grid point' |
call writecdf2D_cf (cdfname,varname,longname,varunit,gridtype, |
> clon,clat,nlonlat,dlonlat,res,time,dx,dy,xmin,ymin,nx, |
> ny,0,crefile,1) |
write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') |
> ' ... ',trim(varname),' -> ',trim(cdfname), |
> ' [ time = ',time,' ]' |
varname = 'AREA' |
longname = 'area corresponding to grid points' |
varunit = 'square kilometers' |
call writecdf2D_cf (cdfname,varname,longname,varunit,gridtype, |
> clon,clat,nlonlat,dlonlat,area,time,dx,dy,xmin,ymin,nx, |
> ny,0,crefile,1) |
write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') |
> ' ... ',trim(varname),' -> ',trim(cdfname), |
> ' [ time = ',time,' ]' |
if ( field.ne.'nil' ) then |
varname = field |
longname = field |
varunit = 'as on trajectory file' |
call writecdf2D_cf (cdfname,varname,longname,varunit,gridtype, |
> clon,clat,nlonlat,dlonlat,fld,time,dx,dy,xmin,ymin,nx, |
> ny,0,crevar,1) |
write(*,'(a8,a10,a5,a10,a10,f7.2,a2)') |
> ' ... ',trim(varname),' -> ',trim(cdfname), |
> ' [ time = ',time,' ]' |
endif |
c Write status information |
print* |
print*,' *** END OF PROGRAM DENSITY **' |
print*,'=========================================================' |
end |
c ******************************************************************** |
c * GRIDDING SUBROUTINES * |
c ******************************************************************** |
c --------------------------------------------------------------------- |
c Gridding of one single data point (smoothing in km, deg, gridp) |
c --------------------------------------------------------------------- |
subroutine gridding1 (lat,lon,addval,radius,unit, |
> connect,connectval, |
> out,nx,ny,xmin,ymin,dx,dy) |
implicit none |
c Declaration of subroutine parameters |
real lat,lon |
integer nx,ny |
real xmin,ymin,dx,dy |
real out(nx,ny) |
real radius |
character*80 unit |
integer connectval |
integer connect(nx,ny) |
real addval |
c Auxiliary variables |
integer i,j,k |
integer mu,md,nr,nl,n,m |
integer stackx(nx*ny),stacky(nx*ny) |
integer tab_x(nx*ny),tab_y(nx*ny) |
real tab_r(nx*ny) |
integer sp |
real lat2,lon2 |
real dist,sum |
real xmax |
integer periodic |
integer test |
c Numerical epsilon |
real eps |
parameter (eps=0.01) |
c Externals |
real sdis,weight |
external sdis,weight |
c Check whether lat/lon point is valid |
xmax=xmin+real(nx-1)*dx |
if (lon.lt.xmin-eps) lon=lon+360. |
if (lon.gt.xmax+eps) lon=lon-360. |
if (abs(lat-90).lt.eps) lat=90. |
if (abs(lat+90).lt.eps) lat=-90. |
if ((abs(lat).gt.(90.+eps)).or. |
> (lon.lt.xmin-eps).or.(lon.gt.xmax+eps)) then |
print*,'Invalid lat/lon point ',lat,lon |
return |
endif |
c Set flag for periodic domain |
if (abs(xmax-xmin-360.).lt.eps) then |
periodic=1 |
else if (abs(xmax-xmin-360+dx).lt.eps) then |
periodic=2 |
else |
periodic=0 |
endif |
c Get indices of one coarse grid point within search radius |
i=nint((lon-xmin)/dx)+1 |
if ((i.eq.nx).and.(periodic.eq.1)) i=1 |
j=nint((lat-ymin)/dy)+1 |
lat2=ymin+real(j-1)*dy |
lon2=xmin+real(i-1)*dx |
dist=sdis(lon,lat,lon2,lat2,unit) |
if (dist.gt.radius) then |
print*,'1: Search radius is too small...' |
stop |
endif |
c Get connected points |
k=0 |
stackx(1)=i |
stacky(1)=j |
sp=1 |
do while (sp.ne.0) |
c Get an element from stack |
n=stackx(sp) |
m=stacky(sp) |
sp=sp-1 |
c Get distance from reference point |
lat2=ymin+real(m-1)*dy |
lon2=xmin+real(n-1)*dx |
dist=sdis(lon,lat,lon2,lat2,unit) |
c Check whether distance is smaller than search radius: connected |
if (dist.lt.radius) then |
c Make entry in filter mask |
k=k+1 |
tab_x(k)=n |
tab_y(k)=m |
tab_r(k)=weight(dist,radius) |
c Mark this point as visited |
connect(n,m)=connectval |
c Get coordinates of neighbouring points |
nr=n+1 |
if ((nr.gt.nx) .and.(periodic.eq.0)) nr=nx |
if ((nr.gt.nx-1).and.(periodic.eq.1)) nr=1 |
if ((nr.gt.nx) .and.(periodic.eq.2)) nr=1 |
nl=n-1 |
if ((nl.lt.1).and.(periodic.eq.0)) nl=1 |
if ((nl.lt.1).and.(periodic.eq.1)) nl=nx-1 |
if ((nl.lt.1).and.(periodic.eq.2)) nl=nx |
mu=m+1 |
if (mu.gt.ny) mu=ny |
md=m-1 |
if (md.lt.1) md=1 |
c Update stack |
if (connect(nr,m).ne.connectval) then |
connect(nr,m)=connectval |
sp=sp+1 |
stackx(sp)=nr |
stacky(sp)=m |
endif |
if (connect(nl,m).ne.connectval) then |
connect(nl,m)=connectval |
sp=sp+1 |
stackx(sp)=nl |
stacky(sp)=m |
endif |
if (connect(n,mu).ne.connectval) then |
connect(n,mu)=connectval |
sp=sp+1 |
stackx(sp)=n |
stacky(sp)=mu |
endif |
if (connect(n,md).ne.connectval) then |
connect(n,md)=connectval |
sp=sp+1 |
stackx(sp)=n |
stacky(sp)=md |
endif |
endif |
end do |
if (k.ge.1) then |
sum=0. |
do i=1,k |
sum=sum+tab_r(i) |
enddo |
do i=1,k |
out(tab_x(i),tab_y(i))=out(tab_x(i),tab_y(i))+ |
> addval*tab_r(i)/sum |
if ((tab_x(i).eq.1).and.(periodic.eq.1)) then |
out(nx,tab_y(i))=out(nx,tab_y(i))+ |
> addval*tab_r(i)/sum |
endif |
enddo |
else |
print*,'2: Search radius is too small...' |
stop |
endif |
end |
c ---------------------------------------------------------------------- |
c Get spherical distance between lat/lon points |
c ---------------------------------------------------------------------- |
real function sdis(xp,yp,xq,yq,unit) |
c Calculates spherical distance (in km) between two points given |
c by their spherical coordinates (xp,yp) and (xq,yq), respectively. |
real re |
parameter (re=6370.) |
real xp,yp,xq,yq,arg |
character*80 unit |
real dlon |
if ( unit.eq.'km' ) then |
arg=sind(yp)*sind(yq)+cosd(yp)*cosd(yq)*cosd(xp-xq) |
if (arg.lt.-1.) arg=-1. |
if (arg.gt.1.) arg=1. |
sdis=re*acos(arg) |
elseif ( unit.eq.'deg' ) then |
dlon = xp-xq |
if ( dlon.gt. 180. ) dlon = dlon - 360. |
if ( dlon.lt.-180. ) dlon = dlon + 360. |
sdis = sqrt( dlon**2 + (yp-yq)**2 ) |
endif |
c Quick and dirty trick to avoid zero distances |
if (sdis.eq.0.) sdis=0.1 |
end |
c ---------------------------------------------------------------------- |
c Weight function for the filter mask |
c ---------------------------------------------------------------------- |
real function weight (r,radius) |
c Attribute to each distanc r its corresponding weight in the filter mask |
implicit none |
c Declaration of subroutine parameters |
real r |
real radius |
c Simple 0/1 mask |
if (r.lt.radius) then |
weight=exp(-r/radius) |
else |
weight=0. |
endif |
end |
c ******************************************************************** |
c * REPARAMETERIZATION SUBROUTINES * |
c ******************************************************************** |
c ------------------------------------------------------------- |
c Interpolation of the trajectory with a natural cubic spline |
c ------------------------------------------------------------- |
SUBROUTINE curvefit (time,lon,n, |
> sptime,splon,spn) |
c Given the curve <time,lon> with <n> data points, fit a |
c cubic spline to this curve. The new curve is returned in |
c <sptime,splon,spn> with <spn> data points. The parameter |
c <spn> specifies on entry the number of spline interpolated points |
c along the curve. |
implicit none |
c Declaration of subroutine parameters |
integer n |
real time(n),lon(n) |
integer spn |
real sptime(spn),splon(spn) |
c Auxiliary variables |
real y2ax(n) |
real dt |
real s |
integer i |
real order |
c Determine whether the input array is ascending or descending |
if (time(1).gt.time(n)) then |
order=-1. |
else |
order= 1. |
endif |
c Bring the time array into ascending order |
do i=1,n |
time(i)=order*time(i) |
enddo |
c Prepare the (natural) cubic spline interpolation |
call spline (time,lon,n,1.e30,1.e30,y2ax) |
dt=(time(n)-time(1))/real(spn-1) |
do i=1,spn |
sptime(i)=time(1)+real(i-1)*dt |
enddo |
c Do the spline interpolation |
do i=1,spn |
call splint(time,lon,y2ax,n,sptime(i),s) |
splon(i)=s |
enddo |
c Change the time arrays back |
do i=1,spn |
sptime(i)=order*sptime(i) |
enddo |
do i=1,n |
time(i)=order*time(i) |
enddo |
return |
end |
c ------------------------------------------------------------- |
c Basic routines for spline interpolation (Numerical Recipes) |
c ------------------------------------------------------------- |
SUBROUTINE spline(x,y,n,yp1,ypn,y2) |
INTEGER n,NMAX |
REAL yp1,ypn,x(n),y(n),y2(n) |
PARAMETER (NMAX=500) |
INTEGER i,k |
REAL p,qn,sig,un,u(NMAX) |
if (yp1.gt..99e30) then |
y2(1)=0. |
u(1)=0. |
else |
y2(1)=-0.5 |
u(1)=(3./(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1) |
endif |
do 11 i=2,n-1 |
sig=(x(i)-x(i-1))/(x(i+1)-x(i-1)) |
p=sig*y2(i-1)+2. |
y2(i)=(sig-1.)/p |
u(i)=(6.*((y(i+1)-y(i))/(x(i+ |
*1)-x(i))-(y(i)-y(i-1))/(x(i)-x(i-1)))/(x(i+1)-x(i-1))-sig* |
*u(i-1))/p |
11 continue |
if (ypn.gt..99e30) then |
qn=0. |
un=0. |
else |
qn=0.5 |
un=(3./(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1))) |
endif |
y2(n)=(un-qn*u(n-1))/(qn*y2(n-1)+1.) |
do 12 k=n-1,1,-1 |
y2(k)=y2(k)*y2(k+1)+u(k) |
12 continue |
return |
END |
SUBROUTINE splint(xa,ya,y2a,n,x,y) |
INTEGER n |
REAL x,y,xa(n),y2a(n),ya(n) |
INTEGER k,khi,klo |
REAL a,b,h |
klo=1 |
khi=n |
1 if (khi-klo.gt.1) then |
k=(khi+klo)/2 |
if(xa(k).gt.x)then |
khi=k |
else |
klo=k |
endif |
goto 1 |
endif |
h=xa(khi)-xa(klo) |
if (h.eq.0.) pause 'bad xa input in splint' |
a=(xa(khi)-x)/h |
b=(x-xa(klo))/h |
y=a*ya(klo)+b*ya(khi)+((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi))*(h** |
*2)/6. |
return |
END |
c ******************************************************************** |
c * INPUT / OUTPUT SUBROUTINES * |
c ******************************************************************** |
c -------------------------------------------------------------------- |
c Subroutines to write the CF netcdf output file |
c -------------------------------------------------------------------- |
subroutine writecdf2D_cf |
> (cdfname,varname,longname,unit,gridtype,clon,clat, |
> nlonlat,dlonlat,arr,time,dx,dy,xmin,ymin,nx,ny, |
> crefile,crevar,cretime) |
c Create and write to the CF netcdf file <cdfname>. The variable |
c with name <varname> and with time <time> is written. The data |
c are in the two-dimensional array <arr>. The list <dx,dy,xmin, |
c ymin,nx,ny> specifies the output grid. The flags <crefile> and |
c <crevar> determine whether the file and/or the variable should |
c be created; correspondingly for the unlimited dimension <time> |
c with the flag <cretime>. |
USE netcdf |
IMPLICIT NONE |
c Declaration of input parameters |
character*80 cdfname |
character*80 varname,longname,unit |
integer nx,ny |
real arr(nx,ny) |
real dx,dy,xmin,ymin |
real time |
integer crefile,crevar,cretime |
character*80 gridtype |
real clon,clat |
integer nlonlat |
real dlonlat |
c Local variables |
integer ierr |
integer ncID |
integer LonDimId, varLonID |
integer LatDimID, varLatID |
integer TimeDimID, varTimeID |
real longitude(nx) |
real latitude (ny) |
real timeindex |
integer i |
integer nvars,varids(100) |
integer ndims,dimids(100) |
real timelist(1000) |
integer ntimes |
integer ind |
integer varID |
c Quick an dirty solution for fieldname conflict |
if ( varname.eq.'time' ) varname = 'TIME' |
c Initially set error to indicate no errors. |
ierr = 0 |
c ---- Create the netCDF - skip if <crefile=0> ---------------------- |
if ( crefile.ne.1 ) goto 100 |
c Create the file |
ierr = nf90_create(trim(cdfname), NF90_CLOBBER, ncID) |
c Define dimensions |
ierr=nf90_def_dim(ncID,'longitude',nx , LonDimID ) |
ierr=nf90_def_dim(ncID,'latitude' ,ny , LatDimID ) |
ierr=nf90_def_dim(ncID,'time' ,nf90_unlimited, TimeDimID) |
c Define coordinate Variables |
ierr = nf90_def_var(ncID,'longitude',NF90_FLOAT, |
> (/ LonDimID /),varLonID) |
ierr = nf90_put_att(ncID, varLonID, "standard_name","longitude") |
ierr = nf90_put_att(ncID, varLonID, "units" ,"degree_east") |
ierr = nf90_def_var(ncID,'latitude',NF90_FLOAT, |
> (/ LatDimID /),varLatID) |
ierr = nf90_put_att(ncID, varLatID, "standard_name", "latitude") |
ierr = nf90_put_att(ncID, varLatID, "units" ,"degree_north") |
ierr = nf90_def_var(ncID,'time',NF90_FLOAT, |
> (/ TimeDimID /), varTimeID) |
ierr = nf90_put_att(ncID, varTimeID, "axis", "T") |
ierr = nf90_put_att(ncID, varTimeID, "calendar", "standard") |
ierr = nf90_put_att(ncID, varTimeID, "long_name", "time") |
ierr = nf90_put_att(ncID, varTimeID, "units", "hours") |
c Write global attributes |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'Conventions', 'CF-1.0') |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'title', |
> 'Trajectory Densities') |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'source', |
> 'Lagranto Trajectories') |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'institution', |
> 'ETH Zurich, IACETH') |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'grid',trim(gridtype) ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'clon',clon ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'clat',clat ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'nlonlat',nlonlat ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'dlonlat',dlonlat ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'nx',nx ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'ny',ny ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'dx',dx ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'dy',dy ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'xmin',xmin ) |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'ymin',ymin ) |
c Write coordinate data |
do i = 1,nx+1 |
longitude(i) = xmin + real(i-1) * dx |
enddo |
do i = 1,ny+1 |
latitude(i) = ymin + real(i-1) * dy |
enddo |
c Check whether the definition was successful |
ierr = nf90_enddef(ncID) |
if (ierr.gt.0) then |
print*, 'An error occurred while attempting to ', |
> 'finish definition mode.' |
stop |
endif |
c Write coordinate data |
ierr = nf90_put_var(ncID,varLonID ,longitude) |
ierr = nf90_put_var(ncID,varLatID ,latitude ) |
c Close netCDF file |
ierr = nf90_close(ncID) |
100 continue |
c ---- Define a new variable - skip if <crevar=0> ----------------------- |
if ( crevar.ne.1 ) goto 110 |
c Open the file for read(write access |
ierr = nf90_open (trim(cdfname), NF90_WRITE , ncID) |
c Get the IDs for dimensions |
ierr = nf90_inq_dimid(ncID,'longitude', LonDimID ) |
ierr = nf90_inq_dimid(ncID,'latitude' , LatDimID ) |
ierr = nf90_inq_dimid(ncID,'time' , TimeDimID) |
c Enter define mode |
ierr = nf90_redef(ncID) |
c Write definition and add attributes |
ierr = nf90_def_var(ncID,varname,NF90_FLOAT, |
> (/ LonDimID, LatDimID, varTimeID /),varID) |
ierr = nf90_put_att(ncID, varID, "long_name" , longname ) |
ierr = nf90_put_att(ncID, varID, "units" , unit ) |
ierr = nf90_put_att(ncID, varID, '_FillValue', -999.99 ) |
c Check whether definition was successful |
ierr = nf90_enddef(ncID) |
if (ierr.gt.0) then |
print*, 'An error occurred while attempting to ', |
> 'finish definition mode.' |
stop |
endif |
c Close netCDF file |
ierr = nf90_close(ncID) |
110 continue |
c ---- Create a new time (unlimited dimension) - skip if <cretime=0> ------ |
if ( cretime.ne.1 ) goto 120 |
c Open the file for read/write access |
ierr = nf90_open (trim(cdfname), NF90_WRITE, ncID) |
c Get the list of times on the netCDF file |
ierr = nf90_inq_dimid(ncID,'time', TimeDimID) |
if ( ierr.ne.0 ) then |
print*,'Time dimension is not defined on ',trim(cdfname), |
> ' .... Stop' |
stop |
endif |
ierr = nf90_inquire_dimension(ncID, TimeDimID, len = ntimes) |
ierr = nf90_inq_varid(ncID,'time', varTimeID) |
if ( ierr.ne.0 ) then |
print*,'Variable time is not defined on ',trim(cdfname), |
> ' ... Stop' |
stop |
endif |
ierr = nf90_get_var(ncID,varTimeID,timelist(1:ntimes)) |
c Decide whether a new time must be written |
ind = 0 |
do i=1,ntimes |
if ( time.eq.timelist(i) ) ind = i |
enddo |
c Extend the time list if required |
if ( ind.eq.0 ) then |
ntimes = ntimes + 1 |
timelist(ntimes) = time |
ierr = nf90_put_var(ncID,varTimeID,timelist(1:ntimes)) |
endif |
c Close netCDF file |
ierr = nf90_close(ncID) |
120 continue |
c ---- Write data -------------------------------------------------- |
c Open the file for read/write access |
ierr = nf90_open (trim(cdfname), NF90_WRITE , ncID) |
c Get the varID |
ierr = nf90_inq_varid(ncID,varname, varID ) |
if (ierr.ne.0) then |
print*,'Variable ',trim(varname),' is not defined on ', |
> trim(cdfname) |
stop |
endif |
c Get the time index |
ierr = nf90_inq_dimid(ncID,'time', TimeDimID) |
if ( ierr.ne.0 ) then |
print*,'Time dimension is not defined on ',trim(cdfname), |
> ' .... Stop' |
stop |
endif |
ierr = nf90_inquire_dimension(ncID, TimeDimID, len = ntimes) |
ierr = nf90_inq_varid(ncID,'time', varTimeID) |
if ( ierr.ne.0 ) then |
print*,'Variable time is not defined on ',trim(cdfname), |
> ' ... Stop' |
stop |
endif |
ierr = nf90_get_var(ncID,varTimeID,timelist(1:ntimes)) |
ind = 0 |
do i=1,ntimes |
if ( time.eq.timelist(i) ) ind = i |
enddo |
if (ind.eq.0) then |
print*,'Time',time,' is not defined on the netCDF file', |
> trim(cdfname),' ... Stop' |
stop |
endif |
c Write data block |
ierr = nf90_put_var(ncID,varID,arr, |
> start = (/ 1, 1, ind /), |
> count = (/ nx, ny, 1 /) ) |
c Check whether writing was successful |
ierr = nf90_close(ncID) |
if (ierr.ne.0) then |
write(*,*) trim(nf90_strerror(ierr)) |
write(*,*) 'An error occurred while attempting to ', |
> 'close the netcdf file.' |
write(*,*) 'in clscdf_CF' |
endif |
end |
c ******************************************************************************** |
c * Transformation routine: LMSTOLM and PHSTOPH from library gm2em * |
c ******************************************************************************** |
REAL FUNCTION LMSTOLM (PHIS, LAMS, POLPHI, POLLAM) |
C |
C**** LMSTOLM - FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER |
C**** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
C**** IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT |
C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** AUFRUF : LAM = LMSTOLM (PHIS, LAMS, POLPHI, POLLAM) |
C** ENTRIES : KEINE |
C** ZWECK : BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER |
C** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
C** IM ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** VERSIONS- |
C** DATUM : 03.05.90 |
C** |
C** EXTERNALS: KEINE |
C** EINGABE- |
C** PARAMETER: PHIS REAL GEOGR. BREITE DES PUNKTES IM ROT.SYS. |
C** LAMS REAL GEOGR. LAENGE DES PUNKTES IM ROT.SYS. |
C** POLPHI REAL WAHRE GEOGR. BREITE DES NORDPOLS |
C** POLLAM REAL WAHRE GEOGR. LAENGE DES NORDPOLS |
C** AUSGABE- |
C** PARAMETER: WAHRE GEOGRAPHISCHE LAENGE ALS WERT DER FUNKTION |
C** ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0) |
C** |
C** COMMON- |
C** BLOECKE : KEINE |
C** |
C** FEHLERBE- |
C** HANDLUNG : KEINE |
C** VERFASSER: D.MAJEWSKI |
REAL LAMS,PHIS,POLPHI,POLLAM |
DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
ZSINPOL = SIN(ZPIR18*POLPHI) |
ZCOSPOL = COS(ZPIR18*POLPHI) |
ZLAMPOL = ZPIR18*POLLAM |
ZPHIS = ZPIR18*PHIS |
ZLAMS = LAMS |
IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0 |
ZLAMS = ZPIR18*ZLAMS |
ZARG1 = SIN(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS) + |
1 ZCOSPOL* SIN(ZPHIS)) - |
2 COS(ZLAMPOL)* SIN(ZLAMS)*COS(ZPHIS) |
ZARG2 = COS(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS) + |
1 ZCOSPOL* SIN(ZPHIS)) + |
2 SIN(ZLAMPOL)* SIN(ZLAMS)*COS(ZPHIS) |
IF (ABS(ZARG2).LT.1.E-30) THEN |
IF (ABS(ZARG1).LT.1.E-30) THEN |
LMSTOLM = 0.0 |
ELSEIF (ZARG1.GT.0.) THEN |
LMSTOLAM = 90.0 |
ELSE |
LMSTOLAM = -90.0 |
ENDIF |
ELSE |
LMSTOLM = ZRPI18*ATAN2(ZARG1,ZARG2) |
ENDIF |
RETURN |
END |
REAL FUNCTION PHSTOPH (PHIS, LAMS, POLPHI, POLLAM) |
C |
C**** PHSTOPH - FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER |
C**** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM |
C**** ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** AUFRUF : PHI = PHSTOPH (PHIS, LAMS, POLPHI, POLLAM) |
C** ENTRIES : KEINE |
C** ZWECK : BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER |
C** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM |
C** ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** VERSIONS- |
C** DATUM : 03.05.90 |
C** |
C** EXTERNALS: KEINE |
C** EINGABE- |
C** PARAMETER: PHIS REAL GEOGR. BREITE DES PUNKTES IM ROT.SYS. |
C** LAMS REAL GEOGR. LAENGE DES PUNKTES IM ROT.SYS. |
C** POLPHI REAL WAHRE GEOGR. BREITE DES NORDPOLS |
C** POLLAM REAL WAHRE GEOGR. LAENGE DES NORDPOLS |
C** AUSGABE- |
C** PARAMETER: WAHRE GEOGRAPHISCHE BREITE ALS WERT DER FUNKTION |
C** ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0) |
C** |
C** COMMON- |
C** BLOECKE : KEINE |
C** |
C** FEHLERBE- |
C** HANDLUNG : KEINE |
C** VERFASSER: D.MAJEWSKI |
REAL LAMS,PHIS,POLPHI,POLLAM |
DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
SINPOL = SIN(ZPIR18*POLPHI) |
COSPOL = COS(ZPIR18*POLPHI) |
ZPHIS = ZPIR18*PHIS |
ZLAMS = LAMS |
IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0 |
ZLAMS = ZPIR18*ZLAMS |
ARG = COSPOL*COS(ZPHIS)*COS(ZLAMS) + SINPOL*SIN(ZPHIS) |
PHSTOPH = ZRPI18*ASIN(ARG) |
RETURN |
END |
REAL FUNCTION LMTOLMS (PHI, LAM, POLPHI, POLLAM) |
C |
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H% |
C |
C**** LMTOLMS - FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM |
C**** AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
C**** IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT |
C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** AUFRUF : LAM = LMTOLMS (PHI, LAM, POLPHI, POLLAM) |
C** ENTRIES : KEINE |
C** ZWECK : UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM AUF |
C** EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM |
C** ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** VERSIONS- |
C** DATUM : 03.05.90 |
C** |
C** EXTERNALS: KEINE |
C** EINGABE- |
C** PARAMETER: PHI REAL BREITE DES PUNKTES IM GEOGR. SYSTEM |
C** LAM REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM |
C** POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS |
C** POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS |
C** AUSGABE- |
C** PARAMETER: WAHRE GEOGRAPHISCHE LAENGE ALS WERT DER FUNKTION |
C** ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0) |
C** |
C** COMMON- |
C** BLOECKE : KEINE |
C** |
C** FEHLERBE- |
C** HANDLUNG : KEINE |
C** VERFASSER: G. DE MORSIER |
REAL LAM,PHI,POLPHI,POLLAM |
DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
ZSINPOL = SIN(ZPIR18*POLPHI) |
ZCOSPOL = COS(ZPIR18*POLPHI) |
ZLAMPOL = ZPIR18*POLLAM |
ZPHI = ZPIR18*PHI |
ZLAM = LAM |
IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0 |
ZLAM = ZPIR18*ZLAM |
ZARG1 = - SIN(ZLAM-ZLAMPOL)*COS(ZPHI) |
ZARG2 = - ZSINPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL)+ZCOSPOL*SIN(ZPHI) |
IF (ABS(ZARG2).LT.1.E-30) THEN |
IF (ABS(ZARG1).LT.1.E-30) THEN |
LMTOLMS = 0.0 |
ELSEIF (ZARG1.GT.0.) THEN |
LMTOLMS = 90.0 |
ELSE |
LMTOLMS = -90.0 |
ENDIF |
ELSE |
LMTOLMS = ZRPI18*ATAN2(ZARG1,ZARG2) |
ENDIF |
RETURN |
END |
REAL FUNCTION PHTOPHS (PHI, LAM, POLPHI, POLLAM) |
C |
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H% |
C |
C**** PHTOPHS - FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI |
C**** AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
C**** IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT |
C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** AUFRUF : PHI = PHTOPHS (PHI, LAM, POLPHI, POLLAM) |
C** ENTRIES : KEINE |
C** ZWECK : UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI AUF |
C** EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM |
C** ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** VERSIONS- |
C** DATUM : 03.05.90 |
C** |
C** EXTERNALS: KEINE |
C** EINGABE- |
C** PARAMETER: PHI REAL BREITE DES PUNKTES IM GEOGR. SYSTEM |
C** LAM REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM |
C** POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS |
C** POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS |
C** AUSGABE- |
C** PARAMETER: ROTIERTE BREITE PHIS ALS WERT DER FUNKTION |
C** ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0) |
C** |
C** COMMON- |
C** BLOECKE : KEINE |
C** |
C** FEHLERBE- |
C** HANDLUNG : KEINE |
C** VERFASSER: G. DE MORSIER |
REAL LAM,PHI,POLPHI,POLLAM |
DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
ZSINPOL = SIN(ZPIR18*POLPHI) |
ZCOSPOL = COS(ZPIR18*POLPHI) |
ZLAMPOL = ZPIR18*POLLAM |
ZPHI = ZPIR18*PHI |
ZLAM = LAM |
IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0 |
ZLAM = ZPIR18*ZLAM |
ZARG = ZCOSPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL) + ZSINPOL*SIN(ZPHI) |
PHTOPHS = ZRPI18*ASIN(ZARG) |
RETURN |
END |
/tags/1.0/density/density.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = density.o ${LAGRANTO}/lib/times.a ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
density: $(OBJS) |
${F77} -o density $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/density/density.sh |
---|
0,0 → 1,257 |
#!/bin/csh |
# --------------------------------------------------------------------- |
# Usage, parameter settings |
# --------------------------------------------------------------------- |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( (${#argv} == 0) | (${#argv} < 2) ) then |
echo |
${LAGRANTO}/bin/lagrantohelp density short |
echo |
exit 0 |
endif |
# Write title |
echo |
echo '=========================================================' |
echo ' *** START OF PREPROCESSOR DENSITY *** ' |
echo |
# --------------------------------------------------------------------- |
# Handle input parameters |
# --------------------------------------------------------------------- |
# Get input parameters |
set inpfile = $1 |
set outfile = $2 |
# Set default values |
set radius = 100 |
set unit = 'km' |
set grid = "360 180 -180. -90. 1. 1." |
set mode = 'keep' |
set tratime = 'all' |
set param = 0 |
set gridtype = 'latlon' |
set sel_file = 'nil' |
set sel_format = 'nil' |
set field = 'nil' |
set crefile = 0 |
# Handle optional arguments |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -radius |
set radius = $argv[2] |
set unit = $argv[3] |
echo "Flag '-radius' -> ${radius} ${unit} (user defined)" |
shift; |
shift; |
breaksw |
case -time |
set tratime=$argv[2] |
echo "Flag '-tratime' -> ${tratime} (user defined)" |
shift; |
breaksw |
case -interp |
set param=$argv[2] |
if ( "$argv[3]" == "h" ) set mode = "time" |
if ( "$argv[3]" == "km" ) set mode = "space" |
if ( "$argv[3]" == "deg" ) set mode = "grid" |
echo "Flag '-interp' -> ${mode} ${param} (user defined)" |
shift; |
shift; |
breaksw |
case -create |
set crefile = 1 |
echo "Flag '-create' -> true (user defined)" |
breaksw |
case -latlon |
set gridtype = 'latlon' |
if ( "$argv[2]" == "dynamic" ) then |
set grid = "0 0 0 0 0 0" |
echo "Flag '-latlon' -> dynamic (user defined)" |
shift; |
else |
set nlon = $argv[2] |
set nlat = $argv[3] |
set lonmin = $argv[4] |
set latmin = $argv[5] |
set dlon = $argv[6] |
set dlat = $argv[7] |
set grid = "${nlon} ${nlat} ${lonmin} ${latmin} ${dlon} ${dlat}" |
echo "Flag '-latlon -> ${grid} (user defined)" |
shift; |
shift; |
shift; |
shift; |
shift; |
shift; |
endif |
breaksw |
case -rotated |
set gridtype = 'rotated' |
set clon = $argv[2] |
set clat = $argv[3] |
set nlonlat = $argv[4] |
set dlonlat = $argv[5] |
set grid = "${clon} ${clat} ${nlonlat} ${dlonlat}" |
echo "Flag '-rotated -> ${clon}, ${clat}, ${nlonlat}, ${dlonlat} (user defined)" |
shift; |
shift; |
shift; |
shift; |
breaksw |
case -index |
set sel_file = $argv[2] |
set sel_format = 'index' |
echo "Flag '-index' -> ${sel_file} (user defined)" |
shift; |
breaksw |
case -boolean |
set sel_file = $argv[2] |
set sel_format = 'boolean' |
echo "Flag '-boolean' -> ${sel_file} (user defined)" |
shift; |
breaksw |
case -field |
set field = $argv[2] |
echo "Flag '-field' -> ${field} (user defined)" |
shift; |
breaksw |
endsw |
shift; |
end |
# --------------------------------------------------------------------- |
# Do some checks and preparation, then run the program |
# --------------------------------------------------------------------- |
# Rename field <time> to <TIME> to avoid conflict with time coordinate |
# on the netCDF file |
if ( "${field}" == "time" ) set field = "TIME" |
# Determine the time step |
if ( "${tratime}" == "all" ) then |
set step = 0 |
else |
set timelist = (`${LAGRANTO}/bin/trainfo.sh $inpfile times`) |
set step = 0 |
set found = 0 |
foreach val ( ${timelist} ) |
@ step = ${step} + 1 |
if ( "${tratime}" == "${val}" ) then |
set found = ${step} |
endif |
end |
if ( ${found} == 0 ) then |
echo "Invalid time ${tratime} for gridding" |
echo "${timelist}" |
exit 1 |
endif |
set step = ${found} |
endif |
# Check consistency of arguments |
if ( ( "${mode}" == "time" ) & ( ${step} != 0 ) ) then |
echo " ERROR: Options 'interp -time' and 'step' incompatible' " |
exit 1 |
endif |
if ( ( "${mode}" == "space" ) & ( ${step} != 0 ) ) then |
echo " ERROR: Options 'interp -space' and 'step' incompatible' " |
exit 1 |
endif |
# Get trajectory info |
set ntra = (`${LAGRANTO}/bin/trainfo.sh $inpfile ntra`) |
set ntime = (`${LAGRANTO}/bin/trainfo.sh $inpfile ntim`) |
set nfield = (`${LAGRANTO}/bin/trainfo.sh $inpfile ncol`) |
# Check whether selection file is available |
if ( "${sel_file}" != "nil" ) then |
if ( ! -f ${sel_file} ) then |
echo " ERROR: selection file ${sel_file} is missing... Stop" |
exit 1 |
endif |
endif |
# Check whether output file exists - set the <crefile> flag |
if ( "${crefile}" == "0" ) then |
if ( ! -f ${outfile} ) then |
set crefile = 1 |
echo |
echo "${outfile} will be created... " |
else |
echo |
echo "${outfile} will be modified ..." |
endif |
else |
echo |
echo "${outfile} will be created... " |
endif |
# Chewck whether the variable exists - set the <crevar> flag |
if ( "${crefile}" == "0" ) then |
set varlist = ` ${LAGRANTO}/goodies/getvars ${outfile}` |
set crevar = 1 |
foreach var ( ${varlist} ) |
if ( "${var}" == "${field}" ) set crevar = 0 |
end |
else |
set crevar = 1 |
endif |
# Prepare parameter file and run program |
\rm -f density.param |
touch density.param |
echo ${inpfile} >> density.param |
echo ${outfile} >> density.param |
echo \"${field}\" >> density.param |
echo ${ntime} ${nfield} ${ntra} >> density.param |
echo ${gridtype} >> density.param |
echo ${grid} >> density.param |
echo ${radius} ${unit} >> density.param |
echo ${mode} >> density.param |
echo ${param} >> density.param |
echo ${step} >> density.param |
echo \"${sel_file}\" >> density.param |
echo \"${sel_format}\" >> density.param |
echo ${crefile} >> density.param |
echo ${crevar} >> density.param |
# Write status info |
echo |
echo ' *** END OF PREPROCESSOR DENSITY *** ' |
echo '=========================================================' |
echo |
# Run density |
${LAGRANTO}/density/density |
# Make clean |
\rm -f density.param |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/docu/man/caltra.0 |
---|
0,0 → 1,97 |
.TH caltra |
.SH NAME |
.B caltra - |
calculate air parcel trajectories |
.SH SYNOPSIS |
.B caltra |
.I startdate |
.I enddate |
.I startfile |
.I filename |
[ |
.I optional arguments |
] |
.SH DESCRIPTION |
Calculate trajectories for the air parcels starting at the positions specified in |
.I startfile. |
The trajectories cover the time period from |
.I startdate |
to |
.I enddate |
and the trajectories are saved in the output file |
.I filename. |
Forward and backward trajectories can be calculated according to the order of the start and end date. |
.SH PARAMETERS |
.TP 15 |
.I startdate |
start time of the air parcels in the format YYYYMMDD_HH(MM) (e.g. 20100101_00 or 20100101_0030 for 1 January 2010, 00 UTC and 00:30 UTC). Note that the minutes (MM) are optional. |
.TP 15 |
.I enddate |
end time of the air parcels (same format as the |
.I startdate |
). If the end time is after the start time, forward trajectories are calculated; otherwise, i.e. for end date before the start date, backward trajectories result. |
.TP 15 |
.I startfile |
file with the starting positions of the trajectories (possibly created with |
.B |
create_strartf |
). Different formats for the "startfile" are supported (see |
.B reformat |
for details). If no format specifier (appendix .[1234]) is given, a simple (longitude,latitude,pressure) list is expected. |
.TP 15 |
.I filename |
output trajectory file with trajectories. Different formats are supported (see |
.B reformat |
for details). |
.SH OPTIONAL |
.br |
.TP 15 |
.I -j |
Jumping flag: if a trajectory crosses the lower boundary, it is raised a little and hence is allowed to move on. Otherwise, i.e. no "-j" flag set, the trajectory would stick at the same position. The default is that "-j" is |
.B not |
set. |
.TP 15 |
.I -i hours |
time increments (in hours) for input P and S files. If not explicitely specified, this is determined from the P and S files in the current directory. |
.TP 15 |
.I -t min |
time step (in minutes) for trajcetory calculation. Per default, the time step is 1/12 the time increment of the input files. For instance, 6-h input P and S files result in a time step of 5 min. The time step must be consisten with the output interval (see next optional parameter "-o"). |
.TP 15 |
.I -o hours |
Output interval (in minutes) of the air parcel positions. Per default it is the same as the time increment between the input P and S files (see option "-i"). Note that the output interval must be a multiple of the time step for trajectory calculation (see optional argument "-t"). |
.TP 15 |
.I -p |
Periodicity flag. If set, a periodic domain is assumed in zonal direction. Per default, the flag is |
.B not |
set. |
.TP 15 |
.I -changet |
flag whether the times of the P and S files should be changed or not before a calculation; the default is that the |
times are |
.B not |
changed. |
.TP 15 |
.I -noclean |
flag whether parameter and criterion files should be kept; this is particularly helpful for debugging. |
.TP 15 |
.I -timecheck |
enforce a time check on the data file |
.SH EXAMPLES |
.TP 5 |
.B [1] caltra 19891020_00 19891020_18 startf OUT.1 |
Calculate forward trajectories from 20/10/1989 00 UTC to 20/10/1989 18 UTC. The starting starting positions are given on the file "startf" as a list of (longitude,latitude,pressure) values. The output trajectories are written to the file "OUT.1", where the appendix 1 denotes ASCII format..B |
.TP 5 |
.B [2] caltra 19891020_18 19891020_00 startf OUT.1 |
As in example 1, but backward trajectories from 20/10/1989 18 UTC to 20/10/1989 00 UTC. |
.TP 5 |
.B [3] caltra 19891020_00 19891020_18 startf OUT -j |
As in example [1], but with jumping flag set: if a trajectory crosses the lower boundary (topography), it is raised a little and then is allowed to move on. |
.TP 5 |
.B [4] caltra 19891020_00 19891020_18 startf OUT -j -o 15 -t 15 |
As in example [3], but the output interval is set to 15 min with the optional argument "-o". Note that the output interval (15 min) must be a multiple of the time step, which is here set explicitely to 15 min with "-t". |
.TP 5 |
.B [5] caltra 19891020_0130 19891020_1730 startf1 OUT -j -o 15 -t 15 -changet |
Start from non-analysis time 01:30 UTC to non-analysis time 17:30 UTC. Furthermore, the times on the prinmary netCDF files are changed accordingly. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/changecst.0 |
---|
0,0 → 1,22 |
.TH changecst |
.SH NAME |
.B changecst - change constants file name on the netCDF file |
.SH SYNOPSIS |
.B changecst |
.I filename |
.I new_cst_file |
.SH DESCRIPTION |
Change the name of the constants file for "filename" to the new name "new_cst_file" |
.SH PARAMETERS |
.TP 15 |
.B filename |
name of the netCDF file |
.TP 15 |
.B new_cst_file |
name of the new constants file name |
.SH EXAMPLES |
.TP 5 |
.B [1] changecst P20110102_18 ml_cst |
change the constants filename for P20110102_18 to its new name "ml_cst". |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/changet.0 |
---|
0,0 → 1,22 |
.TH changet |
.SH NAME |
.B changet - change time on a netCDF file with filename P{YYYYMMDD_HH} or S{YYYYMMDD_HH} |
.SH SYNOPSIS |
.B changet |
.I startdate |
.I file |
.SH DESCRIPTION |
Change the time value of a netCDF file with filename P{YYYYMMDD_HH} or S{YYYYMMDD_HH}; the time is set in hours relative to the startdate (in format YYYYMMDD_HH). |
.SH PARAMETERS |
.TP 15 |
.B startdate |
reference date in format YYYYMMDD_HH. |
.TP 15 |
.B file |
name of the netCDF file with filename P{YYYYMMDD_HH} or S{YYYYMMDD_HH}. |
.SH EXAMPLES |
.TP 5 |
.B [1] changet 20110102_00 P20110102_18 |
sets the time of the netCDF file "P20110102_18" to 18 h. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/create_startf.0 |
---|
0,0 → 1,195 |
.TH create_startf |
.SH NAME |
.B create_startf - |
create starting files for Lagranto |
.SH SYNOPSIS |
.B create_startf |
.I date |
.I filename |
.I specifier |
[ |
.I optional arguments |
] |
.SH DESCRIPTION |
Create starting files |
for a Lagranto calculation. The staring positions are based on the P and S files for |
.I date |
and are as specified in a |
.I specifier. |
The starting coordinates (longitude, latitude, pressure [in hPa]) are written to the file |
.I filename. |
.SH PARAMETERS |
.TP 15 |
.I date |
date of input P and S file (e.g. 20100101_00). If the date is between two P and S files, |
linear interpolation is used between the two times. |
.TP 15 |
.I filename |
output file with starting points (e.g. startf). Different formats are supported (see |
.B reformat |
for details) |
.TP 15 |
.I specifier |
detailed description of starting positions. The specifier has the following format: |
.B |
.I <horizontal> |
@ |
.I <vertical> |
@ |
.I |
<unit> |
@ |
.I <selection>. |
The components of the specifier are described in greater detail in the following sections. |
.SH HORIZONTAL |
.TP 15 |
.B - file[filename] |
read lon/lat from file "filename"; each line contains one lat/lon pair. |
.TP 15 |
.B - line[lon1,lon2,lat1,lat2,n] |
n points from (lon1,la1) to (lon2,lat2); the points are linearly interpolated in lat/lon space. |
.TP 15 |
.B - box.eqd[lon1,lon2,lat1,lat2,ds] |
lat/lon box bounded with south-western point (lon1,lat1) and north-eastern point (lon2,lat2); the equdistant points within the box have a horizontal distance ds (in [km]). |
.TP 15 |
.B - box.grid[lon1,lon2,lat1,lat2,] |
lat/lon box with south-western point (lon1,lat1) and north-eastern point (lon2,lat2 grid points; all grid points within this box are taken as staring points. |
.TP 15 |
.B - point[lon,lat] |
single lon/lat point. |
.TP 15 |
.B - shift[lon,lat,dlon,dlat] |
lon/at points and dlon/dlat shifhted ones, i.e. in total five points: central one and four shifted ones: (lon,lat), (lon+dlon,lat), (lon-dlon,lat), (lon,lat+dlat), (lon,lat-dlat). |
.TP 15 |
.B - polygon.eqd[filename,ds] |
equidistant within arbirtrary polygon (ds in [km]). The file with the polygon points has the following format: 1st line a lon/lat point within the polygon; further lines lon/lat points of the vertices (max 500) of the polygon. |
.TP 15 |
.B - polygon.grid[filename] |
grid points within arbirtrary polygon. The file with the polygon points has the following format: 1st line a lon/lat point within the polygon; further lines lon/lat points of the vertices (max 500) of the polygon. |
.TP 15 |
.B - circle.eqd[lonc,latc,radius,ds] |
circle with centre at (lonc,latc) and radius "radius" (in km); the equdistant points within the circle have a horizontal distance ds (in [km]). |
.TP 15 |
.B - circle.grid[lonc,latc,radius] |
circle with centre at (lonc,latc) and radius "radius" (in km); all rid points within the circle are selected. |
.TP 15 |
.B - region.eqd[id,ds] |
Read region specification from region file ("default regionf", to be changed with option "-regionf") and fill it equidistantly with starting points (ds in km). The region identification is "id", see below in section REGION FILE. |
.TP 15 |
.B - region.grid[id] |
Read region specification from region file ("default regionf", to be changed with option "-regionf") and fill it with starting points on the input grid. The region identification is "id", see below in section REGION FILE. |
.SH VERTICAL |
.TP 15 |
.B - file[filename] |
read levels from file "filename"; each line in the file contains one level. |
.TP 15 |
.B - level[lev] |
a single level |
.TP 15 |
.B - list[lev1,lev2,lev3,...] |
a list of levels; if many levels are needed they are better passed to "create_startf" with the option "file[filename]". |
.TP 15 |
.B - profile[lev1,lev2,n] |
n equdistant levels between lev1 and lev2. |
.TP 15 |
.B - grid[lev1,lev2] |
all grid points within layer (lev1,lev2) are selected |
.SH UNIT |
.TP 15 |
.B - hPa |
pressure (in hPa). |
.TP 15 |
.B - hPa,agl |
pressure (in hPa) above ground level. |
.TP 15 |
.B - K |
potential temperature (in K). |
.TP 15 |
.B - PVU |
potential vorticty (in PVU). Note that potential vorticity (PV) might not be unique as a vertical coordinate; if several levels have a given PV value, the highest one is chosen. |
.TP 15 |
.B - INDEX |
index of model level (1=surface). |
.SH SELECTION |
.TP 15 |
.B - criterion |
Selection criteria based on meteorological fields applied to the starting position; The criteria follow the syntax of the program |
.B select. |
.TP 15 |
.B - nil |
If no selection criteria should be invoked, the argument "nil" should be given. |
.SH REGION FILE |
Several starting regions can be defined for every case in a region file (default filename is "regionf"; to be changed with optional parameter "-regionf filename"). There are two possible formats for specifying a region (they require either a line with 5 or 9 entries): |
.TP 5 |
.B "regnum lonw lone lats latn" |
a regular latitude-longitude square: regnum=integer region number; lonw=westernmost longitude of starting region; lone=easternmost longitude; lats=southernmost latitude; latnNorthernmost latitude. |
.TP 5 |
.B "regnum lon1 lat1 lon2 lat2 lon3 lat3 lon4 lat4" |
an irregular latitude-longitude square: regnum=integer region number; lon{x},lat{x} = longitude and latitude of the x-th corner. Note that the 4 corners must be arranged counterclockwise. For a triangle the 4th corner can be specified identically to the 3rd. |
.TP 5 |
.B Note: (1) if a line starts with '#' it is regarded as comment and not further considered; (2) each line in the region file must start with '"! |
.TP 5 |
.B "101 -40. -24. 52. 60.": |
region in the central Atlantic from 40 W to 24 W and 52 N to 60 N; the region identifier is 101. |
.TP 5 |
.B "250 -30. 43. -24. 36. -18. 50.2 -35.2 50.2": |
irregular square in the central Atlantic; the region identifier is 250. |
.SH OPTIONAL |
.br |
.TP 15 |
.I -t tracefile |
tracing file with variables for selection criteria (see |
.B trace |
for format of the file). If no file is specified, the default |
"tracevars" is used. Further, if no selection criterion is invoked, no |
tracing file is necessary. |
.TP 15 |
.I -changet |
flag whether the times of the P and S files should be changed or not before a calculation; the default is that the |
times are not changed. |
.TP 15 |
.I -noclean |
flag whether parameter and criterion files should be kept; this is particularly helpfuld for debugging. |
.TP 15 |
.I -regionf filename |
change the region file from its default value "regionf" to a new file name: the syntax is "-regionf filename". |
.TP 15 |
.I -timecheck |
enforce a time check on the data files |
.SH EXAMPLES |
.TP 5 |
.B [1] create_startf 19891020_00 startf 'point(-10,50) @ list(450,500,550) @ hPa' |
Starting points are (longitude, latitude, pressure in hPa): (-10,50,450); (-10,50,500); (-10,50,550). No selection criterion is applied; the positions are written to file "startf". |
.TP 5 |
.B [2] create_startf 19891020_00 startf 'line(-10,-5,40,50,10) @ level(450) @ hPa,agl' |
10 points are equidistantly specified between lon/lat point (-10,40) and (-5,50); all trajectories start at 450 hPa above ground level - the surface pressure is taken from the primary file P19891020_00. The positions are saved in "startf". |
.TP 5 |
.B [3] create_startf 19891020_00 startf 'box.grid(-10,-5,40,50) @ list(300,320) @ K' |
All grid points in the box with the south-eastern lon/lat point (-10,40) and the north-eastern one (-5,50) are taken - the horizontal grid spacing is specfified in the primary file P19891020_00. In the vertical, two isentropic levels are chosen: 300 K and 320 K. The potential temperature for the calculation is taken from the secondary file S19891020_00. |
.TP 5 |
.B [4] create_startf 19891020_00 startf 'shift(-10,40,1,1) @ profile(1000,200,100) @ hPa' |
A profile of 100 equidistant levels between 1000 hPa and 200 hPa; in the horizontal the central lon/lat point (-10,40) is taken and four horizontally displaced ones, the diplacement being 1 degree in zonal and meridional direction. |
.TP 5 |
.B [5] create_startf 19891020_00 startf.1 'shift(-10,40,1,1) @ profile(1000,200,100) @ hPa' |
As in the previous example [4], but the starting positions are saved as a trajectory file instead of a (lon,lat,p)-list. |
.TP 5 |
.B [6] create_startf 19891020_00 startf.1 criterion |
As in the previous example [5], but the criterion is saved on a file with filename "criterion". |
.TP 5 |
.B [7] create_startf 19891020_00 startf 'polygon.grid(polygon) @ level(500) @ hPa |
A polygon is specified in the file "polygon"; the different lines in the file are: -5. 45. / -10. 40. / 10. 40. / 10 50. / -10. 45. The first lon/lat point lies within the polygon, all other lon/lat points are the vertices of the polygon. All grid points within the polygon are taken as starting point, at level 500 hPa. |
.TP 5 |
.B [8] create_startf 19891020_00 startf 'polygon.eqd(polygon,50) @ level(500) @ hPa |
As in the previous example [7], except that the starting points are distributed equidistantly within the polygon. The horizontal distance between the starting points is 50 km in zonal and meridional direction. |
.TP 5 |
.B [9] create_startf 19891020_00 startf 'shift(-10,40,1,1) @ profile(1000,200,100) @ hPa @ GT:TH:310' |
As in example [4], but a selection criterion is additionally applied: only starting positions with potential temperature (TH) greater than (GT) 310 K are kept. Potential temperature must be available on the secondary file S19891020_00 and the file "tracevars" must have a line with "TH 1. 0 S". Further examples for selection criteria can be seen in |
.B |
select. |
.TP 5 |
.B [10] create_startf 19891020_00 START.1 'region.eqd(3,10) @ level(500) @ hPa' |
get equidistant starting points (10 km distance) in the region with identifier 3, as listed in the region file "regionf" (the default). |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/datelist.0 |
---|
0,0 → 1,79 |
.TH datelist |
.SH NAME |
.B datelist - handling of datelists |
.SH SYNOPSIS |
.B datelist |
.I filename |
.I mode |
.I [ parameters ] |
.SH DESCRIPTION |
A date list is a file of dates in the format {YYYYMMDD_HH}, e.g. 19900101_00 for 00 UTC, 1 January 1990. This command offers several ways how to create date lists and to work with them. |
.SH PARAMETERS |
.TP 10 |
.I filename |
name of the date list file. If the name |
.B 'stdout' |
or |
.B 'screen' |
is given, the output will be directed to standardoutput: no file will be created. |
.TP 10 |
.I mode |
one of several modes (see below). |
.SH CREATING DATE LISTS |
.TP 5 |
.B -create stardate enddate |
create a datelist from startdate (in format {YYYYMMDD_HHMM}) to enddate; the time interval is per default 6 h (see option -interval). If the start and end date do not match with the analysis times, the date list will contain the enclosing analysis times: for instance, for |
.B -create 20100201_04 20100201_19 |
the date list will contain the following dates: 20100201_00, 20100201_06, 20100201_12, 20100201_18, 20100202_00. |
.TP 5 |
.B -indir dirname |
search for dates (in format {YYYYMMDD_HH}) in the direcory given with {dirname} - the dates are written in ascending order to the datelist file and repeating dates are removed. |
.TP 5 |
.B -interval value |
change the interval to {value} hours, instead of the default 6 hours. |
.SH INFO ABOUT DATE LISTS |
.TP 5 |
.B -ndates |
write the number of dates in the list |
.TP 5 |
.B -timerange |
write the time range {last date} - {first date} [in hours]. |
.TP 5 |
.B -isin date |
check whether the date is in the list (1) or not (0). |
.SH STEPPING THROUGH DATE LISTS |
.TP 5 |
.B -first |
write the first date of the date list |
.TP 5 |
.B -last |
write the last date of the date list |
.TP 5 |
.B -next date |
find the date {date} in the list and write the |
.B next |
date to screen; if no next date is in the list, i.e. the end of the list is reached, 'nil' will be returned. |
.TP 5 |
.B -prev date |
find the date {date} in the list and write the |
.B previous |
date to screen; if no previous date is in the list, i.e. the beginning of the list is reached, 'nil' will be returned. |
.SH COMPARING DATE LISTS |
.TP 5 |
.B -overlap file1 file1 |
determine the overlap of two date lists. |
.TP 5 |
.B -onlyin1 file1 file1 |
determine the dates which only occur in date list 1, but not in datelist 2 |
.TP 5 |
.B -onlyin2 file1 file1 |
determine the dates which only occur in date list 2, but not in datelist 1 |
.SH Examples |
.TP 5 |
.B [1] datelist screen -indir ./ |
look for dates in the current directory and write them to screen |
.TP 5 |
.B [2] datelist dates -create 19890101_00 20110101_00 -interval 2 |
creates dates from 00 UTC, 1 January 1989 to 00 UTC, 1 January 2011 with an interval of 2 hours. The output will be written to the file 'dates'. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/density.0 |
---|
0,0 → 1,125 |
.TH density |
.SH NAME |
.B density - |
gridding of trajectory files: either single trajectories or trajectory densities |
.SH SYNOPSIS |
.B density |
.I inpfile |
.I outfile |
[ |
.I optional arguments |
] |
.SH DESCRIPTION |
Gridding of a trajectory file "inpfile"; the output is written to a netCDF file "outfile). The trajectories can be interpolated to equal-distance intervals or to a higher time resolution; furthermore, an interpolation is provided to give a continuous line in a longitude/latitude grid. Besides densities of trajectories, possibly at different times, gridding of traced meteorological fields is accepted. |
.SH PARAMETERS |
.TP 15 |
.B inpfile |
input trajectory file (in one of the accepted formats, see |
.B reformat |
for details) |
.TP 15 |
.B outfile |
output netCDF file with a regular or rotated longitude/latitude grid. The output can be either in IVE or in CF netCDF format (see switches below). |
.SH OPTIONAL PARAMETERS |
.TP 5 |
.B - field name |
Field name (according to the column names of the trajectory file) which should be gridded. If no field is specified, it is assumed that the trajectory density (counts per grid point) should be gridded. |
.TP 5 |
.B - create |
determines the behaviour if the output file already exists: 1) if the file does NOT exist, it will be created; 2) if the file already exists, it will be overwritten, i.e. newly created. If the flag is not set and the file already exists, the output of the new gridding will appended to the existing file. As a typical scenario: density TRAJECTORY DENSITY; density TRAJECTORY DENSITY -field p; density TRAJECORY DENSITY -field PV;... -> all fields (p, PV,...) will be written to the same output file "DENSITY". |
.TP 5 |
.B - index filename |
perform only a gridding of the trajectories in the index list "filename"; an index list is just a list of the indices of the single trajectories - it can easily be created with |
.B select |
and also is used in |
.B extract. |
.TP 5 |
.B - boolean filename |
perform only a gridding of the trajectories in the boolean list "filename"; a boolean list has for each trajectory an entry 1 (trajectory selected) or 0 (not selected) - it can easily be created with |
.B select |
and also is used in |
.B extract. |
.TP 5 |
.B - interp val unit |
interpolate the trajectories to new positions before the gridding; different modes are accepted: |
.B 1) "-interp 1 h" |
interpolates the trajectories to a new time resolution (here 1 h); |
.B 2) "-interp 20 km" |
interpolates the trajectories to a new space resolution (here 20 km). Note that nearly stationary trajectories will be reduced in their influence considerably if this mode is applied; |
.B 3) "-interp 2 deg" |
interpolates to a new resolution, expressed in deg lon/lat. This mode is particularly helpful if a "line" should be drawn on a lon/lat grid. |
.TP 5 |
.B - radius val unit |
set the filtering radius for the smoothing (default is 100 km); this radius determines over which radius each trajectory point is smeared out during the gridding. It should be adapted to the grid resolution: if it is too small, and no grid point falls into the circle with this radius, an error message is written. A good choice might be |
.B -radius <dlat|dlon [in km]>. |
Further Examples: |
.B "-radius 2 deg" |
for smoothing over 2 degrees lat/lon; |
.B "-radius 20 km" |
for a 20 km smoothing. |
.TP 5 |
.B - latlon [ nlon nlat lonmin latmin dlon dlat | dynamic ] |
specification of the regular output lon/lat grid; the default output grid has parameters: nlon = 360, nlat = 180, lonmin = -180, lonmax = 180, dlon =1, dlat = 1 (global). If the option |
.B dynamic |
is chosen, the grid is automatically adapted to the trajectory file: the longitude and latitude boundaries are determined and the resulting ranges divided in 400 grid pixel in each direction. In a second step the grid distance is set equal in zonal and meridional direction, and the other grid parameters correspondingly adjusted. |
.TP 5 |
.B - rotated clon clat nlonlat dlonlat |
specification of the rotated output lon/lat grid; the centre of the rotated grid is given with the central longitude (clon) and latitude (clat) - this point corresponds to 0/0 in the new coordinate system. The horizontal resolution (dlonlat) of the new grid is equal in rotated longitude and latitude. The final domain extensions are: -(nlonlat-1)/2*dlonlat, +(nlonlat-1)/2*dlonlat and correspondingle for rotated latitude. |
.TP 5 |
.B -time value |
do only a gridding of the time specified; e.g. -time 18.00 would perform a gridding of the trajectory time 18 h. If the netCDF already exists, and if the "-create" flag is not set, the new time will be added to the already existing file - the grid parameters will automatically be taken from the netCDF file. |
.SH OUTPUT FIELDS |
.TP 5 |
.B - COUNT |
number of trajectory points attributed to grid points; the integration of this field over the whole domain is equal to the total number of gridded trajectory points, i.e. equal to the product #trajectories x #times. |
.TP 5 |
.B - RESIDENCE |
residence time of trajectory points attributed to grid points; the integration of this field over the whole domain is equal to the total time of all trajectories, i.e. equal to the product #trajectories x #time x time interval. |
.TP 5 |
.B - AREA |
area (in square kilometers) attributed to each grid point, i.e. dlat x dlon x coslatitude). This field can be used to convert the units of COUNT and RESIDENCE to grid-independent values. For instance, |
.B RESIDENCE/AREA |
is the residence time per square kilometer. |
.TP 5 |
.B - FILED |
gridded field: e.g gridded pressure, temperature, potential vorticity. |
.SH EXAMPLES |
.TP 5 |
.B [1] density TRAJECTORY DENSITY |
bring the TRAJECTORY file into a netCDF file DENSITY with gloabl coverage (longitude/latitude grid). The netCDF file is in CF format and the all trajectory points are gridded, based on a smoothing radius of 100 km. |
.TP 5 |
.B [2] density TRAJECTORY DENSITY -latlon dynamic |
as in example [1], but now the lon/lat grid is automatically adapted to the range of the trajectory file. |
.TP 5 |
.B [3] density TRAJECTORY DENSITY -interp 1 h |
as in exaxmple [1], but the trajectories are interpolated to a 1-h time interval. This gives smoother trajectories. |
.TP 5 |
.B [4] density TRAJECTORY DENSITY -interp 20 km |
as in exaxmple [1], but the trajectories are interpolated to a 20-km distance interval. |
.TP 5 |
.B [5] density TRAJECTORY DENSITY -interp 1 deg |
as in exaxmple [1], but the trajectories are interpolated to a 1 deg distance interval. If the output grid (as specified in option "-latlon" or "-rotated") has the same spacing (1 deg) as given in "-interp 1 deg", a continuous line is drawn. |
.TP 5 |
.B [6] density TRAJECTORY DENSITY -radius 100 km |
the trajectory points are spread out over a circle with radius 100 km; this is equivalent to a smoothing of the resulting density field. Note that in a equidistant cylindrical projection, the circles become distorted towards the pole. If this is not appropriate, the option |
.B "-radius 2 deg" |
can be given, which is independent of geographical latitude. |
.TP 5 |
.B [7] density VALID DENS -time 18.00 |
only gridding of the trajectory points corresponding to time 18 h; if no time is specified or if |
.B "-time all", |
then all trajectory times are included. Note that interpolation with "-interp" (see above) is not allowed, if only one time step is selected, i.e. "-interp" works only with "-time all". |
.TP 5 |
.B [8] density TRAJECTORY DENSITY -rotated 30 50 401 0.1 -interp 0.2 deg |
all trajectory times are gridded, but this time onto a rotated lon/lat grid; for instance, an interesting feature was found at (lon=30,lat=50). The new coordinate system, a rotated lon/lat grid, is centered at this point and spreads from 20 W to 20 W and from 20 S to 20 N, comprising 401 grid points in rotated longitude and latitude direction. The new grid resolution is 0.1 degrees, which was taken into account in the interpolation to 0.2 deg intervals between trajectory points. |
.TP 5 |
.B [9] density TRAJECTORY DENSITY -index filename |
all trajectories in the trajecrtory file TRAJECTORY are gridded which are listed in the index file "filename". |
.TP 5 |
.B [10] density TRAJECTORY DENSITY -field p -time 0.00 -latlon dynamic |
in addition of positional gridding (COUNT, RESIDENCE), do also a gridding of the pressure (p). This gives the pressure at the grid points, averaged over all trajectories passing over the grid point. |
.TP 5 |
.B [11] density TRAJECTORY DENSITY -time 0.00; density TRAJECTORY DENSITY -time 6.00 |
the trajectory density for "TRAJECTORY" is first written to "OUTPUT" for time 0; then, with the second call, the densities are written for the time 6 h and included into the already existing netCDF file "DENSITY". Similarly, additional fiels can be added to a already existing netCDF file, e.g. with the second call "density TRAJECTOR DENSITY -field p -time 0.00". |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/difference.0 |
---|
0,0 → 1,41 |
.TH difference |
.SH NAME |
.B difference - calculate the difference of two trajecrtory files |
.SH SYNOPSIS |
.B difference |
.I inpfil1 |
.I inpfile2 |
.I outfile |
.I field |
.I [ -single|-max ] |
.SH DESCRIPTION |
Calculate the difference of two trajectory files "inpfile1" and "inpfile2" and write it to a new trajectory file "outfile". The difference is calculated of the field "field", which must be available on both input files. If the field "LATLON" is specified, the spherical distance between the two trajectories is taken. Furthermore, with "-single" the difference is written at all times, with "-max" only the time of maximum difference is written. |
.SH PARAMETERS |
.TP 15 |
.I inpfile1 |
first trajectory file |
.TP 15 |
.I inpfile2 |
second trajectory file |
.TP 15 |
.I outfile |
output trajectory file - note that this is not a standard trajectory file which can be further processed! The position of both trajectories are listed and also the field for both trajectories and their difference. |
.TP 15 |
.I field |
Name of field for which the difference should be calculated. It must be available in both trajectory files. IF "LATLON" is specified, the spherical distance between the trajectory positions is calculated. |
.SH OPTIONAL PARAMETERS |
.TP 15 |
.I -single |
the difference is written to "outfile" for all trajectory times |
.TP 15 |
.I -max |
the difference is written to "outfile" only for the trajectory time with maximum difference. |
.SH EXAMPLES |
.TP 5 |
.B [1] difference tra1 tra2 out LATLON -single |
gives the speherical distance (LATLON) between trajectories in "tra1" and "tra2". The difference is written for all trajectory times. |
.TP 5 |
.B [2] difference tra1 tra2 out TH -max |
gives the difference of potential temperature (TH) between trajectory file "ra1" and "tra2" and writes the maximum difference ("-max") to the output file "out". |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/extract.0 |
---|
0,0 → 1,55 |
.TH extract |
.SH extract |
.B extract - extract columns, times, single trajectories and starting positions |
.SH SYNOPSIS |
.B extract |
.I inptra |
.I outtra |
.I mode |
.SH DESCRIPTION |
Extract columns, times, single trajectories or starting positions from an input trajectory file |
.I inptra |
and write output to a new trajectory file |
.I outtra. |
The different extraction modes are specified with |
.I mode. |
Note: the time, longitude, latitude and pressure need not be extracted beacuse they are an integral part of every trajectory file - they are extracted by default. |
.SH EXTRACTION MODE |
.TP 5 |
.B -var |
extract columns of a trajectory file; the columns can be listed by name (e.g. -var TH PV RH) or a range of columns can be specified by the "to" operator (e.g. -var TH to PV). The two modes can also be combined: "-var TH to PV RH" extracts all columns between TH and PV, and additionally RH. |
.TP 5 |
.B -time |
extract trajectory times; the times can be given as a list of times (e.g. -time 6 12) or as a time range (e.g. -time 6 to 18). |
.TP 5 |
.B -tra |
extract single trajectories; the index of the trajectories can be specified as a list (e.g. -tra 10 12 14) or as a range of trajectories (e.g. -tra 10 to 20). |
.TP 5 |
.B -startf |
extract list (longitude, latitude, pressure) of starting positions ofvthe trajectory file (corresponding to time 0). |
.TP 5 |
.B -index |
extract single trajectories - the trajectory indices (from 1 to #trajectories) are given on a file (e.g. -index filename). |
.TP 5 |
.B -boolean |
extract single trajectories - the trajectory are specified on a boolean (0/1) file (e.g. -boolean filename). |
.TP 5 |
.B -pattern |
extract all trajectories which match the pattern given; the pattern is a list of numbers. It is then checked whether |
these numbers occur in a trajectory (all at one time). |
.SH EXAMPLES |
.TP 5 |
.B [1] extract inptra outtra -time 6 to 36 72 |
read input trajectory file "inptra", extract times 6 to 36 and additionally time 72, and write output to trajectory file "outtra". |
.TP 5 |
.B [2] extract inptra outtra -index indfile |
reads input trajectories from "inptra" and write all trajectories to "outtra" which are listed in the file "indfile". In "infile" the indices of selected trajectories are listed line-by-line. |
.TP 5 |
.B [3] extract inptra outtra -pattern -999.99 |
extracts all trajectories which have a missing data (-999.99) entry. |
.TP 5 |
.B [4] extract inptra outtra -pattern 0.00 -44.25 -28.47 140 |
extracts all trajectories which have the numbers '0.00 -44.25 -28.47 140' in their list. This options |
is convenient to search for specific times and positions, and then to see the complete trajectory. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/futureplans.0 |
---|
0,0 → 1,55 |
.TH development |
.SH NAME |
future plans for Lagranto |
.SH MAJOR |
.TP 5 |
.B [1] CF netCDF [until 1 April 2011] |
interface to CF netCDF format |
.TP 5 |
.B [2] GRIB |
interface to GRIB format |
.TP 5 |
.B [3] box tracing |
Instead of tracing point meteorological fields, trace the mean,maximum, minimum, median, variance,... within a box around the trajectory position |
.TP 5 |
.B [4] stochastic trajectories |
allow in caltra the addition of a random noise to the velocities; option "-random 0.01" would allow random variations of U, V and OMEGA in the range of 1 %. As a further step, a physical based "parameterisation" of turbulence could be included (based on Ri, DEF, TKE,...). This would allow to calculate an ensemble of trajectories, e.g. for one receptor point. |
.TP 5 |
.B [5] Parallelisation |
parallelisation of caltra, and possibly also of trace and select. |
.TP 5 |
.B [6] webLagranto |
web interface to Lagranto - in analogy to the HYSPLIT model |
.TP 5 |
.B [7] cosmoLagranto |
new version of COSMO Lagranto |
.SH MINOR |
.TP 5 |
.SH [1] SPECIAL |
remeber the settings for a SPECIAL command in the parameter list; this will make the evaluation of SPECIAL commands more efficient. |
.TP 5 |
.SH [2] offset in K |
allow vertical offsets in K for tracing, e.g. 'PV:+5K' traces PV 5 K above the trajectory position |
.TP 5 |
.B [3] SPECIAL:STE |
special criterion for STE, STT and TST in the form SPECIAL:STE:380,2,0,24,48; tropopause 2 PVU/380 K, STE within time 0-24 h, residence before and after the exchange at least 48 h. |
.TP 5 |
.B [4] compact data format |
additional formats for trajectory files: 1) compressed format; 2) FLEXPART format. |
.TP 5 |
.B [5] Goody: residence |
calculate the residence time in a specified region for all trajectories in a file |
.TP 5 |
.B [6] Goody: distance |
calculate the mimimum distance from a lon/lat/p point for all trajectories in a file. |
.TP 5 |
.B [6] Extension of Lagranto run |
extend forward and backward in time an existing Lagranto run |
.TP 5 |
.B [7] Definition of polygons |
Matlab tool for the definition of polygon files. |
.TP 5 |
.B [8] datelist |
Goody for handling of datelists: 1) datelist file -create start end; 2) datelist file -len; 3) datelist file -first|last; 4) datelist file -sort; 5) datelist file1 file2 -onlyin1|onlyin2|overlap|difference |
.SH REPORT FOR NEW IDEAS |
Please report new ideas to <michael.sprenger@env.ethz.ch>. |
/tags/1.0/docu/man/getmima.0 |
---|
0,0 → 1,32 |
.TH getmima |
.SH NAME |
.B getmima - get the mimimum and maximum of a field on a netCDF file, interpolated either to a pressure or an isentropic surface. |
.SH SYNOPSIS |
.B getmima |
.I filename |
.I field |
.I [ Pval | Tval ] |
.SH DESCRIPTION |
Interpolate the field "field" of a netCDF file "filename" either onto a pressure surface "Pval" or onto an isentropic surface "Tval", where the level is given in hPa or K, respectively. The output is in the format: min.max, lonmin, latmin, pmin, tmin, lonmax, latmax, pmax, tmax. |
.SH PARAMETERS |
.TP 15 |
.B filename |
input netCDF file (e.g. P20110102_00) |
.TP 15 |
.B field |
name of the field on the netCDF file (as obtained from |
.B getvars). |
.TP 15 |
.B Pval |
specification of a pressure surface at height "val" in hPa (e.g. "P500" for 500 hPa). |
.B Tval |
specification of an isentropic surface at height "val" in K (e.g. "T320" for 320 K). |
.SH EXAMPLES |
.TP 5 |
.B [1] getmima P20110201_00 T P500 |
gives the mimimum and maximum temperature on the 500 hPa surface - the output is: -49.155 -2.606 80.00 -88.00 500 0.0 -143.00 9.00 500 0.0, i.e. the minium temperture is -49.155 deg C at (lon,lat,p,time)=(80, -88, 500, 0) and correspondingly for the maximum temperature. |
.TP 5 |
.B [2] getmima S20110201_00 PV P320 |
gives the minium and maximum potential vorticity (PV) on the 320-K isentropic surface. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/getmima.ps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/postscript |
Property changes: |
Added: svn:mime-type |
+application/postscript |
\ No newline at end of property |
/tags/1.0/docu/man/gettidiff.0 |
---|
0,0 → 1,22 |
.TH gettidiff |
.SH NAME |
.B gettidiff - get the difference (in hours) between two dates |
.SH SYNOPSIS |
.B gettidiff |
.I date1 |
.I date2 |
.SH DESCRIPTION |
Get the time difference (in hours) between two dates ( in form YYYYMMDD_HH(MM), i.e. the minutes are optional): date1 - date2. The output is in format HH or HH.MM |
.SH PARAMETERS |
.TP 15 |
.B date1 |
first date ( in form YYYYMMDD_HH(MM) ) |
.TP 15 |
.B date2 |
second date ( in form YYYYMMDD_HH(MM) ) |
.SH EXAMPLES |
.TP 5 |
.B [1] gettidiff 20110102_18 20110205_00 |
gives the time difference between 20110102_18 and 20110205_00; the result is -798 h. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/getvars.0 |
---|
0,0 → 1,18 |
.TH getvars |
.SH NAME |
.B getvars - get a list of a fields on a netCDF file |
.SH SYNOPSIS |
.B getvars |
.I filename |
.SH DESCRIPTION |
Get a list of all fields on a netCDF file - the names of the fields are listed line-by-line. |
.SH PARAMETERS |
.TP 15 |
.B filename |
name of the netCDF file (e.g. P20110102_00). |
.SH EXAMPLES |
.TP 5 |
.B [1] getvars P20110102_00 |
gives a list of all fields on the netCDF file P20110102_00; the results is: time, Q, LWC, IWC, T, U, V, OMEGA, PS, SLP |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/lagranto.0 |
---|
0,0 → 1,180 |
.TH lagranto |
.SH NAME |
.B lagranto - |
master script for a trajectory calculation, including definition of the starting positions, tracing of meteorological fields and selection of trajectories |
.SH SYNOPSIS |
.B lagranto |
.I caseid[.label] |
.I startdate |
.I enddate |
.I startf |
.I select |
.I [ optional flags ] |
.SH DESCRIPTION |
Calculate trajectories for the time period |
.I startdate |
to |
.I enddate |
for the starting positions given in |
.I |
startf, |
either as position file or as criteria for starting positions. Furthermore, some selection criteria can be applied to the trajectory file, as given either in a selection file or an explicit seclection criterion (given in |
.I select |
). Each tracjectory calculation is given a case identifier |
.I caseid |
which determines where the input data and output files are located. |
.SH PARAMETERS |
.TP 10 |
.B caseid |
identifier for a trajectory calculation; "caseid" determines where the input netCDF files are found and where the output trajectory file is written. The different options are: |
.B 1) local |
(the input P and S files must be ready in the directory where Lagranto is called; the output directory is also written to the local directory); |
.B 2) casename |
(the input files are found in "${HOME}/cdf/casename/" and the output is written to "${HOME}/tra/casename/"; |
.B 3) interim |
(the input files are taken from the ERA-Interim archive, the output is written to the local directory); |
.B 4) analysis |
(as in 3), but for the ECMWF operational analysis); |
.B 5) forecast |
(as in 3), but for the ECMWF deterministic forecast). |
.TP 10 |
.B caseid.label |
the specification of "label" is optional; it allows to attribute to the output directory name this label and hence to distinguish between several Lagranto runs. Note that "label" has no influence where the input files are found and where the output directory is writtem to. It only is added to the output directory name! |
.TP 10 |
.B startdate |
starting date for the trajectory calculation in format YYYYMMDD_HH(MM). This date defines the reference date and time for the trajectory output, i.e. it corresponds to time 0. |
.TP 10 |
.B enddate |
end date for the trajectory calculation in format YYYYMMDD_HH(MM); if "enddate" is later than "startdate", a forward trajectory calculation is performed, otherwise a backward calculation. As an example: "20100101_00 20100105_00" is forward, and 20100105_00 20100101_00" is backward in time. |
.TP 10 |
.B startf |
definition of the starting positions; they can be either available as a |
.B 1) (lon/lat/pressure)-list |
in a file; as an |
.B 2) explicit criterion |
(e.g. "point(50,40) @ list(100,200,300,400) @ hPa') - for details, see documentation of |
.B startf; |
or as |
.B 3) a single point |
in the format "longitude latitude pressure". |
.TP 10 |
.B select |
definition of selection criterion; it can be passed either in a file or as an explicit selection criterion (e.g. "GT:PV:2:LAST'). For further details, see documentation of command |
.B select. |
.SH OPTIONAL PARAMETERS |
.TP 10 |
.B -o filename |
name of the output trajectory file; default filename is "lsl_{startdate}". |
.TP 10 |
.B -j |
jumping flag; if the trajectory runs into the ground, it is lifted a little and allowed to move on. This flag is directly passed to the command |
.B caltra. |
See documentation for "caltra" for further details. |
.TP 10 |
.B -v tracefile |
name of the tracing file which enlists all fields to be traced along the trajectories; the tracing file is directly passed to |
.B create_startf |
and |
.B trace |
(see documentation of these two commands for further details). |
.TP 10 |
.B -r regionfile |
name of the region file which enlists all regions; the region file is directly passed to |
.B create_startf |
and |
.B select |
(see documentation of these two commands for further details). |
.TP 10 |
.B -changet |
change the times on the netCDF files relative to the starting date; Lagranto expects the netCDF times to be relative to the starting date. The default value of "-changet" is false. |
.TP 10 |
.B -noclean |
do no cleaning after a trajectory run; the default is that the output directory will be cleaned. If cleaning is requested (the default), the following files will be kept in the outputdirectory: |
.B 1) the output trajectory file; |
.B 2) the log file of the trajectory run; |
.B 3) the run script. |
All other files are deleted. |
.TP 10 |
.B -log |
write log of Lagranto run on screen instead into a file. No log file will be created with this option. |
.TP 10 |
.B -prep |
create the run directory, prepare all files and build the run script - but do not run it. Hence, everything is ready for the Lagranto run, but it is not launched. It can be launched manually, possibly after some manual modifications to the run script, with the following steps: |
.B 1) change to run directory |
(for instance with "lagranto -open caseid.label"); |
.B 2) start the run script |
(with ./runscript.sh, where you have to pass the name of your runscript name). |
.SH INPUT FILES |
A sucessful Lagranto runs needs several input files; the following list shows all mandatory and optional input files |
.TP 10 |
.B P and S files [mandatory] |
input netCDF files; at least the following meteeorological fields must be available on the P files: U=zonal wind [m/s]; V=meridional wind [m/s]; OMEGA=vertical wind [Pa/s]; PS=surface pressure [hPa]. Secondary field can be made available on the S file. Both P and S files have the following format: [P|S]YYYYMMDD_HH, e.g. P20100101_00 for 1st January 2010, 00 UTC. |
.TP 10 |
.B tracevars [optional] |
tracing file where all meteorological fields are listed which should be traced along the trajectories. The tracing file is needed by the program |
.B create_startf |
and particularly |
.B trace |
(for further details about the format of the file, consider the documentation for these two commands). If no tracing of meteorological fields is needed, no tracing file must be specified. Furthermore, the name of the file can be changed from its default (tracevars) with the optional parameter "-v filename" (see above). |
.TP 10 |
.B regionf [optional] |
region specification for definition of strting positions (with |
.B create_startf |
) or application of Lagrangian selection criteria (with |
.B select |
). If no region is used in either "select" or "create_startf", no region file must be specified. The name of the region file can be changed from its default (regionf) with the option "-r filename". |
.TP 10 |
.B startf [optional] |
definition of the starting positions, either as an explicit list of longitude, latitude, pressure; or as a criterion saved on the file. If the specification of the starting positions is done with an explicit specification in |
.B create_startf |
(e.g. "point(50,40) @ list(100,200,300) @ hPa") no starting file is needed. |
.TP 10 |
.B select [optional] |
definition of a selection criterion for command |
.B select. |
If the selection criterion is given explicitely in the Lagranto call (e.g. GT:PV:2), no selection file is needed. |
.SH OUTPUT FILES AND STRUCTURE |
For a Lagranto run a new directory will be created where all needed files are prepared. The name of the directory and the file within it (if cleaning is invoked) are: |
.TP 10 |
.B ntr_${startdate}_{dir}${timerange}_{startf}_{select} |
for instance, the Lagranto call "lagranto local 20100101_00 20100102_00 startf selectf" will create the directory "ntr_19891020_00_f24_local_startf_selectf". Correspondingly, for a backward calculation the name would be "ntr_19891021_00_b24_local_startf_selectf", i.e. the {dir} is set to 'b'. |
.TP 10 |
.B ls_${startdate} |
default name of the output trajectory file placed in the ntr directory. The name can be changed with the option "-o filename". Note further that different output formats are supported, as described in the documentation for command |
.B reformat. |
.TP 10 |
.B runscript.sh |
name of the run script, i.e. the script within the ntr directory which calls all Fortran programs. It cn be manually started with "./runscript.sh". |
.TP 10 |
.B runscript.logfile |
name of the log file; all status information is written to this file. If a Lagranto run fails, this is the place where to start loking for the reason! |
.SH SPECIAL COMMANDS |
The main focus of |
.B lagranto |
is to combine the calls to "create_startf", "caltra", "trace" and "select" into one convenient call. In addition to this, "lagranto" offers some handy special commands which allow more efficient working. |
.TP 10 |
.B -open caseid.label |
open a new |
.B xterm |
window and change to the run directory. If several directories with the same case ID are found, the user is interactively asked to choose one. |
.TP 10 |
.B -remove caseid.label |
remove a run directory. If several directories with the same case ID are found, the user is interactively asked to choose one. |
.TP 10 |
.B -show caseid.label |
show the contents of the trajectory file as a list. If several directories with the same case ID are found, the user is interactively asked to choose one. |
.SH EXAMPLES |
.TP 5 |
.B [1] lagranto local 19891020_00 19891021_00 startf nil -changet |
a forward trajectory calculation from 00 UTC, 20 October 2010 to 00 UTC, 21 October 2010. The starting positions are taken from the file "startf". No selection criterion is applied (nil), and the times on the input netCDF files are set relative to the starting date in advance. |
.TP 5 |
.B [2] lagranto local 19891020_00 19891021_00 startf 'GT:PV:2:LAST' -changet |
as in example [1], but now an explicit selection criterion is applied (GT:PV:2:LAST) - the potential vorticity at the end date (19891021_00) must be larger than 2 PVU. |
.TP 5 |
.B [3] lagranto local 19891020_00 19891021_00 startf 'GT:PV:2:LAST' -changet -prep |
as in the previous two examples, but now only the files and runscript are prepared: no Lagranto run is launched! To do so, you might change to the run directory with |
.B lagranto -open local |
and then start it manually with |
.B ./runscript.sh. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/lagrantohelp.0 |
---|
0,0 → 1,80 |
.TH Lagrantohelp |
.SH NAME |
.B Lagranto - |
calculate trajectories for ECMWF analyses and forecasts |
.SH SYNOPSIS |
.B lagrantohelp [topic|tutorial|reference|future] - |
show this man page or the one corresponding to a specific topic. All |
.I |
underlined |
names in this document have their own man page. If "tutorial" is chosen, |
a detailed tutorial for Lagranto is opened. For "reference" a PDF document with all man pages is opened. Finally, with option "future" plans for additional features will be listed. |
.SH DESCRIPTION |
Lagranto is a software tool (UNIX shell-scripts and Fortran programs) to analyze |
Lagrangian aspects of atmospheric phenomena. It requires a time-series of |
3-dimensional wind fields (and if necessary further variables) on netCDF files. |
.SH CORE PROGRAMS |
.TP 15 |
.I create_startf |
create starting files |
.TP 15 |
.I caltra |
calculate trajectory positions |
.TP 15 |
.I trace |
trace meteorological fields along trajectories |
.TP 15 |
.I select |
select trajectories based on several criteria |
.TP 15 |
.I density |
create netCDF files with trajectory densities |
.SH TRAJECTORY TOOLS |
.TP 15 |
.I extract |
extract single trajectories, times or columns from a trajectory file |
.TP 15 |
.I list2lsl |
transform a (longitude,latitude,pressure) list into a trajectory file |
.TP 15 |
.I lsl2list |
transform a trajectory file into a (longitude,latitude,pressure) list |
.TP 15 |
.I mergetra |
merge two trajectory files |
.TP 15 |
.I reformat |
change the format of a trajectory file |
.TP 15 |
.I timeres |
change the time resolution of a trajectory file with interpolation |
.TP 15 |
.I trainfo |
write some information about a trajectory file |
.TP 15 |
.I difference |
calculate the difference between two trajectory files |
.SH NETCDF TOOLS |
.TP 15 |
.I changecst |
change the constants filename on a netCDF file |
.TP 15 |
.I changet |
change the time on a netCDF file |
.TP 15 |
.I getmima |
get the minimum and maximum value of a field on a netCDF file |
.TP 15 |
.I getvars |
get a list of fields on a netCDF file |
.SH GENERAL TOOLS |
.TP 15 |
.I newtime |
get a new date from an initial date and an offset in hours |
.TP 15 |
.I gettidiff |
get the time difference between two dates |
.SH VISUALISATION |
Lagranto comes with two packages for visualisation of trajectories: one based on Matlab (www.mathworks.com) and one based on NCL (www.ncl.ucar.edu). Examples are provided in folder "figure" of the Lagranto installation. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/lidar.0 |
---|
0,0 → 1,113 |
.TH trace |
.SH NAME |
.B lidar - lidar of meteorological fields along trajectories |
.SH SYNOPSIS |
.B trace |
.I inpfile |
.I outfile |
[ |
.I optional arguments |
] |
.SH DESCRIPTION |
Get pseudo-lidar of meteorological fields along the trajectories given in the input file |
.I inpfile |
and write the field to a netCDF file |
.I outfile. |
The horizontal axis in the netCDF file corresponds to the trajectory times, the vertical axis gives the pressure in hPa (by default, from 100 to 1000 hPa: it can be changet with optional argument '-pmin', '-pmax', '-centering'). By default, the pseudo lidar is taken at a fixed set of pressure levels between 100 and 1000 hPa. If the option '-centering' is selected, the pressure levels are relative to the trajectory position. |
The meteorological fields for the pseudo lidar are listed in a |
.I |
tracing file |
(default: tracevars). Note that the tracevars file has the same format as for |
.I trace |
but that all online calculations in the tracing file are neglected. |
.SH PARAMETERS |
.TP 15 |
.I inpfile |
input trajectory file; the appendix determines the format (see |
.B reformat |
for details). |
.TP 15 |
.I outfile |
output netCDF file for the pseudo-lidar fields. |
.SH OUTPUT FIELDS |
.TP 5 |
.B - [ FIELD_SUM | FIELD_MEAN ] |
Sum or mean of the lidar field FIELD, depending on the optional parameter '-sum' (default) or '-mean'. For instance, if potential temperature TH is passed as a lidar field, then TH_MEAN would contain the mean over all trajectories. The horizontal axis coincides with the times on the trajectory file; the vertical axis depends on the mode. By default, it goes from 100 hPa to 1000 hPa, within 100 steps. If '-centering' is passed as argument, the pressure levels are always relative to the trajectory position. |
.TP 5 |
.B - FIELD_CNT |
Number of values contributing to FIELD_SUM and FIELD_MEAN. This value is variable because the following cases do not contribute to the output field FIELD_SUM/MEAN: (a) if the position is outside the data domain of the input P files; (b) if the position falls below topography; (c) if the trajectory position is invalid; and (d) if the lidar field has a missing value flag set. |
.TP 5 |
.B - POSITION |
Position of all trajectories contributing to the lidar composite. By default, the vertical position of the trajectories between 100 hPA and 1000 hPa can be visualised in this way. If '-centering' is selected, the POSITION corresponds to a single line because then all pressure positions are relative to the trajectory height, i.e. a pressure of 0 hPa on tghe vertical axis corresponds to the trajectory position. |
.SH TRACING FILE |
Normally the meteorological fields for tracing are listed in a file with name |
.B "tracevars". |
The name of the tracing file can be changed with the optional argument "-v" (see below). The format of the tracing file is as follows: |
.br |
.TP 5 |
Format |
.I field |
.I scale |
.I computation |
.I prefix |
.TP 5 |
Examples |
.B - TH 1. 0 S : |
pseudo lidar of potential temperature (TH), scale it with 1 (no scaling); it is available on the S file (no computation is needed: 0). |
.br |
.B - Q 1000. 0 P : |
pseudo lidar of specific humidity (Q), scale it with 1000 to have g/kg; it is available on the P file (no computation is needed: 0). |
.SH OPTIONAL ARGUMENTS |
.TP 15 |
.TP 15 |
.I -i hours |
time increments (in hours) for input P and S files. If not explicitely specified, this is determined from the P and S files i |
n the current directory. |
.TP 15 |
.I -v varfile |
Change the name of the tracing file from its default value "tracevars" to "varfile". |
.TP 15 |
.I -f field scale |
Trace field (with scaling scale) along the trajectories; the computation flag and the prefix for the data file is automatically set. This options allows the quick tracing of a field, without specifying a tracing file. |
.TP 15 |
.I -changet |
flag whether the times of the P and S files should be changed or not before a calculation; the default is that the |
times are |
.B not |
changed. |
.TP 15 |
.I -noclean |
flag whether parameter and criterion files should be kept; this is particularly helpful for debugging. |
.TP 15 |
.I -timecheck |
enforce a time check on the data files |
.TP 15 |
.I -nearest |
Do no interpolation between grid points; just take the nearest neighbor! This option is useful, if a discrete input field is given (e.g. labels), where interpolated values are meaningless. |
.TP 15 |
.I [-sum|-mean] |
If '-sum' (the default) is chosen and several trajectories are on the input file, then the sum of all pseudo lidar fields is written to the output file; otherwise, for '-mean', the mean of all pseudo lidar fields is written. |
.TP 15 |
.I -pmin value |
Set the lower pressure limit for the pseudo lidar. Default is 100 hPa. |
.TP 15 |
.I -pmax value |
Set the upper pressure limit for the pseudo lidar. Default is 1000 hPa. |
.TP 15 |
.I -npre value |
Set the number of pressure levels between 'pmin' and 'pmax. Default is 100. |
.TP 15 |
.I -centering |
Select the pressure levels relative to the trajectory position; by default the pressure levels are given as absolute heights between 100 and 1000 hPa. If '-centering' is chosen and no explicit limits are specified with 'pmin' and 'pmax', the limits are set to pmin=-500 hPa and pmax=500 hPa. |
.SH EXAMPLES |
.TP 5 |
.B [1] lidar TRAJECTORY.1 LIDAR |
Read the trajectory file TRAJECTORY.1 and get a composite pseudo-lidar from 100 to 1000 hPa along the the trajectories. If there are several trajectories on TRAJECTORY.1, the sum is written to the netCDF file LIDAR. The fields of which a pseudo lidar is calculated are listed in the file 'tracevars'. |
.TP 5 |
.B [2] lidar TRAJECTORY.1 LIDAR -pmin 200 -pmax 500 |
As in [1], but the upper and lower limits of the pseudo lidar are set to 200 and 500 hPa. |
.TP 5 |
.B [2] lidar TRAJECTORY.1 LIDAR -centering |
As in [1], but the lidar pressure levels are not fixed: They are taken relative to the trajectory height. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (April 2012). |
/tags/1.0/docu/man/list2lsl.0 |
---|
0,0 → 1,30 |
.TH list2lsl |
.SH NAME |
.B list2lsl - convert a list of longitude, latitude and pressure into a trajectory file. |
.SH SYNOPSIS |
.B list2lsl |
.I inpfile |
.I outfile |
.I [ optional arguments ] |
.SH DESCRIPTION |
Convert an input file "inpfile" wqith a list of longitude, latitude and pressure into a trajectory file. |
.SH PARAMETERS |
.TP 15 |
.I inpfile |
input file (a list of longitude, latitude and pressure) |
.TP 15 |
.I outfile |
output trajectory file |
.SH OPTIONAL PARAMETERS |
.TP 5 |
.B -ref refdate |
set the reference date of the trajectory file to "refdate", e.g. "-ref 20110102_00". |
.TP 5 |
.B -time value |
set the time of the trajectory file to "value" (in format HH.MM): e.g. "-time 6" sets the time to 6 h. |
.SH EXAMPLES |
.TP 5 |
.B [1] list2lsl listfile trafile -refdate 20110101_00 -time 6 |
converts the list "listfile" into a trajectory file "trafile", where the reference date is 20110101_00 and the time is 6 h. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/lsl2list.0 |
---|
0,0 → 1,22 |
.TH lsl2list |
.SH NAME |
.B lsl2list - convert a trajectory file into a list of longitude, latituden and pressure |
.SH SYNOPSIS |
.B lsl2list |
.I inpfile |
.I outfile |
.SH DESCRIPTION |
Convert an input trajectory file "inpfile" into a list of longitude, latitude and pressure; all times are included in this list. |
.SH PARAMETERS |
.TP 15 |
.I inpfile |
input trajectory file |
.TP 15 |
.I outfile |
output file (a list of longitude, latitude and pressure) |
.SH EXAMPLES |
.TP 5 |
.B lsl2list trafile listfile |
converts all entries of the trajectory file "trafile" into a listfile with longitude, latitude and pressure. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/mergetra.0 |
---|
0,0 → 1,38 |
.TH mergetra |
.SH NAME |
.B mergetra - |
combine two trajectory files |
.SH SYNOPSIS |
.B mergetra |
.I inpfile1 |
.I inpfile2 |
.I outfile |
.SH DESCRIPTION |
Combines two input trajectory files "inpfile1" and "inpfile2" and writes a new combined trajectory file "outfile". Three different modes for combination are supported (see below). |
.SH PARAMETERS |
.TP 15 |
.I inpfile1 |
first input trajectory file |
.TP 15 |
.I inpfile2 |
second input trajectory file |
.TP 15 |
.I outfile |
output trajectory file |
.SH MODES FOR COMBINATION |
Three different combination modes are supported. They are tested for sequentially and the first mode which is accepted, based on the criteria listed below, is performed. The three modes are: |
.TP 5 |
.B - column |
The input files have the same trajectory times, longitudes, latitudes and pressures, and both files contain the same number of trajectories. The new trajectory file contains all columns from both input files, duplicate columns only included once, e.g. if "inpfile1" has columns "time,lon,lat,p,TH,PV" and "inpfile2" columns "time,lon,lat,p,PV,Q", the output file will have "time,lon,lat,p,TH,PV,Q". |
.TP 5 |
.B - append |
The input files have the same trajectory times and the same columns, but differ in the number of trajectories. Then the second file is appended to the first one and written as a new trajectory file. |
.TP 5 |
.B - times |
The input files differ only in the time values, e.g. the first file might contain times -96 h to 0 h and the second the times from 0 h to 96 hours. Then the new combined file will contain the time -96 h to 96 h. Note that duplicate times are eliminated. Furthermore, the output times are sorted in increasing order. |
.SH EXAMPLES |
.TP 5 |
.B [1] mergetra file1 file2 newfile |
combines the two trajectory files "file1" and "file2" and writes a new trajectory file; the mode for combination is automatically detected. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/newtime.0 |
---|
0,0 → 1,24 |
.TH newtime |
.SH NAME |
.B newtime - |
get a new date string from an initial date and an offset in hours |
.SH SYNOPSIS |
.B newtime |
.I date |
.I offset |
.SH DESCRIPTION |
Given an initial date string in format "YYYYMMDD_HH" and an offset in hours, create a new date string - agin in the form "YYYYMMDD_HH". |
.SH PARAMETERS |
.TP 15 |
.I date |
initial date in form "YYYYMMDD_HH", e.g. 20110102_18 for 18 UTC, 2nd January 2011. |
.TP 15 |
.I offset |
Offset in hours; the offset can be positive (into the future) or negative (into the past). |
.SH EXAMPLES |
.TP 5 |
.B [1] newtime 20110101_00 45 |
gives 20110102_21, the datestring 45 h after 20110101_00. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/reformat.0 |
---|
0,0 → 1,42 |
.TH reformat |
.SH NAME |
.B reformat - convert trajectory files between different formats |
.SH SYNOPSIS |
.B reformat |
.I inpfile |
.I outfile |
.SH DESCRIPTION |
Convert a Lagranto trajectory file |
.I inpfile |
from one format to another format; the new file is written to |
.I outfile. |
The formats are specified with an appendix to the filename, e.g. "trajectory.1" specifies format 1. If no appendix is given, format 1 is chosen. |
.SH PARAMETERS |
.TP 15 |
.I inpfile |
input trajectory file |
.TP 15 |
.I outfile |
output trajectory file (can be the same as inpfile). |
.SH FORMATS |
Formats must be specified with an appendix to the filename. If no appendix is given, format 1 is chosen. |
.TP 5 |
.B .1 |
ASCII file; the trajectories are sorted according to their starting positions. Different trajectories are separated by a blank line. This format is the only one supported |
by the Matlab and NCL visualisation scripts (see |
.B lagrantohelp/visualisation). |
.TP 5 |
.B .2 |
ASCII file; the trajectories are sorted according to their times. Different times are separated with a blank line. |
.TP 5 |
.B .3 |
unformatted Fortran; this is the most efficient format, but least portable one. |
.TP 5 |
.B .4 |
netCDF; portable and compact data format. |
.SH EXAMPLES |
.TP 5 |
.B [1] reformat trainp.1 trainp.4 |
Convert the input trajectory file in format 1 (ASCII) to format 4 (netCDF). |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/select.0 |
---|
0,0 → 1,289 |
.TH select |
.SH NAME |
.B select - |
select trajectories |
.SH SYNOPSIS |
.B select |
.I inptra |
.I outtra |
.I criterion |
.SH DESCRIPTION |
Select trajectories from the input trajectories in "inptra" based upon meteorological conditions specified in "criterion" (to be described below). The selected trajectories are then written to a new trajectory file "outtra". |
.SH PARAMETERS |
.TP 15 |
.I inptra |
input trajectory file |
.TP 15 |
.I outtra |
output trajectory file |
.TP 15 |
.I criterion |
specification of the selection criterion; the specification is either an explicit criterion or a file containing the specification. Each selection criterion has the following form: |
.br |
.B COMMAND |
: |
.B FIELD |
: |
.B ARGUMENTS |
: |
.B [ TIME ]. |
.br |
Several selection criteria can be combined with logical operator & (AND) and | (OR), the AND having higher priority than the OR. |
.SH OPTIONAL ARGUMENTS |
.TP 5 |
.I -noclean |
keep temporary files for debugging. |
.TP 5 |
.I -boolean |
Write a boolean list (0/1) instead of a trajectory file; the file has #trajectories entries, each line corresponding to an input trajectory /1=trajectory selected, 0=not selected). |
.TP 5 |
.I -index |
Write an index list instead of a trajectory file: the index of all selected trajectories is written to the output file - the index ranges from 1 to #trajectories. |
.TP 5 |
.I -count |
Write only the number of selected trajectories to the output file. |
.TP 5 |
.I -startf |
Write only the starting positions of selected trajectories to the output file. |
.TP 5 |
.I -regionf filename |
change the region file from its default value "regionf" to a new file name: the syntax is "-regionf filename". |
.SH COMMAND |
.TP 5 |
.B - GT |
greater than: e.g. |
.B GT:PV:2 |
selects trajectories with first potential vorticity (PV) larger than 2 PVU. |
.TP 5 |
.B - LT |
less than: e.g. |
.B LT:RH:70 |
selects trajectories with first relative humidity (RH) below 70 %. |
.TP 5 |
.B - IN |
within: e.g. |
.B IN:lon:30,40 |
selects trajectories with first longitude between 30 and 40 deg. |
.TP 5 |
.B - OUT |
outside: e.g. |
.B OUT:lat:-30,30 |
selects trajectories with first latitude outside -30 and 30 deg - neglecting an equatoriual/subtropical band. |
.TP 5 |
.B - EQ |
equal: e.g. |
.B EQ:p:460 |
selects trajectories with first pressure equal to 460 hPa. |
.TP 5 |
.B - TRUE |
check whether value is different from zero (logical TRUE): e.g. |
.B TRUE:CYCL::ALL(ANY) |
checks whether the trajectory passes through a cycclone, which is marked as 0/1 field, at any time. Note that the command 'TRUE' has no arguments of its own! |
.TP 5 |
.B - FALSE |
check whether value is equal to zero (logical FALSE): e.g. |
.B FALSE:CYCL::ALL(ALL) |
checks whether the trajectory never passes through a cycclone, which is marked as 0/1 field. Note that the command 'TRUE' has no arguments of its own! |
.TP 5 |
.B - ALL, ANY, NONE |
these are special commands which only apply for the TRIGGER field. Further explanations are given below in section TRIGGER. |
.SH FIELD |
.TP 5 |
.B - VALUE |
take value of the field: e.g. |
.B GT:PV(VALUE):2 |
selects the trajectories with first potential vorticity (PV) value greater than 2 PVU. This selection criterion is equivalent to |
.B GT:PV:2, |
i.e. the VALUE argument is taken as default. |
.TP 5 |
.B - MEAN |
take the mean over the selected times: e.g. |
.B GT:RH(MEAN):70:ALL |
selects all trajectories for which the mean relative humidity (RH) over all times (ALL) is greater than 70 %. |
.TP 5 |
.B - VAR |
take the variance over the selected times: e.g. |
.B GT:lat(VAR):10:ALL |
selects all trajectories for which the variance of latitude (lat) over all times (ALL) is greater than 10. |
.TP 5 |
.B - MIN |
take the minimum of the selected times: e.g. |
.B LT:p(MIN):300:ALL |
select all trajectories which have a minium pressure (p) less than 300 hPa over all times (ALL). |
.TP 5 |
.B - MAX |
take the maximum of the selected times: e.g. |
.B LT:p(MAX):300:ALL |
select all trajectories which have a maximum pressure (p) less than 300 hPa over all times (ALL). |
.TP 5 |
.B - SUM |
take the sum over the selected times: e.g. |
.B GT:LHR(SUM):2:ALL |
selects all trajectories for which the sum over all latent heating rates (LHR) over all times (ALL) is greater than 2 K. |
.TP 5 |
.B - CHANGE |
take change between two times: e.g. |
.B GT:p(CHANGE):600:FIRST,LAST |
selects all trajectories wich have a pressure difference |p(FIRST)-p(LAST)| greater than 600 hPa between the first and last time or vice versa. Note that the change can be positive or negative, i.e. it is not clear whether it is ascent or descent. |
.TP 5 |
.B - DIFF |
take difference between two times: e.g. |
.B GT:p(DIFF):600:FIRST,LAST |
selects all trajectories wich have a pressure difference p(FIRST)-p(LAST) greater than 600 hPa between the first and last time - corresponding to an ascending air stream. Correspondingly |
.B GT:p(DIFF):600:LAST,FIRST |
finds a descending air stream. |
.SH TIME MODE |
The command are applied to a set of trajectory times; if no time is specified, the the command is only applied to the first time. Most generally, the time mode consists of two parts: time list( time mode), where the first specifies a list of times and the second how to apply the criterion to the selected times. |
.TP 5 |
.B - FIRST |
first time: e.g. |
.B IN:lat:-20,20:FIRST |
selects all trajectories with first latitude between 20 S to 20 N, i.e. wich start in an equatorial band. |
.TP 5 |
.B - LAST |
last time: e.g. |
.B IN:lat:-20,20:LAST |
selects all trajectories with last latitude between 20 S to 20 N, i.e. which end in an equatorial band. |
.TP 5 |
.B - T1,T2,T3 |
an explict list of times: e.g. |
.B IN:lat:-20,20:6,12 |
selects all trajectories which are in the equatorial band at times 6 h and 12 h. The criterion must apply at both times (see below ALL, ANY, NONE). |
.TP 5 |
.B - T1 to T2 |
a time range: e.g. |
.B IN:lat:-20,20:6 to 18 |
selects all trajectories which are in the equatorial band from 6 h to 18 h. The criterion must apply at all times between 6 h and 18 h (see below ALL, ANY, NONE). |
.TP 5 |
.B - ALL |
all times: e.g. |
.B IN:lat:-20,20:ALL |
selects all trajectories which stay at all times in the equatorial band. This time mode is the same as |
.B ALL(ALL), |
i.e. all times are selected and the criterion must apply to all times. With |
.B IN:lat:-20,20:12-24(ALL) |
the criterion must apply for all times between 12 h and 24 h. |
.TP 5 |
.B - ANY |
any times: e.g. |
.B IN:lat:-20,20:ALL(ANY) |
selects all trajectories which stay at any times in the equatorial band. Note that with the first "ALL" the times are selected, i.e. all times in this case, and with the second "ANY" it is specified that the criterion must only apply to at least one of the selected times. |
.TP 5 |
.B - NONE |
at no time: e.g. |
.B IN:lat:-20,20:ALL(NONE) |
selects all trajectories which never stay in the equatorial band. |
.B OUT:lat:-20,20:FIRST(NONE) |
selects the trajectories which are not outside the equatorial time at the first time: they must be inside. |
.TP 5 |
.B - TRIGGER |
the trajectory is automatically selected, but the trigger column is updated. A selection of trajectories might then e accomplished based on this trigger column: e.g |
.B GT:p:700:1(TRIGGER) |
would set the trigger 1 for all trajectory times where the pressure (p) is greater than 700 hPa. Similarly, |
.B GT:p:800:1(TRIGGER) & GT:lat:50:2(TRIGGER) |
would set the trigger 1 for all times where the pressure (p) is larger than 800 hPa and set the trigger 2 for all times where the latitude (lat) is larger than 50 degrees north. Note, that both eents might apply: then the rsulting trigger is 3. The triggers are internally saved as the bits of an integer variable, i.e. trigger 1 corresponds to value 1=2^0, trigger 2 to 2=2^1, trigger 3 to 4=2^2... |
.SH LOGICAL OPERATORS |
.TP 5 |
.B - & |
logical and: e.g. |
.B GT:lat:34:FIRST & GT:lon:50:FIRST |
selects the trajectories to the north of 34 N and to the east of 50 E at first time. Several selection criteria can be combined with '&'. |
.TP 5 |
.B - | |
logical or: e.g. |
.B GT:lat:34:FIRST | GT:lon:50:FIRST |
selects the trajectories to the north of 34 N or to the east of 50 E at first time. Several selection criteria can be combined with '|'. Note that locical OR has a lower priority than logical AND, i.e. in an expression like T1 | T2 & T3 first the expression T2 & T3 is evaluated and only then logically OR-combined with T1. |
.SH IMPLICIT FIELDS |
Implicit variables can be used in the selection criteria, although they do not explicitely appear as a column in the trajectory file. They are calculated on-the-fly during the selection. |
.TP 5 |
.B - DIST |
length of the trajectory (in km), integrated along great circle sections between the trajectory vertices: e.g. |
.B GT:DIST:1000:LAST |
tests whether the total path length of the trajectory (DIST) exceeds 1000 km. |
.TP 5 |
.B - DIST0 |
distance of the trajectory (in km) from its starting position: e.g. |
.B GT:DIST0:1000:18,24(ANY) |
tests whether the air parcel is more than 1000 km away from its starting position, either at time 18 h or at time 24 h. |
.TP 5 |
.B - INPOLYGON |
specification of a polygon: e.g. |
.B TRUE:INPOLYGON:filename:ALL(ANY) |
selects all trajectories which pass through the polygon specified in "filename". The polygon is specified as described in |
.B create_startf |
(see comments there). With |
.B FALSE:INPOLYGON:filename:ALL(ALL) |
all trajectories are selected which never pass through the polygon. Note that for every call of |
.B select |
only one polygon can be used in the criteria! |
.TP 5 |
.B - INBOX |
specification of a longitude/latitude rectangle <lonw,lone,lats,latn>: e.g. |
.B TRUE:INBOX:20,40,30,60:ALL(ANY) |
selects all trajectories which pass through the longitude/latitude rectangle with lower-left corner at 20 E / 30 N and the upper-right corner at 40 E / 60 N. Correspondingly, with |
.B TRUE:INBOX:20,40,30,60:ALL(NONE) |
the trajectories are selected which never pass through the rectangle. |
.TP 5 |
.B - INCIRCLE |
specification of circle around a specified point: e.g. |
.B TRUE:INCIRCLE:40,50,500:LAST |
select all trajectories which have their final position (LAST) in the circle centred at 40 E / 50 N and with a radius of 500 km. |
.TP 5 |
.B - INREGION |
specification of target regions in a region file (default "regionf") - please consider the documentation of "create_startf" for details concerning the format of the region file. As an example, if a region 1 is defined on the region file, the criterion |
.B TRUE:INREGION:1:18 |
selects all trejactories which are within region 1 at time 18 h. |
.SH SPECIAL CRITERIA |
Special criteria are and can be implemented into |
.B select. |
The call to the special criteria is of the following form: |
.B SPECIAL:command:parameters, |
where "command" is a command string (e.g. WCB) and "parameters" is a list of parameter values. |
.TP 5 |
.B - WCB |
identification of Warm Conveyor Belts (WCB): e.g. |
.B SPECIAL:WCB:300,0,24 |
selects trajectories which ascend more than 300 hPa between time 0 and 24 h. Note, the ascent is determined as min{p(0...24)}-p(0), i.e. the first pressure p(0) is fixed whereas the lowest pressure can occur at any time between 0...24 h. |
.SH TRIGGER FIELD |
A trigger (or flag) field can be defined in select. This special column of the trajectory file allows to mark specified events for each trajectory and its times. As an example, you would like to select all trajectories which are below 700 hPa at a certain time and have relative humidity above 80 % |
.B at the same times: |
Then you could set a first trigger for the pressure criterion and a second one for the relative humidity, and then you would check for the simultaneous occurence of the two triggers. More specifically, |
.TP 5 |
.B GT:p:700:1(TRIGGER) & GT:RH:80:2(TRIGGER) |
this will define the triggers for the two events. Note that both events might be fulfilled, in which case both triggers are set. The value of the trigger is: 1 if only the first criterion is fulfilled (binary 01); 2 if only the second is fulfilled (binary 10) and 3 if both are fulfilled (binary 11). |
.TP 5 |
.B ALL:TRIGGER:1,2:ALL(ANY) |
this will select all trajectories for which both triggers 1 and 2 are set - they can be set at any time of all the trajectory times; if, for instance, you would like to test whether the two triggers are set at the two times 6 and 12, the command would be |
.B ALL:TRIGGER:1,2:6,12(ALL). |
.TP 5 |
.B ALL:TRIGGER:1,2:ALL(ANY) |
will only check whether one of the two triggers 1 and 2 is set |
.TP 5 |
.B NONE:TRIGGER:1,2:ALL(ANY) |
will check whether none of the two triggers 1 and 2 is set |
.SH IMPLEMENTING COMPLEX CRITERIA |
New special criteria can easily be implemented into the code - to this aim the following steps must be taken: |
.TP 5 |
.B [1] <special.f> |
in directory "${LAGRANTO}/select/" must be modified. Take the example "WCB" to see how the Fortran code must be changed. |
.TP 5 |
.B [2] <install.sh select> |
must be invoked to recompile the program "select". For successful compilation, the executable "select" will be listed. |
.TP 0 |
Type <select -special> to get a list of all special commands and a detailed description. |
.SH EXAMPLES |
.TP 5 |
.B [1] select trainp traout 'GT:PV:2:LAST' |
selects all trajectories with PV>2 PVU for the last time step. The input trajectories are given in trainp, the selected ones are written to traout. If the two filenames are the same, the input file is overwritten. |
.TP 5 |
.B [2] select trainp traout 'IN:lat:-20,20:6,12' |
selects all trajectories which are in the equatorial band at times 6 h and 12 h. The criterion must apply at both times. |
.TP 5 |
.B [3] select trainp traout 'GT:lat:34:FIRST & GT:lon:50:FIRST' |
selects the trajectories to the north of 34 N and to the east of 50 E at first |
time. Several selection criteria can be combined with '&'. |
.TP 5 |
.B [4] select trainp traout 'LT:p(MIN):300:ALL' |
select all trajectories which have a minium pressure (p) less than 300 hPa over all times (ALL). |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/startf.0 |
---|
0,0 → 1,195 |
.TH create_startf |
.SH NAME |
.B create_startf - |
create starting files for Lagranto |
.SH SYNOPSIS |
.B create_startf |
.I date |
.I filename |
.I specifier |
[ |
.I optional arguments |
] |
.SH DESCRIPTION |
Create starting files |
for a Lagranto calculation. The staring positions are based on the P and S files for |
.I date |
and are as specified in a |
.I specifier. |
The starting coordinates (longitude, latitude, pressure [in hPa]) are written to the file |
.I filename. |
.SH PARAMETERS |
.TP 15 |
.I date |
date of input P and S file (e.g. 20100101_00). If the date is between two P and S files, |
linear interpolation is used between the two times. |
.TP 15 |
.I filename |
output file with starting points (e.g. startf). Different formats are supported (see |
.B reformat |
for details) |
.TP 15 |
.I specifier |
detailed description of starting positions. The specifier has the following format: |
.B |
.I <horizontal> |
@ |
.I <vertical> |
@ |
.I |
<unit> |
@ |
.I <selection>. |
The components of the specifier are described in greater detail in the following sections. |
.SH HORIZONTAL |
.TP 15 |
.B - file[filename] |
read lat/lon from file "filename"; each line contains one lat/lon pair. |
.TP 15 |
.B - line[lon1,lon2,lat1,lat2,n] |
n points from (lon1,la1) to (lon2,lat2); the points are linearly interpolated in lat/lon space. |
.TP 15 |
.B - box.eqd[lon1,lon2,lat1,lat2,ds] |
lat/lon box bounded with south-western point (lon1,lat1) and north-eastern point (lon2,lat2); the equdistant points within the box have a horizontal distance ds (in [km]). |
.TP 15 |
.B - box.grid[lon1,lon2,lat1,lat2,] |
lat/lon box with south-western point (lon1,lat1) and north-eastern point (lon2,lat2 grid points; all grid points within this box are taken as staring points. |
.TP 15 |
.B - point[lon,lat] |
single lon/lat point. |
.TP 15 |
.B - shift[lon,lat,dlon,dlat] |
lon/at points and dlon/dlat shifhted ones, i.e. in total five points: central one and four shifted ones: (lon,lat), (lon+dlon,lat), (lon-dlon,lat), (lon,lat+dlat), (lon,lat-dlat). |
.TP 15 |
.B - polygon.eqd[filename,ds] |
equidistant within arbirtrary polygon (ds in [km]). The file with the polygon points has the following format: 1st line a lon/lat point within the polygon; further lines lon/lat points of the vertices (max 500) of the polygon. |
.TP 15 |
.B - polygon.grid[filename] |
grid points within arbirtrary polygon. The file with the polygon points has the following format: 1st line a lon/lat point within the polygon; further lines lon/lat points of the vertices (max 500) of the polygon. |
.TP 15 |
.B - circle.eqd[lonc,latc,radius,ds] |
circle with centre at (lonc,latc) and radius "radius" (in km); the equdistant points within the circle have a horizontal distance ds (in [km]). |
.TP 15 |
.B - circle.grid[lonc,latc,radius] |
circle with centre at (lonc,latc) and radius "radius" (in km); all rid points within the circle are selected. |
.TP 15 |
.B - region.eqd[id,ds] |
Read region specification from region file ("default regionf", to be changed with option "-regionf") and fill it equidistantly with starting points (ds in km). The region identification is "id", see below in section REGION FILE. |
.TP 15 |
.B - region.grid[id] |
Read region specification from region file ("default regionf", to be changed with option "-regionf") and fill it with starting points on the input grid. The region identification is "id", see below in section REGION FILE. |
.SH VERTICAL |
.TP 15 |
.B - file[filename] |
read levels from file "filename"; each line in the file contains one level. |
.TP 15 |
.B - level[lev] |
a single level |
.TP 15 |
.B - list[lev1,lev2,lev3,...] |
a list of levels; if many levels are needed they are better passed to "create_startf" with the option "file[filename]". |
.TP 15 |
.B - profile[lev1,lev2,n] |
n equdistant levels between lev1 and lev2. |
.TP 15 |
.B - grid[lev1,lev2] |
all grid points within layer (lev1,lev2) are selected |
.SH UNIT |
.TP 15 |
.B - hPa |
pressure (in hPa). |
.TP 15 |
.B - hPa,agl |
pressure (in hPa) above ground level. |
.TP 15 |
.B - K |
potential temperature (in K). |
.TP 15 |
.B - PVU |
potential vorticty (in PVU). Note that potential vorticity (PV) might not be unique as a vertical coordinate; if several levels have a given PV value, the highest one is chosen. |
.TP 15 |
.B - INDEX |
index of model level (1=surface). |
.SH SELECTION |
.TP 15 |
.B - criterion |
Selection criteria based on meteorological fields applied to the starting position; The criteria follow the syntax of the program |
.B select. |
.TP 15 |
.B - nil |
If no selection criteria should be invoked, the argument "nil" should be given. |
.SH REGION FILE |
Several starting regions can be defined for every case in a region file (default filename is "regionf"; to be changed with optional parameter "-regionf filename"). There are two possible formats for specifying a region (they require either a line with 5 or 9 entries): |
.TP 5 |
.B "regnum lonw lone lats latn" |
a regular latitude-longitude square: regnum=integer region number; lonw=westernmost longitude of starting region; lone=easternmost longitude; lats=southernmost latitude; latnNorthernmost latitude. |
.TP 5 |
.B "regnum lon1 lat1 lon2 lat2 lon3 lat3 lon4 lat4" |
an irregular latitude-longitude square: regnum=integer region number; lon{x},lat{x} = longitude and latitude of the x-th corner. Note that the 4 corners must be arranged counterclockwise. For a triangle the 4th corner can be specified identically to the 3rd. |
.TP 5 |
.B Note: (1) if a line starts with '#' it is regarded as comment and not further considered; (2) each line in the region file must start with '"! |
.TP 5 |
.B "101 -40. -24. 52. 60.": |
region in the central Atlantic from 40 W to 24 W and 52 N to 60 N; the region identifier is 101. |
.TP 5 |
.B "250 -30. 43. -24. 36. -18. 50.2 -35.2 50.2": |
irregular square in the central Atlantic; the region identifier is 250. |
.SH OPTIONAL |
.br |
.TP 15 |
.I -t tracefile |
tracing file with variables for selection criteria (see |
.B trace |
for format of the file). If no file is specified, the default |
"tracevars" is used. Further, if no selection criterion is invoked, no |
tracing file is necessary. |
.TP 15 |
.I -changet |
flag whether the times of the P and S files should be changed or not before a calculation; the default is that the |
times are not changed. |
.TP 15 |
.I -noclean |
flag whether parameter and criterion files should be kept; this is particularly helpfuld for debugging. |
.TP 15 |
.I -regionf filename |
change the region file from its default value "regionf" to a new file name: the syntax is "-regionf filename". |
.TP 15 |
.I -timecheck |
enforce a time check on the data files |
.SH EXAMPLES |
.TP 5 |
.B [1] create_startf 19891020_00 startf 'point(-10,50) @ list(450,500,550) @ hPa' |
Starting points are (longitude, latitude, pressure in hPa): (-10,50,450); (-10,50,500); (-10,50,550). No selection criterion is applied; the positions are written to file "startf". |
.TP 5 |
.B [2] create_startf 19891020_00 startf 'line(-10,-5,40,50,10) @ level(450) @ hPa,agl' |
10 points are equidistantly specified between lon/lat point (-10,40) and (-5,50); all trajectories start at 450 hPa above ground level - the surface pressure is taken from the primary file P19891020_00. The positions are saved in "startf". |
.TP 5 |
.B [3] create_startf 19891020_00 startf 'box.grid(-10,-5,40,50) @ list(300,320) @ K' |
All grid points in the box with the south-eastern lon/lat point (-10,40) and the north-eastern one (-5,50) are taken - the horizontal grid spacing is specfified in the primary file P19891020_00. In the vertical, two isentropic levels are chosen: 300 K and 320 K. The potential temperature for the calculation is taken from the secondary file S19891020_00. |
.TP 5 |
.B [4] create_startf 19891020_00 startf 'shift(-10,40,1,1) @ profile(1000,200,100) @ hPa' |
A profile of 100 equidistant levels between 1000 hPa and 200 hPa; in the horizontal the central lon/lat point (-10,40) is taken and four horizontally displaced ones, the diplacement being 1 degree in zonal and meridional direction. |
.TP 5 |
.B [5] create_startf 19891020_00 startf.1 'shift(-10,40,1,1) @ profile(1000,200,100) @ hPa' |
As in the previous example [4], but the starting positions are saved as a trajectory file instead of a (lon,lat,p)-list. |
.TP 5 |
.B [6] create_startf 19891020_00 startf.1 criterion |
As in the previous example [5], but the criterion is saved on a file with filename "criterion". |
.TP 5 |
.B [7] create_startf 19891020_00 startf 'polygon.grid(polygon) @ level(500) @ hPa |
A polygon is specified in the file "polygon"; the different lines in the file are: -5. 45. / -10. 40. / 10. 40. / 10 50. / -10. 45. The first lon/lat point lies within the polygon, all other lon/lat points are the vertices of the polygon. All grid points within the polygon are taken as starting point, at level 500 hPa. |
.TP 5 |
.B [8] create_startf 19891020_00 startf 'polygon.eqd(polygon,50) @ level(500) @ hPa |
As in the previous example [7], except that the starting points are distributed equidistantly within the polygon. The horizontal distance between the starting points is 50 km in zonal and meridional direction. |
.TP 5 |
.B [9] create_startf 19891020_00 startf 'shift(-10,40,1,1) @ profile(1000,200,100) @ hPa @ GT:TH:310' |
As in example [4], but a selection criterion is additionally applied: only starting positions with potential temperature (TH) greater than (GT) 310 K are kept. Potential temperature must be available on the secondary file S19891020_00 and the file "tracevars" must have a line with "TH 1. 0 S". Further examples for selection criteria can be seen in |
.B |
select. |
.TP 5 |
.B [10] create_startf 19891020_00 START.1 'region.eqd(3,10) @ level(500) @ hPa' |
get equidistant starting points (10 km distance) in the region with identifier 3, as listed in the region file "regionf" (the default). |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/man/timeres.0 |
---|
0,0 → 1,36 |
.TH timeres |
.SH NAME |
.B timeres - change the time resolution of a trajectory |
.SH SYNOPSIS |
.B timeres |
.I inpfile |
.I outfile |
.I -[h|min] value |
.I [-cubic|-linear] |
.SH DESCRIPTION |
Change the time resolution of an input trajectory file "inpfile" through interpolation and write a new trajectory file "outfile". The new time resolution "value" is given either in hours "-h" or in minutes "-min". The interpolation is performed on the trajectory file either in linear mode ("-linear") or in cubic spline mode ("-cubic"). The default is "-cubic". |
.SH PARAMETERS |
.TP 15 |
.I inpfile |
input trajectory file |
.TP 15 |
.I outfile |
output trajectory file (can be the same as inpfile). |
.TP 15 |
.I -h value |
new time resolution in hours (e.g. "-h 1"). |
.TP 15 |
.I -min value |
new time resolution in minutes (e.g. "-min 15"). |
.TP 15 |
.I -linear |
linear interpolation between two trajectory times; note that this mode conserves the sign between two trajectory times - possibly of important for specific humidity, relative humidity,... |
.TP 15 |
.I -linear |
subic spline interpolation between two trajectory times; note that this mode conserves can change the sign between two trajectory times! |
.SH EXAMPLES |
.TP 5 |
.B [1] timeres trafile trafile -min 15 -linear |
changes the time resolution to 15 minutes, using linear interpolation, and overwrites the old trajectory file. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011 |
/tags/1.0/docu/man/tracal.0 |
---|
0,0 → 1,34 |
.TH tracal |
.SH NAME |
.B tracal - simple calculations with trajectory files |
.SH SYNOPSIS |
.B tracal |
.I inpfile |
.I outfile |
.I expression |
.SH DESCRIPTION |
Simple calculation on the input trajectory file |
.I inpfile |
; the output is written to the output trajectory file |
.I outfile |
and the expression for the calculation is given in |
.I expression. |
.SH PARAMETERS |
.TP 15 |
.I inpfile |
input trajectory file |
.TP 15 |
.I outfile |
output trajectory file (can be the same as inpfile). |
.TP 15 |
.I expression |
arithmetic expression, e.g. 'DIFF=PS-p' to get difference between surface pressure (PS) and the pressure height of the trajectory (p). Note that the variable names must exactly match to the column names in the trajectory file. |
The mathematical expression can contain previously defined variables, numbers (e.g., 1.5 or 1.5e-6), arithmetic operators (+, -, *, /, ^), and a number of mathematical functions (sin, cos, tan, sqrt, exp, log, ln, abs, ang, real, imag, conjg, complex). The expression can also use nested levels of parentheses for grouping. There are two predefined variables that are available to the user — the constant pi=3.14159265358979 and the imaginary unit i. |
.SH EXAMPLES |
.TP 5 |
.B [1] tracal inp out 'agl=z-zb' |
caculates the difference between air parcel height (z) and surface height (zb). The result is saved in an new column (agl). |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (August 2012); the evaluation of the arithmetic expression is based on the string manipulation routines by 'Dr. George Benthien' (http://gbenthien.net/index.html). |
/tags/1.0/docu/man/trace.0 |
---|
0,0 → 1,193 |
.TH trace |
.SH NAME |
.B trace - trace meteorological fields along trajectories |
.SH SYNOPSIS |
.B trace |
.I inpfile |
.I outfile |
[ |
.I optional arguments |
] |
.SH DESCRIPTION |
Trace meteorological fields along the trajectories given in the input file |
.I inpfile |
and write a new trajectory file |
.I outfile |
. The meteorological fields to trace are listed in a |
.I |
tracing file |
(default: tracevars). Partly they can be computed "online" (see ONLINE CALCULATIONS below), normally they are availbale on the primary and secondary P and S files. |
.SH PARAMETERS |
.TP 15 |
.I inpfile |
input trajectory file; the appendix determines the format (see |
.B reformat |
for details). |
.TP 15 |
.I outfile |
output trajectory file; the appendix determines the format (see |
.B reformat |
for details). |
.SH TRACING FILE |
Normally the meteorological fields for tracing are listed in a file with name |
.B "tracevars". |
The name of the tracing file can be changed with the optional argument "-v" (see below). The format of the tracing file is as follows: |
.br |
.TP 5 |
Format |
.I field[:shift] |
.I scale |
.I computation |
.I prefix |
.TP 5 |
Shifts (optional) |
.B - field:+100km[lat] |
- get field at trajectory position + 100 km shifted to north. A shift to south is obtained with field:-100km[lat]. |
.br |
.B - field:+100km[lon] |
- get field at trajectory position + 100 km shifted to east. A shift to west is obtained with field:-100km[lon]. |
.br |
.B - field:+2[dlat] |
- get field at trajectory position + 2 grid spacings dlat shifted to north. A shift to south is obtained with field:-2[dlat]. |
.br |
.B - field:+2[dlon] |
- get field at trajectory position + 2 grid spacings dlon shifted to east. A shift to west is obtained with field:-2[dlon]. |
.br |
.B - field:+50hPa |
- get field at trajectory position + 50 hPa shifted in vertical. A shift to lower pressures is obtained with field:-50hPa. |
.br |
.B - field:+1dp |
- get field at trajectory position + 1 grid spacing DP shifted in vertical. A shift to lower pressures is obtained with field:-1dp. Note that DP is not fixed but varies with height. |
.br |
.B - field:+6h |
- get field at trajectory position, but 6 h in the future. Shifts to the past are poeeible with field:-6h. In addition to hours (h), the time shift can be specified in minutes (min). |
.TP 5 |
Examples |
.B - TH 1. 0 S : |
trace potential temperature (TH), scale it with 1 (no scaling); it is available on the S file (no computation is needed: 0). |
.br |
.B - Q 1000. 0 P : |
trace specific humidity (Q), scale it with 1000 to have g/kg; it is available on the P file (no computation is needed: 0). |
.br |
.B - RH 1. 1 * : |
trace relative humidity (RH), no scaling is needed (1.); relative humidity is not available on either P or S file and must be computed (1). |
.br |
.B - TH:100hPa 1. 0 S : |
As in the first example, but now the potential temperature is taken 100 hPa below the air parcel position. |
.SH OPTIONAL ARGUMENTS |
.TP 15 |
.TP 15 |
.I -i hours |
time increments (in hours) for input P and S files. If not explicitely specified, this is determined from the P and S files i |
n the current directory. |
.TP 15 |
.I -v varfile |
Change the name of the tracing file from its default value "tracevars" to "varfile". |
.TP 15 |
.I -f field scale |
Trace field (with scaling scale) along the trajectories; the computation flag and the prefix for the data file is automatically set. This options allows the quick tracing of a field, without specifying a tracing file. |
.TP 15 |
.I -changet |
flag whether the times of the P and S files should be changed or not before a calculation; the default is that the |
times are |
.B not |
changed. |
.TP 15 |
.I -noclean |
flag whether parameter and criterion files should be kept; this is particularly helpful for debugging. |
.TP 15 |
.I -timecheck |
enforce a time check for the data file |
.SH SPECIAL INTERPOLATION MODES |
.TP 15 |
.I -nearest |
Do no interpolation between grid points; just take the nearest neighbor! This option is useful, if a discrete input field is given (e.g. labels), where interpolated values are meaningless. |
.TP 15 |
.I -circle_avg radius |
calculate area-weighted average over all grid points within a circle of the specified radius [km]. e.g. -circle_avg 200; note that the tracing of fields within a circle is quite slow. |
.TP 15 |
.I -circle_max radius |
calculate maximum within a circle of a radius [km]. e.g. -circle_max 200 |
.TP 15 |
.I -circle_min radius |
calculate minimum within a circle of a radius [km]. e.g. -circle_min 200 |
.TP 15 |
.I -clustering |
special mode to trace strat/trop label; the labels are attributed according to the program (tropopause), which clusters the atmosphere into five distinct classes according to the definition of the tropopause: PV (2 PVU) and potential temperature (380 K). The clustering mode is a refined version of the nearest mode, where all surrounding eight grid points vote for the final value. |
.SH ONLINE CALCULATIONS |
If the computation flag in the tracing file is set to 1, a meteorological field is calculated based upon the already traced fields and/or based on the fields on the primary and secondary P and S files. The following fields are implemented for online calculations: |
.TP 5 |
.B - TH |
potential temperature (in K). |
.TP 5 |
.B - RHO |
density (in kg/m^-3). |
.TP 5 |
.B - RH |
relative humidity (in %). |
.TP 5 |
.B - THE |
equivalent-potential temperature (in K). |
.TP 5 |
.B - LHR |
latent heating rate (K per input time step, typically K/6h). |
.TP 5 |
.B - D[U,V,T,TH]DX |
horizontal derivative d[U,V,T,TH]/dx in west-east direction along pressure surfaces - zonal distance in m. U=zonal wind component (m/s), V=meridional wind component (m/s), T=temperature (deg C or K), TH=potential temperature (K). |
.TP 5 |
.B - D[U,V,T,TH]DY |
horizontal derivative d[U,V,T,TH]/dy in south-north direction along pressure surfaces -meridional distance in m. |
.TP 5 |
.B - D[U,V,T,TH]DP |
vertical derivative d[U,V,T,TH]/dp - pressure p in Pa. |
.TP 5 |
.B - NSQ |
squared Brunt-Vaisala frequence (in m^-2). |
.TP 5 |
.B - RELVORT |
relative vorticity (in s^-1) - RELVORT = DVDX - DUDY. |
.TP 5 |
.B - ABSVORT |
absolute vorticity (in s^-1) - ABSVORT = DVDX - DUDY + F, F being the Coriolis parameter. |
.TP 5 |
.B - DIV |
horizontal divergence of the velocity field (in s^-1) - DIV = DUDX + DVDY. |
.TP 5 |
.B - DEF |
horizontal deformation of the velocity field (in s^-1) - DEF = SQRT( ( DVDX + DUDY )^2 + (DUDX-DVDY)^2 ). |
.TP 5 |
.B - PV |
Ertel potential vorticity (in PVU) - PV = g * ( ABSVORT * DTHDP + DUDP * DTHDY - DVDP * DTHDX ). |
.TP 5 |
.B - RI |
Richardson number - RI = NSQ / (DUDP^2 + DVDP^2 ). |
.TP 5 |
.B - TI |
tubulence indicator according to Ellrod & Knapp - TI = DEF * SQRT( DUDP^2 + DVDP^2 ) * ( RHO * G). |
.TP 5 |
.B - DIR |
wind direction relative to zonal flow: (U,V)=(1,1) -> 45 deg; (U,V)=(1,-1) -> -45 deg; (U,V)=(-1,-1) -> -135 deg; (U,V)=(-1,1) -> 135 deg. A westerly flow has 0 deg, a southerly flow 90 deg, and a northerly one -90 deg. |
.TP 5 |
.B - DIST0 |
spherical distance (in km) from starting position. |
.TP 5 |
.B - DIST |
length of the trajectory (in km): integrated along great circle sections between the trajectory vertices. |
.TP 5 |
.B - HEAD |
heading of the trajectory: (DX,DY)=(1,1) -> 45 deg; (DX,DY)=(1,-1) -> -45 deg; (DX,DY)=(-1,-1) -> -135 deg; (DX,DY)=(-1,1) -> 135 deg. A path increment to east has heading of 0 deg; to the north 90 deg; to the south -90 deg; and to the west -180 deg. |
.SH EXAMPLES |
.TP 5 |
.B [1] trace TRAJECTORY.1 TRAJECTORY.1 -changet |
Read the trajectory file TRAJECTORY.1, trace all fields in the file "tracevars" along the trajectories and overwrite the existing trajectory file. In preparation, all times on the P and S files are changed prior to the tracing. |
.TP 5 |
.B [2] trace INPTRA.1 OUTTRA.1 -f PV 1. |
Trace PV (with scaling factor 1.) along the trajectories in trajectory file "INPTRA.1" and write a new trajectory file "OUTTRA.1". |
.TP 5 |
.B [3] trace INPTRA.1 OUTTRA.1 -f PV:-100HPA 1. |
As in example [2], but the PV is taken at a position 100 hPa higher (lower pressure) than the air parcel's position. |
.TP 5 |
.B [4] trace INPTRA.1 OUTTRA.1 -f DIST0 1. |
Get the spherical distance (in km) of the air parcel from its starting position. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011). |
/tags/1.0/docu/man/trainfo.0 |
---|
0,0 → 1,58 |
.TH trainfo |
.SH NAME |
.B trainfo - write meta-information for a trajectory file |
.SH SYNOPSIS |
.B trainfo |
.I trafile |
[ |
.I option |
]. |
.SH DESCRIPTION |
Write meta-information for a trajectory file |
.I trafile |
to screen. If no option is given, all meta-information is written, otherwise the specific piece of information is passed with |
.I option. |
.SH PARAMETERS |
.TP 5 |
.I trafile |
name of the input trajectory file |
.SH OPTIONAL ARGUMENTS |
.TP 5 |
.B - dim |
dimensions of the trajectory file: #tra, #ntimes, #ncolumns. |
.TP 5 |
.B - ntra |
number of trajectories. |
.TP 5 |
.B - ntim |
number of times. |
.TP 5 |
.B - ncol |
number of columns (including time, longitude, latitude, pressure). |
.TP 5 |
.B - vars |
list of field names (columns) on the trajectory file. |
.TP 5 |
.B - refdate |
reference date in format (YYYYMMDD_HHMM). |
.TP 5 |
.B - times |
list of times (relative to the referencec date). Times are given in format: HH.MM. |
.TP 5 |
.B - startdate |
starting date for the trajectory calculation (in format YYYYMMD_HHMM). |
.TP 5 |
.B - enddate |
end date for the trajectory calculation (in format YYYYMMD_HHMM). |
.TP 5 |
.B - timerange |
time range (in minutes) of the trajectories. |
.TP 5 |
.B - list |
list all trajectories. |
.SH EXAMPLES |
.TP 5 |
.B [1] trainfo file dim |
Given a trajectory file with name "file", write the three dimensions of the file to screen. The dimensions are: number of trajectories, number of times and number of columns. |
.SH AUTHOR |
Written by Michael Sprenger and Heini Wernli (January 2011) |
/tags/1.0/docu/presentation/presentation.pdf |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/pdf |
Property changes: |
Added: svn:mime-type |
+application/pdf |
\ No newline at end of property |
/tags/1.0/docu/presentation/presentation.pptx |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/vnd.openxmlformats-officedocument.presentationml.presentation |
Property changes: |
Added: svn:mime-type |
+application/vnd.openxmlformats-officedocument.presentationml.presentation |
\ No newline at end of property |
/tags/1.0/docu/reference/reference.pdf |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/pdf |
Property changes: |
Added: svn:mime-type |
+application/pdf |
\ No newline at end of property |
/tags/1.0/docu/reference/title.tex |
---|
0,0 → 1,22 |
\documentclass[a4paper,10pt]{article} |
\usepackage[utf8x]{inputenc} |
\usepackage{graphicx} |
\graphicspath{{/home/sprenger/lagranto/docu/tutorial/}} |
\textwidth16cm |
\textheight22.5cm |
\oddsidemargin0.5cm |
\evensidemargin0cm |
\topmargin0.cm |
\headsep0cm |
\topskip-0.5cm |
\title{Lagranto - Reference} |
\author{Michael Sprenger and Heini Wernli} |
\begin{document} |
\maketitle |
\end{document} |
/tags/1.0/docu/tutorial/screen1.ps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/postscript |
Property changes: |
Added: svn:mime-type |
+application/postscript |
\ No newline at end of property |
/tags/1.0/docu/tutorial/screen2.ps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/postscript |
Property changes: |
Added: svn:mime-type |
+application/postscript |
\ No newline at end of property |
/tags/1.0/docu/tutorial/screen3.ps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/postscript |
Property changes: |
Added: svn:mime-type |
+application/postscript |
\ No newline at end of property |
/tags/1.0/docu/tutorial/screen4.ps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/postscript |
Property changes: |
Added: svn:mime-type |
+application/postscript |
\ No newline at end of property |
/tags/1.0/docu/tutorial/screen5.ps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/postscript |
Property changes: |
Added: svn:mime-type |
+application/postscript |
\ No newline at end of property |
/tags/1.0/docu/tutorial/tutorial.pdf |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/pdf |
Property changes: |
Added: svn:mime-type |
+application/pdf |
\ No newline at end of property |
/tags/1.0/docu/tutorial/tutorial.ps |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/postscript |
Property changes: |
Added: svn:mime-type |
+application/postscript |
\ No newline at end of property |
/tags/1.0/docu/tutorial/tutorial.tex |
---|
0,0 → 1,832 |
\documentclass[a4paper,10pt]{article} |
\usepackage[utf8x]{inputenc} |
\usepackage{graphicx} |
\graphicspath{{/home/sprenger/lagranto/docu/tutorial/}} |
\textwidth16cm |
\textheight22.5cm |
\oddsidemargin0.5cm |
\evensidemargin0cm |
\topmargin0.cm |
\headsep0cm |
\topskip-0.5cm |
\title{Lagranto - Tutorial} |
\author{Michael Sprenger and Heini Wernli} |
\begin{document} |
\maketitle |
\section{Definition of the Problem} |
In this tutorial we consider a simple way how to find airstreams which transport air from the surface into the upper troposphere and lower stratosphere, i.e. the UTLS region. More specifically, we intend |
\begin{itemize} |
\item[1)] to initialize starting positions over the North Atlantic and Europe (80 W to 20 E, 40 N to 80 N) for 00 UTC, 20 October 1989. The starting positions are horizontally equidistant with 80 km horizontal spacing and are set 100 hPa above ground level. |
\item[2)] to calculate trajectories 72 hours forward in time. |
\item[3)] to select trajectories which ascend to levels above 400 hPa within 48 hours and are found at starting time below 700 hPa. |
\item[4)] to trace several meteorological fields along the trajectories: potential vorticity (PV), potential temperature (TH), relative (RH) and specific humidity (Q). |
\item[4] to select subsamples of trajectories: a) those reaching the stratosphere; b) those travelling at most 2000 km; ... |
\item[5)] to show the densities of the trajectories on a geographical map. |
\end{itemize} |
\section{Meteorological Data} |
The following dates and netCDF files are needed for a Lagranto calculation covering the time period from 00\,UTC 20 October 1989 to 00\,UTC 23 October 1989. |
\begin{verbatim} |
> datelist stdout -create 19891020_00 19891023_00 |
19891020_00 |
19891020_06 |
19891020_12 |
... |
19891022_06 |
19891022_12 |
19891022_18 |
19891023_00 |
\end{verbatim} |
\noindent |
There are two different files involved, the P and the S files. Lagranto expects them to be in the running directory: |
\begin{verbatim} |
> ls -1 |
P19891020_00 P19891020_06 P19891020_12 P19891020_18 |
P19891021_00 P19891021_06 P19891021_12 P19891021_18 |
... |
S19891020_00 S19891020_06 S19891020_12 S19891020_18 |
S19891021_00 S19891021_06 S19891021_12 S19891021_18 |
... |
\end{verbatim} |
\noindent |
The meteorological fields on the primary P files are at least: zonal wind (U, in m/s); meridional wind (V, in m/s); vertical wind (OMEGA, in Pa/s); |
surface pressure (PS, in hPa). Additional fields might be available on the P files, e.g. temperature (T), specific |
humidity (Q),... Secondary fields can be saved in the S files, which must have the same grid structure as the P files. |
In the example the following fields are saved on the S files: potential temperature (TH, in K); Ertel potential vorticity (PV, in pvu); relative humidity (in \%). |
Furthermore, the surface pressure (PS) is also saved on the S files; it must be exactly identical to the one in the P files.\\ |
\noindent |
If the P and S files are stored at another place, they might be linked with a simple Shell script (in csh), usimg the command {\em datelist}: |
\begin{verbatim} |
> foreach date ( `datelist stdout -create 19891020_00 19891023_00` ) |
> ln -s {SOURCE DIR}/P${date} {DEST DIR}/P${date} |
> ln -s {SOURCE DIR}/S${date} {DEST DIR}/S${date} |
> end |
\end{verbatim} |
Note that the command {\em datelist} offers several options how to work with date list - creating, stepping through, comparing. |
\section{Starting Positions} |
In a first step the starting positions must be specified. To this aim a file {\em regionf} must be created with the definition of the region. The file is in the same directory as the meteorological data (section 1): |
\begin{verbatim} |
> more regionf |
"1 -80 20 40 80" |
\end{verbatim} |
\noindent |
The first number specifies a region ID (here 1) and the other values are: west boundary (80 W), east boundary (20 E), southern boundary (20 N) and northern boundary (80 N). The starting positions are then created with |
\begin{verbatim} |
> create_startf 19891020_00 startf.2 'region.eqd(1,80) ... |
... @ level(100) @ hPa,agl' -changet |
\end{verbatim} |
\noindent |
The starting positions are written to {\em startf.2}, i.e. in format 2, and cover the region 1 specified in {\em regionf}. The horizontal start points are equidistantly distributed with 80 km spacing, and they are all at 100 hPa above ground. All points refer to the starting date 00 UTC, 20 October 1989. |
In total, 3750 starting positions are written to {\em startf.2}. The first few lines of the file look as follows: |
\begin{verbatim} |
> head -10 startf.2 |
Reference date 19891020_0000 / Time range 0 min |
time lon lat p level |
--------------------------------------- |
0.00 -79.61 40.45 862 100.000 |
0.00 -78.66 40.45 860 100.000 |
0.00 -77.71 40.45 873 100.000 |
0.00 -76.76 40.45 886 100.000 |
0.00 -75.82 40.45 893 100.000 |
\end{verbatim} |
\noindent |
The different columns are: time, longitude, latitude, pressure (in hPa) and level (in hPa,agl). Note that the 'same' starting file could have been created without a region file. In this case, the command would have been: |
\begin{verbatim} |
> create_startf 19891020_00 startf.2 'box.eqd(-80,20,40,80,80) ... |
... @ level(100) @ hPa,agl' -changet |
\end{verbatim} |
\noindent |
However, note that the starting positions are not exactly the same as with the previous command: it is only guaranteed that the starting points are equidistantly distributed within the region. |
\section{Trajectory Calculation} |
In a next step, the trajectories are calculated 72 h forward in time, with starting date 00 UTC, 20 October 1989. The command is: |
\begin{verbatim} |
> caltra 19891020_00 19891023_00 startf.2 traj.4 -j |
\end{verbatim} |
\noindent |
The taring positions are taken from{\em startf.2} and the output is written to {\em traj.4}. Furthermore, the jumping flag {\em -j} is set, i.e. if trajectories run into the ground they are lifted a little and allowed to move on.\\ |
\noindent |
Note that the output file {\em traj.4} is not in ASCII format. To look at the file, use the command {\em trainfo}, for instance: |
\begin{verbatim} |
> trainfo traj.4 vars |
time lon lat p |
> trainfo traj.4 dim |
3750 13 4 |
> trainfo trai.4 startdate |
19891020_0000 |
\end{verbatim} |
\noindent |
It is also possible to convert the trajectory file into ASCII format with the command {\em reformat}: |
\begin{verbatim} |
> reformat traj.4 traj.1 |
> more traj.1 |
Reference date 19891020_0000 / Time range 4320 min |
time lon lat p |
----------------------------- |
0.00 -79.61 40.45 862 |
6.00 -80.57 43.23 791 |
12.00 -82.23 45.89 782 |
18.00 -84.94 47.07 744 |
\end{verbatim} |
\noindent |
The command {\em trafinfo} cna also be used to look at the trajectory tables, i.e. without a conversion to ASCII format. To this aim, use |
\begin{verbatim} |
> trainfo traj.4 list |
\end{verbatim} |
\noindent |
Whereas the ASCII format is most convenient for visual inspection, it is the least compact format. In particular, if the output of {\em caltra} should be further processed, e.g. with {\em trace} or {\em select}, the binary formats should be used (see documentation for {\em reformat}). |
\section{Pre-Selection of Trajectories} |
Quite often, the position of the air parcels is sufficient to select trajectories. It is then most efficient to pre-select these trajectories and do the tracing of additional fields along the trajectories only on the pre-selected ones. In the example, airstreams should be identified which ascend from below 700 hPa at initial time to levels above 300 hPa. The ascent has to take place within 48 h. This selection can be achieved with the command: |
\begin{verbatim} |
> select traj.4 wcb.1 'GT:p:700:FIRST & LT:p(MIN):400:0 to 48' |
\end{verbatim} |
\noindent |
The first criterion selects all trajectories for which the pressure (p) at the initial time (FIRST) is greater than (GT) 700 hPa. This criterison is logically AND-combined with the second criteron: consider all times between 0 and 48 h and take the minimum pressure, i.e. p(MIN), over this time interval; if the minium pressure is less than (LT) 400 hPa, the trajectory is selected. A sample trajectory looks like: |
\begin{verbatim} |
> trainfo wcb.1 list |
Reference date 19891020_0000 / Time range 4320 min |
time lon lat p |
----------------------------- |
0.00 -72.98 40.45 918 |
6.00 -76.45 43.14 879 |
12.00 -78.53 46.69 808 |
18.00 -80.08 48.70 770 |
24.00 -84.49 48.71 563 |
30.00 -87.89 43.32 377 |
36.00 -80.69 37.24 396 |
42.00 -73.05 39.00 477 |
48.00 -67.62 47.21 488 |
54.00 -63.53 54.61 455 |
60.00 -53.79 58.53 447 |
66.00 -38.79 59.08 452 |
72.00 -27.72 55.51 493 |
\end{verbatim} |
\noindent |
In total, 99 trajectories are selected. Further Lagrangian selection criteria might be reasonable. For instance, it could be of interest whether the air parcels are far away from their initial position after 48 h: |
\begin{verbatim} |
> select traj.4 wcb.1 'GT:p:700:FIRST & LT:p(MIN):400:0 to 48 & GT:DIST0:5000:48' |
\end{verbatim} |
\noindent |
The last criterion test whether the spherical distance from the initial position exceeds 5000 km at 48 h (only met by 4 trajectories). Note that the field {\em DIST0} is not available on the trajectory file {\em traj.4}, but is implicitely calculated. \\ |
\noindent |
Similarly, it can be tested whether a trajectory passes through a target region (e.g. 20E-30E,50N-60N). Such a region might be defined in the region file {\em regionf}: |
\begin{verbatim} |
> more regionf |
# Starting positions |
"1 -80 20 40 80" |
# Target region |
"2 20 30 50 60" |
\end{verbatim} |
\noindent |
The call to {\em select} now looks as follows: |
\begin{verbatim} |
> select traj.4 wcb.1 'GT:p:700:FIRST & LT:p(MIN):400:0 to 48 & ... |
... TRUE:INREGION:2:42 to 54(ANY)' |
\end{verbatim} |
\noindent |
The last criterion is interpreted in the following way: consider the times from 42 h to 48 h (42 to 54) and check whether a trajectory is at any of these times (ANY) in the traget region 2, as specified in {\em regionf}. A sample trajectory is given below: |
\begin{verbatim} |
> more wcb.1 |
Reference date 19891020_0000 / Time range 4320 min |
time lon lat p |
----------------------------- |
0.00 -44.56 40.45 914 |
6.00 -41.22 38.95 885 |
12.00 -37.50 37.59 849 |
18.00 -33.54 36.76 823 |
24.00 -29.45 36.45 770 |
30.00 -24.56 37.44 622 |
36.00 -18.89 41.17 429 |
42.00 -10.48 49.48 349 |
48.00 8.75 57.02 355 |
54.00 28.74 56.97 354 |
60.00 37.14 53.71 320 |
66.00 38.99 49.75 334 |
72.00 37.57 45.94 349 |
\end{verbatim} |
\section{Tracing Meteorological Fields} |
Meteorological fields can be traced along the trajectories with the command {\em trace}. Most often, a list of fields to trace will be listed in a file {\em tracevars}: |
\begin{verbatim} |
> more tracevars |
PS 1. 0 P |
Q 1000. 0 P |
TH 1. 0 S |
RH 1. 1 * |
\end{verbatim} |
\noindent |
The following fields are to be traced: surface pressure (PS), specific humidity (Q), potential temperature (TH) and relative humidity (RH). PS and Q are available on the P files and need not to be calculated; Q will be scaled by a factor 1000 to convert from Kg/kg to g/kg. TH is found on the S file and need not to be calculated. Finally, RH is found neither on the P nor on the S file and must becomputed - the flag 1 in the third column.\\ |
\noindent |
With the {\em tracevars} file ready, the tracing is started with: |
\begin{verbatim} |
> trace wcb.1 wcb.1 |
\end{verbatim} |
\noindent |
Note that the input and output file are allowed to have the same name. The following table shows the first few lines of the new trajectory file: |
\begin{verbatim} |
> more wcb.1 |
Reference date 19891020_0000 / Time range 4320 min |
time lon lat p PS Q TH RH |
--------------------------------------------------------------------- |
0.00 -44.56 40.45 914 1014.093 9.664 294.921 86.667 |
6.00 -41.22 38.95 885 1012.965 8.380 296.549 77.992 |
12.00 -37.50 37.59 849 1014.056 8.565 299.122 81.321 |
18.00 -33.54 36.76 823 1012.074 8.720 300.798 85.407 |
24.00 -29.45 36.45 770 1012.254 7.666 303.487 85.262 |
\end{verbatim} |
\noindent |
If it is later found that additional fields should be traced, this can be done with a new {\em tracevars} file or for a single field with (the second number being the scaling factor): |
\begin{verbatim} |
> trace wcb.1 wcb.1 -f PV 1. |
\end{verbatim} |
\noindent |
Note that several fields are allowed for online computation, i.e. with the computation flag set in {\em tracevars}. This is convenient for interactive mode and for few trajectories. However, if tracing is needed for many trajectories, a pre-calculation and saving on the S files is much more efficient! A list of fields for online computation is found in the reference guide for {\em trace}. \\ |
\noindent |
It is also possible to trace the surrounding of a trajectory position, i.e. to get for instance not the temperature at the air parcel's position, but at 50 hPa above or below it. This is done with: |
\begin{verbatim} |
> trace wcb.1 wcb.1 -f T:-50HPA 1. |
> trace wcb.1 wcb.1 -f T:+50HPA 1. |
\end{verbatim} |
\noindent |
Finally, if it is decided that a field is no longer needed in the trajectory file, or if it has to be corrected, it is possible to remove columns from the trajectory file. This can be achieved with {\em extract} - for instance if only PS, TH and RH should be kept: |
\begin{verbatim} |
> extract wcb.1 wcb.1 -var PS TH RH |
\end{verbatim} |
\noindent |
Note that {\em extract} can also be used to extract different times or starting positions (see the reference documentation). |
\section{Final Selection of Trajectories} |
In this section the selection of trajectories should be refined, i.e. it is not only based on positional information but also on further meteorological parameters. We look at several questions:\\ |
\begin{itemize} |
\item[a)] Is there a trajectory which reaches saturation ($RH>99$\%)? The trajectories should be saved in a new trajectory file. |
\begin{verbatim} |
> select wcb.1 sat.1 'GT:RH:99:0 to 72(ANY)' |
> more sat.1 |
Reference date 19891020_0000 / Time range 4320 min |
time lon lat p PS Q TH RH PV |
--------------------------------------------------------------------------------- |
0.00 -72.98 40.45 918 1018.161 9.503 292.020 100.722 0.920 |
6.00 -76.45 43.14 879 986.319 8.723 294.933 92.837 1.101 |
12.00 -78.53 46.69 808 972.550 7.621 297.875 97.737 0.794 |
18.00 -80.08 48.70 770 973.957 6.147 297.914 97.912 1.078 |
24.00 -84.49 48.71 563 962.279 2.327 307.548 87.923 1.034 |
30.00 -87.89 43.32 377 977.415 0.319 314.210 65.759 0.108 |
36.00 -80.69 37.24 396 939.606 0.303 312.705 52.845 0.323 |
42.00 -73.05 39.00 477 1013.693 0.298 314.614 16.248 0.309 |
48.00 -67.62 47.21 488 970.025 0.442 312.975 23.890 0.463 |
54.00 -63.53 54.61 455 950.011 0.386 313.047 30.182 0.479 |
60.00 -53.79 58.53 447 1007.039 0.392 311.951 36.578 0.487 |
66.00 -38.79 59.08 452 1006.532 0.319 311.316 29.286 0.443 |
72.00 -27.72 55.51 493 1009.871 0.279 311.428 15.950 0.513 |
\end{verbatim} |
\item[b)] Get a list of all trajectories which pass through a circle around 20\,W/40\,N and radius 500\,km. |
\begin{verbatim} |
> select wcb.1 indlist 'TRUE:INCIRCLE:-20,40,500:ALL(ANY)' -index |
> more indlist |
4 |
5 |
6 |
11 |
12 |
13 |
14 |
19 |
20 |
21 |
22 |
47 |
\end{verbatim} |
Hence, the trajectories 4,5,... pass through the circle. The trajectories themselves can be extracted in a second step with |
\begin{verbatim} |
> extract wcb.1 pass.1 -index indlist |
\end{verbatim} |
where now the selected trajectories are written to the trajectory file {\em pass.1}. |
\item[c)] Select all trajectories which are in the stratosphere after 48 h. The dynamical tropopause is defined as the 2-PVU isosurface? |
\begin{verbatim} |
> select wcb.1 out 'GT:PV:2:48 to 72(ALL) & LT:P:500:48 to 72(ALL)' |
\end{verbatim} |
The second criterion guarantees that the air parcel is at a height above 500 hPa; indeed, low-level high-PV regions might mimick a stratosphere, although they are of diabatic origin. |
\item[d)] Select all trajectories which are within 2000 km distance of their starting position after 72 h. |
\begin{verbatim} |
> select wcb.1 sel.1 'LT:DIST0:2000:LAST' |
\end{verbatim} |
Note that the fields {\em DIST0} needs not to be available on the trajectory file - it is calculated during the selection. {\em DIST0} refers to the spherical distance (in km) from the strting position. If the path length (in km) is needed, {\em DIST} can be used instead. |
\item[e)] How many trajectories ascend more than 550 hPa between 12 h and 54 h? We are only interested in the number of selected trajectories. |
\begin{verbatim} |
> select wcb.1 count 'GT:P(DIFF):550:12,54' -count |
> more count |
3 |
\end{verbatim} |
\item[f)] We would like to select all trajectories which reach potential vorticity (PV) greather than 2 PVU at levels above 500 hPa. In a first attempt, this might be accomplished with the criterion |
\begin{verbatim} |
> select wcb.1 wcb.1 'GT:PV:2:ALL(ANY) & LT:p:500:ALL(ANY)' |
\end{verbatim} |
But note that this is not exactly what we want - the first criterion might be fulfilled at a time 48 h, for instance, whereas the second criterion is fulfilled at another time, say 72 h. Hence they are not both fulfilled at the same time! A way around this problem is possible if a TRIGGER column is used to mark the two events. The original trajectory file looks as follows: |
\begin{verbatim} |
> more wcb.1 |
Reference date 19891020_0000 / Time range 4320 min |
time lon lat p PS RH PV |
------------------------------------------------------------ |
0.00 -19.56 46.94 905 1005.242 83.514 0.291 |
6.00 -14.72 48.17 892 999.182 88.325 0.242 |
12.00 -10.58 50.53 862 993.145 97.718 0.293 |
18.00 -7.22 53.02 792 972.076 99.216 0.738 |
24.00 -3.71 55.89 724 956.135 93.218 1.076 |
30.00 -0.19 58.87 629 971.334 70.088 1.076 |
36.00 1.46 61.62 452 966.406 66.056 0.558 |
42.00 0.01 62.49 328 977.209 65.319 1.754 |
48.00 -1.54 63.41 313 983.930 56.822 2.727 |
54.00 -3.59 64.77 322 984.627 58.328 1.874 |
60.00 -9.91 66.07 323 988.185 57.894 2.052 |
66.00 -20.91 66.02 316 976.560 57.989 2.565 |
72.00 -28.89 66.19 319 1007.175 54.477 2.693 |
\end{verbatim} |
Then we mark the two events with a TRIGGER: |
\begin{verbatim} |
> select wcb.1 wcb.1 'GT:PV:2:1(TRIGGER) & LT:p:500:2(TRIGGER)' -trigger |
\end{verbatim} |
The first criterion (PV) gets the trigger 1 (in binary system 01), the second one (pressure) get the trigger 2 (in binary system 10). If both criteria are fulfilled, the trigger column becomes 3, which corresponds in the binary system to 11 - i.e. each flag corresponds to a bit in the trigger value. With the option '-trigger' the trigger column is written to the output trajectory file: |
\begin{verbatim} |
> more wcb.1 |
Reference date 19891020_0000 / Time range 4320 min |
time lon lat p PS RH PV TRIGGER |
------------------------------------------------------------------------- |
0.00 -19.56 46.94 905 1005.242 83.514 0.291 0.000 |
6.00 -14.72 48.17 892 999.182 88.325 0.242 0.000 |
12.00 -10.58 50.53 862 993.145 97.718 0.293 0.000 |
18.00 -7.22 53.02 792 972.076 99.216 0.738 0.000 |
24.00 -3.71 55.89 724 956.135 93.218 1.076 0.000 |
30.00 -0.19 58.87 629 971.334 70.088 1.076 0.000 |
36.00 1.46 61.62 452 966.406 66.056 0.558 2.000 |
42.00 0.01 62.49 328 977.200 65.319 1.754 2.000 |
48.00 -1.54 63.41 313 983.930 56.822 2.727 3.000 |
54.00 -3.59 64.77 322 984.627 58.328 1.874 2.000 |
60.00 -9.91 66.07 323 988.185 57.894 2.052 3.000 |
66.00 -20.91 66.02 316 976.560 57.989 2.565 3.000 |
72.00 -28.89 66.19 319 1007.175 54.477 2.693 3.000 |
\end{verbatim} |
Now the selection can be achieved by refering to the TRIGGER column: |
\begin{verbatim} |
> select wcb.1 wcb.1 'ALL:TRIGGER:1,2:ALL(ANY)' |
\end{verbatim} |
This selection means that the trigger values 1 and 2 must be set - the operator ALL (first term) guaranteeing that all selected triggers are set. The time specification ALL(ANY) is as before, i.e. the check is performed for all times and he criterion must be fulfilled at any of these times.\\ |
\item[g)] Select all trajectories which pass at time 60 h over Switzerland! The coordinates of the Swiss boundary are listed in a file {\em borders.dat}: |
\begin{verbatim} |
> more borders.dat |
8.55 47.45 |
7.942863 46.002075 |
7.949024 46.001195 |
7.956945 46.000022 |
7.984226 46.000022 |
7.989800 46.001489 |
8.000068 46.007356 |
8.011508 46.018503 |
... |
\end{verbatim} |
The first line is a point (longitude, latitude) within Switzerland (Zurich), the other lines define the boundary of Switzerland (as 1373 points). With this polygon file, the selection command becomes |
\begin{verbatim} |
> select wcb.1 out.1 'TRUE:INPOLYGON:borders.dat:60' |
\end{verbatim} |
Note that in a criterion only one polygon can be specified. |
\item[g)] New criteria can easily be implemented into the Fortran code; to this aim the file {\em special.f} in directory {\em select} must be edited. The following example shows the implementation of an identification for warm conveyor belts (WCB). The calling sequence for the criterion is {\em SPECIAL:WCB:ascent,first,last}, the air stream must ascend at least {\em ascent} hPa between time {\em first} and time {\em last}. The corresponding Fortran looks as follows: |
\begin{small} |
\begin{verbatim} |
> more select/special.f |
SUBROUTINE special (flag,cmd,tra,ntim,ncol, |
> vars,times,param,nparam) |
c *************************************************************************** |
c * * |
c * OUTPUT: flag -> 1 if trajectory is selected, 0 if not * |
c * * |
c * INPUT: cmd <- command string (e.g. WCB) * |
c * tra(ntim,ncol) <- single trajectory: indices time,column * |
c * ntim <- number of times * |
c * ncol <- number of columns (including time,lon,lat,p) * |
c * vars(ncol) <- names of columns * |
c * times(ntim) <- List of times |
c * param(nparam) <- parameter values * |
c * nparam <- number of parameters * |
c * * |
c *************************************************************************** |
implicit none |
c --------------------------------------------------------------------------- |
c Declaration of subroutine parameters |
c --------------------------------------------------------------------------- |
integer flag ! Boolean flag whether trajectory is selected |
character*80 cmd ! Command string |
integer ntim,ncol ! Dimension of single trajectory |
real tra(ntim,ncol) ! Single trajectory |
character*80 vars(ncol) ! Name of columns |
real times(ntim) ! List of times |
integer nparam ! # parameters |
real param(nparam) ! List of parameters |
c --------------------------------------------------------------------------- |
c Declaration of local variables |
c --------------------------------------------------------------------------- |
integer i |
integer ip,i0,i1 |
c -------------------------------------------------------------------------- %) |
c SPECIAL:WCB:ascent,first,last %) |
c : Detect Warm Conveyor Belts (WCB); the air stream must ascend at least %) |
c : <ascent=param(1)> hPa between the two times <first=param(2)> and %) |
c : <last=param(3)>. Note, the lowest pressure is allowed to occur at any %) |
c : time between <first> and <last>. %) |
c --------------------------------------------------------------------------- %) |
if ( cmd.eq.'WCB' ) then |
c Reset the flag for selection |
flag = 0 |
c Pressure is in the 4th column |
ip = 4 |
c Get indices for times <first> and <last> |
i0 = 0 |
i1 = 0 |
do i=1,ntim |
if ( param(2).eq.times(i) ) i0 = i |
if ( param(3).eq.times(i) ) i1 = i |
enddo |
if ( (i0.eq.0).or.(i1.eq.0) ) then |
print*,' ERROR: invalid times in SPECIAL:WCB... Stop' |
stop |
endif |
c Check for ascent |
do i=i0+1,i1 |
if ( ( tra(1,ip)-tra(i,ip) ) .gt. param(1) ) flag = 1 |
enddo |
endif |
c --------------------------------------------------------------------------- |
end |
\end{verbatim} |
\end{small} |
\end{itemize} |
\section{Trajectory Densities} |
Single trajectories can be visualised e.g. with Matlab or wit NCL (see template scripts in the Lagranto folder). If many trajectories should be visualised instead, it is much more convenient to show trajectory densities. The easiiest way to get trajectory densities is: |
\begin{verbatim} |
> density wcb.1 densisty |
> ncview density |
\end{verbatim} |
This will project the trajectories in the trajectory file {\em wcb.1} onto a global longitude/latitude grid with 1 degree horizontal resolution. A filter radius of 100 km will be used |
\includegraphics[width=0.9\textwidth]{screen1.ps} |
\noindent |
The CF-netCDF file contains several fields: a) the number of trajectory points associated to each grid point (COUNT); b) the residence time of the trajectories (in hours) associated to each grid point - the residence time being the time a trajectory stays at a certain grid cell (RESIDENCE); c) the area (im $km^2$) associated with each grid cell. The area allows to change the unit of the gridded trajectory from counts per grid point to counts per $km^2$.\\ |
\noindent |
Often the trajectories do not spread over the whole globe; then the subdomain can be specified with |
\begin{verbatim} |
> density traj.1 density -latlon 300 150 -100 10 0.5 0.5 -create |
\end{verbatim} |
where the new grid has 300x150 grid points in zonal and meridional direction with south-eastern corner at 100\,W/10\,S and resolution of 0.5 degree in zonal and 0.5 degree in meridional direction. The flag {\em create} forces the netCDF file to be created anew, even if it already exists. |
\includegraphics[width=0.9\textwidth]{screen2.ps} |
\noindent |
It is also possible to re-parameterise the trajectories before they are gridded. For instance, the following command interpolates the positions to a 1-h time interval and then performs the grissing. This results in a smoother density plot: |
\begin{verbatim} |
> density traj.1 density -latlon 300 150 -100 10 0.5 0.5 -create -interp 1 h |
\end{verbatim} |
\includegraphics[width=0.9\textwidth]{screen3.ps} |
\noindent |
In addition to a gridding of the complete trajectories, the single trajectory times can be gridded. |
\begin{verbatim} |
> density traj.1 density -create -time 0.00 -create |
> density traj.1 density -create -time 6.00 |
> density traj.1 density -create -time 12.00 |
> density traj.1 density -create -time 18.00 |
> density traj.1 density -create -time 24.00 |
\end{verbatim} |
\noindent |
In the previous figures, the density of the trajectories was determined - i.e. the number of trajectories associated with a grid point or the residence associated with a grid cell was determined. In addition to this most basic information, it is also possible to perform a gridding of any trajectory field. For instance, the trajectory file contains |
\begin{verbatim} |
Reference date 19891020_0000 / Time range 4320 min |
time lon lat p |
----------------------------- |
0.00 -79.61 40.45 862 |
6.00 -80.57 43.23 791 |
12.00 -82.23 45.89 782 |
18.00 -84.94 47.07 744 |
\end{verbatim} |
\noindent |
and we would like to know at what height the trajectories typically (in the mean) are at a specific grid point. Then we would grid the pressure ``p'' instead of the position: |
\begin{verbatim} |
> density traj.1 density -create -latlon 300 150 -100 10 0.5 0.5 -field p -time 0.00 |
> density traj.1 density -field p -time 24.00 |
> density traj.1 density -field p -time 48.00 |
\end{verbatim} |
\noindent |
The following figures show the gridded pressure at time 0.00 and 24.00 h; note that the trajectories were initialised 100 hPa above ground. |
\noindent |
\begin{center} |
\includegraphics[width=0.8\textwidth]{screen4.ps} |
\\ |
\includegraphics[width=0.8\textwidth]{screen5.ps} |
\end{center} |
\section{Interface Script} |
\subsection{Start from local directory} |
In addition to the programs {\em create\_startf}, {\em caltra}, {\em trace}, {\em select}, Lagranto offers a ``master'' script which combines the call to the individual programs into one single call. For instance, |
\begin{verbatim} |
> lagranto local 19891020_00 19891024_18 startf nil -changet |
\end{verbatim} |
will start a Lagranto run starting from 00,UTC 20 Octiober 2010 to 18,UTC 24 Octiober 2010, based upon the starting positions in the file {\em startf}. No selection of trajectories is applied, as specified with the flag {\em nil}, and the times on the netCDF P and S files are set relative to the starting date prior to the Lagranto run. Finally, {\em local} means that all input files are expected in the directory where Lagranto was called.\\ |
\noindent |
The output for the above Lagranto call is saved in a newly created directory, which is located in the calling directory: |
\begin{verbatim} |
> ls -l ntr_19891020_00_f114_local_startf_nil/ |
-rw-r--r-- 1 michaesp wheel 5328945 2011-03-21 14:03 lsl_19891020_00 |
-rw-r--r-- 1 michaesp wheel 68195 2011-03-21 14:03 runscript.logfile |
-rwxr--r-- 1 michaesp wheel 1025 2011-03-21 14:02 runscript.sh* |
\end{verbatim} |
The three different files are: |
\begin{itemize} |
\item[a)] {\bf lsl\_19891020\_00}: the output trajectory file -the file name starts with {\em lsl} and contains the starting date of the Lagranto run: |
\begin{verbatim} |
> more lsl_19891020_00 |
Reference date 19891020_0000 / Time range 6840 min |
time lon lat p PS Q TH RH |
--------------------------------------------------------------------- |
0.00 -79.61 40.45 862 961.659 6.434 290.838 97.722 |
6.00 -80.57 43.23 791 980.984 5.334 293.824 98.773 |
... |
\end{verbatim} |
Note that additional fields have been traced along the trajectories, as specified in the tracing file {\em tracevars}: |
\begin{verbatim} |
> more tracevars |
PS 1. 0 P |
Q 1000. 0 P |
TH 1. 0 S |
RH 1. 1 * |
\end{verbatim} |
\item[b)] {\bf runscript.logfile}: a log file with all status and error information of the Lagranto run. If the flag {\em -log} is set in a Lagranto call, the log will be written to screen. |
\item[c)] {\bf runscript.sh}: the calling script for the programs {\em create\_startf}, {\em caltra}, {\em trace} and {\em select}. The basic idea of {\em lagranto} is to create the output directory, to prepare all netCDF and other files in this output directory and to create a Shell script with name {\em runscript.sh}. If all these preparations were successfull, Lagranto will change into the output directory and launch {\em runscript.sh}. The {\em runscript.sh} for the previous Lagranto call looks as follows: |
\begin{small} |
\begin{verbatim} |
#!/bin/csh |
# |
#----- Calling command |
# |
# lagranto local 19891020_00 19891024_18 startf nil -changet -log |
# |
#----- Output file |
# |
# lsl_19891020_00 |
# |
#------ Abort if no startf is available |
# |
if ( ! -f startf ) then |
echo " ERROR: no start file available .... Stop" |
exit 1 |
endif |
# |
#------ Remove existing trajectory files |
# |
if ( -f lsl_19891020_00.4 ) then |
\rm -f lsl_19891020_00.4 |
endif |
if ( -f lsl_19891020_00 ) then |
\rm -f lsl_19891020_00 |
endif |
# |
#------ Run <caltra> |
# |
/home/sprenger/lagranto//bin/caltra.sh 19891020_00 19891024_18 startf lsl_19891020_00.4 |
# |
#------ Abort if caltra was not successful |
# |
if ( ! -f lsl_19891020_00.4 ) then |
echo " ERROR: caltra failed .... Stop" |
exit 1 |
endif |
# |
#------ Run <trace> |
# |
/home/sprenger/lagranto//bin/trace.sh lsl_19891020_00.4 lsl_19891020_00 -v tracevars |
# |
#------ Abort if trace was not successful |
# |
if ( ! -f lsl_19891020_00 ) then |
echo " ERROR: trace failed .... Stop" |
exit 1 |
endif |
\end{verbatim} |
\end{small} |
\end{itemize} |
\noindent |
Note that you are free to change to the output directory and manually launch {\em runscript.sh}, possibly after having modified it to your needs. This way of working is uspported by the optional flag {\em -prep} which will only prepare all files and then changes to the output directory: |
\begin{verbatim} |
> lagranto local 19891020_00 19891024_18 startf nil -changet -prep |
\end{verbatim} |
At the end of this call you will be asked to change to the output directory, which -after having agreed- will open a new {\em xterm} window. Note that you can always easily change to a output directory by calling |
\begin{verbatim} |
> lagranto -open local |
\end{verbatim} |
If several trajectory runs are available in the local directory, you are asked to select one. Often, you would like to see the outcome of a run without changing to the output directory. This is most easily accomplished with the following call: |
\begin{verbatim} |
> lagranto -show local |
\end{verbatim} |
\subsection{Start from case directory} |
In this calling sequence, for instance |
\begin{verbatim} |
> lagranto tutorial 19891020_00 19891024_18 startf nil -changet |
\end{verbatim} |
the input files are not expected in the local directory, but are specified by means of a case identifier. For instance, a case has the identifier {\em tutorial}. Then Lagranto will expect the input netCDF P and S files to be located in |
\begin{verbatim} |
> ls -l ${HOME}/cdf/tutorial |
/home/sprenger/cdf/tutorial/P19891020_00 |
/home/sprenger/cdf/tutorial/P19891020_06 |
/home/sprenger/cdf/tutorial/P19891020_12 |
/home/sprenger/cdf/tutorial/P19891020_18 |
/home/sprenger/cdf/tutorial/P19891021_00 |
/home/sprenger/cdf/tutorial/P19891021_06 |
/home/sprenger/cdf/tutorial/P19891021_12 |
/hom |
\end{verbatim} |
and all the other input files (starting positions, tracing file, region file, polygon specification) are expected in |
\begin{verbatim} |
> ls -l ${HOME}/tra/tutorial |
startf |
tracevars |
\end{verbatim} |
The output of the trajectory calculation will be written to the following output directory, where now the case identifier {\em tutorial} is part of the directory name: |
\begin{verbatim} |
> cd /home/michaesp/tra/tutorial/ntr_19891020_00_f114_tutorial_startf_nil |
> ls -1 |
-rw-r--r-- 1 michaesp wheel 5328945 2011-03-21 14:03 lsl_19891020_00 |
-rw-r--r-- 1 michaesp wheel 68195 2011-03-21 14:03 runscript.logfile |
-rwxr--r-- 1 michaesp wheel 1025 2011-03-21 14:02 runscript.sh* |
\end{verbatim} |
All other aspects are identical to the ones described in the previous section. |
\section{Installation} |
In this section you will find some hints how to install Lagranto on a Linux platform. Everthing is handled with the installation script {\em install.sh} which comes with the Lagranto distribution: |
\begin{verbatim} |
> install.csh |
install.sh [lib|core|goodies|links|all] |
\end{verbatim} |
The installation should proceed in several distinct steps: |
\begin{itemize} |
\item[a)] Find the place of the netCDF (http://www.unidata.ucar.edu/software/netcdf/) installation on your system - note that the netCDF comes as a pre-compiled package for many Linux distributions and most often can be installed with the Linux software management. Define an environmental variable {\em NETCDF} which directs to your installation, e.g. |
\begin{verbatim} |
> setenv NETCDF /usr/local/netcdf/ |
\end{verbatim} |
\item[b)] Set the environmental variable {\em LAGRANTO} to the place where you have stored the Lagranto source code and include Lagranto in your search path. In {\em csh} this might look as follows: |
\begin{verbatim} |
> setenv LAGRANTO /home/michaesp/lagranto/ |
> set isLAGRANTO=`echo $PATH | grep $LAGRANTO | wc -l` |
> if ( $isLAGRANTO == 0 ) then |
> setenv PATH $LAGRANTO/bin:${PATH} |
> endif |
\end{verbatim} |
You might include these statements also in your {\em .cshrc} file. If successful, you will then be able to open the lagranto help, e.g. with |
\begin{verbatim} |
> lagrantohelp |
\end{verbatim} |
\item[c)] Install the different components of Lagranto and create links - proceed step by step to ensure that each one was successfully completed: |
\begin{verbatim} |
> install lib |
> install core |
> install goodies |
> install links |
\end{verbatim} |
\end{itemize} |
Lagranto should now be ready to run! As a next step you might want to consider the tutorial, which can be invoked with the command: |
\begin{verbatim} |
> lagrantohelp tutorial |
\end{verbatim} |
If you are familiar with the most basic aspects of Lagranto, please refer to the reference guide which enlists all options of Lagranto: |
\begin{verbatim} |
> lagrantohelp refernce |
\end{verbatim} |
The contents of the reference guide can also be called from within the Linux shell, e.g. the documentation of {\em caltra} can be seen in man page format with: |
\begin{verbatim} |
> lagrantohelp caltra |
\end{verbatim} |
\end{document} |
/tags/1.0/goodies/changet.f |
---|
0,0 → 1,47 |
program changetime |
C Changes the time value of a NetCDF file. |
C-----declarations------------------------------------------------ |
integer ierr,ntimes |
real tstart,time |
integer cdfid,varid |
character*30 filnam |
C-----start of program-------------------------------------------- |
include 'netcdf.inc' |
call ncpopt(NCVERBOS) |
read(9,10)filnam |
10 format(a30) |
read(9,*)time |
C Open the data file |
cdfid=ncopn(filnam,NCWRITE,ierr) |
C Get time value from file |
call gettimes(cdfid,tstart,ntimes,ierr) |
C Get index for time variable |
varid=ncvid(cdfid,'time',ierr) |
C Overwrite time-value |
call ncvpt1(cdfid,varid,1,time,ierr) |
write(*,20)'file ',trim(filnam),' time value changed from ', |
> tstart,' to ',time |
20 format(a,a,a,f8.2,a,f8.2) |
C Close open NetCDF files |
call clscdf(cdfid,ierr) |
end |
/tags/1.0/goodies/changet.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = changet.o ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
changet: $(OBJS) |
${F77} -o changet $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/changet.sh |
---|
0,0 → 1,41 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
if ( $#argv < 1 ) then |
echo |
${LAGRANTO}/bin/lagrantohelp changet short |
echo |
exit 0 |
endif |
set stdate=$1 |
set fort=fort.9 |
if ( $#argv == 2 ) then |
set string=$2 |
else |
set string='P[_0-9]*[0-9] S[_0-9]*[0-9]' |
endif |
foreach i ( $string ) |
\rm -f $fort |
touch $fort |
# set date = `echo $i | sed -e 's/[A-Za-z_]*//' | cut -c 1-9` |
set date = `echo $i | sed -e 's/[A-Za-z_]*//'` |
echo $i >> $fort |
set date=`echo ${date}00 | cut -c 1-13` |
set stdate=`echo ${stdate}00 | cut -c 1-13` |
set tim = `${LAGRANTO}/goodies/gettidiff $date $stdate` |
echo ${tim} >> $fort |
${LAGRANTO}/goodies/changet |
end |
#\rm -f $fort |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/datelist.f |
---|
0,0 → 1,432 |
date PROGRAM datelist |
c ********************************************************************** |
c * Handling of date lists * |
c * Michael Sprenger * |
c ********************************************************************** |
implicit none |
c --------------------------------------------------------------------- |
c Declaration of variables |
c --------------------------------------------------------------------- |
c Parameters |
character*80 datefile |
character*80 mode |
character*80 startdate |
character*80 finaldate |
character*80 refdate |
integer interval |
real randpercent |
c Date list |
integer ndates |
integer,allocatable,dimension(:) :: year,month,day,hour |
c Auxiliary variables |
integer i |
integer year1,month1,day1,hour1,min1 |
integer year2,month2,day2,hour2,min2 |
character direction |
integer date1(5),date2(5) |
character*11 datestr,datestr1,datestr2 |
character ch |
real diff |
real time |
character*80 datefile1,datefile2 |
integer timestamp1,timestamp2 |
integer oldstamp1 ,oldstamp2 |
integer state |
c --------------------------------------------------------------------- |
c Preparations |
c --------------------------------------------------------------------- |
c Read parameter file |
open(10,file='datelist.param') |
read(10,*) datefile ! General parameters |
read(10,*) mode |
if ( mode.eq.'-create' ) then ! Create date list |
read(10,*) startdate |
read(10,*) finaldate |
read(10,*) interval |
elseif ( mode.eq.'-totime' ) then ! Convert to time list |
read(10,*) refdate |
elseif ( mode.eq.'-todate' ) then ! Convert to date list |
read(10,*) refdate |
elseif ( mode.eq.'-onlyin1' ) then ! Dates only in file 1 |
read(10,*) datefile1 |
read(10,*) datefile2 |
else ! Invalid mode |
print*,' ERROR: invalid mode for datelist' |
stop |
endif |
close(10) |
c --------------------------------------------------------------------- |
c Create a date list (-create) |
c --------------------------------------------------------------------- |
if ( mode.ne.'-create' ) goto 100 |
c Check whether interval is ok |
if ( ( interval.le.0 ).or.(interval.gt.24) ) then |
print*,'Interval must be between 1 h and 24 h... Stop' |
stop |
endif |
c Extract dates and times |
read(startdate( 1: 4),*) year1 |
read(startdate( 5: 6),*) month1 |
read(startdate( 7: 8),*) day1 |
read(startdate(10:11),*) hour1 |
read(startdate(12:13),*) min1 |
read(finaldate( 1: 4),*) year2 |
read(finaldate( 5: 6),*) month2 |
read(finaldate( 7: 8),*) day2 |
read(finaldate(10:11),*) hour2 |
read(finaldate(12:13),*) min2 |
c Get direction of the date file |
if (year2.gt.year1) then |
direction = 'f' |
goto 101 |
elseif (year2.lt.year1) then |
direction = 'b' |
goto 101 |
endif |
if (month2.gt.month1) then |
direction = 'f' |
goto 101 |
elseif (month2.lt.month1) then |
direction = 'b' |
goto 101 |
endif |
if (day2.gt.day1) then |
direction = 'f' |
goto 101 |
elseif (day2.lt.day1) then |
direction = 'b' |
goto 101 |
endif |
if (hour2.gt.hour1) then |
direction = 'f' |
goto 101 |
elseif (hour2.lt.hour1) then |
direction = 'b' |
goto 101 |
endif |
if (min2.gt.min1) then |
direction = 'f' |
goto 101 |
elseif (min2.lt.min1) then |
direction = 'b' |
goto 101 |
endif |
direction = 'f' |
101 continue |
c Set the interval step depending on the direction |
if ( direction.eq.'b' ) then |
interval = -interval |
endif |
c Save the dates in arrays |
date1(1) = year1 |
date1(2) = month1 |
date1(3) = day1 |
date1(4) = hour1 |
date1(5) = 0 |
date2(1) = year2 |
date2(2) = month2 |
date2(3) = day2 |
date2(4) = hour2 |
date2(5) = 0 |
c Get starting and ending date for the date list |
if ( direction.eq.'f' ) then |
do while ( mod(date1(4),interval) .ne. 0 ) |
date1(4) = date1(4) - 1 |
enddo |
if (min2.ne.0) call newdate(date2,1.,date2) |
do while ( mod(date2(4),interval) .ne. 0 ) |
date2(4) = date2(4) + 1 |
enddo |
else |
if (min1.ne.0) call newdate(date1,1.,date1) |
do while ( mod(date1(4),interval) .ne. 0 ) |
date1(4) = date1(4) + 1 |
enddo |
do while ( mod(date2(4),interval) .ne. 0 ) |
date2(4) = date2(4) - 1 |
enddo |
endif |
c Create and write the datefile |
if ( datefile.ne.'/dev/stdout') then |
open(10,file=datefile) |
endif |
102 continue |
call datestring(datestr,date1(1),date1(2),date1(3),date1(4) ) |
if ( datefile.ne.'/dev/stdout') then |
write(10,*) datestr |
else |
write(*,*) datestr |
endif |
if ( ( date1(1).ne.date2(1) ).or. |
> ( date1(2).ne.date2(2) ).or. |
> ( date1(3).ne.date2(3) ).or. |
> ( date1(4).ne.date2(4) ) ) |
> then |
diff = real(interval) |
call newdate(date1,diff,date1) |
goto 102 |
endif |
if ( datefile.ne.'/dev/stdout') then |
close(10) |
endif |
100 continue |
c --------------------------------------------------------------------- |
c Convert dates to a list of times |
c --------------------------------------------------------------------- |
if ( mode.ne.'-totime' ) goto 110 |
c Extract reference date |
read(refdate( 1: 4),*) year1 |
read(refdate( 5: 6),*) month1 |
read(refdate( 7: 8),*) day1 |
read(refdate(10:11),*) hour1 |
read(refdate(12:13),*) min1 |
c Loop through the date file |
open(10,file=datefile) |
111 read(10,*,end=110) datestr |
c Extract date |
read(datestr( 1: 4),*) year2 |
read(datestr( 5: 6),*) month2 |
read(datestr( 7: 8),*) day2 |
read(datestr(10:11),*) hour2 |
min1 = 0 |
c Get the time difference |
date1(1) = year1 |
date1(2) = month1 |
date1(3) = day1 |
date1(4) = hour1 |
date1(5) = 0 |
date2(1) = year2 |
date2(2) = month2 |
date2(3) = day2 |
date2(4) = hour2 |
date2(5) = 0 |
call timediff(date2,date1,diff) |
c Write it to screen |
write(*,'(i6)') nint(diff) |
goto 111 |
110 continue |
c Close datefile |
close(10) |
c --------------------------------------------------------------------- |
c Convert times to a list of dates |
c --------------------------------------------------------------------- |
if ( mode.ne.'-todate' ) goto 120 |
c Extract reference date |
read(refdate( 1: 4),*) year1 |
read(refdate( 5: 6),*) month1 |
read(refdate( 7: 8),*) day1 |
read(refdate(10:11),*) hour1 |
read(refdate(12:13),*) min1 |
c Loop through the date file |
open(10,file=datefile) |
121 read(10,*,end=120) time |
c Calculate the new date |
date1(1) = year1 |
date1(2) = month1 |
date1(3) = day1 |
date1(4) = hour1 |
date1(5) = 0 |
call newdate(date1,time,date2) |
call datestring(datestr,date2(1),date2(2),date2(3),date2(4) ) |
c Write it to screen |
write(*,'(a11)') trim(datestr) |
goto 121 |
120 continue |
c Close datefile |
close(10) |
c --------------------------------------------------------------------- |
c Extract all dates which are only in one datefile |
c --------------------------------------------------------------------- |
if ( mode.ne.'-onlyin1' ) goto 130 |
c Set reference date |
date1(1) = 1979 |
date1(2) = 1 |
date1(3) = 1 |
date1(4) = 0 |
date1(5) = 0 |
c Open the output file |
if ( datefile.ne.'/dev/stdout') then |
open(30,file=datefile) |
endif |
c Loop through the input date files |
open(10,file=datefile1) |
open(20,file=datefile2) |
c Loop through both date files |
state = 0 |
oldstamp1 = 0 |
oldstamp2 = 0 |
131 if ( (state.eq.1).or.(state.eq.0) ) then |
read(10,*,end=133) datestr1 |
endif |
if ( (state.eq.2).or.(state.eq.0) ) then |
read(20,*,end=130) datestr2 |
endif |
c Get time stamp for both date strings |
if ( (state.eq.1).or.(state.eq.0) ) then |
read(datestr1( 1: 4),*) year2 |
read(datestr1( 5: 6),*) month2 |
read(datestr1( 7: 8),*) day2 |
read(datestr1(10:11),*) hour2 |
date2(1) = year2 |
date2(2) = month2 |
date2(3) = day2 |
date2(4) = hour2 |
date2(5) = 0 |
call timediff(date2,date1,diff) |
timestamp1 = nint( diff ) |
if ( timestamp1.lt.oldstamp1 ) then |
print*,' ERROR: datelist must be ordered ',trim(datefile1) |
stop |
else |
oldstamp1 = timestamp1 |
endif |
endif |
if ( (state.eq.1).or.(state.eq.0) ) then |
read(datestr2( 1: 4),*) year2 |
read(datestr2( 5: 6),*) month2 |
read(datestr2( 7: 8),*) day2 |
read(datestr2(10:11),*) hour2 |
date2(1) = year2 |
date2(2) = month2 |
date2(3) = day2 |
date2(4) = hour2 |
date2(5) = 0 |
call timediff(date2,date1,diff) |
timestamp2 = nint( diff ) |
if ( timestamp2.lt.oldstamp2 ) then |
print*,' ERROR: datelist must be ordered ',trim(datefile2) |
stop |
else |
oldstamp2 = timestamp2 |
endif |
endif |
c Write output and set new state |
if ( timestamp1.gt.timestamp2 ) then |
state = 2 |
c print*,trim(datestr1)//'.'//trim(datestr2)//' >' |
else if ( timestamp1.lt.timestamp2 ) then |
state = 1 |
if ( datefile.ne.'/dev/stdout') then |
write(30,*) datestr1 |
else |
write(*,*) datestr1 |
endif |
c print*,trim(datestr1)//'.'//trim(datestr2)//' -> out' |
else if (timestamp1.eq.timestamp2 ) then |
state = 0 |
c print*,trim(datestr1)//'.'//trim(datestr2)//' =' |
endif |
goto 131 |
c Exit point for parallel reading through files |
130 continue |
c Write remaining part of datefile 1 |
132 continue |
read(10,*,end=133) datestr1 |
if ( datefile.ne.'/dev/stdout') then |
write(30,*) datestr1 |
else |
write(*,*) datestr1 |
endif |
goto 132 |
133 continue |
c Close datefile |
close(10) |
close(20) |
close(30) |
c --------------------------------------------------------------------- |
c End |
c --------------------------------------------------------------------- |
end |
/tags/1.0/goodies/datelist.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = datelist.o ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/times.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
datelist: $(OBJS) |
${F77} -o datelist $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/datelist.sh |
---|
0,0 → 1,268 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp datelist short |
echo |
exit 0 |
endif |
# Handle fixed arguments |
set filename = $1 |
set mode = $2 |
# Redirect output to screen if requested |
if ( "${filename}" == "stdout" ) set filename="/dev/stdout" |
if ( "${filename}" == "screen" ) set filename="/dev/stdout" |
# Handle optional arguments |
set interval = "6" |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -create |
set startdate = $argv[2] |
set finaldate = $argv[3] |
shift; |
shift; |
breaksw |
case -indir |
set dirname = $argv[2] |
shift; |
breaksw |
case -next |
set date = $argv[2] |
shift; |
breaksw |
case -prev |
set date = $argv[2] |
shift; |
breaksw |
case -isin |
set date = $argv[2] |
shift; |
breaksw |
case -interval |
set interval = $argv[2] |
shift; |
breaksw |
case -overlap |
set file1 = $argv[2] |
set file2 = $argv[3] |
shift; |
shift; |
breaksw |
case -onlyin1 |
set file1 = $argv[2] |
set file2 = $argv[3] |
shift; |
shift; |
breaksw |
case -onlyin2 |
set file1 = $argv[2] |
set file2 = $argv[3] |
shift; |
shift; |
breaksw |
case -totime |
set refdate = $argv[2] |
shift; |
breaksw |
case -todate |
set refdate = $argv[2] |
shift; |
breaksw |
endsw |
shift; |
end |
# Mode: -create startdate finaldate |
if ( "${mode}" == "-create" ) then |
\rm -f datelist.param |
echo \"${filename}\" > datelist.param |
echo \"${mode}\" >> datelist.param |
echo \"${startdate}00\" >> datelist.param |
echo \"${finaldate}00\" >> datelist.param |
echo ${interval} >> datelist.param |
${LAGRANTO}/goodies/datelist |
endif |
# Mode: -first |
if ( "${mode}" == "-first" ) then |
head -1 ${filename} |
endif |
# Mode: -last |
if ( "${mode}" == "-last" ) then |
tail -1 ${filename} |
endif |
# Mode: -ndates |
if ( "${mode}" == "-ndates" ) then |
wc -l ${filename} | awk '{ print $1}' |
endif |
# Mode: -timerange |
if ( "${mode}" == "-timerange" ) then |
set firstdate = `head -1 ${filename}` |
set finaldate = `tail -1 ${filename}` |
${LAGRANTO}/goodies/gettidiff ${finaldate} ${firstdate} |
endif |
# Mode: -indir {directory name} |
if ( "${mode}" == "-indir" ) then |
ls -1 ${dirname} | perl -ne 'print if s/.*([0-9]{8}_[0-9]{2}).*/\1/' | sort | uniq >! ${filename} |
endif |
# Mode: -next |
if ( "${mode}" == "-next" ) then |
set last = `tail -1 ${filename}` |
if ( "${date}" != "${last}" ) then |
set next = `sed -n "/${date}/{n;p;}" ${filename}` |
echo ${next} |
else |
echo "nil" |
endif |
endif |
# Mode: -prev |
if ( "${mode}" == "-prev" ) then |
set first = `head -1 ${filename}` |
if ( "${date}" != "${first}" ) then |
set prev = `sed -n "/${date}/{g;p;};h" ${filename}` |
echo ${prev} |
else |
echo "nil" |
endif |
endif |
# Mode: -isin |
if ( "${mode}" == "-isin" ) then |
set flag = `sed -n "/${date}/p" ${filename}` |
if ( "${flag}" != "" ) then |
echo "1" |
else |
echo "0" |
endif |
endif |
# Mode: -overlap |
if ( "${mode}" == "-overlap" ) then |
if ( "${filename}" != "/dev/stdout" ) then |
set outfile = ${filename}.$$ |
\rm -f ${outfile} |
grep -f ${file1} ${file2} > ${outfile} |
\mv ${outfile} ${filename} |
else |
grep -f ${file1} ${file2} |
endif |
endif |
# Mode: -onlyin1 |
if ( "${mode}" == "-onlyin1" ) then |
\rm -f datelist.param |
echo \"${filename}\" > datelist.param |
echo \"${mode}\" >> datelist.param |
echo \"${file1}\" >> datelist.param |
echo \"${file2}\" >> datelist.param |
${LAGRANTO}/goodies/datelist |
endif |
# Mode: -onlyin2 |
if ( "${mode}" == "-onlyin2" ) then |
set outfile1 = "tmp1.$$" |
set outfile2 = "tmp2.$$" |
\rm -f ${outfile1} |
\rm -f ${outfile2} |
grep -f ${file2} ${file1} >! ${outfile1} |
grep -vf ${outfile1} ${file2} >! ${outfile2} |
if ( "${filename}" != "/dev/stdout" ) then |
\mv ${outfile2} ${filename} |
else |
cat ${outfile2} |
endif |
\rm -f ${outfile1} |
\rm -f ${outfile2} |
endif |
# Mode: -totime |
if ( "${mode}" == "-totime" ) then |
\rm -f datelist.param |
echo \"${filename}\" > datelist.param |
echo \"${mode}\" >> datelist.param |
echo \"${refdate}00\" >> datelist.param |
${LAGRANTO}/goodies/datelist |
endif |
# Mode: -todate |
if ( "${mode}" == "-todate" ) then |
\rm -f datelist.param |
echo \"${filename}\" > datelist.param |
echo \"${mode}\" >> datelist.param |
echo \"${refdate}00\" >> datelist.param |
${LAGRANTO}/goodies/datelist |
endif |
# Mode: -randsample |
if ( "${mode}" == "-randsample" ) then |
\rm -f datelist.param |
echo \"${filename}\" > datelist.param |
echo \"${mode}\" >> datelist.param |
echo ${randsample} >> datelist.param |
${LAGRANTO}/goodies/datelist |
endif |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/difference.f |
---|
0,0 → 1,326 |
PROGRAM difference |
c *********************************************************************** |
c * Get the difference between tow trajectory files * |
c * Michael Sprenger / Spring, summer, autumn 2010 * |
c *********************************************************************** |
implicit none |
c ---------------------------------------------------------------------- |
c Declaration of variables |
c ---------------------------------------------------------------------- |
c Field name and mode for difference calculation |
character*80 mode ! Difference mode |
character*80 fieldname ! Name of differencing |
c Input and output format for trajectories (see iotra.f) |
character*80 inpfile1 ! Input filename 1 |
character*80 inpfile2 ! Input filename 2 |
character*80 outfile ! Output filename |
c Input trajectories |
integer ntra1 ,ntra2 ! Number of trajectories |
integer ntim1 ,ntim2 ! Number of times |
integer ncol1 ,ncol2 ! Number of columns |
real,allocatable, dimension (:,:,:) :: trainp1 ,trainp2 ! Trajectories (ntra,ntim,ncol) |
character*80 vars1(100) ,vars2(100) ! Variable names |
integer refdate1(6),refdate2(6) ! Reference date |
c Output/comparison trajectory |
integer ntra ! Number of trajectories |
integer ntim ! Number of times |
integer ncol ! Number of columns |
real,allocatable, dimension (:,:,:) :: traout ! Trajectories (ntra,ntim,ncol) |
character*80 vars(100) ! Variable names |
integer refdate(6) ! Reference date |
c Auxiliary variables |
integer inpmode1,inpmode2 |
integer outmode |
integer stat |
integer fid |
integer i,j,k |
integer ind1,ind2 |
integer isok |
character ch |
real,allocatable, dimension (:) :: diff |
integer outind |
c Externals |
real,external :: sdis |
c ---------------------------------------------------------------------- |
c Preparations |
c ---------------------------------------------------------------------- |
c Read parameters |
open(10,file='difference.param') |
read(10,*) inpfile1 |
read(10,*) inpfile2 |
read(10,*) outfile |
read(10,*) ntra1,ntim1,ncol1 |
read(10,*) ntra2,ntim2,ncol2 |
read(10,*) mode |
read(10,*) fieldname |
close(10) |
c Determine the formats |
call mode_tra(inpmode1,inpfile1) |
if (inpmode1.eq.-1) inpmode1=1 |
call mode_tra(inpmode2,inpfile2) |
if (inpmode2.eq.-1) inpmode2=1 |
call mode_tra(outmode,outfile) |
if (outmode.eq.-1) outmode=1 |
c Set number of trajectories for output |
if ( ntra1.lt.ntra2) then |
ntra = ntra1 |
else |
ntra = ntra2 |
endif |
c Set number of times for output |
if ( mode.eq.'single' ) then |
ntim = ntim1 |
else |
ntim = 1 |
endif |
c Set the column names for output |
if ( fieldname.eq.'LATLON') then |
ncol = 1 + 3 + 3 + 1 |
vars(1) = 'time' |
vars(2) = 'lon[1]' |
vars(3) = 'lat[1]' |
vars(4) = 'p[1]' |
vars(5) = 'lon[2]' |
vars(6) = 'lat[2]' |
vars(7) = 'p[2]' |
vars(8) = 'SDIS' |
else |
ncol = 1 + 3 + 3 + 2 + 1 |
vars( 1) = 'time' |
vars( 2) = 'lon[1]' |
vars( 3) = 'lat[1]' |
vars( 4) = 'p[1]' |
vars( 5) = 'lon[2]' |
vars( 6) = 'lat[2]' |
vars( 7) = 'p[2]' |
vars( 8) = trim(fieldname)//'[1]' |
vars( 9) = trim(fieldname)//'[2]' |
vars(10) = trim(fieldname)//'[1-2]' |
endif |
c Allocate memory |
allocate(trainp1(ntra1,ntim1,ncol1),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array trainp1 ***' |
allocate(trainp2(ntra2,ntim2,ncol2),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array trainp2 ***' |
allocate(traout(ntra,ntim,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array traout ***' |
allocate(diff(ntim1),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array diff ***' |
c Read inpufiles |
call ropen_tra(fid,inpfile1,ntra1,ntim1,ncol1, |
> refdate1,vars1,inpmode1) |
call read_tra (fid,trainp1,ntra1,ntim1,ncol1,inpmode1) |
call close_tra(fid,inpmode1) |
call ropen_tra(fid,inpfile2,ntra2,ntim2,ncol2, |
> refdate2,vars2,inpmode2) |
call read_tra (fid,trainp2,ntra2,ntim2,ncol2,inpmode2) |
call close_tra(fid,inpmode2) |
c Check dimensions of the two trajectory files (#tim hard check) |
if (ntim1.ne.ntim2) then |
print*,'Trajectoy files have different time dimensions... Stop' |
stop |
endif |
c Check dimensions of the two trajectory files (#tra soft check) |
if (ntra1.ne.ntra2) then |
print*,'Differing number of trajectories... proceed [y/n]' |
read*,ch |
if (ch.eq.'n') stop |
endif |
c Check whether difference field is available on both files |
if ( fieldname.ne.'LATLON') then |
ind1 = 0 |
ind2 = 0 |
do i=1,ncol |
if ( fieldname.eq.vars1(i) ) ind1 = i |
if ( fieldname.eq.vars2(i) ) ind2 = i |
enddo |
if ( (ind1.eq.0).or.(ind2.eq.0) ) then |
print*,'Field ',trim(fieldname),' not available... Stop' |
stop |
endif |
endif |
c Check reference dates (soft check) |
isok = 1 |
do i=1,6 |
if ( refdate1(i).ne.refdate2(i) ) isok = 0 |
enddo |
if ( isok.eq.0 ) then |
print*,'Warning: reference dates differ... proceed [y/n]' |
read*,ch |
if (ch.eq.'n') stop |
endif |
c Check trajectory times (soft check) |
isok = 1 |
do i=1,ntim |
if ( trainp1(1,i,1).ne.trainp2(1,i,1) ) isok = 0 |
enddo |
if ( isok.eq.0 ) then |
print*,'Warning: trajectory times differ... proceed [y/n]' |
read*,ch |
if (ch.eq.'n') stop |
endif |
c Copy reference date to output |
do i=1,6 |
refdate(i) = refdate1(i) |
enddo |
c ---------------------------------------------------------------------- |
c Calculate the difference (depending on mode) |
c ---------------------------------------------------------------------- |
c Loop over all trajectories |
do i=1,ntra |
c Calculate difference for all times |
do j=1,ntim1 |
c Calculate the difference (distance or absolute value) |
if (fieldname.eq.'LATLON') then |
diff(j) = sdis( trainp1(i,j,2),trainp1(i,j,3), |
> trainp2(i,j,2),trainp2(i,j,3) ) |
else |
diff(j) = abs(trainp1(i,j,ind1) - trainp2(i,j,ind2)) |
endif |
enddo |
c Save output for each time |
if ( mode.eq.'single' ) then |
do j=1,ntim |
if ( fieldname.eq.'LATLON' ) then |
traout(i,j, 1) = trainp1(i,j,1) ! time |
traout(i,j, 2) = trainp1(i,j,2) ! lon[1] |
traout(i,j, 3) = trainp1(i,j,3) ! lat[1] |
traout(i,j, 4) = trainp1(i,j,4) ! p[1] |
traout(i,j, 5) = trainp2(i,j,2) ! lon[2] |
traout(i,j, 6) = trainp2(i,j,3) ! lat[2] |
traout(i,j, 7) = trainp2(i,j,4) ! p[2] |
traout(i,j, 8) = diff(j) ! SDIS(j) |
else |
traout(i,j, 1) = trainp1(i,j,1) ! time |
traout(i,j, 2) = trainp1(i,j,2) ! lon[1] |
traout(i,j, 3) = trainp1(i,j,3) ! lat[1] |
traout(i,j, 4) = trainp1(i,j,4) ! p[1] |
traout(i,j, 5) = trainp2(i,j,2) ! lon[2] |
traout(i,j, 6) = trainp2(i,j,3) ! lat[2] |
traout(i,j, 7) = trainp2(i,j,4) ! p[2] |
traout(i,j, 8) = trainp1(i,j,ind1) ! field[1] |
traout(i,j, 9) = trainp2(i,j,ind2) ! field[2] |
traout(i,j,10) = diff(j) ! SDIS(j) |
endif |
enddo |
c Save only maximum |
elseif ( mode.eq.'max') then |
outind = 1 |
do j=2,ntim1 |
if ( diff(j).gt.diff(outind) ) outind = j |
enddo |
if ( fieldname.eq.'LATLON' ) then |
traout(i,1, 1) = trainp1(i,outind,1) ! time |
traout(i,1, 2) = trainp1(i,outind,2) ! lon[1] |
traout(i,1, 3) = trainp1(i,outind,3) ! lat[1] |
traout(i,1, 4) = trainp1(i,outind,4) ! p[1] |
traout(i,1, 5) = trainp2(i,outind,2) ! lon[2] |
traout(i,1, 6) = trainp2(i,outind,3) ! lat[2] |
traout(i,1, 7) = trainp2(i,outind,4) ! p[2] |
traout(i,1, 8) = diff(outind) ! SDIS |
else |
traout(i,1, 1) = trainp1(i,outind,1) ! time |
traout(i,1, 2) = trainp1(i,outind,2) ! lon[1] |
traout(i,1, 3) = trainp1(i,outind,3) ! lat[1] |
traout(i,1, 4) = trainp1(i,outind,4) ! p[1] |
traout(i,1, 5) = trainp2(i,outind,2) ! lon[2] |
traout(i,1, 6) = trainp2(i,outind,3) ! lat[2] |
traout(i,1, 7) = trainp2(i,outind,4) ! p[2] |
traout(i,1, 8) = trainp1(i,outind,ind1) ! field[1] |
traout(i,1, 9) = trainp2(i,outind,ind2) ! field[2] |
traout(i,1,10) = diff(outind) ! SDIS(j) |
endif |
endif |
enddo |
c ---------------------------------------------------------------------- |
c Write output |
c ---------------------------------------------------------------------- |
c Write output file |
call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode) |
call write_tra(fid,traout,ntra,ntim,ncol,outmode) |
call close_tra(fid,outmode) |
end |
c *********************************************************************** |
c * Subroutines * |
c *********************************************************************** |
c ---------------------------------------------------------------------- |
c Spherical distance |
c ---------------------------------------------------------------------- |
real function sdis(xp,yp,xq,yq) |
c |
c calculates spherical distance (in km) between two points given |
c by their spherical coordinates (xp,yp) and (xq,yq), respectively. |
c |
real pi180 |
parameter (pi180=3.14159/180.) |
real re |
parameter (re=6370.) |
real degkm |
parameter (degkm=111.1775) |
real xp,yp,xq,yq,arg |
if ( (abs(xp-xq).gt.0.05).and.(abs(yp-yq).gt.0.05) ) then |
arg=sin(pi180*yp)*sin(pi180*yq)+ |
> cos(pi180*yp)*cos(pi180*yq)*cos(pi180*(xp-xq)) |
if (arg.lt.-1.) arg=-1. |
if (arg.gt.1.) arg=1. |
sdis=re*acos(arg) |
else |
sdis= (yp-yq)**2 + ( (xp-xq) * cos( pi180*0.5*(yp+yq) ) )**2 |
sdis = deg2km * sqrt(sdis) |
endif |
end |
/tags/1.0/goodies/difference.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = difference.o ${LAGRANTO}/lib//iotra.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
difference: $(OBJS) |
${F77} -o difference $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/difference.sh |
---|
0,0 → 1,62 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp difference short |
echo |
exit 0 |
endif |
# Get input and output trajectory file |
set inpfile1 = $1 |
set inpfile2 = $2 |
set outfile = $3 |
set fieldname = $4 |
# Handle optional arguments |
set mode = "single" |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -single |
set mode = "single" |
breaksw |
case -max |
set mode = "max" |
breaksw |
endsw |
shift; |
end |
# Get the dimensions of the trajectory files |
set dim1=`${LAGRANTO}/goodies/trainfo.sh ${inpfile1} dim` |
set dim2=`${LAGRANTO}/goodies/trainfo.sh ${inpfile2} dim` |
# Prepare parameter file and run program |
\rm -f difference.param |
echo \"${inpfile1}\" >! difference.param |
echo \"${inpfile2}\" >> difference.param |
echo \"${outfile}\" >> difference.param |
echo ${dim1} >> difference.param |
echo ${dim2} >> difference.param |
echo \"${mode}\" >> difference.param |
echo \"${fieldname}\" >> difference.param |
${LAGRANTO}/goodies/difference |
# Make clean |
#\rm -f difference.param |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/evalmod.f90 |
---|
0,0 → 1,931 |
module evaluate |
! The user can assign values to parameters that can be used in expressions with |
! the subroutine defparam. The calling syntax is |
! |
! call defparam(symbol,value) or call defparam(symbol,expr) |
! |
! where symbol is the desired parameter name; value is a real, integer, or |
! complex variable (single or double precision); and expr is a string |
! containing an expression to be evaluated. The value obtained by evaluating the |
! expression expr is associated with the parameter symbol. Parameter names must |
! begin with a letter (a-z, A-Z) and must not be longer than 24 characters. |
! Parameter names are not case dependent. |
! |
! An expression can be evaluated with the subroutine evalexpr. The calling |
! syntax is |
! |
! call evalexpr(expr,value) |
! |
! where expr is a string containing the expression to be evaluated; value is the |
! result (single or double precision real, complex or integer). The |
! expression can contain the arithmetic operations +, -, *, /, or ^ as well as |
! the functions sin, cos, tan, log, ln, abs, exp, sqrt, real, imag, conjg, and |
! ang (the function ang calculates the phase angle of its complex argument). The |
! expression can also contain numerical values and previously defined parameters |
! Grouping by nested levels of parentheses is also allowed. The parameters pi |
! and i (imaginary unit) are predefined. Complex numbers can be entered as a+i*b |
! if the parameter i has not been redefined by the user. Complex numbers can also |
! be entered using complex(a,b). |
! Example expression: |
! |
! conjg(((cos(x) + sqrt(a+i*b))^2+complex(ln(1.6e-4),20))/2) |
! |
! An equation of the form <symbol> = <expression> can be evaluated using the |
! subroutine evaleqn. The calling syntax is |
! |
! call evaleqn(eqn) |
! |
! where eqn is a string containing the equation. The right-hand-side of the |
! equation is evaluated and assigned to the symbol given by the left-hand-side. |
! |
! The value assigned to a symbol can be retrieved using the subroutine getparam. |
! The calling syntax is |
! |
! call getparam(sym,value) |
! |
! where sym is a symbol string; value is a numeric variable (any of the six |
! standard types). |
! |
! The symbols and their values in the symbol table can be listed using the |
! subroutine listvar. The variable ierr is always available following a call |
! to any of the above subroutines and is zero if there were no errors. The |
! possible nonzero values for ierr are |
! |
! 1 Expression empty |
! 2 Parentheses don't match |
! 3 Number string does not correspond to a valid number |
! 4 Undefined symbol |
! 5 Less than two operands for binary operation |
! 6 No operand for unary plus or minus operators |
! 7 No argument(s) for function |
! 8 Zero or negative real argument for logarithm |
! 9 Negative real argument for square root |
! 10 Division by zero |
! 11 Improper symbol format |
! 12 Missing operator |
! 13 Undefined function |
! 14 Argument of tangent function a multiple of pi/2 |
! |
use precision |
use strings |
save |
private |
public :: valuep,evalexpr,defparam,evaleqn,getparam,listvar,ierr |
type item |
character(len=24):: char |
character :: type |
end type item |
type param |
character (len=24):: symbol |
complex(kc8):: value |
end type param |
interface defparam |
module procedure strdef ! value given by expression |
module procedure valdef_dc ! Double precision complex value |
module procedure valdef_sc ! Single precision complex value |
module procedure valdef_dr ! Double precision real value |
module procedure valdef_sr ! Single precision real value |
module procedure valdef_di ! Double precision integer value |
module procedure valdef_si ! Single precision integer value |
end interface |
interface evalexpr |
module procedure evalexpr_dc ! Double precision complex result |
module procedure evalexpr_sc ! Single precision complex result |
module procedure evalexpr_dr ! Double precision real result |
module procedure evalexpr_sr ! Single precision real result |
module procedure evalexpr_di ! Double precision integer result |
module procedure evalexpr_si ! Single precision integer result |
end interface |
interface getparam |
module procedure getparam_dc ! Double precision complex result |
module procedure getparam_sc ! Single precision complex result |
module procedure getparam_dr ! Double precision real result |
module procedure getparam_sr ! Single precision real result |
module procedure getparam_di ! Double precision integer result |
module procedure getparam_si ! Single precision integer result |
end interface |
integer,parameter :: numtok=100 ! Maximum number of tokens |
type(param) :: params(100) ! Symbol table |
integer :: nparams=0,itop,ibin |
complex(kc8) :: valstack(numtok) ! Stack used in evaluation of expression |
type(item):: opstack(numtok) ! Operator stack used in conversion to postfix |
integer :: ierr ! Error flag |
!********************************************************************** |
contains |
!********************************************************************** |
SUBROUTINE EVALEXPR_DC(expr,val) ! Evaluate expression expr for |
! val double precision complex |
character (len=*),intent(in) :: expr |
complex(kc8) :: val |
character (len=len(expr)+1) :: tempstr |
character :: cop |
integer :: isp(numtok) ! On stack priority of operators in opstack |
integer :: lstr |
complex(kc8) :: cval,oper1,oper2 |
real(kr8) :: valr,vali |
type(item):: token(numtok) ! List of tokens ( a token is an operator or |
! operand) in postfix order |
type(item) :: x,junk,tok |
ierr=0 |
token(1:)%char=' ' |
if(nparams == 0) then ! Initialize symbol table |
params(1)%symbol='PI' |
params(1)%value=(3.14159265358979_kr8,0.0_kr8) |
params(2)%symbol='I' |
params(2)%value=(0.0_kr8,1.0_kr8) |
nparams=2 |
end if |
if(len_trim(expr) == 0) then ! Expression empty |
ierr=1 |
write(*,*) 'Error: expression being evaluated is empty' |
return |
end if |
tempstr=adjustl(expr) |
call removesp(tempstr) ! Removes spaces, tabs, and control characters |
! **************************************************************************** |
! STEP 1: Convert string to token array. Each token is either an operator or |
! an operand. Token array will be in postfix (reverse Polish) order. |
!***************************************************************************** |
ntok=0 |
ibin=0 |
itop=0 |
do |
lstr=len_trim(tempstr) |
call get_next_token(tempstr(1:lstr),tok,icp,insp) |
select case(tok%type) |
case('S') |
ntok=ntok+1 |
token(ntok)=tok |
case('E') |
do |
if(itop < 1)exit |
call popop(x) ! Output remaining operators on stack |
ntok=ntok+1 |
token(ntok)=x |
end do |
ntok=ntok+1 |
token(ntok)=tok |
exit |
case('R') ! Token is right parenenthesis |
do |
if(opstack(itop)%type == 'L') exit ! Output operators on stack down |
call popop(x) ! to left parenthesis |
ntok=ntok+1 |
token(ntok)=x |
end do |
call popop(junk) ! Remove left parenthesis from stack |
if(opstack(itop)%type == 'F') then ! Output function name if present |
call popop(x) |
ntok=ntok+1 |
token(ntok)=x |
end if |
case('D') ! Token is comma |
do |
if(opstack(itop)%type == 'L') exit ! Output operators on stack down |
call popop(x) ! to left parenthesis |
ntok=ntok+1 |
token(ntok)=x |
end do |
case('U','B','L','F') ! Token is operator, left parenthesis or function name |
do |
if(isp(itop) < icp) exit ! Output operators on stack having |
call popop(x) ! an instack priority that is |
ntok=ntok+1 ! greater than or equal to the |
token(ntok)=x ! priority of the incoming operator |
end do |
call pushop(tok) ! Put incoming operator on stack |
isp(itop)=insp |
end select |
end do |
isum=0 ! Error check for matching parentheses |
do i=1,ntok |
if(token(i)%type == 'L' ) isum=isum+1 |
if(token(i)%type == 'R' ) isum=isum-1 |
end do |
if(isum /= 0) then |
ierr=2 |
write(*,*) 'Error in the evaluation of the expression ',trim(expr) |
write(*,*) "Parentheses don't match" |
write(*,*) |
return |
end if |
!***************************************************************************** |
! STEP 2: Evaluate token string in postfix order |
!***************************************************************************** |
itop=0 |
do i=1,ntok |
x=token(i) |
select case(x%type) |
case('E') ! Token is end token |
if(itop>1) then |
ierr=12 |
write(*,*) 'Error: missing operator in expression ',trim(expr) |
write(*,*) |
return |
end if |
call popval(val) ! Final result left on stack of values |
exit |
case('S') ! Token is operand |
call valuep(x%char,cval) ! Evaluate operand |
if(ierr/=0) return |
call pushval(cval) ! Put value of operand on stack |
case('B') ! Token is a binary operator |
if(itop < 2) then |
ierr=5 |
write(*,*) 'Error in evaluation of expression ',trim(expr) |
write(*,*) 'Less than two operands for binary operator '& |
,trim(x%char) |
write(*,*) |
return |
end if |
call popval(oper1) ! Pull off top two values from stack |
call popval(oper2) |
select case(trim(x%char)) ! Perform operation on values |
case('^') |
cval=oper2**oper1 |
case('*') |
cval=oper2*oper1 |
case('/') |
if(oper1 == (0._kr8,0._kr8)) then |
ierr=10 |
write(*,*) 'Error in expression ',trim(expr) |
write(*,*) 'Division by zero' |
write(*,*) |
return |
end if |
cval=oper2/oper1 |
case('+') |
cval=oper2+oper1 |
case('-') |
cval=oper2-oper1 |
end select |
call pushval(cval) ! Put result back on stack |
case('U') ! Token is unary operator |
if(itop == 0) then |
ierr=6 |
write(*,*) 'Error in expression ',trim(expr) |
write(*,*) 'No operand for unary operator ',trim(x%char) |
write(*,*) |
return |
else |
call popval(oper1) ! Pull top value off stack |
end if |
select case(trim(x%char)) ! Operate on value |
case('+') |
cval=oper1 |
case('-') |
cval=-oper1 |
end select |
call pushval(cval) ! Put result back on stack |
case('F') ! Token is a function name |
if(itop == 0) then |
ierr=7 |
write(*,*) 'Error in expression ',trim(expr) |
write(*,*) 'Missing argument(s) for function ',trim(x%char) |
write(*,*) |
return |
else |
call popval(oper1) ! Pull top value off stack |
end if |
tempstr=uppercase(x%char) |
select case(trim(tempstr)) ! Evaluate function |
case('SIN') |
cval=sin(oper1) |
case('COS') |
cval=cos(oper1) |
case('TAN') |
oper2=cos(oper1) |
if(abs(oper2) == 0.0_kr8) then |
ierr=14 |
write(*,*) 'Error: argument of tan function a multiple',& |
' of pi/2 in expression ',trim(expr) |
write(*,*) |
return |
else |
cval=sin(oper1)/oper2 |
endif |
case('SQRT') |
if(real(oper1,kr8) < 0. .and. aimag(oper1)==0.) then |
ierr=9 |
write(*,*) 'Warning: square root of negative real number',& |
' in expression ',trim(expr) |
write(*,*) |
end if |
cval=sqrt(oper1) |
case('ABS') |
cval=abs(oper1) |
case('LN') |
if(real(oper1,kr8) <= 0. .and. aimag(oper1)==0.) then |
ierr=8 |
write(*,*) 'Error: negative real or zero argument for',& |
' natural logarithm in expression ',trim(expr) |
write(*,*) |
return |
end if |
cval=log(oper1) |
case('LOG') |
if(real(oper1,kr8) <= 0. .and. aimag(oper1)==0.) then |
ierr=8 |
write(*,*) 'Error: negative real or zero argument for base',& |
'10 logarithm in expression ',trim(expr) |
write(*,*) |
return |
end if |
cval=log(oper1)/2.30258509299405_kr8 |
case('EXP') |
cval=exp(oper1) |
case('COMPLEX') |
if(itop == 0) then |
ierr=7 |
write(*,*) 'Error in expression ',trim(expr) |
write(*,*) 'Missing argument(s) for function ',trim(x%char) |
write(*,*) |
return |
else |
call popval(oper2) ! Pull second argument off stack |
end if |
valr=real(oper2,kr8) |
vali=real(oper1,kr8) |
cval=cmplx(valr,vali,kc8) |
case('CONJG') |
cval=conjg(oper1) |
case('ANG') |
cval=atan2(aimag(oper1),real(oper1,kr8)) |
case('REAL') |
cval=real(oper1,kr8) |
case('IMAG') |
cval=aimag(oper1) |
case default ! Undefined function |
ierr=13 |
write(*,*) 'Error: the function ',trim(x%char), ' is undefined',& |
' in the expression ',trim(expr) |
write(*,*) |
return |
end select |
call pushval(cval) ! Put result back on stack |
end select |
end do |
end subroutine evalexpr_dc |
!********************************************************************** |
SUBROUTINE GET_NEXT_TOKEN(str,tok,icp,isp) |
character(len=*) :: str |
character :: cop,chtemp |
type(item) :: tok |
integer :: icp |
lstr=len_trim(str) |
if(lstr == 0) then |
tok%char='#' ! Output end token |
tok%type='E' |
return |
end if |
ipos=scan(str,'+-*/^(),') ! Look for an arithmetic operator |
! + - * / ^ ( ) or , |
cop=str(ipos:ipos) |
select case (ipos) |
case(0) ! Operators not present |
ntok=ntok+1 |
tok%char=str |
tok%type='S' |
str='' |
icp=0 |
isp=0 |
case(1) |
tok%char=cop |
select case(cop) |
case('+','-') |
if(ibin==0) then |
tok%type='U' |
icp=4 |
isp=3 |
else |
tok%type='B' |
icp=1 |
isp=1 |
end if |
ibin=0 |
case('*','/') |
tok%type='B' |
icp=2 |
isp=2 |
ibin=0 |
case('^') |
tok%type='B' |
icp=4 |
isp=3 |
ibin=0 |
case('(') |
tok%type='L' |
icp=4 |
isp=0 |
ibin=0 |
case(')') |
tok%type='R' |
icp=0 |
isp=0 |
ibin=1 |
case(',') |
tok%type='D' |
icp=0 |
isp=0 |
ibin=0 |
end select |
str=str(2:) |
case(2:) |
select case(cop) |
case('(') |
tok%char=str(1:ipos-1) |
tok%type='F' |
icp=4 |
isp=0 |
ibin=0 |
str=str(ipos:) |
case('+','-') |
chtemp=uppercase(str(ipos-1:ipos-1)) |
if(is_letter(str(1:1)).eqv..true. .or. chtemp/='E') then |
tok%char=str(1:ipos-1) |
tok%type='S' |
icp=0 |
isp=0 |
ibin=1 |
str=str(ipos:) |
else |
inext=scan(str(ipos+1:),'+-*/^(),') |
if(inext==0) then |
tok%char=str |
tok%type='S' |
icp=0 |
isp=0 |
ibin=0 |
str='' |
else |
tok%char=str(1:ipos+inext-1) |
tok%type='S' |
icp=0 |
isp=0 |
ibin=1 |
str=str(ipos+inext:) |
end if |
end if |
case default |
tok%char=str(1:ipos-1) |
tok%type='S' |
icp=0 |
isp=0 |
ibin=1 |
str=str(ipos:) |
end select |
end select |
end subroutine get_next_token |
!********************************************************************** |
SUBROUTINE EVALEXPR_SC(expr,val) ! Evaluate expression expr for |
! val single precision complex |
character(len=*) :: expr |
complex(kc4) :: val |
complex(kc8) :: vald |
call evalexpr_dc(expr,vald) |
val=vald |
end subroutine evalexpr_sc |
!********************************************************************** |
SUBROUTINE EVALEXPR_SR(expr,val) ! Evaluate expression expr for |
! val single precision real |
character(len=*) :: expr |
real(kr4) :: val |
complex(kc8) :: vald |
call evalexpr_dc(expr,vald) |
val=real(vald) |
end subroutine evalexpr_sr |
!********************************************************************** |
SUBROUTINE EVALEXPR_DR(expr,val) ! Evaluate expression expr for |
! val double precision real |
character(len=*) :: expr |
real(kr8) :: val |
complex(kc8) :: vald |
call evalexpr_dc(expr,vald) |
val=real(vald,kr8) |
end subroutine evalexpr_dr |
!********************************************************************** |
SUBROUTINE EVALEXPR_SI(expr,ival) ! Evaluate expression expr for |
! ival single precision integer |
character(len=*) :: expr |
integer(ki4) :: ival |
complex(kc8) :: vald |
call evalexpr_dc(expr,vald) |
ival=nint(real(vald,kr8),ki4) |
end subroutine evalexpr_si |
!********************************************************************** |
SUBROUTINE EVALEXPR_DI(expr,ival) ! Evaluate expression expr for |
! ival double precision integer |
character(len=*) :: expr |
integer(ki8) :: ival |
complex(kc8) :: vald |
call evalexpr_dc(expr,vald) |
ival=nint(real(vald,kr8),ki8) |
end subroutine evalexpr_di |
!********************************************************************** |
SUBROUTINE VALDEF_DC(sym,val) ! Associates sym with val in symbol table, |
! val double precision complex |
character(len=*) :: sym |
character(len=len_trim(sym)) :: usym |
complex(kc8) :: val |
ierr=0 |
if(nparams == 0) then ! Initialize symbol table |
params(1)%symbol='PI' |
params(1)%value=(3.14159265358979_kr8,0.0_kr8) |
params(2)%symbol='I' |
params(2)%value=(0.0_kr8,1.0_kr8) |
nparams=2 |
end if |
! Assign val to sym if sym is already in symbol table |
usym=uppercase(sym) |
if(is_letter(sym(1:1)).eqv..false. .or. len_trim(sym)>24) then |
ierr=11 |
write(*,*) 'Error: symbol ',trim(sym),' has improper format' |
write(*,*) |
return |
end if |
do i=1,nparams |
if(trim(usym)==trim(params(i)%symbol)) then |
params(i)%value=val |
return |
end if |
end do |
nparams=nparams+1 ! Otherwise assign val to new symbol sym |
params(nparams)%symbol=usym |
params(nparams)%value=val |
end subroutine valdef_dc |
!********************************************************************** |
SUBROUTINE VALDEF_SC(sym,val) ! Associates sym with val in symbol table, |
! val single precision complex |
character(len=*) :: sym |
complex(kc4) :: val |
complex(kc8) :: vald |
vald=val |
call valdef_dc(sym,vald) |
end subroutine valdef_sc |
!********************************************************************** |
SUBROUTINE VALDEF_DR(sym,val) ! Associates sym with val in symbol table, |
! val double precision real |
character(len=*) :: sym |
real(kr8) :: val |
complex(kc8) :: vald |
vald=cmplx(val,0.0_kr8,kc8) |
call valdef_dc(sym,vald) |
end subroutine valdef_dr |
!********************************************************************** |
SUBROUTINE VALDEF_SR(sym,val) ! Associates sym with val in symbol table, |
! val single precision real |
character(len=*) :: sym |
real(kr4) :: val |
complex(kc8) :: vald |
vald=cmplx(val,0.0,kc8) |
call valdef_dc(sym,vald) |
end subroutine valdef_sr |
!********************************************************************** |
SUBROUTINE VALDEF_DI(sym,ival) ! Associates sym with ival in symbol table, |
! ival double precision integer |
character(len=*) :: sym |
integer(ki8) :: ival |
complex(kc8) :: vald |
vald=cmplx(real(ival,kr8),0.0_kr8,kc8) |
call valdef_dc(sym,vald) |
end subroutine valdef_di |
!********************************************************************** |
SUBROUTINE VALDEF_SI(sym,ival) ! Associates sym with ival in symbol table, |
! ival single precision integer |
character(len=*) :: sym |
integer(ki4) :: ival |
complex(kc8) :: vald |
vald=cmplx(real(ival,kr8),0.0,kc8) |
call valdef_dc(sym,vald) |
end subroutine valdef_si |
!********************************************************************** |
SUBROUTINE STRDEF(sym,expr) ! Associates sym with the value of the |
! expression expr |
character(len=*) :: sym,expr |
complex(kc8) :: val |
if(nparams == 0) then ! Initialize symbol table |
params(1)%symbol='PI' |
params(1)%value=(3.14159265358979_kr8,0.0_kr8) |
params(2)%symbol='I' |
params(2)%value=(0.0_kr8,1.0_kr8) |
nparams=2 |
end if |
call evalexpr_dc(expr,val) ! val is value of expression expr |
if(ierr==0 .or. ierr==9) then |
call valdef_dc(sym,val) ! Assign val to symbol sym |
end if |
end subroutine strdef |
!********************************************************************** |
SUBROUTINE VALUEP(xinchar,cval) ! Finds double precision complex value |
! corresponding to number string xinchar |
! or value in symbol table corresponding |
! to symbol name xinchar. |
character (len=*):: xinchar |
complex(kc8) :: cval |
real(kr8) :: rval |
ierr=0 |
if(is_letter(xinchar(1:1)).eqv..true.) then ! xinchar is a symbol |
call getparam(xinchar,cval) |
else ! xinchar is a number string |
call value(xinchar,rval,ios) ! rval is the value of xinchar |
if(ios > 0) then |
ierr=3 |
write(*,*) 'Error: number string ',trim(xinchar),' does not correspond to a valid number' |
write(*,*) |
end if |
cval=cmplx(rval,0.0_kr8,kc8) |
return |
end if |
end subroutine valuep |
!********************************************************************** |
SUBROUTINE PUSHOP(op) ! Puts an operator on operator stack |
type(item):: op |
itop=itop+1 |
if(itop > numtok) then |
write(*,*) 'Error: operator stack overflow in evaluation of expression' |
write(*,*) |
return |
end if |
opstack(itop)=op |
end subroutine pushop |
SUBROUTINE POPOP(op) ! Takes top operator of operator stack and assigns it to op |
type(item):: op |
op=opstack(itop) |
itop=itop-1 |
end subroutine popop |
SUBROUTINE PUSHVAL(val) ! Puts value on value stack |
complex(kc8) :: val |
itop=itop+1 |
if(itop > numtok) then |
write(*,*) 'Error: value stack overflow in evaluation of expression' |
write(*,*) |
return |
end if |
valstack(itop)=val |
end subroutine pushval |
SUBROUTINE POPVAL(val) ! Takes top value off value stack and assigns it to val |
complex(kc8) :: val |
val=valstack(itop) |
itop=itop-1 |
end subroutine popval |
!********************************************************************** |
SUBROUTINE GETPARAM_DC(sym,var) ! Find double precision complex value var |
! corresponding to symbol sym |
character(len=*) :: sym |
character(len=len_trim(sym)) :: usym |
complex(kc8) :: var |
ierr=0 |
sym=adjustl(sym) |
if(is_letter(sym(1:1)).eqv..false. .or. len_trim(sym)>24) then |
ierr=11 |
write(*,*) 'Error: symbol ',trim(sym),' has incorrect format' |
write(*,*) |
return |
end if |
ifind=0 |
usym=uppercase(sym) |
do j=1,nparams |
if(trim(usym) == trim(params(j)%symbol)) then |
var=params(j)%value |
ifind=j |
exit |
end if |
end do |
if(ifind == 0) then |
ierr=4 |
write(*,*) 'Error: symbol ',trim(sym), ' not in symbol table' |
write(*,*) |
return |
end if |
end subroutine getparam_dc |
!********************************************************************** |
SUBROUTINE GETPARAM_SC(sym,var) ! Find single precision complex value var |
! corresponding to symbol sym |
character(len=*) :: sym |
complex(kc4) :: var |
complex(kc8) :: vard |
call getparam_dc(sym,vard) |
var=vard |
end subroutine getparam_sc |
!********************************************************************** |
SUBROUTINE GETPARAM_DR(sym,var) ! Find double precision real value var |
! corresponding to symbol sym |
character(len=*) :: sym |
real(kr8) :: var |
complex(kc8) :: vard |
call getparam_dc(sym,vard) |
var=real(vard,kr8) |
end subroutine getparam_dr |
!********************************************************************** |
SUBROUTINE GETPARAM_SR(sym,var) ! Find single precision real value var |
! corresponding to symbol sym |
character(len=*) :: sym |
real(kr4) :: var |
complex(kc8) :: vard |
call getparam_dc(sym,vard) |
var=real(vard) |
end subroutine getparam_sr |
!********************************************************************** |
SUBROUTINE GETPARAM_DI(sym,ivar) ! Find double precision integer value ivar |
! corresponding to symbol sym |
character(len=*) :: sym |
integer(ki8) :: ivar |
complex(kc8) :: vard |
call getparam_dc(sym,vard) |
ivar=nint(real(vard,kr8),ki8) |
end subroutine getparam_di |
!********************************************************************** |
SUBROUTINE GETPARAM_SI(sym,ivar) ! Find single precision integer value ivar |
! corresponding to symbol sym |
character(len=*) :: sym |
integer(ki4) :: ivar |
complex(kc8) :: vard |
call getparam_dc(sym,vard) |
ivar=nint(real(vard,kr8),ki4) |
end subroutine getparam_si |
!********************************************************************** |
SUBROUTINE EVALEQN(eqn) ! Evaluate an equation |
character(len=*) :: eqn |
character(len=len(eqn)) :: args(2) |
complex(kc8) :: val |
call parse(eqn,'=',args,nargs) ! Seperate right- and left-hand-sides |
call defparam(adjustl(args(1)),args(2)) ! Evaluate right-hand-side and |
! assign to symbol on the |
! left-hand-side. |
end subroutine evaleqn |
!********************************************************************** |
SUBROUTINE LISTVAR ! List all variables and their values |
write(*,'(/a)') ' VARIABLE LIST:' |
if(nparams == 0) then ! Initialize symbol table |
params(1)%symbol='PI' |
params(1)%value=(3.14159265358979_kr8,0.0_kr8) |
params(2)%symbol='I' |
params(2)%value=(0.0_kr8,1.0_kr8) |
nparams=2 |
end if |
do i=1,nparams |
write(*,*) trim(params(i)%symbol),' = ',params(i)%value |
end do |
end subroutine listvar |
!********************************************************************** |
end module evaluate |
/tags/1.0/goodies/extract.f |
---|
0,0 → 1,724 |
PROGRAM extract |
c *********************************************************************** |
c * Extract columns of a trajectory file * |
c * Michael Sprenger / Spring, summer 2010 * |
c *********************************************************************** |
implicit none |
c ---------------------------------------------------------------------- |
c Declaration of parameters |
c ---------------------------------------------------------------------- |
c Numerical epsilon |
real eps |
parameter (eps=0.0001) |
c ---------------------------------------------------------------------- |
c Declaration of variables |
c ---------------------------------------------------------------------- |
c Extraction mode |
character*80 mode |
c Input and output format for trajectories (see iotra.f) |
character*80 inpfile ! Input filename |
character*80 outfile ! Output filename |
c Trajectories |
integer ntra_inp ! Number of trajectories |
integer ntim_inp ! Number of times |
integer ncol_inp ! Number of columns |
real,allocatable, dimension (:,:,:) :: tra_inp ! Trajectories (ntra,ntim,ncol) |
character*80 vars_inp(100) ! Variable names |
integer ntra_out ! Number of trajectories |
integer ntim_out ! Number of times |
integer ncol_out ! Number of columns |
real,allocatable, dimension (:,:,:) :: tra_out ! Trajectories (ntra,ntim,ncol) |
integer,allocatable, dimension (:) :: ind ! Index for selection |
integer,allocatable, dimension (:) :: isok ! Index for selection |
character*80 vars_out(100) ! Variable names |
real time_inp(500) ! Times of input trajectory |
real time_out(500) ! Times of output trajectory |
integer refdate(6) ! Reference date |
integer ind_time(500) ! Index for time selection |
c Auxiliary variables |
integer inpmode |
integer outmode |
integer stat |
integer fid |
integer i,j,k,n,j0,j1 |
character*80 str |
character*80 split_str(100) |
integer split_n |
integer isstr,nvars,ileft,iright |
character*80 vars(100) |
character ch |
real tmp0,tmp1 |
integer ind1 |
character*2000 linestr |
integer istr(100) |
integer nstr |
character*80 strsplit(100) |
integer flag |
c ---------------------------------------------------------------------- |
c Read and handle parameters |
c ---------------------------------------------------------------------- |
c Read parameters |
open(10,file='extract.param') |
read(10,*) inpfile |
read(10,*) outfile |
read(10,*) mode |
read(10,*) ntra_inp,ntim_inp,ncol_inp |
read(10,*) str |
close(10) |
c Split the input string |
isstr = 0 |
split_n = 0 |
do i=1,80 |
ch = str(i:i) |
if ( (isstr.eq.0).and.(ch.ne.' ') ) then |
isstr=1 |
ileft=i |
elseif ( (isstr.eq.1).and.(ch.eq.' ') ) then |
isstr = 0 |
iright = i-1 |
split_n = split_n+1 |
split_str(split_n) = str(ileft:iright) |
endif |
enddo |
c Determine the formats |
call mode_tra(inpmode,inpfile) |
if (inpmode.eq.-1) inpmode=1 |
call mode_tra(outmode,outfile) |
if ( (mode.ne.'-startf').and.(outmode.eq.-1) ) then |
outmode=1 |
endif |
c ---------------------------------------------------------------------- |
c Read input trajectories |
c ---------------------------------------------------------------------- |
c Allocate memory |
allocate(tra_inp(ntra_inp,ntim_inp,ncol_inp),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_inp ***' |
allocate(ind(ntra_inp),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array ind ***' |
allocate(isok(ntra_inp),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array isok ***' |
c Read inpufile |
fid = 10 |
call ropen_tra(fid,inpfile,ntra_inp,ntim_inp,ncol_inp, |
> refdate,vars_inp,inpmode) |
call read_tra (fid,tra_inp,ntra_inp,ntim_inp,ncol_inp,inpmode) |
call close_tra(fid,inpmode) |
c Check format |
if ( vars_inp(1).ne.'time') goto 990 |
if ( (vars_inp(2).ne.'lon').and.(vars_inp(2).ne.'xpos') ) goto 990 |
if ( (vars_inp(3).ne.'lat').and.(vars_inp(3).ne.'ypos') ) goto 990 |
if ( (vars_inp(4).ne.'p' ).and.(vars_inp(4).ne.'ppos') ) goto 990 |
c ---------------------------------------------------------------------- |
c Option -vars : Extract columns of variables |
c ---------------------------------------------------------------------- |
if ( mode.ne.'-var' ) goto 100 |
c Set the first for columns of the output |
ncol_out = 4 |
vars_out(1)='time' |
vars_out(2)='lon' |
vars_out(3)='lat' |
vars_out(4)='p' |
ind(1) =1 |
ind(2) =2 |
ind(3) =3 |
ind(4) =4 |
c Get final list of extraction columns (set number of columns) |
do i=1,split_n |
if (split_str(i).eq.'to') then |
do j=1,ncol_inp |
if ( vars_inp(j).eq.split_str(i-1) ) j0 = j + 1 |
enddo |
do j=1,ncol_inp |
if ( vars_inp(j).eq.split_str(i+1) ) j1 = j - 1 |
enddo |
do j=j0,j1 |
ncol_out = ncol_out + 1 |
vars_out(ncol_out) = vars_inp(j) |
enddo |
else |
ncol_out = ncol_out + 1 |
vars_out(ncol_out) = split_str(i) |
endif |
enddo |
c Set the dimensions of the output trajectory |
ntra_out = ntra_inp |
ntim_out = ntim_inp |
c Allocate memory for output trajectory |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Extract <time,lon,lat,p> columns |
do i=1,ntra_out |
do j=1,ntim_out |
tra_out(i,j,1) = tra_inp(i,j,1) |
tra_out(i,j,2) = tra_inp(i,j,2) |
tra_out(i,j,3) = tra_inp(i,j,3) |
tra_out(i,j,4) = tra_inp(i,j,4) |
enddo |
enddo |
c Get indices for new columns (1..4 are already ok) |
do i=5,ncol_out |
ind(i)=0 |
enddo |
do i=5,ncol_out |
do j=1,ncol_inp |
if ( vars_inp(j).eq.vars_out(i) ) ind(i) = j |
enddo |
enddo |
c Check if all selected columns are available |
do i=1,ncol_out |
if ( ind(i).eq.0 ) then |
print*,'Invalid column in ',trim(str) |
stop |
endif |
enddo |
c Extract the column |
do i=1,ntra_out |
do j=1,ntim_out |
do k=1,ncol_out |
tra_out(i,j,k) = tra_inp(i,j,ind(k)) |
enddo |
enddo |
enddo |
100 continue |
c ---------------------------------------------------------------------- |
c Option -times : Extract times of trajectories |
c ---------------------------------------------------------------------- |
if ( mode.ne.'-time' ) goto 110 |
c Set the dimension of the output trajectory |
ntim_out = 0 |
c Get the list of times for the input trajectory |
do i=1,ntim_inp |
time_inp(i) = tra_inp(1,i,1) |
enddo |
c Get final list of extraction times (set number of times) |
do i=1,split_n |
if (split_str(i).eq.'to') then |
read(split_str(i-1),*) tmp0 |
do j=1,ntim_inp |
if ( time_inp(j).eq.tmp0 ) j0 = j + 1 |
enddo |
read(split_str(i+1),*) tmp0 |
do j=1,ntim_inp |
if ( time_inp(j).eq.tmp0 ) j1 = j - 1 |
enddo |
do j=j0,j1 |
ntim_out = ntim_out + 1 |
time_out(ntim_out) = time_inp(j) |
enddo |
elseif (split_str(i).eq.'first') then |
ntim_out = ntim_out + 1 |
time_out(ntim_out) = time_inp(1) |
elseif (split_str(i).eq.'last') then |
ntim_out = ntim_out + 1 |
time_out(ntim_out) = time_inp(ntim_inp) |
else |
ntim_out = ntim_out + 1 |
read(split_str(i),*) tmp0 |
time_out(ntim_out) = tmp0 |
endif |
enddo |
c Get the indices of the selected times |
do i=1,ntim_out |
ind_time(i) = 0 |
enddo |
do i=1,ntim_out |
do j=1,ntim_inp |
if ( abs(time_out(i)-time_inp(j)).lt.eps) ind_time(i) = j |
enddo |
enddo |
do i=1,ntim_out |
if ( ind_time(i).eq.0) then |
print*,' Invalid time ',time_out(i) |
stop |
endif |
enddo |
c Set dimensions of output trajectory |
ntra_out = ntra_inp |
ncol_out = ncol_inp |
c Allocate memory for output trajectory |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Copy the selected times to the output trajectory |
do i=1,ntra_out |
do j=1,ntim_out |
do k=1,ncol_out |
tra_out(i,j,k) = tra_inp(i,ind_time(j),k) |
enddo |
enddo |
enddo |
c Copy meta information |
do i=1,ncol_out |
vars_out(i) = vars_inp(i) |
enddo |
110 continue |
c ---------------------------------------------------------------------- |
c Option -tra : Extract trajectories by number |
c ---------------------------------------------------------------------- |
if ( mode.ne.'-tra' ) goto 120 |
c Set the dimension of the output trajectory |
ntra_out = 0 |
c Get final list of extraction times (set number of times) |
do i=1,split_n |
if (split_str(i).eq.'to') then |
read(split_str(i-1),*) tmp0 |
read(split_str(i+1),*) tmp1 |
do j=nint(tmp0)+1,nint(tmp1)-1 |
ntra_out = ntra_out + 1 |
ind(ntra_out) = j |
enddo |
elseif (split_str(i).eq.'first') then |
ntra_out = ntra_out + 1 |
ind(ntra_out) = 1 |
elseif (split_str(i).eq.'last') then |
ntra_out = ntra_out + 1 |
ind(ntra_out) = ntra_inp |
else |
ntra_out = ntra_out + 1 |
read(split_str(i),*) tmp0 |
ind(ntra_out) = nint(tmp0) |
endif |
enddo |
c Check whether selected trajectories are ok |
do i=1,ntra_out |
if ( (ind(i).lt.1).or.(ind(i).gt.ntra_inp) ) then |
print*,'Invalid trajectory selected ',ind(i) |
stop |
endif |
enddo |
c Set dimensions of output trajectory |
ntim_out = ntim_inp |
ncol_out = ncol_inp |
c Allocate memory for output trajectory |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Copy the selected times to the output trajectory |
do i=1,ntra_out |
do j=1,ntim_out |
do k=1,ncol_out |
tra_out(i,j,k) = tra_inp(ind(i),j,k) |
enddo |
enddo |
enddo |
c Copy meta information |
do i=1,ncol_out |
vars_out(i) = vars_inp(i) |
enddo |
120 continue |
c ---------------------------------------------------------------------- |
c Option -startf : Extract starting positions for the trajectory file |
c ---------------------------------------------------------------------- |
if ( mode.ne.'-startf' ) goto 130 |
c Set the first for columns of the output |
ncol_out = 4 |
vars_out(1)='time' |
vars_out(2)='lon' |
vars_out(3)='lat' |
vars_out(4)='p' |
ind(1) =1 |
ind(2) =2 |
ind(3) =3 |
ind(4) =4 |
c Set dimensions of output trajectory |
ntim_out = 1 |
ntra_out = ntra_inp |
c Allocate memory for output trajectory |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Copy the selected times to the output trajectory |
do i=1,ntra_out |
do k=1,ncol_out |
tra_out(i,1,k) = tra_inp(i,1,k) |
enddo |
enddo |
c Copy meta information |
do i=1,ncol_out |
vars_out(i) = vars_inp(i) |
enddo |
130 continue |
c ---------------------------------------------------------------------- |
c Option -index : Extract trajectories by index file |
c ---------------------------------------------------------------------- |
if ( mode.ne.'-index' ) goto 140 |
c Read the index file |
open(10,file=str) |
ntra_out = 1 |
142 read(10,*,end=141) ind(ntra_out) |
ntra_out = ntra_out + 1 |
goto 142 |
141 continue |
ntra_out = ntra_out - 1 |
close(10) |
c Check whether selected trajectories are ok |
do i=1,ntra_out |
if ( (ind(i).lt.1).or.(ind(i).gt.ntra_inp) ) then |
print*,'Invalid trajectory selected ',ind(i) |
stop |
endif |
enddo |
c Set dimensions of output trajectory |
ntim_out = ntim_inp |
ncol_out = ncol_inp |
c Allocate memory for output trajectory |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Copy the selected times to the output trajectory |
do i=1,ntra_out |
do j=1,ntim_out |
do k=1,ncol_out |
tra_out(i,j,k) = tra_inp(ind(i),j,k) |
enddo |
enddo |
enddo |
c Copy meta information |
do i=1,ncol_out |
vars_out(i) = vars_inp(i) |
enddo |
140 continue |
c ---------------------------------------------------------------------- |
c Option -boolean : Extract trajectories by boolean file |
c ---------------------------------------------------------------------- |
if ( mode.ne.'-boolean' ) goto 150 |
c Read the index file |
open(10,file=str) |
ntra_out = 0 |
do i=1,ntra_inp |
read(10,*) ind1 |
if ( ind1.eq.1 ) then |
ntra_out = ntra_out + 1 |
ind(ntra_out) = i |
endif |
enddo |
close(10) |
c Check whether selected trajectories are ok |
do i=1,ntra_out |
if ( (ind(i).lt.1).or.(ind(i).gt.ntra_inp) ) then |
print*,'Invalid trajectory selected ',ind(i) |
stop |
endif |
enddo |
c Set dimensions of output trajectory |
ntim_out = ntim_inp |
ncol_out = ncol_inp |
c Allocate memory for output trajectory |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Copy the selected times to the output trajectory |
do i=1,ntra_out |
do j=1,ntim_out |
do k=1,ncol_out |
tra_out(i,j,k) = tra_inp(ind(i),j,k) |
enddo |
enddo |
enddo |
c Copy meta information |
do i=1,ncol_out |
vars_out(i) = vars_inp(i) |
enddo |
150 continue |
c ---------------------------------------------------------------------- |
c Option -pattern : Extract trajectories which match a regular expression |
c ---------------------------------------------------------------------- |
if ( mode.ne.'-pattern' ) goto 160 |
c All times and columns are extracted |
ncol_out = ncol_inp |
ntim_out = ntim_inp |
ntra_out = 0 |
c Split the search string |
nstr = 0 |
ileft = 0 |
iright = 0 |
do i=1,len_trim(str) |
if ( (str(i:i).eq.' ').and.(ileft.eq.0) ) then |
ileft = ileft + 1 |
elseif ( (str(i:i).ne.' ').and.(ileft.eq.0) ) then |
ileft = i |
iright = 0 |
elseif ( (str(i:i).ne.' ').and.(ileft.ne.0) ) then |
iright = i |
elseif ( (str(i:i).eq.' ').and.(ileft.ne.0) ) then |
nstr = nstr + 1 |
strsplit(nstr) = str(ileft:iright) |
ileft = 0 |
iright = 0 |
endif |
enddo |
if ( (ileft.ne.0).and.(iright.ne.0) ) then |
nstr = nstr + 1 |
strsplit(nstr) = str(ileft:iright) |
ileft = 0 |
endif |
c Loop over the trajectories - check for matching pattern |
do n=1,ntra_inp |
ind(n) = 0 |
do i=1,ntim_inp |
write(linestr,'(1f7.2,f9.2,f8.2,i6,100f10.3)') |
> (tra_inp(n,i,j),j=1,3), ! time, lon, lat |
> nint(tra_inp(n,i,4)), ! p |
> (tra_inp(n,i,j),j=5,ncol_inp) ! fields |
flag = 1 |
do k=1,nstr |
istr(k) = index(trim(linestr),trim(strsplit(k))) |
if ( istr(k).eq.0 ) flag = 0 |
enddo |
if ( flag.eq.1 ) ind(n) = 1 |
enddo |
if ( ind(n).eq.1 ) ntra_out = ntra_out + 1 |
enddo |
c Allocate memory for output trajectory |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Copy the selected times to the output trajectory |
ntra_out = 0 |
do i=1,ntra_inp |
if (ind(i).eq.1) then |
ntra_out = ntra_out + 1 |
do j=1,ntim_out |
do k=1,ncol_out |
tra_out(ntra_out,j,k) = tra_inp(i,j,k) |
enddo |
enddo |
endif |
enddo |
c Copy meta information |
do i=1,ncol_out |
vars_out(i) = vars_inp(i) |
enddo |
160 continue |
c ---------------------------------------------------------------------- |
c Option -leaving : Extract all trajectories which leave domain |
c ---------------------------------------------------------------------- |
if ( mode.ne.'-leaving' ) goto 170 |
c Set dimensions of output trajectory |
ntim_out = ntim_inp |
ncol_out = ncol_inp |
ntra_out = 0 |
c Copy the meta data |
do i=1,ncol_out |
vars_out(i) = vars_inp(i) |
enddo |
c Determine the number of trajectories leaving domain |
do i=1,ntra_inp |
isok(i) = 1 |
do j=1,ntim_inp |
if ( tra_inp(i,j,4).lt.0. ) isok(i) = 0 |
enddo |
if ( isok(i).eq.0 ) then |
ntra_out = ntra_out + 1 |
endif |
enddo |
c Allocate memory for output trajectory |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Copy the selected trajectories to the output trajectory |
ntra_out = 0 |
do i=1,ntra_inp |
if ( isok(i).eq.0 ) then |
ntra_out = ntra_out + 1 |
do j=1,ntim_inp |
do k=1,ncol_out |
tra_out(ntra_out,j,k) = tra_inp(i,j,k) |
enddo |
enddo |
endif |
enddo |
c Copy meta information |
170 continue |
c ---------------------------------------------------------------------- |
c Option -staying : Extract all trajectories which stay in domain |
c ---------------------------------------------------------------------- |
if ( mode.ne.'-staying' ) goto 180 |
c Set dimensions of output trajectory |
ntim_out = ntim_inp |
ncol_out = ncol_inp |
ntra_out = 0 |
c Copy the meta data |
do i=1,ncol_out |
vars_out(i) = vars_inp(i) |
enddo |
c Determine the number of trajectories staying in domain |
do i=1,ntra_inp |
isok(i) = 1 |
do j=1,ntim_inp |
if ( tra_inp(i,j,4).lt.0. ) isok(i) = 0 |
enddo |
if ( isok(i).eq.1 ) then |
ntra_out = ntra_out + 1 |
endif |
enddo |
c Allocate memory for output trajectory |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Copy the selected trajectories to the output trajectory |
ntra_out = 0 |
do i=1,ntra_inp |
if ( isok(i).eq.1 ) then |
ntra_out = ntra_out + 1 |
do j=1,ntim_inp |
do k=1,ncol_out |
tra_out(ntra_out,j,k) = tra_inp(i,j,k) |
enddo |
enddo |
endif |
enddo |
c Copy meta information |
180 continue |
c ---------------------------------------------------------------------- |
c Write output trajectories |
c ---------------------------------------------------------------------- |
c Write output as trajectory file |
if (outmode.ge.1) then |
call wopen_tra(fid,outfile,ntra_out,ntim_out,ncol_out, |
> refdate,vars_out,outmode) |
call write_tra(fid,tra_out,ntra_out,ntim_out,ncol_out,outmode) |
call close_tra(fid,outmode) |
c Write output as (lon, lat, p)-list |
else |
open(10,file=outfile) |
do i=1,ntra_out |
write(10,'(3f10.2)') tra_out(i,1,2), ! lon |
> tra_out(i,1,3), ! lat |
> tra_out(i,1,4) ! p |
enddo |
close(10) |
endif |
!c ---------------------------------------------------------------------- |
c Error handling |
c ---------------------------------------------------------------------- |
stop |
990 print*,'First columns must be <time,lon,lat,p>... Stop' |
stop |
end |
/tags/1.0/goodies/extract.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = extract.o ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
extract: $(OBJS) |
${F77} -o extract $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/extract.sh |
---|
0,0 → 1,67 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp extract short |
echo |
exit 0 |
endif |
# Set the input and output filenames |
set inpfile = $1 |
set outfile = $2 |
shift; shift; |
# Handle optional arguments (get a list, remove , and / separators) |
set mode=$1 |
shift; |
set str= |
while ( $#argv > 0 ) |
set str = "${str} $1" |
shift |
end |
set str=`echo $str | sed -e "s/,//g"` |
set str=`echo $str | sed -e "s/\///g"` |
# Check that the mode is valid |
if ( "${mode}" == "-var" ) goto next |
if ( "${mode}" == "-time" ) goto next |
if ( "${mode}" == "-tra" ) goto next |
if ( "${mode}" == "-startf" ) goto next |
if ( "${mode}" == "-index" ) goto next |
if ( "${mode}" == "-boolean" ) goto next |
if ( "${mode}" == "-pattern" ) goto next |
if ( "${mode}" == "-leaving" ) goto next |
if ( "${mode}" == "-staying" ) goto next |
echo " Invalid mode ${mode}..." |
exit 1 |
next: |
# Set program names |
set prog1=${LAGRANTO}/goodies/extract |
set prog2=${LAGRANTO}/goodies/trainfo.sh |
# Get trajectory dimensions |
set dim=`${prog2} ${inpfile} dim` |
# Run program |
\rm -f extract.param |
echo \"${inpfile}\" >! extract.param |
echo \"${outfile}\" >> extract.param |
echo \"${mode}\" >> extract.param |
echo ${dim} >> extract.param |
echo \"${str}\" >> extract.param |
${prog1} |
#\rm -f extract.param |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/gettidiff.f |
---|
0,0 → 1,139 |
program gettidiff |
C ================= |
implicit none |
integer idate(5),irefdat(5) |
real ihdiff |
integer iargc |
character*(80) arg |
integer nc1,nc2,flag1,flag2 |
c check for sufficient requested arguments |
if (iargc().ne.2) then |
print*, |
> 'USAGE: gettidiff date1 date2 (format (YY)YYMMDD_HH(MM))' |
call exit(1) |
endif |
c read and transform input |
call getarg(1,arg) |
call lenchar(arg,nc1) |
call checkchar(arg,'_',flag1) |
if (flag1.eq.7) then |
read(arg(1:2),'(i2)',err=120)idate(1) |
read(arg(3:4),'(i2)',err=120)idate(2) |
read(arg(5:6),'(i2)',err=120)idate(3) |
read(arg(8:9),'(i2)',err=120)idate(4) |
if (nc1.eq.11) then |
read(arg(10:11),'(i2)',err=120)idate(5) |
else if (nc1.ne.9) then |
print*, |
> 'USAGE: gettidiff date1 date2 (format (YY)YYMMDD_HH(MM))' |
call exit(1) |
endif |
else if (flag1.eq.9) then |
read(arg(1:4),'(i4)',err=120)idate(1) |
read(arg(5:6),'(i2)',err=120)idate(2) |
read(arg(7:8),'(i2)',err=120)idate(3) |
read(arg(10:11),'(i2)',err=120)idate(4) |
if (nc1.eq.13) then |
read(arg(12:13),'(i2)',err=120)idate(5) |
else if (nc1.ne.11) then |
print*, |
> 'USAGE: gettidiff date1 date2 (format (YY)YYMMDD_HH(MM))' |
call exit(1) |
endif |
else |
print*, |
> 'USAGE: gettidiff date1 date2 (format (YY)YYMMDD_HH(MM))' |
call exit(1) |
endif |
call getarg(2,arg) |
call lenchar(arg,nc2) |
call checkchar(arg,'_',flag2) |
if (flag1.ne.flag2) then |
print*, |
> 'error: both dates must be in same format (YY)YYMMDD_HH(MM)' |
call exit(1) |
endif |
if (flag2.eq.7) then |
read(arg(1:2),'(i2)',err=120)irefdat(1) |
read(arg(3:4),'(i2)',err=120)irefdat(2) |
read(arg(5:6),'(i2)',err=120)irefdat(3) |
read(arg(8:9),'(i2)',err=120)irefdat(4) |
if (nc2.eq.11) then |
read(arg(10:11),'(i2)',err=120)irefdat(5) |
else if (nc2.ne.9) then |
print*, |
> 'USAGE: gettidiff date1 date2 (format (YY)YYMMDD_HH(MM))' |
call exit(1) |
endif |
else if (flag2.eq.9) then |
read(arg(1:4),'(i4)',err=120)irefdat(1) |
read(arg(5:6),'(i2)',err=120)irefdat(2) |
read(arg(7:8),'(i2)',err=120)irefdat(3) |
read(arg(10:11),'(i2)',err=120)irefdat(4) |
if (nc2.eq.13) then |
read(arg(12:13),'(i2)',err=120)irefdat(5) |
else if (nc2.ne.11) then |
print*, |
> 'USAGE: gettidiff date1 date2 (format (YY)YYMMDD_HH(MM))' |
call exit(1) |
endif |
else |
print*, |
> 'USAGE: gettidiff date1 date2 (format (YY)YYMMDD_HH(MM))' |
call exit(1) |
endif |
call timediff(idate,irefdat,ihdiff) |
if (int(100.*ihdiff).eq.100*int(ihdiff)) then |
write(*,*)int(ihdiff) |
else |
write(*,'(f7.2)')ihdiff |
endif |
goto 200 |
120 write(*,*) |
>"*** error: date must be in format (YY)YYMMDD_HH(MM) ***" |
200 continue |
end |
subroutine lenchar(string,lstr) |
C =============================== |
character*(*) string |
integer n,lstr |
do n=1,len(string) |
if (string(n:n).eq."") then |
lstr=n-1 |
goto 100 |
endif |
enddo |
100 continue |
end |
subroutine checkchar(string,char,flag) |
C ====================================== |
character*(*) string |
character*(1) char |
integer n,flag |
flag=0 |
do n=1,len(string) |
if (string(n:n).eq.char) then |
flag=n |
return |
endif |
enddo |
end |
/tags/1.0/goodies/gettidiff.make |
---|
0,0 → 1,10 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = gettidiff.o ${LAGRANTO}/lib/times.a |
LIBS = |
.f.o: $*.f $(INCS) |
${F77} -c ${FFLAGS} $*.f |
gettidiff: $(OBJS) |
${F77} -o gettidiff $(OBJS) $(LIBS) |
/tags/1.0/goodies/gettidiff.sh |
---|
0,0 → 1,17 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp gettidiff short |
echo |
exit 0 |
endif |
${LAGRANTO}/goodies/gettidiff $* |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/getvars.f |
---|
0,0 → 1,44 |
C ******************************************************************** |
program getvarnames |
C ******************************************************************** |
implicit none |
include 'netcdf.inc' |
integer ndims,nvars,ngatts,recdim,ierr |
integer vartyp,ndim,nvatts,vardim(4) |
integer cdfid,i |
character*80 cdfname |
character*20 vnam(100) |
integer iargc |
character*(80) arg |
c check for sufficient requested arguments |
if (iargc().ne.1) then |
print*,'USAGE: getvars NetCDF-filename' |
call exit(1) |
endif |
c read and transform input |
call getarg(1,arg) |
cdfname=trim(arg) |
call cdfopn(cdfname,cdfid,ierr) |
call getvars(cdfid,nvars,vnam,ierr) |
C Write variable names to output |
do i=1,nvars |
write(*,*)vnam(i) |
enddo |
C Close the files |
call clscdf(cdfid,ierr) |
end |
/tags/1.0/goodies/getvars.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = getvars.o ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
getvars: $(OBJS) |
${F77} -o getvars $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/getvars.sh |
---|
0,0 → 1,17 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp getvars short |
echo |
exit 0 |
endif |
${LAGRANTO}/goodies/getvars $* |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/list2lsl.f |
---|
0,0 → 1,81 |
PROGRAM list2lsl |
c *********************************************************************** |
c * Convert a lat/lon/p list to a trajectory file * |
c * Michael Sprenger / Spring, summer 2010 * |
c *********************************************************************** |
implicit none |
c ---------------------------------------------------------------------- |
c Declaration of variables |
c ---------------------------------------------------------------------- |
c Input and output format for trajectories (see iotra.f) |
character*80 inpfile ! Input filename |
character*80 outfile ! Output filename |
c Trajectories |
integer ntra ! Number of trajectories |
integer ntim ! Number of times |
integer ncol ! Number of columns |
real,allocatable, dimension (:,:,:) :: tra ! Trajectories (ntra,ntim,ncol) |
character*80 vars(100) ! Variable names |
integer refdate(6) ! Reference date |
real timevalue ! Time |
c Auxiliary variables |
integer inpmode |
integer outmode |
integer stat |
integer fid |
integer i |
c ---------------------------------------------------------------------- |
c Do the reformating |
c ---------------------------------------------------------------------- |
c Read parameters |
open(10,file='list2lsl.param') |
read(10,*) inpfile |
read(10,*) outfile |
read(10,*) ntra |
read(10,*) (refdate(i),i=1,6) |
read(10,*) timevalue |
close(10) |
c Determine the formats |
call mode_tra(outmode,outfile) |
if (outmode.eq.-1) outmode=1 |
c Set parameters for output file |
ntim=1 |
ncol=4 |
vars(1)='time' |
vars(2)='lon' |
vars(3)='lat' |
vars(4)='p' |
c Allocate memory |
allocate(tra(ntra,ntim,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra ***' |
c Read inpufile |
fid = 10 |
open(fid,file=inpfile) |
do i=1,ntra |
tra(i,1,1) = timevalue |
read(fid,*) tra(i,1,2),tra(i,1,3),tra(i,1,4) |
enddo |
close(fid) |
c Write output file |
call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode) |
call write_tra(fid,tra,ntra,ntim,ncol,outmode) |
call close_tra(fid,outmode) |
end |
/tags/1.0/goodies/list2lsl.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = list2lsl.o ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
list2lsl: $(OBJS) |
${F77} -o list2lsl $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/list2lsl.sh |
---|
0,0 → 1,61 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp list2lsl short |
echo |
exit 0 |
endif |
set inpfile=$1 |
set outfile=$2 |
set refdate = `date +'%Y%m%d_%H%M'` |
set timevalue = 0 |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -ref |
set refdate=$argv[2] |
shift; |
breaksw |
case -time |
set timevalue=$argv[2] |
shift; |
breaksw |
endsw |
shift; |
end |
set ntra=`wc -l ${inpfile} | awk '{print $1}'` |
# Split the reference date |
set yyyy=`echo ${refdate} | cut -c 1-4` |
set mm=`echo ${refdate} | cut -c 5-6` |
set dd=`echo ${refdate} | cut -c 7-8` |
set hh=`echo ${refdate} | cut -c 10-11` |
set min=`echo ${refdate}00 | cut -c 12-13` |
\rm -f list2lsl.param |
echo \"${inpfile}\" >! list2lsl.param |
echo \"${outfile}\" >> list2lsl.param |
echo ${ntra} >> list2lsl.param |
echo ${yyyy} ${mm} ${dd} ${hh} ${min} 00 >> list2lsl.param |
echo ${timevalue} >> list2lsl.param |
${LAGRANTO}/goodies/list2lsl |
\rm -f list2lsl.param |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/lsl2list.f |
---|
0,0 → 1,71 |
PROGRAM lsl2list |
c *********************************************************************** |
c * Convert a trajectory file into a lat/lon/p list * |
c * Michael Sprenger / Spring, summer 2010 * |
c *********************************************************************** |
implicit none |
c ---------------------------------------------------------------------- |
c Declaration of variables |
c ---------------------------------------------------------------------- |
c Input and output format for trajectories (see iotra.f) |
character*80 inpfile ! Input filename |
character*80 outfile ! Output filename |
c Trajectories |
integer ntra ! Number of trajectories |
integer ntim ! Number of times |
integer ncol ! Number of columns |
real,allocatable, dimension (:,:,:) :: tra ! Trajectories (ntra,ntim,ncol) |
character*80 vars(100) ! Variable names |
integer refdate(6) ! Reference date |
c Auxiliary variables |
integer inpmode |
integer stat |
integer fid |
integer i,j |
c ---------------------------------------------------------------------- |
c Do the reformating |
c ---------------------------------------------------------------------- |
c Read parameters |
open(10,file='lsl2list.param') |
read(10,*) inpfile |
read(10,*) outfile |
read(10,*) ntra,ntim,ncol |
close(10) |
c Determine the formats |
call mode_tra(inpmode,inpfile) |
if (inpmode.eq.-1) inpmode=1 |
c Allocate memory |
allocate(tra(ntra,ntim,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra ***' |
c Read inpufile |
call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode) |
call read_tra (fid,tra,ntra,ntim,ncol,inpmode) |
call close_tra(fid,inpmode) |
c Write output file inpufile |
fid = 10 |
open(fid,file=outfile) |
do i=1,ntra |
do j=1,ntim |
write(fid,'(f9.2,f8.2,i6)') |
> tra(i,j,2),tra(i,j,3),nint(tra(i,j,4)) |
enddo |
enddo |
close(fid) |
end |
/tags/1.0/goodies/lsl2list.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = lsl2list.o ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
lsl2list: $(OBJS) |
${F77} -o lsl2list $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/lsl2list.sh |
---|
0,0 → 1,31 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp lsl2list short |
echo |
exit 0 |
endif |
set inpfile=$1 |
set outfile=$2 |
set prog1=${LAGRANTO}/goodies/lsl2list |
set dim=`${LAGRANTO}/goodies/trainfo.sh ${inpfile} dim` |
\rm -f lsl2list.param |
echo \"${inpfile}\" >! lsl2list.param |
echo \"${outfile}\" >> lsl2list.param |
echo ${dim} >> lsl2list.param |
${prog1} |
#\rm -f lsl2list.param |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/mergetra.f |
---|
0,0 → 1,433 |
PROGRAM mege |
c *********************************************************************** |
c * Merge two trajectory files * |
c * Michael Sprenger / Spring, summer 2010 * |
c *********************************************************************** |
implicit none |
c ---------------------------------------------------------------------- |
c Declaration of parameters |
c ---------------------------------------------------------------------- |
c Numerical epsilon |
real eps |
parameter (eps=0.0001) |
c ---------------------------------------------------------------------- |
c Declaration of variables |
c ---------------------------------------------------------------------- |
c Merging mode |
integer mode |
character*20 datecheck |
c Input and output format for trajectories (see iotra.f) |
character*80 inpfile1 ! Input filename 1 |
character*80 inpfile2 ! Input filename 2 |
character*80 outfile ! Output filename |
integer inpmode1 ! Input format 1 |
integer inpmode2 ! Input format 2 |
integer outmode ! Output format |
c Trajectories |
integer ntra_inp1 ! Number of trajectories |
integer ntim_inp1 ! Number of times |
integer ncol_inp1 ! Number of columns |
real,allocatable, dimension (:,:,:) :: tra_inp1 ! Trajectories (ntra,ntim,ncol) |
character*80 vars_inp1(100) ! Variable names |
real time_inp1(500) ! Times of input trajectory |
integer refdate1(6) ! Reference date |
integer ntra_inp2 ! Number of trajectories |
integer ntim_inp2 ! Number of times |
integer ncol_inp2 ! Number of columns |
real,allocatable, dimension (:,:,:) :: tra_inp2 ! Trajectories (ntra,ntim,ncol) |
character*80 vars_inp2(100) ! Variable names |
real time_inp2(500) ! Times of input trajectory |
integer refdate2(6) ! Reference date |
integer ntra_out ! Number of trajectories |
integer ntim_out ! Number of times |
integer ncol_out ! Number of columns |
real,allocatable, dimension (:,:,:) :: tra_out ! Trajectories (ntra,ntim,ncol) |
character*80 vars_out(100) ! Variable names |
real time_out(500) ! Times of output trajectory |
integer refdate(6) ! Reference date |
c Auxiliary variables |
integer i,j,k |
integer ind(200) |
integer itr(200) |
integer isok |
integer stat |
integer fid |
real rswap |
integer iswap |
c ---------------------------------------------------------------------- |
c Read and handle parameters |
c ---------------------------------------------------------------------- |
c Read parameters |
open(10,file='mergetra.param') |
read(10,*) inpfile1 |
read(10,*) inpfile2 |
read(10,*) outfile |
read(10,*) ntra_inp1,ntim_inp1,ncol_inp1 |
read(10,*) ntra_inp2,ntim_inp2,ncol_inp2 |
read(10,*) datecheck |
close(10) |
c Determine the formats |
call mode_tra(inpmode1,inpfile1) |
if (inpmode1.eq.-1) inpmode1=1 |
call mode_tra(inpmode2,inpfile2) |
if (inpmode2.eq.-1) inpmode2=1 |
call mode_tra(outmode,outfile) |
if (outmode.eq.-1) outmode=1 |
c ---------------------------------------------------------------------- |
c Read input trajectories |
c ---------------------------------------------------------------------- |
c Allocate memory |
allocate(tra_inp1(ntra_inp1,ntim_inp1,ncol_inp1),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_inp1 ***' |
allocate(tra_inp2(ntra_inp2,ntim_inp2,ncol_inp2),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_inp2 ***' |
c Read inpufile |
call ropen_tra(fid,inpfile1,ntra_inp1,ntim_inp1,ncol_inp1, |
> refdate1,vars_inp1,inpmode1) |
call read_tra (fid,tra_inp1,ntra_inp1,ntim_inp1,ncol_inp1, |
> inpmode1) |
call close_tra(fid,inpmode1) |
call ropen_tra(fid,inpfile2,ntra_inp2,ntim_inp2,ncol_inp2, |
> refdate2,vars_inp2,inpmode2) |
call read_tra (fid,tra_inp2,ntra_inp2,ntim_inp2,ncol_inp2, |
> inpmode2) |
call close_tra(fid,inpmode2) |
c Get the times of the trajectories |
do i=1,ntim_inp1 |
time_inp1(i) = tra_inp1(1,i,1) |
enddo |
do i=1,ntim_inp2 |
time_inp2(i) = tra_inp2(1,i,1) |
enddo |
c Check format |
if ( vars_inp1(1).ne.'time' ) goto 990 |
if ( (vars_inp1(2).ne.'lon').and. |
> (vars_inp1(2).ne.'xpos') ) goto 990 |
if ( (vars_inp1(3).ne.'lat').and. |
> (vars_inp1(3).ne.'ypos') ) goto 990 |
if ( (vars_inp1(4).ne.'p' ).and. |
> (vars_inp1(4).ne.'ppos') ) goto 990 |
if ( vars_inp2(1).ne.'time' ) goto 990 |
if ( (vars_inp2(2).ne.'lon').and. |
> (vars_inp2(2).ne.'xpos') ) goto 990 |
if ( (vars_inp2(3).ne.'lat').and. |
> (vars_inp2(3).ne.'ypos') ) goto 990 |
if ( (vars_inp2(4).ne.'p' ).and. |
> (vars_inp2(4).ne.'ppos') ) goto 990 |
c Check whether the reference dates are equal |
if ( datecheck.eq.'datecheck' ) then |
do i=1,5 |
if ( refdate1(i).ne.refdate2(i) ) then |
print*,' ERROR; Reference dates must be the same... Stop' |
print*,(refdate1(j),j=1,5) |
print*,(refdate2(j),j=1,5) |
stop |
endif |
enddo |
endif |
c ---------------------------------------------------------------------- |
c Decide what to do |
c ---------------------------------------------------------------------- |
c Init the mode |
mode = 0 |
c ---- Check whether only the columns should be combined (mode 1) ------- |
print*,'Testing for mode 1 (combine columns)' |
if ( ntim_inp1.ne.ntim_inp2 ) goto 100 |
print*,' -> ntim ok' |
if ( ntra_inp1.ne.ntra_inp2 ) goto 100 |
print*,' -> ntra ok' |
do i=1,ntim_inp1 |
if ( time_inp1(i).ne.time_inp2(i) ) goto 100 |
enddo |
print*,' -> times ok' |
do i=1,ntra_inp1 |
do j=1,ntim_inp1 |
if ( tra_inp1(i,j,1).ne.tra_inp2(i,j,1) ) goto 100 |
if ( tra_inp1(i,j,2).ne.tra_inp2(i,j,2) ) goto 100 |
if ( tra_inp1(i,j,3).ne.tra_inp2(i,j,3) ) goto 100 |
if ( tra_inp1(i,j,4).ne.tra_inp2(i,j,4) ) goto 100 |
enddo |
enddo |
print*,' -> lon,lat,p ok => Mode 1 accepted' |
mode = 1 |
goto 130 |
100 continue |
c ---- Check whether second file to appended to first one (mode 2) ----- |
print*,'Testing for mode 2 (append file 2 to file 1)' |
if ( ntim_inp1.ne.ntim_inp2 ) goto 110 |
print*,' -> ntim ok' |
if ( ncol_inp1.ne.ncol_inp2 ) goto 110 |
print*,' -> ncol ok' |
do i=1,ntim_inp1 |
if ( time_inp1(i).ne.time_inp2(i) ) goto 110 |
enddo |
print*,' -> times ok' |
do i=1,ncol_inp1 |
if ( vars_inp1(i).ne.vars_inp2(i) ) goto 110 |
enddo |
print*,' -> vars ok => Mode 2 accepted' |
mode = 2 |
goto 130 |
110 continue |
c ----- Check whether to combine different times (mode 3) -------------- |
print*,'Testing for mode 3 (combining times)' |
if ( ntra_inp1.ne.ntra_inp2 ) goto 120 |
print*,' -> ntra ok' |
if ( ncol_inp1.ne.ncol_inp2 ) goto 120 |
print*,' -> ncol ok' |
do i=1,ncol_inp1 |
if ( vars_inp1(i).ne.vars_inp2(i) ) goto 120 |
enddo |
print*,' -> vars ok => Mode 3 accepted' |
mode = 3 |
goto 130 |
120 continue |
c ----- Stop if no valid merging mode could be determined ------------- |
print*,' ERROR: could not determine merging mode ...' |
stop |
c Exit point for mode decision |
130 continue |
c ---------------------------------------------------------------------- |
c Merging depending on mode |
c ---------------------------------------------------------------------- |
c ------ Merging of columns (mode 1) ----------------------------------- |
if ( mode.ne.1 ) goto 200 |
c Get the complete list of additional field |
do i=1,ncol_inp1 |
ncol_out = ncol_out + 1 |
vars_out(ncol_out) = vars_inp1(i) |
ind(ncol_out) = i |
itr(ncol_out) = 1 |
enddo |
do i=5,ncol_inp2 |
isok=1 |
do j=1,ncol_out |
if ( vars_inp2(i).eq.vars_out(j) ) isok=0 |
enddo |
if ( isok.eq.1 ) then |
ncol_out = ncol_out + 1 |
vars_out(ncol_out) = vars_inp2(i) |
ind(ncol_out) = i |
itr(ncol_out) = 2 |
endif |
enddo |
c Allocate memory for output trajectory |
ntra_out = ntra_inp1 |
ntim_out = ntim_inp1 |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Save the trajectory |
do i=1,ntra_out |
do j=1,ntim_out |
do k=1,ncol_out |
if ( itr(k).eq.1) then |
tra_out(i,j,k) = tra_inp1(i,j,ind(k)) |
else |
tra_out(i,j,k) = tra_inp2(i,j,ind(k)) |
endif |
enddo |
enddo |
enddo |
200 continue |
c ------ Appending files (mode 2) -------------------------------------- |
if ( mode.ne.2 ) goto 210 |
c Allocate memory for output trajectory |
ntra_out = ntra_inp1 + ntra_inp2 |
ntim_out = ntim_inp1 |
ncol_out = ncol_inp1 |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Set the field names for the output trajectory |
do i=1,ncol_out |
vars_out(i) = vars_inp1(i) |
enddo |
c Save the trajectory |
do i=1,ntra_out |
do j=1,ntim_out |
do k=1,ncol_out |
if ( i.le.ntra_inp1 ) then |
tra_out(i,j,k) = tra_inp1(i ,j,k) |
else |
tra_out(i,j,k) = tra_inp2(i-ntra_inp1,j,k) |
endif |
enddo |
enddo |
enddo |
210 continue |
c ------ Combining times (mode 3) -------------------------------------- |
if ( mode.ne.3 ) goto 220 |
c Get a list of all output times |
ntim_out = 0 |
do i=1,ntim_inp1 |
isok = 1 |
do j=1,ntim_out |
if ( time_inp1(i).eq.time_out(j) ) isok=0 |
enddo |
if (isok.eq.1 ) then |
ntim_out = ntim_out + 1 |
time_out(ntim_out) = time_inp1(i) |
itr(ntim_out) = 1 |
ind(ntim_out) = i |
endif |
enddo |
do i=1,ntim_inp2 |
isok = 1 |
do j=1,ntim_out |
if ( time_inp2(i).eq.time_out(j) ) isok=0 |
enddo |
if (isok.eq.1 ) then |
ntim_out = ntim_out + 1 |
time_out(ntim_out) = time_inp2(i) |
itr(ntim_out) = 2 |
ind(ntim_out) = i |
endif |
enddo |
c Sort the times |
do i=1,ntim_out |
do j=i+1,ntim_out |
if ( time_out(j).lt.time_out(i) ) then |
rswap = time_out(i) |
time_out(i) = time_out(j) |
time_out(j) = rswap |
iswap = itr(i) |
itr(i) = itr(j) |
itr(j) = iswap |
iswap = ind(i) |
ind(i) = ind(j) |
ind(j) = iswap |
endif |
enddo |
enddo |
c Allocate memory for output trajectory |
ntra_out = ntra_inp1 |
ncol_out = ncol_inp1 |
allocate(tra_out(ntra_out,ntim_out,ncol_out),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra_out ***' |
c Set the field names for the output trajectory |
do i=1,ncol_out |
vars_out(i) = vars_inp1(i) |
enddo |
c Save the trajectory |
do i=1,ntra_out |
do j=1,ntim_out |
do k=1,ncol_out |
if ( itr(j).eq.1 ) then |
tra_out(i,j,k) = tra_inp1(i,ind(j),k) |
else |
tra_out(i,j,k) = tra_inp2(i,ind(j),k) |
endif |
enddo |
enddo |
enddo |
220 continue |
c ---------------------------------------------------------------------- |
c Write the output trajectory |
c ---------------------------------------------------------------------- |
call wopen_tra(fid,outfile,ntra_out,ntim_out,ncol_out, |
> refdate1,vars_out,outmode) |
call write_tra(fid,tra_out,ntra_out,ntim_out,ncol_out,outmode) |
call close_tra(fid,outmode) |
c ---------------------------------------------------------------------- |
c Error handling |
c ---------------------------------------------------------------------- |
stop |
990 print*,'First columns must be <time,lon,lat,p>... Stop' |
stop |
end |
/tags/1.0/goodies/mergetra.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = mergetra.o ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/times.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
mergetra: $(OBJS) |
${F77} -o mergetra $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/mergetra.sh |
---|
0,0 → 1,52 |
#!/bin/csh |
# ----------------------------------------------------------------------------- |
# Set some parameters |
# ----------------------------------------------------------------------------- |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp mergetra short |
echo |
exit 0 |
endif |
# Set input file |
set inpfile1 = $1 |
set inpfile2 = $2 |
set outfile = $3 |
shift; shift; shift |
# Handle optional arguments |
set datecheck = "datecheck" |
while ( $#argv > 0 ) |
if ( "$1" == "-nodatecheck" ) set datecheck="nodatecheck" |
shift |
end |
# Set Fortran program |
set prog=${LAGRANTO}/goodies/mergetra |
# ----------------------------------------------------------------------------- |
# Run program |
# ----------------------------------------------------------------------------- |
set dims1=`${LAGRANTO}/goodies/trainfo.sh ${inpfile1} dim` |
set dims2=`${LAGRANTO}/goodies/trainfo.sh ${inpfile2} dim` |
\rm -f mergetra.param |
echo \"${inpfile1}\" >! mergetra.param |
echo \"${inpfile2}\" >> mergetra.param |
echo \"${outfile}\" >> mergetra.param |
echo ${dims1} >> mergetra.param |
echo ${dims2} >> mergetra.param |
echo \"${datecheck}\" >> mergetra.param |
${prog} |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/newtime.f |
---|
0,0 → 1,129 |
program calcnewdate |
C =================== |
implicit none |
integer date1(5),date2(5) |
integer iargc |
real diff |
character*(80) arg,yychar,cdat |
character*(2) cdate(4) |
integer flag,nc |
c check for sufficient requested arguments |
if (iargc().ne.2) then |
print*,'USAGE: newtime date (format (YY)YYMMDD_HH) timestep' |
call exit(1) |
endif |
c read and transform input |
call getarg(1,arg) |
call lenchar(arg,nc) |
if (nc.eq.9) then |
yychar='' |
read(arg(1:2),'(i2)',err=120)date1(1) |
read(arg(3:4),'(i2)',err=120)date1(2) |
read(arg(5:6),'(i2)',err=120)date1(3) |
read(arg(8:9),'(i2)',err=120)date1(4) |
else if (nc.eq.11) then |
yychar=arg(1:2) |
read(arg(3:4),'(i2)',err=120)date1(1) |
read(arg(5:6),'(i2)',err=120)date1(2) |
read(arg(7:8),'(i2)',err=120)date1(3) |
read(arg(10:11),'(i2)',err=120)date1(4) |
else |
print*,'USAGE: newtime date (format (YY)YYMMDD_HH) timestep' |
call exit(1) |
endif |
call getarg(2,arg) |
call checkchar(arg,".",flag) |
if (flag.eq.0) arg=trim(arg)//"." |
read(arg,'(f10.2)') diff |
call newdate(date1,diff,date2) |
c Transition 2000 |
if ((date2(1).lt.date1(1)).and. |
> (diff.gt.0.).and. |
> (yychar.eq.'19')) yychar='20' |
if (date2(1).lt.0) date2(1)=date2(1)+100 |
if ((date2(1).gt.date1(1)).and. |
> (diff.lt.0.).and. |
> (yychar.eq.'20')) yychar='19' |
c Transition 1900 |
if ((date2(1).lt.date1(1)).and. |
> (diff.gt.0.).and. |
> (yychar.eq.'18')) yychar='19' |
if (date2(1).lt.0) date2(1)=date2(1)+100 |
if ((date2(1).gt.date1(1)).and. |
> (diff.lt.0.).and. |
> (yychar.eq.'19')) yychar='18' |
if (date2(1).lt.10) then |
write(cdate(1),'(a,i1)')'0',date2(1) |
else |
write(cdate(1),'(i2)')date2(1) |
endif |
if (date2(2).lt.10) then |
write(cdate(2),'(a,i1)')'0',date2(2) |
else |
write(cdate(2),'(i2)')date2(2) |
endif |
if (date2(3).lt.10) then |
write(cdate(3),'(a,i1)')'0',date2(3) |
else |
write(cdate(3),'(i2)')date2(3) |
endif |
if (date2(4).lt.10) then |
write(cdate(4),'(a,i1)')'0',date2(4) |
else |
write(cdate(4),'(i2)')date2(4) |
endif |
cdat=trim(yychar)//cdate(1)//cdate(2)//cdate(3)//'_'//cdate(4) |
write(*,'(a)')trim(cdat) |
goto 200 |
120 write(*,*)"*** error: date must be in format (YY)YYMMDD_HH ***" |
200 continue |
end |
subroutine checkchar(string,char,flag) |
C ====================================== |
character*(*) string |
character*(1) char |
integer n,flag |
flag=0 |
do n=1,len(string) |
if (string(n:n).eq.char) then |
flag=n |
return |
endif |
enddo |
end |
subroutine lenchar(string,lstr) |
C =============================== |
character*(*) string |
integer n,lstr |
do n=1,len(string) |
if (string(n:n).eq."") then |
lstr=n-1 |
goto 100 |
endif |
enddo |
100 continue |
end |
/tags/1.0/goodies/newtime.make |
---|
0,0 → 1,10 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = newtime.o ${LAGRANTO}/lib/times.a |
LIBS = |
.f.o: $*.f $(INCS) |
${F77} -c ${FFLAGS} $*.f |
newtime: $(OBJS) |
${F77} -o newtime $(OBJS) $(LIBS) |
/tags/1.0/goodies/newtime.sh |
---|
0,0 → 1,17 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp newtime short |
echo |
exit 0 |
endif |
${LAGRANTO}/goodies/newtime $* |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/precmod.f90 |
---|
0,0 → 1,18 |
module precision |
! Real kinds |
integer, parameter :: kr4 = selected_real_kind(6,37) ! single precision real |
integer, parameter :: kr8 = selected_real_kind(15,307) ! double precision real |
! Integer kinds |
integer, parameter :: ki4 = selected_int_kind(9) ! single precision integer |
integer, parameter :: ki8 = selected_int_kind(18) ! double precision integer |
!Complex kinds |
integer, parameter :: kc4 = kr4 ! single precision complex |
integer, parameter :: kc8 = kr8 ! double precision complex |
end module precision |
/tags/1.0/goodies/reformat.f |
---|
0,0 → 1,68 |
PROGRAM reformat |
c *********************************************************************** |
c * Change format of a trajectory file * |
c * Michael Sprenger / Spring, summer 2010 * |
c *********************************************************************** |
implicit none |
c ---------------------------------------------------------------------- |
c Declaration of variables |
c ---------------------------------------------------------------------- |
c Input and output format for trajectories (see iotra.f) |
character*80 inpfile ! Input filename |
character*80 outfile ! Output filename |
c Trajectories |
integer ntra ! Number of trajectories |
integer ntim ! Number of times |
integer ncol ! Number of columns |
real,allocatable, dimension (:,:,:) :: tra ! Trajectories (ntra,ntim,ncol) |
character*80 vars(100) ! Variable names |
integer refdate(6) ! Reference date |
c Auxiliary variables |
integer inpmode |
integer outmode |
integer stat |
integer fid |
integer i |
c ---------------------------------------------------------------------- |
c Do the reformating |
c ---------------------------------------------------------------------- |
c Read parameters |
open(10,file='reformat.param') |
read(10,*) inpfile |
read(10,*) outfile |
read(10,*) ntra,ntim,ncol |
close(10) |
c Determine the formats |
call mode_tra(inpmode,inpfile) |
if (inpmode.eq.-1) inpmode=1 |
call mode_tra(outmode,outfile) |
if (outmode.eq.-1) outmode=1 |
c Allocate memory |
allocate(tra(ntra,ntim,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra ***' |
c Read inpufile |
call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode) |
call read_tra (fid,tra,ntra,ntim,ncol,inpmode) |
call close_tra(fid,inpmode) |
c Write output file |
call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode) |
call write_tra(fid,tra,ntra,ntim,ncol,outmode) |
call close_tra(fid,outmode) |
end |
/tags/1.0/goodies/reformat.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = reformat.o ${LAGRANTO}/lib//iotra.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
reformat: $(OBJS) |
${F77} -o reformat $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/reformat.refprof |
---|
0,0 → 1,3007 |
1976 Standard Atmosphere |
1: Altitude[m] |
2: Temperature [Kelvin] |
3: Pressure [pascal] |
0.00000 288.150 101325 |
10.0000 288.085 101205 |
20.0000 288.020 101085 |
30.0000 287.955 100965 |
40.0000 287.890 100845 |
50.0000 287.825 100726 |
60.0000 287.760 100606 |
70.0000 287.695 100487 |
80.0000 287.630 100368 |
90.0000 287.565 100248 |
100.000 287.500 100129 |
110.000 287.435 100011 |
120.000 287.370 99891.7 |
130.000 287.305 99773.0 |
140.000 287.240 99654.4 |
150.000 287.175 99536.0 |
160.000 287.110 99417.6 |
170.000 287.045 99299.4 |
180.000 286.980 99181.2 |
190.000 286.915 99063.2 |
200.000 286.850 98945.3 |
210.000 286.785 98827.5 |
220.000 286.720 98709.9 |
230.000 286.655 98592.3 |
240.000 286.590 98474.9 |
250.000 286.525 98357.5 |
260.000 286.460 98240.3 |
270.000 286.395 98123.2 |
280.000 286.330 98006.2 |
290.000 286.265 97889.3 |
300.000 286.200 97772.6 |
310.000 286.135 97655.9 |
320.000 286.070 97539.4 |
330.000 286.005 97423.0 |
340.000 285.940 97306.6 |
350.000 285.875 97190.4 |
360.000 285.810 97074.3 |
370.000 285.745 96958.4 |
380.000 285.680 96842.5 |
390.000 285.615 96726.8 |
400.000 285.550 96611.1 |
410.000 285.485 96495.6 |
420.000 285.420 96380.2 |
430.000 285.355 96264.9 |
440.000 285.290 96149.7 |
450.000 285.225 96034.6 |
460.000 285.160 95919.6 |
470.000 285.095 95804.7 |
480.000 285.030 95690.0 |
490.000 284.965 95575.4 |
500.000 284.900 95460.8 |
510.000 284.835 95346.4 |
520.000 284.770 95232.1 |
530.000 284.705 95117.9 |
540.000 284.640 95003.8 |
550.000 284.575 94889.9 |
560.000 284.510 94776.0 |
570.000 284.445 94662.3 |
580.000 284.380 94548.6 |
590.000 284.315 94435.1 |
600.000 284.250 94321.7 |
610.000 284.185 94208.4 |
620.000 284.120 94095.2 |
630.000 284.055 93982.1 |
640.000 283.990 93869.1 |
650.000 283.925 93756.2 |
660.000 283.860 93643.5 |
670.000 283.795 93530.8 |
680.000 283.730 93418.3 |
690.000 283.665 93305.9 |
700.000 283.600 93193.6 |
710.000 283.535 93081.4 |
720.000 283.470 92969.3 |
730.000 283.405 92857.3 |
740.000 283.340 92745.4 |
750.000 283.275 92633.6 |
760.000 283.210 92521.9 |
770.000 283.145 92410.4 |
780.000 283.080 92299.0 |
790.000 283.015 92187.6 |
800.000 282.950 92076.4 |
810.000 282.885 91965.3 |
820.000 282.820 91854.3 |
830.000 282.755 91743.4 |
840.000 282.690 91632.6 |
850.000 282.625 91521.9 |
860.000 282.560 91411.3 |
870.000 282.495 91300.8 |
880.000 282.430 91190.5 |
890.000 282.365 91080.2 |
900.000 282.300 90970.1 |
910.000 282.235 90860.1 |
920.000 282.170 90750.1 |
930.000 282.105 90640.3 |
940.000 282.040 90530.6 |
950.000 281.975 90421.0 |
960.000 281.910 90311.5 |
970.000 281.845 90202.1 |
980.000 281.780 90092.8 |
990.000 281.715 89983.6 |
1000.00 281.650 89874.6 |
1010.00 281.585 89765.6 |
1020.00 281.520 89656.8 |
1030.00 281.455 89548.0 |
1040.00 281.390 89439.4 |
1050.00 281.325 89330.8 |
1060.00 281.260 89222.4 |
1070.00 281.195 89114.1 |
1080.00 281.130 89005.9 |
1090.00 281.065 88897.8 |
1100.00 281.000 88789.8 |
1110.00 280.935 88681.9 |
1120.00 280.870 88574.1 |
1130.00 280.805 88466.4 |
1140.00 280.740 88358.8 |
1150.00 280.675 88251.3 |
1160.00 280.610 88144.0 |
1170.00 280.545 88036.7 |
1180.00 280.480 87929.6 |
1190.00 280.415 87822.5 |
1200.00 280.350 87715.6 |
1210.00 280.285 87608.7 |
1220.00 280.220 87502.0 |
1230.00 280.155 87395.4 |
1240.00 280.090 87288.9 |
1250.00 280.025 87182.5 |
1260.00 279.960 87076.1 |
1270.00 279.895 86969.9 |
1280.00 279.830 86863.8 |
1290.00 279.765 86757.8 |
1300.00 279.700 86651.9 |
1310.00 279.635 86546.2 |
1320.00 279.570 86440.5 |
1330.00 279.505 86334.9 |
1340.00 279.440 86229.4 |
1350.00 279.375 86124.1 |
1360.00 279.310 86018.8 |
1370.00 279.245 85913.6 |
1380.00 279.180 85808.6 |
1390.00 279.115 85703.6 |
1400.00 279.050 85598.8 |
1410.00 278.985 85494.0 |
1420.00 278.920 85389.4 |
1430.00 278.855 85284.9 |
1440.00 278.790 85180.4 |
1450.00 278.725 85076.1 |
1460.00 278.660 84971.9 |
1470.00 278.595 84867.8 |
1480.00 278.530 84763.7 |
1490.00 278.465 84659.8 |
1500.00 278.400 84556.0 |
1510.00 278.335 84452.3 |
1520.00 278.270 84348.7 |
1530.00 278.205 84245.2 |
1540.00 278.140 84141.8 |
1550.00 278.075 84038.5 |
1560.00 278.010 83935.3 |
1570.00 277.945 83832.2 |
1580.00 277.880 83729.2 |
1590.00 277.815 83626.3 |
1600.00 277.750 83523.5 |
1610.00 277.685 83420.9 |
1620.00 277.620 83318.3 |
1630.00 277.555 83215.8 |
1640.00 277.490 83113.4 |
1650.00 277.425 83011.1 |
1660.00 277.360 82909.0 |
1670.00 277.295 82806.9 |
1680.00 277.230 82704.9 |
1690.00 277.165 82603.1 |
1700.00 277.100 82501.3 |
1710.00 277.035 82399.6 |
1720.00 276.970 82298.1 |
1730.00 276.905 82196.6 |
1740.00 276.840 82095.3 |
1750.00 276.775 81994.0 |
1760.00 276.710 81892.8 |
1770.00 276.645 81791.8 |
1780.00 276.580 81690.8 |
1790.00 276.515 81590.0 |
1800.00 276.450 81489.2 |
1810.00 276.385 81388.6 |
1820.00 276.320 81288.0 |
1830.00 276.255 81187.6 |
1840.00 276.190 81087.2 |
1850.00 276.125 80987.0 |
1860.00 276.060 80886.8 |
1870.00 275.995 80786.8 |
1880.00 275.930 80686.8 |
1890.00 275.865 80587.0 |
1900.00 275.800 80487.2 |
1910.00 275.735 80387.6 |
1920.00 275.670 80288.0 |
1930.00 275.605 80188.6 |
1940.00 275.540 80089.2 |
1950.00 275.475 79990.0 |
1960.00 275.410 79890.8 |
1970.00 275.345 79791.8 |
1980.00 275.280 79692.8 |
1990.00 275.215 79594.0 |
2000.00 275.150 79495.2 |
2010.00 275.085 79396.6 |
2020.00 275.020 79298.0 |
2030.00 274.955 79199.6 |
2040.00 274.890 79101.2 |
2050.00 274.825 79002.9 |
2060.00 274.760 78904.8 |
2070.00 274.695 78806.7 |
2080.00 274.630 78708.8 |
2090.00 274.565 78610.9 |
2100.00 274.500 78513.1 |
2110.00 274.435 78415.5 |
2120.00 274.370 78317.9 |
2130.00 274.305 78220.4 |
2140.00 274.240 78123.1 |
2150.00 274.175 78025.8 |
2160.00 274.110 77928.6 |
2170.00 274.045 77831.5 |
2180.00 273.980 77734.6 |
2190.00 273.915 77637.7 |
2200.00 273.850 77540.9 |
2210.00 273.785 77444.2 |
2220.00 273.720 77347.6 |
2230.00 273.655 77251.1 |
2240.00 273.590 77154.7 |
2250.00 273.525 77058.5 |
2260.00 273.460 76962.3 |
2270.00 273.395 76866.2 |
2280.00 273.330 76770.2 |
2290.00 273.265 76674.3 |
2300.00 273.200 76578.4 |
2310.00 273.135 76482.7 |
2320.00 273.070 76387.1 |
2330.00 273.005 76291.6 |
2340.00 272.940 76196.2 |
2350.00 272.875 76100.9 |
2360.00 272.810 76005.6 |
2370.00 272.745 75910.5 |
2380.00 272.680 75815.5 |
2390.00 272.615 75720.5 |
2400.00 272.550 75625.7 |
2410.00 272.485 75530.9 |
2420.00 272.420 75436.3 |
2430.00 272.355 75341.7 |
2440.00 272.290 75247.3 |
2450.00 272.225 75152.9 |
2460.00 272.160 75058.6 |
2470.00 272.095 74964.5 |
2480.00 272.030 74870.4 |
2490.00 271.965 74776.4 |
2500.00 271.900 74682.5 |
2510.00 271.835 74588.7 |
2520.00 271.770 74495.1 |
2530.00 271.705 74401.5 |
2540.00 271.640 74308.0 |
2550.00 271.575 74214.5 |
2560.00 271.510 74121.2 |
2570.00 271.445 74028.0 |
2580.00 271.380 73934.9 |
2590.00 271.315 73841.9 |
2600.00 271.250 73748.9 |
2610.00 271.185 73656.1 |
2620.00 271.120 73563.4 |
2630.00 271.055 73470.7 |
2640.00 270.990 73378.2 |
2650.00 270.925 73285.7 |
2660.00 270.860 73193.3 |
2670.00 270.795 73101.1 |
2680.00 270.730 73008.9 |
2690.00 270.665 72916.8 |
2700.00 270.600 72824.8 |
2710.00 270.535 72732.9 |
2720.00 270.470 72641.1 |
2730.00 270.405 72549.4 |
2740.00 270.340 72457.8 |
2750.00 270.275 72366.3 |
2760.00 270.210 72274.9 |
2770.00 270.145 72183.5 |
2780.00 270.080 72092.3 |
2790.00 270.015 72001.1 |
2800.00 269.950 71910.1 |
2810.00 269.885 71819.1 |
2820.00 269.820 71728.3 |
2830.00 269.755 71637.5 |
2840.00 269.690 71546.8 |
2850.00 269.625 71456.2 |
2860.00 269.560 71365.7 |
2870.00 269.495 71275.3 |
2880.00 269.430 71185.0 |
2890.00 269.365 71094.8 |
2900.00 269.300 71004.7 |
2910.00 269.235 70914.7 |
2920.00 269.170 70824.7 |
2930.00 269.105 70734.9 |
2940.00 269.040 70645.1 |
2950.00 268.975 70555.5 |
2960.00 268.910 70465.9 |
2970.00 268.845 70376.4 |
2980.00 268.780 70287.0 |
2990.00 268.715 70197.7 |
3000.00 268.650 70108.5 |
3010.00 268.585 70019.4 |
3020.00 268.520 69930.4 |
3030.00 268.455 69841.5 |
3040.00 268.390 69752.7 |
3050.00 268.325 69663.9 |
3060.00 268.260 69575.3 |
3070.00 268.195 69486.7 |
3080.00 268.130 69398.2 |
3090.00 268.065 69309.9 |
3100.00 268.000 69221.6 |
3110.00 267.935 69133.4 |
3120.00 267.870 69045.3 |
3130.00 267.805 68957.3 |
3140.00 267.740 68869.3 |
3150.00 267.675 68781.5 |
3160.00 267.610 68693.8 |
3170.00 267.545 68606.1 |
3180.00 267.480 68518.6 |
3190.00 267.415 68431.1 |
3200.00 267.350 68343.7 |
3210.00 267.285 68256.4 |
3220.00 267.220 68169.2 |
3230.00 267.155 68082.1 |
3240.00 267.090 67995.1 |
3250.00 267.025 67908.2 |
3260.00 266.960 67821.3 |
3270.00 266.895 67734.6 |
3280.00 266.830 67647.9 |
3290.00 266.765 67561.4 |
3300.00 266.700 67474.9 |
3310.00 266.635 67388.5 |
3320.00 266.570 67302.2 |
3330.00 266.505 67216.0 |
3340.00 266.440 67129.9 |
3350.00 266.375 67043.9 |
3360.00 266.310 66957.9 |
3370.00 266.245 66872.1 |
3380.00 266.180 66786.3 |
3390.00 266.115 66700.6 |
3400.00 266.050 66615.0 |
3410.00 265.985 66529.6 |
3420.00 265.920 66444.1 |
3430.00 265.855 66358.8 |
3440.00 265.790 66273.6 |
3450.00 265.725 66188.5 |
3460.00 265.660 66103.4 |
3470.00 265.595 66018.4 |
3480.00 265.530 65933.6 |
3490.00 265.465 65848.8 |
3500.00 265.400 65764.1 |
3510.00 265.335 65679.5 |
3520.00 265.270 65595.0 |
3530.00 265.205 65510.5 |
3540.00 265.140 65426.2 |
3550.00 265.075 65341.9 |
3560.00 265.010 65257.7 |
3570.00 264.945 65173.7 |
3580.00 264.880 65089.7 |
3590.00 264.815 65005.8 |
3600.00 264.750 64921.9 |
3610.00 264.685 64838.2 |
3620.00 264.620 64754.6 |
3630.00 264.555 64671.0 |
3640.00 264.490 64587.5 |
3650.00 264.425 64504.2 |
3660.00 264.360 64420.9 |
3670.00 264.295 64337.7 |
3680.00 264.230 64254.5 |
3690.00 264.165 64171.5 |
3700.00 264.100 64088.6 |
3710.00 264.035 64005.7 |
3720.00 263.970 63922.9 |
3730.00 263.905 63840.2 |
3740.00 263.840 63757.6 |
3750.00 263.775 63675.1 |
3760.00 263.710 63592.7 |
3770.00 263.645 63510.4 |
3780.00 263.580 63428.1 |
3790.00 263.515 63345.9 |
3800.00 263.450 63263.9 |
3810.00 263.385 63181.9 |
3820.00 263.320 63100.0 |
3830.00 263.255 63018.1 |
3840.00 263.190 62936.4 |
3850.00 263.125 62854.7 |
3860.00 263.060 62773.2 |
3870.00 262.995 62691.7 |
3880.00 262.930 62610.3 |
3890.00 262.865 62529.0 |
3900.00 262.800 62447.8 |
3910.00 262.735 62366.6 |
3920.00 262.670 62285.6 |
3930.00 262.605 62204.6 |
3940.00 262.540 62123.7 |
3950.00 262.475 62042.9 |
3960.00 262.410 61962.2 |
3970.00 262.345 61881.6 |
3980.00 262.280 61801.1 |
3990.00 262.215 61720.6 |
4000.00 262.150 61640.2 |
4010.00 262.085 61559.9 |
4020.00 262.020 61479.7 |
4030.00 261.955 61399.6 |
4040.00 261.890 61319.6 |
4050.00 261.825 61239.6 |
4060.00 261.760 61159.8 |
4070.00 261.695 61080.0 |
4080.00 261.630 61000.3 |
4090.00 261.565 60920.7 |
4100.00 261.500 60841.2 |
4110.00 261.435 60761.7 |
4120.00 261.370 60682.4 |
4130.00 261.305 60603.1 |
4140.00 261.240 60523.9 |
4150.00 261.175 60444.8 |
4160.00 261.110 60365.8 |
4170.00 261.045 60286.8 |
4180.00 260.980 60208.0 |
4190.00 260.915 60129.2 |
4200.00 260.850 60050.5 |
4210.00 260.785 59971.9 |
4220.00 260.720 59893.4 |
4230.00 260.655 59814.9 |
4240.00 260.590 59736.6 |
4250.00 260.525 59658.3 |
4260.00 260.460 59580.1 |
4270.00 260.395 59502.0 |
4280.00 260.330 59424.0 |
4290.00 260.265 59346.1 |
4300.00 260.200 59268.2 |
4310.00 260.135 59190.4 |
4320.00 260.070 59112.7 |
4330.00 260.005 59035.1 |
4340.00 259.940 58957.6 |
4350.00 259.875 58880.1 |
4360.00 259.810 58802.8 |
4370.00 259.745 58725.5 |
4380.00 259.680 58648.3 |
4390.00 259.615 58571.2 |
4400.00 259.550 58494.2 |
4410.00 259.485 58417.2 |
4420.00 259.420 58340.3 |
4430.00 259.355 58263.5 |
4440.00 259.290 58186.8 |
4450.00 259.225 58110.2 |
4460.00 259.160 58033.7 |
4470.00 259.095 57957.2 |
4480.00 259.030 57880.8 |
4490.00 258.965 57804.5 |
4500.00 258.900 57728.3 |
4510.00 258.835 57652.2 |
4520.00 258.770 57576.1 |
4530.00 258.705 57500.2 |
4540.00 258.640 57424.3 |
4550.00 258.575 57348.5 |
4560.00 258.510 57272.7 |
4570.00 258.445 57197.1 |
4580.00 258.380 57121.5 |
4590.00 258.315 57046.0 |
4600.00 258.250 56970.6 |
4610.00 258.185 56895.3 |
4620.00 258.120 56820.1 |
4630.00 258.055 56744.9 |
4640.00 257.990 56669.8 |
4650.00 257.925 56594.8 |
4660.00 257.860 56519.9 |
4670.00 257.795 56445.0 |
4680.00 257.730 56370.3 |
4690.00 257.665 56295.6 |
4700.00 257.600 56221.0 |
4710.00 257.535 56146.5 |
4720.00 257.470 56072.0 |
4730.00 257.405 55997.7 |
4740.00 257.340 55923.4 |
4750.00 257.275 55849.2 |
4760.00 257.210 55775.1 |
4770.00 257.145 55701.0 |
4780.00 257.080 55627.1 |
4790.00 257.015 55553.2 |
4800.00 256.950 55479.4 |
4810.00 256.885 55405.7 |
4820.00 256.820 55332.0 |
4830.00 256.755 55258.5 |
4840.00 256.690 55185.0 |
4850.00 256.625 55111.6 |
4860.00 256.560 55038.2 |
4870.00 256.495 54965.0 |
4880.00 256.430 54891.8 |
4890.00 256.365 54818.7 |
4900.00 256.300 54745.7 |
4910.00 256.235 54672.8 |
4920.00 256.170 54599.9 |
4930.00 256.105 54527.1 |
4940.00 256.040 54454.5 |
4950.00 255.975 54381.8 |
4960.00 255.910 54309.3 |
4970.00 255.845 54236.8 |
4980.00 255.780 54164.4 |
4990.00 255.715 54092.1 |
5000.00 255.650 54019.9 |
5010.00 255.585 53947.8 |
5020.00 255.520 53875.7 |
5030.00 255.455 53803.7 |
5040.00 255.390 53731.8 |
5050.00 255.325 53659.9 |
5060.00 255.260 53588.2 |
5070.00 255.195 53516.5 |
5080.00 255.130 53444.9 |
5090.00 255.065 53373.4 |
5100.00 255.000 53301.9 |
5110.00 254.935 53230.6 |
5120.00 254.870 53159.3 |
5130.00 254.805 53088.0 |
5140.00 254.740 53016.9 |
5150.00 254.675 52945.8 |
5160.00 254.610 52874.9 |
5170.00 254.545 52803.9 |
5180.00 254.480 52733.1 |
5190.00 254.415 52662.4 |
5200.00 254.350 52591.7 |
5210.00 254.285 52521.1 |
5220.00 254.220 52450.6 |
5230.00 254.155 52380.1 |
5240.00 254.090 52309.7 |
5250.00 254.025 52239.4 |
5260.00 253.960 52169.2 |
5270.00 253.895 52099.1 |
5280.00 253.830 52029.0 |
5290.00 253.765 51959.0 |
5300.00 253.700 51889.1 |
5310.00 253.635 51819.3 |
5320.00 253.570 51749.5 |
5330.00 253.505 51679.8 |
5340.00 253.440 51610.2 |
5350.00 253.375 51540.7 |
5360.00 253.310 51471.3 |
5370.00 253.245 51401.9 |
5380.00 253.180 51332.6 |
5390.00 253.115 51263.3 |
5400.00 253.050 51194.2 |
5410.00 252.985 51125.1 |
5420.00 252.920 51056.1 |
5430.00 252.855 50987.2 |
5440.00 252.790 50918.3 |
5450.00 252.725 50849.6 |
5460.00 252.660 50780.9 |
5470.00 252.595 50712.2 |
5480.00 252.530 50643.7 |
5490.00 252.465 50575.2 |
5500.00 252.400 50506.8 |
5510.00 252.335 50438.5 |
5520.00 252.270 50370.2 |
5530.00 252.205 50302.1 |
5540.00 252.140 50234.0 |
5550.00 252.075 50165.9 |
5560.00 252.010 50098.0 |
5570.00 251.945 50030.1 |
5580.00 251.880 49962.3 |
5590.00 251.815 49894.6 |
5600.00 251.750 49826.9 |
5610.00 251.685 49759.3 |
5620.00 251.620 49691.8 |
5630.00 251.555 49624.4 |
5640.00 251.490 49557.0 |
5650.00 251.425 49489.8 |
5660.00 251.360 49422.5 |
5670.00 251.295 49355.4 |
5680.00 251.230 49288.4 |
5690.00 251.165 49221.4 |
5700.00 251.100 49154.5 |
5710.00 251.035 49087.6 |
5720.00 250.970 49020.8 |
5730.00 250.905 48954.2 |
5740.00 250.840 48887.5 |
5750.00 250.775 48821.0 |
5760.00 250.710 48754.5 |
5770.00 250.645 48688.1 |
5780.00 250.580 48621.8 |
5790.00 250.515 48555.5 |
5800.00 250.450 48489.4 |
5810.00 250.385 48423.3 |
5820.00 250.320 48357.2 |
5830.00 250.255 48291.3 |
5840.00 250.190 48225.4 |
5850.00 250.125 48159.6 |
5860.00 250.060 48093.8 |
5870.00 249.995 48028.1 |
5880.00 249.930 47962.5 |
5890.00 249.865 47897.0 |
5900.00 249.800 47831.6 |
5910.00 249.735 47766.2 |
5920.00 249.670 47700.9 |
5930.00 249.605 47635.6 |
5940.00 249.540 47570.5 |
5950.00 249.475 47505.4 |
5960.00 249.410 47440.4 |
5970.00 249.345 47375.4 |
5980.00 249.280 47310.6 |
5990.00 249.215 47245.8 |
6000.00 249.150 47181.0 |
6010.00 249.085 47116.4 |
6020.00 249.020 47051.8 |
6030.00 248.955 46987.3 |
6040.00 248.890 46922.8 |
6050.00 248.825 46858.5 |
6060.00 248.760 46794.2 |
6070.00 248.695 46729.9 |
6080.00 248.630 46665.8 |
6090.00 248.565 46601.7 |
6100.00 248.500 46537.7 |
6110.00 248.435 46473.7 |
6120.00 248.370 46409.9 |
6130.00 248.305 46346.1 |
6140.00 248.240 46282.3 |
6150.00 248.175 46218.7 |
6160.00 248.110 46155.1 |
6170.00 248.045 46091.6 |
6180.00 247.980 46028.1 |
6190.00 247.915 45964.7 |
6200.00 247.850 45901.4 |
6210.00 247.785 45838.2 |
6220.00 247.720 45775.0 |
6230.00 247.655 45711.9 |
6240.00 247.590 45648.9 |
6250.00 247.525 45586.0 |
6260.00 247.460 45523.1 |
6270.00 247.395 45460.3 |
6280.00 247.330 45397.5 |
6290.00 247.265 45334.9 |
6300.00 247.200 45272.3 |
6310.00 247.135 45209.7 |
6320.00 247.070 45147.3 |
6330.00 247.005 45084.9 |
6340.00 246.940 45022.5 |
6350.00 246.875 44960.3 |
6360.00 246.810 44898.1 |
6370.00 246.745 44836.0 |
6380.00 246.680 44774.0 |
6390.00 246.615 44712.0 |
6400.00 246.550 44650.1 |
6410.00 246.485 44588.2 |
6420.00 246.420 44526.5 |
6430.00 246.355 44464.8 |
6440.00 246.290 44403.2 |
6450.00 246.225 44341.6 |
6460.00 246.160 44280.1 |
6470.00 246.095 44218.7 |
6480.00 246.030 44157.3 |
6490.00 245.965 44096.1 |
6500.00 245.900 44034.8 |
6510.00 245.835 43973.7 |
6520.00 245.770 43912.6 |
6530.00 245.705 43851.6 |
6540.00 245.640 43790.7 |
6550.00 245.575 43729.8 |
6560.00 245.510 43669.0 |
6570.00 245.445 43608.3 |
6580.00 245.380 43547.6 |
6590.00 245.315 43487.0 |
6600.00 245.250 43426.5 |
6610.00 245.185 43366.0 |
6620.00 245.120 43305.6 |
6630.00 245.055 43245.3 |
6640.00 244.990 43185.1 |
6650.00 244.925 43124.9 |
6660.00 244.860 43064.8 |
6670.00 244.795 43004.7 |
6680.00 244.730 42944.7 |
6690.00 244.665 42884.8 |
6700.00 244.600 42825.0 |
6710.00 244.535 42765.2 |
6720.00 244.470 42705.5 |
6730.00 244.405 42645.8 |
6740.00 244.340 42586.3 |
6750.00 244.275 42526.7 |
6760.00 244.210 42467.3 |
6770.00 244.145 42407.9 |
6780.00 244.080 42348.6 |
6790.00 244.015 42289.4 |
6800.00 243.950 42230.2 |
6810.00 243.885 42171.1 |
6820.00 243.820 42112.1 |
6830.00 243.755 42053.1 |
6840.00 243.690 41994.2 |
6850.00 243.625 41935.3 |
6860.00 243.560 41876.6 |
6870.00 243.495 41817.9 |
6880.00 243.430 41759.2 |
6890.00 243.365 41700.7 |
6900.00 243.300 41642.2 |
6910.00 243.235 41583.7 |
6920.00 243.170 41525.3 |
6930.00 243.105 41467.0 |
6940.00 243.040 41408.8 |
6950.00 242.975 41350.6 |
6960.00 242.910 41292.5 |
6970.00 242.845 41234.5 |
6980.00 242.780 41176.5 |
6990.00 242.715 41118.6 |
7000.00 242.650 41060.7 |
7010.00 242.585 41003.0 |
7020.00 242.520 40945.3 |
7030.00 242.455 40887.6 |
7040.00 242.390 40830.0 |
7050.00 242.325 40772.5 |
7060.00 242.260 40715.1 |
7070.00 242.195 40657.7 |
7080.00 242.130 40600.4 |
7090.00 242.065 40543.1 |
7100.00 242.000 40485.9 |
7110.00 241.935 40428.8 |
7120.00 241.870 40371.7 |
7130.00 241.805 40314.8 |
7140.00 241.740 40257.8 |
7150.00 241.675 40201.0 |
7160.00 241.610 40144.2 |
7170.00 241.545 40087.4 |
7180.00 241.480 40030.8 |
7190.00 241.415 39974.2 |
7200.00 241.350 39917.6 |
7210.00 241.285 39861.2 |
7220.00 241.220 39804.8 |
7230.00 241.155 39748.4 |
7240.00 241.090 39692.1 |
7250.00 241.025 39635.9 |
7260.00 240.960 39579.8 |
7270.00 240.895 39523.7 |
7280.00 240.830 39467.7 |
7290.00 240.765 39411.7 |
7300.00 240.700 39355.8 |
7310.00 240.635 39300.0 |
7320.00 240.570 39244.2 |
7330.00 240.505 39188.5 |
7340.00 240.440 39132.9 |
7350.00 240.375 39077.3 |
7360.00 240.310 39021.8 |
7370.00 240.245 38966.4 |
7380.00 240.180 38911.0 |
7390.00 240.115 38855.7 |
7400.00 240.050 38800.4 |
7410.00 239.985 38745.3 |
7420.00 239.920 38690.1 |
7430.00 239.855 38635.1 |
7440.00 239.790 38580.1 |
7450.00 239.725 38525.1 |
7460.00 239.660 38470.3 |
7470.00 239.595 38415.5 |
7480.00 239.530 38360.7 |
7490.00 239.465 38306.0 |
7500.00 239.400 38251.4 |
7510.00 239.335 38196.9 |
7520.00 239.270 38142.4 |
7530.00 239.205 38087.9 |
7540.00 239.140 38033.6 |
7550.00 239.075 37979.3 |
7560.00 239.010 37925.0 |
7570.00 238.945 37870.9 |
7580.00 238.880 37816.7 |
7590.00 238.815 37762.7 |
7600.00 238.750 37708.7 |
7610.00 238.685 37654.8 |
7620.00 238.620 37600.9 |
7630.00 238.555 37547.1 |
7640.00 238.490 37493.4 |
7650.00 238.425 37439.7 |
7660.00 238.360 37386.1 |
7670.00 238.295 37332.5 |
7680.00 238.230 37279.0 |
7690.00 238.165 37225.6 |
7700.00 238.100 37172.2 |
7710.00 238.035 37118.9 |
7720.00 237.970 37065.7 |
7730.00 237.905 37012.5 |
7740.00 237.840 36959.4 |
7750.00 237.775 36906.3 |
7760.00 237.710 36853.3 |
7770.00 237.645 36800.4 |
7780.00 237.580 36747.5 |
7790.00 237.515 36694.7 |
7800.00 237.450 36642.0 |
7810.00 237.385 36589.3 |
7820.00 237.320 36536.7 |
7830.00 237.255 36484.1 |
7840.00 237.190 36431.6 |
7850.00 237.125 36379.1 |
7860.00 237.060 36326.8 |
7870.00 236.995 36274.4 |
7880.00 236.930 36222.2 |
7890.00 236.865 36170.0 |
7900.00 236.800 36117.8 |
7910.00 236.735 36065.8 |
7920.00 236.670 36013.8 |
7930.00 236.605 35961.8 |
7940.00 236.540 35909.9 |
7950.00 236.475 35858.1 |
7960.00 236.410 35806.3 |
7970.00 236.345 35754.6 |
7980.00 236.280 35702.9 |
7990.00 236.215 35651.3 |
8000.00 236.150 35599.8 |
8010.00 236.085 35548.3 |
8020.00 236.020 35496.9 |
8030.00 235.955 35445.6 |
8040.00 235.890 35394.3 |
8050.00 235.825 35343.1 |
8060.00 235.760 35291.9 |
8070.00 235.695 35240.8 |
8080.00 235.630 35189.7 |
8090.00 235.565 35138.7 |
8100.00 235.500 35087.8 |
8110.00 235.435 35036.9 |
8120.00 235.370 34986.1 |
8130.00 235.305 34935.4 |
8140.00 235.240 34884.7 |
8150.00 235.175 34834.0 |
8160.00 235.110 34783.5 |
8170.00 235.045 34733.0 |
8180.00 234.980 34682.5 |
8190.00 234.915 34632.1 |
8200.00 234.850 34581.8 |
8210.00 234.785 34531.5 |
8220.00 234.720 34481.3 |
8230.00 234.655 34431.1 |
8240.00 234.590 34381.0 |
8250.00 234.525 34331.0 |
8260.00 234.460 34281.0 |
8270.00 234.395 34231.1 |
8280.00 234.330 34181.2 |
8290.00 234.265 34131.4 |
8300.00 234.200 34081.7 |
8310.00 234.135 34032.0 |
8320.00 234.070 33982.4 |
8330.00 234.005 33932.8 |
8340.00 233.940 33883.3 |
8350.00 233.875 33833.8 |
8360.00 233.810 33784.4 |
8370.00 233.745 33735.1 |
8380.00 233.680 33685.8 |
8390.00 233.615 33636.6 |
8400.00 233.550 33587.5 |
8410.00 233.485 33538.3 |
8420.00 233.420 33489.3 |
8430.00 233.355 33440.3 |
8440.00 233.290 33391.4 |
8450.00 233.225 33342.5 |
8460.00 233.160 33293.7 |
8470.00 233.095 33245.0 |
8480.00 233.030 33196.3 |
8490.00 232.965 33147.6 |
8500.00 232.900 33099.0 |
8510.00 232.835 33050.5 |
8520.00 232.770 33002.1 |
8530.00 232.705 32953.6 |
8540.00 232.640 32905.3 |
8550.00 232.575 32857.0 |
8560.00 232.510 32808.8 |
8570.00 232.445 32760.6 |
8580.00 232.380 32712.5 |
8590.00 232.315 32664.4 |
8600.00 232.250 32616.4 |
8610.00 232.185 32568.4 |
8620.00 232.120 32520.6 |
8630.00 232.055 32472.7 |
8640.00 231.990 32424.9 |
8650.00 231.925 32377.2 |
8660.00 231.860 32329.6 |
8670.00 231.795 32282.0 |
8680.00 231.730 32234.4 |
8690.00 231.665 32186.9 |
8700.00 231.600 32139.5 |
8710.00 231.535 32092.1 |
8720.00 231.470 32044.8 |
8730.00 231.405 31997.5 |
8740.00 231.340 31950.3 |
8750.00 231.275 31903.1 |
8760.00 231.210 31856.0 |
8770.00 231.145 31809.0 |
8780.00 231.080 31762.0 |
8790.00 231.015 31715.1 |
8800.00 230.950 31668.2 |
8810.00 230.885 31621.4 |
8820.00 230.820 31574.6 |
8830.00 230.755 31527.9 |
8840.00 230.690 31481.3 |
8850.00 230.625 31434.7 |
8860.00 230.560 31388.1 |
8870.00 230.495 31341.7 |
8880.00 230.430 31295.2 |
8890.00 230.365 31248.9 |
8900.00 230.300 31202.6 |
8910.00 230.235 31156.3 |
8920.00 230.170 31110.1 |
8930.00 230.105 31063.9 |
8940.00 230.040 31017.9 |
8950.00 229.975 30971.8 |
8960.00 229.910 30925.8 |
8970.00 229.845 30879.9 |
8980.00 229.780 30834.0 |
8990.00 229.715 30788.2 |
9000.00 229.650 30742.5 |
9010.00 229.585 30696.8 |
9020.00 229.520 30651.1 |
9030.00 229.455 30605.5 |
9040.00 229.390 30560.0 |
9050.00 229.325 30514.5 |
9060.00 229.260 30469.0 |
9070.00 229.195 30423.7 |
9080.00 229.130 30378.4 |
9090.00 229.065 30333.1 |
9100.00 229.000 30287.9 |
9110.00 228.935 30242.7 |
9120.00 228.870 30197.6 |
9130.00 228.805 30152.6 |
9140.00 228.740 30107.6 |
9150.00 228.675 30062.6 |
9160.00 228.610 30017.7 |
9170.00 228.545 29972.9 |
9180.00 228.480 29928.1 |
9190.00 228.415 29883.4 |
9200.00 228.350 29838.7 |
9210.00 228.285 29794.1 |
9220.00 228.220 29749.6 |
9230.00 228.155 29705.1 |
9240.00 228.090 29660.6 |
9250.00 228.025 29616.2 |
9260.00 227.960 29571.9 |
9270.00 227.895 29527.6 |
9280.00 227.830 29483.3 |
9290.00 227.765 29439.2 |
9300.00 227.700 29395.0 |
9310.00 227.635 29351.0 |
9320.00 227.570 29306.9 |
9330.00 227.505 29263.0 |
9340.00 227.440 29219.0 |
9350.00 227.375 29175.2 |
9360.00 227.310 29131.4 |
9370.00 227.245 29087.6 |
9380.00 227.180 29043.9 |
9390.00 227.115 29000.3 |
9400.00 227.050 28956.7 |
9410.00 226.985 28913.1 |
9420.00 226.920 28869.6 |
9430.00 226.855 28826.2 |
9440.00 226.790 28782.8 |
9450.00 226.725 28739.5 |
9460.00 226.660 28696.2 |
9470.00 226.595 28653.0 |
9480.00 226.530 28609.8 |
9490.00 226.465 28566.7 |
9500.00 226.400 28523.6 |
9510.00 226.335 28480.6 |
9520.00 226.270 28437.6 |
9530.00 226.205 28394.7 |
9540.00 226.140 28351.9 |
9550.00 226.075 28309.1 |
9560.00 226.010 28266.3 |
9570.00 225.945 28223.6 |
9580.00 225.880 28181.0 |
9590.00 225.815 28138.4 |
9600.00 225.750 28095.8 |
9610.00 225.685 28053.3 |
9620.00 225.620 28010.9 |
9630.00 225.555 27968.5 |
9640.00 225.490 27926.2 |
9650.00 225.425 27883.9 |
9660.00 225.360 27841.7 |
9670.00 225.295 27799.5 |
9680.00 225.230 27757.3 |
9690.00 225.165 27715.3 |
9700.00 225.100 27673.2 |
9710.00 225.035 27631.3 |
9720.00 224.970 27589.3 |
9730.00 224.905 27547.5 |
9740.00 224.840 27505.7 |
9750.00 224.775 27463.9 |
9760.00 224.710 27422.2 |
9770.00 224.645 27380.5 |
9780.00 224.580 27338.9 |
9790.00 224.515 27297.3 |
9800.00 224.450 27255.8 |
9810.00 224.385 27214.4 |
9820.00 224.320 27172.9 |
9830.00 224.255 27131.6 |
9840.00 224.190 27090.3 |
9850.00 224.125 27049.0 |
9860.00 224.060 27007.8 |
9870.00 223.995 26966.7 |
9880.00 223.930 26925.6 |
9890.00 223.865 26884.5 |
9900.00 223.800 26843.5 |
9910.00 223.735 26802.6 |
9920.00 223.670 26761.7 |
9930.00 223.605 26720.8 |
9940.00 223.540 26680.0 |
9950.00 223.475 26639.3 |
9960.00 223.410 26598.6 |
9970.00 223.345 26557.9 |
9980.00 223.280 26517.3 |
9990.00 223.215 26476.8 |
10000.0 223.150 26436.3 |
10010.0 223.085 26395.8 |
10020.0 223.020 26355.4 |
10030.0 222.955 26315.1 |
10040.0 222.890 26274.8 |
10050.0 222.825 26234.5 |
10060.0 222.760 26194.3 |
10070.0 222.695 26154.2 |
10080.0 222.630 26114.1 |
10090.0 222.565 26074.0 |
10100.0 222.500 26034.0 |
10110.0 222.435 25994.1 |
10120.0 222.370 25954.2 |
10130.0 222.305 25914.3 |
10140.0 222.240 25874.5 |
10150.0 222.175 25834.8 |
10160.0 222.110 25795.1 |
10170.0 222.045 25755.4 |
10180.0 221.980 25715.8 |
10190.0 221.915 25676.3 |
10200.0 221.850 25636.8 |
10210.0 221.785 25597.3 |
10220.0 221.720 25557.9 |
10230.0 221.655 25518.6 |
10240.0 221.590 25479.3 |
10250.0 221.525 25440.0 |
10260.0 221.460 25400.8 |
10270.0 221.395 25361.6 |
10280.0 221.330 25322.5 |
10290.0 221.265 25283.5 |
10300.0 221.200 25244.5 |
10310.0 221.135 25205.5 |
10320.0 221.070 25166.6 |
10330.0 221.005 25127.7 |
10340.0 220.940 25088.9 |
10350.0 220.875 25050.1 |
10360.0 220.810 25011.4 |
10370.0 220.745 24972.7 |
10380.0 220.680 24934.1 |
10390.0 220.615 24895.5 |
10400.0 220.550 24857.0 |
10410.0 220.485 24818.5 |
10420.0 220.420 24780.1 |
10430.0 220.355 24741.7 |
10440.0 220.290 24703.4 |
10450.0 220.225 24665.1 |
10460.0 220.160 24626.8 |
10470.0 220.095 24588.7 |
10480.0 220.030 24550.5 |
10490.0 219.965 24512.4 |
10500.0 219.900 24474.4 |
10510.0 219.835 24436.4 |
10520.0 219.770 24398.4 |
10530.0 219.705 24360.5 |
10540.0 219.640 24322.7 |
10550.0 219.575 24284.9 |
10560.0 219.510 24247.1 |
10570.0 219.445 24209.4 |
10580.0 219.380 24171.7 |
10590.0 219.315 24134.1 |
10600.0 219.250 24096.5 |
10610.0 219.185 24059.0 |
10620.0 219.120 24021.5 |
10630.0 219.055 23984.1 |
10640.0 218.990 23946.7 |
10650.0 218.925 23909.4 |
10660.0 218.860 23872.1 |
10670.0 218.795 23834.9 |
10680.0 218.730 23797.7 |
10690.0 218.665 23760.5 |
10700.0 218.600 23723.4 |
10710.0 218.535 23686.4 |
10720.0 218.470 23649.4 |
10730.0 218.405 23612.4 |
10740.0 218.340 23575.5 |
10750.0 218.275 23538.6 |
10760.0 218.210 23501.8 |
10770.0 218.145 23465.0 |
10780.0 218.080 23428.3 |
10790.0 218.015 23391.6 |
10800.0 217.950 23355.0 |
10810.0 217.885 23318.4 |
10820.0 217.820 23281.9 |
10830.0 217.755 23245.4 |
10840.0 217.690 23208.9 |
10850.0 217.625 23172.5 |
10860.0 217.560 23136.2 |
10870.0 217.495 23099.9 |
10880.0 217.430 23063.6 |
10890.0 217.365 23027.4 |
10900.0 217.300 22991.2 |
10910.0 217.235 22955.1 |
10920.0 217.170 22919.0 |
10930.0 217.105 22883.0 |
10940.0 217.040 22847.0 |
10950.0 216.975 22811.1 |
10960.0 216.910 22775.2 |
10970.0 216.845 22739.3 |
10980.0 216.780 22703.5 |
10990.0 216.715 22667.8 |
11000.0 216.650 22632.1 |
11010.0 216.650 22596.4 |
11020.0 216.650 22560.8 |
11030.0 216.650 22525.3 |
11040.0 216.650 22489.8 |
11050.0 216.650 22454.3 |
11060.0 216.650 22418.9 |
11070.0 216.650 22383.6 |
11080.0 216.650 22348.4 |
11090.0 216.650 22313.1 |
11100.0 216.650 22278.0 |
11110.0 216.650 22242.9 |
11120.0 216.650 22207.8 |
11130.0 216.650 22172.8 |
11140.0 216.650 22137.9 |
11150.0 216.650 22103.0 |
11160.0 216.650 22068.2 |
11170.0 216.650 22033.4 |
11180.0 216.650 21998.7 |
11190.0 216.650 21964.0 |
11200.0 216.650 21929.4 |
11210.0 216.650 21894.9 |
11220.0 216.650 21860.4 |
11230.0 216.650 21825.9 |
11240.0 216.650 21791.6 |
11250.0 216.650 21757.2 |
11260.0 216.650 21722.9 |
11270.0 216.650 21688.7 |
11280.0 216.650 21654.5 |
11290.0 216.650 21620.4 |
11300.0 216.650 21586.3 |
11310.0 216.650 21552.3 |
11320.0 216.650 21518.4 |
11330.0 216.650 21484.5 |
11340.0 216.650 21450.6 |
11350.0 216.650 21416.8 |
11360.0 216.650 21383.1 |
11370.0 216.650 21349.4 |
11380.0 216.650 21315.7 |
11390.0 216.650 21282.2 |
11400.0 216.650 21248.6 |
11410.0 216.650 21215.1 |
11420.0 216.650 21181.7 |
11430.0 216.650 21148.3 |
11440.0 216.650 21115.0 |
11450.0 216.650 21081.8 |
11460.0 216.650 21048.5 |
11470.0 216.650 21015.4 |
11480.0 216.650 20982.3 |
11490.0 216.650 20949.2 |
11500.0 216.650 20916.2 |
11510.0 216.650 20883.2 |
11520.0 216.650 20850.3 |
11530.0 216.650 20817.5 |
11540.0 216.650 20784.7 |
11550.0 216.650 20751.9 |
11560.0 216.650 20719.2 |
11570.0 216.650 20686.6 |
11580.0 216.650 20654.0 |
11590.0 216.650 20621.4 |
11600.0 216.650 20589.0 |
11610.0 216.650 20556.5 |
11620.0 216.650 20524.1 |
11630.0 216.650 20491.8 |
11640.0 216.650 20459.5 |
11650.0 216.650 20427.3 |
11660.0 216.650 20395.1 |
11670.0 216.650 20362.9 |
11680.0 216.650 20330.9 |
11690.0 216.650 20298.8 |
11700.0 216.650 20266.8 |
11710.0 216.650 20234.9 |
11720.0 216.650 20203.0 |
11730.0 216.650 20171.2 |
11740.0 216.650 20139.4 |
11750.0 216.650 20107.7 |
11760.0 216.650 20076.0 |
11770.0 216.650 20044.4 |
11780.0 216.650 20012.8 |
11790.0 216.650 19981.2 |
11800.0 216.650 19949.8 |
11810.0 216.650 19918.3 |
11820.0 216.650 19886.9 |
11830.0 216.650 19855.6 |
11840.0 216.650 19824.3 |
11850.0 216.650 19793.1 |
11860.0 216.650 19761.9 |
11870.0 216.650 19730.8 |
11880.0 216.650 19699.7 |
11890.0 216.650 19668.6 |
11900.0 216.650 19637.6 |
11910.0 216.650 19606.7 |
11920.0 216.650 19575.8 |
11930.0 216.650 19545.0 |
11940.0 216.650 19514.2 |
11950.0 216.650 19483.4 |
11960.0 216.650 19452.7 |
11970.0 216.650 19422.1 |
11980.0 216.650 19391.5 |
11990.0 216.650 19360.9 |
12000.0 216.650 19330.4 |
12010.0 216.650 19299.9 |
12020.0 216.650 19269.5 |
12030.0 216.650 19239.2 |
12040.0 216.650 19208.9 |
12050.0 216.650 19178.6 |
12060.0 216.650 19148.4 |
12070.0 216.650 19118.2 |
12080.0 216.650 19088.1 |
12090.0 216.650 19058.0 |
12100.0 216.650 19028.0 |
12110.0 216.650 18998.0 |
12120.0 216.650 18968.1 |
12130.0 216.650 18938.2 |
12140.0 216.650 18908.3 |
12150.0 216.650 18878.5 |
12160.0 216.650 18848.8 |
12170.0 216.650 18819.1 |
12180.0 216.650 18789.4 |
12190.0 216.650 18759.8 |
12200.0 216.650 18730.3 |
12210.0 216.650 18700.8 |
12220.0 216.650 18671.3 |
12230.0 216.650 18641.9 |
12240.0 216.650 18612.5 |
12250.0 216.650 18583.2 |
12260.0 216.650 18553.9 |
12270.0 216.650 18524.7 |
12280.0 216.650 18495.5 |
12290.0 216.650 18466.3 |
12300.0 216.650 18437.2 |
12310.0 216.650 18408.2 |
12320.0 216.650 18379.2 |
12330.0 216.650 18350.2 |
12340.0 216.650 18321.3 |
12350.0 216.650 18292.4 |
12360.0 216.650 18263.6 |
12370.0 216.650 18234.8 |
12380.0 216.650 18206.1 |
12390.0 216.650 18177.4 |
12400.0 216.650 18148.8 |
12410.0 216.650 18120.2 |
12420.0 216.650 18091.6 |
12430.0 216.650 18063.1 |
12440.0 216.650 18034.7 |
12450.0 216.650 18006.3 |
12460.0 216.650 17977.9 |
12470.0 216.650 17949.6 |
12480.0 216.650 17921.3 |
12490.0 216.650 17893.0 |
12500.0 216.650 17864.8 |
12510.0 216.650 17836.7 |
12520.0 216.650 17808.6 |
12530.0 216.650 17780.5 |
12540.0 216.650 17752.5 |
12550.0 216.650 17724.5 |
12560.0 216.650 17696.6 |
12570.0 216.650 17668.7 |
12580.0 216.650 17640.9 |
12590.0 216.650 17613.1 |
12600.0 216.650 17585.4 |
12610.0 216.650 17557.6 |
12620.0 216.650 17530.0 |
12630.0 216.650 17502.4 |
12640.0 216.650 17474.8 |
12650.0 216.650 17447.2 |
12660.0 216.650 17419.8 |
12670.0 216.650 17392.3 |
12680.0 216.650 17364.9 |
12690.0 216.650 17337.5 |
12700.0 216.650 17310.2 |
12710.0 216.650 17283.0 |
12720.0 216.650 17255.7 |
12730.0 216.650 17228.5 |
12740.0 216.650 17201.4 |
12750.0 216.650 17174.3 |
12760.0 216.650 17147.2 |
12770.0 216.650 17120.2 |
12780.0 216.650 17093.2 |
12790.0 216.650 17066.3 |
12800.0 216.650 17039.4 |
12810.0 216.650 17012.6 |
12820.0 216.650 16985.7 |
12830.0 216.650 16959.0 |
12840.0 216.650 16932.3 |
12850.0 216.650 16905.6 |
12860.0 216.650 16878.9 |
12870.0 216.650 16852.4 |
12880.0 216.650 16825.8 |
12890.0 216.650 16799.3 |
12900.0 216.650 16772.8 |
12910.0 216.650 16746.4 |
12920.0 216.650 16720.0 |
12930.0 216.650 16693.7 |
12940.0 216.650 16667.4 |
12950.0 216.650 16641.1 |
12960.0 216.650 16614.9 |
12970.0 216.650 16588.7 |
12980.0 216.650 16562.6 |
12990.0 216.650 16536.5 |
13000.0 216.650 16510.4 |
13010.0 216.650 16484.4 |
13020.0 216.650 16458.4 |
13030.0 216.650 16432.5 |
13040.0 216.650 16406.6 |
13050.0 216.650 16380.7 |
13060.0 216.650 16354.9 |
13070.0 216.650 16329.2 |
13080.0 216.650 16303.4 |
13090.0 216.650 16277.7 |
13100.0 216.650 16252.1 |
13110.0 216.650 16226.5 |
13120.0 216.650 16200.9 |
13130.0 216.650 16175.4 |
13140.0 216.650 16149.9 |
13150.0 216.650 16124.5 |
13160.0 216.650 16099.1 |
13170.0 216.650 16073.7 |
13180.0 216.650 16048.4 |
13190.0 216.650 16023.1 |
13200.0 216.650 15997.8 |
13210.0 216.650 15972.6 |
13220.0 216.650 15947.5 |
13230.0 216.650 15922.3 |
13240.0 216.650 15897.2 |
13250.0 216.650 15872.2 |
13260.0 216.650 15847.2 |
13270.0 216.650 15822.2 |
13280.0 216.650 15797.3 |
13290.0 216.650 15772.4 |
13300.0 216.650 15747.5 |
13310.0 216.650 15722.7 |
13320.0 216.650 15698.0 |
13330.0 216.650 15673.2 |
13340.0 216.650 15648.5 |
13350.0 216.650 15623.9 |
13360.0 216.650 15599.3 |
13370.0 216.650 15574.7 |
13380.0 216.650 15550.1 |
13390.0 216.650 15525.6 |
13400.0 216.650 15501.2 |
13410.0 216.650 15476.7 |
13420.0 216.650 15452.4 |
13430.0 216.650 15428.0 |
13440.0 216.650 15403.7 |
13450.0 216.650 15379.4 |
13460.0 216.650 15355.2 |
13470.0 216.650 15331.0 |
13480.0 216.650 15306.8 |
13490.0 216.650 15282.7 |
13500.0 216.650 15258.7 |
13510.0 216.650 15234.6 |
13520.0 216.650 15210.6 |
13530.0 216.650 15186.6 |
13540.0 216.650 15162.7 |
13550.0 216.650 15138.8 |
13560.0 216.650 15115.0 |
13570.0 216.650 15091.1 |
13580.0 216.650 15067.4 |
13590.0 216.650 15043.6 |
13600.0 216.650 15019.9 |
13610.0 216.650 14996.3 |
13620.0 216.650 14972.6 |
13630.0 216.650 14949.0 |
13640.0 216.650 14925.5 |
13650.0 216.650 14902.0 |
13660.0 216.650 14878.5 |
13670.0 216.650 14855.0 |
13680.0 216.650 14831.6 |
13690.0 216.650 14808.3 |
13700.0 216.650 14784.9 |
13710.0 216.650 14761.6 |
13720.0 216.650 14738.4 |
13730.0 216.650 14715.2 |
13740.0 216.650 14692.0 |
13750.0 216.650 14668.8 |
13760.0 216.650 14645.7 |
13770.0 216.650 14622.6 |
13780.0 216.650 14599.6 |
13790.0 216.650 14576.6 |
13800.0 216.650 14553.6 |
13810.0 216.650 14530.7 |
13820.0 216.650 14507.8 |
13830.0 216.650 14484.9 |
13840.0 216.650 14462.1 |
13850.0 216.650 14439.3 |
13860.0 216.650 14416.6 |
13870.0 216.650 14393.9 |
13880.0 216.650 14371.2 |
13890.0 216.650 14348.5 |
13900.0 216.650 14325.9 |
13910.0 216.650 14303.4 |
13920.0 216.650 14280.8 |
13930.0 216.650 14258.3 |
13940.0 216.650 14235.9 |
13950.0 216.650 14213.4 |
13960.0 216.650 14191.0 |
13970.0 216.650 14168.7 |
13980.0 216.650 14146.3 |
13990.0 216.650 14124.1 |
14000.0 216.650 14101.8 |
14010.0 216.650 14079.6 |
14020.0 216.650 14057.4 |
14030.0 216.650 14035.2 |
14040.0 216.650 14013.1 |
14050.0 216.650 13991.1 |
14060.0 216.650 13969.0 |
14070.0 216.650 13947.0 |
14080.0 216.650 13925.0 |
14090.0 216.650 13903.1 |
14100.0 216.650 13881.2 |
14110.0 216.650 13859.3 |
14120.0 216.650 13837.5 |
14130.0 216.650 13815.7 |
14140.0 216.650 13793.9 |
14150.0 216.650 13772.2 |
14160.0 216.650 13750.5 |
14170.0 216.650 13728.8 |
14180.0 216.650 13707.2 |
14190.0 216.650 13685.6 |
14200.0 216.650 13664.0 |
14210.0 216.650 13642.5 |
14220.0 216.650 13621.0 |
14230.0 216.650 13599.5 |
14240.0 216.650 13578.1 |
14250.0 216.650 13556.7 |
14260.0 216.650 13535.3 |
14270.0 216.650 13514.0 |
14280.0 216.650 13492.7 |
14290.0 216.650 13471.5 |
14300.0 216.650 13450.2 |
14310.0 216.650 13429.0 |
14320.0 216.650 13407.9 |
14330.0 216.650 13386.7 |
14340.0 216.650 13365.7 |
14350.0 216.650 13344.6 |
14360.0 216.650 13323.6 |
14370.0 216.650 13302.6 |
14380.0 216.650 13281.6 |
14390.0 216.650 13260.7 |
14400.0 216.650 13239.8 |
14410.0 216.650 13218.9 |
14420.0 216.650 13198.1 |
14430.0 216.650 13177.3 |
14440.0 216.650 13156.5 |
14450.0 216.650 13135.8 |
14460.0 216.650 13115.1 |
14470.0 216.650 13094.5 |
14480.0 216.650 13073.8 |
14490.0 216.650 13053.2 |
14500.0 216.650 13032.7 |
14510.0 216.650 13012.1 |
14520.0 216.650 12991.6 |
14530.0 216.650 12971.1 |
14540.0 216.650 12950.7 |
14550.0 216.650 12930.3 |
14560.0 216.650 12909.9 |
14570.0 216.650 12889.6 |
14580.0 216.650 12869.3 |
14590.0 216.650 12849.0 |
14600.0 216.650 12828.8 |
14610.0 216.650 12808.5 |
14620.0 216.650 12788.4 |
14630.0 216.650 12768.2 |
14640.0 216.650 12748.1 |
14650.0 216.650 12728.0 |
14660.0 216.650 12708.0 |
14670.0 216.650 12687.9 |
14680.0 216.650 12667.9 |
14690.0 216.650 12648.0 |
14700.0 216.650 12628.1 |
14710.0 216.650 12608.2 |
14720.0 216.650 12588.3 |
14730.0 216.650 12568.5 |
14740.0 216.650 12548.6 |
14750.0 216.650 12528.9 |
14760.0 216.650 12509.1 |
14770.0 216.650 12489.4 |
14780.0 216.650 12469.7 |
14790.0 216.650 12450.1 |
14800.0 216.650 12430.5 |
14810.0 216.650 12410.9 |
14820.0 216.650 12391.3 |
14830.0 216.650 12371.8 |
14840.0 216.650 12352.3 |
14850.0 216.650 12332.9 |
14860.0 216.650 12313.4 |
14870.0 216.650 12294.0 |
14880.0 216.650 12274.7 |
14890.0 216.650 12255.3 |
14900.0 216.650 12236.0 |
14910.0 216.650 12216.7 |
14920.0 216.650 12197.5 |
14930.0 216.650 12178.3 |
14940.0 216.650 12159.1 |
14950.0 216.650 12139.9 |
14960.0 216.650 12120.8 |
14970.0 216.650 12101.7 |
14980.0 216.650 12082.6 |
14990.0 216.650 12063.6 |
15000.0 216.650 12044.6 |
15010.0 216.650 12025.6 |
15020.0 216.650 12006.6 |
15030.0 216.650 11987.7 |
15040.0 216.650 11968.8 |
15050.0 216.650 11950.0 |
15060.0 216.650 11931.2 |
15070.0 216.650 11912.4 |
15080.0 216.650 11893.6 |
15090.0 216.650 11874.8 |
15100.0 216.650 11856.1 |
15110.0 216.650 11837.5 |
15120.0 216.650 11818.8 |
15130.0 216.650 11800.2 |
15140.0 216.650 11781.6 |
15150.0 216.650 11763.0 |
15160.0 216.650 11744.5 |
15170.0 216.650 11726.0 |
15180.0 216.650 11707.5 |
15190.0 216.650 11689.1 |
15200.0 216.650 11670.6 |
15210.0 216.650 11652.3 |
15220.0 216.650 11633.9 |
15230.0 216.650 11615.6 |
15240.0 216.650 11597.3 |
15250.0 216.650 11579.0 |
15260.0 216.650 11560.7 |
15270.0 216.650 11542.5 |
15280.0 216.650 11524.3 |
15290.0 216.650 11506.2 |
15300.0 216.650 11488.1 |
15310.0 216.650 11470.0 |
15320.0 216.650 11451.9 |
15330.0 216.650 11433.8 |
15340.0 216.650 11415.8 |
15350.0 216.650 11397.8 |
15360.0 216.650 11379.9 |
15370.0 216.650 11361.9 |
15380.0 216.650 11344.0 |
15390.0 216.650 11326.2 |
15400.0 216.650 11308.3 |
15410.0 216.650 11290.5 |
15420.0 216.650 11272.7 |
15430.0 216.650 11254.9 |
15440.0 216.650 11237.2 |
15450.0 216.650 11219.5 |
15460.0 216.650 11201.8 |
15470.0 216.650 11184.2 |
15480.0 216.650 11166.6 |
15490.0 216.650 11149.0 |
15500.0 216.650 11131.4 |
15510.0 216.650 11113.9 |
15520.0 216.650 11096.3 |
15530.0 216.650 11078.9 |
15540.0 216.650 11061.4 |
15550.0 216.650 11044.0 |
15560.0 216.650 11026.6 |
15570.0 216.650 11009.2 |
15580.0 216.650 10991.9 |
15590.0 216.650 10974.5 |
15600.0 216.650 10957.2 |
15610.0 216.650 10940.0 |
15620.0 216.650 10922.7 |
15630.0 216.650 10905.5 |
15640.0 216.650 10888.4 |
15650.0 216.650 10871.2 |
15660.0 216.650 10854.1 |
15670.0 216.650 10837.0 |
15680.0 216.650 10819.9 |
15690.0 216.650 10802.8 |
15700.0 216.650 10785.8 |
15710.0 216.650 10768.8 |
15720.0 216.650 10751.9 |
15730.0 216.650 10734.9 |
15740.0 216.650 10718.0 |
15750.0 216.650 10701.1 |
15760.0 216.650 10684.3 |
15770.0 216.650 10667.4 |
15780.0 216.650 10650.6 |
15790.0 216.650 10633.8 |
15800.0 216.650 10617.1 |
15810.0 216.650 10600.3 |
15820.0 216.650 10583.6 |
15830.0 216.650 10567.0 |
15840.0 216.650 10550.3 |
15850.0 216.650 10533.7 |
15860.0 216.650 10517.1 |
15870.0 216.650 10500.5 |
15880.0 216.650 10484.0 |
15890.0 216.650 10467.5 |
15900.0 216.650 10451.0 |
15910.0 216.650 10434.5 |
15920.0 216.650 10418.1 |
15930.0 216.650 10401.6 |
15940.0 216.650 10385.3 |
15950.0 216.650 10368.9 |
15960.0 216.650 10352.6 |
15970.0 216.650 10336.2 |
15980.0 216.650 10320.0 |
15990.0 216.650 10303.7 |
16000.0 216.650 10287.5 |
16010.0 216.650 10271.2 |
16020.0 216.650 10255.1 |
16030.0 216.650 10238.9 |
16040.0 216.650 10222.8 |
16050.0 216.650 10206.7 |
16060.0 216.650 10190.6 |
16070.0 216.650 10174.5 |
16080.0 216.650 10158.5 |
16090.0 216.650 10142.5 |
16100.0 216.650 10126.5 |
16110.0 216.650 10110.6 |
16120.0 216.650 10094.6 |
16130.0 216.650 10078.7 |
16140.0 216.650 10062.8 |
16150.0 216.650 10047.0 |
16160.0 216.650 10031.2 |
16170.0 216.650 10015.3 |
16180.0 216.650 9999.57 |
16190.0 216.650 9983.81 |
16200.0 216.650 9968.08 |
16210.0 216.650 9952.37 |
16220.0 216.650 9936.69 |
16230.0 216.650 9921.04 |
16240.0 216.650 9905.40 |
16250.0 216.650 9889.80 |
16260.0 216.650 9874.21 |
16270.0 216.650 9858.65 |
16280.0 216.650 9843.12 |
16290.0 216.650 9827.61 |
16300.0 216.650 9812.13 |
16310.0 216.650 9796.67 |
16320.0 216.650 9781.23 |
16330.0 216.650 9765.82 |
16340.0 216.650 9750.43 |
16350.0 216.650 9735.07 |
16360.0 216.650 9719.73 |
16370.0 216.650 9704.41 |
16380.0 216.650 9689.12 |
16390.0 216.650 9673.86 |
16400.0 216.650 9658.61 |
16410.0 216.650 9643.40 |
16420.0 216.650 9628.20 |
16430.0 216.650 9613.03 |
16440.0 216.650 9597.88 |
16450.0 216.650 9582.76 |
16460.0 216.650 9567.66 |
16470.0 216.650 9552.59 |
16480.0 216.650 9537.54 |
16490.0 216.650 9522.51 |
16500.0 216.650 9507.50 |
16510.0 216.650 9492.52 |
16520.0 216.650 9477.57 |
16530.0 216.650 9462.63 |
16540.0 216.650 9447.72 |
16550.0 216.650 9432.84 |
16560.0 216.650 9417.97 |
16570.0 216.650 9403.14 |
16580.0 216.650 9388.32 |
16590.0 216.650 9373.53 |
16600.0 216.650 9358.76 |
16610.0 216.650 9344.01 |
16620.0 216.650 9329.29 |
16630.0 216.650 9314.59 |
16640.0 216.650 9299.91 |
16650.0 216.650 9285.26 |
16660.0 216.650 9270.63 |
16670.0 216.650 9256.02 |
16680.0 216.650 9241.44 |
16690.0 216.650 9226.88 |
16700.0 216.650 9212.34 |
16710.0 216.650 9197.82 |
16720.0 216.650 9183.33 |
16730.0 216.650 9168.86 |
16740.0 216.650 9154.41 |
16750.0 216.650 9139.99 |
16760.0 216.650 9125.59 |
16770.0 216.650 9111.21 |
16780.0 216.650 9096.85 |
16790.0 216.650 9082.52 |
16800.0 216.650 9068.21 |
16810.0 216.650 9053.92 |
16820.0 216.650 9039.66 |
16830.0 216.650 9025.41 |
16840.0 216.650 9011.19 |
16850.0 216.650 8996.99 |
16860.0 216.650 8982.82 |
16870.0 216.650 8968.66 |
16880.0 216.650 8954.53 |
16890.0 216.650 8940.42 |
16900.0 216.650 8926.34 |
16910.0 216.650 8912.27 |
16920.0 216.650 8898.23 |
16930.0 216.650 8884.21 |
16940.0 216.650 8870.21 |
16950.0 216.650 8856.23 |
16960.0 216.650 8842.28 |
16970.0 216.650 8828.35 |
16980.0 216.650 8814.44 |
16990.0 216.650 8800.55 |
17000.0 216.650 8786.68 |
17010.0 216.650 8772.84 |
17020.0 216.650 8759.01 |
17030.0 216.650 8745.21 |
17040.0 216.650 8731.43 |
17050.0 216.650 8717.68 |
17060.0 216.650 8703.94 |
17070.0 216.650 8690.23 |
17080.0 216.650 8676.53 |
17090.0 216.650 8662.86 |
17100.0 216.650 8649.21 |
17110.0 216.650 8635.58 |
17120.0 216.650 8621.98 |
17130.0 216.650 8608.39 |
17140.0 216.650 8594.83 |
17150.0 216.650 8581.29 |
17160.0 216.650 8567.77 |
17170.0 216.650 8554.27 |
17180.0 216.650 8540.79 |
17190.0 216.650 8527.33 |
17200.0 216.650 8513.89 |
17210.0 216.650 8500.48 |
17220.0 216.650 8487.09 |
17230.0 216.650 8473.71 |
17240.0 216.650 8460.36 |
17250.0 216.650 8447.03 |
17260.0 216.650 8433.72 |
17270.0 216.650 8420.43 |
17280.0 216.650 8407.17 |
17290.0 216.650 8393.92 |
17300.0 216.650 8380.69 |
17310.0 216.650 8367.49 |
17320.0 216.650 8354.30 |
17330.0 216.650 8341.14 |
17340.0 216.650 8328.00 |
17350.0 216.650 8314.88 |
17360.0 216.650 8301.78 |
17370.0 216.650 8288.69 |
17380.0 216.650 8275.63 |
17390.0 216.650 8262.59 |
17400.0 216.650 8249.58 |
17410.0 216.650 8236.58 |
17420.0 216.650 8223.60 |
17430.0 216.650 8210.64 |
17440.0 216.650 8197.71 |
17450.0 216.650 8184.79 |
17460.0 216.650 8171.89 |
17470.0 216.650 8159.02 |
17480.0 216.650 8146.16 |
17490.0 216.650 8133.33 |
17500.0 216.650 8120.51 |
17510.0 216.650 8107.72 |
17520.0 216.650 8094.94 |
17530.0 216.650 8082.19 |
17540.0 216.650 8069.45 |
17550.0 216.650 8056.74 |
17560.0 216.650 8044.04 |
17570.0 216.650 8031.37 |
17580.0 216.650 8018.71 |
17590.0 216.650 8006.08 |
17600.0 216.650 7993.46 |
17610.0 216.650 7980.87 |
17620.0 216.650 7968.29 |
17630.0 216.650 7955.74 |
17640.0 216.650 7943.20 |
17650.0 216.650 7930.69 |
17660.0 216.650 7918.19 |
17670.0 216.650 7905.72 |
17680.0 216.650 7893.26 |
17690.0 216.650 7880.82 |
17700.0 216.650 7868.40 |
17710.0 216.650 7856.01 |
17720.0 216.650 7843.63 |
17730.0 216.650 7831.27 |
17740.0 216.650 7818.93 |
17750.0 216.650 7806.61 |
17760.0 216.650 7794.31 |
17770.0 216.650 7782.03 |
17780.0 216.650 7769.77 |
17790.0 216.650 7757.52 |
17800.0 216.650 7745.30 |
17810.0 216.650 7733.10 |
17820.0 216.650 7720.91 |
17830.0 216.650 7708.75 |
17840.0 216.650 7696.60 |
17850.0 216.650 7684.47 |
17860.0 216.650 7672.37 |
17870.0 216.650 7660.28 |
17880.0 216.650 7648.21 |
17890.0 216.650 7636.16 |
17900.0 216.650 7624.13 |
17910.0 216.650 7612.11 |
17920.0 216.650 7600.12 |
17930.0 216.650 7588.14 |
17940.0 216.650 7576.19 |
17950.0 216.650 7564.25 |
17960.0 216.650 7552.33 |
17970.0 216.650 7540.43 |
17980.0 216.650 7528.55 |
17990.0 216.650 7516.69 |
18000.0 216.650 7504.84 |
18010.0 216.650 7493.02 |
18020.0 216.650 7481.21 |
18030.0 216.650 7469.43 |
18040.0 216.650 7457.66 |
18050.0 216.650 7445.91 |
18060.0 216.650 7434.17 |
18070.0 216.650 7422.46 |
18080.0 216.650 7410.77 |
18090.0 216.650 7399.09 |
18100.0 216.650 7387.43 |
18110.0 216.650 7375.79 |
18120.0 216.650 7364.17 |
18130.0 216.650 7352.57 |
18140.0 216.650 7340.98 |
18150.0 216.650 7329.41 |
18160.0 216.650 7317.87 |
18170.0 216.650 7306.33 |
18180.0 216.650 7294.82 |
18190.0 216.650 7283.33 |
18200.0 216.650 7271.85 |
18210.0 216.650 7260.39 |
18220.0 216.650 7248.95 |
18230.0 216.650 7237.53 |
18240.0 216.650 7226.13 |
18250.0 216.650 7214.74 |
18260.0 216.650 7203.38 |
18270.0 216.650 7192.03 |
18280.0 216.650 7180.69 |
18290.0 216.650 7169.38 |
18300.0 216.650 7158.08 |
18310.0 216.650 7146.80 |
18320.0 216.650 7135.54 |
18330.0 216.650 7124.30 |
18340.0 216.650 7113.08 |
18350.0 216.650 7101.87 |
18360.0 216.650 7090.68 |
18370.0 216.650 7079.51 |
18380.0 216.650 7068.35 |
18390.0 216.650 7057.21 |
18400.0 216.650 7046.09 |
18410.0 216.650 7034.99 |
18420.0 216.650 7023.91 |
18430.0 216.650 7012.84 |
18440.0 216.650 7001.79 |
18450.0 216.650 6990.76 |
18460.0 216.650 6979.74 |
18470.0 216.650 6968.75 |
18480.0 216.650 6957.77 |
18490.0 216.650 6946.80 |
18500.0 216.650 6935.86 |
18510.0 216.650 6924.93 |
18520.0 216.650 6914.02 |
18530.0 216.650 6903.12 |
18540.0 216.650 6892.25 |
18550.0 216.650 6881.39 |
18560.0 216.650 6870.54 |
18570.0 216.650 6859.72 |
18580.0 216.650 6848.91 |
18590.0 216.650 6838.12 |
18600.0 216.650 6827.34 |
18610.0 216.650 6816.59 |
18620.0 216.650 6805.85 |
18630.0 216.650 6795.12 |
18640.0 216.650 6784.42 |
18650.0 216.650 6773.73 |
18660.0 216.650 6763.05 |
18670.0 216.650 6752.40 |
18680.0 216.650 6741.76 |
18690.0 216.650 6731.13 |
18700.0 216.650 6720.53 |
18710.0 216.650 6709.94 |
18720.0 216.650 6699.37 |
18730.0 216.650 6688.81 |
18740.0 216.650 6678.27 |
18750.0 216.650 6667.75 |
18760.0 216.650 6657.24 |
18770.0 216.650 6646.75 |
18780.0 216.650 6636.28 |
18790.0 216.650 6625.83 |
18800.0 216.650 6615.39 |
18810.0 216.650 6604.96 |
18820.0 216.650 6594.55 |
18830.0 216.650 6584.16 |
18840.0 216.650 6573.79 |
18850.0 216.650 6563.43 |
18860.0 216.650 6553.09 |
18870.0 216.650 6542.76 |
18880.0 216.650 6532.46 |
18890.0 216.650 6522.16 |
18900.0 216.650 6511.89 |
18910.0 216.650 6501.63 |
18920.0 216.650 6491.38 |
18930.0 216.650 6481.15 |
18940.0 216.650 6470.94 |
18950.0 216.650 6460.75 |
18960.0 216.650 6450.57 |
18970.0 216.650 6440.40 |
18980.0 216.650 6430.25 |
18990.0 216.650 6420.12 |
19000.0 216.650 6410.01 |
19010.0 216.650 6399.91 |
19020.0 216.650 6389.82 |
19030.0 216.650 6379.76 |
19040.0 216.650 6369.70 |
19050.0 216.650 6359.67 |
19060.0 216.650 6349.65 |
19070.0 216.650 6339.64 |
19080.0 216.650 6329.65 |
19090.0 216.650 6319.68 |
19100.0 216.650 6309.72 |
19110.0 216.650 6299.78 |
19120.0 216.650 6289.85 |
19130.0 216.650 6279.94 |
19140.0 216.650 6270.05 |
19150.0 216.650 6260.17 |
19160.0 216.650 6250.30 |
19170.0 216.650 6240.46 |
19180.0 216.650 6230.62 |
19190.0 216.650 6220.81 |
19200.0 216.650 6211.00 |
19210.0 216.650 6201.22 |
19220.0 216.650 6191.45 |
19230.0 216.650 6181.69 |
19240.0 216.650 6171.95 |
19250.0 216.650 6162.23 |
19260.0 216.650 6152.52 |
19270.0 216.650 6142.82 |
19280.0 216.650 6133.14 |
19290.0 216.650 6123.48 |
19300.0 216.650 6113.83 |
19310.0 216.650 6104.20 |
19320.0 216.650 6094.58 |
19330.0 216.650 6084.98 |
19340.0 216.650 6075.39 |
19350.0 216.650 6065.82 |
19360.0 216.650 6056.26 |
19370.0 216.650 6046.72 |
19380.0 216.650 6037.19 |
19390.0 216.650 6027.68 |
19400.0 216.650 6018.18 |
19410.0 216.650 6008.70 |
19420.0 216.650 5999.23 |
19430.0 216.650 5989.78 |
19440.0 216.650 5980.34 |
19450.0 216.650 5970.92 |
19460.0 216.650 5961.51 |
19470.0 216.650 5952.12 |
19480.0 216.650 5942.74 |
19490.0 216.650 5933.37 |
19500.0 216.650 5924.03 |
19510.0 216.650 5914.69 |
19520.0 216.650 5905.37 |
19530.0 216.650 5896.07 |
19540.0 216.650 5886.78 |
19550.0 216.650 5877.50 |
19560.0 216.650 5868.24 |
19570.0 216.650 5858.99 |
19580.0 216.650 5849.76 |
19590.0 216.650 5840.55 |
19600.0 216.650 5831.34 |
19610.0 216.650 5822.15 |
19620.0 216.650 5812.98 |
19630.0 216.650 5803.82 |
19640.0 216.650 5794.68 |
19650.0 216.650 5785.55 |
19660.0 216.650 5776.43 |
19670.0 216.650 5767.33 |
19680.0 216.650 5758.24 |
19690.0 216.650 5749.17 |
19700.0 216.650 5740.11 |
19710.0 216.650 5731.07 |
19720.0 216.650 5722.04 |
19730.0 216.650 5713.02 |
19740.0 216.650 5704.02 |
19750.0 216.650 5695.03 |
19760.0 216.650 5686.06 |
19770.0 216.650 5677.10 |
19780.0 216.650 5668.15 |
19790.0 216.650 5659.22 |
19800.0 216.650 5650.31 |
19810.0 216.650 5641.40 |
19820.0 216.650 5632.51 |
19830.0 216.650 5623.64 |
19840.0 216.650 5614.78 |
19850.0 216.650 5605.93 |
19860.0 216.650 5597.10 |
19870.0 216.650 5588.28 |
19880.0 216.650 5579.47 |
19890.0 216.650 5570.68 |
19900.0 216.650 5561.91 |
19910.0 216.650 5553.14 |
19920.0 216.650 5544.39 |
19930.0 216.650 5535.66 |
19940.0 216.650 5526.93 |
19950.0 216.650 5518.23 |
19960.0 216.650 5509.53 |
19970.0 216.650 5500.85 |
19980.0 216.650 5492.18 |
19990.0 216.650 5483.53 |
20000.0 216.650 5474.89 |
20010.0 216.660 5466.26 |
20020.0 216.670 5457.65 |
20030.0 216.680 5449.05 |
20040.0 216.690 5440.47 |
20050.0 216.700 5431.90 |
20060.0 216.710 5423.34 |
20070.0 216.720 5414.80 |
20080.0 216.730 5406.27 |
20090.0 216.740 5397.75 |
20100.0 216.750 5389.25 |
20110.0 216.760 5380.77 |
20120.0 216.770 5372.29 |
20130.0 216.780 5363.83 |
20140.0 216.790 5355.39 |
20150.0 216.800 5346.95 |
20160.0 216.810 5338.53 |
20170.0 216.820 5330.13 |
20180.0 216.830 5321.74 |
20190.0 216.840 5313.36 |
20200.0 216.850 5304.99 |
20210.0 216.860 5296.64 |
20220.0 216.870 5288.31 |
20230.0 216.880 5279.98 |
20240.0 216.890 5271.67 |
20250.0 216.900 5263.38 |
20260.0 216.910 5255.09 |
20270.0 216.920 5246.82 |
20280.0 216.930 5238.57 |
20290.0 216.940 5230.32 |
20300.0 216.950 5222.09 |
20310.0 216.960 5213.88 |
20320.0 216.970 5205.67 |
20330.0 216.980 5197.48 |
20340.0 216.990 5189.31 |
20350.0 217.000 5181.14 |
20360.0 217.010 5172.99 |
20370.0 217.020 5164.85 |
20380.0 217.030 5156.73 |
20390.0 217.040 5148.62 |
20400.0 217.050 5140.52 |
20410.0 217.060 5132.44 |
20420.0 217.070 5124.37 |
20430.0 217.080 5116.31 |
20440.0 217.090 5108.26 |
20450.0 217.100 5100.23 |
20460.0 217.110 5092.21 |
20470.0 217.120 5084.20 |
20480.0 217.130 5076.21 |
20490.0 217.140 5068.23 |
20500.0 217.150 5060.26 |
20510.0 217.160 5052.31 |
20520.0 217.170 5044.37 |
20530.0 217.180 5036.44 |
20540.0 217.190 5028.52 |
20550.0 217.200 5020.62 |
20560.0 217.210 5012.73 |
20570.0 217.220 5004.85 |
20580.0 217.230 4996.99 |
20590.0 217.240 4989.13 |
20600.0 217.250 4981.29 |
20610.0 217.260 4973.47 |
20620.0 217.270 4965.65 |
20630.0 217.280 4957.85 |
20640.0 217.290 4950.06 |
20650.0 217.300 4942.29 |
20660.0 217.310 4934.52 |
20670.0 217.320 4926.77 |
20680.0 217.330 4919.03 |
20690.0 217.340 4911.31 |
20700.0 217.350 4903.59 |
20710.0 217.360 4895.89 |
20720.0 217.370 4888.20 |
20730.0 217.380 4880.53 |
20740.0 217.390 4872.86 |
20750.0 217.400 4865.21 |
20760.0 217.410 4857.57 |
20770.0 217.420 4849.94 |
20780.0 217.430 4842.33 |
20790.0 217.440 4834.73 |
20800.0 217.450 4827.14 |
20810.0 217.460 4819.56 |
20820.0 217.470 4811.99 |
20830.0 217.480 4804.44 |
20840.0 217.490 4796.90 |
20850.0 217.500 4789.37 |
20860.0 217.510 4781.85 |
20870.0 217.520 4774.35 |
20880.0 217.530 4766.86 |
20890.0 217.540 4759.38 |
20900.0 217.550 4751.91 |
20910.0 217.560 4744.45 |
20920.0 217.570 4737.01 |
20930.0 217.580 4729.58 |
20940.0 217.590 4722.16 |
20950.0 217.600 4714.75 |
20960.0 217.610 4707.35 |
20970.0 217.620 4699.97 |
20980.0 217.630 4692.60 |
20990.0 217.640 4685.23 |
21000.0 217.650 4677.89 |
21010.0 217.660 4670.55 |
21020.0 217.670 4663.22 |
21030.0 217.680 4655.91 |
21040.0 217.690 4648.61 |
21050.0 217.700 4641.32 |
21060.0 217.710 4634.04 |
21070.0 217.720 4626.78 |
21080.0 217.730 4619.52 |
21090.0 217.740 4612.28 |
21100.0 217.750 4605.05 |
21110.0 217.760 4597.83 |
21120.0 217.770 4590.62 |
21130.0 217.780 4583.43 |
21140.0 217.790 4576.24 |
21150.0 217.800 4569.07 |
21160.0 217.810 4561.91 |
21170.0 217.820 4554.76 |
21180.0 217.830 4547.62 |
21190.0 217.840 4540.50 |
21200.0 217.850 4533.38 |
21210.0 217.860 4526.28 |
21220.0 217.870 4519.19 |
21230.0 217.880 4512.10 |
21240.0 217.890 4505.04 |
21250.0 217.900 4497.98 |
21260.0 217.910 4490.93 |
21270.0 217.920 4483.90 |
21280.0 217.930 4476.87 |
21290.0 217.940 4469.86 |
21300.0 217.950 4462.86 |
21310.0 217.960 4455.87 |
21320.0 217.970 4448.89 |
21330.0 217.980 4441.92 |
21340.0 217.990 4434.97 |
21350.0 218.000 4428.02 |
21360.0 218.010 4421.09 |
21370.0 218.020 4414.17 |
21380.0 218.030 4407.26 |
21390.0 218.040 4400.35 |
21400.0 218.050 4393.47 |
21410.0 218.060 4386.59 |
21420.0 218.070 4379.72 |
21430.0 218.080 4372.87 |
21440.0 218.090 4366.02 |
21450.0 218.100 4359.19 |
21460.0 218.110 4352.36 |
21470.0 218.120 4345.55 |
21480.0 218.130 4338.75 |
21490.0 218.140 4331.96 |
21500.0 218.150 4325.18 |
21510.0 218.160 4318.41 |
21520.0 218.170 4311.66 |
21530.0 218.180 4304.91 |
21540.0 218.190 4298.18 |
21550.0 218.200 4291.45 |
21560.0 218.210 4284.74 |
21570.0 218.220 4278.04 |
21580.0 218.230 4271.34 |
21590.0 218.240 4264.66 |
21600.0 218.250 4257.99 |
21610.0 218.260 4251.33 |
21620.0 218.270 4244.68 |
21630.0 218.280 4238.04 |
21640.0 218.290 4231.42 |
21650.0 218.300 4224.80 |
21660.0 218.310 4218.19 |
21670.0 218.320 4211.60 |
21680.0 218.330 4205.01 |
21690.0 218.340 4198.44 |
21700.0 218.350 4191.87 |
21710.0 218.360 4185.32 |
21720.0 218.370 4178.78 |
21730.0 218.380 4172.25 |
21740.0 218.390 4165.72 |
21750.0 218.400 4159.21 |
21760.0 218.410 4152.71 |
21770.0 218.420 4146.22 |
21780.0 218.430 4139.74 |
21790.0 218.440 4133.27 |
21800.0 218.450 4126.81 |
21810.0 218.460 4120.36 |
21820.0 218.470 4113.93 |
21830.0 218.480 4107.50 |
21840.0 218.490 4101.08 |
21850.0 218.500 4094.67 |
21860.0 218.510 4088.28 |
21870.0 218.520 4081.89 |
21880.0 218.530 4075.51 |
21890.0 218.540 4069.15 |
21900.0 218.550 4062.79 |
21910.0 218.560 4056.44 |
21920.0 218.570 4050.11 |
21930.0 218.580 4043.78 |
21940.0 218.590 4037.47 |
21950.0 218.600 4031.16 |
21960.0 218.610 4024.87 |
21970.0 218.620 4018.58 |
21980.0 218.630 4012.31 |
21990.0 218.640 4006.04 |
22000.0 218.650 3999.79 |
22010.0 218.660 3993.55 |
22020.0 218.670 3987.31 |
22030.0 218.680 3981.09 |
22040.0 218.690 3974.87 |
22050.0 218.700 3968.67 |
22060.0 218.710 3962.47 |
22070.0 218.720 3956.29 |
22080.0 218.730 3950.11 |
22090.0 218.740 3943.95 |
22100.0 218.750 3937.79 |
22110.0 218.760 3931.65 |
22120.0 218.770 3925.51 |
22130.0 218.780 3919.39 |
22140.0 218.790 3913.27 |
22150.0 218.800 3907.17 |
22160.0 218.810 3901.07 |
22170.0 218.820 3894.99 |
22180.0 218.830 3888.91 |
22190.0 218.840 3882.84 |
22200.0 218.850 3876.79 |
22210.0 218.860 3870.74 |
22220.0 218.870 3864.70 |
22230.0 218.880 3858.68 |
22240.0 218.890 3852.66 |
22250.0 218.900 3846.65 |
22260.0 218.910 3840.65 |
22270.0 218.920 3834.66 |
22280.0 218.930 3828.68 |
22290.0 218.940 3822.71 |
22300.0 218.950 3816.75 |
22310.0 218.960 3810.80 |
22320.0 218.970 3804.86 |
22330.0 218.980 3798.93 |
22340.0 218.990 3793.01 |
22350.0 219.000 3787.10 |
22360.0 219.010 3781.19 |
22370.0 219.020 3775.30 |
22380.0 219.030 3769.42 |
22390.0 219.040 3763.54 |
22400.0 219.050 3757.68 |
22410.0 219.060 3751.82 |
22420.0 219.070 3745.97 |
22430.0 219.080 3740.14 |
22440.0 219.090 3734.31 |
22450.0 219.100 3728.49 |
22460.0 219.110 3722.68 |
22470.0 219.120 3716.88 |
22480.0 219.130 3711.09 |
22490.0 219.140 3705.31 |
22500.0 219.150 3699.54 |
22510.0 219.160 3693.78 |
22520.0 219.170 3688.02 |
22530.0 219.180 3682.28 |
22540.0 219.190 3676.54 |
22550.0 219.200 3670.82 |
22560.0 219.210 3665.10 |
22570.0 219.220 3659.39 |
22580.0 219.230 3653.70 |
22590.0 219.240 3648.01 |
22600.0 219.250 3642.33 |
22610.0 219.260 3636.66 |
22620.0 219.270 3630.99 |
22630.0 219.280 3625.34 |
22640.0 219.290 3619.70 |
22650.0 219.300 3614.06 |
22660.0 219.310 3608.44 |
22670.0 219.320 3602.82 |
22680.0 219.330 3597.21 |
22690.0 219.340 3591.61 |
22700.0 219.350 3586.03 |
22710.0 219.360 3580.44 |
22720.0 219.370 3574.87 |
22730.0 219.380 3569.31 |
22740.0 219.390 3563.76 |
22750.0 219.400 3558.21 |
22760.0 219.410 3552.67 |
22770.0 219.420 3547.15 |
22780.0 219.430 3541.63 |
22790.0 219.440 3536.12 |
22800.0 219.450 3530.62 |
22810.0 219.460 3525.13 |
22820.0 219.470 3519.64 |
22830.0 219.480 3514.17 |
22840.0 219.490 3508.70 |
22850.0 219.500 3503.25 |
22860.0 219.510 3497.80 |
22870.0 219.520 3492.36 |
22880.0 219.530 3486.93 |
22890.0 219.540 3481.51 |
22900.0 219.550 3476.09 |
22910.0 219.560 3470.69 |
22920.0 219.570 3465.29 |
22930.0 219.580 3459.91 |
22940.0 219.590 3454.53 |
22950.0 219.600 3449.16 |
22960.0 219.610 3443.79 |
22970.0 219.620 3438.44 |
22980.0 219.630 3433.10 |
22990.0 219.640 3427.76 |
23000.0 219.650 3422.43 |
23010.0 219.660 3417.12 |
23020.0 219.670 3411.81 |
23030.0 219.680 3406.50 |
23040.0 219.690 3401.21 |
23050.0 219.700 3395.93 |
23060.0 219.710 3390.65 |
23070.0 219.720 3385.38 |
23080.0 219.730 3380.12 |
23090.0 219.740 3374.87 |
23100.0 219.750 3369.63 |
23110.0 219.760 3364.39 |
23120.0 219.770 3359.17 |
23130.0 219.780 3353.95 |
23140.0 219.790 3348.74 |
23150.0 219.800 3343.54 |
23160.0 219.810 3338.35 |
23170.0 219.820 3333.16 |
23180.0 219.830 3327.99 |
23190.0 219.840 3322.82 |
23200.0 219.850 3317.66 |
23210.0 219.860 3312.51 |
23220.0 219.870 3307.36 |
23230.0 219.880 3302.23 |
23240.0 219.890 3297.10 |
23250.0 219.900 3291.98 |
23260.0 219.910 3286.87 |
23270.0 219.920 3281.77 |
23280.0 219.930 3276.68 |
23290.0 219.940 3271.59 |
23300.0 219.950 3266.51 |
23310.0 219.960 3261.44 |
23320.0 219.970 3256.38 |
23330.0 219.980 3251.33 |
23340.0 219.990 3246.28 |
23350.0 220.000 3241.25 |
23360.0 220.010 3236.22 |
23370.0 220.020 3231.20 |
23380.0 220.030 3226.18 |
23390.0 220.040 3221.18 |
23400.0 220.050 3216.18 |
23410.0 220.060 3211.19 |
23420.0 220.070 3206.21 |
23430.0 220.080 3201.24 |
23440.0 220.090 3196.27 |
23450.0 220.100 3191.32 |
23460.0 220.110 3186.37 |
23470.0 220.120 3181.42 |
23480.0 220.130 3176.49 |
23490.0 220.140 3171.56 |
23500.0 220.150 3166.65 |
23510.0 220.160 3161.74 |
23520.0 220.170 3156.83 |
23530.0 220.180 3151.94 |
23540.0 220.190 3147.05 |
23550.0 220.200 3142.17 |
23560.0 220.210 3137.30 |
23570.0 220.220 3132.44 |
23580.0 220.230 3127.58 |
23590.0 220.240 3122.74 |
23600.0 220.250 3117.90 |
23610.0 220.260 3113.06 |
23620.0 220.270 3108.24 |
23630.0 220.280 3103.42 |
23640.0 220.290 3098.61 |
23650.0 220.300 3093.81 |
23660.0 220.310 3089.02 |
23670.0 220.320 3084.23 |
23680.0 220.330 3079.45 |
23690.0 220.340 3074.68 |
23700.0 220.350 3069.92 |
23710.0 220.360 3065.16 |
23720.0 220.370 3060.41 |
23730.0 220.380 3055.67 |
23740.0 220.390 3050.94 |
23750.0 220.400 3046.21 |
23760.0 220.410 3041.50 |
23770.0 220.420 3036.79 |
23780.0 220.430 3032.08 |
23790.0 220.440 3027.39 |
23800.0 220.450 3022.70 |
23810.0 220.460 3018.02 |
23820.0 220.470 3013.35 |
23830.0 220.480 3008.68 |
23840.0 220.490 3004.02 |
23850.0 220.500 2999.37 |
23860.0 220.510 2994.73 |
23870.0 220.520 2990.09 |
23880.0 220.530 2985.46 |
23890.0 220.540 2980.84 |
23900.0 220.550 2976.23 |
23910.0 220.560 2971.62 |
23920.0 220.570 2967.02 |
23930.0 220.580 2962.43 |
23940.0 220.590 2957.85 |
23950.0 220.600 2953.27 |
23960.0 220.610 2948.70 |
23970.0 220.620 2944.14 |
23980.0 220.630 2939.58 |
23990.0 220.640 2935.03 |
24000.0 220.650 2930.49 |
24010.0 220.660 2925.96 |
24020.0 220.670 2921.43 |
24030.0 220.680 2916.91 |
24040.0 220.690 2912.40 |
24050.0 220.700 2907.90 |
24060.0 220.710 2903.40 |
24070.0 220.720 2898.91 |
24080.0 220.730 2894.42 |
24090.0 220.740 2889.95 |
24100.0 220.750 2885.48 |
24110.0 220.760 2881.02 |
24120.0 220.770 2876.56 |
24130.0 220.780 2872.11 |
24140.0 220.790 2867.67 |
24150.0 220.800 2863.24 |
24160.0 220.810 2858.81 |
24170.0 220.820 2854.39 |
24180.0 220.830 2849.98 |
24190.0 220.840 2845.58 |
24200.0 220.850 2841.18 |
24210.0 220.860 2836.79 |
24220.0 220.870 2832.40 |
24230.0 220.880 2828.02 |
24240.0 220.890 2823.65 |
24250.0 220.900 2819.29 |
24260.0 220.910 2814.93 |
24270.0 220.920 2810.58 |
24280.0 220.930 2806.24 |
24290.0 220.940 2801.90 |
24300.0 220.950 2797.58 |
24310.0 220.960 2793.25 |
24320.0 220.970 2788.94 |
24330.0 220.980 2784.63 |
24340.0 220.990 2780.33 |
24350.0 221.000 2776.03 |
24360.0 221.010 2771.74 |
24370.0 221.020 2767.46 |
24380.0 221.030 2763.19 |
24390.0 221.040 2758.92 |
24400.0 221.050 2754.66 |
24410.0 221.060 2750.41 |
24420.0 221.070 2746.16 |
24430.0 221.080 2741.92 |
24440.0 221.090 2737.69 |
24450.0 221.100 2733.46 |
24460.0 221.110 2729.24 |
24470.0 221.120 2725.03 |
24480.0 221.130 2720.82 |
24490.0 221.140 2716.62 |
24500.0 221.150 2712.42 |
24510.0 221.160 2708.24 |
24520.0 221.170 2704.06 |
24530.0 221.180 2699.88 |
24540.0 221.190 2695.72 |
24550.0 221.200 2691.56 |
24560.0 221.210 2687.40 |
24570.0 221.220 2683.26 |
24580.0 221.230 2679.12 |
24590.0 221.240 2674.98 |
24600.0 221.250 2670.85 |
24610.0 221.260 2666.73 |
24620.0 221.270 2662.62 |
24630.0 221.280 2658.51 |
24640.0 221.290 2654.41 |
24650.0 221.300 2650.32 |
24660.0 221.310 2646.23 |
24670.0 221.320 2642.15 |
24680.0 221.330 2638.07 |
24690.0 221.340 2634.00 |
24700.0 221.350 2629.94 |
24710.0 221.360 2625.88 |
24720.0 221.370 2621.83 |
24730.0 221.380 2617.79 |
24740.0 221.390 2613.76 |
24750.0 221.400 2609.73 |
24760.0 221.410 2605.70 |
24770.0 221.420 2601.68 |
24780.0 221.430 2597.67 |
24790.0 221.440 2593.67 |
24800.0 221.450 2589.67 |
24810.0 221.460 2585.68 |
24820.0 221.470 2581.69 |
24830.0 221.480 2577.71 |
24840.0 221.490 2573.74 |
24850.0 221.500 2569.77 |
24860.0 221.510 2565.81 |
24870.0 221.520 2561.86 |
24880.0 221.530 2557.91 |
24890.0 221.540 2553.97 |
24900.0 221.550 2550.03 |
24910.0 221.560 2546.11 |
24920.0 221.570 2542.18 |
24930.0 221.580 2538.27 |
24940.0 221.590 2534.36 |
24950.0 221.600 2530.45 |
24960.0 221.610 2526.55 |
24970.0 221.620 2522.66 |
24980.0 221.630 2518.78 |
24990.0 221.640 2514.90 |
25000.0 221.650 2511.02 |
25010.0 221.660 2507.16 |
25020.0 221.670 2503.30 |
25030.0 221.680 2499.44 |
25040.0 221.690 2495.59 |
25050.0 221.700 2491.75 |
25060.0 221.710 2487.91 |
25070.0 221.720 2484.08 |
25080.0 221.730 2480.26 |
25090.0 221.740 2476.44 |
25100.0 221.750 2472.63 |
25110.0 221.760 2468.82 |
25120.0 221.770 2465.02 |
25130.0 221.780 2461.22 |
25140.0 221.790 2457.44 |
25150.0 221.800 2453.65 |
25160.0 221.810 2449.88 |
25170.0 221.820 2446.11 |
25180.0 221.830 2442.34 |
25190.0 221.840 2438.59 |
25200.0 221.850 2434.83 |
25210.0 221.860 2431.09 |
25220.0 221.870 2427.35 |
25230.0 221.880 2423.61 |
25240.0 221.890 2419.88 |
25250.0 221.900 2416.16 |
25260.0 221.910 2412.44 |
25270.0 221.920 2408.73 |
25280.0 221.930 2405.03 |
25290.0 221.940 2401.33 |
25300.0 221.950 2397.63 |
25310.0 221.960 2393.95 |
25320.0 221.970 2390.26 |
25330.0 221.980 2386.59 |
25340.0 221.990 2382.92 |
25350.0 222.000 2379.25 |
25360.0 222.010 2375.60 |
25370.0 222.020 2371.94 |
25380.0 222.030 2368.30 |
25390.0 222.040 2364.65 |
25400.0 222.050 2361.02 |
25410.0 222.060 2357.39 |
25420.0 222.070 2353.77 |
25430.0 222.080 2350.15 |
25440.0 222.090 2346.54 |
25450.0 222.100 2342.93 |
25460.0 222.110 2339.33 |
25470.0 222.120 2335.73 |
25480.0 222.130 2332.14 |
25490.0 222.140 2328.56 |
25500.0 222.150 2324.98 |
25510.0 222.160 2321.41 |
25520.0 222.170 2317.84 |
25530.0 222.180 2314.28 |
25540.0 222.190 2310.72 |
25550.0 222.200 2307.17 |
25560.0 222.210 2303.63 |
25570.0 222.220 2300.09 |
25580.0 222.230 2296.56 |
25590.0 222.240 2293.03 |
25600.0 222.250 2289.51 |
25610.0 222.260 2285.99 |
25620.0 222.270 2282.48 |
25630.0 222.280 2278.97 |
25640.0 222.290 2275.47 |
25650.0 222.300 2271.98 |
25660.0 222.310 2268.49 |
25670.0 222.320 2265.01 |
25680.0 222.330 2261.53 |
25690.0 222.340 2258.06 |
25700.0 222.350 2254.59 |
25710.0 222.360 2251.13 |
25720.0 222.370 2247.67 |
25730.0 222.380 2244.22 |
25740.0 222.390 2240.78 |
25750.0 222.400 2237.34 |
25760.0 222.410 2233.90 |
25770.0 222.420 2230.48 |
25780.0 222.430 2227.05 |
25790.0 222.440 2223.63 |
25800.0 222.450 2220.22 |
25810.0 222.460 2216.82 |
25820.0 222.470 2213.41 |
25830.0 222.480 2210.02 |
25840.0 222.490 2206.63 |
25850.0 222.500 2203.24 |
25860.0 222.510 2199.86 |
25870.0 222.520 2196.49 |
25880.0 222.530 2193.12 |
25890.0 222.540 2189.75 |
25900.0 222.550 2186.39 |
25910.0 222.560 2183.04 |
25920.0 222.570 2179.69 |
25930.0 222.580 2176.35 |
25940.0 222.590 2173.01 |
25950.0 222.600 2169.68 |
25960.0 222.610 2166.35 |
25970.0 222.620 2163.03 |
25980.0 222.630 2159.71 |
25990.0 222.640 2156.40 |
26000.0 222.650 2153.09 |
26010.0 222.660 2149.79 |
26020.0 222.670 2146.50 |
26030.0 222.680 2143.21 |
26040.0 222.690 2139.92 |
26050.0 222.700 2136.64 |
26060.0 222.710 2133.37 |
26070.0 222.720 2130.10 |
26080.0 222.730 2126.83 |
26090.0 222.740 2123.57 |
26100.0 222.750 2120.32 |
26110.0 222.760 2117.07 |
26120.0 222.770 2113.82 |
26130.0 222.780 2110.58 |
26140.0 222.790 2107.35 |
26150.0 222.800 2104.12 |
26160.0 222.810 2100.90 |
26170.0 222.820 2097.68 |
26180.0 222.830 2094.46 |
26190.0 222.840 2091.26 |
26200.0 222.850 2088.05 |
26210.0 222.860 2084.85 |
26220.0 222.870 2081.66 |
26230.0 222.880 2078.47 |
26240.0 222.890 2075.29 |
26250.0 222.900 2072.11 |
26260.0 222.910 2068.94 |
26270.0 222.920 2065.77 |
26280.0 222.930 2062.61 |
26290.0 222.940 2059.45 |
26300.0 222.950 2056.29 |
26310.0 222.960 2053.14 |
26320.0 222.970 2050.00 |
26330.0 222.980 2046.86 |
26340.0 222.990 2043.73 |
26350.0 223.000 2040.60 |
26360.0 223.010 2037.48 |
26370.0 223.020 2034.36 |
26380.0 223.030 2031.24 |
26390.0 223.040 2028.14 |
26400.0 223.050 2025.03 |
26410.0 223.060 2021.93 |
26420.0 223.070 2018.84 |
26430.0 223.080 2015.75 |
26440.0 223.090 2012.66 |
26450.0 223.100 2009.58 |
26460.0 223.110 2006.51 |
26470.0 223.120 2003.44 |
26480.0 223.130 2000.37 |
26490.0 223.140 1997.31 |
26500.0 223.150 1994.26 |
26510.0 223.160 1991.21 |
26520.0 223.170 1988.16 |
26530.0 223.180 1985.12 |
26540.0 223.190 1982.08 |
26550.0 223.200 1979.05 |
26560.0 223.210 1976.03 |
26570.0 223.220 1973.00 |
26580.0 223.230 1969.99 |
26590.0 223.240 1966.97 |
26600.0 223.250 1963.97 |
26610.0 223.260 1960.96 |
26620.0 223.270 1957.97 |
26630.0 223.280 1954.97 |
26640.0 223.290 1951.98 |
26650.0 223.300 1949.00 |
26660.0 223.310 1946.02 |
26670.0 223.320 1943.04 |
26680.0 223.330 1940.07 |
26690.0 223.340 1937.11 |
26700.0 223.350 1934.15 |
26710.0 223.360 1931.19 |
26720.0 223.370 1928.24 |
26730.0 223.380 1925.29 |
26740.0 223.390 1922.35 |
26750.0 223.400 1919.41 |
26760.0 223.410 1916.48 |
26770.0 223.420 1913.55 |
26780.0 223.430 1910.63 |
26790.0 223.440 1907.71 |
26800.0 223.450 1904.80 |
26810.0 223.460 1901.89 |
26820.0 223.470 1898.98 |
26830.0 223.480 1896.08 |
26840.0 223.490 1893.18 |
26850.0 223.500 1890.29 |
26860.0 223.510 1887.40 |
26870.0 223.520 1884.52 |
26880.0 223.530 1881.64 |
26890.0 223.540 1878.77 |
26900.0 223.550 1875.90 |
26910.0 223.560 1873.04 |
26920.0 223.570 1870.18 |
26930.0 223.580 1867.32 |
26940.0 223.590 1864.47 |
26950.0 223.600 1861.62 |
26960.0 223.610 1858.78 |
26970.0 223.620 1855.94 |
26980.0 223.630 1853.11 |
26990.0 223.640 1850.28 |
27000.0 223.650 1847.46 |
27010.0 223.660 1844.64 |
27020.0 223.670 1841.82 |
27030.0 223.680 1839.01 |
27040.0 223.690 1836.20 |
27050.0 223.700 1833.40 |
27060.0 223.710 1830.60 |
27070.0 223.720 1827.81 |
27080.0 223.730 1825.02 |
27090.0 223.740 1822.24 |
27100.0 223.750 1819.46 |
27110.0 223.760 1816.68 |
27120.0 223.770 1813.91 |
27130.0 223.780 1811.14 |
27140.0 223.790 1808.38 |
27150.0 223.800 1805.62 |
27160.0 223.810 1802.87 |
27170.0 223.820 1800.12 |
27180.0 223.830 1797.37 |
27190.0 223.840 1794.63 |
27200.0 223.850 1791.89 |
27210.0 223.860 1789.16 |
27220.0 223.870 1786.43 |
27230.0 223.880 1783.71 |
27240.0 223.890 1780.99 |
27250.0 223.900 1778.27 |
27260.0 223.910 1775.56 |
27270.0 223.920 1772.86 |
27280.0 223.930 1770.15 |
27290.0 223.940 1767.45 |
27300.0 223.950 1764.76 |
27310.0 223.960 1762.07 |
27320.0 223.970 1759.38 |
27330.0 223.980 1756.70 |
27340.0 223.990 1754.03 |
27350.0 224.000 1751.35 |
27360.0 224.010 1748.68 |
27370.0 224.020 1746.02 |
27380.0 224.030 1743.36 |
27390.0 224.040 1740.70 |
27400.0 224.050 1738.05 |
27410.0 224.060 1735.40 |
27420.0 224.070 1732.76 |
27430.0 224.080 1730.12 |
27440.0 224.090 1727.48 |
27450.0 224.100 1724.85 |
27460.0 224.110 1722.22 |
27470.0 224.120 1719.60 |
27480.0 224.130 1716.98 |
27490.0 224.140 1714.37 |
27500.0 224.150 1711.75 |
27510.0 224.160 1709.15 |
27520.0 224.170 1706.55 |
27530.0 224.180 1703.95 |
27540.0 224.190 1701.35 |
27550.0 224.200 1698.76 |
27560.0 224.210 1696.17 |
27570.0 224.220 1693.59 |
27580.0 224.230 1691.01 |
27590.0 224.240 1688.44 |
27600.0 224.250 1685.87 |
27610.0 224.260 1683.30 |
27620.0 224.270 1680.74 |
27630.0 224.280 1678.18 |
27640.0 224.290 1675.63 |
27650.0 224.300 1673.08 |
27660.0 224.310 1670.53 |
27670.0 224.320 1667.99 |
27680.0 224.330 1665.45 |
27690.0 224.340 1662.92 |
27700.0 224.350 1660.39 |
27710.0 224.360 1657.86 |
27720.0 224.370 1655.34 |
27730.0 224.380 1652.82 |
27740.0 224.390 1650.30 |
27750.0 224.400 1647.79 |
27760.0 224.410 1645.29 |
27770.0 224.420 1642.78 |
27780.0 224.430 1640.29 |
27790.0 224.440 1637.79 |
27800.0 224.450 1635.30 |
27810.0 224.460 1632.81 |
27820.0 224.470 1630.33 |
27830.0 224.480 1627.85 |
27840.0 224.490 1625.37 |
27850.0 224.500 1622.90 |
27860.0 224.510 1620.44 |
27870.0 224.520 1617.97 |
27880.0 224.530 1615.51 |
27890.0 224.540 1613.06 |
27900.0 224.550 1610.60 |
27910.0 224.560 1608.15 |
27920.0 224.570 1605.71 |
27930.0 224.580 1603.27 |
27940.0 224.590 1600.83 |
27950.0 224.600 1598.40 |
27960.0 224.610 1595.97 |
27970.0 224.620 1593.54 |
27980.0 224.630 1591.12 |
27990.0 224.640 1588.70 |
28000.0 224.650 1586.29 |
28010.0 224.660 1583.88 |
28020.0 224.670 1581.47 |
28030.0 224.680 1579.07 |
28040.0 224.690 1576.67 |
28050.0 224.700 1574.28 |
28060.0 224.710 1571.88 |
28070.0 224.720 1569.50 |
28080.0 224.730 1567.11 |
28090.0 224.740 1564.73 |
28100.0 224.750 1562.35 |
28110.0 224.760 1559.98 |
28120.0 224.770 1557.61 |
28130.0 224.780 1555.25 |
28140.0 224.790 1552.88 |
28150.0 224.800 1550.53 |
28160.0 224.810 1548.17 |
28170.0 224.820 1545.82 |
28180.0 224.830 1543.47 |
28190.0 224.840 1541.13 |
28200.0 224.850 1538.79 |
28210.0 224.860 1536.45 |
28220.0 224.870 1534.12 |
28230.0 224.880 1531.79 |
28240.0 224.890 1529.47 |
28250.0 224.900 1527.15 |
28260.0 224.910 1524.83 |
28270.0 224.920 1522.51 |
28280.0 224.930 1520.20 |
28290.0 224.940 1517.90 |
28300.0 224.950 1515.59 |
28310.0 224.960 1513.29 |
28320.0 224.970 1511.00 |
28330.0 224.980 1508.70 |
28340.0 224.990 1506.41 |
28350.0 225.000 1504.13 |
28360.0 225.010 1501.85 |
28370.0 225.020 1499.57 |
28380.0 225.030 1497.29 |
28390.0 225.040 1495.02 |
28400.0 225.050 1492.75 |
28410.0 225.060 1490.49 |
28420.0 225.070 1488.23 |
28430.0 225.080 1485.97 |
28440.0 225.090 1483.72 |
28450.0 225.100 1481.47 |
28460.0 225.110 1479.22 |
28470.0 225.120 1476.98 |
28480.0 225.130 1474.74 |
28490.0 225.140 1472.50 |
28500.0 225.150 1470.27 |
28510.0 225.160 1468.04 |
28520.0 225.170 1465.81 |
28530.0 225.180 1463.59 |
28540.0 225.190 1461.37 |
28550.0 225.200 1459.16 |
28560.0 225.210 1456.95 |
28570.0 225.220 1454.74 |
28580.0 225.230 1452.53 |
28590.0 225.240 1450.33 |
28600.0 225.250 1448.13 |
28610.0 225.260 1445.94 |
28620.0 225.270 1443.75 |
28630.0 225.280 1441.56 |
28640.0 225.290 1439.38 |
28650.0 225.300 1437.19 |
28660.0 225.310 1435.02 |
28670.0 225.320 1432.84 |
28680.0 225.330 1430.67 |
28690.0 225.340 1428.50 |
28700.0 225.350 1426.34 |
28710.0 225.360 1424.18 |
28720.0 225.370 1422.02 |
28730.0 225.380 1419.87 |
28740.0 225.390 1417.72 |
28750.0 225.400 1415.57 |
28760.0 225.410 1413.43 |
28770.0 225.420 1411.29 |
28780.0 225.430 1409.15 |
28790.0 225.440 1407.02 |
28800.0 225.450 1404.89 |
28810.0 225.460 1402.76 |
28820.0 225.470 1400.63 |
28830.0 225.480 1398.51 |
28840.0 225.490 1396.40 |
28850.0 225.500 1394.28 |
28860.0 225.510 1392.17 |
28870.0 225.520 1390.06 |
28880.0 225.530 1387.96 |
28890.0 225.540 1385.86 |
28900.0 225.550 1383.76 |
28910.0 225.560 1381.67 |
28920.0 225.570 1379.58 |
28930.0 225.580 1377.49 |
28940.0 225.590 1375.40 |
28950.0 225.600 1373.32 |
28960.0 225.610 1371.24 |
28970.0 225.620 1369.17 |
28980.0 225.630 1367.10 |
28990.0 225.640 1365.03 |
29000.0 225.650 1362.96 |
29010.0 225.660 1360.90 |
29020.0 225.670 1358.84 |
29030.0 225.680 1356.79 |
29040.0 225.690 1354.74 |
29050.0 225.700 1352.69 |
29060.0 225.710 1350.64 |
29070.0 225.720 1348.60 |
29080.0 225.730 1346.56 |
29090.0 225.740 1344.52 |
29100.0 225.750 1342.49 |
29110.0 225.760 1340.46 |
29120.0 225.770 1338.43 |
29130.0 225.780 1336.41 |
29140.0 225.790 1334.39 |
29150.0 225.800 1332.37 |
29160.0 225.810 1330.36 |
29170.0 225.820 1328.35 |
29180.0 225.830 1326.34 |
29190.0 225.840 1324.33 |
29200.0 225.850 1322.33 |
29210.0 225.860 1320.33 |
29220.0 225.870 1318.34 |
29230.0 225.880 1316.34 |
29240.0 225.890 1314.35 |
29250.0 225.900 1312.37 |
29260.0 225.910 1310.39 |
29270.0 225.920 1308.41 |
29280.0 225.930 1306.43 |
29290.0 225.940 1304.45 |
29300.0 225.950 1302.48 |
29310.0 225.960 1300.52 |
29320.0 225.970 1298.55 |
29330.0 225.980 1296.59 |
29340.0 225.990 1294.63 |
29350.0 226.000 1292.68 |
29360.0 226.010 1290.72 |
29370.0 226.020 1288.77 |
29380.0 226.030 1286.83 |
29390.0 226.040 1284.88 |
29400.0 226.050 1282.94 |
29410.0 226.060 1281.01 |
29420.0 226.070 1279.07 |
29430.0 226.080 1277.14 |
29440.0 226.090 1275.21 |
29450.0 226.100 1273.29 |
29460.0 226.110 1271.36 |
29470.0 226.120 1269.44 |
29480.0 226.130 1267.53 |
29490.0 226.140 1265.61 |
29500.0 226.150 1263.70 |
29510.0 226.160 1261.80 |
29520.0 226.170 1259.89 |
29530.0 226.180 1257.99 |
29540.0 226.190 1256.09 |
29550.0 226.200 1254.20 |
29560.0 226.210 1252.30 |
29570.0 226.220 1250.41 |
29580.0 226.230 1248.53 |
29590.0 226.240 1246.64 |
29600.0 226.250 1244.76 |
29610.0 226.260 1242.88 |
29620.0 226.270 1241.01 |
29630.0 226.280 1239.14 |
29640.0 226.290 1237.27 |
29650.0 226.300 1235.40 |
29660.0 226.310 1233.54 |
29670.0 226.320 1231.68 |
29680.0 226.330 1229.82 |
29690.0 226.340 1227.96 |
29700.0 226.350 1226.11 |
29710.0 226.360 1224.26 |
29720.0 226.370 1222.42 |
29730.0 226.380 1220.57 |
29740.0 226.390 1218.73 |
29750.0 226.400 1216.89 |
29760.0 226.410 1215.06 |
29770.0 226.420 1213.23 |
29780.0 226.430 1211.40 |
29790.0 226.440 1209.57 |
29800.0 226.450 1207.75 |
29810.0 226.460 1205.93 |
29820.0 226.470 1204.11 |
29830.0 226.480 1202.29 |
29840.0 226.490 1200.48 |
29850.0 226.500 1198.67 |
29860.0 226.510 1196.87 |
29870.0 226.520 1195.06 |
29880.0 226.530 1193.26 |
29890.0 226.540 1191.46 |
29900.0 226.550 1189.67 |
29910.0 226.560 1187.88 |
29920.0 226.570 1186.09 |
29930.0 226.580 1184.30 |
29940.0 226.590 1182.51 |
29950.0 226.600 1180.73 |
29960.0 226.610 1178.95 |
29970.0 226.620 1177.18 |
29980.0 226.630 1175.40 |
29990.0 226.640 1173.63 |
30000.0 226.650 1171.87 |
/tags/1.0/goodies/reformat.sh |
---|
0,0 → 1,32 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp reformat short |
echo |
exit 0 |
endif |
set inpfile=$1 |
set outfile=$2 |
set prog1=${LAGRANTO}/goodies/reformat |
set prog2=${LAGRANTO}/goodies/trainfo.sh |
set dim=`${prog2} ${inpfile} dim` |
\rm -f reformat.param |
echo \"${inpfile}\" >! reformat.param |
echo \"${outfile}\" >> reformat.param |
echo ${dim} >> reformat.param |
${prog1} |
\rm -f reformat.param |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/stringmod.f90 |
---|
0,0 → 1,785 |
module strings |
use precision |
private :: value_dr,value_sr,value_di,value_si |
private :: write_dr,write_sr,write_di,write_si |
private :: writeq_dr,writeq_sr,writeq_di,writeq_si |
interface value ! Generic operator for converting a number string to a |
! number. Calling syntax is 'call value(numstring,number,ios)' |
! where 'numstring' is a number string and 'number' is a |
! real number or an integer (single or double precision). |
module procedure value_dr |
module procedure value_sr |
module procedure value_di |
module procedure value_si |
end interface |
interface writenum ! Generic interface for writing a number to a string. The |
! number is left justified in the string. The calling syntax |
! is 'call writenum(number,string,format)' where 'number' is |
! a real number or an integer, 'string' is a character string |
! containing the result, and 'format' is the format desired, |
! e.g., 'e15.6' or 'i5'. |
module procedure write_dr |
module procedure write_sr |
module procedure write_di |
module procedure write_si |
end interface |
interface writeq ! Generic interface equating a name to a numerical value. The |
! calling syntax is 'call writeq(unit,name,value,format)' where |
! unit is the integer output unit number, 'name' is the variable |
! name, 'value' is the real or integer value of the variable, |
! and 'format' is the format of the value. The result written to |
! the output unit has the form <name> = <value>. |
module procedure writeq_dr |
module procedure writeq_sr |
module procedure writeq_di |
module procedure writeq_si |
end interface |
!********************************************************************** |
contains |
!********************************************************************** |
subroutine parse(str,delims,args,nargs) |
! Parses the string 'str' into arguments args(1), ..., args(nargs) based on |
! the delimiters contained in the string 'delims'. Preceding a delimiter in |
! 'str' by a backslash (\) makes this particular instance not a delimiter. |
! The integer output variable nargs contains the number of arguments found. |
character(len=*) :: str,delims |
character(len=len_trim(str)) :: strsav |
character(len=*),dimension(:) :: args |
strsav=str |
call compact(str) |
na=size(args) |
do i=1,na |
args(i)=' ' |
end do |
nargs=0 |
lenstr=len_trim(str) |
if(lenstr==0) return |
k=0 |
do |
if(len_trim(str) == 0) exit |
nargs=nargs+1 |
call split(str,delims,args(nargs)) |
call removebksl(args(nargs)) |
end do |
str=strsav |
end subroutine parse |
!********************************************************************** |
subroutine compact(str) |
! Converts multiple spaces and tabs to single spaces; deletes control characters; |
! removes initial spaces. |
character(len=*):: str |
character(len=1):: ch |
character(len=len_trim(str)):: outstr |
str=adjustl(str) |
lenstr=len_trim(str) |
outstr=' ' |
isp=0 |
k=0 |
do i=1,lenstr |
ch=str(i:i) |
ich=iachar(ch) |
select case(ich) |
case(9,32) ! space or tab character |
if(isp==0) then |
k=k+1 |
outstr(k:k)=' ' |
end if |
isp=1 |
case(33:) ! not a space, quote, or control character |
k=k+1 |
outstr(k:k)=ch |
isp=0 |
end select |
end do |
str=adjustl(outstr) |
end subroutine compact |
!********************************************************************** |
subroutine removesp(str) |
! Removes spaces, tabs, and control characters in string str |
character(len=*):: str |
character(len=1):: ch |
character(len=len_trim(str))::outstr |
str=adjustl(str) |
lenstr=len_trim(str) |
outstr=' ' |
k=0 |
do i=1,lenstr |
ch=str(i:i) |
ich=iachar(ch) |
select case(ich) |
case(0:32) ! space, tab, or control character |
cycle |
case(33:) |
k=k+1 |
outstr(k:k)=ch |
end select |
end do |
str=adjustl(outstr) |
end subroutine removesp |
!********************************************************************** |
subroutine value_dr(str,rnum,ios) |
! Converts number string to a double precision real number |
character(len=*)::str |
real(kr8)::rnum |
integer :: ios |
ilen=len_trim(str) |
ipos=scan(str,'Ee') |
if(.not.is_digit(str(ilen:ilen)) .and. ipos/=0) then |
ios=3 |
return |
end if |
read(str,*,iostat=ios) rnum |
end subroutine value_dr |
!********************************************************************** |
subroutine value_sr(str,rnum,ios) |
! Converts number string to a single precision real number |
character(len=*)::str |
real(kr4) :: rnum |
real(kr8) :: rnumd |
call value_dr(str,rnumd,ios) |
if( abs(rnumd) > huge(rnum) ) then |
ios=15 |
return |
end if |
if( abs(rnumd) < tiny(rnum) ) rnum=0.0_kr4 |
rnum=rnumd |
end subroutine value_sr |
!********************************************************************** |
subroutine value_di(str,inum,ios) |
! Converts number string to a double precision integer value |
character(len=*)::str |
integer(ki8) :: inum |
real(kr8) :: rnum |
call value_dr(str,rnum,ios) |
if(abs(rnum)>huge(inum)) then |
ios=15 |
return |
end if |
inum=nint(rnum,ki8) |
end subroutine value_di |
!********************************************************************** |
subroutine value_si(str,inum,ios) |
! Converts number string to a single precision integer value |
character(len=*)::str |
integer(ki4) :: inum |
real(kr8) :: rnum |
call value_dr(str,rnum,ios) |
if(abs(rnum)>huge(inum)) then |
ios=15 |
return |
end if |
inum=nint(rnum,ki4) |
end subroutine value_si |
!********************************************************************** |
subroutine shiftstr(str,n) |
! Shifts characters in in the string 'str' n positions (positive values |
! denote a right shift and negative values denote a left shift). Characters |
! that are shifted off the end are lost. Positions opened up by the shift |
! are replaced by spaces. |
character(len=*):: str |
lenstr=len(str) |
nabs=iabs(n) |
if(nabs>=lenstr) then |
str=repeat(' ',lenstr) |
return |
end if |
if(n<0) str=str(nabs+1:)//repeat(' ',nabs) ! shift left |
if(n>0) str=repeat(' ',nabs)//str(:lenstr-nabs) ! shift right |
return |
end subroutine shiftstr |
!********************************************************************** |
subroutine insertstr(str,strins,loc) |
! Inserts the string 'strins' into the string 'str' at position 'loc'. |
! Characters in 'str' starting at position 'loc' are shifted right to |
! make room for the inserted string. Trailing spaces of 'strins' are |
! removed prior to insertion |
character(len=*):: str,strins |
character(len=len(str))::tempstr |
lenstrins=len_trim(strins) |
tempstr=str(loc:) |
call shiftstr(tempstr,lenstrins) |
tempstr(1:lenstrins)=strins(1:lenstrins) |
str(loc:)=tempstr |
return |
end subroutine insertstr |
!********************************************************************** |
subroutine delsubstr(str,substr) |
! Deletes first occurrence of substring 'substr' from string 'str' and |
! shifts characters left to fill hole. Trailing spaces or blanks are |
! not considered part of 'substr'. |
character(len=*):: str,substr |
lensubstr=len_trim(substr) |
ipos=index(str,substr) |
if(ipos==0) return |
if(ipos == 1) then |
str=str(lensubstr+1:) |
else |
str=str(:ipos-1)//str(ipos+lensubstr:) |
end if |
return |
end subroutine delsubstr |
!********************************************************************** |
subroutine delall(str,substr) |
! Deletes all occurrences of substring 'substr' from string 'str' and |
! shifts characters left to fill holes. |
character(len=*):: str,substr |
lensubstr=len_trim(substr) |
do |
ipos=index(str,substr) |
if(ipos == 0) exit |
if(ipos == 1) then |
str=str(lensubstr+1:) |
else |
str=str(:ipos-1)//str(ipos+lensubstr:) |
end if |
end do |
return |
end subroutine delall |
!********************************************************************** |
function uppercase(str) result(ucstr) |
! convert string to upper case |
character (len=*):: str |
character (len=len_trim(str)):: ucstr |
ilen=len_trim(str) |
ioffset=iachar('A')-iachar('a') |
iquote=0 |
ucstr=str |
do i=1,ilen |
iav=iachar(str(i:i)) |
if(iquote==0 .and. (iav==34 .or.iav==39)) then |
iquote=1 |
iqc=iav |
cycle |
end if |
if(iquote==1 .and. iav==iqc) then |
iquote=0 |
cycle |
end if |
if (iquote==1) cycle |
if(iav >= iachar('a') .and. iav <= iachar('z')) then |
ucstr(i:i)=achar(iav+ioffset) |
else |
ucstr(i:i)=str(i:i) |
end if |
end do |
return |
end function uppercase |
!********************************************************************** |
function lowercase(str) result(lcstr) |
! convert string to lower case |
character (len=*):: str |
character (len=len_trim(str)):: lcstr |
ilen=len_trim(str) |
ioffset=iachar('A')-iachar('a') |
iquote=0 |
lcstr=str |
do i=1,ilen |
iav=iachar(str(i:i)) |
if(iquote==0 .and. (iav==34 .or.iav==39)) then |
iquote=1 |
iqc=iav |
cycle |
end if |
if(iquote==1 .and. iav==iqc) then |
iquote=0 |
cycle |
end if |
if (iquote==1) cycle |
if(iav >= iachar('A') .and. iav <= iachar('Z')) then |
lcstr(i:i)=achar(iav-ioffset) |
else |
lcstr(i:i)=str(i:i) |
end if |
end do |
return |
end function lowercase |
!********************************************************************** |
subroutine readline(nunitr,line,ios) |
! Reads line from unit=nunitr, ignoring blank lines |
! and deleting comments beginning with an exclamation point(!) |
character (len=*):: line |
do |
read(nunitr,'(a)', iostat=ios) line ! read input line |
if(ios /= 0) return |
line=adjustl(line) |
ipos=index(line,'!') |
if(ipos == 1) cycle |
if(ipos /= 0) line=line(:ipos-1) |
if(len_trim(line) /= 0) exit |
end do |
return |
end subroutine readline |
!********************************************************************** |
subroutine match(str,ipos,imatch) |
! Sets imatch to the position in string of the delimiter matching the delimiter |
! in position ipos. Allowable delimiters are (), [], {}, <>. |
character(len=*) :: str |
character :: delim1,delim2,ch |
lenstr=len_trim(str) |
delim1=str(ipos:ipos) |
select case(delim1) |
case('(') |
idelim2=iachar(delim1)+1 |
istart=ipos+1 |
iend=lenstr |
inc=1 |
case(')') |
idelim2=iachar(delim1)-1 |
istart=ipos-1 |
iend=1 |
inc=-1 |
case('[','{','<') |
idelim2=iachar(delim1)+2 |
istart=ipos+1 |
iend=lenstr |
inc=1 |
case(']','}','>') |
idelim2=iachar(delim1)-2 |
istart=ipos-1 |
iend=1 |
inc=-1 |
case default |
write(*,*) delim1,' is not a valid delimiter' |
return |
end select |
if(istart < 1 .or. istart > lenstr) then |
write(*,*) delim1,' has no matching delimiter' |
return |
end if |
delim2=achar(idelim2) ! matching delimiter |
isum=1 |
do i=istart,iend,inc |
ch=str(i:i) |
if(ch /= delim1 .and. ch /= delim2) cycle |
if(ch == delim1) isum=isum+1 |
if(ch == delim2) isum=isum-1 |
if(isum == 0) exit |
end do |
if(isum /= 0) then |
write(*,*) delim1,' has no matching delimiter' |
return |
end if |
imatch=i |
return |
end subroutine match |
!********************************************************************** |
subroutine write_dr(rnum,str,fmt) |
! Writes double precision real number rnum to string str using format fmt |
real(kr8) :: rnum |
character(len=*) :: str,fmt |
character(len=80) :: formt |
formt='('//trim(fmt)//')' |
write(str,formt) rnum |
str=adjustl(str) |
end subroutine write_dr |
!*********************************************************************** |
subroutine write_sr(rnum,str,fmt) |
! Writes single precision real number rnum to string str using format fmt |
real(kr4) :: rnum |
character(len=*) :: str,fmt |
character(len=80) :: formt |
formt='('//trim(fmt)//')' |
write(str,formt) rnum |
str=adjustl(str) |
end subroutine write_sr |
!*********************************************************************** |
subroutine write_di(inum,str,fmt) |
! Writes double precision integer inum to string str using format fmt |
integer(ki8) :: inum |
character(len=*) :: str,fmt |
character(len=80) :: formt |
formt='('//trim(fmt)//')' |
write(str,formt) inum |
str=adjustl(str) |
end subroutine write_di |
!*********************************************************************** |
subroutine write_si(inum,str,fmt) |
! Writes single precision integer inum to string str using format fmt |
integer(ki4) :: inum |
character(len=*) :: str,fmt |
character(len=80) :: formt |
formt='('//trim(fmt)//')' |
write(str,formt) inum |
str=adjustl(str) |
end subroutine write_si |
!*********************************************************************** |
subroutine trimzero(str) |
! Deletes nonsignificant trailing zeroes from number string str. If number |
! string ends in a decimal point, one trailing zero is added. |
character(len=*) :: str |
character :: ch |
character(len=10) :: exp |
ipos=scan(str,'eE') |
if(ipos>0) then |
exp=str(ipos:) |
str=str(1:ipos-1) |
endif |
lstr=len_trim(str) |
do i=lstr,1,-1 |
ch=str(i:i) |
if(ch=='0') cycle |
if(ch=='.') then |
str=str(1:i)//'0' |
if(ipos>0) str=trim(str)//trim(exp) |
exit |
endif |
str=str(1:i) |
exit |
end do |
if(ipos>0) str=trim(str)//trim(exp) |
end subroutine trimzero |
!********************************************************************** |
subroutine writeq_dr(unit,namestr,value,fmt) |
! Writes a string of the form <name> = value to unit |
real(kr8) :: value |
integer :: unit |
character(len=*) :: namestr,fmt |
character(len=32) :: tempstr |
call writenum(value,tempstr,fmt) |
call trimzero(tempstr) |
write(unit,*) trim(namestr)//' = '//trim(tempstr) |
end subroutine writeq_dr |
!********************************************************************** |
subroutine writeq_sr(unit,namestr,value,fmt) |
! Writes a string of the form <name> = value to unit |
real(kr4) :: value |
integer :: unit |
character(len=*) :: namestr,fmt |
character(len=32) :: tempstr |
call writenum(value,tempstr,fmt) |
call trimzero(tempstr) |
write(unit,*) trim(namestr)//' = '//trim(tempstr) |
end subroutine writeq_sr |
!********************************************************************** |
subroutine writeq_di(unit,namestr,ivalue,fmt) |
! Writes a string of the form <name> = ivalue to unit |
integer(ki8) :: ivalue |
integer :: unit |
character(len=*) :: namestr,fmt |
character(len=32) :: tempstr |
call writenum(ivalue,tempstr,fmt) |
call trimzero(tempstr) |
write(unit,*) trim(namestr)//' = '//trim(tempstr) |
end subroutine writeq_di |
!********************************************************************** |
subroutine writeq_si(unit,namestr,ivalue,fmt) |
! Writes a string of the form <name> = ivalue to unit |
integer(ki4) :: ivalue |
integer :: unit |
character(len=*) :: namestr,fmt |
character(len=32) :: tempstr |
call writenum(ivalue,tempstr,fmt) |
call trimzero(tempstr) |
write(unit,*) trim(namestr)//' = '//trim(tempstr) |
end subroutine writeq_si |
!********************************************************************** |
function is_letter(ch) result(res) |
! Returns .true. if ch is a letter and .false. otherwise |
character :: ch |
logical :: res |
select case(ch) |
case('A':'Z','a':'z') |
res=.true. |
case default |
res=.false. |
end select |
return |
end function is_letter |
!********************************************************************** |
function is_digit(ch) result(res) |
! Returns .true. if ch is a digit (0,1,...,9) and .false. otherwise |
character :: ch |
logical :: res |
select case(ch) |
case('0':'9') |
res=.true. |
case default |
res=.false. |
end select |
return |
end function is_digit |
!********************************************************************** |
subroutine split(str,delims,before,sep) |
! Routine finds the first instance of a character from 'delims' in the |
! the string 'str'. The characters before the found delimiter are |
! output in 'before'. The characters after the found delimiter are |
! output in 'str'. The optional output character 'sep' contains the |
! found delimiter. A delimiter in 'str' is treated like an ordinary |
! character if it is preceded by a backslash (\). If the backslash |
! character is desired in 'str', then precede it with another backslash. |
character(len=*) :: str,delims,before |
character,optional :: sep |
logical :: pres |
character :: ch,cha |
pres=present(sep) |
str=adjustl(str) |
call compact(str) |
lenstr=len_trim(str) |
if(lenstr == 0) return ! string str is empty |
k=0 |
ibsl=0 ! backslash initially inactive |
before=' ' |
do i=1,lenstr |
ch=str(i:i) |
if(ibsl == 1) then ! backslash active |
k=k+1 |
before(k:k)=ch |
ibsl=0 |
cycle |
end if |
if(ch == '\\') then ! backslash with backslash inactive |
k=k+1 |
before(k:k)=ch |
ibsl=1 |
cycle |
end if |
ipos=index(delims,ch) |
if(ipos == 0) then ! character is not a delimiter |
k=k+1 |
before(k:k)=ch |
cycle |
end if |
if(ch /= ' ') then ! character is a delimiter that is not a space |
str=str(i+1:) |
if(pres) sep=ch |
exit |
end if |
cha=str(i+1:i+1) ! character is a space delimiter |
iposa=index(delims,cha) |
if(iposa > 0) then ! next character is a delimiter |
str=str(i+2:) |
if(pres) sep=cha |
exit |
else |
str=str(i+1:) |
if(pres) sep=ch |
exit |
end if |
end do |
if(i >= lenstr) str='' |
str=adjustl(str) ! remove initial spaces |
return |
end subroutine split |
!********************************************************************** |
subroutine removebksl(str) |
! Removes backslash (\) characters. Double backslashes (\\) are replaced |
! by a single backslash. |
character(len=*):: str |
character(len=1):: ch |
character(len=len_trim(str))::outstr |
str=adjustl(str) |
lenstr=len_trim(str) |
outstr=' ' |
k=0 |
ibsl=0 ! backslash initially inactive |
do i=1,lenstr |
ch=str(i:i) |
if(ibsl == 1) then ! backslash active |
k=k+1 |
outstr(k:k)=ch |
ibsl=0 |
cycle |
end if |
if(ch == '\\') then ! backslash with backslash inactive |
ibsl=1 |
cycle |
end if |
k=k+1 |
outstr(k:k)=ch ! non-backslash with backslash inactive |
end do |
str=adjustl(outstr) |
end subroutine removebksl |
!********************************************************************** |
end module strings |
/tags/1.0/goodies/timeres.f |
---|
0,0 → 1,415 |
PROGRAM timeresolution |
c *********************************************************************** |
c * Change time resolution of of a trajectory file * |
c * Michael Sprenger / Winter 2010 * |
c *********************************************************************** |
implicit none |
c ---------------------------------------------------------------------- |
c Declaration of variables |
c ---------------------------------------------------------------------- |
c Parameters |
character*80 inpfile |
character*80 outfile |
integer ntra,otim,ncol |
real timeres |
character*80 unit |
character*80 mode |
c Trajectories |
character*80 vars(100) |
integer refdate(6) |
integer ntim |
real,allocatable, dimension (:,:,:) :: trainp |
real,allocatable, dimension (:,:,:) :: traout |
real,allocatable, dimension (:) :: timold,timnew |
real,allocatable, dimension (:) :: fldold,fldnew |
c Numerical constants |
real eps |
parameter (eps=0.001) |
c Auxiliary variables |
integer inpmode |
integer outmode |
integer stat |
integer fid |
integer i,j,k |
real hhmm,tfrac |
real range |
c ---------------------------------------------------------------------- |
c Parameter handling |
c ---------------------------------------------------------------------- |
c Read parameters |
open(10,file='timeres.param') |
read(10,*) inpfile |
read(10,*) outfile |
read(10,*) ntra,otim,ncol |
read(10,*) timeres |
read(10,*) unit |
read(10,*) mode |
close(10) |
c Change unit to minutes |
if ( unit.eq.'min') then |
timeres = 1./60. * timeres |
unit = 'h' |
endif |
c Determine the formats |
call mode_tra(inpmode,inpfile) |
if (inpmode.eq.-1) inpmode=1 |
call mode_tra(outmode,outfile) |
if (outmode.eq.-1) outmode=1 |
c ---------------------------------------------------------------------- |
c Read input trajectory and allocate memory |
c ---------------------------------------------------------------------- |
c Allocate memory for input trajectories |
allocate(trainp(ntra,otim,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array trainp ***' |
allocate(timold(otim),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array timold ***' |
allocate(fldold(otim),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array fldold ***' |
c Read inpufile |
call ropen_tra(fid,inpfile,ntra,otim,ncol,refdate,vars,inpmode) |
call read_tra (fid,trainp,ntra,otim,ncol,inpmode) |
call close_tra(fid,inpmode) |
c Check that first four columns correspond to time,lon,lat,p |
if ( (vars(1).ne.'time' ).or. |
> (vars(2).ne.'xpos' ).and.(vars(2).ne.'lon' ).or. |
> (vars(3).ne.'ypos' ).and.(vars(3).ne.'lat' ).or. |
> (vars(4).ne.'ppos' ).and.(vars(4).ne.'p' ) ) |
>then |
print*,' ERROR: problem with input trajectories ...' |
stop |
endif |
c Convert all times from hhmm to fractional time |
do i=1,ntra |
do j=1,otim |
hhmm = trainp(i,j,1) |
call hhmm2frac(hhmm,tfrac) |
trainp(i,j,1) = tfrac |
enddo |
enddo |
c Get the time range in minutes |
range = ( trainp(1,otim,1) - trainp(1,1,1) ) |
c Determine the new number of times |
ntim = nint( abs( range ) / timeres ) + 1 |
c Check that the time range and new time resolution are consistent |
if ( abs( real(ntim-1) * timeres -range ).gt.eps ) then |
print*,' ERROR: time range and resolution are not compatible' |
print*,' range = ',range |
print*,' (ntim-1) * timeres = ',real(ntim-1) * timeres |
stop |
endif |
c Allocate memory for output trajectories |
allocate(traout(ntra,ntim,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array trainp ***' |
allocate(timnew(ntim),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array timnew ***' |
allocate(fldnew(ntim),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array fldnew ***' |
c Define the old and new times |
do i=1,otim |
timold(i) = trainp(1,i,1) |
enddo |
do i=1,ntim |
timnew(i) = timold(1) + real(i-1) * timeres |
enddo |
c ---------------------------------------------------------------------- |
c Change time resolution |
c ---------------------------------------------------------------------- |
do i=1,ntra |
do k=2,ncol |
c Copy old field |
do j=1,otim |
fldold(j) = trainp(i,j,k) |
enddo |
c Exception: Handle date line problem for longitude |
if ( k.eq.2 ) then |
do j=2,otim |
if ( (fldold(j-1)-fldold(j)).gt.180. ) then |
fldold(j) = fldold(j) + 360. |
else if ( (fldold(j-1)-fldold(j)).lt.-180. ) then |
fldold(j) = fldold(j) - 360. |
endif |
enddo |
endif |
c Cubic spline fitting |
if ( mode.eq.'cubic' ) then |
call cubicfit (timold,fldold,otim,timnew,fldnew,ntim) |
else if (mode.eq.'linear' ) then |
call linearfit(timold,fldold,otim,timnew,fldnew,ntim) |
endif |
c Exception: Reverse date line handling for longitude |
if ( k.eq.2 ) then |
do j=1,ntim |
if ( fldnew(j).gt.180. ) then |
fldnew(j) = fldnew(j) -360. |
else if ( fldnew(j).lt.-180. ) then |
fldnew(j) = fldnew(j) +360. |
endif |
enddo |
endif |
c Save the new field in the output trajectory |
do j=1,ntim |
traout(i,j,1) = timnew(j) |
traout(i,j,k) = fldnew(j) |
enddo |
enddo |
enddo |
c ---------------------------------------------------------------------- |
c Write output trajectory |
c ---------------------------------------------------------------------- |
c Convert all times from fractional to hhmm time |
do i=1,ntra |
do j=1,ntim |
tfrac = traout(i,j,1) |
call frac2hhmm(tfrac,hhmm) |
traout(i,j,1) = hhmm |
enddo |
enddo |
c Write output file |
call wopen_tra(fid,outfile,ntra,ntim,ncol,refdate,vars,outmode) |
call write_tra(fid,traout,ntra,ntim,ncol,outmode) |
call close_tra(fid,outmode) |
end |
c ******************************************************************** |
c * REPARAMETERIZATION SUBROUTINES * |
c ******************************************************************** |
c ------------------------------------------------------------- |
c Interpolation of the trajectory with linear interpolation |
c ------------------------------------------------------------- |
SUBROUTINE linearfit (time,lon,n,sptime,splon,spn) |
c Given the curve <time,lon> with <n> data points, fit a |
c linear fit to this curve. The new curve is returned in |
c <sptime,splon,spn> with <spn> data points. The parameter |
c <spn> specifies on entry the number of interpolated points |
c along the curve. |
implicit none |
c Declaration of subroutine parameters |
integer n |
real time(n),lon(n) |
integer spn |
real sptime(spn),splon(spn) |
c Auxiliary variables |
real dt |
real s |
integer i,j,iold |
real order |
c Determine whether the input array is ascending or descending |
if (time(1).gt.time(n)) then |
order=-1. |
else |
order= 1. |
endif |
c Bring the time array into ascending order |
do i=1,n |
time(i)=order*time(i) |
enddo |
c Prepare the linear interpolation: define the new times |
dt=(time(n)-time(1))/real(spn-1) |
do i=1,spn |
sptime(i)=time(1)+real(i-1)*dt |
enddo |
c Do the interpolation |
iold = 1 |
do i=1,spn |
c Decide which interval of the old time series must be taken |
do j=iold,n-1 |
if ( ( sptime(i).ge.time(j ) ).and. |
> ( sptime(i).lt.time(j+1) ) ) |
> then |
iold = j |
exit |
endif |
enddo |
c Do the linear interpolation |
splon(i) = lon(iold) + ( lon(iold+1) - lon(iold) ) * |
> ( sptime(i) - time(iold) ) / ( time(iold+1) - time(iold) ) |
enddo |
c Change the time arrays back: original order |
do i=1,spn |
sptime(i)=order*sptime(i) |
enddo |
do i=1,n |
time(i)=order*time(i) |
enddo |
return |
end |
c ------------------------------------------------------------- |
c Interpolation of the trajectory with a natural cubic spline |
c ------------------------------------------------------------- |
SUBROUTINE cubicfit (time,lon,n,sptime,splon,spn) |
c Given the curve <time,lon> with <n> data points, fit a |
c cubic spline to this curve. The new curve is returned in |
c <sptime,splon,spn> with <spn> data points. The parameter |
c <spn> specifies on entry the number of spline interpolated points |
c along the curve. |
implicit none |
c Declaration of subroutine parameters |
integer n |
real time(n),lon(n) |
integer spn |
real sptime(spn),splon(spn) |
c Auxiliary variables |
real y2ax(n) |
real dt |
real s |
integer i |
real order |
c Determine whether the input array is ascending or descending |
if (time(1).gt.time(n)) then |
order=-1. |
else |
order= 1. |
endif |
c Bring the time array into ascending order |
do i=1,n |
time(i)=order*time(i) |
enddo |
c Prepare the (natural) cubic spline interpolation |
call spline (time,lon,n,1.e30,1.e30,y2ax) |
dt=(time(n)-time(1))/real(spn-1) |
do i=1,spn |
sptime(i)=time(1)+real(i-1)*dt |
enddo |
c Do the spline interpolation |
do i=1,spn |
call splint(time,lon,y2ax,n,sptime(i),s) |
splon(i)=s |
enddo |
c Change the time arrays back |
do i=1,spn |
sptime(i)=order*sptime(i) |
enddo |
do i=1,n |
time(i)=order*time(i) |
enddo |
return |
end |
c ------------------------------------------------------------- |
c Basic routines for spline interpolation (Numerical Recipes) |
c ------------------------------------------------------------- |
SUBROUTINE spline(x,y,n,yp1,ypn,y2) |
INTEGER n,NMAX |
REAL yp1,ypn,x(n),y(n),y2(n) |
PARAMETER (NMAX=500) |
INTEGER i,k |
REAL p,qn,sig,un,u(NMAX) |
if (yp1.gt..99e30) then |
y2(1)=0. |
u(1)=0. |
else |
y2(1)=-0.5 |
u(1)=(3./(x(2)-x(1)))*((y(2)-y(1))/(x(2)-x(1))-yp1) |
endif |
do 11 i=2,n-1 |
sig=(x(i)-x(i-1))/(x(i+1)-x(i-1)) |
p=sig*y2(i-1)+2. |
y2(i)=(sig-1.)/p |
u(i)=(6.*((y(i+1)-y(i))/(x(i+ |
*1)-x(i))-(y(i)-y(i-1))/(x(i)-x(i-1)))/(x(i+1)-x(i-1))-sig* |
*u(i-1))/p |
11 continue |
if (ypn.gt..99e30) then |
qn=0. |
un=0. |
else |
qn=0.5 |
un=(3./(x(n)-x(n-1)))*(ypn-(y(n)-y(n-1))/(x(n)-x(n-1))) |
endif |
y2(n)=(un-qn*u(n-1))/(qn*y2(n-1)+1.) |
do 12 k=n-1,1,-1 |
y2(k)=y2(k)*y2(k+1)+u(k) |
12 continue |
return |
END |
SUBROUTINE splint(xa,ya,y2a,n,x,y) |
INTEGER n |
REAL x,y,xa(n),y2a(n),ya(n) |
INTEGER k,khi,klo |
REAL a,b,h |
klo=1 |
khi=n |
1 if (khi-klo.gt.1) then |
k=(khi+klo)/2 |
if(xa(k).gt.x)then |
khi=k |
else |
klo=k |
endif |
goto 1 |
endif |
h=xa(khi)-xa(klo) |
if (h.eq.0.) pause 'bad xa input in splint' |
a=(xa(khi)-x)/h |
b=(x-xa(klo))/h |
y=a*ya(klo)+b*ya(khi)+((a**3-a)*y2a(klo)+(b**3-b)*y2a(khi))*(h** |
*2)/6. |
return |
END |
/tags/1.0/goodies/timeres.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = timeres.o ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/times.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
timeres: $(OBJS) |
${F77} -o timeres $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/timeres.sh |
---|
0,0 → 1,70 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp timeres short |
echo |
exit 0 |
endif |
# Get input and output trajectory file |
set inpfile = $1 |
set outfile = $2 |
# Handle optional arguments |
set mode = "cubic" |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -h |
set unit = "h" |
set value = $argv[2] |
shift; |
breaksw |
case -min |
set unit = "min" |
set value = $argv[2] |
shift; |
breaksw |
case -linear |
set mode = "linear" |
breaksw |
case -cubic |
set mode = "cubic" |
breaksw |
endsw |
shift; |
end |
# Get the dimensions of the trajectory file |
set dim=`${LAGRANTO}/goodies/trainfo.sh ${inpfile} dim` |
# Prepare parameter file and run program |
\rm -f timeres.param |
echo \"${inpfile}\" >! timeres.param |
echo \"${outfile}\" >> timeres.param |
echo ${dim} >> timeres.param |
echo ${value} >> timeres.param |
echo \"${unit}\" >> timeres.param |
echo \"${mode}\" >> timeres.param |
${LAGRANTO}/goodies/timeres |
# Make clean |
#\rm -f timeres.param |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/tracal.f |
---|
0,0 → 1,127 |
PROGRAM tracal |
c *********************************************************************** |
c * Calculations with trajectories * |
c * Michael Sprenger / Spring, summer 2010 * |
c *********************************************************************** |
use evaluate |
implicit none |
c ---------------------------------------------------------------------- |
c Declaration of variables |
c ---------------------------------------------------------------------- |
c Input and output format for trajectories (see iotra.f) |
character*80 inpfile ! Input filename |
character*80 outfile ! Output filename |
character*80 expr ! Expression for calculation |
c Trajectories |
integer ntra ! Number of trajectories |
integer ntim ! Number of times |
integer ncol ! Number of columns |
real,allocatable, dimension (:,:,:) :: trainp ! Trajectories (ntra,ntim,ncol ) |
real,allocatable, dimension (:,:,:) :: traout ! Trajectories (ntra,ntim,ncol+1) |
character*80 vars(100) ! Variable names |
integer refdate(6) ! Reference date |
c Auxiliary variables |
integer inpmode |
integer outmode |
integer stat |
integer fid |
integer i,j,k |
character (len=24) col,new |
real value |
character ch |
integer ileft,iright |
c ---------------------------------------------------------------------- |
c Do the reformating |
c ---------------------------------------------------------------------- |
c Read parameters |
open(10,file='tracal.param') |
read(10,*) inpfile |
read(10,*) outfile |
read(10,*) expr |
read(10,*) ntra,ntim,ncol |
close(10) |
c Get the name of the output field |
ileft = 1 |
iright = 0 |
do i=1,80 |
if ( expr(i:i).eq.'=' ) iright = i |
enddo |
if ( iright.eq.0 ) then |
vars(ncol+1) = 'CALC' |
expr = 'CALC='//trim(expr) |
else |
vars(ncol+1) = trim( expr(1:iright-1) ) |
endif |
new = vars( ncol+1 ) |
print*,'inp = ',trim(inpfile) |
print*,'out = ',trim(outfile) |
print*,'expr = ',trim(expr),' ---> ',trim( new ) |
c Determine the formats |
call mode_tra(inpmode,inpfile) |
if (inpmode.eq.-1) inpmode=1 |
call mode_tra(outmode,outfile) |
if (outmode.eq.-1) outmode=1 |
c Allocate memory |
allocate(trainp(ntra,ntim,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array trainp ***' |
allocate(traout(ntra,ntim,ncol+1),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array traout ***' |
c Read inpufile |
call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode) |
call read_tra (fid,trainp,ntra,ntim,ncol,inpmode) |
call close_tra(fid,inpmode) |
c Copy to output trajectory |
do i=1,ntra |
do j=1,ntim |
do k=1,ncol |
traout(i,j,k) = trainp(i,j,k) |
enddo |
enddo |
enddo |
c Loop over all trajectories |
do i=1,ntra |
do j=1,ntim |
do k=1,ncol |
c Attribute trajectory values to symbols |
col = vars(k) |
call defparam( col, traout(i,j,k) ) |
enddo |
c Evaluate expression |
call evaleqn(expr) |
c Get the result |
call getparam(new,value) |
traout(i,j,ncol+1) = value |
enddo |
enddo |
c Write output file |
call wopen_tra(fid,outfile,ntra,ntim,ncol+1,refdate,vars,outmode) |
call write_tra(fid,traout,ntra,ntim,ncol+1,outmode) |
call close_tra(fid,outmode) |
end |
/tags/1.0/goodies/tracal.install |
---|
0,0 → 1,49 |
# ----- Load modules -------------------------- |
module load netcdf/4.2.1-pgf90 |
module list |
set tool = tracal |
# ----- Set libraries and includes ------------ |
set libs = "${LAGRANTO}/lib/iotra.a" |
set libs = "${libs} -L ${LAGRANTO}/lib" |
set libs = "${libs} -lcdfio" |
set libs = "${libs} -lcdfplus" |
set ncdf_incs = `nc-config --fflags` |
set ncdf_libs = `nc-config --flibs` |
# ---- Modules --------------------------------- |
\rm -f precmod.o precision.mod |
echo ${FORTRAN} -c precmod.f90 |
${FORTRAN} -c precmod.f90 |
\rm -f stringmod.o strings.mod |
echo ${FORTRAN} -c stringmod.f90 |
${FORTRAN} -c stringmod.f90 |
\rm -f evalmod.o evaluate.mod |
echo ${FORTRAN} -c evalmod.f90 |
${FORTRAN} -c evalmod.f90 |
set mods = " evalmod.o precmod.o stringmod.o " |
# ----- Compile --------------------- ---------- |
\rm -f ${tool}.o |
\rm -f ${tool} |
echo "${FORTRAN} -c ${tool}.f ${ncdf_incs}" |
${FORTRAN} -c ${tool}.f ${ncdf_incs} |
echo "${FORTRAN} -o ${tool} ${tool}.o ${mods} ${libs} ${ncdf_libs}" |
${FORTRAN} -o ${tool} ${tool}.o ${mods} ${libs} ${ncdf_libs} |
if ( ! -f ${tool} ) then |
echo "ERROR: compilation of <tool> failed... exit" |
exit 1 |
endif |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/tracal.sh |
---|
0,0 → 1,31 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp tracal short |
echo |
exit 0 |
endif |
set inpfile = $1 |
set outfile = $2 |
set expr = $3 |
set dim=`${LAGRANTO}/goodies/trainfo.sh ${inpfile} dim` |
\rm -f tracal.param |
echo \"${inpfile}\" >! tracal.param |
echo \"${outfile}\" >> tracal.param |
echo \"${expr}\" >> tracal.param |
echo ${dim} >> tracal.param |
${LAGRANTO}/goodies/tracal |
\rm -f tracal.param |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/goodies/trainfo.f |
---|
0,0 → 1,300 |
PROGRAM trainfo |
c *********************************************************************** |
c * Get infos for a trajectory file * |
c * Michael Sprenger / Spring, summer 2010 * |
c *********************************************************************** |
implicit none |
c ---------------------------------------------------------------------- |
c Declaration of variables |
c ---------------------------------------------------------------------- |
c Input file |
character*80 inpfile ! Input filename |
character*80 mode ! Mode |
c Trajectories |
integer ntra ! Number of trajectories |
integer ntim ! Number of times |
integer ncol ! Number of columns |
character*80 vars(100) ! Variable names |
integer refdate(6) ! Reference date |
real,allocatable, dimension (:,:,:) :: tra ! Trajectories (ntra,ntim,ncol) |
c Auxiliary variables |
integer inpmode |
integer stat |
integer fid |
integer i,j,n |
integer old(5) |
integer new(5) |
integer hour,min |
character*20 datestr |
character*120 str |
character*4 str1 |
character*2 str2,str3,str4,str5,str6 |
integer isok |
integer nleaving |
c ---------------------------------------------------------------------- |
c Do the reformating |
c ---------------------------------------------------------------------- |
c Read parameters |
open(10,file='trainfo.param') |
read(10,*) inpfile |
read(10,*) mode |
close(10) |
c Determine the formats |
call mode_tra(inpmode,inpfile) |
if (inpmode.eq.-1) inpmode=1 |
c Get the dimension of the trajectory file |
call info_tra(inpfile,ntra,ntim,ncol,inpmode) |
c Get haeder information |
call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode) |
call close_tra(fid,inpmode) |
c Write dimensions |
if ( (mode.eq.'dim').or.(mode.eq.'all') ) then |
print*,ntra,ntim,ncol |
endif |
c Write single dimensions |
if ( (mode.eq.'ntra').or.(mode.eq.'all') ) then |
print*,ntra |
endif |
if ( (mode.eq.'ntim').or.(mode.eq.'all') ) then |
print*,ntim |
endif |
if ( (mode.eq.'ncol').or.(mode.eq.'all') ) then |
print*,ncol |
endif |
c Write variable names |
if ( (mode.eq.'vars').or.(mode.eq.'all') ) then |
print*,(trim(vars(i))//' ',i=1,ncol) |
endif |
c Write reference date |
if ( (mode.eq.'refdate').or.(mode.eq.'all') ) then |
c Concatenate date string |
min = refdate(5) |
call datestring(datestr, |
> refdate(1),refdate(2),refdate(3),refdate(4) ) |
if ( min.eq.0 ) then |
datestr = trim(datestr)//'00' |
elseif (min.lt.10) then |
datestr = trim(datestr)//'0'//char(ichar('0')+min) |
else |
datestr = trim(datestr)// |
> char(ichar('0')+int(min/10))// |
> char(ichar('0')+mod(min,10)) |
endif |
c Write date string |
print*,trim(datestr) |
endif |
c Load all trajectory times if necessary |
if ( (mode.eq.'all' ).or. |
> (mode.eq.'times' ).or. |
> (mode.eq.'startdate').or. |
> (mode.eq.'enddate' ) ) |
>then |
allocate(tra(ntra,ntim,ncol),stat=stat) |
call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode) |
call read_tra (fid,tra,ntra,ntim,ncol,inpmode) |
call close_tra(fid,inpmode) |
endif |
c Write list of all times |
if ( (mode.eq.'times').or.(mode.eq.'all') ) then |
write(*,'(100f8.2)') (tra(1,i,1),i=1,ntim) |
endif |
c Write time range |
if ( (mode.eq.'timerange').or.(mode.eq.'all') ) then |
write(*,'(i6)') refdate(6) |
endif |
c Write firstdate (reference date + first time) |
if ( (mode.eq.'startdate').or.(mode.eq.'all') ) then |
c Set the time shift of first time relative to reference date |
hour = int(tra(1,1,1)) |
min = mod(nint(100.*tra(1,1,1)),100) + refdate(5) |
if (min.gt.60) then |
min = min - 60 |
hour = hour + 1 |
endif |
if (min.lt.0) then |
min = min + 60 |
hour = hour - 1 |
endif |
if (min.lt.0) then |
min = min + 60 |
hour = hour - 1 |
endif |
c Get new date (hours and minutes) |
old(1) = refdate(1) |
old(2) = refdate(2) |
old(3) = refdate(3) |
old(4) = refdate(4) |
old(5) = 0 |
call newdate(old,real(hour),new) |
c Concatenate the date string |
call datestring(datestr, |
> new(1),new(2),new(3),new(4) ) |
if ( min.eq.0 ) then |
datestr = trim(datestr)//'00' |
elseif (min.lt.10) then |
datestr = trim(datestr)//'0'//char(ichar('0')+min) |
else |
datestr = trim(datestr)// |
> char(ichar('0')+int(min/10))// |
> char(ichar('0')+mod(min,10)) |
endif |
c Write date string |
print*,trim(datestr) |
endif |
c Write enddate (reference date + last time) |
if ( (mode.eq.'enddate').or.(mode.eq.'all') ) then |
c Set the time shift of first time relative to reference date |
hour = int(tra(1,ntim,1)) |
min = mod(nint(100.*tra(1,ntim,1)),100) + refdate(5) |
if (min.gt.60) then |
min = min - 60 |
hour = hour + 1 |
endif |
if (min.lt.0) then |
min = min + 60 |
hour = hour - 1 |
endif |
if (min.lt.0) then |
min = min + 60 |
hour = hour - 1 |
endif |
c Get new date (hours and minutes) |
old(1) = refdate(1) |
old(2) = refdate(2) |
old(3) = refdate(3) |
old(4) = refdate(4) |
old(5) = 0 |
call newdate(old,real(hour),new) |
c Concatenate the date string |
call datestring(datestr, |
> new(1),new(2),new(3),new(4) ) |
if ( min.eq.0 ) then |
datestr = trim(datestr)//'00' |
elseif (min.lt.10) then |
datestr = trim(datestr)//'0'//char(ichar('0')+min) |
else |
datestr = trim(datestr)// |
> char(ichar('0')+int(min/10))// |
> char(ichar('0')+mod(min,10)) |
endif |
c Write date string |
print*,trim(datestr) |
endif |
c Write trajectories to screen |
if ( (mode.eq.'list') ) then |
c Read the complete trajectory file |
allocate(tra(ntra,ntim,ncol),stat=stat) |
call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode) |
call read_tra (fid,tra,ntra,ntim,ncol,inpmode) |
call close_tra(fid,inpmode) |
c Get the strings for output |
write(str1,'(i4)') refdate(1) |
write(str2,'(i2)') refdate(2) |
write(str3,'(i2)') refdate(3) |
write(str4,'(i2)') refdate(4) |
write(str5,'(i2)') refdate(5) |
if (refdate(2).eq. 0) str2(1:1)='0' |
if (refdate(3).eq. 0) str3(1:1)='0' |
if (refdate(4).eq. 0) str4(1:1)='0' |
if (refdate(5).eq. 0) str5(1:1)='0' |
if (refdate(2).lt.10) str2(1:1)='0' |
if (refdate(3).lt.10) str3(1:1)='0' |
if (refdate(4).lt.10) str4(1:1)='0' |
if (refdate(5).lt.10) str5(1:1)='0' |
c Write the time specification |
write(*,'(a15,a4,a2,a2,a1,a2,a2,a13,i8,a4)') |
> 'Reference date ', |
> str1,str2,str3,'_',str4,str5, |
> ' / Time range',refdate(6), ' min' |
write(*,*) |
c Write variable names |
str='' |
do i=1,ncol |
str=trim(str)//trim(vars(i)) |
enddo |
write(*,'(a6,a9,a8,a6,100a10)') (trim(vars(i)),i=1,ncol) |
write(*,'(a6,a9,a8,a6,100a10)') |
> '------','---------','--------','------', |
> ('----------',i=5,ncol) |
do n=1,ntra |
write(*,*) |
do i=1,ntim |
write(*,'(1f7.2,f9.2,f8.2,i6,100f10.3)') |
> (tra(n,i,j),j=1,3), ! time, lon, lat |
> nint(tra(n,i,4)), ! p |
> (tra(n,i,j),j=5,ncol) ! fields |
enddo |
enddo |
endif |
c Get number of trajectories leaving domain |
if ( (mode.eq.'leaving') ) then |
c Read the complete trajectory file |
allocate(tra(ntra,ntim,ncol),stat=stat) |
call ropen_tra(fid,inpfile,ntra,ntim,ncol,refdate,vars,inpmode) |
call read_tra (fid,tra,ntra,ntim,ncol,inpmode) |
call close_tra(fid,inpmode) |
c Determine the number of trajectories leaving domain |
do i=1,ntra |
isok = 1 |
do j=1,ntim |
if ( tra(i,j,4).lt.0. ) isok = 0 |
enddo |
if ( isok.eq.0 ) then |
nleaving = nleaving + 1 |
endif |
enddo |
c Write output |
print*,nleaving |
endif |
end |
/tags/1.0/goodies/trainfo.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = trainfo.o ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/times.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
trainfo: $(OBJS) |
${F77} -o trainfo $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/goodies/trainfo.sh |
---|
0,0 → 1,69 |
#!/bin/csh |
# ----------------------------------------------------------------------------- |
# Set some parameters |
# ----------------------------------------------------------------------------- |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Set input file |
set inpfile=$1 |
if ( ${#argv} == 2 ) then |
set mode=$2 |
else |
set mode='all' |
endif |
# Write usage information |
if ( ${#argv} == 0) then |
echo |
${LAGRANTO}/bin/lagrantohelp trainfo short |
echo |
exit 0 |
endif |
# Set Fortran program |
set prog=${LAGRANTO}/goodies/trainfo |
# ----------------------------------------------------------------------------- |
# Run program |
# ----------------------------------------------------------------------------- |
\rm -f trainfo.param |
echo \"${inpfile}\" >! trainfo.param |
echo \"${mode}\" >> trainfo.param |
${prog} |
\rm -f trainfo.param |
exit 0 |
# ----------------------------------------------------------------------------- |
# Old code: shell script extraction of ntra,ntim,ncol |
# ----------------------------------------------------------------------------- |
# Get line numbers of first trajectory block (separated by empty line) |
set first=4 |
loop1: |
@ first = ${first} + 1 |
set line=`sed -ne "${first},${first}p" ${inpfile}` |
if ( "${line}" != "" ) goto loop1 |
@ final = ${first} + 1 |
loop2: |
@ final = ${final} + 1 |
set line=`sed -ne "${final},${final}p" ${inpfile}` |
if ( "${line}" != "" ) goto loop2 |
@ first = ${first} + 1 |
@ final = ${final} - 1 |
# Set the number of fields, of times and of trajectories |
set ntime=`echo "1 + ${final} - ${first}" | bc` |
set line=`sed -ne "${first},${first}p" ${inpfile}` |
set ncol=`echo ${line} | awk '{print NF}'` |
set nlines=`wc -l ${inpfile} | awk '{print $1}'` |
set ntra=`echo "(${nlines}-4)/(${ntime}+1)" | bc` |
# Write info |
echo ${ntra} ${ntime} ${ncol} |
Property changes: |
Added: svn:executable |
/tags/1.0/install.csh |
---|
0,0 → 1,496 |
#!/bin/csh |
# ----------------------------------------------------------------------------- |
# Set some general parameters |
# ----------------------------------------------------------------------------- |
# Usage |
if ( $#argv == 0 ) then |
echo "install.sh [lib|core|goodies|links|all|docu|clean|tag] " |
exit 0 |
endif |
# Set the mode |
set mode = $1 |
# Set path to SVN repository |
set svnpath=https://svn.iac.ethz.ch/pub/lagranto.20cr/ |
# Set paths for development and for synchronisation (operational) |
set path_devel = "${DYN_TOOLS}/lagranto.20cr/" |
set path_sync = "${DYN_TOOLS}/lagranto/" |
# Init Fortran compiler and set netCDF acccordingly |
setenv FORTRAN pgf90 |
# Init netCDF library depending on the Fortran compiler |
if ( "${FORTRAN}" == "pgf90" ) then |
module load netcdf/4.2.1-pgf90 |
module list |
else if ( "${FORTRAN}" == "gfortran" ) then |
module load gfortran |
module load netcdf/4.1.1 |
else if ( "${FORTRAN}" == "ifort" ) then |
module load ifort/10.1.017 |
module load netcdf/4.1.1-ifort |
else |
echo "Fortran Compiler ${FORTRAN} not supported... Exit" |
exit 1 |
endif |
# ----------------------------------------------------------------------------- |
# Set internal parameters and detailed installation mode |
# ----------------------------------------------------------------------------- |
# Set LAGRANTO environment variable |
setenv LAGRANTO ${path_devel} |
# Set netCDF paths |
setenv NETCDF_LIB `nc-config --flibs` |
setenv NETCDF_INC `nc-config --fflags` |
# Set list of core programs |
set core = "create_startf caltra trace select density lidar" |
# Set list of goodies |
set tools = "changet extract gettidiff getvars list2lsl lsl2list mergetra newtime reformat timeres trainfo difference datelist tracal" |
# Set list of libraries |
set libs = "iotra ioinp inter times libcdfio libcdfplus" |
# Core programs |
foreach prog ( $core ) |
if ( "${prog}" == "${mode}" ) then |
set core = ${prog} |
set mode = "core" |
endif |
end |
# Goodies |
foreach tool ( $tools ) |
if ( "${tool}" == "${mode}" ) then |
set tools = ${tool} |
set mode = "goodies" |
endif |
end |
# Libraries |
foreach lib ( $libs ) |
if ( "${lib}" == "${mode}" ) then |
set libs = ${lib} |
set mode = "lib" |
endif |
end |
# Check that the mode is ok |
if ( "${mode}" == "all" ) goto modeok |
if ( "${mode}" == "lib" ) goto modeok |
if ( "${mode}" == "core" ) goto modeok |
if ( "${mode}" == "goodies" ) goto modeok |
if ( "${mode}" == "links" ) goto modeok |
if ( "${mode}" == "clean" ) goto modeok |
if ( "${mode}" == "docu" ) goto modeok |
if ( "${mode}" == "sync" ) goto modeok |
echo "Unsupported mode ${mode} ... Stop" |
exit 1 |
modeok: |
# ----------------------------------------------------------------------------- |
# Create a new tag in SVN repository |
# ----------------------------------------------------------------------------- |
if ( "${mode}" == "tag" ) then |
svn info |
if ( "${#argv}" != 2 ) then |
echo "Usage: install.csh tag id <id=tag number>" |
else |
set tagnr = $2 |
endif |
svn copy ${svnpath}/trunk ${svnpath}/tags/${tagnr} -m "Release ${tagnr}" |
exit 0 |
endif |
# ----------------------------------------------------------------------------- |
# Make clean |
# ----------------------------------------------------------------------------- |
if ( "${mode}" == "clean" ) then |
cd ${LAGRANTO}/ |
foreach prog ( $core ) |
\rm -f ${prog}/${prog} ${prog}/${prog}.o |
end |
\rm -f trace/calvar.o select/special.o |
foreach tool ( $tools ) |
\rm -f goodies/${tool} goodies/${tool}.o |
end |
\rm -f goodies/*.mod goodies/*.o |
\rm lib/*.a lib/*.o |
foreach prog ( $core ) |
\rm -f bin/${prog} bin/${prog}.sh bin/${prog}.20cr |
end |
\rm -f bin/seltra bin/seltra.sh bin/seltra.20cr |
foreach tool ( $tools ) |
\rm -f bin/${tool} bin/${tool}.sh bin/${tool}.20cr |
end |
\rm -f bin/lagrantohelp.sh bin/lagrantohelp.20cr |
\rm -f bin/startf bin/startf.sh bin/startf.20cr |
\rm -f bin/lagranto.sh bin/lagranto.20cr |
\rm ${LAGRANTO}/startf |
exit 0 |
endif |
# ----------------------------------------------------------------------------- |
# Install reference |
# ----------------------------------------------------------------------------- |
if ( ("${mode}" == "docu") | ("${mode}" == "all" ) ) then |
echo "-----------------------------------------------------------------" |
echo "Installing documentation" |
echo "-----------------------------------------------------------------" |
echo |
cd ${LAGRANTO}/docu/reference/ |
\rm -f reference.ps |
\rm -f reference2.ps |
groff -man ../man/*.0 > reference2.ps |
ps2pdf reference2.ps |
latex title |
dvips title |
ps2pdf title.ps |
gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=reference.pdf title.pdf reference2.pdf |
\rm -f *.aux *.log *.dvi |
\rm -f title.ps reference2.ps |
\rm -f title.pdf reference2.pdf |
endif |
if ( "${mode}" == "docu" ) exit 0 |
# ----------------------------------------------------------------------------- |
# Install libraries |
# ----------------------------------------------------------------------------- |
if ( ("${mode}" == "lib") | ("${mode}" == "all" ) ) then |
echo "-----------------------------------------------------------------" |
echo "Installing libraries" |
echo "-----------------------------------------------------------------" |
echo |
# Change to library directory |
cd ${LAGRANTO}/lib |
# Loop over all libraries - compile and make library |
foreach lib ( $libs ) |
\rm -f ${lib}.a |
\rm -f ${lib}.o |
echo ${FORTRAN} -c -O ${lib}.f |
${FORTRAN} -c -O ${NETCDF_INC} ${lib}.f |
ar r ${lib}.a ${lib}.o |
\rm -f ${lib}.l ${lib}.o |
ranlib ${lib}.a |
if ( ! -f ${lib}.a ) then |
echo "Problem in compiling ${lib} ... Stop" |
exit 1 |
endif |
end |
endif |
if ( "${mode}" == "lib" ) exit 0 |
# ----------------------------------------------------------------------------- |
# Check that libraries are ok |
# ----------------------------------------------------------------------------- |
echo |
echo "-----------------------------------------------------------------" |
echo "Check that all libraries are available" |
echo "-----------------------------------------------------------------" |
echo |
# Change to library directory |
cd ${LAGRANTO}/lib |
# Check whether all libraries are available |
foreach lib ( $libs ) |
if ( ! -f ${lib}.a ) then |
echo "Library ${lib} missing... Stop" |
exit 1 |
else |
ls -l ${lib}.a |
endif |
end |
# Exit if only libraries shoudl be installed |
if ( "${mode}" == "lib" ) exit 0 |
# ----------------------------------------------------------------------------- |
# Compile Lagrango core programs |
# ----------------------------------------------------------------------------- |
if ( ("${mode}" == "all" ) | ("${mode}" == "core" ) ) then |
echo |
echo "-----------------------------------------------------------------" |
echo "Installing Lagranto core programs" |
echo "-----------------------------------------------------------------" |
foreach prog ( $core ) |
echo |
echo "----- $prog" |
echo |
cd ${LAGRANTO}/${prog} |
\rm -f ${prog}.o |
\rm -f ${prog} |
if ( "${prog}" == "trace" ) \rm calvar.o |
if ( "${prog}" == "select" ) \rm special.o |
\rm -f ${prog} |
make -f ${prog}.make |
if ( ! -f ${prog} ) then |
echo "Problem in compiling ${prog} ... Stop" |
exit 1 |
endif |
end |
endif |
if ( "${mode}" == "core" ) exit 0 |
# ----------------------------------------------------------------------------- |
# Check that all Lagranto core programs are available |
# ----------------------------------------------------------------------------- |
echo |
echo "-----------------------------------------------------------------" |
echo "Check that all Lagranto core programs are available" |
echo "-----------------------------------------------------------------" |
echo |
foreach prog ( $core ) |
cd ${LAGRANTO}/${prog} |
if ( ! -f ${prog} ) then |
echo "${prog} is missing... Stop" |
exit 1 |
else |
ls -l ${prog} |
endif |
end |
# Exit if only core programs shoudl be installed |
if ( "${mode}" == "core" ) exit 0 |
# ----------------------------------------------------------------------------- |
# Compile Lagrango goodies |
# ----------------------------------------------------------------------------- |
if ( ("${mode}" == "all" ) | ("${mode}" == "goodies" ) ) then |
echo |
echo "-----------------------------------------------------------------" |
echo "Installing Lagranto goodies" |
echo "-----------------------------------------------------------------" |
cd ${LAGRANTO}/goodies |
foreach tool ( $tools ) |
echo |
echo "----- ${tool}" |
echo |
\rm -f ${tool}.o |
\rm -f ${tool} |
if ( -f ${tool}.make ) then |
make -f ${tool}.make |
else if ( -f ${tool}.install ) then |
./${tool}.install |
endif |
if ( ! -f ${tool} ) then |
echo "Problem in compiling ${tool} ... Stop" |
exit 1 |
endif |
end |
endif |
if ( "${mode}" == "goodies" ) exit 0 |
# ----------------------------------------------------------------------------- |
# Check that all Lagranto goodies are available |
# ----------------------------------------------------------------------------- |
echo |
echo "-----------------------------------------------------------------" |
echo "Check that all Lagranto goodies are available" |
echo "-----------------------------------------------------------------" |
echo |
cd ${LAGRANTO}/goodies |
foreach tool ( $tools ) |
if ( ! -f ${tool} ) then |
echo "${tool} is missing... Stop" |
exit 1 |
else |
ls -l ${tool} |
endif |
end |
endif |
# Exit if only goodies should be installed |
if ( "${mode}" == "goodies" ) exit 0 |
# ----------------------------------------------------------------------------- |
# Create links to programs |
# ----------------------------------------------------------------------------- |
if ( ("${mode}" == "all" ) | ("${mode}" == "links" ) ) then |
echo |
echo "-----------------------------------------------------------------" |
echo "Create links in ${LAGRANTO}/bin/" |
echo "-----------------------------------------------------------------" |
echo |
if ( ! -d ${LAGRANTO}/bin ) mkdir ${LAGRANTO}/bin |
cd ${LAGRANTO}/bin |
ln -svf ${LAGRANTO}/bin/lagranto lagranto.20cr |
ln -svf ${LAGRANTO}/bin/lagrantohelp lagrantohelp.20cr |
ln -svf ${LAGRANTO}/caltra/caltra.sh caltra.20cr |
ln -svf ${LAGRANTO}/startf/create_startf.sh create_startf.20cr |
ln -svf ${LAGRANTO}/select/select.sh select.20cr |
ln -svf ${LAGRANTO}/select/select.sh seltra.20cr |
ln -svf ${LAGRANTO}/trace/trace.sh trace.20cr |
ln -svf ${LAGRANTO}/density/density.sh density.20cr |
ln -svf ${LAGRANTO}/startf/create_startf.sh startf.20cr |
ln -svf ${LAGRANTO}/lidar/lidar.sh lidar.20cr |
#ln -svf ${LAGRANTO}/bin/lagranto lagranto |
#ln -svf ${LAGRANTO}/bin/lagrantohelp lagrantohelp |
ln -svf ${LAGRANTO}/caltra/caltra.sh caltra |
ln -svf ${LAGRANTO}/startf/create_startf.sh create_startf |
ln -svf ${LAGRANTO}/select/select.sh select |
ln -svf ${LAGRANTO}/select/select.sh seltra |
ln -svf ${LAGRANTO}/trace/trace.sh trace |
ln -svf ${LAGRANTO}/density/density.sh density |
ln -svf ${LAGRANTO}/startf/create_startf.sh startf |
ln -svf ${LAGRANTO}/lidar/lidar.sh lidar |
ln -svf ${LAGRANTO}/bin/lagranto lagranto.sh |
ln -svf ${LAGRANTO}/bin/lagrantohelp lagrantohelp.sh |
ln -svf ${LAGRANTO}/caltra/caltra.sh caltra.sh |
ln -svf ${LAGRANTO}/startf/create_startf.sh create_startf.sh |
ln -svf ${LAGRANTO}/select/select.sh select.sh |
ln -svf ${LAGRANTO}/select/select.sh seltra.sh |
ln -svf ${LAGRANTO}/trace/trace.sh trace.sh |
ln -svf ${LAGRANTO}/density/density.sh density.sh |
ln -svf ${LAGRANTO}/startf/create_startf.sh startf.sh |
ln -svf ${LAGRANTO}/lidar/lidar.sh lidar.sh |
foreach tool ( $tools ) |
ln -svf ${LAGRANTO}/goodies/${tool}.sh ${tool}.20cr |
ln -svf ${LAGRANTO}/goodies/${tool}.sh ${tool} |
ln -svf ${LAGRANTO}/goodies/${tool}.sh ${tool}.sh |
end |
# Set link for create_startf / startf |
\rm -f ${LAGRANTO}/startf |
ln -svf ${LAGRANTO}/create_startf ${LAGRANTO}/startf |
# Set extra name for <select> to avoid conflict in BASH |
ln -svf ${LAGRANTO}/select/select.sh seltra.20cr |
ln -svf ${LAGRANTO}/select/select.sh seltra.sh |
ln -svf ${LAGRANTO}/select/select.sh seltra |
endif |
# ----------------------------------------------------------------------------- |
# Synchronise ( development -> operational ) |
# ----------------------------------------------------------------------------- |
if ( ("${mode}" == "all" ) | ("${mode}" == "sync" ) ) then |
echo |
echo "-----------------------------------------------------------------" |
echo "Sync ( lagranto.20cr -> lagranto )" |
echo "-----------------------------------------------------------------" |
echo |
cd ${path_sync}/bin/ |
ln -svf ${path_devel}/bin/lagranto.sh lagranto.20cr |
ln -svf ${path_devel}/bin/lagrantohelp.sh lagrantohelp.20cr |
ln -svf ${path_devel}/caltra/caltra.sh caltra.20cr |
ln -svf ${path_devel}/startf/create_startf.sh create_startf.20cr |
ln -svf ${path_devel}/select/select.sh select.20cr |
ln -svf ${path_devel}/trace/trace.sh trace.20cr |
ln -svf ${path_devel}/density/density.sh density.20cr |
ln -svf ${path_devel}/startf/create_startf.sh startf.20cr |
ln -svf ${path_devel}/lidar/lidar.sh lidar.20cr |
ln -svf ${path_devel}/lidar/seltra.sh seltra.20cr |
foreach tool ( $tools ) |
ln -svf ${path_devel}/goodies/${tool}.sh ${tool}.20cr |
end |
# Set all permissions |
chmod -R og+rx ${path_sync}/bin/ |
endif |
# ----------------------------------------------------------------------------- |
# Final tasks |
# ----------------------------------------------------------------------------- |
echo |
echo "-----------------------------------------------------------------" |
echo "Installation complete" |
echo "-----------------------------------------------------------------" |
echo |
echo "Please set the environmental variable LAGRANTO" |
echo |
echo " setenv LAGRANTO ${LAGRANTO}" |
echo |
Property changes: |
Added: svn:executable |
/tags/1.0/lagranto.20cr.docu |
---|
0,0 → 1,0 |
${DYN_TOOLS}/lagranto.20cr/bin/lagrantohelp |
Property changes: |
Added: svn:executable |
/tags/1.0/lagranto.20cr.install |
---|
0,0 → 1,7 |
#!/bin/csh |
# ----- Run Lagrantoninstaller ------------------- |
./install.csh all |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/lib/inter.f |
---|
0,0 → 1,485 |
c ************************************************************* |
c * This package provides a general interpolaton routine * |
c ************************************************************* |
c The main interface routines are: |
c get_index3,4 : get the grid indices for interpolation |
c int_index3,4 : interpolate to the grid position |
c ------------------------------------------------------------- |
c Get index in grid space for interpolation |
c ------------------------------------------------------------- |
subroutine get_index4 (rid,rjd,rkd,xpo,ypo,ppo,rtp, |
> vert0,vert1,surf0,surf1,mode, |
> nx,ny,nz,lonw,lats,dlon,dlat,misdat) |
c Purpose: |
c This subroutine determines the indices (rid,rjd,rkd) in grid |
c space for a point in physical space (xpo,ypo,ppo). The |
c horizontal grid is specified by the south-west point (lats,lonw) |
c and the grid spacing (dlat,dlon). The vertical grid is given |
c by <vert(n1,n2,n3)>. The lower boundary (typicall surface |
c pressure) is given by <surf(n1,n2)>. |
c Arguments: |
c rid,rjd,rkd real output grid location to be interpolated to |
c xpo,ypo,ppo real input physical coordinates |
c rtp real input relative time position (0=beginning, 1=end) |
c n1,n2,n3 int input grid dimensions in x-, y- and p-direction |
c lats,lonw real input south and west boundary of grid space |
c vert real input vertical coordinate grid |
c surf real input lower boundary (surface pressure) |
c mode int input direction of vertical axis (p=1,th=-1) |
c 1: linear, 1 -> nz (th) |
c 2: linear, nz -> 1 (pv) |
c 3: binary (p) |
implicit none |
c Declartion of function parameters |
integer nx,ny,nz |
real xpo,ypo,ppo,rtp |
real vert0(nx*ny*nz),vert1(nx*ny*nz) |
real surf0(nx*ny) ,surf1(nx*ny*nz) |
real rid,rjd,rkd |
real dlat,dlon,lats,lonw |
real misdat |
integer mode |
c Set numerical parameters |
real eps |
parameter (eps=1.e-8) |
c Auxiliary variables |
real rid0,rjd0,rkd0,rid1,rjd1,rkd1 |
c Externals |
real int_time |
external int_time |
c Get the inidices |
if (abs(rtp).lt.eps) then |
call get_index3 (rid,rjd,rkd,xpo,ypo,ppo,mode, |
> vert0,surf0,nx,ny,nz,lonw,lats,dlon,dlat) |
elseif (abs(rtp-1.).lt.eps) then |
call get_index3 (rid,rjd,rkd,xpo,ypo,ppo,mode, |
> vert1,surf1,nx,ny,nz,lonw,lats,dlon,dlat) |
else |
call get_index3 (rid0,rjd0,rkd0,xpo,ypo,ppo,mode, |
> vert0,surf0,nx,ny,nz,lonw,lats,dlon,dlat) |
call get_index3 (rid1,rjd1,rkd1,xpo,ypo,ppo,mode, |
> vert1,surf1,nx,ny,nz,lonw,lats,dlon,dlat) |
rid = int_time (rid0,rid1,rtp,misdat) |
rjd = int_time (rjd0,rjd1,rtp,misdat) |
rkd = int_time (rkd0,rkd1,rtp,misdat) |
endif |
end |
c ------------------------------------------------------------- |
c Interpolate to an arbitrary position in grid space and time |
c ------------------------------------------------------------- |
real function int_index4 (ar0,ar1,n1,n2,n3,rid,rjd,rkd,rtp,misdat) |
c Purpose: |
c This subroutine interpolates a 3d-array to an arbitrary |
c location within the grid including a linear time-interpolation. |
c Arguments: |
c rid,rjd,rkd real output grid location to be interpolated to |
c xpo,ypo,ppo real input physical coordinates |
c n1,n2,n3 int input grid dimensions in x-, y- and p-direction |
c lats,lonw real input south and west boundary of grid space |
c vert real input vertical coordinate grid |
c surf real input lower boundary (surface pressure) |
implicit none |
c Declartion of function parameters |
integer n1,n2,n3 |
real ar0(n1*n2*n3),ar1(n1*n2*n3) |
real rid,rjd,rkd |
real rtp |
real misdat |
c Set numerical parameters |
real eps |
parameter (eps=1.e-8) |
c Externals |
real int_index3,int_time |
external int_index3,int_time |
c Auxiliary variables |
real val0,val1,val |
c Do the 3d-interpolation |
if (abs(rtp).lt.eps) then |
val = int_index3 (ar0,n1,n2,n3,rid,rjd,rkd,misdat) |
elseif (abs(rtp-1.).lt.eps) then |
val = int_index3 (ar1,n1,n2,n3,rid,rjd,rkd,misdat) |
else |
val0 = int_index3 (ar0,n1,n2,n3,rid,rjd,rkd,misdat) |
val1 = int_index3 (ar1,n1,n2,n3,rid,rjd,rkd,misdat) |
val = int_time (val0,val1,rtp,misdat) |
endif |
c Return value |
int_index4 = val |
return |
end |
c ------------------------------------------------------------- |
c Interpolate to an arbitrary position in grid space |
c ------------------------------------------------------------- |
real function int_index3 (ar,n1,n2,n3,rid,rjd,rkd,misdat) |
c Purpose: |
c This subroutine interpolates a 3d-array to an arbitrary |
c location within the grid. The interpolation includes the |
c testing of the missing data flag 'misdat'. If one dimension |
c is 1, a 2d-interpolation is performed; if two dimensions |
c are 1, it is a 1d-interpolation; if all three dimensions are |
c 1, no interpolation is performed and the input value is |
c returned. |
c Arguments: |
c ar real input input data array |
c n1,n2,n3 int input dimensions of ar |
c ri,rj,rk real input grid location to be interpolated to |
c misdat real input missing data flag (on if misdat<>0) |
implicit none |
c Declartion of function parameters |
integer n1,n2,n3 |
real ar(n1*n2*n3) |
real rid,rjd,rkd |
real misdat |
c Set numerical parameters |
real eps |
parameter (eps=1.e-8) |
c Local variables |
integer i,j,k,ip1,jp1,kp1 |
real frac0i,frac0j,frac0k,frac1i,frac1j,frac1k |
real ri,rj,rk |
real val000,val001,val010,val011,val100,val101,val110,val111 |
real frc000,frc001,frc010,frc011,frc100,frc101,frc110,frc111 |
real frc |
real mdv |
real val |
c Elementary test for dimensions |
if ( (n1.lt.1).or.(n2.lt.1).or.(n3.lt.1) ) then |
print*,'Invalid grid dimensions ',n1,n2,n3 |
stop |
endif |
c Activate or inactive the missing data check (quick and dirty) |
if (misdat.ne.0.) then |
mdv = misdat |
else |
mdv = 257.22725394015 |
endif |
c Bring the indices into the grid space |
ri = amax1(1.,amin1(float(n1),rid)) |
rj = amax1(1.,amin1(float(n2),rjd)) |
rk = amax1(1.,amin1(float(n3),rkd)) |
c Get the index of the west-south-bottom corner of the box |
i = min0(int(ri),n1-1) |
ip1 = i+1 |
j = min0(int(rj),n2-1) |
jp1 = j+1 |
k = min0(int(rk),n3-1) |
kp1 = k+1 |
c Special handling for 2d arrays |
if (n3.eq.1) then |
k=1 |
kp1=1 |
endif |
c Get location relative to grid box |
if ( i.ne.ip1 ) then |
frac0i = ri-float(i) |
frac1i = 1.-frac0i |
else |
frac0i = 0. |
frac1i = 1. |
endif |
if ( j.ne.jp1 ) then |
frac0j = rj-float(j) |
frac1j = 1.-frac0j |
else |
frac0j = 0. |
frac1j = 1. |
endif |
if ( k.ne.kp1 ) then |
frac0k = rk-float(k) |
frac1k = 1.-frac0k |
else |
frac0k = 0. |
frac1k = 1. |
endif |
c On a grid point - take the grid point value |
if ( ( abs(frac0i).lt.eps ).and. |
> ( abs(frac0j).lt.eps ).and. |
> ( abs(frac0k).lt.eps ) ) then |
val = ar( i + n1*(j -1) + n1*n2*(k -1) ) |
goto 100 |
endif |
c Init the fractions |
frc000 = frac1i * frac1j * frac1k |
frc001 = frac0i * frac1j * frac1k |
frc010 = frac1i * frac0j * frac1k |
frc011 = frac0i * frac0j * frac1k |
frc100 = frac1i * frac1j * frac0k |
frc101 = frac0i * frac1j * frac0k |
frc110 = frac1i * frac0j * frac0k |
frc111 = frac0i * frac0j * frac0k |
c Init the values |
val000 = ar( i + n1*(j -1) + n1*n2*(k -1) ) |
val001 = ar( ip1 + n1*(j -1) + n1*n2*(k -1) ) |
val010 = ar( i + n1*(jp1-1) + n1*n2*(k -1) ) |
val011 = ar( ip1 + n1*(jp1-1) + n1*n2*(k -1) ) |
val100 = ar( i + n1*(j -1) + n1*n2*(kp1-1) ) |
val101 = ar( ip1 + n1*(j -1) + n1*n2*(kp1-1) ) |
val110 = ar( i + n1*(jp1-1) + n1*n2*(kp1-1) ) |
val111 = ar( ip1 + n1*(jp1-1) + n1*n2*(kp1-1) ) |
c Handle missing data |
if ( abs(val000-mdv).lt.eps ) frc000 = 0. |
if ( abs(val001-mdv).lt.eps ) frc001 = 0. |
if ( abs(val010-mdv).lt.eps ) frc010 = 0. |
if ( abs(val011-mdv).lt.eps ) frc011 = 0. |
if ( abs(val100-mdv).lt.eps ) frc100 = 0. |
if ( abs(val101-mdv).lt.eps ) frc101 = 0. |
if ( abs(val110-mdv).lt.eps ) frc110 = 0. |
if ( abs(val111-mdv).lt.eps ) frc111 = 0. |
c Build the final value |
frc = frc000 + frc001 + frc010 + frc011 + |
> frc100 + frc101 + frc110 + frc111 |
if ( frc.gt.0. ) then |
val = 1./frc * ( frc000 * val000 + frc001 * val001 + |
> frc010 * val010 + frc011 * val011 + |
> frc100 * val100 + frc101 * val101 + |
> frc110 * val110 + frc111 * val111 ) |
else |
val = misdat |
endif |
c Return the value |
100 continue |
int_index3 = val |
end |
c ------------------------------------------------------------- |
c Time interpolation |
c ------------------------------------------------------------- |
real function int_time (val0,val1,reltpos,misdat) |
c Purpose: |
c This subroutine interpolates linearly in time between two |
c values. |
c Arguments: |
c val0 real input value at time 0 |
c val1 real input value at time 1 |
c reltpos real input relative time (between 0 and 1) |
c misdat real input missing data flag (on if misdat<>0) |
implicit none |
c Declaration of parameters |
real val0 |
real val1 |
real reltpos |
real misdat |
c Numerical epsilon |
real eps |
parameter (eps=1.e-8) |
c Local variables |
real val |
real mdv |
c Activate or inactive the missing data check (quick and dirty) |
if (misdat.ne.0.) then |
mdv = misdat |
else |
mdv = 257.22725394015 |
endif |
c Do the linear interpolation |
if ( abs(reltpos).lt.eps ) then |
val = val0 |
elseif ( abs(reltpos-1.).lt.eps ) then |
val = val1 |
elseif ( (abs(val0-mdv).gt.eps).and. |
> (abs(val1-mdv).gt.eps) ) then |
val = (1.-reltpos)*val0+reltpos*val1 |
else |
val = mdv |
endif |
c Return value |
int_time = val |
end |
c ------------------------------------------------------------- |
c Get the position of a physical point in grid space |
c ------------------------------------------------------------- |
subroutine get_index3 (rid,rjd,rkd,xpo,ypo,ppo,mode, |
> vert,surf,nx,ny,nz,lonw,lats,dlon,dlat) |
c Purpose: |
c This subroutine determines the indices (rid,rjd,rkd) in grid |
c space for a point in physical space (xpo,ypo,ppo). The |
c horizontal grid is specified by the south-west point (lats,lonw) |
c and the grid spacing (dlat,dlon). The vertical grid is given |
c by <vert(n1,n2,n3)>. The lower boundary (typicall surface |
c pressure) is given by <surf(n1,n2)>. |
c Arguments: |
c rid,rjd,rkd real output grid location to be interpolated to |
c xpo,ypo,ppo real input physical coordinates |
c n1,n2,n3 int input grid dimensions in x-, y- and p-direction |
c lats,lonw real input south and west boundary of grid space |
c vert real input vertical coordinate grid |
c surf real input lower boundary (surface pressure) |
c mode int input direction of vertical axis |
c 1: linear, 1 -> nz (th) |
c 2: linear, nz -> 1 (pv) |
c 3: binary (p) |
implicit none |
c Declartion of function parameters |
integer nx,ny,nz |
real vert(nx*ny*nz) |
real surf(nx*ny) |
real rid,rjd,rkd |
real xpo,ypo,ppo |
real dlat,dlon,lats,lonw |
integer mode |
c Numerical epsilon |
real eps |
parameter (eps=1.e-8) |
c Local variables |
integer i,j,k |
real ppo0,ppo1,ppom,psur |
integer i0,im,i1 |
c Externals |
real int_index3 |
external int_index3 |
c Get the horizontal grid indices |
rid=(xpo-lonw)/dlon+1. |
rjd=(ypo-lats)/dlat+1. |
c Two-dimensional interpolation on horizontal plane: return |
if ( nz.eq.1 ) then |
rkd = 1. |
goto 100 |
endif |
c Lowest-level interpolation: return |
if ( abs(ppo-1050.).lt.eps ) then |
rkd = 1. |
goto 100 |
endif |
c Get the pressure at the lowest level and at the surface |
ppo0 = int_index3(vert,nx,ny,nz,rid,rjd,real(1),0.) |
psur = int_index3(surf,nx,ny, 1,rid,rjd,real(1),0.) |
c The point is between the surface and the lowest level: return |
if ( (ppo.ge.ppo0).and.(ppo.le.psur).or. |
> (ppo.le.ppo0).and.(ppo.ge.psur) ) |
>then |
psur = int_index3(surf,nx,ny, 1,rid,rjd,real(1),0.) |
rkd = (psur-ppo)/(psur-ppo0) |
goto 100 |
endif |
c Full-level search (TH): linear ascending scanning through all levels |
if ( mode.eq.1 ) then |
ppo0 = int_index3(vert,nx,ny,nz,rid,rjd,real(1),0.) |
rkd=0 |
do i=1,nz-1 |
ppo1 = int_index3(vert,nx,ny,nz,rid,rjd,real(i+1),0.) |
if ( (ppo0.lt.ppo).and.(ppo1.ge.ppo) ) then |
rkd=real(i)+(ppo0-ppo)/(ppo0-ppo1) |
goto 100 |
endif |
ppo0 = ppo1 |
enddo |
c Full-level search (PV): linear descending scanning through all levels |
elseif ( mode.eq.2 ) then |
ppo1 = int_index3(vert,nx,ny,nz,rid,rjd,real(nz),0.) |
rkd=0 |
do i=nz-1,1,-1 |
ppo0 = int_index3(vert,nx,ny,nz,rid,rjd,real(i),0.) |
if ( (ppo1.gt.ppo).and.(ppo0.le.ppo) ) then |
rkd=real(i)+(ppo0-ppo)/(ppo0-ppo1) |
goto 100 |
endif |
ppo1 = ppo0 |
enddo |
c Full-level search (P): binary search |
elseif ( mode.eq.3 ) then |
rkd = 0 |
i0 = 1 |
i1 = nz |
ppo0 = int_index3(vert,nx,ny,nz,rid,rjd,real( 1),0.) |
ppo1 = int_index3(vert,nx,ny,nz,rid,rjd,real(nz),0.) |
do while ( i1.gt.(i0+1) ) |
im = (i0+i1)/2 |
ppom = int_index3(vert,nx,ny,nz,rid,rjd,real(im),0.) |
if (ppom.lt.ppo) then |
i1 = im |
ppo1 = ppom |
else |
i0 = im |
ppo0 = ppom |
endif |
enddo |
rkd=real(i0)+(ppo0-ppo)/(ppo0-ppo1) |
endif |
c Exit point for subroutine |
100 continue |
end |
/tags/1.0/lib/ioinp.f |
---|
0,0 → 1,411 |
c ************************************************************ |
c * This package provides input routines to read the wind * |
c * and other fields from IVE necdf files. The routines are * |
c * * |
c * 1) input_open : to open a data file * |
c * 2) input_grid : to read the grid information, including * |
c * the vertical levels * |
c * 3) input_wind : to read the wind components * |
c * 4) input_close : to close an input file * |
c * * |
c * The file is characterised by an filename <filename> and * |
c * a file identifier <fid>. The horizontal grid is given by * |
c * <xmin,xmax,ymin,ymax,dx,dy,nx,ny> where the pole of the * |
c * rotated grid is given by <pollon,pollat>. The vertical * |
c * grid is characterised by the surface pressure <ps> and * |
c * the pressure at staggered <slev> and unstaggered <ulev> * |
c * levels. The number of levels is given by <nz>. Finally, * |
c * the retrieval of the wind <field> with name <fieldname> * |
c * is characterised by a <time> and a missing data value * |
c * <mdv>. * |
c * * |
c * Author: Michael Sprenger, Autumn 2008 * |
c ************************************************************ |
c ------------------------------------------------------------ |
c Open input file |
c ------------------------------------------------------------ |
subroutine input_open (fid,filename) |
c Open the input file with filename <filename> and return the |
c file identifier <fid> for further reference. |
use netcdf |
implicit none |
c Declaration of subroutine parameters |
integer fid ! File identifier |
character*80 filename ! Filename |
c Declaration of auxiliary variables |
integer ierr |
ierr = NF90_OPEN(TRIM(filename),nf90_nowrite, fid) |
IF ( ierr /= nf90_NoErr ) PRINT *,NF90_STRERROR(ierr) |
end |
c ------------------------------------------------------------ |
c Read information about the grid |
c ------------------------------------------------------------ |
subroutine input_grid |
> (fid,fieldname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> time,pollon,pollat,p3,ps,nz,ak,bk,stagz, |
> timecheck) |
use netcdf |
c Read grid information at <time> from file with identifier <fid>. |
c The horizontal grid is characterized by <xmin,xmax,ymin,ymax,dx,dy> |
c with pole position at <pollon,pollat> and grid dimension <nx,ny>. |
c The 3d arrays <p3(nx,ny,nz)> gives the vertical coordinates, either |
c on the staggered or unstaggered grid (with <stagz> as the flag). |
c The surface pressure is given in <ps(nx,ny)>. If <fid> is negative, |
c only the grid dimensions and grid parameters (xmin...pollat,nz) are |
c determined and returned (this is needed for dynamical allocation of |
c memory). |
implicit none |
c Declaration of subroutine parameters |
integer fid ! File identifier |
real xmin,xmax,ymin,ymax ! Domain size |
real dx,dy ! Horizontal resolution |
integer nx,ny,nz ! Grid dimensions |
real pollon,pollat ! Longitude and latitude of pole |
real p3(nx,ny,nz) ! Staggered levels |
real ps(nx,ny) ! Surface pressure |
real time ! Time of the grid information |
real ak(nz),bk(nz) ! Ak and Bk for layers or levels |
real stagz ! Vertical staggering (0 or -0.5) |
character*80 fieldname ! Variable from which to take grid info |
character*80 timecheck ! Either 'yes' or 'no' |
c Numerical epsilon |
real eps |
parameter (eps=0.0001) |
c Auxiliary varaibles |
integer ierr |
integer i,j,k |
character*80 varname |
character*80 newname |
real lon(1000),lat(1000),lev(1000),lev2(1000) |
integer varid,lonid,latid,levid |
integer nz2 |
real tmp(nx-1,ny) |
integer indx |
real lon1 |
integer itmp |
c Inquire dimensions and grid constants if <fid> is negative |
if (fid.lt.0) then |
c Longitude |
ierr = nf90_inq_dimid(-fid,'lon', lonid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = nf90_inquire_dimension(-fid, lonid, len = nx) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_INQ_VARID(-fid,'lon',varid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_GET_VAR(-fid,varid,lon(1:nx)) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
c Latitude |
ierr = nf90_inq_dimid(-fid,'lat', latid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = nf90_inquire_dimension(-fid, latid, len = ny) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_INQ_VARID(-fid,'lat',varid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_GET_VAR(-fid,varid,lat(1:ny)) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
c Set grid parameters and compare to expected setting |
xmin = lon(1) |
xmax = lon(nx) |
ymin = lat(ny) |
ymax = lat(1) |
dx = (xmax-xmin)/real(nx-1) |
dy = (ymax-ymin)/real(ny-1) |
if ( |
> ( nx .ne.180 ).or. |
> ( ny .ne.91 ).or. |
> ( abs(xmin - 0.).gt.eps ).or. |
> ( abs(xmax - 358.).gt.eps ).or. |
> ( abs(ymin + 90.).gt.eps ).or. |
> ( abs(ymax - 90.).gt.eps ).or. |
> ( abs(dx - 2.).gt.eps ).or. |
> ( abs(dy - 2.).gt.eps ) ) |
> then |
print*,' ERROR: grid does not agree with expectation.. Stop' |
stop |
endif |
c Vertical levels |
ierr = nf90_inq_dimid(-fid,'level', levid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = nf90_inquire_dimension(-fid, levid, len = nz) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_INQ_VARID(-fid,'level',varid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_GET_VAR(-fid,varid,lev(1:nz)) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
c Get vertical levels for omega and check consistence |
ierr = nf90_inq_dimid(-fid,'level_2', levid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = nf90_inquire_dimension(-fid, levid, len = nz2) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_INQ_VARID(-fid,'level_2',varid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_GET_VAR(-fid,varid,lev2(1:nz2)) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
if (nz.gt.nz2 ) then |
itmp = nz |
nz = nz2 |
nz2 = itmp |
endif |
if ( ( nz.ne.19 ).or.(nz2.ne.24) ) then |
print*,' ERROR: grid inconsitence... level vs level_2' |
print*,'nz,nz2 ',nz,nz2 |
stop |
endif |
do i=1,nz |
if ( abs( lev2(i)-lev(i) ).gt.eps ) then |
print*,' ERROR: grid inconsitence... level vs level_2' |
print*,i,lev2(i),lev(i) |
stop |
endif |
enddo |
c Set the final (expected) parameters, including closing and shifting |
nx = 181 |
ny = 91 |
nz = 19 |
xmin = -180. |
xmax = 180. |
ymin = -90. |
ymax = 90. |
dx = 2. |
dy = 2. |
pollon = 0. |
pollat = 90. |
stagz = 0. |
c Get non-constant grid parameters (surface pressure and vertical grid) |
else |
c Set 3D pressure |
ierr = NF90_INQ_VARID(fid,'level_2',varid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_GET_VAR(fid,varid,lev(1:nz)) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
do i=1,nx |
do j=1,ny |
do k=1,nz |
p3(i,j,k) = lev(k) |
enddo |
enddo |
enddo |
c Set ak, bk |
do k=1,nz |
ak(k) = lev(k) |
bk(k) = 0. |
enddo |
c Read surface pressure (close and shift/swap domain; unit conversion) |
varname = 'pres' |
ierr = NF90_INQ_VARID(fid,varname,varid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_GET_VAR(fid,varid,tmp(1:(nx-1),1:ny)) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
do i=1,nx-1 |
lon1 = xmin + real(i-1)*dx |
if ( lon1.lt.-eps ) lon1 = lon1 + 360. |
indx = nint( lon1 / dx + 1. ) |
do j=1,ny |
ps(i,j) = 0.01 * tmp(indx,ny-j+1) |
enddo |
enddo |
do j=1,ny |
ps(nx,j) = ps(1,j) |
enddo |
endif |
end |
c ------------------------------------------------------------ |
c Read wind and other met field |
c ------------------------------------------------------------ |
subroutine input_wind (fid,fieldname,field,time,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz, |
> timecheck) |
use netcdf |
c Read the wind component <fieldname> from the file with identifier |
c <fid> and save it in the 3d array <field>. The vertical staggering |
c information is provided in <stagz> and gives the reference to either |
c the layer or level field from <input_grid>. A consistency check is |
c performed to have an agreement with the grid specified by <xmin,xmax, |
c ymin,ymax,dx,dy,nx,ny,nz>. |
implicit none |
c Declaration of variables and parameters |
integer fid ! File identifier |
character*80 fieldname ! Name of the wind field |
integer nx,ny,nz ! Dimension of fields |
real field(nx,ny,nz) ! 3d wind field |
real stagz ! Staggering in the z direction |
real mdv ! Missing data flag |
real xmin,xmax,ymin,ymax ! Domain size |
real dx,dy ! Horizontal resolution |
real time ! Time |
character*80 timecheck ! Either 'yes' or 'no' |
c Netcdf variables |
integer ierr |
character*80 varname |
character*80 newname |
c Numerical epsilon |
real eps |
parameter (eps=0.0001) |
c Auxiliary variables |
integer i,j,k |
real lev(1000) |
integer varid |
real tmp(nx-1,ny,nz) |
real lon(nx-1) |
integer indx |
real lon1 |
integer is2d |
c Set the correct fieldname |
newname = fieldname |
if ( fieldname.eq.'PLEV' ) newname='P' |
if ( fieldname.eq.'PLAY' ) newname='P' |
if ( fieldname.eq.'P' ) newname='P' |
if ( fieldname.eq.'OMEGA' ) newname='omega' |
if ( fieldname.eq.'PS' ) newname='pres' |
if ( fieldname.eq.'U' ) newname='uwnd' |
if ( fieldname.eq.'V' ) newname='vwnd' |
c Get flag for 2D field |
is2d = 0 |
if ( fieldname.eq.'pres' ) is2d = 1 |
c Get 3D pressure |
if ( fieldname.eq.'P' ) then |
varname = 'level' |
ierr = NF90_INQ_VARID(fid,varname,varid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_GET_VAR(fid,varid,lev(1:nz)) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
do i=1,nx |
do j=1,ny |
do k=1,nz |
field(i,j,k) = lev(k) |
enddo |
enddo |
enddo |
mdv = -9.96921e+36 |
c Get 3D field (close and shift/swap domain) |
elseif ( is2d.eq.0 ) then |
varname = newname |
ierr = NF90_INQ_VARID(fid,varname,varid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_GET_VAR(fid,varid,tmp(1:(nx-1),1:ny,1:nz)) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = nf90_get_att(fid, varid, "_FillValue", mdv) |
IF (ierr /= nf90_NoErr) THEN |
mdv = -9.96921e+36 |
ierr = nf90_NoErr |
ENDIF |
do i=1,nx-1 |
lon1 = xmin + real(i-1)*dx |
if ( lon1.lt.-eps ) lon1 = lon1 + 360. |
indx = nint( lon1 / dx + 1. ) |
do k=1,nz |
do j=1,ny |
field(i,j,k) = tmp(indx,ny-j+1,k) |
enddo |
field(nx,j,k) = field(1,j,k) |
enddo |
enddo |
c Get 2D field (close and shift/swap domain) |
elseif ( is2d.eq.1 ) then |
varname = newname |
ierr = NF90_INQ_VARID(fid,varname,varid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = NF90_GET_VAR(fid,varid,tmp(1:(nx-1),1:ny,1:1)) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
ierr = nf90_get_att(fid, varid, "_FillValue", mdv) |
IF (ierr /= nf90_NoErr) THEN |
mdv = -9.96921e+36 |
ierr = nf90_NoErr |
ENDIF |
do i=1,nx-1 |
lon1 = xmin + real(i-1)*dx |
if ( lon1.lt.-eps ) lon1 = lon1 + 360. |
indx = nint( lon1 / dx + 1. ) |
do j=1,ny |
field(i,j,1) = tmp(indx,ny-j+1,1) |
do k=2,nz |
field(i,j,k) = field(i,j,k-1) |
enddo |
field(nx,j,k) = field(1,j,k) |
enddo |
enddo |
endif |
end |
c ------------------------------------------------------------ |
c Close input file |
c ------------------------------------------------------------ |
subroutine input_close(fid) |
c Close the input file with file identifier <fid>. |
use netcdf |
implicit none |
c Declaration of subroutine parameters |
integer fid |
c Auxiliary variables |
integer ierr |
ierr = NF90_CLOSE(fid) |
IF( ierr /= nf90_NoErr) PRINT *,NF90_STRERROR(ierr) |
end |
/tags/1.0/lib/iotra.f |
---|
0,0 → 1,810 |
c **************************************************************** |
c * This package provides IO routines for trajectories. A file * |
c * is characterised by the filename <filename> and the file * |
c * identifier <fid>. Different modes <mode> are supported: * |
c * mode=1: ascii, sorted by trajectory; * |
c * mode=2: ascii, sorted by time; * |
c * mode=3: fortran (unformatted) * |
c * mode=4: IVE netcdf (for compatibiltzy reasons) * |
c * A trajectory set is given as 3d array <tra(ntra,ntim,ncol)> * |
c * where <ntra> is the number of trajectories, <ntim> the * |
c * number of times of each trajectory and <ncol> the number of * |
c * columns of the trajectory. The first 4 columns are: time, * |
c * longitude, latitude, pressure. The other columns are traced * |
c * fields. The complete list of all columns is given in the * |
c * array <vars(ncol)>. Finally, the reference date is given in * |
c * the array <time(6)=year,month,day,hour,time length of the * |
c * trajectory (hour,min)>. * |
c * * |
c * Author: Michael Sprenger, September 2008 * |
c **************************************************************** |
c ---------------------------------------------------------------- |
c Open a trajectory file for reading |
c ---------------------------------------------------------------- |
subroutine ropen_tra(fid,filename,ntra,ntim,ncol,time,vars,mode) |
implicit none |
c Declaration of subroutine parameters |
integer fid |
character*80 filename |
integer mode |
integer ntra,ntim,ncol |
integer time(6) |
character*80 vars(ncol) |
c Auxiliary variables |
integer vardim(4) |
real varmin(4),varmax(4),stag(4) |
real mdv |
character*80 cfn |
integer ierr |
integer i |
integer nvars |
c Open file |
if (mode.eq.1) then |
fid = 10 |
open(fid,file=filename) |
elseif (mode.eq.2) then |
fid = 10 |
open(fid,file=filename) |
elseif (mode.eq.3) then |
open(fid,file=filename,form='unformatted') |
elseif (mode.eq.4) then |
call cdfopn(filename,fid,ierr) |
elseif (mode.eq.5) then |
print*,' ERROR: Reading KML not supported' |
stop |
endif |
c Read header information |
call read_hea(fid,time,vars,ntra,ntim,ncol,mode) |
end |
c ---------------------------------------------------------------- |
c Open a trajectory file for wrinting |
c ---------------------------------------------------------------- |
subroutine wopen_tra(fid,filename,ntra,ntim,ncol,time,vars,mode) |
implicit none |
c Declaration of subroutine parameters |
integer fid |
character*80 filename |
integer mode |
integer ntra,ntim,ncol |
integer time(6) |
character*80 vars(ncol) |
c Auxiliary variables |
integer vardim(4) |
real varmin(4),varmax(4),stag(4) |
real mdv |
character*80 cfn |
integer ierr |
integer i |
character*80 varname |
real rtime(6) |
c Open file |
if (mode.eq.1) then |
fid = 10 |
open(fid,file=filename) |
elseif (mode.eq.2) then |
fid = 10 |
open(fid,file=filename) |
elseif (mode.eq.3) then |
open(fid,file=filename,form='unformatted') |
elseif (mode.eq.4) then |
vardim(1)=ntra |
vardim(2)=1 |
vardim(3)=1 |
vardim(4)=1 |
cfn =trim(filename)//'_cst' |
mdv =-999.98999 |
call crecdf(filename,fid,varmin,varmax,3,cfn,ierr) |
elseif (mode.eq.5) then |
fid = 10 |
open(fid,file=filename) |
endif |
c Write header information |
call write_hea(fid,time,vars,ntra,ntim,ncol,mode) |
end |
c ---------------------------------------------------------------- |
c Read a trajectory |
c ---------------------------------------------------------------- |
subroutine read_tra(fid,tra,ntra,ntim,ncol,mode) |
implicit none |
c Declaration of subroutine parameters |
integer fid |
integer ntim |
integer ncol |
integer ntra |
real tra(ntra,ntim,ncol) |
integer mode |
c Auxiliary variables |
integer i,j,n |
real arr(ntra) |
integer ntimes |
real times(1000) |
integer ierr |
character*80 vars(ncol+2) |
integer nvars |
c Read ascii mode, sorted by trajectory (mode=1) |
if (mode.eq.1) then |
read(fid,*,end=100) |
do n=1,ntra |
do i=1,ntim |
read(fid,*,end=110) (tra(n,i,j),j=1,ncol) |
enddo |
enddo |
c Read ascii mode, sorted by time (mode=2) |
elseif (mode.eq.2) then |
read(fid,*,end=100) |
do i=1,ntim |
do n=1,ntra |
read(fid,*,end=100) (tra(n,i,j),j=1,ncol) |
enddo |
enddo |
c Read fortran mode (mode=3) |
elseif (mode.eq.3) then |
read(fid) tra |
c Read IVE netcdf mode (mode=4) |
elseif (mode.eq.4) then |
call gettimes(fid,times,ntimes,ierr) |
call getvars(fid,nvars,vars,ierr) |
do i=1,ntim |
do j=1,ncol |
if (j.eq.1) then |
do n=1,ntra |
tra(n,i,1)=times(i) |
enddo |
else |
call getdat(fid,vars(j),times(i),0,arr,ierr) |
do n=1,ntra |
tra(n,i,j)=arr(n) |
enddo |
endif |
enddo |
enddo |
endif |
return |
c End of file has been reached: set negative <fid> |
100 fid=-fid |
return |
c Error: incomplete trajectory |
110 print*,'<read_tra>: Incomplete trajectory... Stop' |
stop |
end |
c ---------------------------------------------------------------- |
c Write a trajectory |
c ---------------------------------------------------------------- |
subroutine write_tra(fid,tra,ntra,ntim,ncol,mode) |
implicit none |
c Declaration of subroutine parameters |
integer fid |
integer ntim |
integer ncol |
integer ntra |
real tra(ntra,ntim,ncol) |
integer mode |
c Auxiliary variables |
integer i,j,n |
real arr(ntra) |
integer ierr |
real time |
character*80 vars(ncol+2) |
integer nvars |
character*20 lonstr,latstr,levstr |
character*80 outstr |
real ref_z(3000),ref_p(3000),ref_t(3000) |
real lev |
character*80 path |
c Write ascii mode, sorted by trajectory (mode=1) |
if (mode.eq.1) then |
do n=1,ntra |
write(fid,*) |
do i=1,ntim |
c Avoid ugly *s or missing space in output |
do j=5,ncol |
if ( abs(tra(n,i,j)).gt.9999.) then |
print*,'Format problem : ',tra(n,i,j),' -> -999.99' |
tra(n,i,j) = -999.99 |
endif |
enddo |
write(fid,'(1f7.2,f9.2,f8.2,i6,100f10.3)') |
> (tra(n,i,j),j=1,3), ! time, lon, lat |
> nint(tra(n,i,4)), ! p |
> (tra(n,i,j),j=5,ncol) ! fields |
enddo |
enddo |
c Write ascii mode, sorted by time (mode=2) |
elseif (mode.eq.2) then |
do i=1,ntim |
write(fid,*) |
do n=1,ntra |
c Avoid ugly *s or missing space in output |
do j=5,ncol |
if ( abs(tra(n,i,j)).gt.9999.) then |
print*,'Format problem : ',tra(n,i,j),' -> -999.99' |
tra(n,i,j) = -999.99 |
endif |
enddo |
write(fid,'(1f7.2,f9.2,f8.2,i6,100f10.3)') |
> (tra(n,i,j),j=1,3), ! time, lon, lat |
> nint(tra(n,i,4)), ! p |
> (tra(n,i,j),j=5,ncol) ! fields |
enddo |
enddo |
c Write fortran mode (mode=3) |
elseif (mode.eq.3) then |
write(fid) tra |
c Write netcdf mode (mode=4) |
elseif (mode.eq.4) then |
call getvars(fid,nvars,vars,ierr) |
do i=1,ntim |
time=tra(1,i,1) |
do j=2,ncol |
do n=1,ntra |
arr(n)=tra(n,i,j) |
enddo |
call putdat(fid,vars(j),time,0,arr,ierr) |
enddo |
enddo |
c Write KML mode (mode=5) |
elseif (mode.eq.5) then |
call getenv('DYN_TOOLS',path) |
path = trim(path)//'/lagranto.ecmwf/goodies/' |
open(fid+1,file=trim(path)//'reformat.refprof') |
do n=1,6 |
read(fid+1,*) |
enddo |
do n=1,3000 |
read(fid+1,*) ref_z(n),ref_t(n),ref_p(n) |
ref_p(n) = 0.01 * ref_p(n) |
enddo |
close(fid+1) |
do n=1,ntra |
write(fid,"(A)") '<Placemark>' |
write(fid,"(A)") '<name>Absolute Extruded</name>' |
write(fid,"(A)") '<styleUrl>#yellowkLineGreenPoly</styleUrl>' |
write(fid,"(A)") '<LineString>' |
write(fid,"(A)") '<extrude>1</extrude>' |
write(fid,"(A)") '<tessellate>1</tessellate>' |
write(fid,"(A)") '<altitudeMode>absolute</altitudeMode>' |
write(fid,"(A)") '<coordinates>' |
do i=1,ntim |
write(lonstr,*) tra(n,i,2) |
write(latstr,*) tra(n,i,3) |
call binary(lev,tra(n,i,4),ref_z,ref_p) |
write(levstr,*) lev |
outstr = trim(adjustl(lonstr))//','// |
> trim(adjustl(latstr))//','// |
> trim(adjustl(levstr)) |
write(fid,"(A)") outstr |
enddo |
write(fid,*) '</coordinates>' |
write(fid,*) '</LineString>' |
write(fid,*) '</Placemark>' |
enddo |
endif |
end |
c ---------------------------------------------------------------- |
c Read header from trajectory file |
c ---------------------------------------------------------------- |
subroutine read_hea(fid,time,vars,ntra,ntim,ncol,mode) |
implicit none |
c Declaration of subroutine parameters |
integer fid |
integer time(6) |
integer ntra,ntim,ncol |
character*80 vars(ncol) |
integer mode |
c Auxiliary variables |
integer i |
character ch(500) |
character*500 str |
integer ich(500) |
integer isstr,ileft,iright |
character*80 varname |
real rtime(6) |
integer ierr |
integer nvars |
character*15 str1 |
character str2 |
character*13 str3 |
character*4 str4 |
character*80 linestr |
integer itmp1,itmp2 |
c Read ascii format (mode=1,2) |
if ( (mode.eq.1).or.(mode.eq.2) ) then |
c Read the time specification (old and new format) |
read(fid,'(a80)') linestr |
if ( linestr(1:14).eq.'Reference date' ) then |
read(linestr,'(a15,i4,i2,i2,a1,i2,i2,a13,i8,a4)') |
> str1, |
> time(1),time(2),time(3),str2,time(4),time(5), |
> str3,time(6),str4 |
elseif ( linestr(1:11).eq.'time period' ) then |
read(linestr,'(a12,i4,i2,i2,a1,i2,a4,i6,a1,i2,a2)') |
> str1, |
> time(1),time(2),time(3),str2,time(4), |
> str3,itmp1,str3,itmp2,str4 |
time(5) = 0 |
time(6) = itmp1 * 60 + itmp2 |
endif |
c Skip the empty line and read field names |
read(fid,*) |
read(fid,'(a500)',end=100) str |
do i=1,500 |
ch(i)=str(i:i) |
enddo |
c Split the input string |
isstr=0 |
nvars=0 |
do i=1,500 |
if ( (isstr.eq.0).and.(ch(i).ne.' ') ) then |
isstr=1 |
ileft=i |
elseif ( (isstr.eq.1).and.(ch(i).eq.' ') ) then |
isstr=0 |
iright=i-1 |
nvars=nvars+1 |
vars(nvars)=str(ileft:iright) |
endif |
enddo |
c Skip the empty line |
read(fid,*,end=100) |
c Read fortran mode (mode=3) |
elseif (mode.eq.3) then |
read(fid) ntra,ntim,ncol |
read(fid) time |
read(fid) vars |
c Read IVE netcdf mode (mode=4) |
elseif (mode.eq.4) then |
call getvars(fid,nvars,vars,ierr) |
varname='BASEDATE' |
call getdat(fid,varname,0.,0,rtime,ierr) |
do i=1,6 |
time(i)=nint(rtime(i)) |
enddo |
endif |
return |
c End of file has been reached |
100 fid=-fid |
return |
c Excetion handling |
110 print*,'<read_hea>: Unexspected time format.... Stop' |
stop |
end |
c ---------------------------------------------------------------- |
c Write header to trajectory file (in ascii mode) |
c ---------------------------------------------------------------- |
subroutine write_hea(fid,time,vars,ntra,ntim,ncol,mode) |
implicit none |
c Declaration of subroutine parameters |
integer fid |
integer time(6) |
integer ntra,ntim,ncol |
character*80 vars(ncol) |
integer mode |
c Auxiliary variables |
integer i |
character*500 str |
character*4 str1 |
character*2 str2,str3,str4,str5,str6 |
integer vardim(4) |
real varmin(4),varmax(4),stag(4) |
real mdv |
integer ierr |
character*80 varname |
real rtime(6) |
integer nvars |
c Write ascii format (mode=1,2) |
if ( (mode.eq.1).or.(mode.eq.2) ) then |
c Get the strings for output |
write(str1,'(i4)') time(1) |
write(str2,'(i2)') time(2) |
write(str3,'(i2)') time(3) |
write(str4,'(i2)') time(4) |
write(str5,'(i2)') time(5) |
if (time(2).eq. 0) str2(1:1)='0' |
if (time(3).eq. 0) str3(1:1)='0' |
if (time(4).eq. 0) str4(1:1)='0' |
if (time(5).eq. 0) str5(1:1)='0' |
if (time(2).lt.10) str2(1:1)='0' |
if (time(3).lt.10) str3(1:1)='0' |
if (time(4).lt.10) str4(1:1)='0' |
if (time(5).lt.10) str5(1:1)='0' |
c Write the time specification |
write(fid,'(a15,a4,a2,a2,a1,a2,a2,a13,i8,a4)') |
> 'Reference date ', |
> str1,str2,str3,'_',str4,str5, |
> ' / Time range',time(6), ' min' |
write(fid,*) |
c Write variable names |
str='' |
do i=1,ncol |
str=trim(str)//trim(vars(i)) |
enddo |
write(fid,'(a6,a9,a8,a6,100a10)') (trim(vars(i)),i=1,ncol) |
write(fid,'(a6,a9,a8,a6,100a10)') |
> '------','---------','--------','------', |
> ('----------',i=5,ncol) |
c Write fortran mode (mode=3) |
elseif (mode.eq.3) then |
write(fid) ntra,ntim,ncol |
write(fid) time |
write(fid) vars |
c Write IVE netcdf format (mode=4) |
elseif (mode.eq.4) then |
vardim(1)=ntra |
vardim(2)=1 |
vardim(3)=1 |
vardim(4)=1 |
mdv =-999.98999 |
do i=2,ncol |
call putdef(fid,vars(i),4,mdv,vardim, |
> varmin,varmax,stag,ierr) |
enddo |
varname='BASEDATE' |
vardim(1)=6 |
call putdef(fid,varname,4,mdv,vardim, |
> varmin,varmax,stag,ierr) |
do i=1,6 |
rtime(i)=real(time(i)) |
enddo |
call putdat(fid,varname,0.,0,rtime,ierr) |
c Write KML format (mode=5) |
elseif (mode.eq.5) then |
write(fid,"(A)") '<?xml version="1.0" encoding="UTF-8"?>' |
write(fid,"(A)") '<kml xmlns="http://www.opengis.net/kml/2.2">' |
write(fid,"(A)") '<Document>' |
write(fid,"(A)") '<name>Paths</name>' |
write(fid,"(A)") '<Style id="yellowLineGreenPoly">' |
write(fid,"(A)") '<LineStyle>' |
c write(fid,*) '<color>7f00ffff</color>' ! Yellow |
write(fid,"(A)") '<color>500A0A0A</color>' ! Black |
write(fid,"(A)") '<width>4</width>' |
write(fid,"(A)") '</LineStyle>' |
write(fid,"(A)") '<PolyStyle>' |
write(fid,"(A)") '<color>7f00ff00</color>' |
write(fid,"(A)") '</PolyStyle>' |
write(fid,"(A)") '</Style>' |
endif |
end |
c ---------------------------------------------------------------- |
c Close a trajectory file |
c ---------------------------------------------------------------- |
subroutine close_tra(fid,mode) |
implicit none |
c Declaration of subroutine parameters |
integer fid |
integer mode |
c Auxiliary variables |
integer ierr |
c Close file |
if (mode.eq.1) then |
close(abs(fid)) |
elseif (mode.eq.2) then |
close(abs(fid)) |
elseif (mode.eq.3) then |
close(fid) |
elseif (mode.eq.4) then |
call clscdf(fid,ierr) |
elseif (mode.eq.5) then |
write(fid,"(A)") '</Document>' |
write(fid,"(A)") '</kml>' |
close(abs(fid)) |
endif |
end |
c ---------------------------------------------------------------- |
c Determine the mode of a trajectory file |
c ---------------------------------------------------------------- |
subroutine mode_tra(mode,filename) |
implicit none |
c Declaration of subroutine parameters |
integer mode |
character*80 filename |
c Auxiliary variables |
integer len |
character char0,char1,char2,char3,char4 |
c Get mode |
mode=-1 |
len = len_trim(filename) |
c Mode specified by number |
char0 = filename((len-1):(len-1)) |
char1 = filename(len:len) |
if ( (char0.eq.'.').and.(char1.eq.'1') ) mode=1 |
if ( (char0.eq.'.').and.(char1.eq.'2') ) mode=2 |
if ( (char0.eq.'.').and.(char1.eq.'3') ) mode=3 |
if ( (char0.eq.'.').and.(char1.eq.'4') ) mode=4 |
if ( (char0.eq.'.').and.(char1.eq.'5') ) mode=5 |
if ( mode.gt.0 ) return |
c Mode specified by appendix |
char0 = filename((len-3):(len-3)) |
char1 = filename((len-2):(len-2)) |
char2 = filename((len-1):(len-1)) |
char3 = filename(len:len) |
if ( (char1.eq.'.').and.(char2.eq.'l').and.(char3.eq.'s') ) mode=1 |
if ( (char1.eq.'.').and.(char2.eq.'t').and.(char3.eq.'i') ) mode=2 |
if ( (char1.eq.'.').and.(char2.eq.'d').and.(char3.eq.'u') ) mode=3 |
if ( (char1.eq.'.').and.(char2.eq.'n').and.(char3.eq.'c') ) mode=4 |
if ( (char0.eq.'.').and.(char1.eq.'k').and. |
> (char2.eq.'m').and. |
> (char3.eq.'l') ) mode = 5 |
end |
c ---------------------------------------------------------------- |
c Get dimension of a trajectory file |
c ---------------------------------------------------------------- |
subroutine info_tra(filename,ntra,ntim,ncol,mode) |
implicit none |
c Declaration of subroutine parameters |
integer fid |
character*80 filename |
integer mode |
integer ntra,ntim,ncol |
c Auxiliary variables |
integer vardim(4) |
real varmin(4),varmax(4),stag(4) |
real mdv |
character*80 cfn |
integer ierr |
integer i,ndim |
character*80 vars(100) |
integer nvars |
integer ntimes |
real times(100) |
character*500 str |
integer nline0,nline1,nline2 |
integer isstr,isok |
character ch |
c Open file |
if (mode.eq.1) then |
fid=10 |
open(fid,file=filename) |
elseif (mode.eq.2) then |
fid=10 |
open(fid,file=filename) |
elseif (mode.eq.3) then |
fid=10 |
open(fid,file=filename,form='unformatted') |
elseif (mode.eq.4) then |
call cdfopn(filename,fid,ierr) |
endif |
c Get dimension information |
if ( (mode.eq.1).or.(mode.eq.2) ) then |
read(fid,*) |
read(fid,*) |
read(fid,'(a500)') str |
read(fid,*) |
c Get the number of columns |
isstr=0 |
ncol =0 |
do i=1,500 |
ch = str(i:i) |
if ( (isstr.eq.0).and.(ch.ne.' ') ) then |
isstr=1 |
elseif ( (isstr.eq.1).and.(ch.eq.' ') ) then |
isstr=0 |
ncol=ncol+1 |
endif |
enddo |
c Get the first data block |
nline0 = 5 |
nline1 = 5 |
read(fid,*) |
100 read(fid,'(a500)',end=110) str |
if (str.ne.'') then |
nline1 = nline1 + 1 |
goto 100 |
endif |
110 continue |
c Get the total numbers of lines in the data block |
nline2 = nline1 |
120 read(fid,*,end=130) |
nline2 = nline2 + 1 |
goto 120 |
130 nline2 = nline2 + 1 |
c Set the dimensions |
if (mode.eq.1) then |
ntim = nline1 - nline0 |
ntra = (nline2-nline0+1)/(ntim+1) |
else |
ntra = nline1 - nline0 |
ntim = (nline2-nline0+1)/(ntra+1) |
endif |
elseif (mode.eq.3) then |
read(fid) ntra,ntim,ncol |
elseif (mode.eq.4) then |
call gettimes(fid,times,ntimes,ierr) |
call getvars(fid,nvars,vars,ierr) |
call getdef(fid,trim(vars(2)),ndim,mdv,vardim, |
> varmin,varmax,stag,ierr) |
ntra = vardim(1) |
ntim = ntimes |
ncol = nvars-1 |
endif |
c Close file |
if (mode.eq.1) then |
close(fid) |
elseif (mode.eq.2) then |
close(fid) |
elseif (mode.eq.3) then |
close(fid) |
elseif (mode.eq.4) then |
call clscdf(fid,ierr) |
endif |
end |
c ---------------------------------------------------------------- |
c Binary search algorithm |
c ---------------------------------------------------------------- |
subroutine binary (z,p,ref_z,ref_p) |
implicit none |
c Declaration of subroutine parameters |
real z |
real p |
real ref_z(3000) |
real ref_p(3000) |
c Auxiliary variables |
integer i0,i1,im |
c Binary search |
i0 = 1 |
i1 = 3000 |
100 continue |
im = (i0 + i1) / 2 |
if ( p.lt.ref_p(im) ) then |
i0 = im |
else |
i1 = im |
endif |
if ( (i1-i0).gt.1 ) goto 100 |
c Linear interpolation in between |
z = ref_z(i0) + ( p - ref_p(i0) ) / ( ref_p(i1) - ref_p(i0) ) * |
> ( ref_z(i1) - ref_z(i0) ) |
end |
/tags/1.0/lib/libcdfio.f |
---|
0,0 → 1,1601 |
subroutine clscdf (cdfid, error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine closes an open netCDF file. |
c Aguments : |
c cdfid int input the id of the file to be closed. |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 error detected. |
c History: |
c Nov. 91 PPM UW Created. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
c Argument declarations. |
integer cdfid, error |
c Local variable declarations. |
integer ncopts |
c Get current value of error options. |
call ncgopt (ncopts) |
c Make sure netCDF errors do not abort execution. |
call ncpopt (NCVERBOS) |
c Close requested file. |
call ncclos (cdfid, error) |
c Reset error options. |
call ncpopt (ncopts) |
end |
subroutine crecdf (filnam, cdfid, phymin, phymax, ndim, cfn, |
& error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to create a netCDF file for use with |
c the UWGAP plotting package. |
c Any netCDF file written to must be closed with the call |
c 'call clscdf(cdfid,error)', where cdfid and error are |
c as in the argumentlist below. |
c Arguments: |
c filnam char input the user-supplied netCDF file name. |
c cdfid int output the file-identifier |
c phymin real input the minimum physical dimension of the |
c entire physical domain along each axis. |
c phymin is dimensioned (ndim) |
c phymax real input the maximum physical dimension of the |
c entire physical domain along each axis. |
c phymax is dimensioned (ndim) |
c ndim int input the number of dimensions in the file |
c (i.e. number of elements in phymin, |
c phymax) |
c cfn char input constants file name |
c ('0' = no constants file). |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 error detected. |
c History: |
c Nov. 91 PPM UW Created cr3df. |
c Jan. 92 CS UW Created crecdf. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
c Argument declarations. |
integer MAXDIM |
parameter (MAXDIM=4) |
integer ndim, error |
character *(*) filnam,cfn |
real phymin(*), phymax(*) |
c Local variable declarations. |
character *(20) attnam |
character *(1) chrid(MAXDIM) |
integer cdfid, k, ibeg, iend, lenfil, ncopts |
data chrid/'x','y','z','a'/ |
c Get current value of error options, and make sure netCDF-errors do |
c not abort execution |
call ncgopt (ncopts) |
call ncpopt(NCVERBOS) |
c Initially set error to indicate no errors. |
error = 0 |
c create the netCDF file |
cdfid = nccre (trim(filnam), NCCLOB, error) |
if (error.ne.0) go to 920 |
c define global attributes |
do k=1,ndim |
attnam(1:3)='dom' |
attnam(4:4)=chrid(k) |
attnam(5:7)='min' |
attnam=attnam(1:7) |
call ncapt(cdfid,NCGLOBAL,attnam,NCFLOAT,1,phymin(k),error) |
if (error.gt.0) goto 920 |
attnam(1:3)='dom' |
attnam(4:4)=chrid(k) |
attnam(5:7)='max' |
attnam=attnam(1:7) |
call ncapt(cdfid,NCGLOBAL,attnam,NCFLOAT,1,phymax(k),error) |
if (error.gt.0) goto 920 |
enddo |
c define constants file name |
if (cfn.ne.'0') then |
call ncaptc (cdfid, NCGLOBAL, 'constants_file_name', |
c & NCCHAR, len_trim(cfn)+1, cfn // char(0) , error) |
& NCCHAR, len_trim(cfn), cfn , error) |
if (error.gt.0) goto 920 |
endif |
c End variable definitions. |
call ncendf (cdfid, error) |
if (error.gt.0) goto 920 |
c normal exit |
call ncpopt (ncopts) |
return |
c error exit |
920 write (6, *) 'ERROR: An error occurred while attempting to ', |
& 'create the data file in subroutine crecdf.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
end |
subroutine opncdf(filnam, cdfid, |
& phymin, phymax, ndim, varnam, nvar, cfn, error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to open a netCDF file for read and write |
c with the UWGAP plotting package. |
c Arguments: |
c filnam char input the user-supplied netCDF file name. |
c cdfid int output the file-identifier |
c phymin real output the minimum physical dimension of the |
c entire physical domain along each axis. |
c phymin is dimensioned (ndim) |
c phymax real output the maximum physical dimension of the |
c entire physical domain along each axis. |
c phymax is dimensioned (ndim) |
c ndim int output the number of dimensions in the file |
c (i.e. number of elements in phymin, |
c phymax) |
c varnam char output an array containing the variable names. |
c varnam is dimensioned (nvar). |
c nvar int output the number of variables in the file |
c cfn char output constants file name |
c ('0'=no constants file). |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 error detected. |
c History: |
c Nov. 91 PPM UW Created cr3df. |
c Jan. 92 CS UW Created opncdf. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
c Argument declarations. |
integer MAXDIM |
parameter (MAXDIM=4) |
integer ndim, nvar, error |
character *(*) filnam, varnam(*),cfn |
real phymin(*), phymax(*) |
c Local variable declarations. |
character *(20) attnam,vnam |
character *(1) chrid(MAXDIM) |
integer cdfid, i,k |
integer ncopts, ndims,ngatts,recdim |
integer nvdims,vartyp,nvatts,vardim(MAXDIM) |
real attval |
integer lenstr |
data chrid/'x','y','z','a'/ |
data lenstr/80/ |
c Get current value of error options and make sure netCDF-errors do |
c not abort execution |
call ncgopt (ncopts) |
call ncpopt(NCVERBOS) |
c Initially set error to indicate no errors. |
error = 0 |
c open the netCDF file for write |
cdfid = ncopn (trim(filnam), NCWRITE, error) |
if (error.ne.0) then |
c try to open the netCDF file for read |
cdfid = ncopn (trim(filnam), NCNOWRIT, error) |
if (error.ne.0) go to 920 |
endif |
c inquire for number of variables |
call ncinq(cdfid,ndims,nvar,ngatts,recdim,error) |
if (error.eq.1) goto 920 |
c read the variables |
do i=1,nvar |
call ncvinq(cdfid,i,varnam(i),vartyp,nvdims,vardim, |
& nvatts,error) |
if (vartyp.ne.NCFLOAT) error=1 |
if (error.gt.0) goto 920 |
enddo |
c get global attributes |
k=0 |
100 continue |
k=k+1 |
attnam(1:3)='dom' |
attnam(4:4)=chrid(k) |
attnam(5:7)='min' |
attnam=attnam(1:7) |
c switch off error message |
call ncpopt(0) |
c check whether dimension k is present |
call ncagt(cdfid,NCGLOBAL,attnam,attval,error) |
if (error.gt.0) goto 110 |
phymin(k)=attval |
attnam(1:3)='dom' |
attnam(4:4)=chrid(k) |
attnam(5:7)='max' |
attnam=attnam(1:7) |
call ncagt(cdfid,NCGLOBAL,attnam,attval,error) |
if (error.gt.0) goto 920 |
phymax(k)=attval |
if (k.lt.3) goto 100 |
k=k+1 |
c define ndim-parameter |
110 continue |
ndim=k-1 |
error=0 |
c switch on error messages |
call ncpopt(NCVERBOS) |
c get constants file name |
c call ncagt(cdfid,NCGLOBAL,'constants_file_name',cfn,error) |
c ! chrigel |
call ncagtc(cdfid,NCGLOBAL,'constants_file_name',cfn,lenstr,error) |
if (error.gt.0) cfn='0' |
c normal exit |
call ncpopt (ncopts) |
return |
c error exit |
920 write (6, *) 'ERROR: An error occurred while attempting to ', |
& 'read the data file in subroutine opncdf.' |
call ncclos (cdfid, error) |
call ncpopt (ncopts) |
end |
subroutine readcdf(filnam, cdfid, |
& phymin, phymax, ndim, varnam, nvar, cfn, error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to open a netCDF file for read |
c with the UWGAP plotting package. |
c Arguments: |
c filnam char input the user-supplied netCDF file name. |
c cdfid int output the file-identifier |
c phymin real output the minimum physical dimension of the |
c entire physical domain along each axis. |
c phymin is dimensioned (ndim) |
c phymax real output the maximum physical dimension of the |
c entire physical domain along each axis. |
c phymax is dimensioned (ndim) |
c ndim int output the number of dimensions in the file |
c (i.e. number of elements in phymin, |
c phymax) |
c varnam char output an array containing the variable names. |
c varnam is dimensioned (nvar). |
c nvar int output the number of variables in the file |
c cfn char output constants file name |
c ('0'=no constants file). |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 error detected. |
c History: |
c Nov. 91 PPM UW Created cr3df. |
c Jan. 92 CS UW Created opncdf. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
c Argument declarations. |
integer MAXDIM |
parameter (MAXDIM=4) |
integer ndim, nvar, error |
character *(*) filnam, varnam(*),cfn |
real phymin(*), phymax(*) |
c Local variable declarations. |
character *(20) attnam |
character *(1) chrid(MAXDIM) |
integer cdfid, i,k |
integer ncopts, ndims,ngatts,recdim |
integer nvdims,vartyp,nvatts,vardim(MAXDIM) |
real attval |
integer lenstr |
data chrid/'x','y','z','a'/ |
data lenstr/80/ |
c Get current value of error options. |
call ncgopt (ncopts) |
c make sure netCDF-errors do not abort execution |
call ncpopt(NCVERBOS) |
c Initially set error to indicate no errors. |
error = 0 |
c open the netCDF file for read |
cdfid = ncopn (trim(filnam), NCNOWRIT, error) |
if (error.ne.0) go to 920 |
c inquire for number of variables |
call ncinq(cdfid,ndims,nvar,ngatts,recdim,error) |
if (error.eq.1) goto 920 |
c read the variables |
do i=1,nvar |
call ncvinq(cdfid,i,varnam(i),vartyp,nvdims,vardim, |
& nvatts,error) |
if (vartyp.ne.NCFLOAT) error=1 |
c print *,varnam(i),nvdims,nvatts |
if (error.gt.0) goto 920 |
enddo |
c get global attributes |
k=0 |
100 continue |
k=k+1 |
attnam(1:3)='dom' |
attnam(4:4)=chrid(k) |
attnam(5:7)='min' |
attnam=attnam(1:7) |
c switch off error message |
call ncpopt(0) |
c check whether dimension k is present |
call ncagt(cdfid,NCGLOBAL,attnam,attval,error) |
if (error.gt.0) goto 110 |
phymin(k)=attval |
attnam(1:3)='dom' |
attnam(4:4)=chrid(k) |
attnam(5:7)='max' |
attnam=attnam(1:7) |
call ncagt(cdfid,NCGLOBAL,attnam,attval,error) |
if (error.gt.0) goto 920 |
phymax(k)=attval |
if (k.lt.4) goto 100 |
k=k+1 |
c define ndim-parameter |
110 continue |
ndim=k-1 |
error=0 |
c switch on error messages |
call ncpopt(NCVERBOS) |
c get constants file name |
c call ncagt(cdfid,NCGLOBAL,'constants_file_name',cfn,error) |
c ! chrigel |
call ncagtc(cdfid,NCGLOBAL,'constants_file_name',cfn,lenstr,error) |
if (error.gt.0) cfn='0' |
c print *,cfn |
c normal exit |
call ncpopt (ncopts) |
return |
c error exit |
920 write (6, *) 'ERROR: An error occurred while attempting to ', |
& 'read the data file in subroutine opncdf.' |
call ncclos (cdfid, error) |
call ncpopt (ncopts) |
end |
subroutine getcdf (cdfid, varnam, ndim, misdat, |
& vardim, varmin, varmax, stag, dat, error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to get a variable and its attributes |
c from a netCDF file for use with the UWGAP plotting package. |
c It is assumed that the data is floating-point data. Prior to |
c calling this routine, the file must be opened with a call to |
c opncdf. |
c Arguments: |
c cdfid int input file-identifier |
c (can be obtained by calling routine |
c opncdf) |
c varnam char input the user-supplied variable name. |
c (can be obtained by calling routine |
c opncdf) |
c ndim int output the number of dimensions (ndim<=4) |
c misdat real output missing data value for the variable. |
c vardim int output the dimensions of the variable. |
c is dimensioned at least (ndim). |
c varmin real output the location in physical space of the |
c origin of each variable. |
c is dimensioned at least Min(ndim,3). |
c varmax real output the extent of each variable in physical |
c space. |
c is dimensioned at least Min(ndim,3). |
c stag real output the grid staggering for each variable. |
c is dimensioned at least Min(ndim,3). |
c dat real output data-array dimensioned suffiecently |
c large, at least |
c vardim(1)* ... vardim(ndim) |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 error detected. |
c History: |
c Nov. 91 PPM UW Created cr3df. |
c Jan. 92 CS UW Created getcdf. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
c Argument declarations. |
integer MAXDIM |
parameter (MAXDIM=4) |
character *(*) varnam |
integer vardim(*), ndim, error, cdfid |
real misdat, stag(*), varmin(*), varmax(*), dat(*) |
c Local variable declarations. |
character *(20) dimnam(100),attnam |
character *(1) chrid(MAXDIM) |
integer id,i,k,corner(MAXDIM) |
integer ndims,nvars,ngatts,recdim,dimsiz(100) |
integer vartyp,nvatts, ncopts |
data chrid/'x','y','z','a'/ |
data corner/1,1,1,1/ |
c Get current value of error options, and make sure netCDF-errors do |
c not abort execution |
call ncgopt (ncopts) |
call ncpopt(NCVERBOS) |
c Initially set error to indicate no errors. |
error = 0 |
c inquire for number of dimensions |
call ncinq(cdfid,ndims,nvars,ngatts,recdim,error) |
if (error.eq.1) goto 920 |
c read dimension-table |
do i=1,ndims |
call ncdinq(cdfid,i,dimnam(i),dimsiz(i),error) |
if (error.gt.0) goto 920 |
enddo |
c get id of the variable |
id=ncvid(cdfid,varnam,error) |
if (error.eq.1) goto 910 |
c inquire about variable |
call ncvinq(cdfid,id,varnam,vartyp,ndim,vardim,nvatts,error) |
if (vartyp.ne.NCFLOAT) error=1 |
if (error.gt.0) goto 920 |
c Make sure ndim <= MAXDIM. |
if (ndim.gt.MAXDIM) then |
error = 1 |
go to 900 |
endif |
c get dimensions from dimension-table |
do k=1,ndim |
vardim(k)=dimsiz(vardim(k)) |
enddo |
c get attributes |
do k=1,min0(ndim,3) |
c get staggering |
attnam(1:1)=chrid(k) |
attnam(2:5)='stag' |
attnam=attnam(1:5) |
call ncagt(cdfid,id,attnam,stag(k),error) |
if (error.gt.0) goto 920 |
c get min postion |
attnam(1:1)=chrid(k) |
attnam(2:4)='min' |
attnam=attnam(1:4) |
call ncagt(cdfid,id,attnam,varmin(k),error) |
if (error.gt.0) goto 920 |
c get max position |
attnam(1:1)=chrid(k) |
attnam(2:4)='max' |
attnam=attnam(1:4) |
call ncagt(cdfid,id,attnam,varmax(k),error) |
if (error.gt.0) goto 920 |
enddo |
c get missing data value |
call ncagt(cdfid,id,'missing_data',misdat,error) |
if (error.gt.0) goto 920 |
c get data |
call ncvgt(cdfid,id,corner,vardim,dat,error) |
if (error.gt.0) goto 920 |
c normal exit |
call ncpopt (ncopts) |
return |
c Error exits. |
900 write (6, *) 'ERROR: When calling getcdf, the number of ', |
& 'variable dimensions must be less or equal 4.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
910 write (6, *) 'ERROR: The selected variable could not be found ', |
& 'in the file by getcdf.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
920 write (6, *) 'ERROR: An error occurred while attempting to ', |
& 'read the data file in subroutine getcdf.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
end |
subroutine putcdf (cdfid, varnam, ndim, misdat, |
& vardim, varmin, varmax, stag, dat, error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to put a variable and its attributes |
c onto a netCDF file for use with the UWGAP plotting package. |
c It is assumed that the data is floating-point data. Prior to |
c calling this routine, the file must be created (crecdf) or |
c opened (opncdf). |
c Any netCDF file written to must be closed with the call |
c call ncclos(cdfid,error), where cdfid and error are |
c as in the argumentlist below. |
c Arguments: |
c cdfid int input file-identifier |
c (can be obtained by calling routine |
c opncdf) |
c varnam char input the user-supplied variable name. |
c (can be obtained by calling routine |
c opncdf) |
c ndim int input the number of dimensions (ndim<=4) |
c misdat real input missing data value for the variable. |
c vardim int input the dimensions of the variable. |
c is dimensioned at least (ndim). |
c varmin real input the location in physical space of the |
c origin of each variable. |
c is dimensioned at least Min(ndim,3). |
c varmax real input the extent of each variable in physical |
c space. |
c is dimensioned at least Min(ndim,3). |
c stag real input the grid staggering for each variable. |
c is dimensioned at least Min(ndim,3). |
c dat real input data-array dimensioned suffiecently |
c large, at least |
c vardim(1)* ... vardim(ndim) |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 error detected. |
c History: |
c Nov. 91 PPM UW Created cr3df, wr3df. |
c Jan. 92 CS UW Created putcdf. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
c Argument declarations. |
integer MAXDIM |
parameter (MAXDIM=4) |
character *(*) varnam |
integer vardim(*), ndim, error, cdfid |
real misdat, stag(*), varmin(*), varmax(*), dat(*) |
c Local variable declarations. |
character *(20) dimnam,attnam,dimchk |
character *(1) chrid(MAXDIM) |
character *(20) dimnams(MAXNCDIM) |
integer dimvals(MAXNCDIM) |
integer numdims,numvars,numgats,dimulim |
integer id,did(MAXDIM),i,k,corner(MAXDIM) |
integer ncopts |
integer ibeg,iend |
data chrid/'x','y','z','t'/ |
data corner/1,1,1,1/ |
c Get current value of error options. |
call ncgopt (ncopts) |
c make sure netCDF-errors do not abort execution |
call ncpopt(NCVERBOS) |
c Initially set error to indicate no errors. |
error = 0 |
c Make sure ndim <= MAXDIM. |
if (ndim.gt.MAXDIM) then |
error = 1 |
go to 900 |
endif |
c Read existing dimensions-declarations from the file |
call ncinq(cdfid,numdims,numvars,numgats,dimulim,error) |
if (error.ne.0) numdims=0 |
if (numdims.gt.0) then |
do i=1,numdims |
call ncdinq(cdfid,i,dimnams(i),dimvals(i),error) |
c print *,dimnams(i),dimvals(i) |
enddo |
endif |
c put file into define mode |
call ncredf(cdfid,error) |
if (error.ne.0) goto 920 |
c define the dimension |
do k=1,ndim |
c define the dimension-name |
dimnam(1:3)='dim' |
dimnam(4:4)=chrid(k) |
dimnam(5:5)='_' |
dimnam(6:5+len_trim(varnam))=trim(varnam) |
dimnam=dimnam(1:5+len_trim(varnam)) |
did(k)=-1 |
if (numdims.gt.0) then |
c check if an existing dimension-declaration can be used |
c instead of defining a nuw dimension |
do i=1,numdims |
dimchk=dimnams(i) |
if ((vardim(k).eq.dimvals(i)).and. |
& (dimnam(1:4).eq.dimchk(1:4))) then |
did(k)=i |
goto 100 |
endif |
enddo |
100 continue |
endif |
if (did(k).lt.0) then |
c define the dimension |
did(k)=ncddef(cdfid,dimnam,vardim(k),error) |
if (error.ne.0) goto 920 |
endif |
enddo |
c define variable |
id=ncvdef(cdfid,varnam,NCFLOAT,ndim,did,error) |
if (error.ne.0) goto 920 |
c define attributes |
do k=1,min0(ndim,3) |
c staggering |
attnam(1:1)=chrid(k) |
attnam(2:5)='stag' |
attnam=attnam(1:5) |
call ncapt(cdfid,id,attnam,NCFLOAT,1,stag(k),error) |
if (error.gt.0) goto 920 |
c min postion |
attnam(1:1)=chrid(k) |
attnam(2:4)='min' |
attnam=attnam(1:4) |
call ncapt(cdfid,id,attnam,NCFLOAT,1,varmin(k),error) |
if (error.gt.0) goto 920 |
c max position |
attnam(1:1)=chrid(k) |
attnam(2:4)='max' |
attnam=attnam(1:4) |
call ncapt(cdfid,id,attnam,NCFLOAT,1,varmax(k),error) |
if (error.gt.0) goto 920 |
enddo |
c define missing data value |
call ncapt(cdfid,id,'missing_data',NCFLOAT,1,misdat,error) |
if (error.gt.0) goto 920 |
c leave define mode |
call ncendf(cdfid,error) |
if (error.gt.0) goto 920 |
c define data |
call ncvpt(cdfid,id,corner,vardim,dat,error) |
if (error.gt.0) goto 920 |
c synchronyse output to disk and exit |
call ncsnc (cdfid,error) |
call ncpopt (ncopts) |
return |
c Error exits. |
900 write (6, *) 'ERROR: When calling putcdf, the number of ', |
& 'variable dimensions must be less or equal 4.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
920 write (6, *) 'ERROR: An error occurred while attempting to ', |
& 'write the data file in subroutine putcdf.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
end |
c |
c |
subroutine getdef (cdfid, varnam, ndim, misdat, |
& vardim, varmin, varmax, stag, error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to get the dimensions and attributes of |
c a variable from an IVE-NetCDF file for use with the IVE plotting |
c package. Prior to calling this routine, the file must be opened |
c with a call to opncdf. |
c Arguments: |
c cdfid int input file-identifier |
c (can be obtained by calling routine |
c opncdf) |
c varnam char input the user-supplied variable name. |
c (can be obtained by calling routine |
c opncdf) |
c ndim int output the number of dimensions (ndim<=4) |
c misdat real output missing data value for the variable. |
c vardim int output the dimensions of the variable. |
c Is dimensioned at least (ndim). |
c varmin real output the location in physical space of the |
c origin of each variable. |
c Is dimensioned at least Min(3,ndim). |
c varmax real output the extend of each variable in physical |
c space. |
c Is dimensioned at least Min(3,ndim). |
c stag real output the grid staggering for each variable. |
c Is dimensioned at least Min(3,ndim). |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 the variable is not on the file. |
c error =10 other errors. |
c History: |
c Apr. 93 Christoph Schaer (ETHZ) Created. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
c Argument declarations. |
integer MAXDIM |
parameter (MAXDIM=4) |
character *(*) varnam |
integer vardim(*), ndim, error, cdfid |
real misdat, stag(*), varmin(*), varmax(*) |
c Local variable declarations. |
character *(20) dimnam(MAXNCDIM),attnam,vnam |
character *(1) chrid(MAXDIM) |
integer id,i,k |
integer ndims,nvars,ngatts,recdim,dimsiz(MAXNCDIM) |
integer vartyp,nvatts, ncopts |
data chrid/'x','y','z','t'/ |
c Get current value of error options. |
call ncgopt (ncopts) |
c make sure NetCDF-errors do not abort execution |
call ncpopt(NCVERBOS) |
c Initially set error to indicate no errors. |
error = 0 |
c inquire for number of dimensions |
call ncinq(cdfid,ndims,nvars,ngatts,recdim,error) |
if (error.eq.1) goto 920 |
c read dimension-table |
do i=1,ndims |
call ncdinq(cdfid,i,dimnam(i),dimsiz(i),error) |
if (error.gt.0) goto 920 |
enddo |
c get id of the variable |
id=ncvid(cdfid,varnam,error) |
if (error.eq.1) goto 910 |
c inquire about variable |
call ncvinq(cdfid,id,vnam,vartyp,ndim,vardim,nvatts,error) |
if (vartyp.ne.NCFLOAT) error=1 |
if (error.gt.0) goto 920 |
c Make sure ndim <= MAXDIM. |
if (ndim.gt.MAXDIM) then |
error = 1 |
go to 900 |
endif |
c get dimensions from dimension-table |
do k=1,ndim |
vardim(k)=dimsiz(vardim(k)) |
enddo |
c get attributes |
do k=1,min0(3,ndim) |
c get min postion |
attnam(1:1)=chrid(k) |
attnam(2:4)='min' |
attnam=attnam(1:4) |
call ncagt(cdfid,id,attnam,varmin(k),error) |
if (error.gt.0) goto 920 |
c get max position |
attnam(1:1)=chrid(k) |
attnam(2:4)='max' |
attnam=attnam(1:4) |
call ncagt(cdfid,id,attnam,varmax(k),error) |
if (error.gt.0) goto 920 |
c get staggering |
attnam(1:1)=chrid(k) |
attnam(2:5)='stag' |
attnam=attnam(1:5) |
call ncagt(cdfid,id,attnam,stag(k),error) |
if (error.gt.0) goto 920 |
enddo |
c get missing data value |
call ncagt(cdfid,id,'missing_data',misdat,error) |
if (error.gt.0) goto 920 |
c normal exit |
call ncpopt (ncopts) |
return |
c Error exits. |
900 write (6, *) '*ERROR*: When calling getcdf, the number of ', |
& 'variable dimensions must be less or equal 4.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
910 write (6, *) '*ERROR*: The selected variable could not be found ', |
& 'in the file by getcdf.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
920 write (6, *) '*ERROR*: An error occurred while attempting to ', |
& 'read the data file in subroutine getcdf.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
end |
subroutine getdat(cdfid, varnam, time, level, dat, error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to read the data of a variable |
c from an IVE-NetCDF file for use with the IVE plotting package. |
c Prior to calling this routine, the file must be opened with |
c a call to opncdf (for extension) or crecdf (for creation) or |
c readcdf (for readonly). |
c Arguments: |
c cdfid int input file-identifier |
c (must be obtained by calling routine |
c opncdf,readcdf or crecdf) |
c varnam char input the user-supplied variable name (must |
c previously be defined with a call to |
c putdef) |
c time real input the user-supplied time-level of the |
c data to be read from the file (the time- |
c levels stored in the file can be obtained |
c with a call to gettimes). |
c level int input the horizontal level(s) to be read |
c to the NetCDF file. Suppose that the |
c variable is defined as (nx,ny,nz,nt). |
c level>0: the call reads the subdomain |
c (1:nx,1:ny,level,itimes) |
c level=0: the call reads the subdomain |
c (1:nx,1:ny,1:nz,itimes) |
c Here itimes is the time-index corresponding |
c to the value of 'time'. |
c dat real output data-array dimensioned sufficiently |
c large. The dimensions (nx,ny,nz) |
c of the variable must previously be defined |
c with a call to putdef. No previous |
c definition of the time-dimension is |
c required. |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 the variable is not present on |
c the file. |
c error = 2 the value of 'time' is not |
c known.to the file. |
c error = 3 inconsistent value of level |
c error =10 another error. |
c History: |
c March 93 Heini Wernli (ETHZ) Created wr2cdf. |
c April 93 Bettina Messmer (ETHZ) Created putdat. |
c June 93 Christoph Schaer (ETHZ) Created getdat |
c Sept. 07 Johannes Jenkner (ETHZ) Integer and double times |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
C Declaration of local variables |
character*(*) varnam |
character*(20) chars,dimnam |
integer cdfid |
real dat(*) |
real misdat,varmin(3),varmax(3),stag(3) |
real time, timeval |
integer corner(4),edgeln(4),didtim,vardim(4),ndims |
integer error, ierr |
integer level,ntime |
integer idtime,idvar,iflag |
integer i |
integer vtyp,dn,nat |
integer dims(4) |
integer inttime |
double precision doubletime |
call ncpopt(NCVERBOS) |
c access the variable |
call getdef (cdfid, trim(varnam), ndims, misdat, |
& vardim, varmin, varmax, stag, ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* in getdef in getdat' |
error=1 |
return |
endif |
idvar=ncvid(cdfid,trim(varnam),ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* in ncvid in getdat' |
error=1 |
return |
endif |
C Get times-array |
didtim=ncdid(cdfid,'time',ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* didtim in getdat' |
error=10 |
return |
endif |
call ncdinq(cdfid,didtim,chars,ntime,ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* in ncdinq in getdat' |
error=10 |
return |
endif |
idtime=ncvid(cdfid,'time',ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* in ncvid for time in getdat' |
error=10 |
return |
endif |
c find appropriate time-index |
iflag=0 |
call ncvinq(cdfid,idtime,dimnam,vtyp,dn,dims,natt,ierr) |
do i=1,ntime |
if (vtyp.eq.5) then |
call ncvgt1(cdfid,idtime,i,timeval,ierr) |
elseif (vtyp.eq.4) then ! integer version |
call ncvgt1(cdfid,idtime,i,inttime,ierr) |
timeval=real(inttime) |
elseif (vtyp.eq.6) then ! double precision version |
call ncvgt1(cdfid,idtime,i,doubletime,ierr) |
timeval=real(doubletime) |
endif |
if (ierr.ne.0) print *,'*ERROR* in ncvgt1 in getdat' |
if (time.eq.timeval) iflag=i |
enddo |
if (iflag.eq.0) then |
error=2 |
print *,'Error: Unknown time in getdat' |
return |
endif |
C Define data volume to be written (index space) |
corner(1)=1 |
corner(2)=1 |
edgeln(1)=vardim(1) |
edgeln(2)=vardim(2) |
if (level.eq.0) then |
corner(3)=1 |
edgeln(3)=vardim(3) |
else if ((level.le.vardim(3)).and.(level.ge.1)) then |
corner(3)=level |
edgeln(3)=1 |
else |
error=3 |
return |
endif |
corner(4)=iflag |
edgeln(4)=1 |
C Read data from NetCDF file |
c print *,'getdat vor Aufruf ncvgt' |
c print *,'cdfid ',cdfid |
c print *,'idvar ',idvar |
c print *,'corner ',corner |
c print *,'edgeln ',edgeln |
call ncvgt(cdfid,idvar,corner,edgeln,dat,error) |
if (error.ne.0) then |
print *, '*ERROR* in ncvgt in getdat' |
error=10 |
endif |
end |
subroutine putdat(cdfid, varnam, time, level, dat, error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to write the data of a variable |
c to an IVE-NetCDF file for use with the IVE plotting package. |
c Prior to calling this routine, the file must be opened with |
c a call to opncdf (for extension) or crecdf (for creation), the |
c variable must be defined with a call to putdef. |
c Arguments: |
c cdfid int input file-identifier |
c (must be obtained by calling routine |
c opncdf or crecdf) |
c varnam char input the user-supplied variable name (must |
c previously be defined with a call to |
c putdef) |
c time real input the user-supplied time-level of the |
c data to be written to the file (the time- |
c levels stored in the file can be obtained |
c with a call to gettimes). If 'time' is not |
c yet known to the file, a knew time-level is |
c allocated and appended to the times-array. |
c level int input the horizontal level(s) to be written |
c to the NetCDF file. Suppose that the |
c variable is defined as (nx,ny,nz,nt). |
c level>0: the call writes the subdomain |
c (1:nx,1:ny,level,itimes) |
c level=0: the call writes the subdomain |
c (1:nx,1:ny,1:nz,itimes) |
c Here itimes is the time-index corresponding |
c to the value of 'time'. |
c dat real output data-array dimensioned sufficiently |
c large. The dimensions (nx,ny,nz) |
c of the variable must previously be defined |
c with a call to putdef. No previous |
c definition of the time-dimension is |
c required. |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 the variable is not present on |
c the file. |
c error = 2 the value of 'time' is new, but |
c appending it would yield a non |
c ascending times-array. |
c error = 3 inconsistent value of level |
c error =10 another error. |
c History: |
c March 93 Heini Wernli (ETHZ) Created wr2cdf. |
c April 93 Bettina Messmer (ETHZ) Created putdat. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
C Declaration of local variables |
character*(*) varnam |
character*(20) chars |
integer cdfid |
real dat(*) |
real misdat,varmin(3),varmax(3),stag(3) |
real time, timeval |
data stag/0.,0.,0./ |
integer corner(4),edgeln(4),did(4),vardim(4),ndims |
integer error, ierr |
integer level,ntime |
integer idtime,idvar,iflag |
integer i |
call ncpopt(NCVERBOS) |
c get definitions of data |
call getdef (cdfid, trim(varnam), ndims, misdat, |
& vardim, varmin, varmax, stag, ierr) |
if (ierr.ne.0) print *,'*ERROR* in getdef in putdat' |
c get id of variable |
idvar=ncvid(cdfid,trim(varnam),ierr) |
if (ierr.ne.0) print *,'*ERROR* in ncvid in putdat' |
c get times-array |
did(4)=ncdid(cdfid,'time',ierr) |
if (ierr.ne.0) print *,'*ERROR* did(4) in putdat' |
call ncdinq(cdfid,did(4),chars,ntime,ierr) |
if (ierr.ne.0) print *,'*ERROR* in ncdinq in putdat' |
idtime=ncvid(cdfid,'time',ierr) |
if (ierr.ne.0) print *,'*ERROR* in ncvid in putdat' |
C Check if a new time step is starting |
iflag=0 |
do i=1,ntime |
call ncvgt1(cdfid,idtime,i,timeval,ierr) |
if (ierr.ne.0) print *,'*ERROR* in ncvgt1 in putdat' |
if (time.eq.timeval) iflag=i |
enddo |
if (iflag.eq.0) then ! new time step |
ntime=ntime+1 |
iflag=ntime |
idtime=ncvid(cdfid,'time',ierr) |
if (ierr.ne.0) print *, '*ERROR* in ncvid in putdat' |
call ncvpt1(cdfid,idtime,ntime,time,ierr) |
if (ierr.ne.0) print *, '*ERROR* in ncvpt1 in putdat' |
endif |
C Define data volume to write on the NetCDF file in index space |
corner(1)=1 ! starting corner of data volume |
corner(2)=1 |
edgeln(1)=vardim(1) ! edge lengthes of data volume |
edgeln(2)=vardim(2) |
if (level.eq.0) then |
corner(3)=1 |
edgeln(3)=vardim(3) |
else |
corner(3)=level |
edgeln(3)=1 |
endif |
corner(4)=iflag |
edgeln(4)=1 |
C Put data on NetCDF file |
c print *,'vor Aufruf ncvpt d.h. Daten schreiben in putdat ' |
c print *,'cdfid ',cdfid |
c print *,'idvar ',idvar |
c print *,'corner ',corner |
c print *,'edgeln ',edgeln |
call ncvpt(cdfid,idvar,corner,edgeln,dat,error) |
if (error.ne.0) then |
print *, '*ERROR* in ncvpt in putdat - Put data on NetCDF file' |
endif |
C Synchronize output to disk and close the files |
call ncsnc(cdfid,ierr) |
if (ierr.ne.0) print *, '*ERROR* in ncsnc in putdat' |
end |
subroutine putdef (cdfid, varnam, ndim, misdat, |
& vardim, varmin, varmax, stag, error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to define the dimensions and the |
c attributes of a variable on an IVE-NetCDF file for use with the |
c IVE plotting package. Prior to calling this routine, the file must |
c be opened with a call to opncdf (extend an existing file) or |
c crecdf (create a new file). |
c Arguments: |
c cdfid int input file-identifier |
c (can be obtained by calling routine |
c opncdf) |
c varnam char input the user-supplied variable name. |
c ndim int input the number of dimensions (ndim<=4). |
c Upon ndim=4, the fourth dimension of the |
c variable is specified as 'unlimited' |
c on the file (time-dimension). It can |
c later be extended to arbitrary length. |
c misdat real input missing data value for the variable. |
c vardim int input the dimensions of the variable. |
c Is dimensioned at least Min(3,ndim). |
c varmin real input the location in physical space of the |
c origin of each variable. |
c Is dimensioned at least Min(3,ndim). |
c varmax real input the extent of each variable in physical |
c space. |
c Is dimensioned at least Min(ndim). |
c stag real input the grid staggering for each variable. |
c Is dimensioned at least Min(3,ndim). |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error =10 other errors detected. |
c History: |
c Apr. 93 Christoph Schaer (ETHZ) Created. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
c Argument declarations. |
integer MAXDIM |
parameter (MAXDIM=4) |
character *(*) varnam |
integer vardim(*), ndim, error, cdfid |
real misdat, stag(*), varmin(*), varmax(*) |
c Local variable declarations. |
character *(20) dimnam,attnam,dimchk |
character *(1) chrid(MAXDIM) |
character *(20) dimnams(MAXNCDIM) |
integer dimvals(MAXNCDIM) |
integer numdims,numvars,numgats,dimulim |
integer id,did(MAXDIM),idtime,i,k,ierr |
integer ncopts |
integer ibeg,iend |
data chrid/'x','y','z','t'/ |
c Get current value of error options. |
call ncgopt (ncopts) |
c make sure NetCDF-errors do not abort execution |
call ncpopt(NCVERBOS) |
c Initially set error to indicate no errors. |
error = 0 |
c Make sure ndim <= MAXDIM. |
if (ndim.gt.MAXDIM) then |
error = 10 |
go to 900 |
endif |
c Read existing dimensions-declarations from the file |
call ncinq(cdfid,numdims,numvars,numgats,dimulim,error) |
if (numdims.gt.0) then |
do i=1,numdims |
call ncdinq(cdfid,i,dimnams(i),dimvals(i),error) |
c print *,dimnams(i),dimvals(i) |
enddo |
endif |
c put file into define mode |
call ncredf(cdfid,error) |
if (error.ne.0) goto 920 |
c define spatial dimensions |
do k=1,min0(3,ndim) |
c define the default dimension-name |
dimnam(1:3)='dim' |
dimnam(4:4)=chrid(k) |
dimnam(5:5)='_' |
dimnam(6:5+len_trim(varnam))=trim(varnam) |
dimnam=dimnam(1:5+len_trim(varnam)) |
did(k)=-1 |
if (numdims.gt.0) then |
c check if an existing dimension-declaration can be used |
c instead of defining a new dimension |
do i=1,numdims |
dimchk=dimnams(i) |
if ((vardim(k).eq.dimvals(i)).and. |
& (dimnam(1:4).eq.dimchk(1:4))) then |
did(k)=i |
goto 100 |
endif |
enddo |
100 continue |
endif |
if (did(k).lt.0) then |
c define the dimension |
did(k)=ncddef(cdfid,dimnam,vardim(k),error) |
if (error.ne.0) goto 920 |
endif |
enddo |
c define the times-array |
if (ndim.eq.4) then |
c define dimension and variable 'time' |
if (numdims.ge.4) then |
did(4)=ncdid(cdfid,'time',ierr) |
idtime=ncvid(cdfid,'time',ierr) |
else |
c this dimension must first be defined |
did(4) = ncddef (cdfid,'time',NCUNLIM,ierr) |
idtime = ncvdef (cdfid,'time',NCFLOAT,1,did(4),ierr) |
endif |
endif |
c define variable |
id=ncvdef(cdfid,varnam,NCFLOAT,ndim,did,error) |
if (error.ne.0) goto 920 |
c define attributes |
do k=1,min0(ndim,3) |
c min postion |
attnam(1:1)=chrid(k) |
attnam(2:4)='min' |
attnam=attnam(1:4) |
call ncapt(cdfid,id,attnam,NCFLOAT,1,varmin(k),error) |
if (error.gt.0) goto 920 |
c max position |
attnam(1:1)=chrid(k) |
attnam(2:4)='max' |
attnam=attnam(1:4) |
call ncapt(cdfid,id,attnam,NCFLOAT,1,varmax(k),error) |
if (error.gt.0) goto 920 |
c staggering |
attnam(1:1)=chrid(k) |
attnam(2:5)='stag' |
attnam=attnam(1:5) |
call ncapt(cdfid,id,attnam,NCFLOAT,1,stag(k),error) |
if (error.gt.0) goto 920 |
enddo |
c define missing data value |
call ncapt(cdfid,id,'missing_data',NCFLOAT,1,misdat,error) |
if (error.gt.0) goto 920 |
c leave define mode |
call ncendf(cdfid,error) |
if (error.gt.0) goto 920 |
c synchronyse output to disk and exit |
call ncsnc (cdfid,error) |
call ncpopt (ncopts) |
return |
c Error exits. |
900 write (6, *) '*ERROR*: When calling putcdf, the number of ', |
& 'variable dimensions must be less or equal 4.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
920 write (6, *) '*ERROR*: An error occurred while attempting to ', |
& 'write the data file in subroutine putcdf.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
end |
subroutine puttimes(cdfid,times,ntimes,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Redefine all times on the specified NetCDF file |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C times real input array contains all time values on the file, |
C dimensioned at least times(ntimes) |
C ntimes int input number of times on the file |
C error int output errorflag |
C History: |
C Heini Wernli, ETHZ |
C Christoph Schaer, ETHZ |
C Johannes Jenkner, ETHZ (adjustment for integer and double times) |
C Note: |
C This preliminary version does not define the times-array, but only |
C overwrites or extends an existing times-array. |
C------------------------------------------------------------------------ |
integer ierr,i |
real times(*) |
integer didtim,ntimes |
integer cdfid,idtime,nfiltim |
integer ncdid,ncvid |
integer vtyp,dn,nat |
integer dims(4) |
idtime=ncvid(cdfid,'time',ierr) ! inquire id for time array |
if (ierr.ne.0) return |
didtim=ncdid(cdfid,'time',ierr) ! inquire id for time dimension |
if (ierr.ne.0) return |
call ncdinq(cdfid,didtim,'time',nfiltim,ierr) ! inquire # of times |
if (ierr.ne.0) return |
call ncvinq(cdfid,idtime,dimnam,vtyp,dn,dims,natt,ierr) |
if (nfiltim.lt.ntimes) then |
print *,'Warning: puttimes is extending times-array' |
else if (nfiltim.gt.ntimes) then |
print *,'Warning: puttimes does not cover range of times-array' |
endif |
if (vtyp.eq.5) then |
do i=1,ntimes |
call ncvpt1(cdfid,idtime,i,times(i),ierr) |
if (ierr.ne.0) return |
enddo |
elseif (vtyp.eq.4) then ! integer version |
do i=1,ntimes |
call ncvpt1(cdfid,idtime,i,int(times(i)),ierr) |
if (ierr.ne.0) return |
enddo |
elseif (vtyp.eq.6) then ! double precision version |
do i=1,ntimes |
call ncvgt1(cdfid,idtime,i,dble(times(i)),ierr) |
if (ierr.ne.0) return |
enddo |
else |
return |
endif |
end |
subroutine gettimes(cdfid,times,ntimes,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Get all times on the specified NetCDF file |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C times real output array contains all time values on the file, |
C dimensioned at least times(ntimes) |
C ntimes int output number of times on the file |
C error int output errorflag |
C History: |
C Heini Wernli, ETHZ |
C Johannes Jenkner, ETHZ (adjustment for integer and double times) |
C------------------------------------------------------------------------ |
include "netcdf.inc" |
integer ierr,i |
real times(*) |
integer didtim,ntimes |
integer cdfid,idtime |
integer ncopts |
character*(20) dimnam |
integer vtyp,dn,nat |
integer dims(4) |
integer,dimension(:),allocatable :: inttimes |
double precision,dimension(:),allocatable :: doubletimes |
c Get current value of error options, and make sure netCDF-errors do |
c not abort execution |
call ncgopt (ncopts) |
call ncpopt(NCVERBOS) |
didtim=ncdid(cdfid,'time',ierr) ! inquire id for time dimension |
if (ierr.ne.0) goto 900 |
idtime=ncvid(cdfid,'time',ierr) ! inquire id for time array |
if (ierr.ne.0) goto 900 |
call ncdinq(cdfid,didtim,dimnam,ntimes,ierr) ! inquire # of times |
if (ierr.ne.0) goto 900 |
call ncvinq(cdfid,idtime,dimnam,vtyp,dn,dims,natt,ierr) |
if (vtyp.eq.5) then |
do i=1,ntimes |
call ncvgt1(cdfid,idtime,i,times(i),ierr) ! get times |
if (ierr.ne.0) goto 900 |
enddo |
elseif (vtyp.eq.4) then ! integer version |
allocate(inttimes(ntimes)) |
do i=1,ntimes |
call ncvgt1(cdfid,idtime,i,inttimes(i),ierr) ! get times |
if (ierr.ne.0) goto 900 |
enddo |
times(1:ntimes)=real(inttimes(1:ntimes)) |
elseif (vtyp.eq.6) then ! double precision version |
allocate(doubletimes(ntimes)) |
do i=1,ntimes |
call ncvgt1(cdfid,idtime,i,doubletimes(i),ierr) ! get times |
if (ierr.ne.0) goto 900 |
enddo |
times(1:ntimes)=real(doubletimes(1:ntimes)) |
else |
goto 900 |
endif |
c normal exit |
call ncpopt (ncopts) |
return |
c error exit |
900 ntimes=1 |
times(1)=0. |
call ncpopt (ncopts) |
end |
subroutine cpp_crecdf(filnam,filnam_len,cdfid,phymin,phymax,ndim, |
& cfn,cfn_len,error) |
C------------------------------------------------------------------------ |
C Purpose: |
C allows to call crecdf from c++ |
C Arguments: |
C see crecdf |
C additionally: fname_len and cfn_len, the length of the |
C strings |
C |
C |
C History: |
C 981221 Mark A. Liniger ETHZ |
C |
C Note: |
C |
C |
C------------------------------------------------------------------------ |
integer filnam_len,ndim,cfn_len,error,cdfid |
character *(*) filnam,cfn |
real phymin(*),phymax(*) |
call crecdf (filnam(1:filnam_len),cdfid,phymin,phymax,ndim, |
& cfn(1:cfn_len),error) |
end |
subroutine cpp_putdef(cdfid,varnam,varnam_len,ndim,misdat, |
& vardim,varmin,varmax,stag,error) |
C------------------------------------------------------------------------ |
C Purpose: |
C allows to call putdef from c++ |
C Arguments: |
C see crecdf |
C additionally: varnam_len, the length of the |
C strings |
C |
C |
C History: |
C 981221 Mark A. Liniger ETHZ |
C |
C Note: |
C |
C |
C------------------------------------------------------------------------ |
integer varnam_len,ndim,error,vardim(*),cdfid |
character *(*) varnam |
real misdat,stag(*),varmin(*),varmax(*) |
call putdef (cdfid, varnam(1:varnam_len), ndim, misdat, |
& vardim, varmin, varmax, stag, error) |
end |
subroutine cpp_putdat(cdfid, varnam,varnam_len, |
& time, level, dat, error) |
C------------------------------------------------------------------------ |
C Purpose: |
C allows to call putdef from c++ |
C Arguments: |
C see crecdf |
C additionally: varnam_len, the length of the |
C strings |
C |
C |
C History: |
C 981221 Mark A. Liniger ETHZ |
C |
C Note: |
C |
C |
C------------------------------------------------------------------------ |
integer varnam_len,cdfid,error,level |
character *(*) varnam |
real dat(*) |
real time |
call putdat(cdfid, varnam(1:varnam_len), time, level, dat, error) |
end |
/tags/1.0/lib/libcdfplus.f |
---|
0,0 → 1,1568 |
subroutine wricst(cstnam,datar,aklev,bklev,aklay,bklay,stdate) |
C------------------------------------------------------------------------ |
C Creates the constants file for NetCDF files containing ECMWF |
C data. The constants file is compatible with the one created |
C for EM data (with subroutine writecst). |
C |
C Input parameters: |
C |
C cstnam name of constants file |
C datar array contains all required parameters to write file |
C datar(1): number of points along x |
C datar(2): number of points along y |
C datar(3): maximum latitude of data region (ymax) |
C datar(4): minimum longitude of data region (xmin) |
C datar(5): minimum latitude of data region (ymin) |
C datar(6): maximum longitude of data region (xmax) |
C datar(7): grid increment along x |
C datar(8): grid increment along y |
C datar(9): number of levels |
C datar(10): data type (forecast or analysis) |
C datar(11): data version |
C datar(12): constants file version |
C datar(13): longitude of pole of coordinate system |
C datar(14): latitude of pole of coordinate system |
C aklev array contains the aklev values |
C bklev array contains the bklev values |
C aklay array contains the aklay values |
C bklay array contains the bklay values |
C stdate array contains date (year,month,day,time,step) of first |
C field on file (start-date), dimensionised as stdate(5) |
C------------------------------------------------------------------------ |
include "netcdf.inc" |
integer nchar,maxlev |
parameter (nchar=20,maxlev=32) |
real aklev(maxlev),bklev(maxlev) |
real aklay(maxlev),bklay(maxlev) |
real pollat,latmin,latmax |
integer datar(14) |
integer stdate(5) |
character*80 cstnam |
C declarations for constants-variables |
integer nz |
integer dattyp, datver, cstver |
C further declarations |
integer ierr ! error flag |
integer cdfid ! NetCDF id |
integer xid,yid,zid ! dimension ids |
integer pollonid, pollatid, ! variable ids |
> aklevid, bklevid, aklayid, bklayid, |
> lonminid, lonmaxid, latminid, latmaxid, |
> dellonid, dellatid, |
> startyid, startmid, startdid, starthid, startsid, |
> dattypid, datverid, cstverid |
nz=datar(9) ! number of levels |
C Set data-type and -version, version of cst-file-format |
dattyp=datar(10) |
datver=datar(11) |
cstver=datar(12) |
C Initially set error to false |
ierr=0 |
C Create constants file |
cdfid=nccre(trim(cstnam),NCCLOB,ierr) |
C Define the dimensions |
xid = ncddef (cdfid,'nx',datar(1),ierr) |
yid = ncddef (cdfid,'ny',datar(2),ierr) |
zid = ncddef (cdfid,'nz',datar(9),ierr) |
C Define integer constants |
pollonid = ncvdef(cdfid,'pollon', NCFLOAT,0,0,ierr) |
pollatid = ncvdef(cdfid,'pollat', NCFLOAT,0,0,ierr) |
aklevid = ncvdef (cdfid, 'aklev', NCFLOAT, 1, zid, ierr) |
bklevid = ncvdef (cdfid, 'bklev', NCFLOAT, 1, zid, ierr) |
aklayid = ncvdef (cdfid, 'aklay', NCFLOAT, 1, zid, ierr) |
bklayid = ncvdef (cdfid, 'bklay', NCFLOAT, 1, zid, ierr) |
lonminid = ncvdef (cdfid, 'lonmin', NCFLOAT, 0, 0, ierr) |
lonmaxid = ncvdef (cdfid, 'lonmax', NCFLOAT, 0, 0, ierr) |
latminid = ncvdef (cdfid, 'latmin', NCFLOAT, 0, 0, ierr) |
latmaxid = ncvdef (cdfid, 'latmax', NCFLOAT, 0, 0, ierr) |
dellonid = ncvdef (cdfid, 'dellon', NCFLOAT, 0, 0, ierr) |
dellatid = ncvdef (cdfid, 'dellat', NCFLOAT, 0, 0, ierr) |
startyid = ncvdef (cdfid, 'starty', NCLONG, 0, 0, ierr) |
startmid = ncvdef (cdfid, 'startm', NCLONG, 0, 0, ierr) |
startdid = ncvdef (cdfid, 'startd', NCLONG, 0, 0, ierr) |
starthid = ncvdef (cdfid, 'starth', NCLONG, 0, 0, ierr) |
startsid = ncvdef (cdfid, 'starts', NCLONG, 0, 0, ierr) |
dattypid = ncvdef (cdfid, 'dattyp', NCLONG, 0, 0, ierr) |
datverid = ncvdef (cdfid, 'datver', NCLONG, 0, 0, ierr) |
cstverid = ncvdef (cdfid, 'cstver', NCLONG, 0, 0, ierr) |
C Leave define mode |
call ncendf(cdfid,ierr) |
C Store levels |
call ncvpt(cdfid, aklevid, 1, nz, aklev, ierr) |
call ncvpt(cdfid, bklevid, 1, nz, bklev, ierr) |
call ncvpt(cdfid, aklayid, 1, nz, aklay, ierr) |
call ncvpt(cdfid, bklayid, 1, nz, bklay, ierr) |
C Store position of pole (trivial for ECMWF data) |
call ncvpt1(cdfid, pollonid, 1, real(datar(13))/1000., ierr) |
if (datar(14).gt.0) then |
pollat=min(real(datar(14))/1000.,90.) |
else |
pollat=max(real(datar(14))/1000.,-90.) |
endif |
call ncvpt1(cdfid, pollatid, 1, pollat, ierr) |
C Store horizontal data borders and grid increments |
call ncvpt1(cdfid, lonminid, 1, real(datar(4))/1000., ierr) |
call ncvpt1(cdfid, lonmaxid, 1, real(datar(6))/1000., ierr) |
latmin=max(real(datar(5))/1000.,-90.) |
latmax=min(real(datar(3))/1000.,90.) |
call ncvpt1(cdfid, latminid, 1, latmin, ierr) |
call ncvpt1(cdfid, latmaxid, 1, latmax, ierr) |
call ncvpt1(cdfid, dellonid, 1, real(datar(7))/1000., ierr) |
call ncvpt1(cdfid, dellatid, 1, real(datar(8))/1000., ierr) |
C Store date of first field on file (start-date) |
call ncvpt1(cdfid, startyid, 1, stdate(1), ierr) |
call ncvpt1(cdfid, startmid, 1, stdate(2), ierr) |
call ncvpt1(cdfid, startdid, 1, stdate(3), ierr) |
call ncvpt1(cdfid, starthid, 1, stdate(4), ierr) |
call ncvpt1(cdfid, startsid, 1, stdate(5), ierr) |
C Store datatype and version |
call ncvpt1(cdfid, dattypid, 1, dattyp, ierr) |
call ncvpt1(cdfid, datverid, 1, datver, ierr) |
C Store version of the constants file format |
call ncvpt1(cdfid, cstverid, 1, cstver, ierr) |
C Store strings |
call ncclos(cdfid,ierr) |
return |
end |
subroutine writelmcst(cdfid,nx,ny,nz,pollon,pollat,lonmin, |
&lonmax,latmin,latmax,dellon,dellat,dattyp,datver,cstver, |
&psref,tstar,tbeta,pintf,p0top,idate) |
c ------------------------------------------------------------------ |
implicit none |
integer cdfid |
c deklarationen der constants-variablen |
real pollon,pollat |
real lonmin,lonmax,latmin,latmax,dellon,dellat |
integer idate(5) |
integer nx,ny,nz |
integer dattyp, datver, cstver |
real psref, tstar, tbeta, pintf, p0top |
include 'netcdf.inc' |
* netcdf declaration |
integer iret, k |
* dimension ids |
integer nxdim, nydim, nzdim |
* variable ids |
integer startyid, startmid, startdid, starthid |
* variable shapes, corners and edge lengths |
integer dims(1), corner(1), edges(1) |
* enter define mode |
call ncredf(cdfid, iret) |
startyid = ncvdef (cdfid, 'starty', NCLONG, 0, 0, iret) |
startmid = ncvdef (cdfid, 'startm', NCLONG, 0, 0, iret) |
startdid = ncvdef (cdfid, 'startd', NCLONG, 0, 0, iret) |
starthid = ncvdef (cdfid, 'starth', NCLONG, 0, 0, iret) |
* store the rest as global attributes |
* store nx,ny,nz |
call ncapt(cdfid,NCGLOBAL,'nx',NCLONG,1,nx,iret) |
call ncapt(cdfid,NCGLOBAL,'ny',NCLONG,1,ny,iret) |
call ncapt(cdfid,NCGLOBAL,'nz',NCLONG,1,nz,iret) |
* store pollon, pollat |
call ncapt(cdfid,NCGLOBAL,'pollon',NCFLOAT,1,pollon,iret) |
call ncapt(cdfid,NCGLOBAL,'pollat',NCFLOAT,1,pollat,iret) |
* store lonmin, etc |
call ncapt(cdfid,NCGLOBAL,'lonmin',NCFLOAT,1,lonmin,iret) |
call ncapt(cdfid,NCGLOBAL,'lonmax',NCFLOAT,1,lonmax,iret) |
call ncapt(cdfid,NCGLOBAL,'latmin',NCFLOAT,1,latmin,iret) |
call ncapt(cdfid,NCGLOBAL,'latmax',NCFLOAT,1,latmax,iret) |
call ncapt(cdfid,NCGLOBAL,'dellon',NCFLOAT,1,dellon,iret) |
call ncapt(cdfid,NCGLOBAL,'dellat',NCFLOAT,1,dellat,iret) |
* store data type and version |
call ncapt(cdfid,NCGLOBAL,'dattyp',NCLONG,1,dattyp,iret) |
call ncapt(cdfid,NCGLOBAL,'datver',NCLONG,1,datver,iret) |
call ncapt(cdfid,NCGLOBAL,'cstver',NCLONG,1,cstver,iret) |
* store information of lm model vertical grid |
call ncapt(cdfid,NCGLOBAL,'psref',NCFLOAT,1,psref,iret) |
call ncapt(cdfid,NCGLOBAL,'tstar',NCFLOAT,1,tstar,iret) |
call ncapt(cdfid,NCGLOBAL,'tbeta',NCFLOAT,1,tbeta,iret) |
call ncapt(cdfid,NCGLOBAL,'pintf',NCFLOAT,1,pintf,iret) |
call ncapt(cdfid,NCGLOBAL,'p0top',NCFLOAT,1,p0top,iret) |
* leave define mode |
call ncendf(cdfid, iret) |
* store starty, etc |
corner(1) = 1 |
edges(1) = 1 |
call ncvpt(cdfid, startyid, corner, edges, idate(1), iret) |
call ncvpt(cdfid, startmid, corner, edges, idate(2), iret) |
call ncvpt(cdfid, startdid, corner, edges, idate(3), iret) |
call ncvpt(cdfid, starthid, corner, edges, idate(4), iret) |
end |
subroutine globcst(cdfnam,datar,aklev,bklev,aklay,bklay,stdate) |
C------------------------------------------------------------------------ |
C+ |
C NAME: |
C subroutine globcst |
C |
C PURPOSE: |
C instead of writing a constants-file (*_cst), the information |
C is added to the netCDF file as global variables |
C the data format is compatible with the one requested by |
C the IVE ETH/MIT version, contact author about details |
C |
C CATEGORY: |
C model,netCDF |
C |
C CALLING SEQUENCE: |
C subroutine globcst(cdfnam,datar,aklev,bklev,aklay,bklay,stdate) |
C |
C INPUTS: |
C cdfnam name of netCDF file |
C The file needs to exist, otherwise an ERROR occurs, |
C i.e. nothing is done |
C datar array contains all required parameters to write file |
C datar(1): number of points along x |
C datar(2): number of points along y |
C datar(3): maximum latitude of data region (ymax) |
C datar(4): minimum longitude of data region (xmin) |
C datar(5): minimum latitude of data region (ymin) |
C datar(6): maximum longitude of data region (xmax) |
C datar(7): grid increment along x |
C datar(8): grid increment along y |
C datar(9): number of levels |
C datar(10): data type (forecast or analysis) |
C datar(11): data version |
C datar(12): constants file version |
C datar(13): longitude of pole of coordinate system |
C datar(14): latitude of pole of coordinate system |
C aklev array contains the aklev values |
C bklev array contains the bklev values |
C aklay array contains the aklay values |
C bklay array contains the bklay values |
C stdate array contains date (year,month,day,time,step) of first |
C field on file (start-date), dimensionised as stdate(5) |
C list the griblist-ASCII-file |
C varno the GRIB code number |
C |
C OUTPUTS: |
C Adds cdf-information to EXISTING netCDF-file |
C |
C MODIFICATION HISTORY: |
C |
C June 93 Christoph Schaer (ETHZ) created |
C Nov 93 Heini Wernli (ETHZ) wricst |
C Nov 98 David N. Bresch (MIT) wricst to globcst |
C- |
C Sun include statement. |
include "netcdf.inc" |
integer nchar,maxlev |
parameter (nchar=20,maxlev=32) |
real aklev(maxlev),bklev(maxlev) |
real aklay(maxlev),bklay(maxlev) |
integer datar(14) |
integer stdate(5) |
character*80 cdfnam |
C declarations for constants-variables |
integer nz |
integer dattyp, datver, cstver |
C further declarations |
integer ierr ! error flag |
integer cdfid ! NetCDF id |
integer xid,yid,zid ! dimension ids |
integer pollonid, pollatid, ! variable ids |
> aklevid, bklevid, aklayid, bklayid, |
> lonminid, lonmaxid, latminid, latmaxid, |
> dellonid, dellatid, |
> startyid, startmid, startdid, starthid, startsid, |
> dattypid, datverid, cstverid |
nz=datar(9) ! number of levels |
C Set data-type and -version, version of cst-file-format |
dattyp=datar(10) |
datver=datar(11) |
cstver=datar(12) |
C Initially set error to false |
ierr=0 |
C open the netCDF-file: |
call cdfwopn(cdfnam,cdfid,ierr) |
if (ierr.ne.0) then |
print*,'ERROR opening netCDF-file ',cdfnam |
return |
endif |
C Put file into define mode |
call ncredf(cdfid,ierr) |
if (ierr.ne.0) then |
print*,'ERROR switching to netCDF redefine mode' |
return |
endif |
C Define the dimensions |
xid = ncddef (cdfid,'nx',datar(1),ierr) |
yid = ncddef (cdfid,'ny',datar(2),ierr) |
zid = ncddef (cdfid,'nz',datar(9),ierr) |
C Define integer constants |
pollonid = ncvdef(cdfid,'pollon', NCFLOAT,0,0,ierr) |
pollatid = ncvdef(cdfid,'pollat', NCFLOAT,0,0,ierr) |
aklevid = ncvdef (cdfid, 'aklev', NCFLOAT, 1, zid, ierr) |
bklevid = ncvdef (cdfid, 'bklev', NCFLOAT, 1, zid, ierr) |
aklayid = ncvdef (cdfid, 'aklay', NCFLOAT, 1, zid, ierr) |
bklayid = ncvdef (cdfid, 'bklay', NCFLOAT, 1, zid, ierr) |
lonminid = ncvdef (cdfid, 'lonmin', NCFLOAT, 0, 0, ierr) |
lonmaxid = ncvdef (cdfid, 'lonmax', NCFLOAT, 0, 0, ierr) |
latminid = ncvdef (cdfid, 'latmin', NCFLOAT, 0, 0, ierr) |
latmaxid = ncvdef (cdfid, 'latmax', NCFLOAT, 0, 0, ierr) |
dellonid = ncvdef (cdfid, 'dellon', NCFLOAT, 0, 0, ierr) |
dellatid = ncvdef (cdfid, 'dellat', NCFLOAT, 0, 0, ierr) |
startyid = ncvdef (cdfid, 'starty', NCLONG, 0, 0, ierr) |
startmid = ncvdef (cdfid, 'startm', NCLONG, 0, 0, ierr) |
startdid = ncvdef (cdfid, 'startd', NCLONG, 0, 0, ierr) |
starthid = ncvdef (cdfid, 'starth', NCLONG, 0, 0, ierr) |
startsid = ncvdef (cdfid, 'starts', NCLONG, 0, 0, ierr) |
dattypid = ncvdef (cdfid, 'dattyp', NCLONG, 0, 0, ierr) |
datverid = ncvdef (cdfid, 'datver', NCLONG, 0, 0, ierr) |
cstverid = ncvdef (cdfid, 'cstver', NCLONG, 0, 0, ierr) |
C Leave define mode |
call ncendf(cdfid,ierr) |
if (ierr.ne.0) then |
print*,'ERROR exiting define mode' |
return |
endif |
C Store levels |
call ncvpt(cdfid, aklevid, 1, nz, aklev, ierr) |
call ncvpt(cdfid, bklevid, 1, nz, bklev, ierr) |
call ncvpt(cdfid, aklayid, 1, nz, aklay, ierr) |
call ncvpt(cdfid, bklayid, 1, nz, bklay, ierr) |
C Store position of pole (trivial for ECMWF data) |
call ncvpt1(cdfid, pollonid, 1, real(datar(13))/1000., ierr) |
call ncvpt1(cdfid, pollatid, 1, real(datar(14))/1000., ierr) |
C Store horizontal data borders and grid increments |
call ncvpt1(cdfid, lonminid, 1, real(datar(4))/1000., ierr) |
call ncvpt1(cdfid, lonmaxid, 1, real(datar(6))/1000., ierr) |
call ncvpt1(cdfid, latminid, 1, real(datar(5))/1000., ierr) |
call ncvpt1(cdfid, latmaxid, 1, real(datar(3))/1000., ierr) |
call ncvpt1(cdfid, dellonid, 1, real(datar(7))/1000., ierr) |
call ncvpt1(cdfid, dellatid, 1, real(datar(8))/1000., ierr) |
C Store date of first field on file (start-date) |
call ncvpt1(cdfid, startyid, 1, stdate(1), ierr) |
call ncvpt1(cdfid, startmid, 1, stdate(2), ierr) |
call ncvpt1(cdfid, startdid, 1, stdate(3), ierr) |
call ncvpt1(cdfid, starthid, 1, stdate(4), ierr) |
call ncvpt1(cdfid, startsid, 1, stdate(5), ierr) |
C Store datatype and version |
call ncvpt1(cdfid, dattypid, 1, dattyp, ierr) |
call ncvpt1(cdfid, datverid, 1, datver, ierr) |
C Store version of the constants file format |
call ncvpt1(cdfid, cstverid, 1, cstver, ierr) |
if (ierr.ne.0) then |
print*,'ERROR adding cst-date as global variables' |
return |
endif |
C Store strings |
call ncclos(cdfid,ierr) |
if (ierr.ne.0) then |
print*,'ERROR closing netCDF file' |
endif |
return |
end |
subroutine getsdat(cdfid,varnam,time,ix,iy,iz,sx,sy,sz,dat,error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to read the data within a selected |
c domain of a variable from an IVE-NetCDF file. |
c Prior to calling this routine, the file must be opened with |
c a call to opncdf (for extension) or crecdf (for creation) or |
c readcdf (for readonly). |
c Arguments: |
c cdfid int input file-identifier |
c (must be obtained by calling routine |
c opncdf,readcdf or crecdf) |
c varnam char input the user-supplied variable name |
c time real input the user-supplied time-level of the |
c data to be read from the file (the time- |
c levels stored in the file can be obtained |
c with a call to gettimes). |
c ix/y/z int input indices of lower left corner of selected |
c data volume. |
c sx/y/z int input size of selected data volume |
c dat real output data-array with dimensions (sx,sy,sz). |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 the variable is not present on |
c the file. |
c error = 2 the value of 'time' is not |
c known.to the file. |
c error = 6,7,8 data volume too large |
c error =10 another error. |
c History: |
c June 93 Christoph Schaer (ETHZ) Created getdat |
c Nov 93 Heini Wernli (ETHZ) Created getsdat |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
C Declaration of local variables |
character*(*) varnam |
character*(20) chars |
integer cdfid |
integer ix,iy,iz,sx,sy,sz |
real dat(sx,sy,sz) |
real misdat,varmin(3),varmax(3),stag(3) |
real time, timeval |
integer corner(4),edgeln(4),didtim,vardim(4),ndims |
integer error, ierr |
integer ntime |
integer idtime,idvar,iflag |
integer i |
call ncpopt(NCVERBOS) |
c access the variable |
call getdef (cdfid, trim(varnam), ndims, misdat, |
& vardim, varmin, varmax, stag, ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* in getdef in getdat' |
error=1 |
return |
endif |
idvar=ncvid(cdfid,trim(varnam),ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* in ncvid in getsdat' |
error=1 |
return |
endif |
C Get times-array |
didtim=ncdid(cdfid,'time',ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* didtim in getsdat' |
error=10 |
return |
endif |
call ncdinq(cdfid,didtim,chars,ntime,ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* in ncdinq in getsdat' |
error=10 |
return |
endif |
idtime=ncvid(cdfid,'time',ierr) |
if (ierr.ne.0) then |
print *,'*ERROR* in ncvid for time in getsdat' |
error=10 |
return |
endif |
c find appropriate time-index |
iflag=0 |
do i=1,ntime |
call ncvgt1(cdfid,idtime,i,timeval,ierr) |
if (ierr.ne.0) print *,'*ERROR* in ncvgt1 in getsdat' |
if (time.eq.timeval) iflag=i |
enddo |
if (iflag.eq.0) then |
error=2 |
print *,'Error: Unknown time in getsdat' |
print *,time,timeval |
return |
endif |
C Define data volume to be written (index space) |
corner(1)=ix |
corner(2)=iy |
corner(3)=iz |
corner(4)=iflag |
edgeln(1)=sx |
edgeln(2)=sy |
edgeln(3)=sz |
edgeln(4)=1 |
C Check if data volume is within data domain |
if (ix+sx-1.gt.vardim(1)) then |
error=7 |
print *,'Error: data volume too large in x-direction' |
print *,ix,sx,vardim(1) |
return |
endif |
if (iy+sy-1.gt.vardim(2)) then |
error=8 |
print *,'Error: data volume too large in y-direction' |
return |
endif |
if (iz+sz-1.gt.vardim(3)) then |
error=9 |
print *,'Error: data volume too large in z-direction' |
return |
endif |
C Read data from NetCDF file |
call ncvgt(cdfid,idvar,corner,edgeln,dat,error) |
if (error.ne.0) then |
print *, 'corner ',corner(1),corner(2),corner(3) |
print *, 'edgeln ',edgeln(1),edgeln(2),edgeln(3) |
print *, '*ERROR* in ncvgt in getsdat' |
error=10 |
endif |
end |
subroutine getlevs(cstid,nlev,aklev,bklev,aklay,bklay,error) |
c----------------------------------------------------------------------- |
c Purpose: |
c This routine is called to get the level arrays aklev and |
c bklev from a NetCDF constants file. |
c Arguments: |
c cstid int input identifier for NetCDF constants file |
c nlev int input number of levels |
c aklev real output array contains all aklev values |
c bklev real output array contains all bklev values |
c aklay real output array contains all aklay values |
c bklay real output array contains all bklay values |
c error int output error flag |
c error = 0 no errors detected |
c error = 1 error detected |
c History: |
c Aug. 93 Heini Wernli Created. |
c----------------------------------------------------------------------- |
integer error |
integer cstid |
integer ncdid,ncvid ! NetCDF functions |
integer didz,idak,idbk,idaky,idbky |
integer nlev |
real aklev(nlev),bklev(nlev),aklay(nlev),bklay(nlev) |
character*(20) dimnam |
integer i |
didz =ncdid(cstid,'nz',error) |
if (error.ne.0) goto 920 |
idak =ncvid(cstid,'aklev',error) |
if (error.ne.0) goto 920 |
idbk =ncvid(cstid,'bklev',error) |
if (error.ne.0) goto 920 |
idaky =ncvid(cstid,'aklay',error) |
if (error.ne.0) goto 920 |
idbky =ncvid(cstid,'bklay',error) |
if (error.ne.0) goto 920 |
call ncdinq(cstid,didz,dimnam,nlev,error) ! read number of levels |
if (error.ne.0) goto 920 |
do 10 i=1,nlev |
call ncvgt1(cstid,idak,i,aklev(i),error) ! get aklev |
call ncvgt1(cstid,idbk,i,bklev(i),error) ! get bklev |
call ncvgt1(cstid,idaky,i,aklay(i),error) ! get aklay |
call ncvgt1(cstid,idbky,i,bklay(i),error) ! get bklay |
if (error.ne.0) goto 920 |
10 continue |
return |
c Error exits. |
920 write(*,*)'*ERROR*: An error occured in subroutine getlevs' |
return |
end |
subroutine getntim(cdfid,ntimes,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Get number of times on the specified NetCDF file |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C ntimes int output number of times on the file |
C error int output errorflag |
C History: |
C Heini Wernli, ETHZ |
C------------------------------------------------------------------------ |
include "netcdf.inc" |
integer ierr |
integer didtim,ntimes |
integer cdfid,idtime |
integer ncopts |
character*(20) dimnam |
c Get current value of error options, and make sure netCDF-errors do |
c not abort execution |
call ncgopt (ncopts) |
call ncpopt(NCVERBOS) |
didtim=ncdid(cdfid,'time',ierr) ! inquire id for time dimension |
if (ierr.ne.0) goto 900 |
idtime=ncvid(cdfid,'time',ierr) ! inquire id for time array |
if (ierr.ne.0) goto 900 |
call ncdinq(cdfid,didtim,dimnam,ntimes,ierr) ! inquire # of times |
if (ierr.ne.0) goto 900 |
c normal exit |
call ncpopt (ncopts) |
return |
c error exit |
900 ntimes=1 |
call ncpopt (ncopts) |
end |
subroutine getstart(cdfid,idate,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Get start date for fields on specified NetCDF file |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C idate int output array contains date (year,month,day,time,step) |
C dimensioned as idate(5) |
C ierr int output error flag |
C------------------------------------------------------------------------ |
include "netcdf.inc" |
c variable declarations |
integer ierr |
integer idate(5) |
integer cdfid,ncopts,idvar,nvars |
integer ndims,ngatts,recdim,i,vartyp,nvatts,vardim(4) |
character*20 vnam(100) |
c Get current value of error options, and make sure NetCDF-errors do |
c not abort execution |
call ncgopt (ncopts) |
call ncpopt (NCVERBOS) |
idvar=ncvid(cdfid,'starty',ierr) |
if (ierr.ne.0) goto 930 |
call ncvgt1(cdfid,idvar,1,idate(1),ierr) |
if (ierr.ne.0) goto 920 |
idvar=ncvid(cdfid,'startm',ierr) |
if (ierr.ne.0) goto 920 |
call ncvgt1(cdfid,idvar,1,idate(2),ierr) |
if (ierr.ne.0) goto 920 |
idvar=ncvid(cdfid,'startd',ierr) |
if (ierr.ne.0) goto920 |
call ncvgt1(cdfid,idvar,1,idate(3),ierr) |
if (ierr.ne.0) goto 920 |
idvar=ncvid(cdfid,'starth',ierr) |
if (ierr.ne.0) goto 920 |
call ncvgt1(cdfid,idvar,1,idate(4),ierr) |
if (ierr.ne.0) goto 920 |
C Starts is not defined on all files |
C Only ask for it if it exists |
C Inquire number of dimensions, variables and attributes |
idate(5)=0 |
call ncinq(cdfid,ndims,nvars,ngatts,recdim,ierr) |
do i=1,nvars |
call ncvinq(cdfid,i,vnam(i),vartyp,ndims,vardim,nvatts,ierr) |
if (vnam(i).eq.'starts') then |
idvar=ncvid(cdfid,'starts',ierr) |
call ncvgt1(cdfid,idvar,1,idate(5),ierr) |
if (ierr.ne.0) goto 920 |
endif |
enddo |
c normal exit |
call ncpopt (ncopts) |
return |
c error exit |
920 continue |
write (6, *) 'ERROR: An error occurred while attempting to ', |
& 'read the starting-time in subroutine putstart.' |
930 continue |
call ncpopt (ncopts) |
end |
subroutine putstart(cdfid,idate,ierr) |
C---------------------------------------------------------------------- |
C Purpose: |
C Puts the 'starting-time' on the specified NetCDF file. |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C idate int input array contains date (year,month,day,time,step) |
C dimensioned as idate(5) |
C ierr int output error flag |
C------------------------------------------------------------------------ |
include "netcdf.inc" |
c variable declarations |
integer ierr,idate(5),startid(5),cdfid,ncopts,i |
c Get current value of error options, and make sure NetCDF-errors do |
c not abort execution |
call ncgopt (ncopts) |
call ncpopt (NCVERBOS) |
c define variables |
call ncredf(cdfid,ierr) |
if (ierr.ne.0) goto 920 |
startid(1) = ncvdef (cdfid, 'starty', NCLONG, 0, 0, ierr) |
if (ierr.ne.0) goto 920 |
startid(2) = ncvdef (cdfid, 'startm', NCLONG, 0, 0, ierr) |
if (ierr.ne.0) goto 920 |
startid(3) = ncvdef (cdfid, 'startd', NCLONG, 0, 0, ierr) |
if (ierr.ne.0) goto 920 |
startid(4) = ncvdef (cdfid, 'starth', NCLONG, 0, 0, ierr) |
if (ierr.ne.0) goto 920 |
startid(5) = ncvdef (cdfid, 'starts', NCLONG, 0, 0, ierr) |
if (ierr.ne.0) goto 920 |
call ncendf(cdfid, ierr) |
if (ierr.ne.0) goto 920 |
c store variables |
do i=1,5 |
call ncvpt1(cdfid,startid(i),1,idate(i),ierr) |
if (ierr.ne.0) goto 920 |
enddo |
c synchronyse output to disk, revert to previous error-mode, and exit |
call ncsnc (cdfid,ierr) |
call ncpopt (ncopts) |
return |
c error exit |
920 write (6, *) 'ERROR: An error occurred while attempting to ', |
& 'write the starting-time in subroutine putstart.' |
call ncpopt (ncopts) |
call ncclos (cdfid, ierr) |
end |
subroutine getgrid(cdfid,dx,dy,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Get grid increments for fields on specified NetCDF file |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C dx real output grid increment along latitude |
C dy real output grid increment along longitude |
C ierr int output error flag |
C------------------------------------------------------------------------ |
integer ierr |
integer cdfid |
integer ncvid |
integer idilon,idilat |
real dx,dy |
idilon =ncvid(cdfid,'dellon',ierr) |
if (ierr.ne.0) return |
idilat =ncvid(cdfid,'dellat',ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idilon,1,dx,ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idilat,1,dy,ierr) |
if (ierr.ne.0) return |
end |
subroutine getdattyp(cdfid,typ,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Get data type for specified NetCDF file |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C typ int output data type: 1 (52) for pressure (theta) coord |
C ierr int output error flag |
C------------------------------------------------------------------------ |
integer ierr |
integer cdfid |
integer ncvid |
integer idtyp,typ |
idtyp =ncvid(cdfid,'dattyp',ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idtyp,1,typ,ierr) |
if (ierr.ne.0) return |
end |
subroutine getpole(cdfid,pollon,pollat,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Get physical coordinates of pole of coordinate system |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C pollon real output longitude of pole |
C pollat real output latitude of pole |
C ierr int output error flag |
C------------------------------------------------------------------------ |
integer ierr |
integer cdfid |
integer ncvid |
integer idplon,idplat |
real pollon,pollat |
idplon =ncvid(cdfid,'pollon',ierr) |
if (ierr.ne.0) return |
idplat =ncvid(cdfid,'pollat',ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idplon,1,pollon,ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idplat,1,pollat,ierr) |
if (ierr.ne.0) return |
end |
subroutine getmc2grid(cdfid,polx,poly,delx,shem,phi0,lam0,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Get physical coordinates of pole of coordinate system |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C ierr int output error flag |
C------------------------------------------------------------------------ |
integer ierr |
integer cdfid |
integer ncvid |
integer idpolx,idpoly,iddelx,idshem,idphi0,idlam0 |
real polx,poly,delx,shem,phi0,lam0 |
idpolx =ncvid(cdfid,'polx',ierr) |
if (ierr.ne.0) return |
idpoly =ncvid(cdfid,'poly',ierr) |
if (ierr.ne.0) return |
iddelx =ncvid(cdfid,'delx',ierr) |
if (ierr.ne.0) return |
idshem =ncvid(cdfid,'shem',ierr) |
if (ierr.ne.0) return |
idphi0 =ncvid(cdfid,'phi0',ierr) |
if (ierr.ne.0) return |
idlam0 =ncvid(cdfid,'lam0',ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idpolx,1,polx,ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idpoly,1,poly,ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,iddelx,1,delx,ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idshem,1,shem,ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idphi0,1,phi0,ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idlam0,1,lam0,ierr) |
if (ierr.ne.0) return |
end |
subroutine getcfn(cdfid,cfn,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Get name of constants file |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C cfn char output name of constants file |
C ierr int output error flag |
C------------------------------------------------------------------------ |
include "netcdf.inc" |
integer ierr |
integer cdfid,lenstr |
character*80 cfn |
lenstr=80 |
call ncagtc(cdfid,NCGLOBAL,"constants_file_name",cfn,lenstr,ierr) |
if (ierr.ne.0) write(*,*)'error in SR getcfn' |
end |
subroutine gettype(cdfid,dattyp,datver,cstver,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C Get data type information from constants file |
C Arguments: |
C cdfid int input identifier for NetCDF file |
C dattyp int output data type |
C datver int output data version |
C cstver int output constants file version |
C------------------------------------------------------------------------ |
integer ierr |
integer cdfid |
integer ncvid |
integer idtyp,idver,idcstv |
integer dattyp,datver,cstver |
idtyp =ncvid(cdfid,'dattyp',ierr) |
if (ierr.ne.0) return |
idver =ncvid(cdfid,'datver',ierr) |
if (ierr.ne.0) return |
idcstv =ncvid(cdfid,'cstver',ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idtyp,1,dattyp,ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idver,1,datver,ierr) |
if (ierr.ne.0) return |
call ncvgt1(cdfid,idcstv,1,cstver,ierr) |
if (ierr.ne.0) return |
end |
subroutine getvars(cdfid,nvars,vnam,ierr) |
C------------------------------------------------------------------------ |
C Opens the NetCDF file 'filnam' and returns its identifier cdfid. |
C filnam char input name of NetCDF file to open |
C nvars int output number of variables on file |
C vnam char output array with variable names |
C ierr int output error flag |
C------------------------------------------------------------------------ |
include "netcdf.inc" |
integer cdfid,ierr,nvars |
character*(*) vnam(*) |
integer ndims,ngatts,recdim,i,vartyp,nvatts,vardim(4) |
call ncpopt(NCVERBOS) |
C Inquire number of dimensions, variables and attributes |
call ncinq(cdfid,ndims,nvars,ngatts,recdim,ierr) |
C Inquire variable names from NetCDF file |
do i=1,nvars |
call ncvinq(cdfid,i,vnam(i),vartyp,ndims,vardim,nvatts,ierr) |
enddo |
return |
end |
subroutine cdfopn(filnam,cdfid,ierr) |
C------------------------------------------------------------------------ |
C Opens the NetCDF file 'filnam' and returns its identifier cdfid. |
C filnam char input name of NetCDF file to open |
C cdfid int output identifier of NetCDF file |
C ierr int output error flag |
C------------------------------------------------------------------------ |
include "netcdf.inc" |
integer cdfid,ierr |
character*(*) filnam |
call ncpopt(NCVERBOS) |
cdfid=ncopn(trim(filnam),NCNOWRIT,ierr) |
return |
end |
subroutine cdfwopn(filnam,cdfid,ierr) |
C------------------------------------------------------------------------ |
C Opens the NetCDF file 'filnam' and returns its identifier cdfid. |
C filnam char input name of NetCDF file to open |
C cdfid int output identifier of NetCDF file |
C ierr int output error flag |
C------------------------------------------------------------------------ |
include "netcdf.inc" |
integer cdfid,ierr |
character*(*) filnam |
call ncpopt(NCVERBOS) |
cdfid=ncopn(trim(filnam),NCWRITE,ierr) |
return |
end |
subroutine gettra(cdfid,varnam,ix,iy,iz,ntimes,array,ierr) |
C------------------------------------------------------------------------ |
C |
C Reads the time-evolution for one grid-point of the variable |
C indicated by varnam. |
C |
C cdfid int input identifier for NetCDF file |
C varnam char input name of variable |
C ix int input x-index for values to read |
C iy int input y-index for values to read |
C iz int input z-index for values to read |
C ntimes int input number of time-indices to read |
C array real output array contains the readed values |
C ierr int output error flag |
C------------------------------------------------------------------------ |
C Declaration of attributes |
integer cdfid |
character*(*) varnam |
integer ix,iy,iz |
integer ntimes |
real array(ntimes) |
C Declaration of local variables |
integer corner(4),edgeln(4) |
integer idvar,ierr |
integer ncvid |
corner(1)=ix |
corner(2)=iy |
corner(3)=iz |
corner(4)=1 |
edgeln(1)=1 |
edgeln(2)=1 |
edgeln(3)=1 |
edgeln(4)=ntimes |
idvar =ncvid(cdfid,varnam,ierr) |
call ncvgt(cdfid,idvar,corner,edgeln,array,ierr) |
if (ierr.ne.0) goto 991 |
return |
991 stop 'Variable not found on NetCDF file in SR gettra' |
end |
subroutine new_gettra(cdfid,varnam,ix,ntimes,array,ierr) |
C------------------------------------------------------------------------ |
C |
C Reads the time-evolution for one grid-point of the variable |
C indicated by varnam. |
C |
C cdfid int input identifier for NetCDF file |
C varnam char input name of variable |
C ix int input index for trajectory to read |
C ntimes int input number of time-indices to read |
C array real output array contains the readed values |
C ierr int output error flag |
C------------------------------------------------------------------------ |
C Declaration of attributes |
integer cdfid |
character*(*) varnam |
integer ix |
integer ntimes |
real array(ntimes) |
C Declaration of local variables |
integer corner(4),edgeln(4) |
integer idvar,ierr |
integer ncvid |
corner(1)=ix |
corner(2)=1 |
corner(3)=1 |
corner(4)=1 |
edgeln(1)=1 |
edgeln(2)=1 |
edgeln(3)=1 |
edgeln(4)=ntimes |
idvar =ncvid(cdfid,trim(varnam),ierr) |
call ncvgt(cdfid,idvar,corner,edgeln,array,ierr) |
if (ierr.ne.0) goto 991 |
return |
991 stop 'Variable not found on NetCDF file in SR new_gettra' |
end |
subroutine puttra(cdfid,varnam,ix,ntimes,array,ierr) |
C------------------------------------------------------------------------ |
C |
C Writes the time-evolution for one grid-point of the variable |
C indicated by varnam. |
C |
C cdfid int input identifier for NetCDF file |
C varnam char input name of variable |
C ix int input index for trajectory to read |
C ntimes int input number of time-indices to read |
C array real output array contains the readed values |
C ierr int output error flag |
C------------------------------------------------------------------------ |
C Declaration of attributes |
integer cdfid |
character*(*) varnam |
integer ix |
integer ntimes |
real array(ntimes) |
C Declaration of local variables |
integer corner(4),edgeln(4) |
integer idvar,ierr |
integer ncvid |
corner(1)=1 |
corner(2)=1 |
corner(3)=1 |
corner(4)=ix |
edgeln(1)=ntimes |
edgeln(2)=1 |
edgeln(3)=1 |
edgeln(4)=1 |
idvar =ncvid(cdfid,varnam,ierr) |
call ncvpt(cdfid,idvar,corner,edgeln,array,ierr) |
if (ierr.ne.0) goto 991 |
return |
991 stop 'Could not write data on NetCDF file in SR puttra' |
end |
subroutine getakbk(nlev,flev,akbk,nn,aklev,bklev,aklay,bklay) |
C------------------------------------------------------------------------ |
C |
C Defines the level- and layer-arrays given the number of levels nlev. |
C |
C nlev int input number of levels/layers wanted |
C akbk real input array contains ak/bk values from grib (zsec2) |
C nn int input number of elements in array akbk |
C aklev real output array contains ak values for levels |
C bklev real output array contains bk values for levels |
C aklay real output array contains ak values for layers |
C bklay real output array contains bk values for layers |
C------------------------------------------------------------------------ |
integer nn,nz,nlev,k |
real aklev(100),bklev(100), ! level coefficients |
> aklay(100),bklay(100), ! layer coefficients |
> akbk(nn) |
real ak(100),bk(100) |
real flev |
C Determine number of levels in array akbk |
do k=1,nn |
if (akbk(k).eq.1.0) nz=(k-12)/2 |
enddo |
c print*,nlev,nz |
do k=1,nz+1 |
ak(k)=akbk(k+10)/100. |
bk(k)=akbk(k+11+nz) |
enddo |
do k=1,nz |
aklay(k)=(ak(nz+2-k)+ak(nz+1-k))/2. |
bklay(k)=(bk(nz+2-k)+bk(nz+1-k))/2. |
aklev(k)=ak(nz+1-k) |
bklev(k)=bk(nz+1-k) |
c if (k.eq.2) print*,'bugfix ',bklev(2) |
enddo |
c do k=1,nz |
c print*,k,flev,bk(nz+1-k),aklev(k),aklay(k),bklev(k),bklay(k) |
c enddo |
return |
end |
subroutine modlevs(nlev,aklev,bklev,aklay,bklay) |
C------------------------------------------------------------------------ |
C |
C Defines the level- and layer-arrays given the number of levels nlev. |
C |
C nlev int input number of levels/layers |
C aklev real output array contains ak values for levels |
C bklev real output array contains bk values for levels |
C aklay real output array contains ak values for layers |
C bklay real output array contains bk values for layers |
C------------------------------------------------------------------------ |
integer n19,n31,n50,nlev,k |
parameter(n19=20,n31=32,n50=51) ! number of model levels |
real aklev(nlev+1),bklev(nlev+1), ! level coefficients |
> aklay(nlev+1),bklay(nlev+1) ! layer coefficients |
real ak19(n19),bk19(n19), ! 19 level version |
> ak31(n31),bk31(n31), ! 31 level version |
> ak50(n50),bk50(n50) ! 50 level version |
C Modell level specification for 19 level version |
DATA AK19/0,20,40,60,83,106,128,146,158,161,153,136,111, |
> 82,52,26,8,0,0,0/ |
DATA BK19/0,0,0,0,.004,.014,.035,.072,.127,.202,.296,.405, |
> .524,.645,.759,.856,.929,.973,.992,1./ |
C Modell level specification for 31 level version |
DATA AK31/ |
> 0.000000, 20.00000000, 40.00000000, 60.00000000, |
> 80.000000, 99.76135361, 118.20539617, 134.31393926, |
> 147.363569, 156.89207458, 162.66610500, 164.65005734, |
> 162.976193, 157.91598604, 149.85269630, 139.25517858, |
> 126.652916, 112.61228878, 97.71406290, 82.53212096, |
> 67.613413, 53.45914240, 40.50717678, 29.11569385, |
> 19.548052, 11.95889791, 6.38148911, 2.71626545, |
> .720635, 0.00000000, 0.00000000, 0.00000000/ |
DATA BK31/ |
> 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, |
> 0.0000000000, 0.0003908582, 0.0029197006, 0.0091941320, |
> 0.0203191555, 0.0369748598, 0.0594876397, 0.0878949492, |
> 0.1220035886, 0.1614415235, 0.2057032385, 0.2541886223, |
> 0.3062353873, 0.3611450218, 0.4182022749, 0.4766881754, |
> 0.5358865832, 0.5950842740, 0.6535645569, 0.7105944258, |
> 0.7654052430, 0.8171669567, 0.8649558510, 0.9077158297, |
> 0.9442132326, 0.9729851852, 0.9922814815, 1.0000000000/ |
C Modell level specification for 50 level version |
DATA AK50/ |
> 0.0000, .200061, .432978, |
> .753462, 1.150821, 1.618974, 2.158969, |
> 2.780058, 3.501381, 4.355622, 5.396513, |
> 6.686154, 8.283989, 10.263669, 12.716445, |
> 15.755378, 19.520544, 24.185498, 29.965266, |
> 37.126262, 45.998554, 56.991132, 69.983867, |
> 85.074101, 101.817070, 118.830898, 134.429140, |
> 147.363554, 156.892070, 162.666093, 164.650039, |
> 162.976210, 157.915976, 149.852695, 139.255195, |
> 126.652968, 112.612304, 97.714062, 82.532109, |
> 67.613398, 53.459179, 40.507187, 29.115703, |
> 19.548046, 11.958906, 6.381484, 2.716250, |
> .720625, 0.000000, 0.000000, 0.000000/ |
DATA BK50/ |
> 0.0000000000, 0.0000000000, 0.0000000000, |
> 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, |
> 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, |
> 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, |
> 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, |
> 0.0000000000, 0.0000000000, 0.0000000000, 0.0000000000, |
> 0.0001003604, 0.0006727143, 0.0031633405, 0.0092923380, |
> 0.0203191563, 0.0369748585, 0.0594876409, 0.0878949761, |
> 0.1220036149, 0.1614415050, 0.2057032585, 0.2541885972, |
> 0.3062353730, 0.3611450195, 0.4182022810, 0.4766881466, |
> 0.5358865857, 0.5950842500, 0.6535645723, 0.7105944157, |
> 0.7654052377, 0.8171669841, 0.8649558425, 0.9077158570, |
> 0.9442132115, 0.9729852080, 0.9922814965, 1.0000000000/ |
do k=1,nlev |
if (nlev.eq.19) then |
aklay(k)=(ak19(nlev+2-k)+ak19(nlev+1-k))/2. ! layi=(levi+levi+1)/2 |
bklay(k)=(bk19(nlev+2-k)+bk19(nlev+1-k))/2. |
aklev(k)=ak19(nlev+1-k) ! reverse order of coeffs for IVE |
bklev(k)=bk19(nlev+1-k) |
elseif (nlev.eq.31) then |
aklay(k)=(ak31(nlev+2-k)+ak31(nlev+1-k))/2. ! layi=(levi+levi+1)/2 |
bklay(k)=(bk31(nlev+2-k)+bk31(nlev+1-k))/2. |
aklev(k)=ak31(nlev+1-k) ! reverse order of coeffs for IVE |
bklev(k)=bk31(nlev+1-k) |
elseif (nlev.eq.50) then |
aklay(k)=(ak50(nlev+2-k)+ak50(nlev+1-k))/2. ! layi=(levi+levi+1)/2 |
bklay(k)=(bk50(nlev+2-k)+bk50(nlev+1-k))/2. |
aklev(k)=ak50(nlev+1-k) ! reverse order of coeffs for IVE |
bklev(k)=bk50(nlev+1-k) |
else |
stop'*** invalid number of modellevels ***' |
endif |
enddo |
if (nlev.eq.19) then |
aklay(nlev+1)=ak19(1)/2. |
bklay(nlev+1)=bk19(1)/2. |
aklev(nlev+1)=ak19(1) |
bklev(nlev+1)=bk19(1) |
elseif (nlev.eq.31) then |
aklay(nlev+1)=ak31(1)/2. |
bklay(nlev+1)=bk31(1)/2. |
aklev(nlev+1)=ak31(1) |
bklev(nlev+1)=bk31(1) |
elseif (nlev.eq.50) then |
aklay(nlev+1)=ak50(1)/2. |
bklay(nlev+1)=bk50(1)/2. |
aklev(nlev+1)=ak50(1) |
bklev(nlev+1)=bk50(1) |
else |
stop'*** invalid number of modellevels ***' |
endif |
* print*,aklev(1),aklev(2),aklev(3),aklev(4),aklev(5),aklev(6) |
return |
end |
subroutine prelevs(nlev,level,aklev,bklev,aklay,bklay) |
C------------------------------------------------------------------------ |
C |
C Defines the (dummy-) ak- and bk-arrays given the array that |
C contains all pressure levels. |
C |
C nlev int input number of pressure levels |
C level real input pressure levels |
C aklev real output array contains ak values for levels |
C bklev real output array contains bk values for levels |
C aklay real output array contains ak values for layers |
C bklay real output array contains bk values for layers |
C------------------------------------------------------------------------ |
integer nlev,k |
real aklev(nlev),bklev(nlev), ! level coefficients |
> aklay(nlev),bklay(nlev), ! layer coefficients |
> level(nlev+1) |
do k=1,nlev |
aklay(k)=level(k) |
bklay(k)=0. |
if (nlev.eq.1) then |
aklev(k)=level(k) |
else |
aklev(k)=0.5*(level(k)+level(k+1)) |
endif |
bklev(k)=0. |
enddo |
return |
end |
subroutine cpp_cdfwopn(filnam,filnam_len,cdfid,ierr) |
C------------------------------------------------------------------------ |
C Purpose: |
C allows to call cdfopn from c++ |
C Arguments: |
C see crecdf |
C additionally: filnam_len, the length of the |
C string |
C |
C |
C History: |
C 981221 Mark A. Liniger ETHZ |
C |
C Note: |
C |
C |
C------------------------------------------------------------------------ |
integer filnam_len,cdfid,ierr |
character *(*) filnam |
call cdfwopn(filnam(1:filnam_len),cdfid,ierr) |
end |
subroutine getdim (cdfid, varnam, nx, ny, nz, error) |
c------------------------------------------------------------------------- |
c Purpose: |
c This routine is called to get the dimensions of |
c a variable from an IVE-NetCDF file for use with the IVE plotting |
c package. Prior to calling this routine, the file must be opened |
c with a call to opncdf. |
c Arguments: |
c cdfid int input file-identifier |
c (can be obtained by calling routine |
c opncdf) |
c varnam char input the user-supplied variable name. |
c (can be obtained by calling routine |
c opncdf) |
c nx int output the zonal dimension of the variable. |
c ny int output the meridional dimension of the variable. |
c nz int output the vertical dimension of the variable. |
c |
c error int output indicates possible errors found in this |
c routine. |
c error = 0 no errors detected. |
c error = 1 the variable is not on the file. |
c error =10 other errors. |
c History: |
c March 2000 Heini Wernli (ETHZ) Created. |
c----------------------------------------------------------------------- |
include "netcdf.inc" |
c Argument declarations. |
character *(*) varnam |
integer vardim(4), ndim, error, cdfid |
integer nx,ny,nz |
c Local variable declarations. |
character *(20) dimnam(MAXNCDIM),vnam |
integer id,i,k |
integer ndims,nvars,ngatts,recdim,dimsiz(MAXNCDIM) |
integer vartyp,nvatts, ncopts |
c Get current value of error options. |
call ncgopt (ncopts) |
c make sure NetCDF-errors do not abort execution |
call ncpopt(NCVERBOS) |
c Initially set error to indicate no errors. |
error = 0 |
c inquire for number of dimensions |
call ncinq(cdfid,ndims,nvars,ngatts,recdim,error) |
if (error.eq.1) goto 920 |
c read dimension-table |
do i=1,ndims |
call ncdinq(cdfid,i,dimnam(i),dimsiz(i),error) |
if (error.gt.0) goto 920 |
enddo |
c get id of the variable |
id=ncvid(cdfid,varnam,error) |
if (error.eq.1) goto 910 |
c inquire about variable |
call ncvinq(cdfid,id,vnam,vartyp,ndim,vardim,nvatts,error) |
if (vartyp.ne.NCFLOAT) error=1 |
if (error.gt.0) goto 920 |
c get dimensions from dimension-table |
do k=1,ndim |
vardim(k)=dimsiz(vardim(k)) |
enddo |
nx=vardim(1) |
ny=vardim(2) |
nz=vardim(3) |
c normal exit |
call ncpopt (ncopts) |
return |
c Error exits. |
910 write (6, *) '*ERROR*: The selected variable could not be found ', |
& 'in the file by getdim.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
return |
920 write (6, *) '*ERROR*: An error occurred while attempting to ', |
& 'read the data file in subroutine getcdf.' |
call ncpopt (ncopts) |
call ncclos (cdfid, error) |
end |
subroutine rvarfile(vnam,gribnr,levty,unit,factor,bias, |
> lnum,stg,tdep,p,lval,varcnt,ierr) |
C ======================================================= |
C Variablen-File in Arrays einlesen |
integer maxvar |
parameter(maxvar=100) |
character*(15) vnam(maxvar) |
character*(13) unit(maxvar) |
character*(1) flag |
integer gribnr(maxvar),levty(maxvar),lnum(maxvar), |
> stg(maxvar),tdep(maxvar),p(maxvar),lval(maxvar) |
real factor(maxvar),bias(maxvar) |
integer i,varcnt,ierr,nt |
nt=14 ! number of tape |
i=1 ! initialize var-counter |
C Read first character of row and decide if it is comment or not |
100 read(nt,10,err=123,end=126) flag |
if (flag.eq."#") goto 100 ! don't bother about comments |
backspace nt |
121 read(nt,122, err=123, end=126) vnam(i), gribnr(i), levty(i), |
& unit(i), factor(i), bias(i), lnum(i), stg(i), tdep(i), p(i), |
& lval(i) |
i=i+1 |
* goto 100 |
goto 121 |
10 format(a1) |
122 format(a14,i3,i11,a17,f7.5,f9.2,i7,i4,i6,i3,i5) |
* 123 print *,'*ERROR* in subroutine rvarfile' |
123 goto 121 |
126 continue |
varcnt=i-1 ! # of variables in varfile_i |
C Check some things |
ierr=0 ! initialize error flag |
do i=1,varcnt |
if ((lnum(i).ne.1).and.(lnum(i).ne.2).and.(lnum(i).ne.3) |
> .and.(lnum(i).ne.4)) ierr=11 |
if ((stg(i).ne.0).and.(stg(i).ne.1).and.(stg(i).ne.10).and. |
> (stg(i).ne.11)) ierr=12 |
if ((tdep(i).ne.0).and.(tdep(i).ne.1)) ierr=13 |
if ((p(i).ne.0).and.(p(i).ne.1).and.(p(i).ne.2)) ierr=14 |
if ((lval(i).lt.0).or.(lval(i).gt.1050)) ierr=15 |
enddo |
return |
end |
/tags/1.0/lib/times.f |
---|
0,0 → 1,296 |
c ************************************************************************** |
c * This library provides subroutines related to time and file name * |
c * handling * |
c * * |
c ************************************************************************** |
c --------------------------------------------------------------------------- |
c Concatenate a date string |
c --------------------------------------------------------------------------- |
subroutine datestring(datestr,yyyy,mm,dd,hh) |
c Declaration of subroutine parameters |
integer yyyy,mm,dd,hh |
character*20 datestr |
c Auxiliary parameters |
integer f1,f2,i0 |
integer yy,ce |
i0=ichar('0') |
datestr='' |
yy=mod(yyyy,100) |
ce=int(yyyy/100) |
if ((ce.ne.19).and.(ce.ne.20).and.(ce.ne.18)) then |
print*,'Invalid century... Stop' |
stop |
endif |
if (yy.ge.0) then |
f1=yy/10 |
f2=mod(yy,10) |
if (ce.eq.18) then |
datestr=trim(datestr)//'18'//char(f1+i0)//char(f2+i0) |
else if (ce.eq.19) then |
datestr=trim(datestr)//'19'//char(f1+i0)//char(f2+i0) |
else if (ce.eq.20) then |
datestr=trim(datestr)//'20'//char(f1+i0)//char(f2+i0) |
endif |
endif |
if (mm.gt.0) then |
f1=mm/10 |
f2=mod(mm,10) |
datestr=trim(datestr)//char(f1+i0)//char(f2+i0) |
endif |
if (dd.gt.0) then |
f1=dd/10 |
f2=mod(dd,10) |
datestr=trim(datestr)//char(f1+i0)//char(f2+i0) |
endif |
if (hh.ge.0) then |
f1=hh/10 |
f2=mod(hh,10) |
datestr=trim(datestr)//'_'//char(f1+i0)//char(f2+i0) |
endif |
return |
end |
c --------------------------------------------------------------------------- |
c Calculates the new date when diff (in hours) is added to date1. |
c --------------------------------------------------------------------------- |
subroutine newdate(date1,diff,date2) |
C |
C date1 int input array contains a date in the form |
C year,month,day,hour,step |
C diff real input timestep in hours to go from date1 |
C date2 int output array contains new date in the same form |
integer date1(5),date2(5) |
integer idays(12) ! array containing the days of the monthes |
real diff |
logical yearchange |
data idays/31,28,31,30,31,30,31,31,30,31,30,31/ |
yearchange=.false. |
if ((mod(date1(1),4).eq.0).and.(date1(2).le.2)) idays(2)=29 |
date2(1)=date1(1) |
date2(2)=date1(2) |
date2(3)=date1(3) |
date2(4)=date1(4) |
date2(5)=0 |
date2(4)=date1(4)+int(diff)+date1(5) |
if (date2(4).ge.24) then |
date2(3)=date2(3)+int(date2(4)/24) |
date2(4)=date2(4)-int(date2(4)/24)*24 |
endif |
if (date2(4).lt.0) then |
if (mod(date2(4),24).eq.0) then |
date2(3)=date2(3)-int(abs(date2(4))/24) |
date2(4)=date2(4)+int(abs(date2(4))/24)*24 |
else |
date2(3)=date2(3)-(1+int(abs(date2(4))/24)) |
date2(4)=date2(4)+(1+int(abs(date2(4))/24))*24 |
endif |
endif |
100 if (date2(3).gt.idays(date2(2))) then |
if ((date2(2).eq.2).and.(mod(date2(1),4).eq.0)) idays(2)=29 |
date2(3)=date2(3)-idays(date2(2)) |
if (idays(2).eq.29) idays(2)=28 |
date2(2)=date2(2)+1 |
if (date2(2).gt.12) then |
* date2(1)=date2(1)+int(date2(2)/12) |
* date2(2)=date2(2)-int(date2(2)/12)*12 |
date2(1)=date2(1)+1 |
date2(2)=date2(2)-12 |
endif |
if (date2(2).lt.1) then |
date2(1)=date2(1)-(1+int(abs(date2(2)/12))) |
date2(2)=date2(2)+(1+int(abs(date2(2)/12)))*12 |
endif |
goto 100 |
endif |
200 if (date2(3).lt.1) then |
date2(2)=date2(2)-1 |
if (date2(2).gt.12) then |
date2(1)=date2(1)+int(date2(2)/12) |
date2(2)=date2(2)-int(date2(2)/12)*12 |
endif |
if (date2(2).lt.1) then |
date2(1)=date2(1)-(1+int(abs(date2(2)/12))) |
date2(2)=date2(2)+(1+int(abs(date2(2)/12)))*12 |
endif |
if ((date2(2).eq.2).and.(mod(date2(1),4).eq.0)) idays(2)=29 |
date2(3)=date2(3)+idays(date2(2)) |
if (idays(2).eq.29) idays(2)=28 |
goto 200 |
endif |
if (date2(2).gt.12) then |
date2(1)=date2(1)+int(date2(2)/12) |
date2(2)=date2(2)-int(date2(2)/12)*12 |
endif |
if (date2(2).lt.1) then |
date2(1)=date2(1)-(1+int(abs(date2(2)/12))) |
date2(2)=date2(2)+(1+int(abs(date2(2)/12)))*12 |
endif |
if (date2(1).lt.1000) then |
if (date2(1).ge.100) date2(1)=date2(1)-100 |
endif |
return |
end |
c --------------------------------------------------------------------------- |
c Convert <hh.mm> -> <frac> and <frac> -> <hhmm> |
c --------------------------------------------------------------------------- |
subroutine hhmm2frac (hhmm,frac) |
real hhmm |
real frac |
frac=real(int(hhmm))+ |
> 100.*(hhmm-real(int(hhmm)))/60. |
end |
subroutine frac2hhmm (frac,hhmm) |
real hhmm |
real frac |
real hh,mm |
hh = real(int(frac)) |
mm = 60. * (frac-real(int(frac))) |
hhmm = hh + 0.01 * mm |
end |
c --------------------------------------------------------------------------- |
c Time difference between two dates |
c --------------------------------------------------------------------------- |
subroutine timediff(date1,date2,diff) |
C New version with hour and minutes! (for hour and step [in hours] |
C use the routine oldtimediff!) |
C |
C Calculates the time difference in hours (and minutes) for the two |
C dates specified by the two arrays date1 and date2. |
C They are expected to contain the following date information: |
C year month day hour minute. |
C |
C date1 array specifying the first date |
C date2 array specifying the second date |
C diff time differenc between date1 and date2 in hours |
C |
integer date1(5),date2(5) |
integer idays(12) ! array containing the days of the monthes |
real diff |
integer ixday,imdiff,ihdiff,iddiff,j |
integer yy,yy1,yy2 |
idays(1)=31 |
idays(2)=28 |
idays(3)=31 |
idays(4)=30 |
idays(5)=31 |
idays(6)=30 |
idays(7)=31 |
idays(8)=31 |
idays(9)=30 |
idays(10)=31 |
idays(11)=30 |
idays(12)=31 |
C Check format of year (YYYY or YY - in case of YY assume 19YY) |
if (date1(1).lt.100) date1(1)=1900+date1(1) |
if (date2(1).lt.100) date2(1)=1900+date2(1) |
C Determine if the period between date1 and date2 contains a Feb.29 |
ixday=0 ! extra day flag |
yy1=min(date1(1),date2(1)) |
yy2=max(date1(1),date2(1)) |
if (yy1.eq.yy2) then |
if (mod(yy1,4).eq.0) then |
idays(2)=29 |
endif |
else |
if (mod(yy1,4).eq.0) then |
if (((yy1.eq.date1(1)).and.(date1(2).le.2)).or. |
> ((yy1.eq.date2(1)).and.(date2(2).le.2))) then |
ixday=ixday+1 |
endif |
endif |
if (mod(yy2,4).eq.0) then |
if (((yy2.eq.date1(1)).and.(date1(2).gt.2)).or. |
> ((yy2.eq.date2(1)).and.(date2(2).gt.2))) then |
ixday=ixday+1 |
endif |
endif |
if (yy2-yy1.gt.1) then |
do yy=yy1+1,yy2-1 |
if (mod(yy,4).eq.0) then |
ixday=ixday+1 |
endif |
enddo |
endif |
endif |
ihdiff=0 ! diff. in hours between date1/date2 |
iddiff=0 ! diff. in days between date1/date2 |
if (date1(1).gt.date2(1)) then ! compare years |
do j=date2(1),date1(1)-1 |
iddiff=iddiff+365 |
enddo |
iddiff=iddiff+ixday |
else if (date1(1).lt.date2(1)) then |
do j=date1(1),date2(1)-1 |
iddiff=iddiff-365 |
enddo |
iddiff=iddiff-ixday |
endif |
if (date1(2).gt.date2(2)) then ! compare monthes |
do j=date2(2),date1(2)-1 |
iddiff=iddiff+idays(j) |
enddo |
else if (date1(2).lt.date2(2)) then |
do j=date1(2),date2(2)-1 |
iddiff=iddiff-idays(j) |
enddo |
endif |
iddiff=iddiff+date1(3)-date2(3) |
ihdiff=iddiff*24+date1(4)-date2(4) |
imdiff=ihdiff*60+date1(5)-date2(5) |
ihdiff=imdiff/60 |
imdiff=mod(imdiff,60) |
diff=real(ihdiff)+real(imdiff)/100. |
return |
end |
/tags/1.0/lidar/lidar.f |
---|
0,0 → 1,1350 |
PROGRAM trace |
C ******************************************************************** |
C * * |
C * Pseudo-lidar plots along trajectories * |
C * * |
C * Heini Wernli first version: April 1993 * |
C * Michael Sprenger major upgrade: 2008-2009 * |
C * * |
C ******************************************************************** |
implicit none |
c -------------------------------------------------------------------- |
c Declaration of parameters |
c -------------------------------------------------------------------- |
c Maximum number of levels for input files |
integer nlevmax |
parameter (nlevmax=100) |
c Maximum number of input files (dates, length of trajectories) |
integer ndatmax |
parameter (ndatmax=500) |
c Numerical epsilon (for float comparison) |
real eps |
parameter (eps=0.001) |
c Conversion factors |
real pi180 ! deg -> rad |
parameter (pi180=3.14159/180.) |
real deg2km ! deg -> km (at equator) |
parameter (deg2km=111.) |
c Prefix for primary and secondary fields |
character charp |
character chars |
parameter (charp='P') |
parameter (chars='S') |
c -------------------------------------------------------------------- |
c Declaration of variables |
c -------------------------------------------------------------------- |
c Input and output format for trajectories (see iotra.f) |
integer inpmode |
c Input parameters |
character*80 inpfile ! Input trajectory file |
character*80 outfile ! Output netCDF file |
character*80 outmode ! Output mode (sum,mean) |
integer ntra ! Number of trajectories |
integer ncol ! Number of columns (including time, lon, lat, p) |
integer ntim ! Number of times per trajectory |
integer ntrace0 ! Number of trace variables |
character*80 tvar(200) ! Tracing variable name (only the variable) |
character*1 tfil(200) ! Filename prefix |
real fac(200) ! Scaling factor |
integer compfl(200) ! Computation flag (1=compute) |
integer numdat ! Number of input files |
character*11 dat(ndatmax) ! Dates of input files |
real timeinc ! Time increment between input files |
real tst ! Time shift of start relative to first data file |
real ten ! Time shift of end relatiev to first data file |
character*20 startdate ! First time/date on trajectory |
character*20 enddate ! Last time/date on trajectory |
character*80 timecheck ! Either 'yes' or 'no' |
character*80 intmode ! Interpolation mode ('normal', 'nearest') |
real pmin,pmax ! Pressure range for output grid |
integer npre ! Number of pressure levels in output grid |
character*80 centering ! Centering around trajectory position ('yes','no') |
character*80 direction ! Direction of lidar (vertical,lat,lon,normal) |
character*80 dumpcoord ! Dumping coordinates ('yes','no') |
c Trajectories |
real,allocatable, dimension (:,:,:) :: trainp ! Input trajectories (ntra,ntim,ncol) |
integer reftime(6) ! Reference date |
character*80 varsinp(100) ! Field names for input trajectory |
integer fid,fod ! File identifier for inp and out trajectories |
real x0_tra,y0_tra,p0_tra ! Position of air parcel (physical space) |
real reltpos0 ! Relative time of air parcel |
real xind,yind,pind ! Position of air parcel (grid space) |
integer fbflag ! Flag for forward (1) or backward (-1) trajectories |
c Meteorological fields from input file |
real,allocatable, dimension (:) :: spt0,spt1 ! Surface pressure |
real,allocatable, dimension (:) :: p3t0,p3t1 ! 3d-pressure |
real,allocatable, dimension (:) :: f3t0,f3t1 ! 3d field for tracing |
character*80 svars(100) ! List of variables on S file |
character*80 pvars(100) ! List of variables on P file |
integer n_svars ! Number of variables on S file |
integer n_pvars ! Number of variables on P file |
c Input grid description |
real pollon,pollat ! Longitude/latitude of pole |
real ak(100) ! Vertical layers and levels |
real bk(100) |
real xmin,xmax ! Zonal grid extension |
real ymin,ymax ! Meridional grid extension |
integer nx,ny,nz ! Grid dimensions |
real dx,dy ! Horizontal grid resolution |
integer hem ! Flag for hemispheric domain |
integer per ! Flag for periodic domain |
real stagz ! Vertical staggering |
real mdv ! Missing data value |
c Output grid and fields |
real levels(1000) ! Ouput levels |
real times (1000) ! Output times |
real,allocatable, dimension (:,:) :: out_pos ! Position of trajectories |
real,allocatable, dimension (:,:) :: out_val ! Output lidar field |
real,allocatable, dimension (:,:) :: out_cnt ! # output lidar sum ups |
c Auxiliary variables |
integer i,j,k,l,n |
real rd |
character*80 filename |
real time0,time1,reltpos |
integer itime0,itime1 |
integer stat |
real tstart |
integer iloaded0,iloaded1 |
real f0 |
real frac |
real tload,tfrac |
integer isok |
character ch |
integer ind |
integer ind1,ind2,ind3,ind4,ind5 |
integer ind6,ind7,ind8,ind9,ind0 |
integer noutside |
real delta |
integer itrace0 |
character*80 string |
character*80 cdfname |
character*80 varname |
real time |
character*80 longname |
character*80 unit |
integer ind_time |
integer ind_pre |
real rlat,rlon |
real x0,y0,p0 |
real vx0,vy0,vx1,vy1 |
real rotation,lon,lat |
c Externals |
real int_index4 |
external int_index4 |
c -------------------------------------------------------------------- |
c Start of program, Read parameters, get grid parameters |
c -------------------------------------------------------------------- |
c Write start message |
print*,'=========================================================' |
print*,' *** START OF PROGRAM LIDAR ***' |
print* |
c Read parameters |
open(10,file='trace.param') |
read(10,*) inpfile |
read(10,*) outfile |
read(10,*) outmode |
read(10,*) startdate |
read(10,*) enddate |
read(10,*) fbflag |
read(10,*) numdat |
if ( fbflag.eq.1) then |
do i=1,numdat |
read(10,'(a11)') dat(i) |
enddo |
else |
do i=numdat,1,-1 |
read(10,'(a11)') dat(i) |
enddo |
endif |
read(10,*) timeinc |
read(10,*) tst |
read(10,*) ten |
read(10,*) ntra |
read(10,*) ntim |
read(10,*) ncol |
read(10,*) ntrace0 |
do i=1,ntrace0 |
read(10,*) tvar(i), fac(i), compfl(i), tfil(i) |
enddo |
read(10,*) n_pvars |
do i=1,n_pvars |
read(10,*) pvars(i) |
enddo |
read(10,*) n_svars |
do i=1,n_svars |
read(10,*) svars(i) |
enddo |
read(10,*) timecheck |
read(10,*) intmode |
read(10,*) pmin,pmax,npre |
read(10,*) centering |
read(10,*) direction |
read(10,*) dumpcoord |
close(10) |
c Check that the direction is ok |
if ( ( direction.ne.'vertical' ).and. |
> ( direction.ne.'lat' ).and. |
> ( direction.ne.'lon' ).and. |
> ( direction.ne.'normal' ) ) |
>then |
print*,' ERROR: invalid direction ',trim(direction) |
stop |
endif |
c Remove commented tracing fields |
itrace0 = 1 |
do while ( itrace0.le.ntrace0) |
string = tvar(itrace0) |
if ( string(1:1).eq.'#' ) then |
do i=itrace0,ntrace0-1 |
tvar(i) = tvar(i+1) |
fac(i) = fac(i+1) |
compfl(i) = compfl(i+1) |
tfil(i) = tfil(i+1) |
enddo |
ntrace0 = ntrace0 - 1 |
else |
itrace0 = itrace0 + 1 |
endif |
enddo |
c Set the formats of the input files |
call mode_tra(inpmode,inpfile) |
if (inpmode.eq.-1) inpmode=1 |
C Convert time shifts <tst,ten> from <hh.mm> into fractional time |
call hhmm2frac(tst,frac) |
tst = frac |
call hhmm2frac(ten,frac) |
ten = frac |
c Set the time for the first data file (depending on forward/backward mode) |
if (fbflag.eq.1) then |
tstart = -tst |
else |
tstart = tst |
endif |
c Read the constant grid parameters (nx,ny,nz,xmin,xmax,ymin,ymax,pollon,pollat) |
c The negative <-fid> of the file identifier is used as a flag for parameter retrieval |
filename = charp//dat(1) |
varname = 'U' |
call input_open (fid,filename) |
call input_grid (-fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tstart,pollon,pollat,rd,rd,nz,rd,rd,rd,timecheck) |
call input_close(fid) |
C Allocate memory for some meteorological arrays |
allocate(spt0(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array spt0 ***' ! Surface pressure |
allocate(spt1(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array spt1 ***' |
allocate(p3t0(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t0 ***' ! Pressure |
allocate(p3t1(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t1 ***' |
allocate(f3t0(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t0 ***' ! Lidar field |
allocate(f3t1(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t1 ***' |
c Allocate memory for output field |
allocate(out_pos(ntim,npre),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array out_pos ***' |
allocate(out_val(ntim,npre),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array out_val ***' |
allocate(out_cnt(ntim,npre),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array out_cnt ***' |
C Get memory for trajectory arrays |
allocate(trainp(ntra,ntim,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra ***' |
c Set the flags for periodic domains |
if ( abs(xmax-xmin-360.).lt.eps ) then |
per = 1 |
elseif ( abs(xmax-xmin-360.+dx).lt.eps ) then |
per = 2 |
else |
per = 0 |
endif |
C Set logical flag for periodic data set (hemispheric or not) |
hem = 0 |
if (per.eq.0.) then |
delta=xmax-xmin-360. |
if (abs(delta+dx).lt.eps) then ! Program aborts: arrays must be closed |
print*,' ERROR: arrays must be closed... Stop' |
else if (abs(delta).lt.eps) then ! Periodic and hemispheric |
hem=1 |
per=360. |
endif |
else ! Periodic and hemispheric |
hem=1 |
endif |
c Write some status information |
print*,'---- INPUT PARAMETERS -----------------------------------' |
print* |
print*,' Input trajectory file : ',trim(inpfile) |
print*,' Format of input file : ',inpmode |
print*,' Output netCDF file : ',trim(outfile) |
print*,' Format of output file : ',trim(outmode) |
print*,' Forward/backward : ',fbflag |
print*,' #tra : ',ntra |
print*,' #col : ',ncol |
print*,' #tim : ',ntim |
print*,' No time check : ',trim(timecheck) |
print*,' Interpolation mode : ',trim(intmode) |
do i=1,ntrace0 |
if (compfl(i).eq.0) then |
print*,' Tracing field : ', |
> trim(tvar(i)), fac(i), ' 0 ', tfil(i) |
else |
print*,' Tracing field : ', |
> trim(tvar(i)),' : online calc not supported' |
endif |
enddo |
print*,' Output (pmin,pmax,n) : ',pmin,pmax,npre |
print*,' Centering : ',trim(centering) |
print*,' Orientation : ',trim(direction) |
print*,' Coordinate Dump : ',trim(dumpcoord) |
print* |
print*,'---- INPUT DATA FILES -----------------------------------' |
print* |
call frac2hhmm(tstart,tload) |
print*,' Time of 1st data file : ',tload |
print*,' #input files : ',numdat |
print*,' time increment : ',timeinc |
call frac2hhmm(tst,tload) |
print*,' Shift of start : ',tload |
call frac2hhmm(ten,tload) |
print*,' Shift of end : ',tload |
print*,' First/last input file : ',trim(dat(1)), |
> ' ... ', |
> trim(dat(numdat)) |
print*,' Primary variables : ',trim(pvars(1)) |
do i=2,n_pvars |
print*,' : ',trim(pvars(i)) |
enddo |
if ( n_svars.ge.1 ) then |
print*,' Secondary variables : ',trim(svars(1)) |
do i=2,n_svars |
print*,' : ',trim(svars(i)) |
enddo |
endif |
print* |
print*,'---- CONSTANT GRID PARAMETERS ---------------------------' |
print* |
print*,' xmin,xmax : ',xmin,xmax |
print*,' ymin,ymax : ',ymin,ymax |
print*,' dx,dy : ',dx,dy |
print*,' pollon,pollat : ',pollon,pollat |
print*,' nx,ny,nz : ',nx,ny,nz |
print*,' per, hem : ',per,hem |
print* |
c -------------------------------------------------------------------- |
c Load the input trajectories |
c -------------------------------------------------------------------- |
c Read the input trajectory file |
call ropen_tra(fid,inpfile,ntra,ntim,ncol,reftime,varsinp,inpmode) |
call read_tra (fid,trainp,ntra,ntim,ncol,inpmode) |
call close_tra(fid,inpmode) |
c Check that first four columns correspond to time,lon,lat,p |
if ( (varsinp(1).ne.'time' ).or. |
> (varsinp(2).ne.'xpos' ).and.(varsinp(2).ne.'lon' ).or. |
> (varsinp(3).ne.'ypos' ).and.(varsinp(3).ne.'lat' ).or. |
> (varsinp(4).ne.'ppos' ).and.(varsinp(4).ne.'p' ) ) |
>then |
print*,' ERROR: problem with input trajectories ...' |
stop |
endif |
varsinp(1) = 'time' |
varsinp(2) = 'lon' |
varsinp(3) = 'lat' |
varsinp(4) = 'p' |
c Write some status information of the input trajectories |
print*,'---- INPUT TRAJECTORIES ---------------------------------' |
print* |
print*,' Start date : ',trim(startdate) |
print*,' End date : ',trim(enddate) |
print*,' Reference time (year) : ',reftime(1) |
print*,' (month) : ',reftime(2) |
print*,' (day) : ',reftime(3) |
print*,' (hour) : ',reftime(4) |
print*,' (min) : ',reftime(5) |
print*,' Time range (min) : ',reftime(6) |
do i=1,ncol |
print*,' Var :',i,trim(varsinp(i)) |
enddo |
print* |
c Check that first time is 0 - otherwise the tracing will produce |
c wrong results because later in the code only absolute times are |
c considered: <itime0 = int(abs(tfrac-tstart)/timeinc) + 1>. This |
c will be changed in a future version. |
if ( abs( trainp(1,1,1) ).gt.eps ) then |
print*,' ERROR: First time of trajectory must be 0, i.e. ' |
print*,' correspond to the reference date. Otherwise' |
print*,' the tracing will give wrong results... STOP' |
stop |
endif |
c If requested, open the coordinate dump file |
if ( dumpcoord.eq.'yes' ) then |
open(10,file=trim(outfile)//'.coord') |
endif |
c -------------------------------------------------------------------- |
c Trace the fields (fields available on input files) |
c -------------------------------------------------------------------- |
print* |
print*,'---- LIDAR FROM PRIMARY AND SECONDARY DATA FILES ------' |
c Loop over all tracing fields |
do i=1,ntrace0 |
c Skip all fields marked for online calculation |
if ( compfl(i).eq.1 ) goto 110 |
c Init the output fields: position and lidar field |
do k=1,ntim |
do l=1,npre |
out_pos(k,l) = 0. |
out_val(k,l) = 0. |
out_cnt(k,l) = 0. |
enddo |
enddo |
c Write some status information |
print* |
print*,' Now lidaring : ', |
> trim(tvar(i)),compfl(i),' ',trim(tfil(i)) |
c Reset flags for load manager |
iloaded0 = -1 |
iloaded1 = -1 |
c Reset the counter for fields outside domain |
noutside = 0 |
c Loop over all times |
do j=1,ntim |
c Convert trajectory time from hh.mm to fractional time |
call hhmm2frac(trainp(1,j,1),tfrac) |
c Get the times which are needed |
itime0 = int(abs(tfrac-tstart)/timeinc) + 1 |
time0 = tstart + fbflag * real(itime0-1) * timeinc |
itime1 = itime0 + 1 |
time1 = time0 + fbflag * timeinc |
if ( itime1.gt.numdat ) then |
itime1 = itime0 |
time1 = time0 |
endif |
c Load manager: Check whether itime0 can be copied from itime1 |
if ( itime0.eq.iloaded1 ) then |
f3t0 = f3t1 |
p3t0 = p3t1 |
spt0 = spt1 |
iloaded0 = itime0 |
endif |
c Load manager: Check whether itime1 can be copied from itime0 |
if ( itime1.eq.iloaded0 ) then |
f3t1 = f3t0 |
p3t1 = p3t0 |
spt1 = spt0 |
iloaded1 = itime1 |
endif |
c Load manager: Load first time (tracing variable and grid) |
if ( itime0.ne.iloaded0 ) then |
filename = tfil(i)//dat(itime0) |
call frac2hhmm(time0,tload) |
varname = tvar(i) |
write(*,'(a23,a20,a3,a5,f7.2)') |
> ' -> loading : ', |
> trim(filename),' ',trim(varname),tload |
call input_open (fid,filename) |
call input_wind |
> (fid,varname,f3t0,tload,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_grid |
> (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tload,pollon,pollat,p3t0,spt0,nz,ak,bk,stagz, |
> timecheck) |
call input_close(fid) |
iloaded0 = itime0 |
endif |
c Load manager: Load second time (tracing variable and grid) |
if ( itime1.ne.iloaded1 ) then |
filename = tfil(i)//dat(itime1) |
call frac2hhmm(time1,tload) |
varname = tvar(i) |
write(*,'(a23,a20,a3,a5,f7.2)') |
> ' -> loading : ', |
> trim(filename),' ',trim(varname),tload |
call input_open (fid,filename) |
call input_wind |
> (fid,varname,f3t1,tload,stagz,mdv, |
> xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_grid |
> (fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, |
> tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz, |
> timecheck) |
call input_close(fid) |
iloaded1 = itime1 |
endif |
c Loop over all trajectories |
do k=1,ntra |
c Set the trajectory position |
x0_tra = trainp(k,j,2) ! Longitude |
y0_tra = trainp(k,j,3) ! Latitude |
p0_tra = trainp(k,j,4) ! Pressure |
c Get rotation angle - orient normal to trajectory |
if ( direction.eq.'normal' ) then |
vx0 = 1. |
vy0 = 0. |
if ( j.lt.ntim ) then |
lat = 0.5 * ( trainp(k,j,3) + trainp(k,j+1,3) ) |
vx1 = ( trainp(k,j+1,2) - trainp(k,j,2) ) * |
> cos( lat * pi180 ) |
vy1 = ( trainp(k,j+1,3) - trainp(k,j,3) ) |
else |
lat = 0.5 * ( trainp(k,j,3) + trainp(k,j-1,3) ) |
vx1 = ( trainp(k,j,2) - trainp(k,j-1,2) ) * |
> cos( lat * pi180 ) |
vy1 = ( trainp(k,j,3) - trainp(k,j-1,3) ) |
endif |
if ( vx1.gt.180 ) vx1 = vx1 - 360 |
if ( vx1.lt.-180 ) vx1 = vx1 + 360. |
call getangle (vx0,vy0,vx1,vy1,rotation) |
rotation = -rotation |
else |
rotation = 0. |
endif |
c Set the relative time |
call hhmm2frac(trainp(k,j,1),tfrac) |
reltpos0 = fbflag * (tfrac-time0)/timeinc |
c Loop over pressure profile (or other positions for horizontal mode) |
do l=1,npre |
c Vertical |
if ( direction.eq.'vertical' ) then |
x0 = x0_tra |
y0 = y0_tra |
p0 = pmin + real(l-1)/real(npre-1) * (pmax-pmin) |
if ( centering.eq.'yes' )then |
p0 = p0 + trainp(k,j,4) |
endif |
c Longitude |
elseif ( direction.eq.'lon' ) then |
x0 = pmin + real(l-1)/real(npre-1) * (pmax-pmin) |
y0 = y0_tra |
p0 = p0_tra |
if ( centering.eq.'yes' )then |
x0 = x0 + x0_tra |
endif |
c Latitude |
elseif ( direction.eq.'lat' ) then |
x0 = x0_tra |
y0 = pmin + real(l-1)/real(npre-1) * (pmax-pmin) |
p0 = p0_tra |
if ( centering.eq.'yes' )then |
y0 = y0 + y0_tra |
endif |
c Normal to trajerctory |
elseif ( direction.eq.'normal' ) then |
c Set the coordinate in the rotated system |
rlat = pmin + |
> real(l-1)/real(npre-1) * (pmax-pmin) |
rlon = 0. |
c Transform it back to geographical lon/lat |
call getenvir_b (x0_tra,y0_tra,rotation, |
> x0,y0,rlon,rlat,1) |
c Pressure unchanged |
p0 = p0_tra |
endif |
c Handle periodic boundaries in zonal direction |
if ( (x0.gt.xmax).and.(per.ne.0) ) x0 = x0 - 360. |
if ( (x0.lt.xmin).and.(per.ne.0) ) x0 = x0 + 360. |
c Handle pole problems for hemispheric data (taken from caltra.f) |
if ((hem.eq.1).and.(y0.gt.90.)) then |
y0=180.-y0 |
x0=x0+per/2. |
endif |
if ((hem.eq.1).and.(y0.lt.-90.)) then |
y0=-180.-y0 |
x0=x0+per/2. |
endif |
if (y0.gt.89.99) then |
y0=89.99 |
endif |
c If requested, dump the lidar coordinates |
if ( (dumpcoord.eq.'yes').and.(i.eq.1) ) then |
write(10,'(3f10.2)') x0,y0,trainp(k,j,1) |
write(10,'(3f10.2)') x0_tra,y0_tra,5. |
endif |
C Get the index where to interpolate (x0,y0,p0) |
if ( (abs(x0-mdv).gt.eps).and. |
> (abs(y0-mdv).gt.eps) ) |
> then |
call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0, |
> p3t0,p3t1,spt0,spt1,3, |
> nx,ny,nz,xmin,ymin,dx,dy,mdv) |
else |
xind = mdv |
yind = mdv |
pind = mdv |
endif |
c If requested, apply nearest-neighbor interpolation |
if ( intmode.eq.'nearest') then |
xind = real( nint(xind) ) |
yind = real( nint(yind) ) |
pind = real( nint(pind) ) |
if ( xind.lt.1. ) xind = 1. |
if ( xind.gt.nx ) xind = real(nx) |
if ( yind.lt.1. ) yind = 1. |
if ( yind.gt.ny ) yind = real(ny) |
if ( pind.lt.1. ) pind = 1. |
if ( pind.gt.nz ) pind = real(nz) |
endif |
c Do the interpolation: everthing is ok |
if ( (xind.ge.1.).and.(xind.le.real(nx)).and. |
> (yind.ge.1.).and.(yind.le.real(ny)).and. |
> (pind.ge.1.).and.(pind.le.real(nz)) ) |
> then |
f0 = int_index4(f3t0,f3t1,nx,ny,nz, |
> xind,yind,pind,reltpos0,mdv) |
c Set to missing data |
else |
f0 = mdv |
endif |
c Save result to output array |
if (abs(f0-mdv).gt.eps) then |
out_val(j,l) = out_val(j,l) + f0 * fac(i) |
out_cnt(j,l) = out_cnt(j,l) + 1. |
endif |
c End loop over all pressure levels |
enddo |
c Save output - time index |
ind_time = j |
c Save output - space index for 'no centering' |
if ( centering.eq.'no' ) then |
if ( direction.eq.'vertical') then |
ind_pre = nint( real(npre) * |
> ( (p0_tra - pmin)/(pmax-pmin) ) + 1.) |
elseif ( direction.eq.'lon') then |
ind_pre = nint( real(npre) * |
> ( (x0_tra - pmin)/(pmax-pmin) ) + 1.) |
elseif ( direction.eq.'lat') then |
ind_pre = nint( real(npre) * |
> ( (y0_tra - pmin)/(pmax-pmin) ) + 1.) |
endif |
c Save output - space index for 'centering' |
else |
ind_pre = nint( real(npre) * |
> ( (0. - pmin)/(pmax-pmin) ) + 1.) |
endif |
c Update the output array |
if ( (ind_time.ge.1).and.(ind_time.le.ntim).and. |
> (ind_pre .ge.1).and.(ind_pre .le.npre) ) |
> then |
out_pos(ind_time,ind_pre) = |
> out_pos(ind_time,ind_pre) + 1. |
endif |
c End loop over all trajectories |
enddo |
c End loop over all times |
enddo |
c Write the trajectory position to netCDF file - only once |
if ( i.eq.1 ) then |
cdfname = outfile |
varname = 'POSITION' |
longname = 'position of trajectory points' |
unit = 'none' |
time = 0. |
do k=1,npre |
levels(k) = pmin + real(k-1)/real(npre-1) * (pmax-pmin) |
enddo |
do k=1,ntim |
times(k) = trainp(1,k,1) |
enddo |
call writecdf2D_cf |
> (cdfname,varname,longname,unit,out_pos,time,levels, |
> times,npre,ntim,1,1,direction) |
endif |
c If no valid lidar count: set the field to missing data |
do k=1,ntim |
do l=1,npre |
if (abs(out_cnt(k,l)).lt.eps) then |
out_val(k,l) = mdv |
endif |
enddo |
enddo |
c If requested, calculate the mean of the lidar field |
if ( outmode.eq.'mean' ) then |
do k=1,ntim |
do l=1,npre |
if ( (abs(out_val(k,l)-mdv).gt.eps).and. |
> (abs(out_cnt(k,l) ).gt.0. ) ) |
> then |
out_val(k,l) = out_val(k,l) / out_cnt(k,l) |
endif |
enddo |
enddo |
endif |
c Write the lidar field and count |
cdfname = outfile |
if (outmode.eq.'sum' ) then |
varname = trim(tvar(i))//'_SUM' |
elseif (outmode.eq.'mean' ) then |
varname = trim(tvar(i))//'_MEAN' |
endif |
longname = 'sum over all '//trim(tvar(i))//' profiles' |
unit = 'not given' |
time = 0. |
call writecdf2D_cf |
> (cdfname,varname,longname,unit,out_val,time,levels, |
> times,npre,ntim,0,1,direction) |
cdfname = outfile |
varname = trim(tvar(i))//'_CNT' |
longname = 'counts of all '//trim(tvar(i))//' profiles' |
unit = 'not given' |
time = 0. |
call writecdf2D_cf |
> (cdfname,varname,longname,unit,out_cnt,time,levels, |
> times,npre,ntim,0,1,direction) |
c Exit point for loop over all tracing variables |
110 continue |
c End loop over all lidar variables |
enddo |
c -------------------------------------------------------------------- |
c Write output to netCDF file |
c -------------------------------------------------------------------- |
c Write status information |
print* |
print*,'---- WRITE OUTPUT LIDAR FIELDS --------------------------' |
print* |
c Close coord dump file |
print*,' LIDAR written to : ',trim(outfile) |
if ( dumpcoord.eq.'yes' ) then |
print*,' Coordinates dumped to : ',trim(outfile)//'.coord' |
endif |
c Write some status information, and end of program message |
print* |
print*,'---- STATUS INFORMATION --------------------------------' |
print* |
print*,' ok' |
print* |
print*,' *** END OF PROGRAM LIDAR ***' |
print*,'=========================================================' |
end |
c ******************************************************************** |
c * INPUT / OUTPUT SUBROUTINES * |
c ******************************************************************** |
c -------------------------------------------------------------------- |
c Subroutines to write 2D CF netcdf output file |
c -------------------------------------------------------------------- |
subroutine writecdf2D_cf |
> (cdfname,varname,longname,unit,arr,time,levels,times, |
> npre,ntim,crefile,crevar,direction) |
c Create and write to the CF netcdf file <cdfname>. The variable |
c with name <varname> and with time <time> is written. The data |
c are in the two-dimensional array <arr>. The flags <crefile> and |
c <crevar> determine whether the file and/or the variable should |
c be created. |
USE netcdf |
IMPLICIT NONE |
c Declaration of input parameters |
character*80 cdfname |
character*80 varname,longname,unit |
integer npre,ntim |
real arr(ntim,npre) |
real levels(npre) |
real times (ntim) |
real time |
integer crefile,crevar |
character*80 direction |
c Numerical epsilon |
real eps |
parameter (eps=1.e-5) |
c Local variables |
integer ierr |
integer ncID |
integer LevDimId, varLevID |
integer TimeDimID, varTimeID |
real timeindex |
integer i,j |
integer nvars,varids(100) |
integer ndims,dimids(100) |
real timelist(1000) |
integer ntimes |
integer ind |
integer varID |
c Quick an dirty solution for fieldname conflict |
if ( varname.eq.'time' ) varname = 'TIME' |
c Initially set error to indicate no errors. |
ierr = 0 |
c ---- Create the netCDF - skip if <crefile=0> ---------------------- |
if ( crefile.ne.1 ) goto 100 |
c Create the file |
ierr = nf90_create(trim(cdfname), NF90_CLOBBER, ncID) |
c Define dimensions |
ierr=nf90_def_dim(ncID,'level',npre, LevDimID ) |
ierr=nf90_def_dim(ncID,'time' ,ntim, TimeDimID) |
c Define space coordinate |
ierr = nf90_def_var(ncID,'level',NF90_FLOAT, |
> (/ LevDimID /),varLevID) |
if ( direction.eq.'vertical' ) then |
ierr = nf90_put_att(ncID, varLevID, "standard_name","level") |
ierr = nf90_put_att(ncID, varLevID, "units" ,"hPa") |
elseif ( direction.eq.'lat' ) then |
ierr = nf90_put_att(ncID, varLevID, "standard_name","latitude") |
ierr = nf90_put_att(ncID, varLevID, "units" ,"deg") |
elseif ( direction.eq.'lon' ) then |
ierr = nf90_put_att(ncID, varLevID, "standard_name","longitude") |
ierr = nf90_put_att(ncID, varLevID, "units" ,"deg") |
elseif ( direction.eq.'normal' ) then |
ierr = nf90_put_att(ncID, varLevID, "standard_name","normal") |
ierr = nf90_put_att(ncID, varLevID, "units" ,"deg") |
endif |
c Define time coordinate |
ierr = nf90_def_var(ncID,'time',NF90_FLOAT, |
> (/ TimeDimID /), varTimeID) |
ierr = nf90_put_att(ncID, varTimeID, "long_name", "time") |
ierr = nf90_put_att(ncID, varTimeID, "units", "hours") |
c Write global attributes |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'Conventions', 'CF-1.0') |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'title', |
> 'pseudo-lidar from trajectory file') |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'source', |
> 'Lagranto Trajectories') |
ierr = nf90_put_att(ncID, NF90_GLOBAL, 'institution', |
> 'ETH Zurich, IACETH') |
c Check whether the definition was successful |
ierr = nf90_enddef(ncID) |
if (ierr.gt.0) then |
print*, 'An error occurred while attempting to ', |
> 'finish definition mode.' |
stop |
endif |
c Write coordinate data |
ierr = nf90_put_var(ncID,varLevID ,levels) |
ierr = nf90_put_var(ncID,varTimeID ,times ) |
c Close netCDF file |
ierr = nf90_close(ncID) |
100 continue |
c ---- Define a new variable - skip if <crevar=0> ----------------------- |
if ( crevar.ne.1 ) goto 110 |
print*,'Now defining ',trim(varname) |
c Open the file for read/write access |
ierr = nf90_open (trim(cdfname), NF90_WRITE , ncID) |
c Get the IDs for dimensions |
ierr = nf90_inq_dimid(ncID,'level', LevDimID ) |
ierr = nf90_inq_dimid(ncID,'time' , TimeDimID) |
c Enter define mode |
ierr = nf90_redef(ncID) |
c Write definition and add attributes |
ierr = nf90_def_var(ncID,varname,NF90_FLOAT, |
> (/ TimeDimID, LevDimID /),varID) |
ierr = nf90_put_att(ncID, varID, "long_name" , longname ) |
ierr = nf90_put_att(ncID, varID, "units" , unit ) |
ierr = nf90_put_att(ncID, varID, '_FillValue', -999.99 ) |
c Check whether definition was successful |
ierr = nf90_enddef(ncID) |
if (ierr.gt.0) then |
print*, 'An error occurred while attempting to ', |
> 'finish definition mode.' |
stop |
endif |
c Close netCDF file |
ierr = nf90_close(ncID) |
110 continue |
c ---- Write data -------------------------------------------------- |
c Open the file for read/write access |
ierr = nf90_open (trim(cdfname), NF90_WRITE , ncID) |
c Get the varID |
ierr = nf90_inq_varid(ncID,varname, varID ) |
if (ierr.ne.0) then |
print*,'Variable ',trim(varname),' is not defined on ', |
> trim(cdfname) |
stop |
endif |
c Write data block |
ierr = nf90_put_var(ncID,varID,arr, |
> start = (/ 1, 1 /), |
> count = (/ ntim, npre/) ) |
c Check whether writing was successful |
ierr = nf90_close(ncID) |
if (ierr.ne.0) then |
write(*,*) trim(nf90_strerror(ierr)) |
write(*,*) 'An error occurred while attempting to ', |
> 'close the netcdf file.' |
write(*,*) 'in clscdf_CF' |
endif |
end |
c ******************************************************************************** |
c * Coordinate rotation - lidar normal to trajectory * |
c ******************************************************************************** |
c -------------------------------------------------------------------------------- |
c Backward coordinate transformation (Rotated lon/lat -> True lon/lat) |
c -------------------------------------------------------------------------------- |
SUBROUTINE getenvir_b (clon,clat,rotation, |
> lon,lat,rlon,rlat,n) |
implicit none |
c Declaration of input and output parameters |
integer n |
real clon,clat,rotation |
real lon(n), lat(n) |
real rlon(n),rlat(n) |
c Auxiliary variables |
real pollon,pollat |
integer i |
real rlon1(n),rlat1(n) |
c Externals |
real lmstolm,phstoph |
external lmstolm,phstoph |
c First coordinate transformation (make the local coordinate system parallel to equator) |
pollon=-180. |
pollat=90.+rotation |
do i=1,n |
rlon1(i)=90.+lmstolm(rlat(i),rlon(i)-90.,pollat,pollon) |
rlat1(i)=phstoph(rlat(i),rlon(i)-90.,pollat,pollon) |
enddo |
c Second coordinate transformation (make the local coordinate system parallel to equator) |
pollon=clon-180. |
if (pollon.lt.-180.) pollon=pollon+360. |
pollat=90.-clat |
do i=1,n |
lon(i)=lmstolm(rlat1(i),rlon1(i),pollat,pollon) |
lat(i)=phstoph(rlat1(i),rlon1(i),pollat,pollon) |
enddo |
END |
c --------------------------------------------------------------------- |
c Determine the angle between two vectors |
c --------------------------------------------------------------------- |
SUBROUTINE getangle (vx1,vy1,vx2,vy2,angle) |
c Given two vectors <vx1,vy1> and <vx2,vy2>, determine the angle (in deg) |
c between the two vectors. |
implicit none |
c Declaration of subroutine parameters |
real vx1,vy1 |
real vx2,vy2 |
real angle |
c Auxiliary variables and parameters |
real len1,len2,len3 |
real val1,val2,val3 |
real pi |
parameter (pi=3.14159265359) |
len1=sqrt(vx1*vx1+vy1*vy1) |
len2=sqrt(vx2*vx2+vy2*vy2) |
if ((len1.gt.0.).and.(len2.gt.0.)) then |
vx1=vx1/len1 |
vy1=vy1/len1 |
vx2=vx2/len2 |
vy2=vy2/len2 |
val1=vx1*vx2+vy1*vy2 |
val2=-vy1*vx2+vx1*vy2 |
len3=sqrt(val1*val1+val2*val2) |
if ( (val1.ge.0.).and.(val2.ge.0.) ) then |
val3=acos(val1/len3) |
else if ( (val1.lt.0.).and.(val2.ge.0.) ) then |
val3=pi-acos(abs(val1)/len3) |
else if ( (val1.ge.0.).and.(val2.le.0.) ) then |
val3=-acos(val1/len3) |
else if ( (val1.lt.0.).and.(val2.le.0.) ) then |
val3=-pi+acos(abs(val1)/len3) |
endif |
else |
val3=0. |
endif |
angle=180./pi*val3 |
END |
c -------------------------------------------------------------------------------- |
c Transformation routine: LMSTOLM and PHSTOPH from library gm2em |
c -------------------------------------------------------------------------------- |
REAL FUNCTION LMSTOLM (PHIS, LAMS, POLPHI, POLLAM) |
C |
C**** LMSTOLM - FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER |
C**** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
C**** IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT |
C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** AUFRUF : LAM = LMSTOLM (PHIS, LAMS, POLPHI, POLLAM) |
C** ENTRIES : KEINE |
C** ZWECK : BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER |
C** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
C** IM ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** VERSIONS- |
C** DATUM : 03.05.90 |
C** |
C** EXTERNALS: KEINE |
C** EINGABE- |
C** PARAMETER: PHIS REAL GEOGR. BREITE DES PUNKTES IM ROT.SYS. |
C** LAMS REAL GEOGR. LAENGE DES PUNKTES IM ROT.SYS. |
C** POLPHI REAL WAHRE GEOGR. BREITE DES NORDPOLS |
C** POLLAM REAL WAHRE GEOGR. LAENGE DES NORDPOLS |
C** AUSGABE- |
C** PARAMETER: WAHRE GEOGRAPHISCHE LAENGE ALS WERT DER FUNKTION |
C** ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0) |
C** |
C** COMMON- |
C** BLOECKE : KEINE |
C** |
C** FEHLERBE- |
C** HANDLUNG : KEINE |
C** VERFASSER: D.MAJEWSKI |
REAL LAMS,PHIS,POLPHI,POLLAM |
DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
ZSINPOL = SIN(ZPIR18*POLPHI) |
ZCOSPOL = COS(ZPIR18*POLPHI) |
ZLAMPOL = ZPIR18*POLLAM |
ZPHIS = ZPIR18*PHIS |
ZLAMS = LAMS |
IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0 |
ZLAMS = ZPIR18*ZLAMS |
ZARG1 = SIN(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS) + |
1 ZCOSPOL* SIN(ZPHIS)) - |
2 COS(ZLAMPOL)* SIN(ZLAMS)*COS(ZPHIS) |
ZARG2 = COS(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS) + |
1 ZCOSPOL* SIN(ZPHIS)) + |
2 SIN(ZLAMPOL)* SIN(ZLAMS)*COS(ZPHIS) |
IF (ABS(ZARG2).LT.1.E-30) THEN |
IF (ABS(ZARG1).LT.1.E-30) THEN |
LMSTOLM = 0.0 |
ELSEIF (ZARG1.GT.0.) THEN |
LMSTOLAM = 90.0 |
ELSE |
LMSTOLAM = -90.0 |
ENDIF |
ELSE |
LMSTOLM = ZRPI18*ATAN2(ZARG1,ZARG2) |
ENDIF |
RETURN |
END |
REAL FUNCTION PHSTOPH (PHIS, LAMS, POLPHI, POLLAM) |
C |
C**** PHSTOPH - FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER |
C**** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM |
C**** ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** AUFRUF : PHI = PHSTOPH (PHIS, LAMS, POLPHI, POLLAM) |
C** ENTRIES : KEINE |
C** ZWECK : BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER |
C** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM |
C** ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** VERSIONS- |
C** DATUM : 03.05.90 |
C** |
C** EXTERNALS: KEINE |
C** EINGABE- |
C** PARAMETER: PHIS REAL GEOGR. BREITE DES PUNKTES IM ROT.SYS. |
C** LAMS REAL GEOGR. LAENGE DES PUNKTES IM ROT.SYS. |
C** POLPHI REAL WAHRE GEOGR. BREITE DES NORDPOLS |
C** POLLAM REAL WAHRE GEOGR. LAENGE DES NORDPOLS |
C** AUSGABE- |
C** PARAMETER: WAHRE GEOGRAPHISCHE BREITE ALS WERT DER FUNKTION |
C** ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0) |
C** |
C** COMMON- |
C** BLOECKE : KEINE |
C** |
C** FEHLERBE- |
C** HANDLUNG : KEINE |
C** VERFASSER: D.MAJEWSKI |
REAL LAMS,PHIS,POLPHI,POLLAM |
DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
SINPOL = SIN(ZPIR18*POLPHI) |
COSPOL = COS(ZPIR18*POLPHI) |
ZPHIS = ZPIR18*PHIS |
ZLAMS = LAMS |
IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0 |
ZLAMS = ZPIR18*ZLAMS |
ARG = COSPOL*COS(ZPHIS)*COS(ZLAMS) + SINPOL*SIN(ZPHIS) |
PHSTOPH = ZRPI18*ASIN(ARG) |
RETURN |
END |
REAL FUNCTION LMTOLMS (PHI, LAM, POLPHI, POLLAM) |
C |
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H% |
C |
C**** LMTOLMS - FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM |
C**** AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
C**** IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT |
C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** AUFRUF : LAM = LMTOLMS (PHI, LAM, POLPHI, POLLAM) |
C** ENTRIES : KEINE |
C** ZWECK : UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM AUF |
C** EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM |
C** ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** VERSIONS- |
C** DATUM : 03.05.90 |
C** |
C** EXTERNALS: KEINE |
C** EINGABE- |
C** PARAMETER: PHI REAL BREITE DES PUNKTES IM GEOGR. SYSTEM |
C** LAM REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM |
C** POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS |
C** POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS |
C** AUSGABE- |
C** PARAMETER: WAHRE GEOGRAPHISCHE LAENGE ALS WERT DER FUNKTION |
C** ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0) |
C** |
C** COMMON- |
C** BLOECKE : KEINE |
C** |
C** FEHLERBE- |
C** HANDLUNG : KEINE |
C** VERFASSER: G. DE MORSIER |
REAL LAM,PHI,POLPHI,POLLAM |
DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
ZSINPOL = SIN(ZPIR18*POLPHI) |
ZCOSPOL = COS(ZPIR18*POLPHI) |
ZLAMPOL = ZPIR18*POLLAM |
ZPHI = ZPIR18*PHI |
ZLAM = LAM |
IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0 |
ZLAM = ZPIR18*ZLAM |
ZARG1 = - SIN(ZLAM-ZLAMPOL)*COS(ZPHI) |
ZARG2 = - ZSINPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL)+ZCOSPOL*SIN(ZPHI) |
IF (ABS(ZARG2).LT.1.E-30) THEN |
IF (ABS(ZARG1).LT.1.E-30) THEN |
LMTOLMS = 0.0 |
ELSEIF (ZARG1.GT.0.) THEN |
LMTOLMS = 90.0 |
ELSE |
LMTOLMS = -90.0 |
ENDIF |
ELSE |
LMTOLMS = ZRPI18*ATAN2(ZARG1,ZARG2) |
ENDIF |
RETURN |
END |
REAL FUNCTION PHTOPHS (PHI, LAM, POLPHI, POLLAM) |
C |
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H% |
C |
C**** PHTOPHS - FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI |
C**** AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
C**** IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT |
C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** AUFRUF : PHI = PHTOPHS (PHI, LAM, POLPHI, POLLAM) |
C** ENTRIES : KEINE |
C** ZWECK : UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI AUF |
C** EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM |
C** ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
C** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
C** VERSIONS- |
C** DATUM : 03.05.90 |
C** |
C** EXTERNALS: KEINE |
C** EINGABE- |
C** PARAMETER: PHI REAL BREITE DES PUNKTES IM GEOGR. SYSTEM |
C** LAM REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM |
C** POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS |
C** POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS |
C** AUSGABE- |
C** PARAMETER: ROTIERTE BREITE PHIS ALS WERT DER FUNKTION |
C** ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0) |
C** |
C** COMMON- |
C** BLOECKE : KEINE |
C** |
C** FEHLERBE- |
C** HANDLUNG : KEINE |
C** VERFASSER: G. DE MORSIER |
REAL LAM,PHI,POLPHI,POLLAM |
DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
ZSINPOL = SIN(ZPIR18*POLPHI) |
ZCOSPOL = COS(ZPIR18*POLPHI) |
ZLAMPOL = ZPIR18*POLLAM |
ZPHI = ZPIR18*PHI |
ZLAM = LAM |
IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0 |
ZLAM = ZPIR18*ZLAM |
ZARG = ZCOSPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL) + ZSINPOL*SIN(ZPHI) |
PHTOPHS = ZRPI18*ASIN(ZARG) |
RETURN |
END |
/tags/1.0/lidar/lidar.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = lidar.o ${LAGRANTO}/lib/times.a ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/ioinp.a ${LAGRANTO}/lib/inter.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
lidar: $(OBJS) |
${F77} -o lidar $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/lidar/lidar.sh |
---|
0,0 → 1,624 |
#!/bin/csh |
# --------------------------------------------------------------------- |
# Usage, parameter settings |
# --------------------------------------------------------------------- |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( (${#argv} == 0) | (${#argv} < 2) ) then |
echo |
${LAGRANTO}/bin/lagrantohelp lidar short |
echo |
exit 0 |
endif |
# Write title |
echo |
echo '=========================================================' |
echo ' *** START OF PREPROCESSOR LIDAR *** ' |
echo |
# Get the arguments |
set inpfile = $1 |
set outfile = $2 |
# Set base directories (run+prog) |
set cdfdir=${PWD} |
set tradir=${PWD} |
# Set program paths and filenames |
set parfile = ${tradir}/trace.param |
set prog = ${LAGRANTO}/lidar/lidar |
# Set the prefix of the primary and secondary data files |
set charp = 'P' |
set chars = 'S' |
echo '---- DIRECTORIES AND PROGRAMS ---------------------------' |
echo |
echo "CDF directory : ${cdfdir}" |
echo "TRA directory : ${tradir}" |
echo "PROGRAM LIDAR : ${prog}" |
echo "PARAMETER file : ${parfile}" |
echo |
# --------------------------------------------------------------------- |
# Set optional flags |
# --------------------------------------------------------------------- |
echo '---- OPTIONAL FLAGS -------------------------------------' |
echo |
# Set some default values ("nil" must be set according to input files) |
set flag_i = "nil" |
set flag_v = "tracevars" |
set flag_f = "nil" |
set tvfile = 'tracevars' |
set changet = 'false' |
set noclean = 'false' |
set timecheck = 'no' |
set intmode = 'normal' |
set pmin = 'nil' |
set pmax = 'nil' |
set npre = 100 |
set centering = 'no' |
set orientation = 'vertical' |
set outmode = 'sum' |
set dumpcoord = 'no' |
# Set flag for consistency |
set isok = 1 |
set explicit_limits = false |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -i |
set flag_i=$argv[2] |
echo "Flag '-i' -> ${flag_i} (user defined)" |
shift; |
breaksw |
case -pmin |
set explicit_limits = true |
set pmin=$argv[2] |
echo "Flag '-pmin' -> pmin (user defined): ${pmin}" |
shift; |
breaksw |
case -pmax |
set explicit_limits = true |
set pmax=$argv[2] |
echo "Flag '-pmax' -> pmax (user defined): ${pmax}" |
shift; |
breaksw |
case -npre |
set npre=$argv[2] |
echo "Flag '-npre' -> npre (user defined): ${npre}" |
shift; |
breaksw |
case -centering |
set centering = 'yes' |
echo "Flag '-centering' -> centering (user defined): ${centering}" |
breaksw |
case -dumpcoord |
set dumpcoord = 'yes' |
echo "Flag '-dumpcoord' -> dumpcoord (user defined): ${dumpcoord}" |
breaksw |
case -orientation |
set orientation=$argv[2] |
echo "Flag '-orientation'-> orientation (user defined): ${orientation}" |
shift; |
breaksw |
case -v |
set flag_v="-v" |
set tvfile=$argv[2] |
echo "Flag '-v' -> ${tvfile} (user defined)" |
shift; |
if ( $isok == 2 ) set isok = 0 |
if ( $isok == 1 ) set isok = 2 |
breaksw |
case -f |
set flag_f="-f" |
set tvfile="tracevars.tmp" |
shift; |
set tvar="$argv[1]" |
shift; |
set tscale="$argv[1]" |
echo "Flag '-f' -> ${tvar} ${tscale} (user defined)" |
if ( $isok == 2 ) set isok = 0 |
if ( $isok == 1 ) set isok = 2 |
breaksw |
case -changet |
set changet = 'true' |
echo "changet -> true (user defined)" |
breaksw |
case -noclean |
set noclean = 'true' |
echo "noclean -> true (user defined)" |
breaksw |
case -mean |
set outmode = 'mean' |
echo "outmode -> mean (user defined)" |
breaksw |
case -timecheck |
set timecheck = 'yes' |
echo "timecheck -> yes (user defined)" |
breaksw |
case -nearest |
set intmode = 'nearest' |
echo "intmode -> nearest (user defined)" |
breaksw |
endsw |
shift; |
end |
# For orientation=normal: only centering is reasonable |
if ( "${orientation}" == "normal" && "${centering}" == "no" ) then |
echo "For horizontal(normal) Lidar, only centering is reasonable - > mode changed" |
set centering = 'yes' |
endif |
# No change of times necessary if no check requested |
if ( "${timecheck}" == "no" ) then |
set changet = 'false' |
endif |
# Check consitency of arguments |
if ( $isok == 0 ) then |
echo |
echo " ERROR: Use either option '-v' or '-f', but not both..." |
exit 1 |
endif |
# Set position boundaries - pmin,pmax (pressure, lat,lon, deg rotated) |
if ( ( "${pmin}" == "nil" ) && ( "${orientation}" == "vertical" ) ) then |
set pmin = 100 |
set pmax = 1000 |
else if ( ( "${pmin}" == "nil" ) && ( "${orientation}" == "lat" ) ) then |
set pmin = -90 |
set pmax = 90 |
else if ( ( "${pmin}" == "nil" ) && ( "${orientation}" == "lon" ) ) then |
set pmin = -180 |
set pmax = 180 |
else if ( ( "${pmin}" == "nil" ) && ( "${orientation}" == "normal" ) ) then |
set pmin = -90 |
set pmax = 90 |
endif |
# If centering is chosen, set reasonable upper and lower limits |
if ( ( "$centering" == "yes" ) && ( "${explicit_limits}" == "false" ) ) then |
if ( "${orientation}" == "vertical" ) then |
set pmin = -500 |
set pmax = 500 |
else if ( "${orientation}" == "lat" ) then |
set pmin = -10 |
set pmax = 10 |
else if ( "${orientation}" == "lon" ) then |
set pmin = -10 |
set pmax = 10 |
else if ( "${orientation}" == "normal" ) then |
set pmin = -10 |
set pmax = 10 |
endif |
endif |
# --------------------------------------------------------------------- |
# Handle the input trajectory file |
# --------------------------------------------------------------------- |
echo |
echo '---- TIME RANGE -----------------------------------------' |
echo |
# Check whether the input file can be found |
if ( ! -f ${inpfile} ) then |
echo " ERROR : Input file ${inpfile} is missing" |
exit 1 |
endif |
# Get the start, end and reference date for the tracing |
set startdate = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} startdate` |
set enddate = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} enddate` |
set refdate = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} refdate` |
set ntra = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} ntra` |
set ntim = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} ntim` |
set ncol = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} ncol` |
# Check format of start and end date - must be the same |
set ns=`echo $startdate | sed -e 's/_[0-9]*//' | wc -c` |
set ne=`echo $enddate | sed -e 's/_[0-9]*//' | wc -c` |
if ( $ns != $ne ) then |
echo " ERROR: start and end date must be in the same format ***" |
exit 1 |
endif |
if ( $ns != 9 ) then |
echo " ERROR: Date format must be yyyymmdd ***" |
exit 1 |
endif |
set ns=`echo $startdate | sed -e 's/[0-9]*_//' | wc -c` |
set ne=`echo $enddate | sed -e 's/[0-9]*_//' | wc -c` |
if ( $ns != $ne ) then |
echo " ERROR: start and end date must be in the same format ***" |
exit 1 |
endif |
if ( ( $ns != 5 ) & ( $ns != 3 ) ) then |
echo " ERROR: Time format must be hh(mm) ***" |
exit 1 |
endif |
# Split the start and end date into <yymmdd_hh and mm> |
set startdate_ymdh = `echo $startdate | cut -c 1-11` |
set startdate_min = `echo $startdate | cut -c 12-13` |
if ( $startdate_min == "" ) set startdate_min = 00 |
set enddate_ymdh = `echo $enddate | cut -c 1-11` |
set enddate_min = `echo $enddate | cut -c 12-13` |
if ( $enddate_min == "" ) set enddate_min = 00 |
# Get the time difference between <start_ymdh> and <end_ymdh> date |
# Decide whether trajectoriesare forward or backward |
set timediff_hh = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${startdate_ymdh}` |
if ( $timediff_hh == 0 ) then |
if ( $enddate_min > $startdate_min ) then |
set direction = f |
set idir = 1 |
else |
set direction = b |
set idir = -1 |
endif |
else if ( $timediff_hh > 0 ) then |
set direction = f |
set idir = 1 |
else |
set direction = b |
set idir = -1 |
@ timediff_hh = $idir * $timediff_hh |
endif |
# Get also minutes for time difference, if <start_min> or <end_min> != 0 |
set timediff_mm= |
if ( $startdate_min != 00 || $enddate_min != 00 ) then |
@ min = ( $enddate_min - $startdate_min ) |
if ( $min == 0 ) then |
set timediff_mm= |
else if ( $min > 0 ) then |
if ( $idir == 1 ) then |
set timediff_mm=$min |
else |
@ timediff_hh -- |
@ timediff_mm = 60 - $min |
endif |
else |
if ( $idir == 1 ) then |
@ timediff_hh -- |
@ timediff_mm = 60 + $min |
else |
@ timediff_mm = 0 - $min |
endif |
endif |
endif |
# Write status information |
echo "Time range : ${startdate} -> ${enddate}" |
if ( ${timediff_mm} != "" ) then |
echo "Time difference : ${timediff_hh} h ${timediff_mm} min" |
else |
echo "Time difference : ${timediff_hh} h" |
endif |
echo "Direction : ${direction} (${idir})" |
# --------------------------------------------------------------------- |
# Check availability of input data |
# --------------------------------------------------------------------- |
echo |
echo '---- INPUT FILES ----------------------------------------' |
echo |
# Take the time increment from flag list ('nil', if not defined) |
set timeinc = ${flag_i} |
# Find a first data file (if possible corresponding to start/end date |
# If starttime is not a data time, take the first file in the direectory |
if ( $direction == "f" ) then |
set file=${charp}${startdate_ymdh} |
else |
set file=${charp}${enddate_ymdh} |
endif |
if ( ! -f $file ) then |
set file=`ls ${charp}[0-9_]*[0-9] | head -1 | sed -e 's/@//'` |
endif |
# Determine timeinc (the time difference in hours between two data file) |
# if not already defined with option -i |
if ( ${timeinc} == "nil" ) then |
set date1=`echo $file | cut -c 2-12` |
set n=`ls ${charp}[0-9_]*[0-9] | grep -n $date1 | awk -F: '{print $1}'` |
@ n ++ |
set date2=`ls ${charp}[0-9_]*[0-9] | head -$n | tail -1 | cut -c 2-12` |
set timeinc=`${LAGRANTO}/goodies/gettidiff $date2 $date1` |
endif |
if ( $timeinc == 0 ) then |
echo " ERROR: cannot set the time increment between input files ***" |
exit 1 |
endif |
# Search the first file to use |
set flag=0 |
set td= |
foreach i ( ${charp}????????_?? ) |
set date = `echo $i | cut -c 2-12` |
set td1 = `${LAGRANTO}/goodies/gettidiff ${startdate_ymdh} ${date}` |
set td2 = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${date}` |
if (( $td1 < $timeinc || $td2 < $timeinc ) && ( $td1 >= 0 || $td2 >= 0 )) then |
set datfiles=$date |
if ( $td1 < $timeinc ) set td=$td1 |
if ( $td2 < $timeinc ) set td=$td2 |
if ( ( $startdate_min > 0 ) || ( $enddate_min > 0 ) ) @ td ++ |
goto label2 |
endif |
end |
# if no P/T-files are available for the specified time period, then $td is |
# still undefined |
if ( $td == "" ) then |
echo " ERROR: no data files available for the specified time period" |
exit 1 |
endif |
# Everything is fine so far: proceed |
label2: |
# Check whether first date is ok - before or at needed dates |
if ( $direction == "f" ) then |
set tdiff0 = `${LAGRANTO}/goodies/gettidiff ${startdate_ymdh} ${date}` |
else |
set tdiff0 = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${date}` |
endif |
if ( $tdiff0 < 0 ) then |
echo " ERROR: data files missing for the specified time period" |
exit 1 |
endif |
# Calculate the number of further files |
@ num = ( $timediff_hh + $td ) / $timeinc + 1 |
@ dum1 = ( $num - 1 ) * $timeinc |
@ dum2 = $timediff_hh + $td |
if ( $dum1 != $dum2 ) @ num ++ |
# Get a list of all needed files |
set numfiles=$num |
set sfiles=1 |
while ( $num > 1 ) |
set date=`${LAGRANTO}/goodies/newtime $date $timeinc` |
if ( ! -f ${charp}${date} ) then |
echo " ERROR: file with primary data is missing for $date" |
exit 1 |
else if ( ! -f ${chars}${date} ) then |
set sfiles=0 |
set datfiles=`echo $datfiles $date` |
else |
set datfiles=`echo $datfiles $date` |
endif |
@ num -- |
end |
# Calculate the start and the end time relative to the first datfile |
if ( $direction == f ) then |
set tstart = `${LAGRANTO}/goodies/gettidiff $startdate $datfiles[1]` |
set tend = `${LAGRANTO}/goodies/gettidiff $datfiles[$numfiles] $enddate` |
else |
set tstart = `${LAGRANTO}/goodies/gettidiff $datfiles[$numfiles] $startdate` |
set tend = `${LAGRANTO}/goodies/gettidiff $enddate $datfiles[1]` |
endif |
# Write some status information |
echo "Primary file prefix : ${charp}" |
echo "Secondary file prefix : ${chars}" |
echo "Time increment for input files : ${timeinc}" |
echo "# input files : ${numfiles}" |
echo "First input file : $datfiles[1] " |
echo "Last input file : $datfiles[$numfiles] " |
echo "${charp} files availability : 1" |
echo "${chars} files availability : ${sfiles}" |
if ( $direction == f ) then |
echo "Start time relative to first file : $datfiles[1] + ${tstart} " |
echo "End time relative to last file : $datfiles[$numfiles] - ${tend} " |
else |
echo "Start time relative to last file : $datfiles[$numfiles] - ${tstart} " |
echo "End time relative to first file : $datfiles[1] + ${tend} " |
endif |
# --------------------------------------------------------------------- |
# Check availability of input data |
# --------------------------------------------------------------------- |
echo |
echo '---- TRACEVAR FILE --------------------------------------' |
echo |
# If "-f" option is used, create a temporary tracevar file |
if ( "${flag_f}" == "-f" ) then |
# Preset values for <compfl> and <tprefix> |
set tcompfl=1 |
set tprefix='P' |
# Check availability on P file |
foreach var ( `${LAGRANTO}/goodies/getvars ${charp}$datfiles[1]` ) |
if ( "${var}" == "${tvar}" ) then |
set tcompfl=0 |
set tprefix="P" |
endif |
end |
# Check availability on S file |
if ( ${sfiles} == 1 ) then |
foreach var ( `${LAGRANTO}/goodies/getvars ${chars}$datfiles[1]` ) |
if ( "${var}" == "${tvar}" ) then |
set tcompfl=0 |
set tprefix="S" |
endif |
end |
endif |
# Write the temporary <tracevars> file |
echo "${tvar} ${tscale} ${tcompfl} ${tprefix}" >! ${tvfile} |
echo "Temporary tracervar file <${tvfile}> created" |
echo |
endif |
# Check if tracevars-file exists |
if ( ! -f $tvfile ) then |
echo " ERROR: file $tvfile was not found ***" |
exit 1 |
endif |
# check if the variables contained in the tracevars-file are available in the |
# data file and check also if there are no empty lines in the tracevars-file |
set nlines = `cat $tvfile | wc -l` |
set vars = `cat $tvfile | awk '{print $1}'` |
set nvars = `echo $vars | wc -w` |
if ( $nlines != $nvars ) then |
echo " ERROR: tracevars-files must not contain empty lines ***" |
exit 1 |
endif |
set calf=`cat $tvfile | awk '{print $3}'` |
set tfil=`cat $tvfile | awk '{print $4}'` |
foreach v ( $vars ) |
if ( $calf[1] == 0 ) then |
set v0 = `echo $v | awk 'BEGIN {FS = ":"}; {print $1}'` |
set flag=`${LAGRANTO}/goodies/getvars $tfil[1]$datfiles[1] | grep " $v0 " | wc -l` |
set iscomment=`echo $v0 | cut -c 1` |
if ( "${iscomment}" != "#" ) then |
if ( $flag == 0 ) then |
echo " ERROR: variable $v listed in $tvfile is not on the $tfil[1]-files ***" |
exit 1 |
endif |
endif |
endif |
shift calf |
shift tfil |
end |
set ntrace=${nlines} |
# Write some status information |
cat ${tvfile} |
echo |
echo "# Number of tracing variables : ${ntrace}" |
# --------------------------------------------------------------------- |
# Prepare input file for trace and run it |
# --------------------------------------------------------------------- |
# Set times relative to the reference date |
if ( "${changet}" == "true" ) then |
echo |
echo '---- CHANGE TIMES ON DATA FILES ------------------------' |
echo |
foreach i ( $datfiles ) |
${LAGRANTO}/goodies/changet.sh ${refdate} ${charp}${i} |
end |
if ( ${sfiles} == 1 ) then |
foreach i ( $datfiles ) |
${LAGRANTO}/goodies/changet.sh ${refdate} ${chars}${i} |
end |
endif |
endif |
# --------------------------------------------------------------------- |
# Prepare input file for lidar and run it |
# --------------------------------------------------------------------- |
# Write parameter file |
\rm -f ${parfile} |
touch ${parfile} |
echo $inpfile >> $parfile |
echo $outfile >> $parfile |
echo $outmode >> $parfile |
echo $startdate >> $parfile |
echo $enddate >> $parfile |
echo $idir >> $parfile |
echo $numfiles >> $parfile |
foreach i ( $datfiles ) |
echo $i >> $parfile |
end |
echo $timeinc >> $parfile |
echo $tstart >> $parfile |
echo $tend >> $parfile |
echo $ntra >> $parfile |
echo $ntim >> $parfile |
echo $ncol >> $parfile |
echo $ntrace >> $parfile |
cat ${tvfile} >> $parfile |
${LAGRANTO}/goodies/getvars ${charp}$datfiles[1] | wc -l >> $parfile |
${LAGRANTO}/goodies/getvars ${charp}$datfiles[1] >> $parfile |
if ( $sfiles == 1 ) then |
${LAGRANTO}/goodies/getvars ${chars}$datfiles[1] | wc -l >> $parfile |
${LAGRANTO}/goodies/getvars ${chars}$datfiles[1] >> $parfile |
else |
echo 0 >> $parfile |
endif |
echo \"${timecheck}\" >> $parfile |
echo \"${intmode}\" >> $parfile |
echo ${pmin},${pmax},${npre} >> $parfile |
echo \"${centering}\" >> $parfile |
echo \"${orientation}\" >> $parfile |
echo \"${dumpcoord}\" >> $parfile |
# Finish the preprocessor |
echo |
echo ' *** END OF PREPROCESSOR LIDAR *** ' |
echo '=========================================================' |
echo |
# Run lidar |
${prog} |
if ( "${status}" != "0" ) then |
echo "ERROR: Program <lidar> failed" |
exit 1 |
endif |
# --------------------------------------------------------------------- |
# Final tasks (make clean) |
# --------------------------------------------------------------------- |
finish: |
if ( "${noclean}" == "false" ) then |
\rm -f ${parfile} |
endif |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/select/select.f |
---|
0,0 → 1,2199 |
PROGRAM select |
c ************************************************************** |
c * Select trajectories from LSL file * |
c * Michael Sprenger / January, February 2008 * |
c ************************************************************** |
implicit none |
c -------------------------------------------------------------- |
c Declaration of parameters |
c -------------------------------------------------------------- |
c Maximum number of columns per trajectory |
integer maxcol |
parameter (maxcol=100) |
c Maximum number of commands |
integer maxcmd |
parameter (maxcmd=10000) |
c -------------------------------------------------------------- |
c Declaration of variables |
c -------------------------------------------------------------- |
c Input and output files |
character*120 inp_lslfile ! Input lsl file |
character*120 out_lslfile ! Output lsl file |
character*120 inp_criteria ! Input file with criteria |
integer inpmode ! Format of input file |
integer outmode ! Format of output file |
character*80 outformat ! Trajectory/Boolean/Index of output |
character*80 regionf ! Name of the regionfile |
c Trajectories |
integer ntim ! Number of times |
integer ncol ! Number of columns (including time...) |
integer ntrainp,ntraout ! Number of trajectories |
character*80 vars(maxcol) ! Names of trajectory columns |
integer basetime(6) ! Base time of trajectory (first line in lsl) |
real,allocatable, dimension (:,:,:) :: trainp ! Input trajectories |
real,allocatable, dimension (:,:,:) :: traout ! Output trajectories |
integer,allocatable,dimension (:) :: selflag ! Flag for selection |
real,allocatable, dimension (:) :: time ! Times of the trajectory |
integer,allocatable,dimension (:,:) :: trigger ! Trigger column |
integer itrigger ! Column index for trigger |
character*80 addtrigger ! Flag whether to add trigger column |
c Command stack |
real cmd(maxcmd) ! Decoded slection criterion |
integer ncmd ! Number of commands |
c Common block for initialisation of polygon check |
real tlonv(2000),vlat_c(2000),vlon_c(2000) |
real xlat_c,xlon_c |
integer ibndry,nv_c |
data ibndry/0/ |
common /spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry |
c Auxiliary variables |
integer stat ! Logical (state) variable |
integer fid,fod,fcr ! File identifier for input and output |
integer i,j,k ! Index counter |
integer isok ! Flag for selected trajectory |
real param(1000) ! List of parameters |
integer nparam ! Number of parameters |
character*80 specialstr ! Name of special command |
integer len |
integer,allocatable,dimension (:) :: trigger1 ! Trigger column |
real,allocatable,dimension (:,:) :: trainp1 ! A single trajectory |
character ch |
c -------------------------------------------------------------- |
c Preparations |
c -------------------------------------------------------------- |
c Write start message |
print*,'=========================================================' |
print*,' *** START OF PROGRAM SELECT ***' |
print* |
c Read parameter file |
open(10,file='select.param') |
read(10,*) inp_lslfile |
read(10,*) out_lslfile |
read(10,*) outformat |
read(10,*) inp_criteria |
read(10,*) ntrainp |
read(10,*) ntim |
read(10,*) ncol |
read(10,*) regionf |
read(10,*) addtrigger |
close(10) |
c Set the formats of the input and output files |
call mode_tra(inpmode,inp_lslfile) |
if (inpmode.eq.-1) inpmode=1 |
call mode_tra(outmode,out_lslfile) |
if ( (outmode.eq.-1).and.(outformat.ne.'startf') ) then |
outmode=1 |
endif |
c Allocate memory for a single trajectory |
allocate(trainp(ntrainp,ntim,ncol),stat=stat) |
if (stat.ne.0) stop '*** error allocating array trainp ***' |
allocate(time(ntim),stat=stat) |
if (stat.ne.0) stop '*** error allocating array time ***' |
allocate(selflag(ntrainp),stat=stat) |
if (stat.ne.0) stop '*** error allocating array selflag ***' |
allocate(trigger(ntrainp,ntim),stat=stat) |
if (stat.ne.0) stop '*** error allocating array trigger ***' |
allocate(trigger1(ntim),stat=stat) |
if (stat.ne.0) stop '*** error allocating array trigger1 ***' |
allocate(trainp1(ntim,ncol),stat=stat) |
if (stat.ne.0) stop '*** error allocating array trainp1 ***' |
c Read the input trajectory file |
call ropen_tra(fid,inp_lslfile,ntrainp,ntim,ncol, |
> basetime,vars,inpmode) |
call read_tra (fid,trainp,ntrainp,ntim,ncol,inpmode) |
call close_tra(fid,inpmode) |
c Check that first four columns correspond to time,lon,lat,p |
if ( (vars(1).ne.'time' ).or. |
> (vars(2).ne.'xpos' ).and.(vars(2).ne.'lon' ).or. |
> (vars(3).ne.'ypos' ).and.(vars(3).ne.'lat' ).or. |
> (vars(4).ne.'ppos' ).and.(vars(4).ne.'p' ) ) |
>then |
print*,' ERROR: problem with input trajectories ...' |
stop |
endif |
vars(1) = 'time' |
vars(2) = 'lon' |
vars(3) = 'lat' |
vars(4) = 'p' |
c Get the trajectory times from first trajectory |
do i=1,ntim |
time(i)=trainp(1,i,1) |
enddo |
c Init the trigger field - first check whether it is already available |
itrigger = 0 |
do i=1,ncol |
if ( vars(i).eq.'TRIGGER' ) itrigger = i |
enddo |
if ( itrigger.ne.0 ) then |
do i=1,ntrainp |
do j=1,ntim |
trigger(i,j) = nint( trainp(i,j,itrigger) ) |
enddo |
enddo |
else |
do i=1,ntrainp |
do j=1,ntim |
trigger(i,j) = 0 |
enddo |
enddo |
endif |
c Write some info about the trajectory |
print*,'---- INPUT PARAMETERS -----------------------------------' |
write(*,*) |
write(*,*) 'Input file : ',trim(inp_lslfile) |
write(*,*) 'Output file : ',trim(out_lslfile) |
write(*,*) 'Output format : ',trim(outformat) |
write(*,*) 'Criteria file : ',trim(inp_criteria) |
write(*,*) '# tra : ',ntrainp |
write(*,*) '# time : ',ntim |
write(*,*) '# col : ',ncol |
write(*,*) 'Region file : ',trim(regionf) |
write(*,*) 'Add trigger : ',trim(addtrigger) |
print* |
print*,'---- INPUT TRAJECTORY FILE ------------------------------' |
print* |
write(*,'(1x,a12,i4,a10)') 'Vars : ',1,trim(vars(1)) |
do i=2,ncol |
write(*,'(1x,a12,i4,a10)') ' ',i,trim(vars(i)) |
enddo |
print* |
write(*,'(1x,a12,i4,f10.2)') 'Time : ',1,time(1) |
do i=2,ntim |
write(*,'(1x,a12,i4,f10.2)') ' ',i,time(i) |
enddo |
print* |
write(*,'(1x,a12,i4,i10)') 'Base date : ',1,basetime(1) |
write(*,'(1x,a12,i4,i10)') ' ',2,basetime(2) |
write(*,'(1x,a12,i4,i10)') ' ',3,basetime(3) |
write(*,'(1x,a12,i4,i10)') ' ',4,basetime(4) |
write(*,'(1x,a12,i4,i10)') ' ',5,basetime(5) |
print* |
write(*,'(1x,a12,i4,i10)') 'Time range : ',6,basetime(6) |
print* |
if ( itrigger.ne.0 ) then |
print*,'TRIGGER FIELD FOUND IN COLUMN ',itrigger |
print* |
endif |
c Read and decode the selection criterion |
fcr = 10 |
open(fcr,file=inp_criteria) |
ncmd=maxcmd |
call decode(fcr,cmd,ncmd,vars,ncol,time,ntim,regionf) |
close(fcr) |
print* |
print*,'---- PSEUDO CODE FOR SELECTION --------------------------' |
print* |
call dumpcode(cmd,ncmd,vars,ncol,time,ntim) |
c -------------------------------------------------------------- |
c Loop over all trajectories - selection |
c -------------------------------------------------------------- |
c Prepare string and parameters for SPECIAL commands |
if ( cmd(1).eq.0 ) then |
c Get command string |
j = 2 |
len = nint(cmd(j)) |
specialstr = '' |
do k=1,len |
j = j + 1 |
specialstr = trim(specialstr)//char(nint(cmd(j))) |
enddo |
c Get paramters |
j = j + 1 |
nparam = nint(cmd(j)) |
do k=1,nparam |
j = j + 1 |
param(k) = cmd(j) |
enddo |
endif |
c Init the counter for selected trajectories |
ntraout = 0 |
c Loop over all trajectories |
do i=1,ntrainp |
c Copy a single trajectory to <trainp1> and <trigger1> |
do j=1,ntim |
do k=1,ncol |
trainp1(j,k) = trainp(i,j,k) |
enddo |
trigger1(j) = trigger(i,j) |
enddo |
C Skip the trajectory if missing data are found for positions |
isok = 1 |
do j=1,ntim |
if ( trainp1(j,4).lt.0. ) isok = 0 |
enddo |
c Decide whether the trajectory is selected (handle SPECIAL commands) |
if ( isok.eq.1 ) then |
if (cmd(1).ne.0 ) then |
call select_tra (isok,cmd,ncmd,trainp1,trigger1,ntim,ncol) |
else |
call special (isok,specialstr,trainp1,ntim,ncol, |
> vars,time,param,nparam) |
endif |
endif |
c The trigger might be changed in the selection - copy it |
do j=1,ntim |
trigger(i,j) = trigger1(j) |
enddo |
c Set flag for selected trajectories |
if (isok.eq.1) then |
selflag(i) = 1 |
ntraout = ntraout + 1 |
else |
selflag(i) = 0 |
endif |
enddo |
c -------------------------------------------------------------- |
c Write output trajectories |
c -------------------------------------------------------------- |
c ------ Write output trajectories ----------------------------- |
if ( outformat.eq.'trajectory' ) then |
c Define the trigger field if it is not yet defined |
if ( ( addtrigger.eq.'-trigger' ).and.(itrigger.eq.0) ) then |
ncol = ncol + 1 |
vars(ncol) = 'TRIGGER' |
itrigger = ncol |
endif |
c Allocate memory for output trajectory |
allocate(traout(ntraout,ntim,ncol),stat=stat) |
if (stat.ne.0) stop '*** error allocating array apply ***' |
c Set output trajectories |
j = 0 |
do i=1,ntrainp |
if (selflag(i).eq.1) then |
j = j + 1 |
traout(j,1:ntim,1:ncol) = trainp(i,1:ntim,1:ncol) |
if ( itrigger.ne.0 ) then |
traout(j,1:ntim,itrigger) = real(trigger(i,1:ntim)) |
endif |
endif |
enddo |
c Write trajectories |
call wopen_tra(fod,out_lslfile,ntraout,ntim,ncol, |
> basetime,vars,outmode) |
call write_tra(fod,traout,ntraout,ntim,ncol,outmode) |
call close_tra(fod,outmode) |
c ------ Write index list ------------------------------------- |
elseif ( outformat.eq.'index' ) then |
open(10,file=out_lslfile) |
do i=1,ntrainp |
if ( selflag(i).eq.1) write(10,*) i |
enddo |
close(10) |
c ------ Write boolean list ----------------------------------- |
elseif ( outformat.eq.'boolean' ) then |
open(10,file=out_lslfile) |
do i=1,ntrainp |
write(10,'(i1)') selflag(i) |
enddo |
close(10) |
c ------ Write count ------------------------------------------- |
elseif ( outformat.eq.'count' ) then |
open(10,file=out_lslfile) |
write(10,'(i7)') ntraout |
close(10) |
c ------ Write starting positions ----------------------------- |
elseif ( outformat.eq.'startf' ) then |
c Allocate memory for output trajectory |
allocate(traout(ntraout,1,ncol),stat=stat) |
if (stat.ne.0) stop '*** error allocating array apply ***' |
c Set output trajectories |
j = 0 |
do i=1,ntrainp |
if (selflag(i).eq.1) then |
j = j + 1 |
traout(j,1,:) = trainp(i,1,:) |
endif |
enddo |
c Write trajectories |
if (outmode.ne.-1) then |
call wopen_tra(fod,out_lslfile,ntraout,1,ncol, |
> basetime,vars,outmode) |
call write_tra(fod,traout,ntraout,1,ncol,outmode) |
call close_tra(fod,outmode) |
c Output as a triple list (corresponding to <startf> file) |
else |
fid = 10 |
open(fid,file=out_lslfile) |
do i=1,ntraout |
write(fid,'(3f10.3)') traout(i,1,2), ! longitude |
> traout(i,1,3), ! latitude |
> traout(i,1,4) ! pressure |
enddo |
close(fid) |
endif |
endif |
c Write some status information, and end of program message |
print* |
print*,'---- STATUS INFORMATION --------------------------------' |
print* |
print*,' # input trajectories : ',ntrainp |
print*,' # output trajectories : ',ntraout |
print* |
print*,' *** END OF PROGRAM SELECT ***' |
print*,'=========================================================' |
stop |
c Exception handling |
100 stop 'select: First column in input trajectory must be <time>' |
101 stop 'select: Input trajectory file is empty' |
end |
c -------------------------------------------------------------- |
c Dump the command list |
c -------------------------------------------------------------- |
subroutine dumpcode(out,n,vars,nvars,times,ntimes) |
c Write the command list to screen. The command list is decoded |
c by call to <decode> |
implicit none |
c Declaration of subroutine parameters |
integer n |
real out(n) |
integer nvars |
character*80 vars(nvars) |
integer ntimes |
real times(ntimes) |
c A single command |
character*80 cmd |
character*80 var,mode,strtim |
integer nval |
integer ntim |
integer ivar,imode,icmd,itime |
c Auxiliary variables |
integer i,j |
c Loop through the complete list |
i=0 |
100 if (i.lt.n) then |
write(*,*) '---------------------------------------' |
c Get command |
i=i+1 |
icmd=nint(out(i)) |
c Special handling of SPECIAL commands |
if ( icmd.eq.0 ) then |
c Write 'header' for SPECIAL command |
write(*,'(i5,f15.4,10x,a10)') i,out(i),'SPECIAL' |
c Write command string |
i = i + 1 |
icmd = nint(out(i)) |
write(*,'(i5,f15.4,10x,a10)') i,out(i),'LEN(CMD)' |
do j=1,icmd |
i = i + 1 |
ivar = nint(out(i)) |
write(*,'(i5,f15.4,10x,a10)') i,out(i),char(ivar) |
enddo |
c Write parameters |
i = i + 1 |
nval = nint(out(i)) |
write(*,'(i5,f15.4,10x,a10)') i,out(i),'#PARAMETER' |
do j=1,nval |
i=i+1 |
if ( var.ne.'INPOLYGON' ) then |
write(*,'(i5,f15.4)') i,out(i) |
else |
write(*,'(i5,f15.4,a2)') i,out(i),char(nint(out(i))) |
endif |
enddo |
c Nothing else to do - exit |
goto 200 |
endif |
c Set the command |
if (icmd.eq. 1) cmd='GT' |
if (icmd.eq. 2) cmd='LT' |
if (icmd.eq. 3) cmd='IN' |
if (icmd.eq. 4) cmd='OUT' |
if (icmd.eq. 5) cmd='EQ' |
if (icmd.eq. 6) cmd='TRUE' |
if (icmd.eq. 7) cmd='FALSE' |
if (icmd.eq. 8) cmd='ALL' |
if (icmd.eq. 9) cmd='ANY' |
if (icmd.eq. 10) cmd='NONE' |
if (icmd.eq. -1) cmd='BEGIN' |
if (icmd.eq. -2) cmd='END' |
if (icmd.eq. -3) cmd='AND' |
if (icmd.eq. -4) cmd='OR' |
write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(cmd) |
if (icmd.lt.0) goto 100 |
c Get variable |
i=i+1 |
ivar=nint(out(i)) |
if ( ivar.eq. -1 ) then |
var = 'DIST' |
elseif ( ivar.eq. -2 ) then |
var = 'DIST0' |
elseif ( ivar.eq. -3 ) then |
var = 'INPOLYGON' |
elseif ( ivar.eq. -4 ) then |
var = 'INBOX' |
elseif ( ivar.eq. -5 ) then |
var = 'INCIRCLE' |
elseif ( ivar.eq. -6 ) then |
var = 'INREGION' |
elseif ( ivar.eq. -7 ) then |
var = 'TRIGGER' |
elseif ( ivar.eq. -8 ) then |
var = 'VERT0' |
else |
var=vars(ivar) |
endif |
write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(var) |
c Get variable mode |
i=i+1 |
imode=nint(out(i)) |
if (imode.eq.1) mode='VALUE' |
if (imode.eq.2) mode='MEAN' |
if (imode.eq.3) mode='MAX' |
if (imode.eq.4) mode='MIN' |
if (imode.eq.5) mode='VAR' |
if (imode.eq.6) mode='SUM' |
if (imode.eq.7) mode='CHANGE' |
if (imode.eq.8) mode='DIFF' |
if (imode.eq.9) mode='RANGE' |
write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(mode) |
c Get values |
i=i+1 |
nval=nint(out(i)) |
write(*,'(i5,f15.4,10x,a10)') i,out(i),'#PARAMETER' |
do j=1,nval |
i=i+1 |
if ( var.ne.'INPOLYGON' ) then |
write(*,'(i5,f15.4)') i,out(i) |
else |
write(*,'(i5,f15.4,a2)') i,out(i),char(nint(out(i))) |
endif |
enddo |
c Get the number of times |
i=i+1 |
ntim=nint(out(i)) |
c the number of times is variable - depending on TRIGGER |
if ( ntim .eq. -993 ) then |
write(*,'(i5,f15.4,7x,7x,a15)') i,out(i),'TIMES @ TRIGGER' |
c Get the detailed list of times |
else |
write(*,'(i5,f15.4,7x,7x,a6)') i,out(i),'#TIMES' |
do j=1,ntim |
i=i+1 |
write(*,'(i5,f15.4,f7.0)') i,out(i),times(nint(out(i))) |
enddo |
endif |
c Get time mode |
i=i+1 |
itime=nint(out(i)) |
if (itime.eq.1) strtim='ALL' |
if (itime.eq.2) strtim='ANY' |
if (itime.eq.3) strtim='NONE' |
if (itime.lt.0) strtim='TRIGGER' |
if ( strtim.ne.'TRIGGER' ) then |
write(*,'(i5,f15.4,10x,a10)') i,out(i),trim(strtim) |
else |
write(*,'(i5,f15.4,10x,a10,a3,i3)') i,out(i),trim(strtim), |
> ' ->',abs(itime) |
endif |
goto 100 |
endif |
c Exit point |
200 continue |
write(*,*) '---------------------------------------' |
end |
c -------------------------------------------------------------- |
c Read and decode a selection set |
c -------------------------------------------------------------- |
subroutine decode(fid,out,n,vars,nvars,times,ntimes,regionf) |
c A selection file is opened with file id <fid> and transformed |
c into a set of commands applied to the trajectories. On input |
c <n> sets the maximum dimension of <out>, on output it gives the |
c total length of the command string. The output is a list of |
c commands with the following format: |
c |
c out(i) = Command |
c out(i+1) = Column index of variable |
c out(i+2) = Mode for variable |
c out(i+3) = Number of parameters (n) |
c out(i+4:i+4+n) = Parameters |
c out(i+5+n) = Number of times |
c out(i+6+n:i+6+n+m) = List of time indices (m) |
c out(i+7+n+m) = Time mode |
c |
c For SPECIAL commands (to be coded in <special.f>) the format is: |
c |
c out(i) = Length of command string (n) |
c out(i+1:i+n) = Command string |
c out(i+n+1) = Number of parameters (m) |
c out(i+n+2:i+n+1+m) = List of parameters |
c |
c The following coding is used |
c |
c Command Variable mode Time mode |
c ---------- ------------- --------- |
c GT 1 VALUE 1 ALL 1 |
c LT 2 MEAN 2 ANY 2 |
c IN 3 MAX 3 NONE 3 |
c OUT 4 MIN 4 TRIGGER -i (i the trigger index) |
c EQ 5 VAR 5 |
c BEGIN -1 SUM 6 |
c END -2 CHANGE 7 |
c AND -3 DIFF 8 |
c OR -4 RANGE 9 |
c TRUE 6 |
c FALSE 7 |
c SPECIAL 0 |
c ALL 8 (TRIGGER) |
c ANY 9 (TRIGGER) |
c NONE 10 (TRIGGER) |
c Several "implicit variables" are supported - out(i+1): |
c |
c DIST -1 : Path length of the trajectory |
c DIST0 -2 : Distance from starting position |
c INPOLYGON -3 : Specified polygon region |
c INBOX -4 : Longitude/latitude rectangle |
c INCIRCLE -5 : Within a specified radius |
c INREGION -6 : Within a specified rehion on the region file |
c TRIGGER -7 : Trigger field |
c VERT0 -8 : Vertical distance from starting position |
c |
c For the special commands BEGIN, END, AND and OR, only one field |
c in <out> is used. |
implicit none |
c Declaration of subroutine parameters |
integer fid |
integer n |
real out(n) |
integer nvars |
character*80 vars(nvars) |
integer ntimes |
real times(ntimes) |
character*80 regionf |
c Numerical epsilon |
real eps |
parameter (eps=0.001) |
c A single command term |
character*80 cmd |
character*80 var,mode |
integer nval |
real val(1000) |
integer ntim |
real tim(1000) |
character*80 tmode |
c Specification of a polygon |
character*80 filename |
integer pn ! Number of entries in lat/lon poly |
real latpoly(1000) ! List of polygon latitudes |
real lonpoly(1000) ! List of polygon longitudes |
real loninpoly,latinpoly ! Lon/lat inside polygon |
c Specification of a region |
real xcorner(4) |
real ycorner(4) |
integer iregion |
character*80 string |
c Transformation to UPN (handling of logical operators) |
integer nlogical |
integer ilogical(n) |
real tmp(n) |
integer mlogical |
integer isor |
c Auxiliary variables |
integer i,j |
integer j1,j2 |
integer flag(ntimes) |
integer count |
integer ok |
integer itrigger,ttrigger |
c Common block for initialisation of polygon check |
real tlonv(1000),vlat_c(1000),vlon_c(1000) |
real xlat_c,xlon_c |
integer ibndry,nv_c |
common /spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry |
c ------ Decode single commands --------------------- |
c Reset the filename for polygons |
filename='nil' |
c Reset the counter for logical commands |
nlogical=0 |
c Loop through all commands |
100 continue |
c Read next command (handle special cases) |
read(fid,*) cmd |
c Special handling of SPECIAL commands |
if ( cmd.eq.'SPECIAL' ) then |
c Set the flag for SPECIAL command |
n = 1 |
out(n) = 0. |
c Read the command string |
read(fid,*) var |
c Add the command string |
n = n + 1 |
out(n) = len_trim(var) |
do j=1,len_trim(var) |
n = n + 1 |
out(n) = ichar(var(j:j)) |
enddo |
c Read the parameters |
read(fid,*) nval |
read(fid,*) (val(i),i=1,nval) |
c Add the parameters |
n = n + 1 |
out(n)=real(nval) |
do i=1,nval |
n=n+1 |
out(n)=val(i) |
enddo |
c Goto exit point - nothing more top do |
goto 350 |
endif |
c Handle structure commands |
if ( cmd.eq.'BEGIN') then |
out(1)=-1. |
n=1 |
nlogical=1 |
ilogical(1)=n |
goto 200 |
elseif ( cmd.eq.'AND' ) then |
n=n+1 |
out(n)=-3. |
nlogical=nlogical+1 |
ilogical(nlogical)=n |
goto 200 |
elseif ( cmd.eq.'OR' ) then |
n=n+1 |
out(n)=-4. |
nlogical=nlogical+1 |
ilogical(nlogical)=n |
goto 200 |
elseif ( cmd.eq.'END' ) then |
n=n+1 |
out(n)=-2. |
nlogical=nlogical+1 |
ilogical(nlogical)=n |
goto 300 |
endif |
c Read other fields associated with the command |
read(fid,*) var,mode |
c Read parameter |
if ( var.eq.'INPOLYGON' ) then |
read(fid,*) nval |
read(fid,*) filename |
filename = trim(filename) |
else |
read(fid,*) nval |
read(fid,*) (val(i),i=1,nval) |
endif |
c Read times (on request, change to special trigger times) |
read(fid,*) ntim |
if ( ntim.eq.-993 ) then |
ttrigger = 1 |
ntim = 1 |
tim(1) = -999. |
else |
ttrigger = 0 |
read(fid,*) (tim(i),i=1,ntim) |
endif |
read(fid,*) tmode |
c Bring CAPITAL "TIME,LAT,LON,P" into "time,lat,lon,p" |
if (var.eq.'TIME') var='time' |
if (var.eq.'LAT' ) var='lat' |
if (var.eq.'LON' ) var='lon' |
if (var.eq.'P' ) var='p' |
c If the time mode is 'TRIGGER', all times of a trajectory |
c must be considered |
if ( tmode.eq.'TRIGGER' ) then |
itrigger = nint(tim(1)) |
ntim = 1 |
tim(1) = -999. |
endif |
c Special times: transform into real time |
do i=1,ntim |
if ( abs(tim(i)+996.).lt.eps ) tim(i)=times(1) |
if ( abs(tim(i)+995.).lt.eps ) tim(i)=times(ntimes) |
enddo |
c Check whether times are valid |
ok=0 |
do i=1,ntim |
if ( (abs(tim(i)+994.).gt.eps).and. |
> (abs(tim(i)+999.).gt.eps) ) |
> then |
do j=1,ntimes |
if ( abs(tim(i)-times(j)).lt.eps ) then |
ok=ok+1 |
endif |
enddo |
else |
ok=ok+1 |
endif |
enddo |
if (ok.ne.ntim) goto 400 |
c Select all times which are included in the criterion |
do i=1,ntimes |
flag(i)=0 |
enddo |
i=1 |
150 if (i.le.ntim) then |
c A list of times |
if ( (abs(tim(i)+994.).lt.eps) ) then |
j1=0 |
do j=1,ntimes |
if ( abs(tim(i-1)-times(j)).lt.eps ) then |
j1=j |
endif |
enddo |
j2=0 |
do j=1,ntimes |
if ( abs(tim(i+1)-times(j)).lt.eps ) then |
j2=j |
endif |
enddo |
if ( (j1.eq.0).or.(j2.eq.0) ) goto 400 |
do j=j1,j2 |
flag(j)=1 |
enddo |
i=i+1 |
c Explicitly given time value |
else |
do j=1,ntimes |
if ( abs(tim(i)-times(j)).lt.eps ) then |
flag(j)=1 |
endif |
enddo |
endif |
i=i+1 |
goto 150 |
endif |
c Write command identifier |
n=n+1 |
if (cmd.eq.'GT' ) out(n)= 1. |
if (cmd.eq.'LT' ) out(n)= 2. |
if (cmd.eq.'IN' ) out(n)= 3. |
if (cmd.eq.'OUT' ) out(n)= 4. |
if (cmd.eq.'EQ' ) out(n)= 5. |
if (cmd.eq.'TRUE' ) out(n)= 6. |
if (cmd.eq.'FALSE' ) out(n)= 7. |
if (cmd.eq.'ALL ' ) out(n)= 8. |
if (cmd.eq.'ANY ' ) out(n)= 9. |
if (cmd.eq.'NONE ' ) out(n)=10. |
c Write index for variable - force implicit trigger |
ok=0 |
do j=1,nvars |
if (vars(j).eq.var) ok=j |
enddo |
if (var.eq.'TRIGGER') ok = 0 |
if (ok.eq.0) then |
if (var.eq.'DIST') then |
ok = -1 |
elseif (var.eq.'DIST0') then |
ok = -2 |
elseif (var.eq.'INPOLYGON') then |
ok = -3 |
elseif (var.eq.'INBOX') then |
ok = -4 |
elseif (var.eq.'INCIRCLE') then |
ok = -5 |
elseif (var.eq.'INREGION') then |
ok = -6 |
elseif (var.eq.'TRIGGER') then |
ok = -7 |
elseif (var.eq.'VERT0') then |
ok = -8 |
else |
goto 400 |
endif |
endif |
n=n+1 |
out(n)=real(ok) |
c Write mode for variable |
ok=0 |
if (mode.eq.'VALUE' ) ok=1 |
if (mode.eq.'MEAN' ) ok=2 |
if (mode.eq.'MAX' ) ok=3 |
if (mode.eq.'MIN' ) ok=4 |
if (mode.eq.'VAR' ) ok=5 |
if (mode.eq.'SUM' ) ok=6 |
if (mode.eq.'CHANGE' ) ok=7 |
if (mode.eq.'DIFF' ) ok=8 |
if (mode.eq.'RANGE' ) ok=9 |
if (ok.eq.0) goto 400 |
n=n+1 |
out(n)=real(ok) |
c Write the parameter values: INPOLYGON |
if ( var.eq.'INPOLYGON' ) then |
n = n+1 |
out(n) = len_trim(filename) |
do j=1,len_trim(filename) |
n = n + 1 |
out(n) = ichar(filename(j:j)) |
enddo |
c Write parameter value: INREGION |
elseif ( var.eq.'INREGION' ) then |
iregion = nint(val(1)) |
open(fid+1,file=regionf) |
50 read(fid+1,*,end=51) string |
if ( string(1:1).ne.'#' ) then |
call regionsplit(string,i,xcorner,ycorner) |
if ( i.eq.iregion ) goto 52 |
endif |
goto 50 |
51 close(fid+1) |
print*,' ERROR: region ',iregion,' not found on ', |
> trim(regionf) |
stop |
52 continue |
n = n + 1 |
out(n) = 8 ! Number of parameters |
do i=1,4 |
n = n + 1 |
out(n) = xcorner(i) |
enddo |
do i=1,4 |
n = n + 1 |
out(n) = ycorner(i) |
enddo |
c Write parameter values: all other cases |
else |
n=n+1 |
out(n)=real(nval) |
do i=1,nval |
n=n+1 |
out(n)=val(i) |
enddo |
endif |
c Special time handling: only trigger times are cosidered |
if ( ttrigger.eq.1 ) then |
n = n+1 |
out(n)=-993. |
c All times are selected |
elseif ( abs(tim(1)+999.).lt.eps ) then |
n=n+1 |
out(n)=real(ntimes) |
do i=1,ntimes |
n=n+1 |
out(n)=real(i) |
enddo |
c A selection of times is given |
else |
count=0 |
do i=1,ntimes |
count=count+flag(i) |
enddo |
n=n+1 |
out(n)=real(count) |
do i=1,ntimes |
if (flag(i).eq.1) then |
n=n+1 |
out(n)=real(i) |
endif |
enddo |
endif |
c Write the time mode |
if ( tmode.eq.'ALL') then |
n=n+1 |
out(n)=1. |
elseif ( tmode.eq.'ANY') then |
n=n+1 |
out(n)=2. |
elseif ( tmode.eq.'NONE') then |
n=n+1 |
out(n)=3. |
elseif ( tmode.eq.'TRIGGER') then |
n=n+1 |
out(n)=-real(itrigger) |
endif |
c End loop: handle single command |
200 continue |
goto 100 |
c End loop: loop over all commands |
300 continue |
c ------ Read polygon file, if requested ----------- |
if ( filename.ne.'nil' ) then |
print* |
print*, |
> '---- POLYGON --------------------------------------------' |
print* |
print*,'Filename = ',trim(filename) |
print* |
c Read list of polygon coordinates from file |
pn = 0 |
open(fid+1,file=filename) |
read(fid+1,*) loninpoly,latinpoly |
print*,'Inside (lon/lat) =',loninpoly,latinpoly |
print* |
510 continue |
pn = pn + 1 |
read(fid+1,*,end=511) lonpoly(pn), |
> latpoly(pn) |
print*,pn,lonpoly(pn),latpoly(pn) |
goto 510 |
511 continue |
pn = pn - 1 |
close(fid+1) |
c Define the polygon boundaries |
call DefSPolyBndry(latpoly,lonpoly,pn,latinpoly,loninpoly) |
endif |
c ------ Transform to UPN -------------------------- |
c Check whether logical commands are ok |
mlogical=nint(out(ilogical(1))) |
if ( mlogical.ne.-1) goto 400 |
mlogical=nint(out(ilogical(nlogical))) |
if ( mlogical.ne.-2) goto 400 |
c No transformation necessary if only one command |
if (nlogical.eq.2) goto 350 |
c Copy the output to temporary list |
do i=1,n |
tmp(i)=out(i) |
enddo |
c Set BEGIN statement |
n=1 |
out(n)=-1. |
c Reorder commands and transform to UPN |
isor=0 |
do i=1,nlogical-1 |
c Get the logical command |
mlogical=nint(out(ilogical(i))) |
c Connecting OR |
if (mlogical.eq.-4) then |
if (isor.eq.1) then |
n=n+1 |
out(n)=-4. |
else |
isor=1 |
endif |
endif |
c Put the command onto the stack |
do j=ilogical(i)+1,ilogical(i+1)-1 |
n=n+1 |
out(n)=tmp(j) |
enddo |
c Connecting AND operator |
if ( mlogical.eq.-3 ) then |
n=n+1 |
out(n)=-3. |
endif |
enddo |
c Set final connecting OR |
if (isor.eq.1) then |
n=n+1 |
out(n)=-4. |
endif |
c Set END statement |
n=n+1 |
out(n)=-2. |
c ------ Exit point --------------------------------- |
350 continue |
return |
c ----- Exception handling -------------------------- |
400 print*,'Invalid selection criterion... Stop' |
stop |
end |
c -------------------------------------------------------------- |
c Decide whether a trajectory is selected or not |
c -------------------------------------------------------------- |
subroutine select_tra (select,cmd,n,tra,trigger,ntim,ncol) |
c Decide whether a single trajectory is selected (<select=1>) or |
c is not selected <select=0> according to the selection criterion |
c given in <cmd(ncmd)>. The selection criterion <cmd(ncmd)> is |
c returned from the call to the subroutine <decode>. The trajectory |
c is given in <tra(ntim,ncol)> where <ntim> is the number of times |
c and <ncol> is the number of columns. |
c |
c Important note: the structure of <tra(ntim,ncol)> must match to the |
c call parameter <vars,nvars,times,ntimes> in subroutine <decode>. |
implicit none |
c Declaration of subroutine parameters |
integer select |
integer n |
real cmd(n) |
integer ntim,ncol |
real tra(ntim,ncol) |
integer trigger(ntim) |
c Numerical epsilon (for test of equality) |
real eps |
parameter (eps=0.000001) |
c A single command and the associated field |
integer icmd,ivar,imode,itime,nsel,nval |
integer time(ntim) |
real param(100) |
real var (ntim) |
integer intvar(ntim) |
c Boolean values for a single time, a single command and build-up |
integer stack(100) |
integer nstack |
integer istrue(ntim) |
integer decision |
c Auxiliary variables |
integer i,j,k |
real tmp,mea |
integer istack1,istack2 |
real lat0,lon0,lat1,lon1 |
real length(ntim) |
integer flag |
real dist |
real xcorner(4),ycorner(4) |
integer iparam |
character ch |
real varmin,varmax |
real lev0,lev1 |
c Common block for initialisation of polygon check |
real tlonv(1000),vlat_c(1000),vlon_c(1000) |
real xlat_c,xlon_c |
integer ibndry,nv_c |
common /spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry |
c Externals |
real sdis ! Spherical distance |
external sdis |
integer inregion ! Boolean flag for regions |
external inregion |
c Reset the decision stack (with locical values) |
nstack=0 |
c Loop through the complete command list |
i=0 |
100 if (i.lt.n) then |
c --- Get the command ------------------------------- |
i=i+1 |
icmd=nint(cmd(i)) |
c --- Handle structural commands (BEGIN, END, AND, OR) |
c Handle BEGIN statement |
if ( icmd.eq.-1) then |
nstack=0 |
goto 200 |
endif |
c Handle END statement |
if (icmd.eq.-2) then |
goto 300 |
endif |
c Handle AND statement |
if (icmd.eq.-3) then |
istack1=stack(nstack) |
nstack=nstack-1 |
istack2=stack(nstack) |
if ((istack1.eq.1).and.(istack2.eq.1)) then |
stack(nstack)=1 |
else |
stack(nstack)=0 |
endif |
goto 200 |
endif |
c Handle OR statement |
if (icmd.eq.-4) then |
istack1=stack(nstack) |
nstack=nstack-1 |
istack2=stack(nstack) |
if ((istack1.eq.1).or.(istack2.eq.1)) then |
stack(nstack)=1 |
else |
stack(nstack)=0 |
endif |
goto 200 |
endif |
c --- Get all command details (parameters, modes, times) |
c Get variable (<ivar> gets the column index in <tra>) |
i=i+1 |
ivar=nint(cmd(i)) |
c Get variable mode |
i=i+1 |
imode=nint(cmd(i)) |
c Get parameter values |
i=i+1 |
nval=nint(cmd(i)) |
do j=1,nval |
i=i+1 |
param(j)=cmd(i) |
enddo |
c Get times (<time(j)> gets the row indices of <tra>) |
i=i+1 |
nsel=nint(cmd(i)) |
if ( nsel .eq. -993 ) then |
nsel = 0 |
do k=1,ntim |
if ( trigger(k).ne.0 ) then |
nsel = nsel + 1 |
time(nsel) = k |
endif |
enddo |
else |
do j=1,nsel |
i=i+1 |
time(j)=nint(cmd(i)) |
enddo |
endif |
c If no times are selected, exit with non-select status |
if ( nsel.eq.0 ) then |
stack(1) = 0 |
goto 300 |
endif |
c Get time mode |
i=i+1 |
itime=nint(cmd(i)) |
c --- Prepare field values for analysis ----------- |
c Implicit variable: DIST |
if ( ivar.eq. -1 ) then |
length(1) = 0. |
do j=2,ntim |
lon0 = tra(j-1,2) |
lat0 = tra(j-1,3) |
lon1 = tra(j ,2) |
lat1 = tra(j ,3) |
length(j) = length(j-1) + sdis(lon0,lat0,lon1,lat1) |
enddo |
do j=1,nsel |
var(j) = length( time(j) ) |
enddo |
c Implict variable: DIST0 |
elseif ( ivar.eq. -2 ) then |
do j=1,nsel |
lon0 = tra(1 ,2) |
lat0 = tra(1 ,3) |
lon1 = tra(time(j),2) |
lat1 = tra(time(j),3) |
var(j) = sdis(lon0,lat0,lon1,lat1) |
enddo |
c Implict variable: INPOLYGON |
elseif ( ivar.eq. -3 ) then |
do j=1,nsel |
lon1 = tra(time(j),2) |
lat1 = tra(time(j),3) |
call LctPtRelBndry(lat1,lon1,flag) |
if ( (flag.eq.1).or.(flag.eq.2) ) then |
var(j) = 1. |
else |
var(j) = 0. |
endif |
enddo |
c Implict variable: INBOX |
elseif ( ivar.eq. -4 ) then |
do j=1,nsel |
lon1 = tra(time(j),2) |
lat1 = tra(time(j),3) |
if ( ( lon1.ge.param(1) ).and. ! lonmin |
> ( lon1.le.param(2) ).and. ! lonmax |
> ( lat1.ge.param(3) ).and. ! latmin |
> ( lat1.le.param(4) ) ) ! latmax |
> then |
var(j) = 1 |
else |
var(j) = 0 |
endif |
enddo |
c Implict variable: INCIRCLE (lonc=param(1),latc=param(2),radius=param(3)) |
elseif ( ivar.eq. -5 ) then |
do j=1,nsel |
lon1 = tra(time(j),2) |
lat1 = tra(time(j),3) |
dist = sdis( lon1,lat1,param(1),param(2) ) |
if ( dist.le.param(3) ) then |
var(j) = 1 |
else |
var(j) = 0 |
endif |
enddo |
c Implict variable: INREGION (xcorner=param(1..4),ycorner=param(5..8) ) |
elseif ( ivar.eq.-6 ) then |
do j=1,4 |
xcorner(j) = param(j ) |
ycorner(j) = param(j+4) |
enddo |
do j=1,nsel |
lon1 = tra(time(j),2) |
lat1 = tra(time(j),3) |
var(j) = inregion (lon1,lat1,xcorner,ycorner) |
enddo |
c Implict variable: TRIGGER |
elseif ( ivar.eq. -7 ) then |
do j=1,nsel |
intvar(j) = trigger( time(j) ) |
enddo |
c Implicit variable: VERT0 |
elseif ( ivar.eq. -8 ) then |
do j=1,nsel |
lev0 = tra(1 ,4) |
lev1 = tra(time(j),4) |
var(j) = lev0 - lev1 |
enddo |
c Explicit variable (column index <ivar>) |
else |
do j=1,nsel |
var(j) = tra(time(j),ivar) |
enddo |
endif |
c Take MEAN of the variable (mean of selected times) |
if (imode.eq.2) then |
tmp=0. |
do j=1,nsel |
tmp=tmp+var(j) |
enddo |
var(1)=tmp/real(nsel) |
nsel=1 |
c Take MAX of the variable (maximum of selected times) |
elseif (imode.eq.3) then |
tmp=var(1) |
do j=2,nsel |
if (var(j).gt.tmp) tmp=var(j) |
enddo |
var(1)=tmp |
nsel=1 |
c Take MIN of the variable (minimum of selected times) |
elseif (imode.eq.4) then |
tmp=var(1) |
do j=2,nsel |
if (var(j).lt.tmp) tmp=var(j) |
enddo |
var(1)=tmp |
nsel=1 |
c Take VAR of the variable (variance over all selected times) |
elseif (imode.eq.5) then |
tmp=0. |
do j=1,nsel |
tmp=tmp+var(j) |
enddo |
mea=tmp/real(nsel) |
do j=1,nsel |
tmp=tmp+(var(j)-mea)**2 |
enddo |
var(1)=1./real(nsel-1)*tmp |
nsel=1 |
c Take SUM of the variable (sum over all selected times) |
elseif (imode.eq.6) then |
tmp=0. |
do j=1,nsel |
tmp=tmp+var(j) |
enddo |
var(1)=tmp |
nsel=1 |
c Take CHANGE of the variable (absolute difference between first and last time) |
elseif (imode.eq.7) then |
var(1)=abs(var(1)-var(nsel)) |
nsel=1 |
c Take DIFF of the variable (first minus last time) |
elseif (imode.eq.8) then |
var(1)=var(1)-var(nsel) |
nsel=1 |
c Take RANGE of the variable |
elseif (imode.eq.9) then |
varmax=var(1) |
varmin=var(1) |
do j=2,nsel |
if (var(j).gt.varmax) varmax=var(j) |
if (var(j).lt.varmin) varmin=var(j) |
enddo |
var(1) = varmax - varmin |
nsel=1 |
endif |
c --- Apply the operators to the single values --- |
do j=1,nsel |
c GT |
if (icmd.eq.1) then |
if (var(j).gt.param(1)) then |
istrue(j)=1 |
else |
istrue(j)=0 |
endif |
c LT |
elseif (icmd.eq.2) then |
if (var(j).lt.param(1)) then |
istrue(j)=1 |
else |
istrue(j)=0 |
endif |
c IN |
elseif (icmd.eq.3) then |
if ( (var(j).gt.param(1)).and. |
> (var(j).lt.param(2)) ) |
> then |
istrue(j)=1 |
else |
istrue(j)=0 |
endif |
c OUT |
elseif (icmd.eq.4) then |
if ( (var(j).lt.param(1)).or. |
> (var(j).gt.param(2)) ) |
> then |
istrue(j)=1 |
else |
istrue(j)=0 |
endif |
c EQ |
elseif (icmd.eq.5) then |
if (abs(var(j)-param(1)).lt.eps) then |
istrue(j)=1 |
else |
istrue(j)=0 |
endif |
c TRUE |
elseif (icmd.eq.6) then |
if (abs(var(j)).lt.eps) then |
istrue(j)=0 |
else |
istrue(j)=1 |
endif |
c FALSE |
elseif (icmd.eq.7) then |
if (abs(var(j)).lt.eps) then |
istrue(j)=1 |
else |
istrue(j)=0 |
endif |
c ALL |
elseif (icmd.eq.8) then |
istrue(j) = 1 |
do k=1,nval |
iparam = nint(param(k))-1 |
if (btest(intvar(j),iparam).eqv..false.) then |
istrue(j) = 0 |
endif |
enddo |
c ANY |
elseif (icmd.eq.9) then |
istrue(j) = 0 |
do k=1,nval |
iparam = nint(param(k))-1 |
if (btest(intvar(j),iparam).eqv..true.) then |
istrue(j) = 1 |
endif |
enddo |
c NONE |
elseif (icmd.eq.10) then |
istrue(j) = 1 |
do k=1,nval |
iparam = nint(param(k))-1 |
if (btest(intvar(j),iparam).eqv..true.) then |
istrue(j) = 0 |
endif |
enddo |
endif |
enddo |
c --- Determine the overall boolean value ---------- |
c ALL |
if (itime.eq.1) then |
decision=1 |
do j=1,nsel |
if (istrue(j).eq.0) then |
decision=0 |
goto 110 |
endif |
enddo |
110 continue |
c ANY |
elseif (itime.eq.2) then |
decision=0 |
do j=1,nsel |
if (istrue(j).eq.1) then |
decision=1 |
goto 120 |
endif |
enddo |
120 continue |
c NONE |
elseif (itime.eq.3) then |
decision=1 |
do j=1,nsel |
if (istrue(j).eq.1) then |
decision=0 |
goto 130 |
endif |
enddo |
130 continue |
c TRIGGER |
elseif (itime.lt.0) then |
decision=1 |
do j=1,nsel |
if (istrue(j).eq.1) then |
trigger(j) = ior( trigger(j), 2**(abs(itime)-1) ) |
endif |
enddo |
endif |
c --- Put the new boolean value onto the stack |
nstack=nstack+1 |
stack(nstack)=decision |
c Exit point for loop |
200 continue |
goto 100 |
endif |
c Return the decision (selected or non-selected) |
300 continue |
select=stack(1) |
end |
c -------------------------------------------------------------------------- |
c Split a region string and get corners of the domain |
c -------------------------------------------------------------------------- |
subroutine regionsplit(string,iregion,xcorner,ycorner) |
c The region string comes either as <lonw,lone,lats,latn> or as <lon1,lat1, |
c lon2,lat2,lon3,lat3,lon4,lat4>: split it into ints components and get the |
c four coordinates for the region |
implicit none |
c Declaration of subroutine parameters |
character*80 string |
real xcorner(4),ycorner(4) |
integer iregion |
c Local variables |
integer i,n |
integer il,ir |
real subfloat (80) |
integer stat |
integer len |
c ------- Split the string |
i = 1 |
n = 0 |
stat = 0 |
il = 1 |
len = len_trim(string) |
100 continue |
c Find start of a substring |
do while ( stat.eq.0 ) |
if ( string(i:i).ne.' ' ) then |
stat = 1 |
il = i |
else |
i = i + 1 |
endif |
enddo |
c Find end of substring |
do while ( stat.eq.1 ) |
if ( ( string(i:i).eq.' ' ) .or. ( i.eq.len ) ) then |
stat = 2 |
ir = i |
else |
i = i + 1 |
endif |
enddo |
c Convert the substring into a number |
if ( stat.eq.2 ) then |
n = n + 1 |
read(string(il:ir),*) subfloat(n) |
stat = 0 |
endif |
if ( i.lt.len ) goto 100 |
c -------- Get the region number |
iregion = nint(subfloat(1)) |
c -------- Get the corners of the region |
if ( n.eq.5 ) then ! lonw(2),lone(3),lats(4),latn(5) |
xcorner(1) = subfloat(2) |
ycorner(1) = subfloat(4) |
xcorner(2) = subfloat(3) |
ycorner(2) = subfloat(4) |
xcorner(3) = subfloat(3) |
ycorner(3) = subfloat(5) |
xcorner(4) = subfloat(2) |
ycorner(4) = subfloat(5) |
elseif ( n.eq.9 ) then ! lon1,lat1,lon2,lat2,lon3,lon4,lat4 |
xcorner(1) = subfloat(2) |
ycorner(1) = subfloat(3) |
xcorner(2) = subfloat(4) |
ycorner(2) = subfloat(5) |
xcorner(3) = subfloat(6) |
ycorner(3) = subfloat(7) |
xcorner(4) = subfloat(8) |
ycorner(4) = subfloat(9) |
else |
print*,' ERROR: invalid region specification ' |
print*,' ',trim(string) |
stop |
endif |
end |
c -------------------------------------------------------------------------- |
c Decide whether lat/lon point is in or out of region |
c -------------------------------------------------------------------------- |
integer function inregion (lon,lat,xcorner,ycorner) |
c Decide whether point (lon/lat) is in the region specified by <xcorner(1..4), |
c ycorner(1..4). |
implicit none |
c Declaration of subroutine parameters |
real lon,lat |
real xcorner(4),ycorner(4) |
c Local variables |
integer flag |
real xmin,xmax,ymin,ymax |
integer i |
c Reset the flag |
flag = 0 |
c Set some boundaries |
xmax = xcorner(1) |
xmin = xcorner(1) |
ymax = ycorner(1) |
ymin = ycorner(1) |
do i=2,4 |
if (xcorner(i).lt.xmin) xmin = xcorner(i) |
if (xcorner(i).gt.xmax) xmax = xcorner(i) |
if (ycorner(i).lt.ymin) ymin = ycorner(i) |
if (ycorner(i).gt.ymax) ymax = ycorner(i) |
enddo |
c Do the tests - set flag=1 if all tests pased |
if (lon.lt.xmin) goto 970 |
if (lon.gt.xmax) goto 970 |
if (lat.lt.ymin) goto 970 |
if (lat.gt.ymax) goto 970 |
if ((lon-xcorner(1))*(ycorner(2)-ycorner(1))- |
> (lat-ycorner(1))*(xcorner(2)-xcorner(1)).gt.0.) goto 970 |
if ((lon-xcorner(2))*(ycorner(3)-ycorner(2))- |
> (lat-ycorner(2))*(xcorner(3)-xcorner(2)).gt.0.) goto 970 |
if ((lon-xcorner(3))*(ycorner(4)-ycorner(3))- |
> (lat-ycorner(3))*(xcorner(4)-xcorner(3)).gt.0.) goto 970 |
if ((lon-xcorner(4))*(ycorner(1)-ycorner(4))- |
> (lat-ycorner(4))*(xcorner(1)-xcorner(4)).gt.0.) goto 970 |
flag = 1 |
c Return the value |
970 continue |
inregion = flag |
return |
end |
c -------------------------------------------------------------------------- |
c Spherical distance between lat/lon points |
c -------------------------------------------------------------------------- |
real function sdis(xp,yp,xq,yq) |
c |
c calculates spherical distance (in km) between two points given |
c by their spherical coordinates (xp,yp) and (xq,yq), respectively. |
c |
real re |
parameter (re=6370.) |
real pi180 |
parameter (pi180=3.14159/180.) |
real xp,yp,xq,yq,arg |
arg=sin(pi180*yp)*sin(pi180*yq)+ |
> cos(pi180*yp)*cos(pi180*yq)*cos(pi180*(xp-xq)) |
if (arg.lt.-1.) arg=-1. |
if (arg.gt.1.) arg=1. |
sdis=re*acos(arg) |
end |
c **************************************************************** |
c * Given some spherical polygon S and some point X known to be * |
c * located inside S, these routines will determine if an arbit- * |
c * -rary point P lies inside S, outside S, or on its boundary. * |
c * The calling program must first call DefSPolyBndry to define * |
c * the boundary of S and the point X. Any subsequent call to * |
c * subroutine LctPtRelBndry will determine if some point P lies * |
c * inside or outside S, or on its boundary. (Usually * |
c * DefSPolyBndry is called once, then LctPrRelBndry is called * |
c * many times). * |
c * * |
c * REFERENCE: Bevis, M. and Chatelain, J.-L. (1989) * |
c * Maflaematical Geology, vol 21. * |
c * VERSION 1.0 * |
c **************************************************************** |
Subroutine DefSPolyBndry(vlat,vlon,nv,xlat, xlon) |
c **************************************************************** |
c * This mmn entry point is used m define ~e spheric~ polygon S * |
c * and the point X. * |
c * ARGUMENTS: * |
c * vlat,vlon (sent) ... vectors containing the latitude and * |
c * longitude of each vertex of the * |
c * spherical polygon S. The ith.vertex is * |
c * located at [vlat(i),vlon(i)]. * |
c * nv (sent) ... the number of vertices and sides in the * |
c * spherical polygon S * |
c * xlat,xlon (sent) ... latitude and longitude of some point X * |
c * located inside S. X must not be located * |
c * on any great circle that includes two * |
c * vertices of S. * |
c * * |
c * UNITS AND SIGN CONVENTION: * |
c * Latitudes and longitudes are specified in degrees. * |
c * Latitudes are positive to the north and negative to the * |
c * south. * |
c * Longitudes are positive to the east and negative to the * |
c * west. * |
c * * |
c * VERTEX ENUMERATION: * |
c * The vertices of S should be numbered sequentially around the * |
c * border of the spherical polygon. Vertex 1 lies between vertex* |
c * nv and vertex 2. Neighbouring vertices must be seperated by * |
c * less than 180 degrees. (In order to generate a polygon side * |
c * whose arc length equals or exceeds 180 degrees simply * |
c * introduce an additional (pseudo)vertex). Having chosen * |
c * vertex 1, the user may number the remaining vertices in * |
c * either direction. However if the user wishes to use the * |
c * subroutine SPA to determine the area of the polygon S (Bevis * |
c * & Cambareri, 1987, Math. Geol., v.19, p. 335-346) then he or * |
c * she must follow the convention whereby in moving around the * |
c * polygon border in the direction of increasing vertex number * |
c * clockwise bends occur at salient vertices. A vertex is * |
c * salient if the interior angle is less than 180 degrees. * |
c * (In the case of a convex polygon this convention implies * |
c * that vertices are numbered in clockwise sequence). * |
c **************************************************************** |
implicit none |
integer mxnv,nv |
c ---------------------------------------------------------------- |
c Edit next statement to increase maximum number of vertices that |
c may be used to define the spherical polygon S |
c The value of parameter mxnv in subroutine LctPtRelBndry must match |
c that of parameter mxnv in this subroutine, as assigned above. |
c ---------------------------------------------------------------- |
parameter (mxnv=2000) |
real vlat(nv),vlon(nv),xlat,xlon,dellon |
real tlonv(mxnv),vlat_c(mxnv),vlon_c(mxnv),xlat_c,xlon_c |
integer i,ibndry,nv_c,ip |
data ibndry/0/ |
common/spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry |
if (nv.gt.mxnv) then |
print *,'nv exceeds maximum allowed value' |
print *,'adjust parameter mxnv in subroutine DefSPolyBndry' |
stop |
endif |
ibndry=1 ! boundary defined at least once (flag) |
nv_c=nv ! copy for named common |
xlat_c=xlat ! . . . . |
xlon_c=xlon ! |
do i=1,nv |
vlat_c(i)=vlat(i) ! " |
vlon_c(i)=vlon(i) ! |
call TrnsfmLon(xlat,xlon,vlat(i),vlon(i),tlonv(i)) |
if (i.gt.1) then |
ip=i-1 |
else |
ip=nv |
endif |
if ((vlat(i).eq.vlat(ip)).and.(vlon(i).eq.vlon(ip))) then |
print *,'DefSPolyBndry detects user error:' |
print *,'vertices ',i,' and ',ip,' are not distinct' |
print*,'lat ',i,ip,vlat(i),vlat(ip) |
print*,'lon ',i,ip,vlon(i),vlon(ip) |
stop |
endif |
if (tlonv(i).eq.tlonv(ip)) then |
print *,'DefSPolyBndry detects user error:' |
print *,'vertices ',i,' & ',ip,' on same gt. circle as X' |
stop |
endif |
if (vlat(i).eq.(-vlat(ip))) then |
dellon=vlon(i)-vlon(ip) |
if (dellon.gt.+180.) dellon=dellon-360. |
if (dellon.lt.-180.) dellon=dellon-360. |
if ((dellon.eq.+180.0).or.(dellon.eq.-180.0)) then |
print *,'DefSPolyBndry detects user error:' |
print *,'vertices ',i,' and ',ip,' are antipodal' |
stop |
endif |
endif |
enddo |
return |
end |
c **************************************************************** |
Subroutine LctPtRelBndry(plat,plon,location) |
c **************************************************************** |
c **************************************************************** |
c * This routine is used to see if some point P is located * |
c * inside, outside or on the boundary of the spherical polygon * |
c * S previously defined by a call to subroutine DefSPolyBndry. * |
c * There is a single restriction on point P: it must not be * |
c * antipodal to the point X defined in the call to DefSPolyBndry* |
c * (ie.P and X cannot be seperated by exactly 180 degrees). * |
c * ARGUMENTS: * |
c * plat,plon (sent)... the latitude and longitude of point P * |
c * location (returned)... specifies the location of P: * |
c * location=0 implies P is outside of S * |
c * location=1 implies P is inside of S * |
c * location=2 implies P on boundary of S * |
c * location=3 implies user error (P is * |
c * antipodal to X) * |
c * UNFfS AND SIGN CONVENTION: * |
c * Latitudes and longitudes are specified in degrees. * |
c * Latitudes are positive to the north and negative to the * |
c * south. * |
c * Longitudes are positive to the east and negative to the * |
c * west. * |
c **************************************************************** |
implicit none |
integer mxnv |
c ---------------------------------------------------------------- |
c The statement below must match that in subroutine DefSPolyBndry |
c ---------------------------------------------------------------- |
parameter (mxnv=2000) |
real tlonv(mxnv),vlat_c(mxnv),vlon_c(mxnv),xlat_c,xlon_c |
real plat,plon,vAlat,vAlon,vBlat,vBlon,tlonA,tlonB,tlonP |
real tlon_X,tlon_P,tlon_B,dellon |
integer i,ibndry,nv_c,location,icross,ibrngAB,ibrngAP,ibrngPB |
integer ibrng_BX,ibrng_BP,istrike |
common/spolybndry/vlat_c,vlon_c,nv_c,xlat_c,xlon_c,tlonv,ibndry |
if (ibndry.eq.0) then ! user has never defined the bndry |
print*,'Subroutine LctPtRelBndry detects user error:' |
print*,'Subroutine DefSPolyBndry must be called before' |
print*,'subroutine LctPtRelBndry can be called' |
stop |
endif |
if (plat.eq.(-xlat_c)) then |
dellon=plon-xlon_c |
if (dellon.lt.(-180.)) dellon=dellon+360. |
if (dellon.gt.+180.) dellon=dellon-360. |
if ((dellon.eq.+180.0).or.(dellon.eq.-180.)) then |
print*,'Warning: LctPtRelBndry detects case P antipodal |
> to X' |
print*,'location of P relative to S is undetermined' |
location=3 |
return |
endif |
endif |
location=0 ! default ( P is outside S) |
icross=0 ! initialize counter |
if ((plat.eq.xlat_c).and.(plon.eq.xlon_c)) then |
location=1 |
return |
endif |
call TrnsfmLon (xlat_c,xlon_c,plat,plon,tlonP) |
do i=1,nv_c ! start of loop over sides of S |
vAlat=vlat_c(i) |
vAlon=vlon_c(i) |
tlonA=tlonv(i) |
if (i.lt.nv_c) then |
vBlat=vlat_c(i+1) |
vBlon=vlon_c(i+1) |
tlonB=tlonv(i+1) |
else |
vBlat=vlat_c(1) |
vBlon=vlon_c(1) |
tlonB=tlonv(1) |
endif |
istrike=0 |
if (tlonP.eq.tlonA) then |
istrike=1 |
else |
call EastOrWest(tlonA,tlonB,ibrngAB) |
call EastOrWest(tlonA,tlonP,ibrngAP) |
call EastOrWest(tlonP,tlonB,ibrngPB) |
if((ibrngAP.eq.ibrngAB).and.(ibrngPB.eq.ibrngAB)) istrike=1 |
endif |
if (istrike.eq.1) then |
if ((plat.eq.vAlat).and.(plon.eq.vAlon)) then |
location=2 ! P lies on a vertex of S |
return |
endif |
call TrnsfmLon(vAlat,vAlon,xlat_c,xlon_c,tlon_X) |
call TrnsfmLon(vAlat,vAlon,vBlat,vBlon,tlon_B) |
call TrnsfmLon(vAlat,vAlon,plat,plon,tlon_P) |
if (tlon_P.eq.tlon_B) then |
location=2 ! P lies on side of S |
return |
else |
call EastOrWest(tlon_B,tlon_X,ibrng_BX) |
call EastOrWest(tlon_B,tlon_P,ibrng_BP) |
if(ibrng_BX.eq.(-ibrng_BP)) icross=icross+1 |
endif |
endif |
enddo ! end of loop over the sides of S |
c if the arc XP crosses the boundary S an even number of times then P |
c is in S |
if (mod(icross,2).eq.0) location=1 |
return |
end |
c **************************************************************** |
subroutine TrnsfmLon(plat,plon,qlat,qlon,tranlon) |
c **************************************************************** |
c * This subroutine is required by subroutines DefSPolyBndry & * |
c * LctPtRelBndry. It finds the 'longitude' of point Q in a * |
c * geographic coordinate system for which point P acts as a * |
c * 'north pole'. SENT: plat,plon,qlat,qlon, in degrees. * |
c * RETURNED: tranlon, in degrees. * |
c **************************************************************** |
implicit none |
real pi,dtr,plat,plon,qlat,qlon,tranlon,t,b |
parameter (pi=3.141592654,dtr=pi/180.0) |
if (plat.eq.90.) then |
tranlon=qlon |
else |
t=sin((qlon-plon)*dtr)*cos(qlat*dtr) |
b=sin(dtr*qlat)*cos(plat*dtr)-cos(qlat*dtr)*sin(plat*dtr) |
> *cos((qlon-plon)*dtr) |
tranlon=atan2(t,b)/dtr |
endif |
return |
end |
c **************************************************************** |
subroutine EastOrWest(clon,dlon,ibrng) |
c **************************************************************** |
c * This subroutine is required by subroutine LctPtRelBndry. * |
c * This routine determines if in travelling the shortest path * |
c * from point C (at longitude clon) to point D (at longitude * |
c * dlon) one is heading east, west or neither. * |
c * SENT: clon,dlon; in degrees. RETURNED: ibrng * |
c * (1=east,-1=west, 0=neither). * |
c **************************************************************** |
implicit none |
real clon,dlon,del |
integer ibrng |
del=dlon-clon |
if (del.gt.180.) del=del-360. |
if (del.lt.-180.) del=del+360. |
if ((del.gt.0.0).and.(del.ne.180.)) then |
ibrng=-1 ! (D is west of C) |
elseif ((del.lt.0.0).and.(del.ne.-180.)) then |
ibrng=+1 ! (D is east of C) |
else |
ibrng=0 ! (D north or south of C) |
endif |
return |
end |
/tags/1.0/select/select.make |
---|
0,0 → 1,11 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = special.o select.o ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
.f.o: $*.f |
${F77} -c ${FFLAGS} ${INCS} $*.f |
select: $(OBJS) |
${F77} -o select $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/select/select.perl |
---|
0,0 → 1,220 |
#!/usr/bin/perl |
# -------------------------------------------------------- |
# Separate different commands out (delimiter & and |) |
# -------------------------------------------------------- |
# Get input command and remove all spaces |
$cmd = $ARGV[0]; |
$_ = $cmd;s/\s+//g;$cmd=$_; |
$len = length $cmd; |
# Split the command string according to logical operators |
$nline = 0; |
while ( $len > 0 ) |
{ |
# Get the length of the (remaining) command string |
$len = length $cmd; |
# Get the position of the next command separator |
$and = index($cmd,'&'); |
$or = index($cmd,'|' ); |
if ( ($and == -1) && ($or == -1) ) |
{ $next = $len+1; } |
elsif ( ($and == -1) && ($or >= 0) ) |
{ $next = $or; @logop[$nline] = 'OR'; } |
elsif ( ($and >= 0) && ($or == -1) ) |
{ $next = $and; @logop[$nline] = 'AND'; } |
elsif ($and > $or) |
{ $next = $or; @logop[$nline] = 'OR'; } |
else |
{ $next = $and; @logop[$nline] = 'AND'; } |
# A logical operator is not allowed to be at position 0 |
if ( $next == 0) |
{ |
die('Invalid expression... Check logical operators & and |'); |
} |
# Extract the next substring |
$sub = substr($cmd,0,$next); |
$cmd = substr($cmd,$next+1,$len-$next-1); |
$len = length $cmd; |
# Save the command in a new line |
@field[$nline] = $sub; |
$nline = $nline + 1; |
} |
# -------------------------------------------------------- |
# Handle each command line separately |
# -------------------------------------------------------- |
# Write start marker |
print "BEGIN \n"; |
foreach ( $i = 0; $i < $nline; $i++ ) |
{ |
# Split the command into its four components |
@entry = split /:/, @field[$i]; |
$nentry = @entry; |
# Either four or three elements are needed |
if ( ($nentry < 3) | ($nentry > 4) ) |
{ |
die('Each expression needs either 3 or 4 fields...'); |
} |
# Write the command |
print "@entry[0] \n"; |
# Get the variable and the 'mode' for this variable |
$left = index(@entry[1],'('); |
$right = index(@entry[1],')'); |
if ( ($left == -1) && ($right == -1) ) |
{ |
$var = @entry[1]; |
$mode = 'VALUE'; |
} |
elsif ( ($left > 0) && ($right > $left) ) |
{ |
$var = substr(@entry[1],0,$left); |
$mode = substr(@entry[1],$left+1,$right-$left-1); |
} |
else |
{ |
die('Invalid variable specification...'); |
} |
print "$var $mode \n"; |
# Get the parameter list for this command |
@param = split /,/, @entry[2]; |
$nparam = @param; |
print "$nparam \n"; |
print "@param \n"; |
# If only three parameters are given, the time is assumed to be the first one |
if ( $nentry == 3 ) |
{ |
@entry[3]='FIRST'; |
} |
# Get the variable and the 'mode' for this variable |
$left = index(@entry[3],'('); |
$right = index(@entry[3],')'); |
if ( ($left == -1) && ($right == -1) ) |
{ |
$time = @entry[3]; |
$mode = 'ALL'; |
} |
elsif ( ($left > 0) && ($right > $left) ) |
{ |
$time = substr(@entry[3],0,$left); |
$mode = substr(@entry[3],$left+1,$right-$left-1); |
} |
else |
{ |
die('Invalid time specification...'); |
} |
# Get the time list for this command |
if ( $time eq 'ALL' ) |
{ |
$time = -999; |
print "1 \n"; |
print "$time \n"; |
} |
elsif ( $time eq 'FIRST' ) |
{ |
$time = -996; |
print "1 \n"; |
print "$time \n"; |
} |
elsif ( $time eq 'LAST' ) |
{ |
$time = -995; |
print "1 \n"; |
print "$time \n"; |
} |
elsif ( $time eq 'TRIGGER' ) |
{ |
print "-993 \n"; |
} |
else |
{ |
@times = split /,/, $time; |
$outstr = ""; |
$outlen = 0; |
foreach $j ( @times ) |
{ |
$to = index($j,'to'); |
if ( $to == -1 ) |
{ |
if ( $j eq 'FIRST' ) |
{ |
$outlen=$outlen+1; |
$outstr=$outstr . " -996 "; |
} |
elsif ( $j eq 'LAST' ) |
{ |
$outlen=$outlen+1; |
$outstr=$outstr . " -995 "; |
} |
else |
{ |
$outlen=$outlen+1; |
$outstr=$outstr . "$j "; |
} |
} |
else |
{ |
$outlen = $outlen+3; |
$t1 = substr($j,0,$to); |
$t2 = substr($j,$to+2,length($j)-$to+1); |
if ( $t1 eq 'FIRST' ) |
{ $t1='-996'; }; |
if ( $t2 eq 'FIRST' ) |
{ $t2='-996'; }; |
if ( $t1 eq 'LAST' ) |
{ $t1='-995'; }; |
if ( $t2 eq 'LAST' ) |
{ $t2='-995'; }; |
$outstr=$outstr . $t1 . " -994 " . $t2 . " "; |
} |
} |
print "$outlen \n"; |
print "$outstr \n"; |
} |
# Write the time mode |
if ( $mode eq 'ALL' ) |
{ |
print "$mode \n"; |
} |
elsif ( $mode eq 'ANY' ) |
{ |
print "$mode \n"; |
} |
elsif ( $mode eq 'NONE' ) |
{ |
print "$mode \n"; |
} |
elsif ( $mode eq 'TRIGGER' ) |
{ |
print "$mode \n"; |
} |
else |
{ |
die('Invalid time mode...'); |
} |
# Write the logical operator |
if ( $i < $nline-1 ) |
{ |
print "@logop[$i] \n"; |
} |
} |
# Write end marker |
print "END \n"; |
Property changes: |
Added: svn:executable |
/tags/1.0/select/select.sh |
---|
0,0 → 1,188 |
#!/bin/csh |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Set some parameters |
set crifile=${PWD}/select.parsed |
# Set base directories (run+prog) |
set cdfdir=${PWD} |
set tradir=${PWD} |
# Write usage information |
if ( ${#argv} == 0 ) then |
echo |
${LAGRANTO}/bin/lagrantohelp select short |
echo |
exit 0 |
endif |
# Write list of special selection criteria |
if ( "$1" == "-special" ) then |
grep '%)' ${LAGRANTO}/select/special.f |
exit 0 |
endif |
# Write title |
echo |
echo '=========================================================' |
echo ' *** START OF PREPROCESSOR SELECT *** ' |
echo |
# Save input arguments |
set inpfile=$1 |
set outfile=$2 |
set crit="$3" |
shift |
shift |
shift |
# Handle optional arguments |
echo |
echo '---- OPTIONAL FLAGS -------------------------------------' |
echo |
set noclean = 'false' |
set format = 'trajectory' |
set regionf = 'regionf' |
set trigger = 'nil' |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -noclean |
set noclean = 'true' |
echo "noclean -> true (user defined)" |
breaksw |
case -trigger |
set trigger = '-trigger' |
echo "trigger -> true (user defined)" |
breaksw |
case -boolean |
set format = 'boolean' |
echo "format -> boolean (user defined)" |
breaksw |
case -index |
set format = 'index' |
echo "format -> index (user defined)" |
breaksw |
case -count |
set format = 'count' |
echo "format -> count (user defined)" |
breaksw |
case -startf |
set format = 'startf' |
echo "format -> startf (user defined)" |
breaksw |
case -regionf |
set regionf = $argv[2] |
echo "regionf -> ${regionf} (user defined)" |
shift; |
breaksw |
endsw |
shift; |
end |
# Decide whether <select> is a file or an explicit criterion |
set flag_select = 'criterion' |
set test = `echo ${crit} | grep ':' | wc -c` |
if ( "${test}" == "0" ) then |
set flag_select = 'file' |
set flag_selectfile = $crit |
if ( -f ${flag_selectfile} ) then |
set crit = `cat ${flag_selectfile}` |
else |
echo " ERROR: criterion file ${flag_selectfile} is missing... Stop" |
exit 1 |
endif |
endif |
# Get the start, end and reference date for the tracing |
set ntra = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} ntra` |
set ntim = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} ntim` |
set ncol = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} ncol` |
set times = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} times` |
set vars = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} vars` |
# Split the criterion into subunits (with Perl) |
${LAGRANTO}/select/select.perl "${crit}" >! ${crifile} |
if ( "${status}" != "0" ) then |
echo "ERROR: Parser <select> failed" |
exit 1 |
endif |
# Write some status information |
echo |
echo '---- DIRECTORIES AND PROGRAMS ---------------------------' |
echo |
echo "CDF directory : ${cdfdir}" |
echo "TRA directory : ${tradir}" |
echo "PROGRAM SELECT : ${LAGRANTO}/select/select" |
echo "PARSER : ${LAGRANTO}/select/select.perl" |
echo "CRITERION FILE : ${crifile}" |
echo |
echo '---- INPUT PARAMETERS -----------------------------------' |
echo |
echo "Input file : ${inpfile}" |
echo "Output file : ${outfile}" |
echo "Output format : ${format}" |
if ( "${flag_select}" == "criterion" ) then |
echo "Criterion : ${crit}" |
else |
echo "Criterion : ${crit} (from file ${flag_selectfile})" |
endif |
echo |
echo '---- INPUT FILE -----------------------------------------' |
echo |
echo "# TRA : ${ntra}" |
echo "# TIMES : ${ntim}" |
echo "# COLUMNS : ${ncol}" |
echo "Times : ${times}" |
echo "Variables : ${vars}" |
echo |
echo '---- PARSED CRITERION ------------------------------------' |
echo |
cat ${crifile} |
# Finish the preprocessor |
echo |
echo ' *** END OF PREPROCESSOR SELECT *** ' |
echo '=========================================================' |
echo |
# Run the selection programme |
echo \"${inpfile}\" >! select.param |
echo \"${outfile}\" >> select.param |
echo \"${format}\" >> select.param |
echo \"${crifile}\" >> select.param |
echo ${ntra} >> select.param |
echo ${ntim} >> select.param |
echo ${ncol} >> select.param |
echo \"${regionf}\" >> select.param |
echo \"${trigger}\" >> select.param |
${LAGRANTO}/select/select |
if ( "${status}" != "0" ) then |
echo "ERROR: Program <select> failed" |
exit 1 |
endif |
# Make clean |
if ( "${noclean}" == "false" ) then |
\rm -f select.param |
\rm -f ${crifile} |
endif |
exit 0 |
Property changes: |
Added: svn:executable |
/tags/1.0/select/special.f |
---|
0,0 → 1,80 |
SUBROUTINE special (flag,cmd,tra,ntim,ncol, |
> vars,times,param,nparam) |
c *************************************************************************** |
c * * |
c * OUTPUT: flag -> 1 if trajectory is selected, 0 if not * |
c * * |
c * INPUT: cmd <- command string * |
c * tra(ntim,ncol) <- single trajectory: indices time,column * |
c * ntim <- number of times * |
c * ncol <- number of columns (including time,lon,lat,p) * |
c * vars(ncol) <- names of columns * |
c * times(ntim) <- List of times |
c * param(nparam) <- parameter values * |
c * nparam <- number of parameters * |
c * * |
c *************************************************************************** |
implicit none |
c --------------------------------------------------------------------------- |
c Declaration of subroutine parameters |
c --------------------------------------------------------------------------- |
integer flag ! Boolean flag whether trajectory is selected |
character*80 cmd ! Command string |
integer ntim,ncol ! Dimension of single trajectory |
real tra(ntim,ncol) ! Single trajectory |
character*80 vars(ncol) ! Name of columns |
real times(ntim) ! List of times |
integer nparam ! # parameters |
real param(nparam) ! List of parameters |
c --------------------------------------------------------------------------- |
c Declaration of local variables |
c --------------------------------------------------------------------------- |
integer i |
integer ip,i0,i1 |
c -------------------------------------------------------------------------- %) |
c SPECIAL:WCB:ascent,first,last %) |
c : Detect Warm Conveyor Belts (WCB); the air stream must ascend at least %) |
c : <ascent=param(1)> hPa between the two times <first=param(2)> and %) |
c : <last=param(3)>. Note, the lowest pressure is allowed to occur at any %) |
c : time between <first> and <last>. %) |
c --------------------------------------------------------------------------- %) |
if ( cmd.eq.'WCB' ) then |
c Reset the flag for selection |
flag = 0 |
c Pressure is in the 4th column |
ip = 4 |
c Get times |
i0 = 0 |
i1 = 0 |
do i=1,ntim |
if ( param(2).eq.times(i) ) i0 = i |
if ( param(3).eq.times(i) ) i1 = i |
enddo |
if ( (i0.eq.0).or.(i1.eq.0) ) then |
print*,' ERROR: invalid times in SPECIAL:WCB... Stop' |
stop |
endif |
c Check for ascent |
do i=i0+1,i1 |
if ( ( tra(i0,ip)-tra(i,ip) ) .gt. param(1) ) flag = 1 |
enddo |
endif |
c --------------------------------------------------------------------------- |
end |
/tags/1.0/trace/calvar.f |
---|
0,0 → 1,859 |
c ------------------------------------------------------------------------- |
c Potential temperature (TH) |
c ------------------------------------------------------------------------- |
subroutine calc_TH (pt,t,p) |
implicit none |
c Argument declaration |
real pt ! Potential temperature [K] |
real t ! Temperature [either in C or in K] |
real p ! Pressure [hPa] |
c Physical parameters |
real rdcp,tzero |
data rdcp,tzero /0.286,273.15/ |
c Calculation - distinction between temperature in C or in K |
if (t.lt.100.) then |
pt = (t+tzero) * ( (1000./p)**rdcp ) |
else |
pt = t * ( (1000./p)**rdcp ) |
endif |
end |
c ------------------------------------------------------------------------- |
c Density (RHO) |
c ------------------------------------------------------------------------- |
subroutine calc_RHO (rho,t,p) |
implicit none |
c Argument declaration |
real rho ! Density [kg/m^3] |
real t ! Temperature [either in C or in K] |
real p ! Pressure [hPa] |
c Physical parameters |
real rd,tzero |
data rd,tzero /287.05,273.15/ |
c Auxiliary variables |
real tk |
c Calculation - distinction between temperature in C or in K |
if (t.lt.100.) then |
tk = t + tzero |
else |
tk = t |
endif |
rho = 100.*p/( tk * rd ) |
end |
c ------------------------------------------------------------------------- |
c Relative humidity (RH) |
c ------------------------------------------------------------------------- |
subroutine calc_RH (rh,t,p,q) |
implicit none |
c Argument declaration |
real rh ! Relative humidity [%] |
real t ! Temperature [either in C or in K] |
real p ! Pressure [hPa] |
real q ! Specific humidity [kg/kg] |
c Physical parameters |
real rdcp,tzero |
data rdcp,tzero /0.286,273.15/ |
real b1,b2w,b3,b4w,r,rd |
data b1,b2w,b3,b4w,r,rd /6.1078, 17.2693882, 273.16, 35.86, |
& 287.05, 461.51/ |
c Auxiliary variables |
real ge |
real gqd |
real tc |
real pp,qk |
c Calculation - distinction between temperature in C or in K |
if (t.gt.100.) then |
tc = t - tzero |
else |
tc = t |
endif |
qk = q |
ge = b1*exp(b2w*tc/(tc+b3-b4w)) |
gqd = r/rd*ge/(p-(1.-r/rd)*ge) |
rh = 100.*qk/gqd |
end |
c ------------------------------------------------------------------------- |
c Equivalent potential temperature (THE) |
c ------------------------------------------------------------------------- |
subroutine calc_THE (the,t,p,q) |
implicit none |
c Argument declaration |
real the ! Equivalent potential temperature [K] |
real t ! Temperature [either in C or in K] |
real p ! Pressure [hPa] |
real q ! Specific humidity [kg/kg] |
c Physical parameters |
real rdcp,tzero |
data rdcp,tzero /0.286,273.15/ |
c Auxiliary variables |
real tk,qk |
c Calculation - distinction between temperature in C or in K |
if (t.lt.100.) then |
tk = t + tzero |
else |
tk = t |
endif |
qk = q |
the = tk*(1000./p) |
+ **(0.2854*(1.0-0.28*qk))*exp( |
+ (3.376/(2840.0/(3.5*alog(tk)-alog( |
+ 100.*p*max(1.0E-10,qk)/(0.622+0.378* |
+ q))-0.1998)+55.0)-0.00254)*1.0E3* |
+ max(1.0E-10,qk)*(1.0+0.81*qk)) |
end |
c ------------------------------------------------------------------------- |
c Latent heating rate (LHR) |
c ------------------------------------------------------------------------- |
subroutine calc_LHR (lhr,t,p,q,omega,rh) |
implicit none |
c Argument declaration |
real lhr ! Latent heating rate [K/6h] |
real t ! Temperature [either in C or in K] |
real p ! Pressure [hPa] |
real q ! Specific humidity [kg/kg] |
real omega ! Vertical velocity [Pa/s] |
real rh ! Relative humidity [%] |
c Physical parameters |
real p0,kappa,tzero |
data p0,kappa,tzero /1000.,0.286,273.15/ |
real blog10,cp,r,lw,eps |
data blog10,cp,r,lw,eps /.08006,1004.,287.,2.5e+6,0.622/ |
c Auxiliary variables |
real tk |
real qk |
real tt |
real esat,c |
c Calculation - distinction between temperature in C or in K |
if (t.lt.100.) then |
tk = t + tzero |
else |
tk = t |
endif |
qk = q |
if (rh.lt.80.) then |
lhr = 0. |
else if (omega.gt.0.) then |
lhr = 0. |
else |
c = lw/cp*eps*blog10*esat(tk)/p |
tt = (tk*(p0/p)**kappa) |
lhr = 21600.* |
> (1.-exp(.2*(80.-rh))) |
> *(-c*kappa*tt*omega/(100.*p))/(1.+c) |
endif |
end |
c ------------------------------------------------------------------------- |
c Wind speed (VEL) |
c ------------------------------------------------------------------------- |
subroutine calc_VEL (vel,u,v) |
implicit none |
c Argument declaration |
real vel ! Wind speed [m/s] |
real u ! Zonal wind component [m/s] |
real v ! Meridional wind component [m/s] |
vel = sqrt ( u*u + v*v ) |
end |
c ------------------------------------------------------------------------- |
c Wind direction (DIR) |
c ------------------------------------------------------------------------- |
subroutine calc_DIR (dir,u,v) |
implicit none |
c Argument declaration |
real dir ! Wind direction [deg] |
real u ! Zonal wind component [m/s] |
real v ! Meridional wind component [m/s] |
call getangle(1.,0.,u,v,dir) |
end |
c ------------------------------------------------------------------------- |
c Zonal derivative of U (DUDX) |
c ------------------------------------------------------------------------- |
subroutine calc_DUDX (dudx,u1,u0,lat) |
implicit none |
c Argument declaration |
real dudx ! Derivative of U in zonal direction [s^-1] |
real u1 ! U @ LON + 1 DLON [m/s] |
real u0 ! U @ LON - 1 DLON [m/s] |
real lat ! Latitude [deg] |
c Physical parameters |
real pi180 |
parameter (pi180=31.14159/180.) |
real deltay |
parameter (deltay =1.11e5) |
dudx = (u1-u0) / ( 2. * deltay * cos(pi180 * lat) ) |
end |
c ------------------------------------------------------------------------- |
c Zonal derivative of V (DVDX) |
c ------------------------------------------------------------------------- |
subroutine calc_DVDX (dvdx,v1,v0,lat) |
c Argument declaration |
real dvdx ! Derivative of V in zonal direction [s^-1] |
real v1 ! V @ LON + 1 DLON [m/s] |
real v0 ! V @ LON - 1 DLON [m/s] |
real lat ! Latitude [deg] |
c Physical parameters |
real pi180 |
parameter (pi180=3.14159/180.) |
real deltay |
parameter (deltay =1.11e5) |
dvdx = (v1-v0) / ( 2. * deltay * cos(pi180 * lat) ) |
end |
c ------------------------------------------------------------------------- |
c Zonal derivative of T (DTDX) |
c ------------------------------------------------------------------------- |
subroutine calc_DTDX (dtdx,t1,t0,lat) |
implicit none |
c Argument declaration |
real dtdx ! Derivative of T in zonal direction [K/m] |
real t1 ! T @ LON + 1 DLON [K] |
real t0 ! T @ LON - 1 DLON [K] |
real lat ! Latitude [deg] |
c Physical parameters |
real pi180 |
parameter (pi180=3.14159/180.) |
real deltay |
parameter (deltay =1.11e5) |
dtdx = (t1-t0) / ( 2. * deltay * cos(pi180 * lat) ) |
end |
c ------------------------------------------------------------------------- |
c Zonal derivative of TH (DTHDX) |
c ------------------------------------------------------------------------- |
subroutine calc_DTHDX (dthdx,t1,t0,p,lat) |
implicit none |
c Argument declaration |
real dthdx ! Derivative of TH in zonal direction [K/m] |
real t1 ! T @ LON + 1 DLON [K] |
real t0 ! T @ LON - 1 DLON [K] |
real p ! P [hPa] |
real lat ! Latitude [deg] |
c Physical parameters |
real pi180 |
parameter (pi180=3.14159/180.) |
real deltay |
parameter (deltay =1.11e5) |
real rdcp,pref |
data rdcp,pref /0.286,1000./ |
dthdx = (pref/p)**rdcp * |
> (t1-t0) / ( 2. * deltay * cos(pi180 * lat) ) |
end |
c ------------------------------------------------------------------------- |
c Meridional derivative of U (DUDY) |
c ------------------------------------------------------------------------- |
subroutine calc_DUDY (dudy,u1,u0) |
implicit none |
c Argument declaration |
real dudy ! Derivative of U in meridional direction [s^-1] |
real u1 ! U @ LAT + 1 DLAT [m/s] |
real u0 ! U @ LAT - 1 DLAT [m/s] |
c Physical parameters |
real deltay |
parameter (deltay =1.11e5) |
dudy = (u1-u0) / ( 2. * deltay ) |
end |
c ------------------------------------------------------------------------- |
c Meridional derivative of V (DVDY) |
c ------------------------------------------------------------------------- |
subroutine calc_DVDY (dvdy,v1,v0) |
implicit none |
c Argument declaration |
real dvdy ! Derivative of V in meridional direction [s^-1] |
real v1 ! V @ LAT + 1 DLAT [m/s] |
real v0 ! V @ LAT - 1 DLAT [m/s] |
c Physical parameters |
real deltay |
parameter (deltay =1.11e5) |
dvdy = (v1-v0) / ( 2. * deltay ) |
end |
c ------------------------------------------------------------------------- |
c Meridional derivative of T (DTDY) |
c ------------------------------------------------------------------------- |
subroutine calc_DTDY (dtdy,t1,t0) |
implicit none |
c Argument declaration |
real dtdy ! Derivative of T in meridional direction [K/m] |
real t1 ! T @ LAT + 1 DLAT [K] |
real t0 ! T @ LAT - 1 DLAT [K] |
c Physical parameters |
real deltay |
parameter (deltay =1.11e5) |
dtdy = (t1-t0) / ( 2. * deltay ) |
end |
c ------------------------------------------------------------------------- |
c Meridional derivative of TH (DTHDY) |
c ------------------------------------------------------------------------- |
subroutine calc_DTHDY (dthdy,t1,t0,p) |
implicit none |
c Argument declaration |
real dthdy ! Derivative of TH in meridional direction [K/m] |
real t1 ! TH @ LAT + 1 DLAT [K] |
real t0 ! TH @ LAT - 1 DLAT [K] |
real p ! P [hPa] |
c Physical parameters |
real deltay |
parameter (deltay =1.11e5) |
real rdcp,pref |
data rdcp,pref /0.286,1000./ |
dthdy = (pref/p)**rdcp * (t1-t0) / ( 2. * deltay ) |
end |
c ------------------------------------------------------------------------- |
c Wind shear of U (DUDP) |
c ------------------------------------------------------------------------- |
subroutine calc_DUDP (dudp,u1,u0,p1,p0) |
implicit none |
c Argument declaration |
real dudp ! Wind shear [m/s per Pa] |
real u1 ! U @ P + 1 DP [m/s] |
real u0 ! U @ P - 1 DP [m/s] |
real p1 ! P + 1 DP [hPa] |
real p0 ! P - 1 DP [hPa] |
dudp = 0.01 * (u1-u0) / (p1-p0) |
end |
c ------------------------------------------------------------------------- |
c Wind shear of V (DVDP) |
c ------------------------------------------------------------------------- |
subroutine calc_DVDP (dvdp,v1,v0,p1,p0) |
implicit none |
c Argument declaration |
real dvdp ! Wind shear [m/s per Pa] |
real v1 ! V @ P + 1 DP [m/s] |
real v0 ! V @ P - 1 DP [m/s] |
real p1 ! P + 1 DP [hPa] |
real p0 ! P - 1 DP [hPa] |
dvdp = 0.01 * (v1-v0) / (p1-p0) |
end |
c ------------------------------------------------------------------------- |
c Vertical derivative of T (DTDP) |
c ------------------------------------------------------------------------- |
subroutine calc_DTDP (dtdp,t1,t0,p1,p0) |
implicit none |
c Argument declaration |
real dtdp ! Vertical derivative of T [K/Pa] |
real t1 ! T @ P + 1 DP [K] |
real t0 ! T @ P - 1 DP [K] |
real p1 ! P + 1 DP [hPa] |
real p0 ! P - 1 DP [hPa] |
dtdp = 0.01 * (t1-t0) / (p1-p0) |
end |
c ------------------------------------------------------------------------- |
c Vertical derivative of TH (DTHDP) |
c ------------------------------------------------------------------------- |
subroutine calc_DTHDP (dthdp,t1,t0,p1,p0,p,t) |
implicit none |
c Argument declaration |
real dthdp ! Vertical derivative of TH [K/Pa] |
real t1 ! T @ P + 1 DP [K] |
real t0 ! T @ P - 1 DP [K] |
real t ! T [K] |
real p1 ! P + 1 DP [hPa] |
real p0 ! P - 1 DP [hPa] |
real p ! P [hPa] |
c Physical parameters |
real rdcp,tzero,pref |
data rdcp,tzero,pref /0.286,273.15,1000./ |
c Auxiliary variables |
real tk1,tk0,tk |
if (t0.lt.100.) then |
tk0 = t0 + tzero |
endif |
if (t1.lt.100.) then |
tk1 = t1 + tzero |
endif |
if (t.lt.100.) then |
tk = t + tzero |
endif |
dthdp = 0.01*(pref/p)**rdcp * |
> ( (tk1-tk0)/(p1-p0) - rdcp * tk/p ) |
end |
c ------------------------------------------------------------------------- |
c Squared Brunt-Vaisäla frequency (NSQ) |
c ------------------------------------------------------------------------- |
subroutine calc_NSQ (nsq,dthdp,th,rho) |
implicit none |
c Argument declaration |
real nsq ! Squared Brunt-Vaisäla frequency [s^-1] |
real dthdp ! D(TH)/DP [K/Pa] |
real th ! K |
real rho ! Density [kg m^-3] |
c Physical parameters |
real g |
parameter (g=9.81) |
nsq = -g**2/th * rho * dthdp |
end |
c ------------------------------------------------------------------------- |
c Relative vorticity (RELVORT) |
c ------------------------------------------------------------------------- |
subroutine calc_RELVORT (relvort,dudy,dvdx,u,lat) |
implicit none |
c Argument declaration |
real relvort ! Relative vorticity [s^-1] |
real u ! Zonal wind component [m/s] |
real dudy ! du/dy [s^-1] |
real dvdx ! dv/dx [s^-1] |
real lat ! Latitude [deg] |
c Physical parameters |
real pi180 |
parameter (pi180=3.14159/180.) |
real deltay |
parameter (deltay =1.11e5) |
relvort = dvdx - dudy + u * pi180/deltay * tan(pi180 * lat) |
end |
c ------------------------------------------------------------------------- |
c Absolute vorticity (ABSVORT) |
c ------------------------------------------------------------------------- |
subroutine calc_ABSVORT (absvort,dudy,dvdx,u,lat) |
implicit none |
c Argument declaration |
real absvort ! Absolute vorticity [s^-1] |
real u ! Zonal wind component [m/s] |
real dudy ! du/dy [s^-1] |
real dvdx ! dv/dx [s^-1] |
real lat ! Latitude [deg] |
c Physical parameters |
real pi180 |
parameter (pi180=3.14159/180.) |
real deltay |
parameter (deltay =1.11e5) |
real omega |
parameter (omega=7.292e-5) |
absvort = dvdx - dudy + u * pi180/deltay * tan(pi180 * lat) + |
> 2. * omega * sin(pi180 * lat) |
end |
c ------------------------------------------------------------------------- |
c Divergence (DIV) |
c ------------------------------------------------------------------------- |
subroutine calc_DIV (div,dudx,dvdy,v,lat) |
implicit none |
c Argument declaration |
real div ! Divergence [s^-1] |
real v ! Meridional wind component [m/s] |
real dudx ! du/dx [s^-1] |
real dvdy ! dv/dy [s^-1] |
real lat ! Latitude [deg] |
c Physical parameters |
real pi180 |
parameter (pi180=3.14159/180.) |
real deltay |
parameter (deltay =1.11e5) |
div = dudx + dvdy - v * pi180/deltay * tan(pi180 * lat) |
end |
c ------------------------------------------------------------------------- |
c Deformation (DEF) |
c ------------------------------------------------------------------------- |
subroutine calc_DEF (def,dudx,dvdx,dudy,dvdy) |
implicit none |
c Argument declaration |
real def ! Deformation [s^-1] |
real dudx ! du/dx [s^-1] |
real dvdx ! dv/dy [s^-1] |
real dudy ! du/dx [s^-1] |
real dvdy ! dv/dy [s^-1] |
c Physical parameters |
real pi180 |
parameter (pi180=3.14159/180.) |
def = sqrt( (dvdx+dudy)**2 + (dudx-dvdy)**2 ) |
end |
c ------------------------------------------------------------------------- |
c Potential Vorticity (PV) |
c ------------------------------------------------------------------------- |
subroutine calc_PV (pv,absvort,dthdp,dudp,dvdp,dthdx,dthdy) |
implicit none |
c Argument declaration |
real pv ! Ertel-PV [PVU] |
real absvort ! Absolute vorticity [s^-1] |
real dthdp ! dth/dp [K/Pa] |
real dudp ! du/dp [m/s per Pa] |
real dvdp ! dv/dp [m/s per Pa] |
real dthdx ! dth/dx [K/m] |
real dthdy ! dth/dy [K/m] |
c Physical and numerical parameters |
real scale |
parameter (scale=1.E6) |
real g |
parameter (g=9.80665) |
pv = -scale * g * ( absvort * dthdp + dudp * dthdy - dvdp * dthdx) |
end |
c ------------------------------------------------------------------------- |
c Richardson number (RI) |
c ------------------------------------------------------------------------- |
subroutine calc_RI (ri,dudp,dvdp,nsq,rho) |
implicit none |
c Argument declaration |
real ri ! Richardson number |
real dudp ! Du/Dp [m/s per Pa] |
real dvdp ! Dv/Dp [m/s per Pa] |
real nsq ! Squared Brunt-Vailälä frequency [s^-1] |
real rho ! Density [kg/m^3] |
c Physical and numerical parameters |
real g |
parameter (g=9.80665) |
ri = nsq / ( dudp**2 + dvdp**2 ) / ( rho * g )**2 |
end |
c ------------------------------------------------------------------------- |
c Ellrod and Knapp's turbulence indicator (TI) |
c ------------------------------------------------------------------------- |
subroutine calc_TI (ti,def,dudp,dvdp,rho) |
implicit none |
c Argument declaration |
real ti ! Turbulence idicator |
real def ! Deformation [s^-1] |
real dudp ! Du/Dp [m/s per Pa] |
real dvdp ! Dv/Dp [m/s per Pa] |
real rho ! Density [kg/m^3] |
c Physical and numerical parameters |
real g |
parameter (g=9.80665) |
ti = def * sqrt ( dudp**2 + dvdp**2 ) * ( rho * g ) |
end |
c ------------------------------------------------------------------------- |
c Distance from starting position |
c ------------------------------------------------------------------------- |
subroutine calc_DIST0 (dist0,lon0,lat0,lon1,lat1) |
implicit none |
c Argument declaration |
real dist0 ! Distance from starting position [km] |
real lon0,lat0 ! Starting position |
real lon1,lat1 ! New position |
c Externals |
real sdis |
external sdis |
dist0 = sdis(lon0,lat0,lon1,lat1) |
end |
c ------------------------------------------------------------------------- |
c Heading of the trajectory (HEAD) |
c ------------------------------------------------------------------------- |
subroutine calc_HEAD (head,lon0,lat0,lon1,lat1) |
implicit none |
c Argument declaration |
real head ! Heading angle (in deg) relativ to zonal direction |
real lon0,lat0 ! Starting position |
real lon1,lat1 ! New position |
c Physical parameters |
real pi180 |
parameter (pi180=3.14159/180.) |
c Auixiliary variables |
real dx,dy |
dx = (lon1-lon0) * cos(pi180*0.5*(lat0+lat1)) |
dy = lat1-lat0 |
call getangle(1.,0.,dx,dy,head) |
end |
c |
c ************************************************************************* |
c Auxiliary subroutines and functions |
c ************************************************************************* |
c ------------------------------------------------------------------------- |
c Saturation vapor pressure over water |
c ------------------------------------------------------------------------- |
real function esat(t) |
C This function returns the saturation vapor pressure over water |
c (mb) given the temperature (Kelvin). |
C The algorithm is due to Nordquist, W. S. ,1973: "Numerical |
C Approximations of Selected Meteorological Parameters for Cloud |
C Physics Problems" ECOM-5475, Atmospheric Sciences Laboratory, |
c U. S. Army Electronics Command, White Sands Missile Range, |
c New Mexico 88002. |
real p1,p2,c1,t |
p1=11.344-0.0303998*t |
p2=3.49149-1302.8844/t |
c1=23.832241-5.02808*log10(t) |
esat=10.**(c1-1.3816e-7*10.**p1+8.1328e-3*10.**p2-2949.076/t) |
end |
c -------------------------------------------------------------------------- |
c Angle between two vectors |
c -------------------------------------------------------------------------- |
SUBROUTINE getangle (ux1,uy1,ux2,uy2,angle) |
c Given two vectors <ux1,uy1> and <ux2,uy2>, determine the angle (in deg) |
c between the two vectors. |
implicit none |
c Declaration of subroutine parameters |
real ux1,uy1 |
real ux2,uy2 |
real angle |
c Auxiliary variables and parameters |
real len1,len2,len3 |
real val1,val2,val3 |
real vx1,vy1 |
real vx2,vy2 |
real pi |
parameter (pi=3.14159265359) |
vx1 = ux1 |
vx2 = ux2 |
vy1 = uy1 |
vy2 = uy2 |
len1=sqrt(vx1*vx1+vy1*vy1) |
len2=sqrt(vx2*vx2+vy2*vy2) |
if ((len1.gt.0.).and.(len2.gt.0.)) then |
vx1=vx1/len1 |
vy1=vy1/len1 |
vx2=vx2/len2 |
vy2=vy2/len2 |
val1=vx1*vx2+vy1*vy2 |
val2=-vy1*vx2+vx1*vy2 |
len3=sqrt(val1*val1+val2*val2) |
if ( (val1.ge.0.).and.(val2.ge.0.) ) then |
val3=acos(val1/len3) |
else if ( (val1.lt.0.).and.(val2.ge.0.) ) then |
val3=pi-acos(abs(val1)/len3) |
else if ( (val1.ge.0.).and.(val2.le.0.) ) then |
val3=-acos(val1/len3) |
else if ( (val1.lt.0.).and.(val2.le.0.) ) then |
val3=-pi+acos(abs(val1)/len3) |
endif |
else |
val3=0. |
endif |
angle=180./pi*val3 |
END |
c -------------------------------------------------------------------------- |
c Spherical distance between lat/lon points |
c -------------------------------------------------------------------------- |
real function sdis(xp,yp,xq,yq) |
c |
c calculates spherical distance (in km) between two points given |
c by their spherical coordinates (xp,yp) and (xq,yq), respectively. |
c |
real re |
parameter (re=6370.) |
real pi180 |
parameter (pi180=3.14159/180.) |
real xp,yp,xq,yq,arg |
arg=sin(pi180*yp)*sin(pi180*yq)+ |
> cos(pi180*yp)*cos(pi180*yq)*cos(pi180*(xp-xq)) |
if (arg.lt.-1.) arg=-1. |
if (arg.gt.1.) arg=1. |
sdis=re*acos(arg) |
end |
/tags/1.0/trace/trace.f90 |
---|
0,0 → 1,2155 |
PROGRAM trace |
! ******************************************************************** |
! * * |
! * Trace fields along trajectories * |
! * * |
! * April 1993: First version (Heini Wernli) * |
! * 2008-2009 : Major upgrades (Michael Sprenger) * |
! * Mar 2012: Clustering option (Bojan Skerlak) * |
! * Nov 2012: Circle options (") * |
! * Jul 2013: user-defined PV,TH @ clustering mode (") * |
! * * |
! ******************************************************************** |
implicit none |
! -------------------------------------------------------------------- |
! Declaration of parameters |
! -------------------------------------------------------------------- |
! Maximum number of levels for input files |
integer :: nlevmax |
parameter (nlevmax=100) |
! Maximum number of input files (dates, length of trajectories) |
integer :: ndatmax |
parameter (ndatmax=500) |
! Numerical epsilon (for float comparison) |
real :: eps |
parameter (eps=0.001) |
! Conversion factors |
real :: pi180 ! deg -> rad |
parameter (pi180=3.14159/180.) |
real :: deg2km ! deg -> km (at equator) |
parameter (deg2km=111.) |
real :: pir |
parameter (pir=255032235.95489) ! 2*Pi*R^2 Bojan |
! Prefix for primary and secondary fields |
character :: charp |
character :: chars |
parameter (charp='P') |
parameter (chars='S') |
! -------------------------------------------------------------------- |
! Declaration of variables |
! -------------------------------------------------------------------- |
! Input and output format for trajectories (see iotra.f) |
integer :: inpmode |
integer :: outmode |
! Input parameters |
character(len=80) :: inpfile ! Input trajectory file |
character(len=80) :: outfile ! Output trajectory file |
integer :: ntra ! Number of trajectories |
integer :: ncol ! Number of columns (including time, lon, lat, p) |
integer :: ntim ! Number of times per trajectory |
integer :: ntrace0 ! Number of trace variables |
character(len=80) :: tvar0(200) ! Tracing variable (with mode specification) |
character(len=80) :: tvar(200) ! Tracing variable name (only the variable) |
character(len=1) :: tfil(200) ! Filename prefix |
real :: fac(200) ! Scaling factor |
real :: shift_val(200) ! Shift in space and time relative to trajectory position |
character(len=80) :: shift_dir(200) ! Direction of shift |
integer :: compfl(200) ! Computation flag (1=compute) |
integer :: numdat ! Number of input files |
character(len=11) :: dat(ndatmax) ! Dates of input files |
real :: timeinc ! Time increment between input files |
real :: tst ! Time shift of start relative to first data file |
real :: ten ! Time shift of end relatiev to first data file |
character(len=20) :: startdate ! First time/date on trajectory |
character(len=20) :: enddate ! Last time/date on trajectory |
integer :: ntrace1 ! Count trace and additional variables |
character(len=80) :: timecheck ! Either 'yes' or 'no' |
character(len=80) :: intmode ! Interpolation mode ('normal', 'nearest') Bojan ('clustering','circle_avg','circle_max','circle_min') |
! Trajectories |
real,allocatable, dimension (:,:,:) :: trainp ! Input trajectories (ntra,ntim,ncol) |
real,allocatable, dimension (:,:,:) :: traint ! Internal trajectories (ntra,ntim,ncol+ntrace1) |
real,allocatable, dimension (:,:,:) :: traout ! Output trajectories (ntra,ntim,ncol+ntrace0) |
integer :: reftime(6) ! Reference date |
character(len=80) :: varsinp(100) ! Field names for input trajectory |
character(len=80) :: varsint(100) ! Field names for internal trajectory |
character(len=80) :: varsout(100) ! Field names for output trajectory |
integer :: fid,fod ! File identifier for inp and out trajectories |
real :: x0,y0,p0 ! Position of air parcel (physical space) |
real :: reltpos0 ! Relative time of air parcel |
real :: xind,yind,pind ! Position of air parcel (grid space) |
integer :: fbflag ! Flag for forward (1) or backward (-1) trajectories |
integer :: fok(100) ! Flag whether field is ready |
! Meteorological fields |
real,allocatable, dimension (:) :: spt0,spt1 ! Surface pressure |
real,allocatable, dimension (:) :: p3t0,p3t1 ! 3d-pressure |
real,allocatable, dimension (:) :: f3t0,f3t1 ! 3d field for tracing |
character(len=80) :: svars(100) ! List of variables on S file |
character(len=80) :: pvars(100) ! List of variables on P file |
integer :: n_svars ! Number of variables on S file |
integer :: n_pvars ! Number of variables on P file |
! Grid description |
real :: pollon,pollat ! Longitude/latitude of pole |
real :: ak(100) ! Vertical layers and levels |
real :: bk(100) |
real :: xmin,xmax ! Zonal grid extension |
real :: ymin,ymax ! Meridional grid extension |
integer :: nx,ny,nz ! Grid dimensions |
real :: dx,dy ! Horizontal grid resolution |
integer :: hem ! Flag for hemispheric domain |
integer :: per ! Flag for periodic domain |
real :: stagz ! Vertical staggering |
real :: mdv ! Missing data value |
! Auxiliary variables |
integer :: i,j,k,l,m,n |
real :: rd |
character(len=80) :: filename,varname |
real :: time0,time1,reltpos |
integer :: itime0,itime1 |
integer :: stat |
real :: tstart |
integer :: iloaded0,iloaded1 |
real :: f0 |
real :: frac |
real :: tload,tfrac |
integer :: isok |
character :: ch |
integer :: ind |
integer :: ind1,ind2,ind3,ind4,ind5 |
integer :: ind6,ind7,ind8,ind9,ind0 |
integer :: noutside |
real :: delta |
integer :: itrace0 |
character(len=80) :: string |
integer err_c1,err_c2,err_c3 |
! Bojan |
real :: dist,circlesum,circlemax,circlemin,circleavg,radius ! distance (great circle), sum/max/min/avg in circle, radius of circle |
integer :: ist,jst,kst,sp,ml,mr,nd,nu ! ijk in stack, sp=stack counter, ml (left), mr (right), nd (down), nu (up) |
integer :: lci,lcj,xindb,xindf ! label count i and j, xind back, xind forward |
integer :: yindb,yindf,pindb,pindf ! yind back, yind forward, pind back, pind forward |
integer :: pvpos,thpos ! position of variables PV and TH in trajectory |
real :: tropo_pv,tropo_th ! values of PV and TH at dynamical tropopause |
integer, allocatable, dimension (:) :: stackx,stacky ! lon/lat of stack |
integer, allocatable, dimension (:) :: lblcount ! counter for label |
integer, allocatable, dimension (:,:) :: connect ! array that keeps track of the visited grid points |
real, allocatable, dimension (:) :: lbl ! label |
real, allocatable, dimension (:) :: circlelon,circlelat ! value of f, lon and lat in circle |
real, allocatable, dimension (:) :: circlef,circlearea ! value of f, lon and lat in circle |
real, allocatable, dimension (:) :: longrid,latgrid ! arrays of longitude and latitude of grid points |
! Bojan |
! Externals |
real :: int_index4 |
external int_index4 |
real :: sdis ! Bojan: need function sdis (calculates great circle distance) |
external sdis ! Bojan: need function sdis |
! -------------------------------------------------------------------- |
! Start of program, Read parameters, get grid parameters |
! -------------------------------------------------------------------- |
! Write start message |
print*,'=========================================================' |
print*,' *** START OF PROGRAM TRACE ***' |
print* |
! Read parameters |
open(10,file='trace.param') |
read(10,*) inpfile |
read(10,*) outfile |
read(10,*) startdate |
read(10,*) enddate |
read(10,*) fbflag |
read(10,*) numdat |
if ( fbflag.eq.1) then |
do i=1,numdat |
read(10,'(a11)') dat(i) |
enddo |
else |
do i=numdat,1,-1 |
read(10,'(a11)') dat(i) |
enddo |
endif |
read(10,*) timeinc |
read(10,*) tst |
read(10,*) ten |
read(10,*) ntra |
read(10,*) ntim |
read(10,*) ncol |
read(10,*) ntrace0 |
do i=1,ntrace0 |
read(10,*) tvar(i), fac(i), compfl(i), tfil(i) |
enddo |
read(10,*) n_pvars |
do i=1,n_pvars |
read(10,*) pvars(i) |
enddo |
read(10,*) n_svars |
do i=1,n_svars |
read(10,*) svars(i) |
enddo |
read(10,*) timecheck |
read(10,*) intmode |
read(10,*) radius |
read(10,*) tropo_pv |
read(10,*) tropo_th |
close(10) |
! Bojan: error if radius < 0 |
if (((intmode .eq. "circle_avg") .or. (intmode .eq. "circle_min") .or. (intmode .eq. "circle_max")) .and. (radius .lt. 0)) then |
print*,'ERROR (circle): radius < 0!' |
stop |
endif |
! Remove commented tracing fields |
itrace0 = 1 |
do while ( itrace0.le.ntrace0) |
string = tvar(itrace0) |
if ( string(1:1).eq.'#' ) then |
do i=itrace0,ntrace0-1 |
tvar(i) = tvar(i+1) |
fac(i) = fac(i+1) |
compfl(i) = compfl(i+1) |
tfil(i) = tfil(i+1) |
enddo |
ntrace0 = ntrace0 - 1 |
else |
itrace0 = itrace0 + 1 |
endif |
enddo |
! Save the tracing variable (including all mode specifications) |
do i=1,ntrace0 |
tvar0(i) = tvar(i) |
enddo |
! Set the formats of the input and output files |
call mode_tra(inpmode,inpfile) |
if (inpmode.eq.-1) inpmode=1 |
call mode_tra(outmode,outfile) |
if (outmode.eq.-1) outmode=1 |
! Convert time shifts <tst,ten> from <hh.mm> into fractional time |
call hhmm2frac(tst,frac) |
tst = frac |
call hhmm2frac(ten,frac) |
ten = frac |
! Set the time for the first data file (depending on forward/backward mode) |
if (fbflag.eq.1) then |
tstart = -tst |
else |
tstart = tst |
endif |
! Read the constant grid parameters (nx,ny,nz,xmin,xmax,ymin,ymax,pollon,pollat) |
! The negative <-fid> of the file identifier is used as a flag for parameter retrieval |
filename = charp//dat(1) |
varname = 'U' |
call input_open (fid,filename) |
call input_grid (-fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny,tstart,pollon,pollat,rd,rd,nz,rd,rd,rd,timecheck) |
call input_close(fid) |
! Allocate memory for some meteorological arrays |
allocate(spt0(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array spt0 ***' ! Surface pressure |
allocate(spt1(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array spt1 ***' |
allocate(p3t0(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t0 ***' ! Pressure |
allocate(p3t1(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t1 ***' |
allocate(f3t0(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t0 ***' ! Tracing field |
allocate(f3t1(nx*ny*nz),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array p3t1 ***' |
! Get memory for trajectory arrays |
allocate(trainp(ntra,ntim,ncol),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array tra ***' |
! Bojan |
! allocate memory for clustering mode |
if (intmode .eq. 'clustering') then |
allocate(lbl(8),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array lbl ***' |
allocate(lblcount(5),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array lblcount ***' |
endif |
! allocate memory for circle mode |
if ( (intmode.eq.'circle_avg') .or. (intmode.eq.'circle_min') .or. (intmode.eq.'circle_max') ) then |
allocate(connect(nx,ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating connect ***' |
allocate(stackx(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating stackx ***' |
allocate(stacky(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating stacky ***' |
allocate(circlelon(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating circlelon ***' |
allocate(circlelat(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating circlelat ***' |
allocate(circlef(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating circlef ***' |
allocate(circlearea(nx*ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating circlearea ***' |
allocate(longrid(nx),stat=stat) |
if (stat.ne.0) print*,'*** error allocating longrid ***' |
allocate(latgrid(ny),stat=stat) |
if (stat.ne.0) print*,'*** error allocating latgrid ***' |
do m=1,nx |
longrid(m)=xmin+dx*(m-1) |
enddo |
do n=1,ny |
latgrid(n)=ymin+dy*(n-1) |
enddo |
endif |
! Bojan |
! Set the flags for periodic domains |
if ( abs(xmax-xmin-360.).lt.eps ) then |
per = 1 |
elseif ( abs(xmax-xmin-360.+dx).lt.eps ) then |
per = 2 |
else |
per = 0 |
endif |
! Set logical flag for periodic data set (hemispheric or not) |
hem = 0 |
if (per.eq.0.) then |
delta=xmax-xmin-360. |
if (abs(delta+dx).lt.eps) then ! Program aborts: arrays must be closed |
print*,' ERROR: arrays must be closed... Stop' |
else if (abs(delta).lt.eps) then ! Periodic and hemispheric |
hem=1 |
per=360. |
endif |
else ! Periodic and hemispheric |
hem=1 |
endif |
! Write some status information |
print*,'---- INPUT PARAMETERS -----------------------------------' |
print* |
print*,' Input trajectory file : ',trim(inpfile) |
print*,' Output trajectory file : ',trim(outfile) |
print*,' Format of input file : ',inpmode |
print*,' Format of output file : ',outmode |
print*,' Forward/backward : ',fbflag |
print*,' #tra : ',ntra |
print*,' #col : ',ncol |
print*,' #tim : ',ntim |
print*,' No time check : ',trim(timecheck) |
print*,' Interpolation mode : ',trim(intmode) |
! Bojan |
if (trim(intmode) .eq. "clustering") then |
print*,' Tropopause PV [pvu] : ',tropo_pv |
print*,' Tropopause TH [K] : ',tropo_th |
endif |
do i=1,ntrace0 |
if (compfl(i).eq.0) then |
print*,' Tracing field : ', trim(tvar(i)), fac(i), ' 0 ', tfil(i) |
else |
print*,' Tracing field : ', trim(tvar(i)), fac(i), ' 1 ', tfil(i) |
endif |
enddo |
print* |
print*,'---- INPUT DATA FILES -----------------------------------' |
print* |
call frac2hhmm(tstart,tload) |
print*,' Time of 1st data file : ',tload |
print*,' #input files : ',numdat |
print*,' time increment : ',timeinc |
call frac2hhmm(tst,tload) |
print*,' Shift of start : ',tload |
call frac2hhmm(ten,tload) |
print*,' Shift of end : ',tload |
print*,' First/last input file : ',trim(dat(1)), ' ... ', trim(dat(numdat)) |
print*,' Primary variables : ',trim(pvars(1)) |
do i=2,n_pvars |
print*,' : ',trim(pvars(i)) |
enddo |
if ( n_svars.ge.1 ) then |
print*,' Secondary variables : ',trim(svars(1)) |
do i=2,n_svars |
print*,' : ',trim(svars(i)) |
enddo |
endif |
print* |
print*,'---- CONSTANT GRID PARAMETERS ---------------------------' |
print* |
print*,' xmin,xmax : ',xmin,xmax |
print*,' ymin,ymax : ',ymin,ymax |
print*,' dx,dy : ',dx,dy |
print*,' pollon,pollat : ',pollon,pollat |
print*,' nx,ny,nz : ',nx,ny,nz |
print*,' per, hem : ',per,hem |
print* |
! -------------------------------------------------------------------- |
! Load the input trajectories |
! -------------------------------------------------------------------- |
! Read the input trajectory file |
call ropen_tra(fid,inpfile,ntra,ntim,ncol,reftime,varsinp,inpmode) |
call read_tra (fid,trainp,ntra,ntim,ncol,inpmode) |
call close_tra(fid,inpmode) |
! Check that first four columns correspond to time,lon,lat,p |
if ( (varsinp(1).ne.'time' ).or. & |
(varsinp(2).ne.'xpos' ).and.(varsinp(2).ne.'lon' ).or. & |
(varsinp(3).ne.'ypos' ).and.(varsinp(3).ne.'lat' ).or. & |
(varsinp(4).ne.'ppos' ).and.(varsinp(4).ne.'p' ) ) then |
print*,' ERROR: problem with input trajectories ...' |
stop |
endif |
varsinp(1) = 'time' |
varsinp(2) = 'lon' |
varsinp(3) = 'lat' |
varsinp(4) = 'p' |
! Write some status information of the input trajectories |
print*,'---- INPUT TRAJECTORIES ---------------------------------' |
print* |
print*,' Start date : ',trim(startdate) |
print*,' End date : ',trim(enddate) |
print*,' Reference time (year) : ',reftime(1) |
print*,' (month) : ',reftime(2) |
print*,' (day) : ',reftime(3) |
print*,' (hour) : ',reftime(4) |
print*,' (min) : ',reftime(5) |
print*,' Time range (min) : ',reftime(6) |
do i=1,ncol |
print*,' Var :',i,trim(varsinp(i)) |
enddo |
print* |
! Check that first time is 0 - otherwise the tracing will produce |
! wrong results because later in the code only absolute times are |
! considered: <itime0 = int(abs(tfrac-tstart)/timeinc) + 1>. This |
! will be changed in a future version. |
if ( abs( trainp(1,1,1) ).gt.eps ) then |
print*,' ERROR: First time of trajectory must be 0, i.e. ' |
print*,' correspond to the reference date. Otherwise' |
print*,' the tracing will give wrong results... STOP' |
stop |
endif |
! -------------------------------------------------------------------- |
! Check dependencies for trace fields which must be calculated |
! -------------------------------------------------------------------- |
! Set the counter for extra fields |
ntrace1 = ntrace0 |
! Loop over all tracing variables |
i = 1 |
do while (i.le.ntrace1) |
! Skip fields which must be available on the input files |
if (i.le.ntrace0) then |
if (compfl(i).eq.0) goto 100 |
endif |
! Get the dependencies for potential temperature (TH) |
if ( tvar(i).eq.'TH' ) then |
varname='P' ! P |
call add2list(varname,tvar,ntrace1) |
varname='T' ! T |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for potential temperature (TH) |
elseif ( tvar(i).eq.'RHO' ) then |
varname='P' ! P |
call add2list(varname,tvar,ntrace1) |
varname='T' ! T |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for relative humidity (RH) |
elseif ( tvar(i).eq.'RH' ) then |
varname='P' ! P |
call add2list(varname,tvar,ntrace1) |
varname='T' ! T |
call add2list(varname,tvar,ntrace1) |
varname='Q' ! Q |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for equivalent potential temperature (THE) |
elseif ( tvar(i).eq.'THE' ) then |
varname='P' ! P |
call add2list(varname,tvar,ntrace1) |
varname='T' ! T |
call add2list(varname,tvar,ntrace1) |
varname='Q' ! Q |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for latent heating rate (LHR) |
elseif ( tvar(i).eq.'LHR' ) then |
varname='P' ! P |
call add2list(varname,tvar,ntrace1) |
varname='T' ! T |
call add2list(varname,tvar,ntrace1) |
varname='Q' ! Q |
call add2list(varname,tvar,ntrace1) |
varname='OMEGA' ! OMEGA |
call add2list(varname,tvar,ntrace1) |
varname='RH' ! RH |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for wind speed (VEL) |
elseif ( tvar(i).eq.'VEL' ) then |
varname='U' ! U |
call add2list(varname,tvar,ntrace1) |
varname='V' ! V |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for wind direction (DIR) |
elseif ( tvar(i).eq.'DIR' ) then |
varname='U' ! U |
call add2list(varname,tvar,ntrace1) |
varname='V' ! V |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for du/dx (DUDX) |
elseif ( tvar(i).eq.'DUDX' ) then |
varname='U:+1DLON' ! U:+1DLON |
call add2list(varname,tvar,ntrace1) |
varname='U:-1DLON' ! U:-1DLON |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for dv(dx (DVDX) |
elseif ( tvar(i).eq.'DVDX' ) then |
varname='V:+1DLON' ! V:+1DLON |
call add2list(varname,tvar,ntrace1) |
varname='V:-1DLON' ! V:-1DLON |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for du/dy (DUDY) |
elseif ( tvar(i).eq.'DUDY' ) then |
varname='U:+1DLAT' ! U:+1DLAT |
call add2list(varname,tvar,ntrace1) |
varname='U:-1DLAT' ! U:-1DLAT |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for dv/dy (DVDY) |
elseif ( tvar(i).eq.'DVDY' ) then |
varname='V:+1DLAT' ! V:+1DLAT |
call add2list(varname,tvar,ntrace1) |
varname='V:-1DLAT' ! V:-1DLAT |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for du/dp (DUDP) |
elseif ( tvar(i).eq.'DUDP' ) then |
varname='U:+1DP' ! U:+1DP |
call add2list(varname,tvar,ntrace1) |
varname='U:-1DP' ! U:-1DP |
call add2list(varname,tvar,ntrace1) |
varname='P:+1DP' ! P:+1DP |
call add2list(varname,tvar,ntrace1) |
varname='P:-1DP' ! P:-1DP |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for dv/dp (DVDP) |
elseif ( tvar(i).eq.'DVDP' ) then |
varname='V:+1DP' ! V:+1DP |
call add2list(varname,tvar,ntrace1) |
varname='V:-1DP' ! V:-1DP |
call add2list(varname,tvar,ntrace1) |
varname='P:+1DP' ! P:+1DP |
call add2list(varname,tvar,ntrace1) |
varname='P:-1DP' ! P:-1DP |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for dt/dx (DTDX) |
elseif ( tvar(i).eq.'DTDX' ) then |
varname='T:+1DLON' ! T:+1DLON |
call add2list(varname,tvar,ntrace1) |
varname='T:-1DLON' ! T:-1DLON |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for dth/dy (DTHDY) |
elseif ( tvar(i).eq.'DTHDY' ) then |
varname='T:+1DLAT' ! T:+1DLON |
call add2list(varname,tvar,ntrace1) |
varname='T:-1DLAT' ! T:-1DLON |
call add2list(varname,tvar,ntrace1) |
varname='P' ! P |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for dth/dx (DTHDX) |
elseif ( tvar(i).eq.'DTHDX' ) then |
varname='T:+1DLON' ! T:+1DLON |
call add2list(varname,tvar,ntrace1) |
varname='T:-1DLON' ! T:-1DLON |
call add2list(varname,tvar,ntrace1) |
varname='P' ! P |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for dt/dy (DTDY) |
elseif ( tvar(i).eq.'DTDY' ) then |
varname='T:+1DLAT' ! T:+1DLON |
call add2list(varname,tvar,ntrace1) |
varname='T:-1DLAT' ! T:-1DLON |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for dt/dp (DTDP) |
elseif ( tvar(i).eq.'DTDP' ) then |
varname='T:+1DP' ! T:+1DP |
call add2list(varname,tvar,ntrace1) |
varname='T:-1DP' ! T:-1DP |
call add2list(varname,tvar,ntrace1) |
varname='P:+1DP' ! P:+1DP |
call add2list(varname,tvar,ntrace1) |
varname='P:-1DP' ! P:-1DP |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for dth/dp (DTHDP) |
elseif ( tvar(i).eq.'DTHDP' ) then |
varname='T:+1DP' ! T:+1DP |
call add2list(varname,tvar,ntrace1) |
varname='T:-1DP' ! T:-1DP |
call add2list(varname,tvar,ntrace1) |
varname='T' ! T |
call add2list(varname,tvar,ntrace1) |
varname='P:+1DP' ! P:+1DP |
call add2list(varname,tvar,ntrace1) |
varname='P:-1DP' ! P:-1DP |
call add2list(varname,tvar,ntrace1) |
varname='P' ! P |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for squared Brunt Vaiäläa frequency (NSQ) |
elseif ( tvar(i).eq.'NSQ' ) then |
varname='DTHDP' ! DTHDP |
call add2list(varname,tvar,ntrace1) |
varname='TH' ! TH |
call add2list(varname,tvar,ntrace1) |
varname='RHO' ! RHO |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for relative vorticity (RELVORT) |
elseif ( tvar(i).eq.'RELVORT' ) then |
varname='U' ! U |
call add2list(varname,tvar,ntrace1) |
varname='DUDY' ! DUDY |
call add2list(varname,tvar,ntrace1) |
varname='DVDX' ! DVDX |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for relative vorticity (ABSVORT) |
elseif ( tvar(i).eq.'ABSVORT' ) then |
varname='U' ! U |
call add2list(varname,tvar,ntrace1) |
varname='DUDY' ! DUDY |
call add2list(varname,tvar,ntrace1) |
varname='DVDX' ! DVDX |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for divergence (DIV) |
elseif ( tvar(i).eq.'DIV' ) then |
varname='V' ! U |
call add2list(varname,tvar,ntrace1) |
varname='DUDX' ! DUDX |
call add2list(varname,tvar,ntrace1) |
varname='DVDY' ! DVDY |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for deformation (DEF) |
elseif ( tvar(i).eq.'DEF' ) then |
call add2list(varname,tvar,ntrace1) |
varname='DUDX' ! DUDX |
call add2list(varname,tvar,ntrace1) |
varname='DVDY' ! DVDY |
call add2list(varname,tvar,ntrace1) |
varname='DUDY' ! DUDY |
call add2list(varname,tvar,ntrace1) |
varname='DVDX' ! DVDX |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for potential vorticity (PV) |
elseif ( tvar(i).eq.'PV' ) then |
varname='ABSVORT' ! ABSVORT |
call add2list(varname,tvar,ntrace1) |
varname='DTHDP' ! DTHDP |
call add2list(varname,tvar,ntrace1) |
varname='DUDP' ! DUDP |
call add2list(varname,tvar,ntrace1) |
varname='DVDP' ! DVDP |
call add2list(varname,tvar,ntrace1) |
varname='DTHDX' ! DTHDX |
call add2list(varname,tvar,ntrace1) |
varname='DTHDY' ! DTHDY |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for Richardson number (RI) |
elseif ( tvar(i).eq.'RI' ) then |
varname='DUDP' ! DUDP |
call add2list(varname,tvar,ntrace1) |
varname='DVDP' ! DVDP |
call add2list(varname,tvar,ntrace1) |
varname='NSQ' ! NSQ |
call add2list(varname,tvar,ntrace1) |
varname='RHO' ! RHO |
call add2list(varname,tvar,ntrace1) |
! Get the dependencies for Ellrod&Knapp's turbulence index (TI) |
elseif ( tvar(i).eq.'TI' ) then |
varname='DEF' ! DEF |
call add2list(varname,tvar,ntrace1) |
varname='DUDP' ! DUDP |
call add2list(varname,tvar,ntrace1) |
varname='DVDP' ! DVDP |
call add2list(varname,tvar,ntrace1) |
varname='RHO' ! RHO |
call add2list(varname,tvar,ntrace1) |
endif |
! Exit point for handling additional fields |
100 continue |
i = i + 1 |
enddo |
! Save the full variable name (including shift specification) |
do i=1,ncol |
varsint(i) = varsinp(i) |
enddo |
do i=1,ntrace1 |
varsint(i+ncol) = tvar(i) |
enddo |
! Bojan: check that PV and TH are on trajectory |
if (intmode .eq. 'clustering') then |
pvpos=-1 |
thpos=-1 |
do i=1,ncol+ntrace1 |
if (varsint(i) .eq. 'TH') then |
thpos=i |
print*,'Clustering: Found TH at position:',thpos |
endif |
if (varsint(i) .eq. 'PV') then |
pvpos=i |
print*,'Clustering: Found PV at position:',pvpos |
endif |
enddo |
if (thpos .eq. -1) then |
print*,'WARNING (clustering): Did not find TH' |
stop |
endif |
if (pvpos .eq. -1) then |
print*,'WARNING (clustering): Did not find PV' |
stop |
endif |
endif |
! Bojan |
! Split the tracing variables |
do i=1,ntrace0 |
call splitvar(tvar(i),shift_val(i),shift_dir(i) ) |
enddo |
! Split the variable name and set flags |
do i=ntrace0+1,ntrace1 |
! Set the scaling factor |
fac(i) = 1. |
! Set the base variable name, the shift and the direction |
call splitvar(tvar(i),shift_val(i),shift_dir(i) ) |
! Set the prefix of the file name for additional fields |
tfil(i)='*' |
do j=1,n_pvars |
if ( tvar(i).eq.pvars(j) ) tfil(i)=charp |
enddo |
do j=1,n_svars |
if ( tvar(i).eq.svars(j) ) tfil(i)=chars |
enddo |
! Set the computational flag |
if ( (tvar(i).eq.'P' ).or. & |
(tvar(i).eq.'PLAY').or. & |
(tvar(i).eq.'PLEV') ) then |
compfl(i) = 0 |
tfil(i) = charp |
elseif ( ( tfil(i).eq.charp ).or.( tfil(i).eq.chars ) ) then |
compfl(i) = 0 |
else |
compfl(i) = 1 |
endif |
enddo |
! Check whether the shift modes are supported |
do i=1,ntrace1 |
if ( ( shift_dir(i).ne.'nil' ).and. & |
( shift_dir(i).ne.'DLON' ).and. & |
( shift_dir(i).ne.'DLAT' ).and. & |
( shift_dir(i).ne.'DP' ).and. & |
( shift_dir(i).ne.'HPA' ).and. & |
( shift_dir(i).ne.'KM(LON)' ).and. & |
( shift_dir(i).ne.'KM(LAT)' ).and. & |
( shift_dir(i).ne.'H' ).and. & |
( shift_dir(i).ne.'MIN' ).and. & |
( shift_dir(i).ne.'INDP' ) ) then |
print*,' ERROR: shift mode ',trim(shift_dir(i)), ' not supported' |
stop |
endif |
enddo |
! Write status information |
print* |
print*,'---- COMPLETE TABLE FOR TRACING -------------------------' |
print* |
do i=1,ntrace1 |
if ( ( shift_dir(i).ne.'nil' ) ) then |
write(*,'(i4,a4,a8,f10.2,a8,3x,a1,i5)') i,' : ',trim(tvar(i)), & |
shift_val(i),trim(shift_dir(i)),tfil(i),compfl(i) |
else |
write(*,'(i4,a4,a8,10x,8x,3x,a1,i5)') & |
i,' : ',trim(tvar(i)),tfil(i),compfl(i) |
endif |
enddo |
! -------------------------------------------------------------------- |
! Prepare the internal and output trajectories |
! -------------------------------------------------------------------- |
! Allocate memory for internal trajectories |
allocate(traint(ntra,ntim,ncol+ntrace1),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array traint ***' |
! Copy input to output trajectory |
do i=1,ntra |
do j=1,ntim |
do k=1,ncol |
traint(i,j,k)=trainp(i,j,k) |
enddo |
enddo |
enddo |
! Set the flags for ready fields/colums - at begin only read-in fields are ready |
do i=1,ncol |
fok(i) = 1 |
enddo |
do i=ncol+1,ntrace1 |
fok(i) = 0 |
enddo |
! -------------------------------------------------------------------- |
! Trace the fields (fields available on input files) |
! -------------------------------------------------------------------- |
print* |
print*,'---- TRACING FROM PRIMARY AND SECONDARY DATA FILES ------' |
! Loop over all tracing fields |
do i=1,ntrace1 |
! Skip fields which must be computed (compfl=1), will be handled later |
if (compfl(i).ne.0) goto 110 |
! Write some status information |
print* |
print*,' Now tracing : ', trim(tvar(i)),shift_val(i),trim(shift_dir(i)),compfl(i),' ',trim(tfil(i)) |
! Set the flag for ready field/column |
fok(ncol+i) = 1 |
! Reset flags for load manager |
iloaded0 = -1 |
iloaded1 = -1 |
! Reset the counter for fields outside domain |
noutside = 0 |
err_c1 = 0 |
err_c2 = 0 |
err_c3 = 0 |
! Loop over all times |
do j=1,ntim |
! Convert trajectory time from hh.mm to fractional time |
call hhmm2frac(trainp(1,j,1),tfrac) |
! Shift time if requested |
if ( shift_dir(i).eq.'H' ) then |
tfrac = tfrac + shift_val(i) |
elseif ( shift_dir(i).eq.'MIN' ) then |
tfrac = tfrac + shift_val(i)/60. |
endif |
! Get the times which are needed |
itime0 = int(abs(tfrac-tstart)/timeinc) + 1 |
time0 = tstart + fbflag * real(itime0-1) * timeinc |
itime1 = itime0 + 1 |
time1 = time0 + fbflag * timeinc |
if ( itime1.gt.numdat ) then |
itime1 = itime0 |
time1 = time0 |
endif |
! Load manager: Check whether itime0 can be copied from itime1 |
if ( itime0.eq.iloaded1 ) then |
f3t0 = f3t1 |
p3t0 = p3t1 |
spt0 = spt1 |
iloaded0 = itime0 |
endif |
! Load manager: Check whether itime1 can be copied from itime0 |
if ( itime1.eq.iloaded0 ) then |
f3t1 = f3t0 |
p3t1 = p3t0 |
spt1 = spt0 |
iloaded1 = itime1 |
endif |
! Load manager: Load first time (tracing variable and grid) |
if ( itime0.ne.iloaded0 ) then |
filename = tfil(i)//dat(itime0) |
call frac2hhmm(time0,tload) |
varname = tvar(i) |
write(*,'(a23,a20,a3,a5,f7.2)') ' -> loading : ', trim(filename),' ',trim(varname),tload |
call input_open (fid,filename) |
call input_wind & |
(fid,varname,f3t0,tload,stagz,mdv, & |
xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_grid & |
(fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, & |
tload,pollon,pollat,p3t0,spt0,nz,ak,bk,stagz, & |
timecheck) |
call input_close(fid) |
iloaded0 = itime0 |
endif |
! Load manager: Load second time (tracing variable and grid) |
if ( itime1.ne.iloaded1 ) then |
filename = tfil(i)//dat(itime1) |
call frac2hhmm(time1,tload) |
varname = tvar(i) |
write(*,'(a23,a20,a3,a5,f7.2)') ' -> loading : ', trim(filename),' ',trim(varname),tload |
call input_open (fid,filename) |
call input_wind & |
(fid,varname,f3t1,tload,stagz,mdv, & |
xmin,xmax,ymin,ymax,dx,dy,nx,ny,nz,timecheck) |
call input_grid & |
(fid,varname,xmin,xmax,ymin,ymax,dx,dy,nx,ny, & |
tload,pollon,pollat,p3t1,spt1,nz,ak,bk,stagz, & |
timecheck) |
call input_close(fid) |
iloaded1 = itime1 |
endif |
! Loop over all trajectories |
do k=1,ntra |
! Set the horizontal position where to interpolate to |
x0 = traint(k,j,2) ! Longitude |
y0 = traint(k,j,3) ! Latitude |
! Set the vertical position where to interpolate to |
if ( nz.gt.1 ) then |
p0 = traint(k,j,4) ! Pressure (3D tracing) |
else |
p0 = 1050. ! Lowest level (2D tracing) |
endif |
! Set negative pressures to mdv |
if (p0.lt.0.) then |
f0 = mdv |
goto 109 |
endif |
! Set the relative time |
call hhmm2frac(traint(k,j,1),tfrac) |
reltpos0 = fbflag * (tfrac-time0)/timeinc |
! Make adjustments depending on the shift flag |
if ( shift_dir(i).eq.'DLON' ) then ! DLON |
x0 = x0 + shift_val(i) |
elseif ( shift_dir(i).eq.'DLAT' ) then ! DLAT |
y0 = y0 + shift_val(i) |
elseif ( shift_dir(i).eq.'KM(LON)' ) then ! KM(LON) |
x0 = x0 + shift_val(i)/deg2km * 1./cos(y0*pi180) |
elseif ( shift_dir(i).eq.'KM(LAT)' ) then ! KM(LAT) |
y0 = y0 + shift_val(i)/deg2km |
elseif ( shift_dir(i).eq.'HPA' ) then ! HPA |
p0 = p0 + shift_val(i) |
elseif ( shift_dir(i).eq.'DP' ) then ! DP |
call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0, & |
p3t0,p3t1,spt0,spt1,3,nx,ny,nz,xmin,ymin,dx,dy,mdv) |
pind = pind - shift_val(i) |
p0 = int_index4(p3t0,p3t1,nx,ny,nz,xind,yind,pind,reltpos0,mdv) |
elseif ( shift_dir(i).eq.'INDP' ) then |
p0 = int_index4(p3t0,p3t1,nx,ny,nz,xind,yind,shift_val(i),reltpos0,mdv) |
endif |
! Handle periodic boundaries in zonal direction |
if ( (x0.gt.xmax).and.(per.ne.0) ) x0 = x0 - 360. |
if ( (x0.lt.xmin).and.(per.ne.0) ) x0 = x0 + 360. |
! Handle pole problems for hemispheric data (taken from caltra.f) |
if ((hem.eq.1).and.(y0.gt.90.)) then |
print*,'WARNING: y0>90 ',y0,' => setting to 180-y0 ',180.-y0 |
y0=180.-y0 |
x0=x0+per/2. |
endif |
if ((hem.eq.1).and.(y0.lt.-90.)) then |
print*,'WARNING: y0<-90 ',y0,' => setting to -180-y0 ',-180.-y0 |
y0=-180.-y0 |
x0=x0+per/2. |
endif |
! Get the index where to interpolate (x0,y0,p0) |
if ( (abs(x0-mdv).gt.eps).and. (abs(y0-mdv).gt.eps) ) then |
call get_index4 (xind,yind,pind,x0,y0,p0,reltpos0, & |
p3t0,p3t1,spt0,spt1,3,nx,ny,nz,xmin,ymin,dx,dy,mdv) |
else |
xind = mdv |
yind = mdv |
pind = mdv |
endif |
! Check if point is within grid (keep indices if ok) |
if ( (xind.ge.1.).and.(xind.le.real(nx)).and. & |
(yind.ge.1.).and.(yind.le.real(ny)).and. & |
(pind.ge.1.).and.(pind.le.real(nz)) ) then |
xind = xind |
yind = yind |
pind = pind |
! Check if pressure is outside, but rest okay => adjust to lowest or highest level |
elseif ( (xind.ge.1.).and.(xind.le.real(nx)).and. (yind.ge.1.).and.(yind.le.real(ny)) ) then ! only vertical problem |
if ( pind.gt.nz ) then ! pressure too low, index too high |
err_c1 = err_c1 + 1 |
if ( err_c1.lt.10 ) then |
write(*,'(Af5.3A)') ' WARNING: pressure too low (pind = ',pind,') => adjusted to highest level (pind=nz.)' |
print*,'(x0,y0,p0)=',x0,y0,p0 |
pind = real(nz) |
elseif ( err_c1.eq.10 ) then |
print*,' WARNING: more pressures too low -> adjusted to highest level ' |
pind = real(nz) |
else |
pind = real(nz) |
endif |
elseif (pind.lt.1.) then ! pressure too high, index too low |
err_c2 = err_c2 + 1 |
if ( err_c2.lt.10 ) then |
write(*,'(Af5.3A)') ' WARNING: pressure too high (pind = ',pind,') => adjusted to lowest level, (pind=1.)' |
print*,'(x0,y0,p0)=',x0,y0,p0 |
pind = 1. |
elseif ( err_c2.eq.10 ) then |
print*,' WARNING: more pressures too high -> adjusted to lowest level ' |
pind = 1. |
else |
pind = 1. |
endif |
endif |
! Grid point is outside! |
else |
err_c3 = err_c3 + 1 |
if ( err_c3.lt.10 ) then |
print*,'ERROR: point is outside grid (horizontally)' |
print*,' Trajectory # ',k |
print*,' Position ',x0,y0,p0 |
print*,' (xind,yind): ',xind,yind |
xind = mdv |
yind = mdv |
pind = mdv |
traint(k,j,2) = mdv |
traint(k,j,3) = mdv |
traint(k,j,4) = mdv |
elseif ( err_c3.eq.10 ) then |
print*,'ERROR: more points outside grid (horizontally)' |
xind = mdv |
yind = mdv |
pind = mdv |
traint(k,j,2) = mdv |
traint(k,j,3) = mdv |
traint(k,j,4) = mdv |
else |
xind = mdv |
yind = mdv |
pind = mdv |
traint(k,j,2) = mdv |
traint(k,j,3) = mdv |
traint(k,j,4) = mdv |
endif |
endif |
! ------------------------ NEAREST mode ------------------------------- |
! Interpolate to nearest grid point |
if ( intmode.eq.'nearest') then |
xind = real( nint(xind) ) |
yind = real( nint(yind) ) |
pind = real( nint(pind) ) |
if ( xind.lt.1. ) xind = 1. |
if ( xind.gt.nx ) xind = real(nx) |
if ( yind.lt.1. ) yind = 1. |
if ( yind.gt.ny ) yind = real(ny) |
if ( pind.lt.1. ) pind = 1. |
if ( pind.gt.nz ) pind = real(nz) |
if ( abs(reltpos0).ge.eps ) then |
print*,'ERROR (nearest): reltpos != 0',reltpos0 |
stop |
endif |
! interpolate |
f0 = int_index4(f3t0,f3t1,nx,ny,nz,xind,yind,pind,reltpos0,mdv) |
! ------------------------ end NEAREST mode ------------------------------- |
! ------------------------ CLUSTERING mode ------------------------------- Bojan |
elseif (intmode.eq.'clustering') then |
if (varname.ne.'LABEL' ) then |
print*,'ERROR (clustering): varname is not LABEL' |
stop |
endif |
! Get indices of box around the point |
xindb=floor(xind) |
xindf=ceiling(xind) |
yindb=floor(yind) |
yindf=ceiling(yind) |
pindb=floor(pind) |
pindf=ceiling(pind) |
! Make sure all points are within grid |
if ( xindb.lt.1 ) xindb = 1 |
if ( xindf.lt.1 ) xindf = 1 |
if ( xindb.gt.nx ) xindb = nx |
if ( xindf.gt.nx ) xindf = nx |
if ( yindb.lt.1 ) yindb = 1 |
if ( yindf.lt.1 ) yindf = 1 |
if ( yindb.gt.ny ) yindb = ny |
if ( yindf.gt.ny ) yindf = ny |
if ( pindb.lt.1 ) pindb = 1 |
if ( pindf.lt.1 ) pindf = 1 |
if ( pindb.gt.nz ) pindb = nz |
if ( pindf.gt.nz ) pindf = nz |
! Shift one point if they are equal |
if ( xindb.eq.xindf ) then |
if ( xindf.eq.nx ) then |
xindb=nx-1 |
else |
xindf=xindb+1 |
endif |
endif |
if ( yindb.eq.yindf ) then |
if ( yindf.eq.ny ) then |
yindb=ny-1 |
else |
yindf=yindb+1 |
endif |
endif |
if ( pindb.eq.pindf ) then |
if ( pindf.eq.nz ) then |
pindb=nz-1 |
else |
pindf=pindb+1 |
endif |
endif |
! Give warnings and stop if problems occur |
if ( xindb.eq.xindf ) then |
print*,'ERROR (clustering): xindb=xindf' |
print*,xind,xindb,xindf |
stop |
endif |
if ( yindb.eq.yindf ) then |
print*,'ERROR (clustering): yindb=yindf' |
print*,yind,yindb,yindf |
stop |
endif |
if ( pindb.eq.pindf ) then |
print*,'ERROR (clustering): pindb=pindf' |
print*,pind,pindb,pindf |
stop |
endif |
if ( ( xindb.lt.1 ).or.( xindf.gt.nx ) ) then |
print*,'ERROR (clustering): xindb/f outside' |
print*,xind,xindb,xindf |
stop |
endif |
if ( ( yindb.lt.1 ).or.( yindf.gt.ny ) ) then |
print*,'ERROR (clustering): yindb/f outside' |
print*,yind,yindb,yindf |
stop |
endif |
if ( ( pindb.lt.1 ).or.( pindf.gt.nz ) ) then |
print*,'ERROR (clustering): pindb/f outside' |
print*,pind,pindb,pindf |
stop |
endif |
if ( abs(reltpos0).ge.eps ) then |
print*,'ERROR (clustering): reltpos != 0',reltpos0 |
stop |
endif |
! Get Value in Box |
lblcount=(/0,0,0,0,0/) |
lbl(1) = f3t0( xindb + nx*(yindb-1) + nx*ny*(pindb-1) ) |
lbl(2) = f3t0( xindf + nx*(yindb-1) + nx*ny*(pindb-1) ) |
lbl(3) = f3t0( xindb + nx*(yindf-1) + nx*ny*(pindb-1) ) |
lbl(4) = f3t0( xindf + nx*(yindf-1) + nx*ny*(pindb-1) ) |
lbl(5) = f3t0( xindb + nx*(yindb-1) + nx*ny*(pindf-1) ) |
lbl(6) = f3t0( xindf + nx*(yindb-1) + nx*ny*(pindf-1) ) |
lbl(7) = f3t0( xindb + nx*(yindf-1) + nx*ny*(pindf-1) ) |
lbl(8) = f3t0( xindf + nx*(yindf-1) + nx*ny*(pindf-1) ) |
! Count the number of times every label appears |
do lci=1,5 |
do lcj=1,8 |
if ( abs(lbl(lcj)-lci).lt.eps ) then |
lblcount(lci)=lblcount(lci)+1 |
endif |
enddo |
enddo |
! Set to -9 to detect if no label was assigned in the end |
f0=-9 |
! Stratosphere (PV) |
if ( abs(traint(k,j,pvpos)) .ge. tropo_pv ) then |
if ( (lblcount(2).ge.lblcount(3)).and. (lblcount(2).ge.lblcount(5)) ) then |
f0=2 |
elseif ( lblcount(3).ge.lblcount(5) ) then |
f0=3 |
elseif ( lblcount(5).gt.lblcount(3) ) then |
f0=5 |
endif |
endif |
! Troposphere (PV) |
if ( abs(traint(k,j,pvpos)) .lt. tropo_pv ) then |
if ( lblcount(1).ge.lblcount(4) ) then |
f0=1 |
elseif ( lblcount(4).gt.lblcount(1) ) then |
f0=4 |
endif |
endif |
! Stratosphere (TH) |
if ( traint(k,j,thpos) .ge. tropo_th ) then |
f0=2 |
endif |
if (f0.eq.-9) then |
print*,'ERROR (Clustering): No label assigned!' |
stop |
endif |
! ------------------------ end CLUSTERING mode ------------------------------- |
! ------------------------ CIRCLE modes ------------------------------- Bojan |
! elseif (not clustering but one of the possible circle modes) |
elseif ( (intmode.eq.'circle_avg') .or. (intmode.eq.'circle_min') .or. (intmode.eq.'circle_max') ) then |
! reset arrays for this point |
connect=0 |
stackx=0 |
stacky=0 |
circlelon=0 |
circlelat=0 |
circlef=0 |
circlearea=0 |
! Get indices of one coarse grid point within search radius (nint=round to next integer) |
if ( sdis(x0,y0,longrid(nint(xind)),latgrid(nint(yind))) .gt. radius) then |
print*,'ERROR (circle): Search radius is too small... (1). r =',radius |
print*,'Distance to nint grid point (minimum search radius)=',sdis(x0,y0,longrid(nint(xind)),latgrid(nint(yind))) |
stop |
endif |
! Initialize stack with nint(xind),nint(yind) |
kst=0 ! counts the number of points in circle |
stackx(1)=nint(xind) |
stacky(1)=nint(yind) |
sp=1 ! stack counter |
do while (sp.ne.0) |
! Get an element from stack |
ist=stackx(sp) |
jst=stacky(sp) |
sp=sp-1 |
! Get distance from reference point |
dist=sdis(x0,y0,longrid(ist),latgrid(jst)) |
! Check whether distance is smaller than search radius: connected |
if (dist.lt.radius) then |
! Increase total stack index |
kst=kst+1 |
circlelon(kst)=longrid(ist) |
circlelat(kst)=latgrid(jst) |
! Interpolate field to position of point (interpolation in time!) |
circlef(kst) = int_index4(f3t0,f3t1,nx,ny,nz,real(ist),real(jst),pind,reltpos0,mdv) |
! Calculate area of point (for circle_avg mode only) |
if ( intmode .eq. 'circle_avg' ) then |
circlearea(kst) = pir/(nx-1)*(sin(pi180*abs(circlelat(kst)))-sin(pi180*(abs(circlelat(kst))-dy))) |
endif |
! Mark this point as visited |
connect(ist,jst)=1 |
! Get coordinates of neighbouring points and implement periodicity |
mr=ist+1 |
if (mr.gt.nx) mr=1 |
ml=ist-1 |
if (ml.lt.1) ml=nx |
nu=jst+1 |
if (nu.gt.ny) nu=ny |
nd=jst-1 |
if (nd.lt.1) nd=1 |
! Update stack with neighbouring points |
if (connect(mr,jst).ne. 1) then |
connect(mr,jst)=1 |
sp=sp+1 |
stackx(sp)=mr |
stacky(sp)=jst |
endif |
if (connect(ml,jst).ne. 1) then |
connect(ml,jst)=1 |
sp=sp+1 |
stackx(sp)=ml |
stacky(sp)=jst |
endif |
if (connect(ist,nd).ne. 1) then |
connect(ist,nd)=1 |
sp=sp+1 |
stackx(sp)=ist |
stacky(sp)=nd |
endif |
if (connect(ist,nu).ne. 1) then |
connect(ist,nu)=1 |
sp=sp+1 |
stackx(sp)=ist |
stacky(sp)=nu |
endif |
endif ! endif radius is smaller => end of updating stack |
end do ! end working on stack |
if (kst.ge.1) then |
! Choose output depending on intmode |
if ( intmode .eq. 'circle_avg' ) then |
! calculate area-weighted average of f in circle |
circlesum=0. |
do l=1,kst |
circlesum=circlesum+circlef(l)*circlearea(l) |
enddo |
circleavg=circlesum/sum(circlearea(1:kst)) |
!print*,'area-weighted average of f in circle=',circleavg |
f0=circleavg |
elseif ( intmode .eq. 'circle_min' ) then |
! calculate minimum in circle |
circlemin=circlef(1) |
do l=1,kst |
if (circlef(l) .lt. circlemin) then |
circlemin=circlef(l) |
endif |
enddo |
!print*,'minimum of f in circle=',circlemin |
f0=circlemin |
elseif ( intmode .eq. 'circle_max' ) then |
! calculate maximum in circle |
circlemax=circlef(1) |
do l=1,kst |
if (circlef(l) .gt. circlemax) then |
circlemax=circlef(l) |
endif |
enddo |
!print*,'maximum of f in circle=',circlemax |
f0=circlemax |
else |
print*,'ERROR (circle): intmode not valid!' |
stop |
endif |
else |
print*,'ERROR (circle): Search radius is too small... (2). r =',radius |
stop |
endif |
! ------------------------ end CIRCLE modes ------------------------------- |
! ------------------------ NORMAL mode ------------------------------- |
else ! not clustering nor circle: NORMAL mode |
! Check if point is within grid |
! if ( (xind.ge.1.).and.(xind.le.real(nx)).and. & |
! (yind.ge.1.).and.(yind.le.real(ny)).and. & |
! (pind.ge.1.).and.(pind.le.real(nz)) ) then |
! |
! Do the interpolation: everthing is ok |
f0 = int_index4(f3t0,f3t1,nx,ny,nz,xind,yind,pind,reltpos0,mdv) |
! ! Check if pressure is outside, but rest okay: adjust to lowest or highest level |
! elseif ( (xind.ge.1.).and.(xind.le.real(nx)).and. (yind.ge.1.).and.(yind.le.real(ny)) ) then ! only vertical problem |
! if ( pind.gt.nz ) then ! pressure too low, index too high |
! pind = real(nz) |
! print*,' Warning: pressure too low -> adjusted to highest level, pind=nz.' |
! print*,'(x0,y0,p0)=',x0,y0,p0 |
! elseif (pind.lt.1.) then ! pressure too high, index too low |
! pind = 1. |
! print*,' Warning: pressure too high -> adjusted to lowest level, pind=1.' |
! print*,'(x0,y0,p0)=',x0,y0,p0 |
! endif |
! f0 = int_index4(f3t0,f3t1,nx,ny,nz,xind,yind,pind,reltpos0,mdv) |
! ! Less than 10 outside |
! elseif (noutside.lt.10) then |
! print*,' ',trim(tvar(i)),' @ ',x0,y0,p0,'outside' |
! f0 = mdv |
! noutside = noutside + 1 |
! |
! ! More than 10 outside |
! elseif (noutside.eq.10) then |
! print*,' ...more than 10 outside...' |
! f0 = mdv |
! noutside = noutside + 1 |
! ! Else (not everything okay and also not 'tolerated cases') set to missing data |
! else |
! f0 = mdv |
! endif |
! ------------------------ end NORMAL mode ------------------------------- |
endif ! end if nearest case |
! Exit for loop over all trajectories and times -save interpolated value |
109 continue |
! Save the new field |
if ( abs(f0-mdv).gt.eps) then |
traint(k,j,ncol+i) = f0 |
else |
traint(k,j,ncol+i) = mdv |
endif |
enddo ! end loop over all trajectories |
enddo ! end loop over all times |
! Exit point for loop over all tracing variables |
110 continue |
enddo ! end loop over all variables |
! -------------------------------------------------------------------- |
! Calculate additional fields along the trajectories |
! -------------------------------------------------------------------- |
print* |
print*,'---- CALCULATE ADDITIONAL FIELDS FROM TRAJECTORY TABLE --' |
! Loop over all tracing fields |
do i=ntrace1,1,-1 |
! Skip fields which must not be computed (compfl=0) |
if (compfl(i).eq.0) goto 120 |
! Write some status information |
print* |
write(*,'(a10,f10.2,a5,i3,3x,a2)') & |
trim(tvar(i)),shift_val(i),trim(shift_dir(i)),compfl(i),trim(tfil(i)) |
! Loop over trajectories and times |
do j=1,ntra |
do k=1,ntim |
! Potential temperature (TH) |
if ( varsint(i+ncol).eq.'TH' ) then |
varname='T' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='p' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
call calc_TH (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2) ) |
! Density (RHO) |
elseif ( varsint(i+ncol).eq.'RHO' ) then |
varname='T' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='p' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
call calc_RHO (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2) ) |
! Relative humidity (RH) |
elseif ( varsint(i+ncol).eq.'RH' ) then |
varname='T' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='p' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='Q' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
call calc_RH (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3) ) |
! Equivalent potential temperature (THE) |
elseif ( varsint(i+ncol).eq.'THE' ) then |
varname='T' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='p' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='Q' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
call calc_THE (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3) ) |
! Latent heating rate (LHR) |
elseif ( varsint(i+ncol).eq.'LHR' ) then |
varname='T' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='p' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='Q' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='OMEGA' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
varname='RH' |
call list2ind (ind5,varname,varsint,fok,ncol+ntrace1) |
call calc_LHR (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4),traint(j,k,ind5) ) |
! Wind speed (VEL) |
elseif ( varsint(i+ncol).eq.'VEL' ) then |
varname='U' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='V' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
call calc_VEL (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2) ) |
! Wind direction (DIR) |
elseif ( varsint(i+ncol).eq.'DIR' ) then |
varname='U' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='V' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
call calc_DIR (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2) ) |
! Zonal gradient of U (DUDX) |
elseif ( varsint(i+ncol).eq.'DUDX' ) then |
varname='U:+1DLON' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='U:-1DLON' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
call calc_DUDX (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3) ) |
! Zonal gradient of V (DVDX) |
elseif ( varsint(i+ncol).eq.'DVDX' ) then |
varname='V:+1DLON' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='V:-1DLON' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
call calc_DVDX (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3) ) |
! Zonal gradient of T (DTDX) |
elseif ( varsint(i+ncol).eq.'DVDX' ) then |
varname='T:+1DLON' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='T:-1DLON' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
call calc_DTDX (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3) ) |
! Zonal gradient of TH (DTHDX) |
elseif ( varsint(i+ncol).eq.'DTHDX' ) then |
varname='T:+1DLON' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='T:-1DLON' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='P' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_DTHDX (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4) ) |
! Meridional gradient of U (DUDY) |
elseif ( varsint(i+ncol).eq.'DUDY' ) then |
varname='U:+1DLAT' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='U:-1DLAT' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
call calc_DUDY (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2) ) |
! Meridional gradient of V (DVDY) |
elseif ( varsint(i+ncol).eq.'DVDY' ) then |
varname='V:+1DLAT' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='V:-1DLAT' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
call calc_DVDY (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2) ) |
! Meridional gradient of T (DTDY) |
elseif ( varsint(i+ncol).eq.'DTDY' ) then |
varname='T:+1DLAT' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='T:-1DLAT' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
call calc_DTDY (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2) ) |
! Meridional gradient of TH (DTHDY) |
elseif ( varsint(i+ncol).eq.'DTHDY' ) then |
varname='T:+1DLAT' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='T:-1DLAT' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='P' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
call calc_DTDY (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3) ) |
! Vertical wind shear DU/DP (DUDP) |
elseif ( varsint(i+ncol).eq.'DUDP' ) then |
varname='U:+1DP' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='U:-1DP' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='P:+1DP' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='P:-1DP' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_DUDP (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4) ) |
! Vertical wind shear DV/DP (DVDP) |
elseif ( varsint(i+ncol).eq.'DVDP' ) then |
varname='V:+1DP' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='V:-1DP' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='P:+1DP' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='P:-1DP' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_DVDP (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4) ) |
! Vertical derivative of T (DTDP) |
elseif ( varsint(i+ncol).eq.'DTDP' ) then |
varname='T:+1DP' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='T:-1DP' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='P:+1DP' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='P:-1DP' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_DTDP (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4) ) |
! Vertical derivative of TH (DTHDP) |
elseif ( varsint(i+ncol).eq.'DTHDP' ) then |
varname='T:+1DP' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='T:-1DP' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='P:+1DP' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='P:-1DP' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
varname='P' |
call list2ind (ind5,varname,varsint,fok,ncol+ntrace1) |
varname='T' |
call list2ind (ind6,varname,varsint,fok,ncol+ntrace1) |
call calc_DTHDP (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4),traint(j,k,ind5),traint(j,k,ind6) ) |
! Squared Brunt-Vaisäla frequency (NSQ) |
elseif ( varsint(i+ncol).eq.'NSQ' ) then |
varname='DTHDP' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='TH' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='RHO' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
call calc_NSQ (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3)) |
! Relative vorticity (RELVORT) |
elseif ( varsint(i+ncol).eq.'RELVORT' ) then |
varname='DUDY' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='DVDX' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='U' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_RELVORT (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4)) |
! Absolute vorticity (ABSVORT) |
elseif ( varsint(i+ncol).eq.'ABSVORT' ) then |
varname='DUDY' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='DVDX' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='U' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_ABSVORT (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4)) |
! Divergence (DIV) |
elseif ( varsint(i+ncol).eq.'DIV' ) then |
varname='DUDX' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='DVDY' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='V' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_DIV (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4)) |
! Deformation (DEF) |
elseif ( varsint(i+ncol).eq.'DEF' ) then |
varname='DUDX' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='DVDX' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='DUDY' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='DVDY' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_DEF (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4)) |
! Potential Vorticity (PV) |
elseif ( varsint(i+ncol).eq.'PV' ) then |
varname='ABSVORT' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='DTHDP' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='DUDP' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='DVDP' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
varname='DTHDX' |
call list2ind (ind5,varname,varsint,fok,ncol+ntrace1) |
varname='DTHDY' |
call list2ind (ind6,varname,varsint,fok,ncol+ntrace1) |
call calc_PV (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4),traint(j,k,ind5),traint(j,k,ind6) ) |
! Richardson number (RI) |
elseif ( varsint(i+ncol).eq.'RI' ) then |
varname='DUDP' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='DVDP' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='NSQ' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='RHO' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_RI (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4) ) |
! Ellrod and Knapp's turbulence idicator (TI) |
elseif ( varsint(i+ncol).eq.'TI' ) then |
varname='DEF' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='DUDP' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
varname='DVDP' |
call list2ind (ind3,varname,varsint,fok,ncol+ntrace1) |
varname='RHO' |
call list2ind (ind4,varname,varsint,fok,ncol+ntrace1) |
call calc_TI (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,k,ind3),traint(j,k,ind4) ) |
! Spherical distance from starting position (DIST0) |
elseif ( varsint(i+ncol).eq.'DIST0' ) then |
varname='lon' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
call calc_DIST0 (traint(j,k,ncol+i), traint(j,k,ind1), & |
traint(j,k,ind2),traint(j,1,ind1),traint(j,1,ind2) ) |
! Spherical distance length of trajectory (DIST) |
elseif ( varsint(i+ncol).eq.'DIST' ) then |
varname='lon' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
if ( k.eq.1 ) then |
traint(j,k,ncol+i) = 0. |
else |
call calc_DIST0 (delta, traint(j,k ,ind1), & |
traint(j,k ,ind2),traint(j,k-1,ind1),traint(j,k-1,ind2) ) |
traint(j,k,ncol+i) = traint(j,k-1,ncol+i) + delta |
endif |
! Heading of the trajectory (HEAD) |
elseif ( varsint(i+ncol).eq.'HEAD' ) then |
varname='lon' |
call list2ind (ind1,varname,varsint,fok,ncol+ntrace1) |
varname='lat' |
call list2ind (ind2,varname,varsint,fok,ncol+ntrace1) |
if (k.eq.ntim) then |
traint(j,k,ncol+i) = mdv |
else |
call calc_HEAD (traint(j,k,ncol+i), & |
traint(j,k ,ind1),traint(j,k ,ind2),traint(j,k+1,ind1),traint(j,k+1,ind2) ) |
endif |
! Invalid tracing variable |
else |
print*,' ERROR: invalid tracing variable ', trim(varsint(i+ncol)) |
stop |
endif |
! End loop over all trajectories and times |
enddo |
enddo |
! Set the flag for a ready field/column |
fok(ncol+i) = 1 |
! Exit point for loop over all tracing fields |
120 continue |
enddo |
! -------------------------------------------------------------------- |
! Write output to output trajectory file |
! -------------------------------------------------------------------- |
! Write status information |
print* |
print*,'---- WRITE OUTPUT TRAJECTORIES --------------------------' |
print* |
! Allocate memory for internal trajectories |
allocate(traout(ntra,ntim,ncol+ntrace0),stat=stat) |
if (stat.ne.0) print*,'*** error allocating array traout ***' |
! Copy input to output trajectory (apply scaling of output) |
do i=1,ntra |
do j=1,ntim |
do k=1,ncol+ntrace0 |
if ( k.le.ncol ) then |
traout(i,j,k) = traint(i,j,k) |
elseif ( abs(traint(i,j,k)-mdv).gt.eps ) then |
traout(i,j,k) = fac(k-ncol) * traint(i,j,k) |
else |
traout(i,j,k) = mdv |
endif |
enddo |
enddo |
enddo |
! Set the variable names for output trajectory |
do i=1,ncol+ntrace0 |
varsout(i) = varsint(i) |
enddo |
! Write trajectories |
call wopen_tra(fod,outfile,ntra,ntim,ncol+ntrace0, & |
reftime,varsout,outmode) |
call write_tra(fod,traout ,ntra,ntim,ncol+ntrace0,outmode) |
call close_tra(fod,outmode) |
! Write some status information, and end of program message |
print* |
print*,'---- STATUS INFORMATION --------------------------------' |
print* |
print*,' ok' |
print* |
print*,' *** END OF PROGRAM TRACE ***' |
print*,'=========================================================' |
end program trace |
! ****************************************************************** |
! * SUBROUTINE SECTION * |
! ****************************************************************** |
! ------------------------------------------------------------------ |
! Add a variable to the list if not yet included in this list |
! ------------------------------------------------------------------ |
subroutine add2list (varname,list,nlist) |
implicit none |
! Declaration of subroutine parameters |
character(len=80) :: varname |
character(len=80) :: list(200) |
integer :: nlist |
! Auxiliray variables |
integer :: i,j |
integer :: isok |
! Expand the list, if necessary |
isok = 0 |
do i=1,nlist |
if ( list(i).eq.varname ) isok = 1 |
enddo |
if ( isok.eq.0 ) then |
nlist = nlist + 1 |
list(nlist) = varname |
endif |
! Check for too large number of fields |
if ( nlist.ge.200) then |
print*,' ERROR: too many additional fields for tracing ...' |
stop |
endif |
end subroutine add2list |
! ------------------------------------------------------------------ |
! Get the index of a variable in the list |
! ------------------------------------------------------------------ |
subroutine list2ind (ind,varname,list,fok,nlist) |
implicit none |
! Declaration of subroutine parameters |
integer :: ind |
character(len=80) :: varname |
character(len=80) :: list(200) |
integer :: fok(200) |
integer :: nlist |
! Auxiliray variables |
integer :: i,j |
integer :: isok |
! Get the index - error message if not found |
ind = 0 |
do i=1,nlist |
if ( varname.eq.list(i) ) then |
ind = i |
goto 100 |
endif |
enddo |
if ( ind.eq.0) then |
print* |
print*,' ERROR: cannot find ',trim(varname),' in list ...' |
do i=1,nlist |
print*,i,trim(list(i)) |
enddo |
print* |
stop |
endif |
! Exit point |
100 continue |
! Check whether the field/column is ready |
if ( fok(ind).eq.0 ) then |
print* |
print*,' ERROR: unresolved dependence : ',trim(list(ind)) |
print* |
stop |
endif |
end subroutine list2ind |
! ------------------------------------------------------------------ |
! Split the variable name into name, shift and direction |
! ------------------------------------------------------------------ |
subroutine splitvar (tvar,shift_val,shift_dir) |
implicit none |
! Declaration of subroutine parameters |
character(len=80) :: tvar |
real :: shift_val |
character(len=80) :: shift_dir |
! Auxiliary variables |
integer :: i,j |
integer :: icolon,inumber |
character(len=80) :: name |
character :: ch |
! Save variable name |
name = tvar |
! Search for colon |
icolon=0 |
do i=1,80 |
if ( (name(i:i).eq.':').and.(icolon.ne.0) ) goto 100 |
if ( (name(i:i).eq.':').and.(icolon.eq.0) ) icolon=i |
enddo |
! If there is a colon, split the variable name |
if ( icolon.ne.0 ) then |
tvar = name(1:(icolon-1)) |
do i=icolon+1,80 |
ch = name(i:i) |
if ( ( ch.ne.'0' ).and. ( ch.ne.'1' ).and.( ch.ne.'2' ).and. & |
( ch.ne.'3' ).and. ( ch.ne.'4' ).and.( ch.ne.'5' ).and. & |
( ch.ne.'6' ).and. ( ch.ne.'7' ).and.( ch.ne.'8' ).and. & |
( ch.ne.'9' ).and. ( ch.ne.'+' ).and.( ch.ne.'-' ).and. & |
( ch.ne.'.' ).and. ( ch.ne.' ' ) ) then |
inumber = i |
exit |
endif |
enddo |
read(name( (icolon+1):(inumber-1) ),*) shift_val |
shift_dir = name(inumber:80) |
else |
shift_dir = 'nil' |
shift_val = 0. |
endif |
return |
! Error handling |
100 continue |
print*,' ERROR: cannot split variable name ',trim(tvar) |
stop |
end subroutine splitvar |
/tags/1.0/trace/trace.make |
---|
0,0 → 1,8 |
F77 = ${FORTRAN} |
FFLAGS = -O |
OBJS = ${LAGRANTO}/lib/times.a ${LAGRANTO}/lib/iotra.a ${LAGRANTO}/lib/ioinp.a ${LAGRANTO}/lib/inter.a ${LAGRANTO}/lib/libcdfio.a ${LAGRANTO}/lib/libcdfplus.a |
INCS = ${NETCDF_INC} |
LIBS = ${NETCDF_LIB} |
trace: $(OBJS) |
${F77} -o trace trace.f90 calvar.f $(OBJS) ${INCS} $(LIBS) |
/tags/1.0/trace/trace.sh |
---|
0,0 → 1,616 |
#!/bin/csh |
# --------------------------------------------------------------------- |
# Usage, parameter settings |
# --------------------------------------------------------------------- |
# Set Lagranto |
set LAGRANTO = ${LAGRANTOBASE}.${MODEL}/ |
# Write usage information |
if ( (${#argv} == 0) | (${#argv} < 2) ) then |
echo |
${LAGRANTO}/bin/lagrantohelp trace short |
echo |
exit 0 |
endif |
# Write title |
echo |
echo '=========================================================' |
echo ' *** START OF PREPROCESSOR TRACE *** ' |
echo |
# Get the arguments |
set inpfile = $1 |
set outfile = $2 |
# Set base directories (run+prog) |
set cdfdir=${PWD} |
set tradir=${PWD} |
# Set program paths and filenames |
set parfile = ${tradir}/trace.param |
set prog = ${LAGRANTO}/trace/trace |
# Set the prefix of the primary and secondary data files |
set charp = 'P' |
set chars = 'S' |
echo '---- DIRECTORIES AND PROGRAMS ---------------------------' |
echo |
echo "CDF directory : ${cdfdir}" |
echo "TRA directory : ${tradir}" |
echo "PROGRAM TRACE : ${prog}" |
echo "PARAMETER file : ${parfile}" |
echo |
# --------------------------------------------------------------------- |
# Set optional flags |
# --------------------------------------------------------------------- |
echo '---- OPTIONAL FLAGS -------------------------------------' |
echo |
# Set some default values ("nil" must be set according to input files) |
set flag_i = "nil" |
set flag_v = "tracevars" |
set flag_f = "nil" |
set tvfile = 'tracevars' |
set changet = 'false' |
set noclean = 'false' |
set timecheck = 'no' |
set intmode = 'normal' |
set radius = '0' |
set tropo_pv = '2' |
set tropo_th = '380' |
# Set flag for consistency |
set isok = 1 |
while ( $#argv > 0 ) |
switch ( $argv[1] ) |
case -i |
set flag_i=$argv[2] |
echo "Flag '-i' -> ${flag_i} (user defined)" |
shift; |
breaksw |
case -v |
set flag_v="-v" |
set tvfile=$argv[2] |
echo "Flag '-v' -> ${tvfile} (user defined)" |
shift; |
if ( $isok == 2 ) set isok = 0 |
if ( $isok == 1 ) set isok = 2 |
breaksw |
case -f |
set flag_f="-f" |
set tvfile="tracevars.tmp" |
shift; |
set tvar="$argv[1]" |
shift; |
set tscale="$argv[1]" |
echo "Flag '-f' -> ${tvar} ${tscale} (user defined)" |
if ( $isok == 2 ) set isok = 0 |
if ( $isok == 1 ) set isok = 2 |
breaksw |
case -changet |
set changet = 'true' |
echo "changet -> true (user defined)" |
breaksw |
case -noclean |
set noclean = 'true' |
echo "noclean -> true (user defined)" |
breaksw |
case -timecheck |
set timecheck = 'yes' |
echo "timecheck -> yes (user defined)" |
breaksw |
case -nearest |
set intmode = 'nearest' |
echo "intmode -> nearest (user defined)" |
breaksw |
case -clustering |
set intmode = 'clustering' |
echo "intmode -> clustering (user defined)" |
shift; |
if ( "$1" == "" ) then |
echo "ERROR (clustering): specify tropopause PV [pvu] and TH [K]! Example: -clustering 2 380" |
exit |
else |
set tropo_pv = $1 |
endif |
shift; |
if ( "$1" == "" ) then |
echo "ERROR (clustering): specify tropopause PV [pvu] and TH [K]! Example: -clustering 2 380" |
exit |
else |
set tropo_th = $1 |
echo 'intmode -> clustering tropo_pv = ' ${tropo_pv} 'pvu and tropo_th = ' ${tropo_th} 'K' |
endif |
breaksw |
case -circle_avg |
set intmode = 'circle_avg' |
echo "intmode -> circle_avg (user defined)" |
shift; |
if ( "$1" == "" ) then |
echo "ERROR (circle_avg): specify radius in circle mode (km)! Example: -circle_avg 500" |
exit |
else |
set radius = $1 |
echo 'intmode -> circle_avg radius =' ${radius} 'km' |
endif |
breaksw |
case -circle_min |
set intmode = 'circle_min' |
echo "intmode -> circle_min (user defined)" |
shift; |
if ( "$1" == "" ) then |
echo "ERROR (circle_min): specify radius in circle mode (km)! Example: -circle_min 400" |
exit |
else |
set radius = $1 |
echo 'intmode -> circle_min radius =' ${radius} 'km' |
endif |
breaksw |
case -circle_max |
set intmode = 'circle_max' |
echo "intmode -> circle_max (user defined)" |
shift; |
if ( "$1" == "" ) then |
echo "ERROR (circle_max): specify radius in circle mode (km)! Example: -circle_max 600" |
exit |
else |
set radius = $1 |
echo 'intmode -> circle_max radius =' ${radius} 'km' |
endif |
breaksw |
endsw |
shift; |
end |
# No change of times necessary if no check requested |
if ( "${timecheck}" == "no" ) then |
set changet = 'false' |
endif |
# Check consitency of arguments |
if ( $isok == 0 ) then |
echo |
echo " ERROR: Use either option '-v' or '-f', but not both..." |
exit 1 |
endif |
# --------------------------------------------------------------------- |
# Handle the input trajectory file |
# --------------------------------------------------------------------- |
echo |
echo '---- TIME RANGE -----------------------------------------' |
echo |
# Check whether the input file can be found |
if ( ! -f ${inpfile} ) then |
echo " ERROR : Input file ${inpfile} is missing" |
exit 1 |
endif |
# Get the start, end and reference date for the tracing |
set startdate = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} startdate` |
set enddate = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} enddate` |
set refdate = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} refdate` |
set ntra = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} ntra` |
set ntim = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} ntim` |
set ncol = `${LAGRANTO}/goodies/trainfo.sh ${inpfile} ncol` |
# Check format of start and end date - must be the same |
set ns=`echo $startdate | sed -e 's/_[0-9]*//' | wc -c` |
set ne=`echo $enddate | sed -e 's/_[0-9]*//' | wc -c` |
if ( $ns != $ne ) then |
echo " ERROR: start and end date must be in the same format ***" |
exit 1 |
endif |
if ( $ns != 9 ) then |
echo " ERROR: Date format must be yyyymmdd ***" |
exit 1 |
endif |
set ns=`echo $startdate | sed -e 's/[0-9]*_//' | wc -c` |
set ne=`echo $enddate | sed -e 's/[0-9]*_//' | wc -c` |
if ( $ns != $ne ) then |
echo " ERROR: start and end date must be in the same format ***" |
exit 1 |
endif |
if ( ( $ns != 5 ) & ( $ns != 3 ) ) then |
echo " ERROR: Time format must be hh(mm) ***" |
exit 1 |
endif |
# Split the start and end date into <yymmdd_hh and mm> |
set startdate_ymdh = `echo $startdate | cut -c 1-11` |
set startdate_min = `echo $startdate | cut -c 12-13` |
if ( $startdate_min == "" ) set startdate_min = 00 |
set enddate_ymdh = `echo $enddate | cut -c 1-11` |
set enddate_min = `echo $enddate | cut -c 12-13` |
if ( $enddate_min == "" ) set enddate_min = 00 |
# Get the time difference between <start_ymdh> and <end_ymdh> date |
# Decide whether trajectoriesare forward or backward |
set timediff_hh = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${startdate_ymdh}` |
if ( $timediff_hh == 0 ) then |
if ( $enddate_min > $startdate_min ) then |
set direction = f |
set idir = 1 |
else |
set direction = b |
set idir = -1 |
endif |
else if ( $timediff_hh > 0 ) then |
set direction = f |
set idir = 1 |
else |
set direction = b |
set idir = -1 |
@ timediff_hh = $idir * $timediff_hh |
endif |
# Get also minutes for time difference, if <start_min> or <end_min> != 0 |
set timediff_mm= |
if ( $startdate_min != 00 || $enddate_min != 00 ) then |
@ min = ( $enddate_min - $startdate_min ) |
if ( $min == 0 ) then |
set timediff_mm= |
else if ( $min > 0 ) then |
if ( $idir == 1 ) then |
set timediff_mm=$min |
else |
@ timediff_hh -- |
@ timediff_mm = 60 - $min |
endif |
else |
if ( $idir == 1 ) then |
@ timediff_hh -- |
@ timediff_mm = 60 + $min |
else |
@ timediff_mm = 0 - $min |
endif |
endif |
endif |
# Write status information |
echo "Time range : ${startdate} -> ${enddate}" |
if ( ${timediff_mm} != "" ) then |
echo "Time difference : ${timediff_hh} h ${timediff_mm} min" |
else |
echo "Time difference : ${timediff_hh} h" |
endif |
echo "Direction : ${direction} (${idir})" |
# --------------------------------------------------------------------- |
# Check availability of input data |
# --------------------------------------------------------------------- |
echo |
echo '---- INPUT FILES ----------------------------------------' |
echo |
# Take the time increment from flag list ('nil', if not defined) |
set timeinc = ${flag_i} |
# Find a first data file (if possible corresponding to start/end date |
# If starttime is not a data time, take the first file in the direectory |
if ( $direction == "f" ) then |
set file=${charp}${startdate_ymdh} |
else |
set file=${charp}${enddate_ymdh} |
endif |
if ( ! -f $file ) then |
set file=`ls ${charp}[0-9_]*[0-9] | head -1 | sed -e 's/@//'` |
endif |
# Determine timeinc (the time difference in hours between two data file) |
# if not already defined with option -i |
if ( ${timeinc} == "nil" ) then |
set date1=`echo $file | cut -c 2-12` |
set n=`ls ${charp}[0-9_]*[0-9] | grep -n $date1 | awk -F: '{print $1}'` |
@ n ++ |
set date2=`ls ${charp}[0-9_]*[0-9] | head -$n | tail -1 | cut -c 2-12` |
set timeinc=`${LAGRANTO}/goodies/gettidiff $date2 $date1` |
endif |
if ( $timeinc == 0 ) then |
echo " ERROR: cannot set the time increment between input files ***" |
exit 1 |
endif |
# Search the first file to use: We step through all P files and see whether they are |
# good P files. Let's first do the test for the first data file found. If it's ok, we |
# take it; if not, we step through all P files and find the good one |
set flag=0 |
set td= |
set date = `echo $file | cut -c 2-12` |
set td1 = `${LAGRANTO}/goodies/gettidiff ${startdate_ymdh} ${date}` |
set td2 = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${date}` |
if (( $td1 < $timeinc || $td2 < $timeinc ) && ( $td1 >= 0 || $td2 >= 0 )) then |
set datfiles=$date |
if ( $td1 < $timeinc ) set td=$td1 |
if ( $td2 < $timeinc ) set td=$td2 |
if ( ( $startdate_min > 0 ) || ( $enddate_min > 0 ) ) @ td ++ |
goto label2 |
endif |
foreach i ( ${charp}????????_?? ) |
set date = `echo $i | cut -c 2-12` |
set td1 = `${LAGRANTO}/goodies/gettidiff ${startdate_ymdh} ${date}` |
set td2 = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${date}` |
if (( $td1 < $timeinc || $td2 < $timeinc ) && ( $td1 >= 0 || $td2 >= 0 )) then |
set datfiles=$date |
if ( $td1 < $timeinc ) set td=$td1 |
if ( $td2 < $timeinc ) set td=$td2 |
if ( ( $startdate_min > 0 ) || ( $enddate_min > 0 ) ) @ td ++ |
goto label2 |
endif |
end |
# if no P/T-files are available for the specified time period, then $td is |
# still undefined |
if ( $td == "" ) then |
echo " ERROR: no data files available for the specified time period" |
exit 1 |
endif |
# Everything is fine so far: proceed |
label2: |
# Check whether first date is ok - before or at needed dates |
if ( $direction == "f" ) then |
set tdiff0 = `${LAGRANTO}/goodies/gettidiff ${startdate_ymdh} ${date}` |
else |
set tdiff0 = `${LAGRANTO}/goodies/gettidiff ${enddate_ymdh} ${date}` |
endif |
if ( $tdiff0 < 0 ) then |
echo " ERROR: data files missing for the specified time period" |
exit 1 |
endif |
# Calculate the number of further files |
@ num = ( $timediff_hh + $td ) / $timeinc + 1 |
@ dum1 = ( $num - 1 ) * $timeinc |
@ dum2 = $timediff_hh + $td |
if ( $dum1 != $dum2 ) @ num ++ |
# Get a list of all needed files |
set numfiles=$num |
set sfiles=1 |
while ( $num > 1 ) |
set date=`${LAGRANTO}/goodies/newtime $date $timeinc` |
if ( ! -f ${charp}${date} ) then |
echo " ERROR: file with primary data is missing for $date" |
exit 1 |
else if ( ! -f ${chars}${date} ) then |
set sfiles=0 |
set datfiles=`echo $datfiles $date` |
else |
set datfiles=`echo $datfiles $date` |
endif |
@ num -- |
end |
# Calculate the start and the end time relative to the first datfile |
if ( $direction == f ) then |
set tstart = `${LAGRANTO}/goodies/gettidiff $startdate $datfiles[1]` |
set tend = `${LAGRANTO}/goodies/gettidiff $datfiles[$numfiles] $enddate` |
else |
set tstart = `${LAGRANTO}/goodies/gettidiff $datfiles[$numfiles] $startdate` |
set tend = `${LAGRANTO}/goodies/gettidiff $enddate $datfiles[1]` |
endif |
# Write some status information |
echo "Primary file prefix : ${charp}" |
echo "Secondary file prefix : ${chars}" |
echo "Time increment for input files : ${timeinc}" |
echo "# input files : ${numfiles}" |
echo "First input file : $datfiles[1] " |
echo "Last input file : $datfiles[$numfiles] " |
echo "${charp} files availability : 1" |
echo "${chars} files availability : ${sfiles}" |
if ( $direction == f ) then |
echo "Start time relative to first file : $datfiles[1] + ${tstart} " |
echo "End time relative to last file : $datfiles[$numfiles] - ${tend} " |
else |
echo "Start time relative to last file : $datfiles[$numfiles] - ${tstart} " |
echo "End time relative to first file : $datfiles[1] + ${tend} " |
endif |
# --------------------------------------------------------------------- |
# Check availability of input data |
# --------------------------------------------------------------------- |
echo |
echo '---- TRACEVAR FILE --------------------------------------' |
echo |
# If "-f" option is used, create a temporary tracevar file |
if ( "${flag_f}" == "-f" ) then |
# Preset values for <compfl> and <tprefix> |
set tcompfl=1 |
set tprefix='P' |
# Check availability on P file |
foreach var ( `${LAGRANTO}/goodies/getvars ${charp}$datfiles[1]` ) |
if ( "${var}" == "${tvar}" ) then |
set tcompfl=0 |
set tprefix="P" |
endif |
end |
# Check availability on S file |
if ( ${sfiles} == 1 ) then |
foreach var ( `${LAGRANTO}/goodies/getvars ${chars}$datfiles[1]` ) |
if ( "${var}" == "${tvar}" ) then |
set tcompfl=0 |
set tprefix="S" |
endif |
end |
endif |
# Write the temporary <tracevars> file |
echo "${tvar} ${tscale} ${tcompfl} ${tprefix}" >! ${tvfile} |
echo "Temporary tracervar file <${tvfile}> created" |
echo |
endif |
# Check if tracevars-file exists |
if ( ! -f $tvfile ) then |
echo " ERROR: file $tvfile was not found ***" |
exit 1 |
endif |
# check if the variables contained in the tracevars-file are available in the |
# data file and check also if there are no empty lines in the tracevars-file |
set nlines = `cat $tvfile | wc -l` |
set vars = `cat $tvfile | awk '{print $1}'` |
set nvars = `echo $vars | wc -w` |
if ( $nlines != $nvars ) then |
echo " ERROR: tracevars-files must not contain empty lines ***" |
exit 1 |
endif |
set calf=`cat $tvfile | awk '{print $3}'` |
set tfil=`cat $tvfile | awk '{print $4}'` |
# Write some status information |
cat ${tvfile} |
echo |
echo "# Number of tracing variables : ${nlines}" |
echo "Fields are read from following files : ${tfil}" |
# Loop over all variables - check availability |
foreach v ( $vars ) |
if ( $calf[1] == 0 ) then |
set v0 = `echo $v | awk 'BEGIN {FS = ":"}; {print $1}'` |
set flag=`${LAGRANTO}/goodies/getvars $tfil[1]$datfiles[1] | grep " $v0 " | wc -l` |
set iscomment=`echo $v0 | cut -c 1` |
if ( "${iscomment}" != "#" ) then |
if ( $flag == 0 ) then |
echo " ERROR: variable $v listed in $tvfile is not on the $tfil[1]-files ***" |
exit 1 |
endif |
endif |
endif |
shift calf |
shift tfil |
end |
set ntrace=${nlines} |
# --------------------------------------------------------------------- |
# Prepare input file for trace and run it |
# --------------------------------------------------------------------- |
# Set times relative to the reference date |
if ( "${changet}" == "true" ) then |
echo |
echo '---- CHANGE TIMES ON DATA FILES ------------------------' |
echo |
foreach i ( $datfiles ) |
${LAGRANTO}/goodies/changet.sh ${refdate} ${charp}${i} |
end |
if ( ${sfiles} == 1 ) then |
foreach i ( $datfiles ) |
${LAGRANTO}/goodies/changet.sh ${refdate} ${chars}${i} |
end |
endif |
endif |
# --------------------------------------------------------------------- |
# Prepare input file for caltra and run it |
# --------------------------------------------------------------------- |
# Write parameter file |
\rm -f ${parfile} |
touch ${parfile} |
echo $inpfile >> $parfile |
echo $outfile >> $parfile |
echo $startdate >> $parfile |
echo $enddate >> $parfile |
echo $idir >> $parfile |
echo $numfiles >> $parfile |
foreach i ( $datfiles ) |
echo $i >> $parfile |
end |
echo $timeinc >> $parfile |
echo $tstart >> $parfile |
echo $tend >> $parfile |
echo $ntra >> $parfile |
echo $ntim >> $parfile |
echo $ncol >> $parfile |
echo $ntrace >> $parfile |
cat ${tvfile} >> $parfile |
${LAGRANTO}/goodies/getvars ${charp}$datfiles[1] | wc -l >> $parfile |
${LAGRANTO}/goodies/getvars ${charp}$datfiles[1] >> $parfile |
if ( $sfiles == 1 ) then |
${LAGRANTO}/goodies/getvars ${chars}$datfiles[1] | wc -l >> $parfile |
${LAGRANTO}/goodies/getvars ${chars}$datfiles[1] >> $parfile |
else |
echo 0 >> $parfile |
endif |
echo \"${timecheck}\" >> $parfile |
echo \"${intmode}\" >> $parfile |
echo ${radius} >> $parfile # Bojan circle mode |
echo ${tropo_pv} >> $parfile # Bojan clustering mode |
echo ${tropo_th} >> $parfile # Bojan clustering mode |
# Finish the preprocessor |
echo |
echo ' *** END OF PREPROCESSOR TRACE *** ' |
echo '=========================================================' |
echo |
# Run trace |
${prog} |
if ( "${status}" != "0" ) then |
echo "ERROR: Program <trace> failed" |
exit 1 |
endif |
# --------------------------------------------------------------------- |
# Final tasks (make clean) |
# --------------------------------------------------------------------- |
finish: |
if ( "${noclean}" == "false" ) then |
\rm -f ${parfile} |
endif |
exit 0 |
Property changes: |
Added: svn:executable |