#!/usr/bin/perl -w
#
# generate list file for IDL visualizer
# from time.dat.* data files matching grid files and input parameters
#
# Modification history: 2002 - first SAMI2 version: 0.90
# 2011/01/28 Lutz Rastaetter - adapted from SAMI_list.pl (for SAMI-2 model)
#                         supporting sami3_mpi-1.00
# 2011/03/24: use write_sami3conf.pro to write whole range in
#                         ionospheric longitudes and latitudes
# 2011/10/13 - Lutz Rastaetter - read data once to create tetra*dat files
#                         that complete the setup for online visualization
#
# 2016/11/03 Lutz Rastaetter - Generate TEC data from SAMI3 outputs.
# 2016/11/04 Lutz Rastaetter - separated out from SAAMI_list.pl script.
# 2017/07/19 Lutz Rastaetter - using gfortran to compile sources.
# 2017/08/16 Lutz Rastaetter - use -mcmodel=medium to compile interpolation and tec calcualtion executables for larger runs
# 2021/06/04 Maksym Petrenko - surrounded 'grep parameter' with \s and $ to make sure epxressions are have correct bounds

# some global path names
$ENV{'DISPLAY'}="";
$script_name=`basename $0`;
chomp $script_name;
$PERLSCRIPTDIR=substr($0,0,index($0,$script_name));
#
# input file used
#
# this will pick up param-0.97.inc as well
#
@allparam=`ls param3_mpi-????.inc |tail -1`;
chomp @allparam;
$param_filename=$allparam[0];
if ($param_filename ne ""){
    $SAMI3_version=substr($param_filename,11,4);
} else {
    if ( -s "parameter_mod.f90" ){
	$param_filename="parameter_mod.f90";
	$SAMI3_version=`grep version DatabaseInfo | awk '{print \$1}'`;
    } else {
	print "no file comtaining needed parameters found\n";
	exit 1;
    }  
}
print "SAMI3 version: $SAMI3_version\n";
#
# getting variable order from param file
#
$pthp=`grep parameter $param_filename | grep '\\sh\\+\$' | awk '{print \$5}'`+0;
$pthep=`grep parameter $param_filename | grep '\\she\\+\$' | awk '{print \$5}'`+0;
$ptnp=`grep parameter $param_filename | grep '\\sn\\+\$' | awk '{print \$5}'`+0;
$ptop=`grep parameter $param_filename | grep '\\so\\+\$' | awk '{print \$5}'`+0;
$ptn2p=`grep parameter $param_filename | grep '\\sn2\\+\$' | awk '{print \$5}'`+0;
$ptnop=`grep parameter $param_filename | grep '\\sno\\+\$' | awk '{print \$5}'`+0;
$pto2p=`grep parameter $param_filename | grep '\\so2\\+\$' | awk '{print \$5}'`+0;

print "Ion species positions: [$pthp] [$pthep] [$ptnp] [$ptop] [$ptn2p] [$ptnop] [$pto2p]\n";
$SAMI_varlist[0]="N_e";
$SAMI_varlist[$pthp]="N_H+";
$SAMI_varlist[$pthep]="N_He+";
$SAMI_varlist[$ptnp]="N_N+";
$SAMI_varlist[$ptop]="N_O+";
$SAMI_varlist[$ptnop]="N_NO+";
$SAMI_varlist[$ptn2p]="N_N2+";
$SAMI_varlist[$pto2p]="N_O2+";
$SAMI3_varlist="";
$SAMI3_unitlist="";
foreach $var (@SAMI_varlist){
        $SAMI3_varlist="$SAMI3_varlist $var";
	$SAMI3_unitlist="$SAMI3_unitlist 1/m^3";
}
print "$SAMI3_varlist\n";

# add velocities if the files are of nonzero length
@species=split (/\s+/,$SAMI3_varlist);
if (    ( (-s "denif1.dat") > 0 && (-s "vrf.dat") > 0 && (-s "vtf.dat") > 0 ) 
     || ( (-s "deniu1.dat") > 0 && (-s "vru.dat") > 0 && (-s "vtu.dat") > 0 ) ){
    for ($i=1;$i<=$#species;$i++){
	$s=substr($species[$i],2,length($species[$i])-2);
	$SAMI3_varlist="$SAMI3_varlist V_${s}_H V_${s}_Lat";
	$SAMI3_unitlist="$SAMI3_unitlist km/s km/s "
    }
}
# ditto for ion temperatures
if (    ( (-s "tif1.dat") > 0 ) 
     || ( (-s "tiu1.dat") > 0 ) ){
    for ($i=1;$i<=$#species;$i++){
	$s=substr($species[$i],2,length($species[$i])-2);
	$SAMI3_varlist="$SAMI3_varlist T_${s}";
	$SAMI3_unitlist="$SAMI3_unitlist K "
    }
}
# ditto for electron temperatures
if (    ( (-s "tef.dat") > 0 ) 
     || ( (-s "teu.dat") > 0 ) ){
    $SAMI3_varlist="$SAMI3_varlist T_e";
    $SAMI3_unitlist="$SAMI3_unitlist K "
}
print "$SAMI3_varlist\n";
#
# get information from input file
#
#$nt=get_parameter($param_filename,'parameter ( nt',5);
if ( -s "time.dat" ){
    $nt=`wc -l time.dat |awk '{print \$1}'`+0;
    if ($nt == 0){$nt=1;}
} else {
    $nt=get_parameter($param_filename,'parameter ( nt',5);
    print "Grid NT: $nt\n";
}
print "Number of timesteps: $nt\n";


if (index($param_filename,"f90") < 0){
    # old namelist file for model version 1.x
    $nion=get_parameter($param_filename,'parameter ( nion',5);
    print "NION: $nion\n";

    $nf=get_parameter($param_filename,'parameter ( nf',5)+0;
    $nz=get_parameter($param_filename,'parameter ( nz',5);
    $nlon=96;
    #nl is the number of layers in longitude (parallelization)
    $nlon=get_parameter($param_filename,'parameter ( nlt ',5);
    # patch to perform calculation for nlon from numwork and nl
    if (index($nlon,"numwork") >=0){
	$numwork=get_parameter($param_filename,'parameter ( numwork ',5);
	$nl=get_parameter($param_filename,'parameter ( nl ',5);
	print "nlon: $nlon\n";
	print "numwork: $numwork\n";
	$nlon =~ s/numwork/$numwork/g;
	$nlon =~ s/nl/$nl/g;
	print "nlon: $nlon\n";
	$nlon=`echo "$nlon" | bc`+0;
    }
} else {
    # parse parameters_mod.f90 file
    $nion=get_parameter($param_filename,'parameter :: nion',5);

    $nf=get_parameter($param_filename,'parameter :: nf ',5);

    $nz=get_parameter($param_filename,'parameter :: nz',5);
    # nx or nlon is calculated from nl (block size) and numwork (number of processors running ITM model) parameters
    $nl=get_parameter($param_filename,'parameter ::  nl ',5);
    $numwork=get_parameter($param_filename,'parameter ::  numwork',5);
    print("NL: $nl numwork: $numwork\n");
    $nlon=($nl-2)*$numwork;
}
print "NION: $nion\n";
print "Grid NF: $nf\n";
print "Grid NZ: $nz\n";
print "Grid NLON: $nlon\n";
#exit;
# make local executable to generate TEC:

#$SAMI_SRC="/ccmcshare/MODELS_at_CCMC/SAMI3/sami3_mpi-1.00/";
$SAMI_SRC="/home/mchou1/sami3_TEC/";
$DIAG_INC_TEMPLATE="param_diag.inc_template";
$DIAG_INC_FILE="param_diag.inc";
$DIAG_SOURCE="tec_nmf2_hmf2-3d-quad.f";
$DIAG_EXE="tec_nmf2_hmf2-3d-quad.x";
$INTERP_SOURCE="interp-3d-dene-d.f";
$INTERP_EXE="interp-3d-dene-d";
#system("cat $SAMI_SRC/$DIAG_INC_TEMPLATE | sed 's/NT/$nt/g' | sec 's/NL/$nlon/g' | sed 's/NF/$nf/g' | sed 's/NZ/$nz/g' > ./$DIAG_INC_FILE ; pgf90 -o $INTERP_EXE $SAMI_SRC/$INTERP_SOURCE; pgf90 -o $DIAG_EXE $SAMI_SRC/$DIAG_SOURCE");
system("cat $SAMI_SRC/$DIAG_INC_TEMPLATE | sed 's/NION/$nion/g' | sed 's/NT/$nt/g' | sed 's/NL/$nlon/g' | sed 's/NF/$nf/g' | sed 's/NZ/$nz/g' > ./$DIAG_INC_FILE ; cp -p $SAMI_SRC/$INTERP_SOURCE . ; gfortran -mcmodel=medium -o $INTERP_EXE $INTERP_SOURCE ; cp -p $SAMI_SRC/$DIAG_SOURCE . ; gfortran -mcmodel=medium -o $DIAG_EXE $DIAG_SOURCE");
system("cat param_diag.inc");

if ( -s $DIAG_EXE && -s $INTERP_EXE){
    system("./$INTERP_EXE");
    system("./$DIAG_EXE");
}

exit;

sub sec2ut {
    local($secofday)=@_;
# input: integer number of seconds
# return ut string for minutes entered
# format:  d:hh:mi:ss.sss
    $day=int($secofday/86400);
    $hour=int(($secofday % 86400)/3600);
    $min =int(($secofday % 3600)/60);
    $sec =($secofday % 60);
    @time_array=($hour, $min, $sec);
    $ut = sprintf "%02u:%02u:%02u", (@time_array);
    if ($day > 0){ $ut = "${day}:$ut";}
    return $ut;
}

sub get_parameter{
    local($debug)=1;
    local($m)=0;
    local($return_value)="";
    local($filename,$search_string,$return_index)=@_;
    if ($return_index eq "") {$return_index=1;} # default
    local (@parameter_lines)=`grep \"$search_string\" ${filename}`;
    if ($debug){
	print "grep -i \"$search_string\" $filename\n";
	print "Get_parameter: ${filename}|${search_string}|${return_index}\n";
	print "Get_parameter: $#parameter_lines\n";
    }
    foreach $m (0..$#parameter_lines) {
	local($parameter_line)=$parameter_lines[$m];
	print ("Parameter line: $parameter_line\n");
	local @parameter_array=split(/\s+/,$parameter_line);
	local $index_offset=$parameter_array[0] eq "";
	local $first_string = (split(/\s+/,$parameter_array[$index_offset]))[0];
        $return_value=$parameter_array[$return_index-1+$index_offset];
	if ($debug){
	    print "Return Value: $return_value\n";
	}
    }
# purge trailing ","
    if (index($return_value,',') > 0) {
	$return_value=substr($return_value,0,index($return_value,','));
    }
    return $return_value;
}


sub get_parameter_old{
    local($debug)=1;
    local($filename,$search_string,$return_index)=@_;
    if (return_index eq "") {$return_index=1;} # default
    local (@parameter_lines)=`grep \"$search_string\" ${filename}`;
    if ($debug){
	print "grep -i \"$search_string\" $filename\n";
	print "Get_parameter: ${filename}|${search_string}|${return_index}\n";
	print "Get_parameter: $#parameter_lines\n";
    }
    foreach $m (0..$#parameter_lines) {
	local($parameter_line)=$parameter_lines[$m];
        $parameter_line =~ s/nl -2/nl-2/g;
	@parameter_array=split(/\s+/,$parameter_line);
	$first_string = $parameter_array[0];
#
# return result when search string appears first in a line
#
	if ($debug){
	    print "Get Parameters: Array: $#parameter_array\n";
	    print "Get_parameter: |@{parameter_array}|${parameter_array[5]}|\n";
	    print "Get parameters: comparing \"$parameter_array[0]\" with \"${search_string}\"\n";
	}
	$return_value= $parameter_array[$return_index];
	if ($debug){
	    print "Return Value: $return_value\n";
	}
    }
# purge trailing ","
    if (index($return_value,',') > 0) {
	$return_value=substr($return_value,0,index($return_value,','));
    }
    return $return_value;
}


sub get_parameter{
    local($debug)=0;
    local($m)=0;
    local($return_value)="";
    local($filename,$search_string,$return_index)=@_;
    if ($return_index eq "") {$return_index=1;} # default
    local (@parameter_lines)=`grep \"$search_string\" ${filename}`;
    if ($debug){
	print "grep -i \"$search_string\" $filename\n";
	print "Get_parameter: ${filename}|${search_string}|${return_index}\n";
	print "Get_parameter: $#parameter_lines\n";
    }
    foreach $m (0..$#parameter_lines) {
	local($parameter_line)=$parameter_lines[$m];
	local @parameter_array=split(/\s+/,$parameter_line);
	# return_index assumed to be starting with 1 for first word in line
        # This will cover cases where the matching line starts with white space or not
	local $index_offset=$parameter_array[0] eq "";
	$return_value= $parameter_array[$return_index-1+$index_offset];
	if ($debug){
	    print "Return Value: $return_value\n";
	}
    }
# purge trailing ","
    if (index($return_value,',') > 0) {
	$return_value=substr($return_value,0,index($return_value,','));
    }
    return $return_value;
}


