mirror of
https://github.com/nasa/trick.git
synced 2024-12-22 22:42:26 +00:00
2fa76ce704
Removed all references to Data::Dumper. Only one module was even using the Data::Dumper. Fixes #30.
788 lines
27 KiB
Perl
Executable File
788 lines
27 KiB
Perl
Executable File
#!/usr/bin/env perl
|
||
|
||
#==============================================================================
|
||
#
|
||
# Name: start_sim
|
||
#
|
||
# Synopsis: start_sim -n <SIM_name> -i <RUN_directory_name>/<in_file>
|
||
#
|
||
# Description: Run any simulation from any path
|
||
#
|
||
# Assumptions: 1) Must be a Trick installed user
|
||
#
|
||
# Examples: start_sim SIM_cannon RUN_test
|
||
#
|
||
# Created By: Warwick Woodard, L-3 Communications 05/01/2008
|
||
#
|
||
#==============================================================================
|
||
|
||
use lib $ENV{"TRICK_HOME"} . "/bin/pm" ;
|
||
use gte ;
|
||
#use strict ;
|
||
require $ENV{"TRICK_HOME"} . "/bin/pm/XML/Parser.pm" ;
|
||
use XML::Simple ;
|
||
|
||
my @element_stack;
|
||
my $record_index;
|
||
my $fh;
|
||
my $DATA_PATH;
|
||
my $INCLUDE_PATH;
|
||
|
||
|
||
my $usage="
|
||
Name:
|
||
start_sim - run any simulation from any path
|
||
|
||
Additional options from S_main_<host_cpu>.exe (above)
|
||
are also available for use with start_sim.
|
||
|
||
Options specific to start_sim command:
|
||
(Note: start_sim can run without options)
|
||
-s, -sim, -name <SIM_name>
|
||
name of trick directory system that holds the simulation
|
||
-i, -input <input_file>
|
||
simulation input file to use
|
||
-nexiom, -nexcsims <XML_input_file>
|
||
parse a NExIOM input file and generate a nexcsims.d data file,
|
||
then auto load nexcsims.d after standard input file is read
|
||
-user_home, -u <USER_HOME_path>
|
||
overwrite default value for the location of sims (full path)
|
||
-freq <#.##>
|
||
overwrite data recording cycle time (>= 0.01 sec)
|
||
-ddd, -debug
|
||
start simulation using the data display debugger (DDD)
|
||
-gdb
|
||
start simulation using the GNU debugger
|
||
-echo
|
||
send start_sim script print statements to terminal
|
||
-h, -help, --help
|
||
display this help and exit
|
||
|
||
Usage:
|
||
start_sim [-s <SIM_name>] [-i <input_file>] [option(s)...]
|
||
|
||
Examples:
|
||
% start_sim -s SIM_cannon -i RUN_grav/input
|
||
% start_sim
|
||
% start_sim -O \$HOME/my_log_files/
|
||
% start_sim -nexiom nexiom_input.xml
|
||
" ;
|
||
|
||
|
||
# Local Variables
|
||
my $name=""; # Name of Trick directory system that holds simulation
|
||
my $input=""; # Simulation Input File
|
||
my $use_input=1; # Input file required for S_MAIN_*.exe
|
||
my $nexiom_format=0; # Input file is in XML format, create XML output
|
||
my $nexiom_input=""; # Filename of the nexiom input parameters (XML format)
|
||
my $nexiom_output=""; # Filename of the nexiom output (Datatable format)
|
||
my $freq=0.0; # Overwrite data recording rate (>= 0.01 sec)
|
||
my $user_home=""; # Overwrite default location of $TRICK_USER_HOME
|
||
my $echo_ON=0; # Print the generated start command to screen
|
||
my $help=0; # Print usage text to screen
|
||
my $DDD=0; # Start simulation in ddd Flag
|
||
my $GDB=0; # Start simulation in gdb Flag
|
||
my $options=""; # Additional options to pass along to S_MAIN_*.exe
|
||
my $default_host_cpu="Linux_3.4_234_x86_64";# Given in case TRICK_HOST_CPU is undef
|
||
|
||
|
||
my $kernel_name;
|
||
open $fh, "uname -s |";
|
||
{
|
||
local $/;
|
||
$kernel_name = trim(<$fh>); # remove whitespace
|
||
}
|
||
close $fh;
|
||
my $redirect="";
|
||
if ( substr($kernel_name,0,4) eq "IRIX" ) {
|
||
$redirect=" > /dev/null "; # Redirect outputs away from the screen
|
||
}
|
||
|
||
|
||
# IMPORTANT: Do not create options that could be used by S_MAIN.exe
|
||
while ( @ARGV > 0 ) {
|
||
my $argc = $ARGV[0]; # Copy current argument
|
||
my $argc2 = $ARGV[1];
|
||
|
||
if (( $argc eq "-name" ) ||
|
||
( $argc eq "-sim" ) ||
|
||
( $argc eq "-s" )) {
|
||
shift; $name=$argc2;
|
||
} elsif (( $argc eq "-input" ) ||
|
||
( $argc eq "-i" ) ||
|
||
( $argc eq "-run" )) {
|
||
shift; $input=$argc2;
|
||
} elsif (( $argc eq "-frequency" ) ||
|
||
( $argc eq "-freq" ) ||
|
||
( $argc eq "-f" )) {
|
||
shift; $freq=$argc2;
|
||
} elsif (( $argc eq "-user_home" ) ||
|
||
( $argc eq "-user" ) ||
|
||
( $argc eq "-u" )) {
|
||
shift; $user_home=$argc2;
|
||
} elsif (( $argc eq "-debug" ) ||
|
||
( $argc eq "-ddd" )) {
|
||
$DDD=1;
|
||
} elsif (( $argc eq "-gdb" )) {
|
||
$GDB=1;
|
||
} elsif (( $argc eq "-echo" ) ||
|
||
( $argc eq "-print" )) {
|
||
$echo_ON=1;
|
||
} elsif (( $argc eq "-help" ) ||
|
||
( $argc eq "-h" ) ||
|
||
( $argc eq "help" ) ||
|
||
( $argc eq "-x" )) {
|
||
$help=1;
|
||
$options = $options." -help";
|
||
} elsif (( $argc eq "-nexiom" ) ||
|
||
( $argc eq "-nexcsims" )) {
|
||
$nexiom_format=1;
|
||
shift;
|
||
$nexiom_input=$argc2;
|
||
} else {
|
||
if (( $argc eq "sie" ) ||
|
||
( $argc eq "trick_version" ) ||
|
||
( $argc eq "-V" ) ||
|
||
( $argc eq "--version" )) {
|
||
# Don't run sim; generate files or print info to screen.
|
||
$use_input = 0;
|
||
# Save option.
|
||
$options = $options." ".$argc;
|
||
} elsif ( substr($argc,0,1) eq "-" ) {
|
||
# Add two backslashes to support Debug argument parsing.
|
||
# Otherwise some arguments are saved as internal ddd/gdb
|
||
# commands and not passed along to S_MAIN.exe
|
||
$options = $options." ".$argc."\\\\";
|
||
} else {
|
||
# Leave argument as is and append to previous option(s).
|
||
$options = $options." ".$argc;
|
||
}
|
||
}
|
||
|
||
shift;
|
||
}
|
||
|
||
|
||
# Executable name is a product of host_cpu description.
|
||
my $S_MAIN_EXE;
|
||
if ( defined($ENV{"TRICK_HOST_CPU"}) ) {
|
||
# Set "S_MAIN_EXE" equal to "S_main_" + the environment variable TRICK_HOST_CPU
|
||
$S_MAIN_EXE = "S_main_".$ENV{"TRICK_HOST_CPU"} .".exe"; # concatenate strings
|
||
} else {
|
||
# If TRICK_HOST_CPU is undef, then "S_MAIN_EXE" is equal to "S_main_" plus
|
||
# local variable default_host_cpu (set above).
|
||
$S_MAIN_EXE = "S_main_".$default_host_cpu .".exe"; # concatenate strings
|
||
}
|
||
if ( $echo_ON == 1 ) {
|
||
print "debug: setting S_MAIN_EXE equal to \"$S_MAIN_EXE\"\n";
|
||
}
|
||
|
||
|
||
# If $user_home is not null, copy value
|
||
if ( $user_home ne "" ) {
|
||
# If $user_home input is not null, test if path exists
|
||
if ( ! -d $user_home ) {
|
||
# An invalid sim path was provided; clear variable
|
||
$user_home="";
|
||
}
|
||
}
|
||
|
||
my $userid;
|
||
open $fh, "whoami |";
|
||
{
|
||
local $/;
|
||
$userid = trim(<$fh>); # remove whitespace
|
||
}
|
||
close $fh;
|
||
|
||
|
||
my $trick_sims;
|
||
if ( $user_home ne "" ) {
|
||
# Set "trick_sims" equal to the variable $user_home.
|
||
$trick_sims = $user_home;
|
||
} elsif ( defined($ENV{"TRICK_USER_HOME"}) ) {
|
||
# If $user_home not set, set "trick_sims" equal to the env var TRICK_USER_HOME.
|
||
$trick_sims = $ENV{"TRICK_USER_HOME"};
|
||
} elsif ( defined($ENV{"HOME"}) ) {
|
||
# If TRICK_USER_HOME is undef, then set "trick_sims" equal to $HOME/trick_sims.
|
||
$trick_sims = $ENV{"HOME"}."/trick_sims"; # concatenate strings
|
||
} else {
|
||
# If HOME is undefined then default "trick_sims" to /users/<userid>/trick_sims.
|
||
$trick_sims = "/users/".$userid."/trick_sims"; # concatenate strings
|
||
}
|
||
if ( $echo_ON == 1 ) {
|
||
print "debug: setting trick_sims equal to \"$trick_sims\"\n";
|
||
}
|
||
|
||
|
||
my $pwd_;
|
||
if ( defined($ENV{"PWD"}) ) {
|
||
# Set "pwd_" equal to the envirnment variable PWD.
|
||
$pwd_ = $ENV{"PWD"};
|
||
} elsif ( defined($ENV{"cwd"}) ) {
|
||
# If PWD is undef, then set "pwd_" equal to the envirnment variable cwd.
|
||
$pwd_ = $ENV{"cwd"};
|
||
} else {
|
||
# If cwd is undefined, then execute `pwd`.
|
||
open $fh, "pwd |";
|
||
{
|
||
local $/;
|
||
$pwd_ = trim(<$fh>); # remove whitespace
|
||
}
|
||
close $fh;
|
||
}
|
||
|
||
|
||
# which Simulation to use
|
||
# Possible Scenarios:
|
||
# 1. SIM_name was provided by user
|
||
# 2. SIM_name was not entered but current path is within a simulation directory
|
||
# 3. SIM_name was not entered & current path is not within any simulation dir
|
||
my $sim_="SIM";
|
||
if ( $name ne "" ) {
|
||
# If $name is not null, copy value
|
||
$sim_ = $name;
|
||
if ( substr($name,0,1) eq "/" ) {
|
||
# If the full path of the simulation directory was entered,
|
||
# then separate into two parts
|
||
my $last_slash = rindex($name, "\/");
|
||
if ( -e substr($name,0,$last_slash) ) {
|
||
# if path exists, copy all chars prior to the last forward slash
|
||
$trick_sims = substr($name,0,$last_slash);
|
||
}
|
||
$sim_=substr($name,($last_slash+1)); # copy all chars after the last forward slash
|
||
}
|
||
} elsif ( ($nexiom_format == 1) && ($nexiom_input ne "") ) {
|
||
# If $nexiom_input is not null, parse file
|
||
$sim_ = process_nexiom_input( $nexiom_input, "name");
|
||
if ( substr($sim_,0,1) eq "/" ) {
|
||
# If the full path of the simulation directory was entered,
|
||
# then separate into two parts
|
||
my $last_slash = rindex($sim_, "\/");
|
||
if ( -e substr($sim_,0,$last_slash) ) {
|
||
# if path exists, copy all chars prior to the last forward slash
|
||
$trick_sims = substr($sim_,0,$last_slash);
|
||
}
|
||
$sim_=substr($sim_,($last_slash+1)); # copy all chars after the last forward slash
|
||
}
|
||
} else {
|
||
# $name is null, search the current path to determine if
|
||
# this script was executed within a simulation directory.
|
||
# If not, default to the simulation directory with the
|
||
# most recent time stamp.
|
||
if ( `echo $pwd_ | grep $sim_ $redirect` ) {
|
||
# Script was executed within a Trick simulation directory
|
||
my $last_slash = rindex($pwd_, $sim_) - 1;
|
||
$trick_sims = substr($pwd_,0,$last_slash); # Copy section of path PRIOR to SIM_name
|
||
$sim_=substr($pwd_,($last_slash+1)); # Copy section of path AFTER trick_sims
|
||
# Copy portion of SIM_name PRIOR to first slash (if any)
|
||
# This would imply that the path of execution was nested
|
||
# down past the simulation directory path
|
||
if ( index($sim_, "\/") != -1 ) {
|
||
my $new_slash = index($sim_, "\/");
|
||
$sim_ = substr($sim_,0,$new_slash);
|
||
}
|
||
} else {
|
||
# Script was executed outside of a Trick simulation directory
|
||
# List, then sort (comma delimited) all SIM_names by mod time
|
||
open $fh, "ls -vtmBd ".$trick_sims."/".$sim_."* ".$redirect." |";
|
||
{
|
||
local $/;
|
||
$sim_ = trim(<$fh>); # remove whitespace
|
||
}
|
||
close $fh;
|
||
# Copy the single SIM_name PRIOR to the first comma (if any)
|
||
if ( index($sim_, ",") != -1 ) {
|
||
my $first_comma = index($sim_, ",");
|
||
$sim_ = substr($sim_,0,$first_comma);
|
||
}
|
||
# Results show full path;
|
||
# strip off everything up to and including the last slash
|
||
my $last_slash = rindex($sim_, "\/");
|
||
$sim_=substr($sim_,($last_slash+1)); # copy all chars after the last forward slash
|
||
}
|
||
}
|
||
my $NAME = $trick_sims."/".$sim_ ;
|
||
if ( $echo_ON == 1 ) {
|
||
print "debug: setting NAME equal to \"$NAME\"\n";
|
||
}
|
||
if ( ! -e $NAME ) {
|
||
print "\e[31mError:\e[00m SIM directory... \n\"$NAME\" \n...does not exists.\n";
|
||
if ( $nexiom_format == 1 ) {
|
||
print " Please overwrite NExIOM value by adding \"-s <SIM_name>\"\n";
|
||
print " (e.g. \"start_sim -nexiom <XML_input_file> -s <SIM_name>\" )\n";
|
||
}
|
||
print " \e[34mPlease set <SIM_name> to one of the following:\e[00m\n";
|
||
system("ls -vtmBd ".$trick_sims."/*SIM*");
|
||
print "Type \"start_sim -help\" for more info.\n";
|
||
exit
|
||
}
|
||
|
||
|
||
# where to find S_default.dat
|
||
$DATA_PATH=$NAME;
|
||
|
||
# where to look for input file's #includes
|
||
$INCLUDE_PATH=$NAME;
|
||
|
||
|
||
# Which input file to use
|
||
# Possible Scenarios:
|
||
# 1. input_file was provided by user
|
||
# 2. input_file was not entered, but current path is within a RUN directory
|
||
# 3. input_file was not entered & current path is not within any RUN dir
|
||
my $run_ = "RUN";
|
||
my $in_ = "input";
|
||
if ( $input ne "" ) {
|
||
# If $input is not null, copy value
|
||
if ( `echo $input | grep "\/" $redirect ` ) {
|
||
# A run directory AND input file name was provided
|
||
my $last_slash = rindex($input, "\/");
|
||
$run_ = substr($input,0,$last_slash); # Copy section of path PRIOR to $input's last slash
|
||
if ( rindex($run_, "\/") != -1 ) {
|
||
my $new_slash = rindex($run_, "\/");
|
||
$run_=substr($run_,($new_slash+1)); # Copy section of path AFTER $run_'s last slash
|
||
}
|
||
$in_=substr($input,($last_slash+1)); # Copy section of path AFTER $input's last slash
|
||
} else {
|
||
# A path was not provided, but an input file name was.
|
||
$in_ = $input;
|
||
if ( -e $input ) {
|
||
# Assume that this script is being executed in the desired RUN dir.
|
||
my $last_slash = rindex($pwd_, "\/");
|
||
$run_=substr($pwd_,($last_slash+1)); # Copy section of path AFTER $pwd_'s last slash
|
||
} else {
|
||
# The input file does not exist in current working directory.
|
||
# Search for it in the RUN directories with recent time stamps.
|
||
# List, then sort (comma delimited) all RUN_names by mod time
|
||
open $fh, "ls -vtmBd ".$NAME."/".$run_."* ".$redirect." |";
|
||
{
|
||
local $/;
|
||
$run_ = trim(<$fh>); # remove whitespace
|
||
}
|
||
close $fh;
|
||
# Copy the single RUN_name PRIOR to the first comma (if any)
|
||
if ( index($run_, ",") != -1 ) {
|
||
my $first_comma = index($run_, ",");
|
||
$run_ = substr($run_,0,$first_comma);
|
||
}
|
||
# Results show full path; strip off everything from first to last slash
|
||
my $last_slash = rindex($run_, "\/");
|
||
$run_=substr($run_,($last_slash+1)); # copy all chars after the last forward slash
|
||
}
|
||
}
|
||
} else {
|
||
if ( `echo $pwd_ | grep $run_ $redirect ` ) {
|
||
my $name_slash = rindex($pwd_, $sim_); # Find string index where simulation's name begins
|
||
my $next_slash = index($pwd_, "\/", $name_slash); # Find string index where simulation's name ends
|
||
$run_=substr($pwd_,($next_slash+1)); # Copy section of path AFTER $NAME
|
||
# Copy portion of results PRIOR to first slash (if any)
|
||
# This would imply that the path of execution was nested
|
||
# down past the RUN directory path
|
||
if ( index($run_, "\/") != -1 ) {
|
||
my $new_slash = index($run_, "\/");
|
||
$run_ = substr($run_,0,$new_slash);
|
||
}
|
||
} else {
|
||
# Script was executed outside of a RUN directory
|
||
# List, then sort (comma delimited) all RUN_names by mod time
|
||
open $fh, "ls -vtmBd ".$NAME."/".$run_."* ".$redirect." |";
|
||
{
|
||
local $/;
|
||
$run_ = trim(<$fh>); # remove whitespace
|
||
}
|
||
close $fh;
|
||
# Copy the single RUN_name PRIOR to the first comma (if any)
|
||
if ( index($run_, ",") != -1 ) {
|
||
my $first_comma = index($run_, ",");
|
||
$run_ = substr($run_,0,$first_comma);
|
||
}
|
||
# Results show full path; strip off everything from first to last slash
|
||
my $last_slash = rindex($run_, "\/");
|
||
$run_=substr($run_,($last_slash+1)); # copy all chars after the last forward slash
|
||
}
|
||
}
|
||
|
||
my $INPUT="";
|
||
if ( $use_input == 0 ) {
|
||
# Execute S_MAIN_*.exe without an input file (e.g. sie, --version, etc.)
|
||
} else {
|
||
$INPUT=$NAME."/".$run_."/".$in_;
|
||
}
|
||
if ( $echo_ON == 1 ) {
|
||
print "debug: setting INPUT equal to \"$INPUT\"\n";
|
||
}
|
||
if ( (! -e $INPUT) && ($use_input!=0) ) {
|
||
print "\e[31mError:\e[00m Input file... \n\"$INPUT\" \n...is not a valid file name.\n";
|
||
if ( $nexiom_format == 1 ) {
|
||
print " Please overwrite NExIOM value by adding \"-i <input_file>\"\n";
|
||
}
|
||
printf " \e[34mPlease set <input_file> to a valid input file name\e[00m\n";
|
||
printf " \e[34mfrom one of the following directories:\e[00m\n";
|
||
system("ls -vtmBd ".$NAME."/RUN*");
|
||
print "Type \"start_sim -help\" for more info.\n";
|
||
exit;
|
||
}
|
||
|
||
|
||
my $CMD = $NAME."/".$S_MAIN_EXE." ".$INPUT." ".$options ;
|
||
if ( ! -e $NAME."/".$S_MAIN_EXE ) {
|
||
print "\n" ;
|
||
print "\e[31mError: \"$S_MAIN_EXE\" does not exist.\e[00m\n";
|
||
print " \e[33mThe executable that you were expecting may not have \e[00m\n";
|
||
print " \e[33mbeen created yet, or maybe was created on a different \e[00m\n";
|
||
print " \e[33mplatform and will not run on this one.[00m\n";
|
||
print "File(s) Found:\n";
|
||
print "\e[34m";
|
||
system("ls -apv S_main_*");
|
||
print "\e[00m";
|
||
print "Try running CP, then start_sim again.\n\n";
|
||
exit;
|
||
} else {
|
||
if ( $help == 1 ) {
|
||
# First print help info from S_main_*.exe. Defined in file:
|
||
# $TRICK_HOME/trick_source/sim_services/exec/process_sim_args.c
|
||
system($NAME."/".$S_MAIN_EXE." ".$options);
|
||
# Now append start_sim specific help info.
|
||
print "$usage\n";
|
||
exit;
|
||
} else {
|
||
if ( $nexiom_format == 1 ) {
|
||
$nexiom_output = process_nexiom_input( $nexiom_input );
|
||
# strip off everything up to and including the last slash
|
||
my $last_slash = rindex($nexiom_output, "\/");
|
||
$nexiom_output = substr($nexiom_output,($last_slash+1));
|
||
if ( $echo_ON == 1 ) {
|
||
#print "setting NExIOM output file to \"$nexiom_output\"\n";
|
||
}
|
||
#$CMD = $CMD." -auto -nexiom ".$nexiom_output;
|
||
$CMD = $CMD." -auto -nexiom ";
|
||
}
|
||
if ( $DDD == 1 ) {
|
||
# Prepend command with ddd
|
||
$CMD = "ddd --args ".$CMD;
|
||
} elsif ( $GDB == 1 ) {
|
||
# Prepend command with gdb
|
||
$CMD = "gdb --args ".$CMD;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
# START THE SIM!!!
|
||
if ( $echo_ON == 1 ) {
|
||
print "starting the simulation:\n";
|
||
print " \"$CMD\"\n\n";
|
||
}
|
||
system("cd ".$NAME."; ".$CMD);
|
||
|
||
|
||
|
||
|
||
#######################################################################
|
||
######################## DECLARE SUBROUTINES ########################
|
||
#######################################################################
|
||
sub process_nexiom_input {
|
||
|
||
# PARSE NExIOM INPUT FILE
|
||
my ($infile, $tag) ;
|
||
my ($value, $outfile) ;
|
||
|
||
# If two arguments received (input_filename, XML tag)
|
||
if ( $_[1] ) {
|
||
# save input_filename and XML tag strings
|
||
($infile, $tag) = handle_nexiom_args($_[0], $_[1]) ;
|
||
|
||
# One argument received (input_filename)
|
||
} else {
|
||
# save input_filename; XML tag is null
|
||
($infile, $tag) = handle_nexiom_args($_[0], 0) ;
|
||
}
|
||
|
||
# If an XML tag was provided
|
||
if ( $tag ) {
|
||
# Save the value of the first occurrence of this XML tag.
|
||
$value = get_tag_val($infile, $tag) ;
|
||
# This value is most commonly used as the NExIOM default SIM directory name.
|
||
return $value;
|
||
|
||
# No XML tag provided
|
||
} else {
|
||
# Translate input file to "nexcsims.d"
|
||
$outfile=generate_data_files($infile) ;
|
||
return $outfile;
|
||
}
|
||
|
||
}
|
||
|
||
sub handle_nexiom_args($$) {
|
||
|
||
my ( $infile, $tag ) ;
|
||
|
||
$infile = $_[0] ;
|
||
$tag = $_[1] ;
|
||
|
||
# Exit script if input_file does not exist
|
||
if ( ! -e $infile ) {
|
||
print "ERROR: Can't find NExIOM input file \"$infile\" \n" ;
|
||
print "File does not exist: $infile \n" ;
|
||
exit
|
||
}
|
||
|
||
return $infile, $tag ;
|
||
}
|
||
|
||
sub get_tag_val($$) {
|
||
|
||
my ( $file ) = $_[0] ;
|
||
my ( $tag ) = $_[1] ;
|
||
my $value ;
|
||
|
||
# Parse XML contents to hashref, $data
|
||
my $data = XML::Simple::XMLin($file) ;
|
||
# Find first occurrence of XML tag (i.e. <foo="bar">)
|
||
if ( ! ($value = $data->{$tag}) ) {
|
||
# Couldn't find this XML tag, so clear $value
|
||
$value = "" ;
|
||
}
|
||
|
||
return $value ;
|
||
}
|
||
|
||
sub generate_data_files($) {
|
||
|
||
my ( $file ) = $_[0] ;
|
||
my $results;
|
||
my $record_name;
|
||
$record_index = 0; # counter for the number of vars to data record
|
||
|
||
# Save the value of the first occurrence of this XML tag.
|
||
if ( ! ($results = get_tag_val($file,"results")) ) {
|
||
# Couldn't find this XML tag, so provide default value
|
||
$results = "nexiom_output.xml" ;
|
||
}
|
||
# strip off everything up to and including the last slash
|
||
my $last_slash = rindex($results, "\/");
|
||
$record_name=substr($results,($last_slash+1)); # copy all chars after the last forward slash
|
||
|
||
# create/overwrite nexcsims.d data file
|
||
open (FILE, ">".$DATA_PATH."/Modified_data/nexcsims.d");
|
||
close FILE;
|
||
|
||
# create/overwrite nexcsims.dr recording file
|
||
open (DR_FILE, ">".$DATA_PATH."/Modified_data/nexcsims.dr");
|
||
# Insert header declarations
|
||
print DR_FILE "#ifndef DR_GROUP_ID\n";
|
||
print DR_FILE " #define DR_GROUP_ID sys.exec.record.num_group\n";
|
||
print DR_FILE "#else\n";
|
||
print DR_FILE " DR_GROUP_ID -- ;\n";
|
||
print DR_FILE "#endif\n\n";
|
||
print DR_FILE "sys.exec.record.group[DR_GROUP_ID].name = \"$record_name\" ;\n";
|
||
if ( $freq > 0.0 ) {
|
||
print DR_FILE "sys.exec.record.group[DR_GROUP_ID].cycle = $freq ;\n";
|
||
}
|
||
print DR_FILE "sys.exec.record.group[DR_GROUP_ID].record = Yes ;\n";
|
||
print DR_FILE "sys.exec.record.group[DR_GROUP_ID].format = DR_Binary ;\n";
|
||
close DR_FILE;
|
||
|
||
# Create a new XML::Parser object, $parser
|
||
my $parser = XML::Parser->new(
|
||
Handlers => {
|
||
# 'Start' handler - references the start subroutine (hand-written below)
|
||
Start=>\&start,
|
||
# 'End' handler - reference the end subroutine (hand-written below)
|
||
End=>\&end,
|
||
}
|
||
);
|
||
$parser->parsefile($file);
|
||
|
||
# Append footer to recording file
|
||
open (DR_FILE, ">>".$DATA_PATH."/Modified_data/nexcsims.dr");
|
||
print DR_FILE "\nDR_GROUP_ID ++ ;\n";
|
||
close DR_FILE;
|
||
|
||
return $results ;
|
||
}
|
||
|
||
sub start {
|
||
|
||
# Called by generate_data_files()
|
||
my ( $expat, $element, %attrval ) = @_;
|
||
|
||
my ( $i, $j, $k );
|
||
my $dimension_counter = 0;
|
||
my @array_of_arrays = ();
|
||
my $pos = 1;
|
||
|
||
# Search for <InputParameters> tag to build an input data file
|
||
if ( $element eq "Parameter" and $element_stack[ -1 ] eq "InputParameters" ) {
|
||
|
||
# Append variables to data file
|
||
open (FILE, ">>".$DATA_PATH."/Modified_data/nexcsims.d");
|
||
|
||
# Translate the NExIOM variable name to a local variable name
|
||
my ($in_variable, @arrays) = find_sim_var( $attrval{name}, "in" ) ;
|
||
# Determine if var is scalar, single dimension array, double (matrix), etc
|
||
# If @arrays list is empty, then this variable is scalar
|
||
$dimension_counter = @arrays;
|
||
|
||
for ( $i = 0; $i < $dimension_counter; $i++ ) {
|
||
push @array_of_arrays, [1..$arrays[$i]];
|
||
}
|
||
|
||
$pos = 1; # default array size
|
||
my $iter = make_permutation(@array_of_arrays);
|
||
while (my @elements = $iter->() ){
|
||
print FILE "$in_variable";
|
||
if ($dimension_counter >= 1) {
|
||
foreach (@elements) {
|
||
$pos = $_ - 1; # decrease array position by 1 for C code
|
||
print FILE "[$pos]"; # append array index to variable
|
||
}
|
||
}
|
||
if( exists $attrval{units} ) {
|
||
# Identify what units this parameter's value will be given in
|
||
print FILE " \{$attrval{units}\}";
|
||
}
|
||
# Retrieve the value being assigned to this parameter
|
||
print FILE " = $attrval{value};\n";
|
||
}
|
||
|
||
close FILE;
|
||
|
||
# Search for <OutputParameters> tag to build a data recording file
|
||
} elsif ( $element eq "Parameter" and $element_stack[ -1 ] eq "OutputParameters" ) {
|
||
|
||
# Append variables to recording file
|
||
open (DR_FILE, ">>".$DATA_PATH."/Modified_data/nexcsims.dr");
|
||
|
||
# Translate the NExIOM variable name to a local variable name
|
||
my ($out_variable, @arrays) = find_sim_var( $attrval{name}, "out" ) ;
|
||
# Determine if var is scalar, single dimension array, double (matrix), etc
|
||
# If @arrays list is empty, then this variable is scalar
|
||
$dimension_counter = @arrays;
|
||
|
||
for ( $i = 0; $i < $dimension_counter; $i++ ) {
|
||
# Create an array of integers from 1 to n,
|
||
# then populate that array into an array list.
|
||
|
||
# Example: given a multi-dimensional array that is of size 2 x 10 x ?,
|
||
# produce this array list => ([1..2], [1..10], [1..?], etc... )
|
||
|
||
push @array_of_arrays, [1..$arrays[$i]];
|
||
}
|
||
|
||
$pos = 1; # default array size
|
||
my $iter = make_permutation(@array_of_arrays);
|
||
while (my @elements = $iter->() ){
|
||
print DR_FILE "sys.exec.record.group[DR_GROUP_ID].ref".
|
||
"[$record_index] = \"$out_variable";
|
||
if ($dimension_counter >= 1) {
|
||
foreach (@elements) {
|
||
$pos = $_ - 1; # decrease array position by 1 for C code
|
||
print DR_FILE "[$pos]"; # append array index to variable
|
||
}
|
||
}
|
||
# End string with closed quote, semi-colon & newline
|
||
print DR_FILE "\" ;\n"; # write to data recording file
|
||
$record_index++;
|
||
}
|
||
|
||
close DR_FILE;
|
||
}
|
||
|
||
push @element_stack, $element;
|
||
}
|
||
|
||
sub end {
|
||
|
||
my ( $expat, $element ) = @_;
|
||
|
||
pop @element_stack;
|
||
}
|
||
|
||
sub find_sim_var {
|
||
|
||
# Use a mappping file to find which simulation variable
|
||
# is equivalent to this nexiom input variable name.
|
||
my $nexiom_variable = my $new_variable = shift;
|
||
my $in_out = shift;
|
||
my ($from, $to, @slots);
|
||
|
||
if ((defined $in_out) && ($in_out eq "out")) {
|
||
open (MAP_FILE, $INCLUDE_PATH."/nexiom_output.map");
|
||
} else {
|
||
open (MAP_FILE, $INCLUDE_PATH."/nexiom_input.map");
|
||
}
|
||
|
||
while (<MAP_FILE>) {
|
||
chomp; # read file until another newline character is found
|
||
|
||
# Copy values (assume data is comma delimited)
|
||
($from, $to, @slots) = split(",");
|
||
$from = trim($from); # remove whitespace
|
||
$to = trim($to); # remove whitespace
|
||
# Values in the output mapping file are opposite/backwards
|
||
if ((defined $in_out) && ($in_out eq "out")) {
|
||
# Swap from & to values
|
||
($from, $to) = ($to, $from);
|
||
}
|
||
foreach (@slots) {
|
||
$_ = int(trim($_)); # save array demensions (if any)
|
||
}
|
||
|
||
# Search for the nexiom variable name
|
||
if( $nexiom_variable eq $from ) {
|
||
# Cross mapping found. Rename to local simulation name.
|
||
$new_variable = $to ;
|
||
last; # break out of loop
|
||
} elsif( $nexiom_variable eq $to ) {
|
||
# No cross mapping needed. Leave variable name as is.
|
||
$new_variable = $nexiom_variable ;
|
||
last; # break out of loop
|
||
} else {
|
||
# clear tmp values prior to parsing next line of MAP_FILE
|
||
($from, $to, $#slots) = ( "", "", -1);
|
||
}
|
||
}
|
||
|
||
close (MAP_FILE);
|
||
|
||
my @found_it = ($new_variable, @slots) ;
|
||
return @found_it ;
|
||
}
|
||
|
||
sub make_permutation{
|
||
my @refs = @_;
|
||
my @arrayindexes = ();
|
||
foreach (@refs){
|
||
push @arrayindexes,[$_,0,$#{$_}];
|
||
}
|
||
|
||
return sub {
|
||
return if $arrayindexes[0]->[1] > $arrayindexes[0]->[2];
|
||
my @elements = map { $_->[0]->[ $_->[1]] } @arrayindexes;
|
||
# Check for out of bounds....
|
||
$arrayindexes[$#arrayindexes]->[1]++;
|
||
for (my $i = $#arrayindexes; $i > 0; $i--) {
|
||
if ($arrayindexes[$i]->[1] > $arrayindexes[$i]->[2]) {
|
||
$arrayindexes[$i]->[1] = 0;
|
||
$arrayindexes[$i-1]->[1]++;
|
||
} else {
|
||
last;
|
||
}
|
||
}
|
||
return @elements;
|
||
|
||
};
|
||
}
|
||
|
||
sub trim($)
|
||
{
|
||
# Remove whitespaces
|
||
my $string = $_[0];
|
||
$string =~ s/^\s+//;
|
||
$string =~ s/\s+$//;
|
||
return $string;
|
||
}
|