Class: CodeRunner::Run

Inherits:
Object show all
Includes:
Log
Defined in:
lib/coderunner/run.rb,
lib/coderunner/repository.rb,
lib/coderunner/fortran_namelist.rb,
lib/coderunner/fortran_namelist_c.rb,
lib/coderunner/heuristic_run_methods.rb

Overview

Every code module defines a custom child class of CodeRunner::Run. This class will also include a module which customizes it to work on the current system. The result is a class which knows how to run and analyses the results of the given code on the given system.

Every simulation that is carried out has an instance of this custom class created for it, and this object, known as a run, contains both the results and the input parameters pertaining to that simulation. All these runs are then stored in the variable run_list in a runner (an instance of the CodeRunner class). The result is that every run has a runner that it can talk to, and that runner has a set of runs that it can talk to.

Every run has its own directory, where all the input and output files from the simulation are stored. CodeRunner data for the run is stored in this folder in the files code_runner_info.rb and code_runner_results.rb.

As soon as the simulation is complete, CodeRunner call Run#process_directory to carry out any anlysis, and the results are stored in code_runner_results.rb. For speed CodeRunner also caches the data in the file .code_runner_run_data in binary format. This cache will be used after the initial analysis unless CodeRunner is specifically told to reanalyse this run.

All input parameters and results are available during run time as instance variables of the run class.

The class CodeRunner::Run itself defines a base set of methods which are added to by the code module.

Direct Known Subclasses

FortranNamelist

Defined Under Namespace

Classes: FortranNamelist, FortranNamelistC, Merged, NoRunnerError, RunClassPropertyFetcher, SubmitError

Constant Summary collapse

@@run_sys_name =
nil
@@successful_trial_system =
nil
@@successful_trial_class =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(runner) ⇒ Run

Create a new run. runner should be an instance of the class CodeRunner.

Raises:



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/coderunner/run.rb', line 164

def initialize(runner)
	logf('initialize')
# 	raise "runner must be either a CodeRunner or a RemoteCoderunner: it is a #{runner.class}" unless [CodeRunner, RemoteCodeRunner].include? runner.class
	@runner = runner
# 	raise CRFatal.new("Code not defined: #{CODE}") unless @@code and @@code.class == String and @@code =~ /\S/  
	@sys, @code = rcp.sys, rcp.code
	@naming_pars = rcp.naming_pars.dup
	raise CRFatal.new("@modlet not specified for #{self.class}") if rcp.modlet_required and not rcp.modlet
# 	@modlet = @@modlet; @modlet_location = @@modlet_location
# # 	@executable_location = executable_location
# 		@@necessary_run_variables.each{|v,clas| instance_eval("@#{v} = nil")}
		
# 		initialize_code_specific
	
# 	@script_folder  = @@script_folder
# 	@recalc_all = @@recalc_all
	@wall_mins = @runner.wall_mins if @runner
 	@smaxes = {}; @csmaxes = {}; @max_complete = {};
end

Instance Attribute Details

#codeObject

Returns the value of attribute code.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def code
  @code
end

#code_runner_versionObject

Returns the value of attribute code_runner_version.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def code_runner_version
  @code_runner_version
end

#executable_nameObject

aliold :_dump def _dump(*args) @runner, runner = nil, @runner ans = super(*args) @runner = runner return ans end



71
72
73
# File 'lib/coderunner/run.rb', line 71

def executable_name
  @executable_name
end

#max_completeObject

Returns the value of attribute max_complete.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def max_complete
  @max_complete
end

#maxesObject

Returns the value of attribute maxes.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def maxes
  @maxes
end

#naming_parsObject

Returns the value of attribute naming_pars.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def naming_pars
  @naming_pars
end

#nprocsObject

Returns the value of attribute nprocs.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def nprocs
  @nprocs
end

#real_idObject

Returns the value of attribute real_id.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def real_id
  @real_id
end

#run_test_flagsObject

Purely for testing purposes; see the test suite



75
76
77
# File 'lib/coderunner/run.rb', line 75

def run_test_flags
  @run_test_flags
end

#runnerObject

Returns the value of attribute runner.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def runner
  @runner
end

#sysObject

Returns the value of attribute sys.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def sys
  @sys
end

#versionObject

Returns the value of attribute version.



71
72
73
# File 'lib/coderunner/run.rb', line 71

def version
  @version
end

Class Method Details

.check_and_updateObject

ALL = [] READOUT_LIST = [] CODE = nil



811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
# File 'lib/coderunner/run.rb', line 811

def self.check_and_update
		Log.logf(:check_and_update)

# 	
		finish_setting_up_class
# 				ep self.to_s, constants, self.ancestors

# 		raise CRFatal.new("Code not defined (#{CODE.inspect}) in class #{self.to_s}") unless CODE and CODE.class == String and CODE =~ /\S/  


		NECESSARY_RUN_SYSTEM_METHODS.each do |method|
			raise CRFatal.new("#{method} not defined in #{SYS}_system_runner.rb") unless instance_methods.include?(method)
		end

		NECESSARY_RUN_CODE_METHODS.each do |method|
			raise CRFatal.new("#{method} not defined in #{self.class}_code_runner.rb") unless instance_methods.include?(method)
		end
	
		
		NECESSARY_RUN_CLASS_PROPERTIES.each do |v,class_list|
# 			raise CRFatal.new("#{v} not defined") unless rcp[v]
			raise CRFatal.new("#{v} not defined correctly: class is #{rcp[v].class} instead of one of #{class_list.to_s}") unless class_list.include? rcp[v].class
		end
		
		@readout_list = (rcp.variables+rcp.results) unless rcp.readout_list?

		raise "

Please add the line 

-----------------------------------------------------------
@code_module_folder = folder = File.dirname(File.expand_path(__FILE__)) # i.e. the directory this file is in
---------------------------------------------------------

to your code module.
		
		" unless rcp.code_module_folder?

# 		(variables+results).each{|v| const_get(:READOUT_LIST).push v} unless READOUT_LIST.size > 0

		#if rcp.variables_0_5_0
			#rcp.variables_0_5_0.dup.each do |par, info| #for backwards compatibility only
				#rcp.variables_0_5_0[par] = info[0] if info.class == Array
			#end
		#end





# 		Log.log(:@@variables0, @@variables[0])

		@run_info = rcp.run_info || [] # Run info can optionally be defined in the code module.
# 		ep @run_info
		@run_info = rcp.run_info + ([:preamble, :job_no, :running, :id, :status, :sys, :is_component, :naming_pars, :run_name, :resubmit_id, :real_id, :component_runs, :parameter_hash, :parameter_hash_string, :output_file, :error_file, :extra_files, :code_run_environment] + SUBMIT_OPTIONS) #.each{|v| RUN_INFO.push v} unless RUN_INFO.include? :job_no
		@all = (rcp.variables + rcp.results + rcp.run_info) #.each{|v| ALL.push v}
# 		ep "GOT HERE"
		(@all + [:directory, :run_name, :modlet, :relative_directory]).each{|var| send(:attr_accessor, var)}
		#eputs "Checking and updating"
    @user_defaults_location = ENV['HOME'] + "/.coderunner/#{rcp.code}crmod/defaults_files"
		#eputs ' user_defaults_location', rcp.user_defaults_location
		define_method(:output_file) do 
			return @output_file if @output_file
			@output_file = super()
		end
		define_method(:error_file) do 
			return @error_file if @error_file
			@error_file = super()
		end

		Dir.chdir(SCRIPT_FOLDER + "/system_modules") do 
		@system_run_classes ||= 	
			Dir.entries(Dir.pwd).find_all{|file| file =~ /^[^\.].+\.rb$/}.inject([]) do |arr, file|
				#p Dir.pwd
				#p 'required', file, Dir.pwd
				require Dir.pwd + '/' + file
# 				p CodeRunner.constants
				sys = file.sub(/\.rb$/, '')
				arr.push(add_a_child_class("#{sys.variable_to_class_name}Run"))
				arr[-1].send(:include, CodeRunner.const_get(sys.variable_to_class_name))
				arr
			end
		end

		
end

.defaults_location_listObject

A list of places where defaults files may be found



442
443
444
445
446
447
448
449
450
451
# File 'lib/coderunner/run.rb', line 442

def self.defaults_location_list
  locs = [rcp.user_defaults_location, rcp.code_module_folder + "/defaults_files"]
  if Repository.repo_folder
    repo = Repository.open_in_subfolder(Dir.pwd)
    folder = repo.dir.to_s + '/defaults_files/' + rcp.code + 'crmod/'
    FileUtils.makedirs folder
    locs.unshift folder
  end
  locs
end

.finish_setting_up_classObject

A hook for module developers



804
805
# File 'lib/coderunner/run.rb', line 804

def self.finish_setting_up_class
end

.getsObject



53
54
55
# File 'lib/coderunner/run.rb', line 53

def self.gets
	$stdin.gets
end

.load(dir, runner) ⇒ Object

Load the run object from the file .code_runner_run_data

Raises:



399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
# File 'lib/coderunner/run.rb', line 399

def self.load(dir, runner)
	raise CRFatal.new("runner supplied in Run.load was not an instance of code runner; runner.class = #{runner.class}") unless runner.class.to_s == "CodeRunner"
	begin
		raise CRMild.new("No saved run data") unless FileTest.exist? (dir+"/.code_runner_run_data")
		run = Marshal.load(File.read(dir+"/.code_runner_run_data"))
	rescue ArgumentError => err
		raise err unless err.message =~ /undefined class/
		#NB this means that all code_names have to contain only lowercase letters:
# 		code, modlet = err.message.scan(/CodeRunner\:\:([A-Z][a-z0-9]+)((?:[A-Z]\w+)+)?Run/)[0]
# 		code, modlet = err.message.scan(/CodeRunner\:\:([A-Z][a-z0-9_]+)(?:::([A-Z]\w+))?/)[0]
# 		ep code, modlet; exit
# 		code.gsub!(/([a-z0-9])([A-Z])/, '\1_\2')
# 		modlet.gsub!(/([a-z0-9])([A-Z])/, '\1_\2')
# 		ep err, modlet, code
# 		runner.setup_run_class(code.downcase, modlet: modlet.downcase)
# 		retry
		CodeRunner.repair_marshal_run_class_not_found_error(err)
		run = Marshal.load(File.read(dir+"/.code_runner_run_data"))		
	end
	run.runner = runner
	raise CRFatal.new("Something has gone horribly wrong: runner.class is #{run.runner.class} instead of CodeRunner") unless run.runner.class.to_s == "CodeRunner"
	run.directory = dir
	# For backwards compatibility with versions < 0.14
	run.instance_variable_set(:@component_run_list, run.instance_variable_get(:@phantom_run_list)) if run.instance_variable_get(:@phantom_run_list) 
	run.component_runs.each{|r| runner.add_component_run(r); r.runner = runner} if run.component_runs
	#@component_runs = []
	return run
end

.modify_job_script(runner, runs, script) ⇒ Object

A hook… default is to do nothing



1086
1087
1088
# File 'lib/coderunner/run.rb', line 1086

def self.modify_job_script(runner, runs, script)
	return script
end

.rcpObject

Access properties of the run class. These properties are stored as instance variables of the run class object. (Remember, in Ruby, every Class is an Object (and Object is a Class!)).

E.g. puts rcp.variables



152
153
154
# File 'lib/coderunner/run.rb', line 152

def self.rcp
	@rcp ||= RunClassPropertyFetcher.new(self)
end

.set_modlet(modlet, folder = nil) ⇒ Object



767
768
769
770
771
772
# File 'lib/coderunner/run.rb', line 767

def self.set_modlet(modlet, folder = nil)
	raise 'old method -- needs to be debugged'
	Log.log("self.set_modlet", self.to_s)
	class_eval(File.read("#{folder ? folder + "/" : ""}#{modlet}"))
	check_and_update
end

.update_status(runner) ⇒ Object

Use the instance method #queue_status (defined in the system module) to put a list of current jobs obtained from the system into the class variable @@current_status



39
40
41
42
43
44
45
46
47
# File 'lib/coderunner/run.rb', line 39

def self.update_status(runner)
	if runner.no_run
		@@current_status =  ""
	else
		#eputs 'Getting queue status...'
		@@current_status = new(runner).queue_status
	end
# 	puts @@current_status
end

Instance Method Details

#actual_number_of_processorsObject

Returns the number of nodes times the number of cores, assuming the processor layout is specified as either cores, nodesxcores, or nodesxcoresxthreads



1114
1115
1116
1117
# File 'lib/coderunner/run.rb', line 1114

def actual_number_of_processors
	  raise "Please specify the processor layout using the -n or (n:) option" unless @nprocs
		  @nprocs.split('x').slice(0..1).map{|n| n.to_i}.inject(1){|ntot, n| ntot*n}
end

#add_to_repoObject

Add CodeRunner files within the run folder to git. If the run_class for this run defines the run class property repo_file_match, also add any files which match any of



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/coderunner/repository.rb', line 10

def add_to_repo
  Dir.chdir(@directory) do
    repo = Repository.open_in_subfolder
    repo.add("code_runner_info.rb")
    repo.add("code_runner_results.rb")
    Dir.entries.each do |f|
      repo.add(f) if rcp.repo_file_match? and f =~ rcp.repo_file_match
    end
    repo.autocommit("Submitted simulation id #{id} in folder #{repo.relative_path(@runner.root_folder)}")
  end
end

#analyse_input_file_text(input_file_text) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/coderunner/heuristic_run_methods.rb', line 37

def analyse_input_file_text(input_file_text)
	logf(:analyse_input_file_text)
	pars = self.class.analyse_input_file_text(input_file_text, rcp.matching_regex)[0]
# 	log("These pars were found in the input file"); logi(pars)
 	logi(rcp.variables[rcp.variables.keys[0]])
	pars.each do |id, hash|
#  		puts hash.inspect
# 		puts @@variables[hash[:name].to_sym].inspect
		if rcp.variables[hash[:name].to_sym]
			set(hash[:name].to_sym, hash[:default].send(rcp.variables[hash[:name].to_sym]))
			# @@variables[hash[:name].to_sym] is the type conversion appropriate for the variable hash[:name]
		end
	end
end

#cacheObject

Access to a hash which is stored in the runner (not the run). The hash will persist while the runner is in the object space.

E.g. cache = something_to_store



82
83
84
85
86
# File 'lib/coderunner/run.rb', line 82

def cache
	@runner.cache[:runs] ||= {} 
	@runner.cache[:runs][@id] ||= {} 
	@runner.cache[:runs][@id]
end

#clear_cacheObject

Empty the cache for this run



89
90
91
92
# File 'lib/coderunner/run.rb', line 89

def clear_cache
	@runner.cache[:runs] ||= {} 
	@runner.cache[:runs][@id] = {} 
end

#code_run_environmentObject

A hook… a string which gets put into the job script. Used to load modules, configure the run time environment for a given code. Default is to return an empty string.



1095
1096
1097
# File 'lib/coderunner/run.rb', line 1095

def code_run_environment
	@code_run_environment
end

#comment_lineObject

Used for the status with comments command.



373
374
375
376
# File 'lib/coderunner/run.rb', line 373

def comment_line
	"#{id}: #{@comment}"
	sprintf("%2d:%d %1s:%2.1f(%s) %3s%1s %s",  @id, @job_no, @status.to_s[0,1],  @run_time.to_f / 60.0, @nprocs.to_s, percent_complete, "%", @comment)
end

#commit_resultsObject



21
22
23
24
25
26
27
28
29
30
# File 'lib/coderunner/repository.rb', line 21

def commit_results
  Dir.chdir(@directory) do
    repo = Repository.open_in_subfolder
    repo.add("code_runner_results.rb")
    Dir.entries.each do |f|
      repo.add(f) if rcp.repo_file_match? and f =~ rcp.repo_file_match
    end
    repo.autocommit("Updated results for id #{id} in folder #{repo.relative_path(@runner.root_folder)}") if repo.changed_in_folder(@directory).size > 0
  end
end

#copy_extra_filesObject

This function copies any files which are required at run time into the run folder. It takes the form of an input parameter ‘extra_files’ which takes in an array of file locations and copies them when the run folder is set up. It is called in prepare_submission.



708
709
710
711
712
713
714
715
716
# File 'lib/coderunner/run.rb', line 708

def copy_extra_files
  if @extra_files.kind_of?String
    @extra_files = [@extra_files]
  end
  if @extra_files.kind_of?Array
    @extra_files.each{|file| 
    FileUtils.cp(file, File.basename(file))}
  end
end

#create_componentObject



902
903
904
905
906
907
908
909
910
# File 'lib/coderunner/run.rb', line 902

def create_component
	@component_runs ||= []
	new_run = dup
	new_run.is_component = true
	new_run.real_id = @id
	@runner.add_component_run(new_run)
	@component_runs.push new_run
	new_run
end

#data_stringObject

Return a line of data for printing to file in CodeRunner#readout, organised according to the run class property rcp.readout_list



367
368
369
# File 'lib/coderunner/run.rb', line 367

def data_string
	rcp.readout_list.inject(""){|str,var| str+"#{send(var)}code_runner_spacer"}.gsub(/\s/, '_').gsub(/code_runner_spacer/, "\t") + "\n" 
end

#defaults_file_nameObject

Return the name of the defaults file currently in use.



430
431
432
433
434
435
436
# File 'lib/coderunner/run.rb', line 430

def defaults_file_name
	if @runner.defaults_file
		return "#{@runner.defaults_file}_defaults.rb"
	else
		return "#{rcp.code}_defaults.rb"
	end
end

#defaults_locationObject

Return the folder where the default defaults file is located.



459
460
461
462
463
# File 'lib/coderunner/run.rb', line 459

def defaults_location
  location = defaults_location_list.find{|folder| FileTest.exist? folder and Dir.entries(folder).include? defaults_file_name}
  raise "Can't find defaults_file #{defaults_file_name} in #{defaults_location_list.join(',')}." unless location
  location
end

#defaults_location_listObject



453
454
455
# File 'lib/coderunner/run.rb', line 453

def defaults_location_list
  self.class.defaults_location_list
end

#dupObject



898
899
900
# File 'lib/coderunner/run.rb', line 898

def dup
	return self.class.new(@runner).learn_from(self)
end

#error(message) ⇒ Object

Prints an error message and raises a SubmitError, useful for pre-submit checks.



1108
1109
1110
# File 'lib/coderunner/run.rb', line 1108

def error(message)
	raise("Error: " + message)
end

#evaluate_defaults_file(filename) ⇒ Object

Update instance variables using the given defaults file. Give warnings if the defaults file contains variables which are not simulation input parameters



487
488
489
490
491
492
493
494
495
496
497
# File 'lib/coderunner/run.rb', line 487

def evaluate_defaults_file(filename)
	text = File.read(filename)
	text.scan(/^\s*@(\w+)/) do
		var_name = $~[1].to_sym
		next if var_name == :defaults_file_description
		unless rcp.variables.include? var_name
			warning("---#{var_name}---, specified in #{File.expand_path(filename)}, is not a variable. This could be an error")
		end
	end
	instance_eval(text)
end

#executable_locationObject



1051
1052
1053
1054
1055
# File 'lib/coderunner/run.rb', line 1051

def executable_location
	@executable||=@runner.executable
	raise "No executable" unless @executable
	File.dirname(@executable)
end

#execute_submissionObject



578
579
580
581
582
583
584
585
586
587
# File 'lib/coderunner/run.rb', line 578

def execute_submission
	if @runner.test_submission
		log 'testing submission'
		eputs info_file
		File.delete(@runner.root_folder + "/submitting")
		exit
	else
		execute
	end
end

#generate_combined_ids(type) ⇒ Object

Raises:



954
955
956
# File 'lib/coderunner/run.rb', line 954

def generate_combined_ids(type)
	raise CRFatal.new("Can't call generate_combined_ids from a run")
end

#generate_component_runsObject



951
952
# File 'lib/coderunner/run.rb', line 951

def generate_component_runs
end

#generate_run_nameObject



718
719
720
721
722
723
# File 'lib/coderunner/run.rb', line 718

def generate_run_name
		@run_name = %[v#@version] + @naming_pars.inject("") do |str, par|
			str+="_#{par}_#{send(par).to_s[0...8]}"
		end
		@run_name = @run_name.gsub(/\s+/, "_").gsub(/\//, '') + "_id_#@id"
end

#getsObject

No reading from the command line thank you very much!



50
51
52
# File 'lib/coderunner/run.rb', line 50

def gets #No reading from the command line thank you very much!
	$stdin.gets
end

#hard_cacheObject

The hard cache persists after the current program ceases because it is written in the .code_runner_run_data file. It will disappear if the -a or -A flags are specified at any point If you edit the hard cache you ”must” call save afterwards or your changes may not be kept



99
100
101
102
# File 'lib/coderunner/run.rb', line 99

def hard_cache
	@hard_cache ||={}
	@hard_cache
end

#info_fileObject

private :write_info



731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
# File 'lib/coderunner/run.rb', line 731

def info_file
		@modlet = rcp.modlet if rcp.modlet?
		return <<EOF
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
# #{rcp.code_long} Input Parameters
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
# Code: 		#{rcp.code}
# System: 	#{@sys}
# Version:	#{@version}
# Nprocs: 	#{@nprocs}
# Directory:	#{Dir.pwd}
# Runname:	#{@run_name}
# ID:		#{@id}
# #{@modlet ? "Modlet:\t#@modlet" : ""} 
# Classname:	#{self.class.to_s}

# #{@job_no ? "Job_No:		#{@job_no}" : ""}

# Parameters:
#{(rcp.variables + rcp.run_info + [:version, :code, :modlet, :sys] - [:component_runs]).inject({}){|hash, var| hash[var] = send(var) unless (!send(var) and send(var) ==  nil); hash}.pretty_inspect}


# Actual Command:
# #{run_command.gsub(/\n/, "\n#")}
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
EOF

end

#inspectObject

aliold :inspect



775
776
777
778
779
780
# File 'lib/coderunner/run.rb', line 775

def inspect
	old, @runner = @runner, nil
	str = super
	@runner = old
	str
end

#is_completeObject Also known as: ctd

Return true if the run is completed, false otherwise



467
468
469
# File 'lib/coderunner/run.rb', line 467

def is_complete
	@status == :Complete
end

#job_identifierObject

This function is a hook which is used by system modules. For runs it is defined as the id.



475
476
477
# File 'lib/coderunner/run.rb', line 475

def job_identifier
	id
end

#latex_report_headerObject



1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
# File 'lib/coderunner/run.rb', line 1119

def latex_report_header
#gsub is a hack which removes 14 spaces from the beginning of the file. This allows nice code indentation here.
<<-EOF.gsub(/^ {4}/, "")
    % Set up  
    \\documentclass[11pt, twocolumn]{report}
    \\usepackage{amsmath}
    \\usepackage{amsthm}
    \\usepackage{amssymb}
    \\usepackage{graphicx}
    \\usepackage{caption}
    \\usepackage{subcaption}
    \\usepackage{wrapfig}
    \\usepackage{epstopdf}
    \\usepackage{fullpage}

    \\newcommand{\\newfig}[1]{
    \\includegraphics[width=\\linewidth]{#1}
    }

    \\begin{document}

    % Title Page
    \\title{Run summary for run number #{id}}
    \\date{#{Time.now}}
    \\author{CodeRunner}
                  
    \\maketitle

EOF

end

#learn_from(run) ⇒ Object



912
913
914
915
916
917
918
919
920
921
922
923
924
# File 'lib/coderunner/run.rb', line 912

def learn_from(run)
	run.instance_variables.each do |var|	
#   		puts var
#  		puts run.instance_variable_get(var)
			instance_variable_set(var,run.instance_variable_get(var)) 
#  				puts instance_variable_get(var)

# 		rescue NoMethodError
# 			next
# 		end
	end
	self
end

#logivObject



929
930
931
932
933
934
935
# File 'lib/coderunner/run.rb', line 929

def logiv
	instance_variables.each do |var|
		unless var == :@runner or var == :@system_triers
			log(var); logi(instance_variable_get(var))
		end
	end
end

#max(variable, complete = false) ⇒ Object

@@maxes = {} @@cmaxes = {}

Raises:

  • (ArgumentError)


961
962
963
964
965
966
967
968
969
970
971
972
# File 'lib/coderunner/run.rb', line 961

def max(variable, complete=false) #does this run have the maximum value of this variable
	raise ArgumentError.new("complete must be true or false") unless [TrueClass, FalseClass].include? complete.class
	@runner.generate_combined_ids
	ids = @runner.combined_ids 
	if complete
		ids = ids.find_all{|id| @runner.combined_run_list[id].status == :Complete}
		max_id = @runner.cmaxes[variable] ||= ids.sort_by{|id| @runner.combined_run_list[id].send(variable)}[-1]
	else
		max_id = @runner.maxes[variable] ||= ids.sort_by{|id| @runner.combined_run_list[id].send(variable)}[-1]
	end
	return @runner.combined_run_list[max_id].send(variable) == send(variable)
end

#min(variable, complete = false) ⇒ Object

does this run have the minimum value of this variable

Raises:

  • (ArgumentError)


978
979
980
981
982
983
984
985
986
987
988
989
990
# File 'lib/coderunner/run.rb', line 978

def min(variable, complete=false) #does this run have the minimum value of this variable
	raise ArgumentError.new("complete must be true or false") unless [TrueClass, FalseClass].include? complete.class
	@runner.generate_combined_ids
	ids = @runner.combined_ids 
	
	if complete
		ids = ids.find_all{|id| @runner.combined_run_list[id].status == :Complete}
		min_id = @runner.cmins[variable] ||= ids.sort_by{|id| @runner.combined_run_list[id].send(variable)}[0]
	else
		min_id = @runner.mins[variable] ||= ids.sort_by{|id| @runner.combined_run_list[id].send(variable)}[0]
	end
	return @runner.combined_run_list[min_id].send(variable) == send(variable)
end

#p(*args) ⇒ Object

Here we redefine the inspect function p to raise an error if anything is written to standard out while in server mode. This is because the server mode uses standard out to communicate and writing to standard out can break it. All messages, debug information and so on, should always be written to standard error.



189
190
191
192
193
194
195
# File 'lib/coderunner/run.rb', line 189

def p(*args)
	if @runner and @runner.server
		raise "Writing to stdout in server mode will break things!"
	else
		super(*args)
	end
end

#prepare_submission(options = {}) ⇒ Object

Generate the run name and the directory name, and check that the directory is empty. The run name, i.e. @run_name can be set beforehand, in which case it will not be changed. The directory name choice can be influenced by the variable @dir_name, which is not used outside this function.



662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
# File 'lib/coderunner/run.rb', line 662

def prepare_submission(options={})
	raise "Test Submit Error Handling" if @run_test_flags and @run_test_flags[:test_submit_error_handling]
	
	#p '@nprocs', @nprocs
	if @runner
		SUBMIT_OPTIONS.each do |option|
				set(option, @runner.send(option)) if @runner.send(option)
		end
	end
	#p '@nprocs', @nprocs
	
# 		puts send(:q)

	raise CRFatal.new ("Can't find executable: #{executable_location}/#{executable_name}") unless FileTest.exist? File.expand_path("#{executable_location}/#{executable_name}")

	@naming_pars.each{|par| raise CRFatal.new("@naming_par #{par} is not listed in variables or run_info") unless (rcp.variables + rcp.run_info).include? par}
	@naming_pars.delete(:g_exb_start_timestep)
	unless @dir_name # dir_name can be set in advance to change the default directory name
		@dir_name = %[v#@version]
		@dir_name = @dir_name.gsub(/\s+/, "_") + "/id_#@id"
	end
	generate_run_name unless @run_name
	
	@directory = File.expand_path(@dir_name)
	#@relative_directory = File.expand_path(Dir.pwd).sub(File.expand_path(@runner.root_folder) + '/', '')
	#@relative_directory = @directory.sub(File.expand_path(@runner.root_folder) + '/', '')
	@relative_directory = @dir_name

	raise "Directory #@dir_name contains code_runner_info" if FileTest.exist? @directory and Dir.entries(@directory).include? ["code_runner_info.rb"]

	@job_no = nil
	FileUtils.makedirs(@dir_name)
	Dir.chdir(@dir_name) do 
		generate_input_file
    copy_extra_files
		
		File.open(".code_runner_version.txt", 'w'){|file| file.puts CODE_RUNNER_VERSION}
		#File.open("code_runner_modlet.rb", 'w'){|file| file.puts rcp.modlet_source} if rcp.modlet_required
	end
	@dir_name = nil

end

#pretty_print(q) ⇒ Object

aliold :pretty_inspect



784
785
786
787
788
789
790
# File 'lib/coderunner/run.rb', line 784

def pretty_print(q)
	old, @runner = @runner, nil
	str = q.pp_object(self)
	@runner = old
	str

end

Here we redefine the function print to raise an error if anything is written to standard out while in server mode. This is because the server mode uses standard out to communicate and writing to standard out can break it. All messages, debug information and so on, should always be written to standard error.



215
216
217
218
219
220
221
# File 'lib/coderunner/run.rb', line 215

def print(*args)
	if @runner and @runner.server
		raise "Writing to stdout in server mode will break things!"
	else
		super(*args)
	end
end

#process_directoryObject

Analyse the directory of the run. This should be called from the directory where the files of the run are located. This method reads in the CodeRunner data already available in code_runner_info.rb and code_runner_results.rb, and then calls process_directory_code_specific which is defined in the code module.

Raises:



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# File 'lib/coderunner/run.rb', line 226

def process_directory
	
	# Clear the cache
  # EGH removed the two lines below because code module need the cache
  # to last, e.g. if it contains references to other files
	#@runner.cache[:runs]||={}
	#@runner.cache[:runs][@id] = {}
	logf(:process_directory)
	raise CRFatal.new("Something has gone horribly wrong: runner.class is #{@runner.class} instead of CodeRunner") unless @runner.class.to_s == "CodeRunner"

	begin
		@code_runner_version = Version.new(File.read('.code_runner_version.txt'))
		File.read('code_runner_info.rb')
	rescue Errno::ENOENT # version may be less than 0.5.1 when .code_runner_version.txt was introduced
		@code_runner_version = Version.new('0.5.0')
	end
	
	@directory = Dir.pwd
	@relative_directory = File.expand_path(Dir.pwd).sub(File.expand_path(@runner.root_folder) + '/', '')
# 	p @directory
	@readme = nil
	
	#if @code_runner_version < Version.new('0.5.1')
		#begin
			#update_from_version_0_5_0_and_lower
		#rescue Errno::ENOENT => err # No code runner files were found
			#unless @runner.heuristic_analysis
				#puts err
				#raise CRFatal.new("No code runner files found: suggest using heuristic analysis (flag -H if you are using the code_runner script)")
			#end
			#unless @runner.current_request == :traverse_directories
				#@runner.requests.push :traverse_directories unless @runner.requests.include? :traverse_directories
				#raise CRMild.new("can't begin heuristic analysis until there has been a sweep over all directories") # this will get rescued
			#end
			#@runner.increment_max_id	
			#@id = @runner.max_id
			#@job_no = -1
			#run_heuristic_analysis
		#end
	#end
		begin
			read_info
		rescue Errno::ENOENT => err # No code runner files were found
			unless @runner.heuristic_analysis
				puts err
				raise CRFatal.new("No code runner files found: suggest using heuristic analysis (flag -H if you are using the code_runner script)")
			end
			unless @runner.current_request == :traverse_directories
				@runner.requests.push :traverse_directories unless @runner.requests.include? :traverse_directories
				raise CRMild.new("can't begin heuristic analysis until there has been a sweep over all directories") # this will get rescued
			end
			@runner.increment_max_id	
			@id = @runner.max_id
			@job_no = -1
			run_heuristic_analysis
		end
	
	
	begin
		read_results if FileTest.exist? 'code_runner_results.rb'
	rescue NoMethodError, SyntaxError => err
		puts err
		puts 'Results file possibly corrupted for ' + @run_name
	end	

	@running = (@@current_status =~ Regexp.new(@job_no.to_s)) ? true : false 
	if methods.include? :get_run_status
		@status = get_run_status(@job_no, @@current_status) rescue :Unknown
	else
		@status ||= :Unknown
	end
	#logi '@@current_status', @@current_status, '@job_no', @job_no
	#logi '@running', @running
	process_directory_code_specific	
  
  # Sometimes the run can be completed and still in the queue, in
  # which case process_directory_code_specific may set @status==:Complete
  # or @status==:Failed even though @running = true. Here we update
  # @running if this is the case. This will have no effect on any subsequent
  # update as CodeRunner does not use @running as a criterion for deciding
  # whether or not to recheck a run and call process_directory again.
  @running = false if [:Complete, :Failed].include? @status
	
	raise CRFatal.new("status must be one of #{PERMITTED_STATI.inspect}") unless PERMITTED_STATI.include? @status
	@max = {}
	write_results
	@component_runs = []
	generate_component_runs
	save
  commit_results if @runner.is_in_repo? and not @running
	return self
end

#puts(*args) ⇒ Object

Here we redefine the function puts to raise an error if anything is written to standard out while in server mode. This is because the server mode uses standard out to communicate and writing to standard out can break it. All messages, debug information and so on, should always be written to standard error.



202
203
204
205
206
207
208
# File 'lib/coderunner/run.rb', line 202

def puts(*args)
	if @runner and @runner.server
		raise "Writing to stdout in server mode will break things!"
	else
		super(*args)
	end
end

#rcpObject

Calls Run.rcp



158
159
160
# File 'lib/coderunner/run.rb', line 158

def rcp 
	self.class.rcp
end

#read_infoObject

Read input parameters from the file code_runner_info.rb



321
322
323
324
325
# File 'lib/coderunner/run.rb', line 321

def read_info
	eval(File.read('code_runner_info.rb')).each do |key, value|
		set(key, value)
	end
end

#read_resultsObject

Read results from the file code_runner_results.rb



329
330
331
332
333
334
# File 'lib/coderunner/run.rb', line 329

def read_results
	return if @runner.recalc_all
	eval(File.read('code_runner_results.rb')).each do |key, value|
		set(key, value)
	end
end

#recheckObject



937
938
939
940
941
942
943
944
945
946
947
948
949
# File 'lib/coderunner/run.rb', line 937

def recheck
	logf(:recheck)
	Dir.chdir(@directory) do
# 		puts 'ackack'
		puts "Rechecking #@run_name"
		runner = @runner
		instance_variables.each{|var| instance_variable_set(var, nil) unless var == :@runner}
		begin File.delete("CODE_RUNNER_RUN_DATA") rescue Errno::ENOENT end
		begin File.delete("CODE_RUNNER_RESULTS") rescue Errno::ENOENT end
		process_directory
		save
	end
end

#results_fileObject

Return the text of the results file.



345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/coderunner/run.rb', line 345

def results_file
	logf(:results_file)
	return <<EOF
# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
# #{rcp.code_long} Results
# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#
# This is a syntactically correct Ruby file, which is used by CodeRunner. Please do not edit unless you know what you are doing.
# Directory:	#{@directory}
# Runname:	#{@run_name}
# ID:		#{@id}

# Results:
#{(rcp.results+rcp.run_info - [:component_runs]).inject({}){|hash, (var,type_co)| hash[var] = send(var); hash}.pretty_inspect}

# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
EOF

end

#run_heuristic_analysisObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/coderunner/heuristic_run_methods.rb', line 5

def run_heuristic_analysis
	
	begin
		
		puts Dir.pwd
		raise CRMild.new("can't find input file") unless @rcp.input_file_extension
		input_file = Dir.entries.find_all{|file| file =~ Regexp.new("^[^.].*"+Regexp.escape(rcp.input_file_extension) + "$")}[0]
		raise CRMild.new("can't find input file") unless input_file
		log(input_file)
		input_file_text = File.read(input_file)
		@run_name = File.basename(input_file, rcp.input_file_extension) if rcp.use_file_name_as_run_name
		analyse_input_file_text(input_file_text)
		log("Automatic analysis complete")
# 				logiv
	rescue CRMild => err
		log(err)
		input_file = Feedback.get_choice("Unable to find a code runner inputs file. If there is another input file please choose it from this list", Dir.entries(Dir.pwd).find_all{|file| not [".",".."].include? file and File.file? file} + ["not available"])
		if input_file == "not available"
			FileUtils.touch('.CODE_RUNNER_IGNORE_THIS_DIRECTORY')
			raise CRError.new("run could be analysed, or folder does not contain a run")
		end
		input_file_text = File.read(input_file)
		log(input_file_text)
		analyse_input_file_text(input_file_text)
# 				logiv
		rcp.input_file_extension = File.extname(input_file)
		@rcp.use_file_name_as_run_name = Feedback.get_boolean("Do you want to use the input file name (minus the extension) as a run name? (Your answer will apply to all directories with code runner inputs files).") if rcp.use_file_name_as_run_name.class == NilClass
		@run_name = File.basename(input_file, rcp.input_file_extension) if rcp.use_file_name_as_run_name
	end
end

#saveObject

Cache the run object in the file .code_runner_run_data

Raises:



380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/coderunner/run.rb', line 380

def save
	
	logf(:save)
	raise CRFatal.new("Something has gone horribly wrong: runner.class is #{@runner.class} instead of CodeRunner") unless @runner.class.to_s =~ /^CodeRunner(::Merged)?/
	runner, @runner = @runner, nil
	@system_triers, old_triers = nil, @system_triers
	@component_runs.each{|run| run.runner = nil} if @component_runs
	#@component_runs.each{|run| run.runner = nil} if @component_runs
# 	logi(self)
	#pp self
	Dir.chdir(@directory){File.open(".code_runner_run_data", 'w'){|file| file.puts Marshal.dump(self)}}
	@runner = runner
	@component_runs.each{|run| run.runner = runner} if @component_runs
	@system_triers = old_triers 
end

#smax(variable, sweep = nil, complete = nil) ⇒ Object

# Does this run have the maximum value of this variable to be found amoung the filtered runs?

def fmax(variable, complete = false) raise ArgumentError.new(“complete must be true or false”) unless [TrueClass, FalseClass].include complete.class @runner.generate_combined_ids ids = @runner.filtered_ids # o^o-¬ if complete ids = ids.find_all|id| @runner.combined_run_list[id].status == :Complete} max_id = @@cfmaxes[variable] ||= ids.sort_by{|id| @runner.combined_run_list[id].send(variable) else max_id = @@fmaxes ||= ids.sort_by|id| @runner.combined_run_list[id].send(variable) end return @runner.combined_run_list.send(variable) == send(variable) end



1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
# File 'lib/coderunner/run.rb', line 1011

def smax(variable,sweep=nil, complete=nil)
	logf(:max)
 	sweep ||= variable
	if complete
		@csmaxes[variable] ||= {}
		max_id = @csmaxes[variable][sweep] = @runner.get_max(self, variable,sweep, complete)
	else
		@smaxes[variable] ||= {}
		max_id = @smaxes[variable][sweep] = @runner.get_max(self, variable,sweep, complete)
	end
	return @runner.combined_run_list[max_id].send(variable) == send(variable)
end

#smin(variable, sweep = nil, complete = nil) ⇒ Object



1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
# File 'lib/coderunner/run.rb', line 1024

def smin(variable,sweep=nil, complete=nil)
	logf(:min)
 	sweep ||= variable
	@smins ||= {}
	@csmins ||= {}
	if complete
		@csmins[variable] ||= {}
		min_id = @csmins[variable][sweep] = @runner.get_min(self, variable,sweep, complete)
	else
		@smins[variable] ||= {}
		min_id = @smins[variable][sweep] = @runner.get_min(self, variable,sweep, complete)
	end
	return @runner.combined_run_list[min_id].send(variable) == send(variable)
end

#try_by_system(expected_return = NilClass, &block) ⇒ Object

Raises:



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/coderunner/heuristic_run_methods.rb', line 56

def try_by_system(expected_return=NilClass, &block)
# 	puts "Trying by system"
# 	puts @@system_run_classes[0].new(@runner).inspect
	@@system_triers ||= rcp.system_run_classes.inject({}){|hash, run_class| 
# 		puts run_class.new(@runner).learn_from(self).inspect
		log hash.class
		hash[run_class] = run_class.new(@runner).learn_from(self).freeze
		hash}
# 	puts @system_triers.inspect
# 	i=0
	answer = nil
	if @@successful_trial_class
		begin
			answer = yield(@@system_triers[@@successful_trial_class].dup, self)
			raise CRError.new("trial returned an answer, but answer was not of the right class") unless expected_return == NilClass or answer.is_a? expected_return
			return answer
		rescue => err
			log err
		end
	end

	@@system_triers.values.each do |trier|
		begin	
# 			puts i
# 			i+=1
#  			puts trier.class.ancestors
# 			puts "asld"
			answer = yield(trier.dup, self)
# 			puts expected_return
# 			puts answer.is_a? Fixnum
# 			puts "Sd"
			raise CRError.new("trial returned an answer, but answer was not of the right class") unless expected_return == NilClass or answer.is_a? expected_return 
#  			puts answer, "HASG"
# 			puts "asfd"
			@@successful_trial_system = trier.class.run_sys_name
			@@successful_trial_class = trier.class
# 			puts @@successful_trial_system
			return answer
		rescue Errno::ENOENT, TypeError, CRMild, CRError => err
# 			puts err
			next
		end
	end
# 	puts answer; gets
# 	answer
	raise CRError.new("try by system was not successful")
end

#try_to_find_job_output_endsObject



191
192
193
194
195
196
197
198
# File 'lib/coderunner/heuristic_run_methods.rb', line 191

def try_to_find_job_output_ends
	output = try_to_get_output_file
	return nil unless output
#  	return try_by_system(Fixnum) do |trier, myself|
	found = File.read(output) =~ /job output ends/i
	return found ? true : false
#  	end
end

#try_to_get_error_fileObject



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/coderunner/heuristic_run_methods.rb', line 155

def try_to_get_error_file
	logf(:try_to_get_error_file)
	begin
		error_file =  try_by_system(String) do |trier, myself|
	# 		trier = trier.dup
	# 		puts trier
			trier.executable_name = "mx123456zz"
			trier.job_no = "mx123456yy"
			trier.version = ""
			scanner = Regexp.new("(?<outputfile>"+Regexp.escape(trier.error_file).sub("mx123456zz", ".+").sub("mx123456yy", "\\d+")+")")
			ans = nil
			Dir.entries.each do |file|
				if file =~ scanner
	# 				puts $~[:outputfile] 
					ans = $~[:outputfile] 
				end
			end
			ans
		end
	rescue CRError => err
 		log(err)
		error_file = nil
	end
	log("Error file was: ", error_file)
	if error_file
		begin
			logi(File.readlines(error_file))
			logi(File.readlines(error_file).size)
			logi(File.readlines(error_file).size.class)
		rescue => err
			log(err)
		end
	end
	return error_file
end

#try_to_get_job_numberObject



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/coderunner/heuristic_run_methods.rb', line 105

def try_to_get_job_number
	begin
		job_no = try_by_system(Fixnum) do |trier, myself|	

			trier.executable_name = "mx123456zz"
			trier.job_no = "mx123456yy"
			trier.version = ""

			scanner = Regexp.new(Regexp.escape(trier.output_file).sub("mx123456zz", ".+").sub("mx123456yy", "(?<jobno>\\d+)$"))
			answer = nil
			Dir.entries(Dir.pwd).each do |file|

					return   $~[:jobno].to_i if file =~ scanner
	# 			end
			end

			nil
		end
	rescue CRError => err
		job_no = -1
	end
	job_no
# 	exit
end

#try_to_get_output_fileObject



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/coderunner/heuristic_run_methods.rb', line 130

def try_to_get_output_file
	#very hacky!
	logf(:try_to_get_output_file)
	begin
		out_file =  try_by_system(String) do |trier, myself|
	# 		trier = trier.dup
	# 		puts trier
			trier.executable_name = "mx123456zz"
			trier.job_no = "mx123456yy"
			trier.version = ""
			scanner = Regexp.new("(?<outputfile>"+Regexp.escape(trier.output_file).sub("mx123456zz", ".+").sub("mx123456yy", "\\d+")+")")
# 			ep scanner
			ans = nil
			Dir.entries(Dir.pwd).each do |file|
				ans = $~[:outputfile] if file =~ scanner 
			end
			ans
		end
	rescue CRError => err
		log(err)
		out_file = nil
	end
	out_file
end

#update_in_queueObject



1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
# File 'lib/coderunner/run.rb', line 1057

def update_in_queue
	unless @status == :Queueing
		raise 'Can only updated runs whose status is :Queueing'
	end
	unless methods.include? :batch_script_file
		raise 'Can only update runs which have been submitted using a batch script file'
	end	
	old_run_name = @run_name
	generate_run_name
	new_run_name = @run_name
	#@run_name = old_run_name
	unless FileTest.exist?(filename = @directory + '/' + batch_script_file) or 
	 	FileTest.exist?(filename =  @runner.root_folder + '/' + batch_script_file)
			raise 'Could not find batch_script_file'
	end
	old_batch_script=File.read(filename)
	eputs old_batch_script
eputs old_batch_script.gsub(Regexp.new(Regexp.escape(old_run_name)), new_run_name)
	ep Regexp.new(Regexp.escape(old_run_name))
	File.open(filename, 'w'){|file| file.puts old_batch_script.gsub(Regexp.new(Regexp.escape(old_run_name)), new_run_name)}

	
	generate_input_file
	#throw(:done)
	write_info
end

#update_submission_parameters(parameters, start_from_defaults = true) ⇒ Object

This function set the input parameters of the run using the following sources in ascending order of priority: main defaults file (in the code module folder), local defaults file (in the local Directory), parameters (an inspected hash usually specified on the command line).



501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
# File 'lib/coderunner/run.rb', line 501

def update_submission_parameters(parameters, start_from_defaults=true)
	logf(:update_submission_parameters)
	if start_from_defaults
		#upgrade_defaults_from_0_5_0 if self.class.constants.include? :DEFAULTS_FILE_NAME_0_5_0
		main_defaults_file = "#{defaults_location}/#{defaults_file_name}"
		main_defaults_file_text = 		File.read(main_defaults_file)
		evaluate_defaults_file(main_defaults_file)

		unless FileTest.exist?(defaults_file_name)
			main_defaults_file_text.gsub!(/^/, "#")
			header = <<EOF
#############################################################
# CodeRunner Local Defaults File 
############################################################
#
# This is a local copy of the central defaults file, which 
# was copied from the central defaults file 
#		#{defaults_file_name} 
# 
# to the folder
# 	#{Dir.pwd}
#
# at 
# 	#{Time.now}
#
# by CodeRunner version #{CODE_RUNNER_VERSION}
#
# All lines in the original file have been commented out:
# they are kept as a reference to make adding local defaults easier. 
# It is suggested that local changes are placed at the top 
# of this file, not in the body of the commented out section.
#
# Local changes override the central defaults file. However,
# if the central defaults file changes, any variables which 
# are not overidden here will change for any future simulations
# in this folder.
#
##############################################################






# Begin Copy of Central Defaults:
#
#
EOF
			main_defaults_file_text = header + main_defaults_file_text
			File.open(defaults_file_name, 'w'){|file| file.puts main_defaults_file_text}
      if @runner.is_in_repo?
        repo = Repository.open_in_subfolder(Dir.pwd)
        repo.add(defaults_file_name)
        repo.autocommit("Added local defaults file #{defaults_file_name} in folder #{Dir.pwd}")
      end
                                                                                     #{defaults_file_name} in folder #{Dir.pwd
                                                                                     ##{defaults_file_name} in folder #{Dir.pwd
                                                                                     #
		end
		#FileUtils.cp("#{defaults_location}/#{defaults_file_name}", defaults_file_name) 
		
		evaluate_defaults_file(defaults_file_name)
	end
	return unless parameters
	@parameter_hash_string = parameters
	raise "parameters: #{parameters.inspect} must be a string which evaluates to a hash" unless parameters.class == String and parameters = eval(parameters) and parameters.class == Hash # parameters.class == String and parameters =~ /\S/
	@parameter_hash = parameters 
	parameters.each do |var, value|
		raise CRFatal.new('Cannot specify id as a parameter') if var.to_sym == :id
		set(var, value) unless value == :default
		next if [:comment, :extra_files].include? var
		@naming_pars.push var
	end
	@naming_pars.uniq!
	self
end

#warning(message) ⇒ Object

Prints a warning message, useful for pre-submit checks.



1100
1101
1102
# File 'lib/coderunner/run.rb', line 1100

def warning(message)
	eputs "Warning: " + message; sleep 0.1
end

#write_infoObject



725
726
727
# File 'lib/coderunner/run.rb', line 725

def write_info
	Dir.chdir(@directory){File.open("code_runner_info.rb", 'w'){|file| file.puts info_file}}
end

#write_resultsObject

Write results to the file code_runner_results.rb



338
339
340
341
# File 'lib/coderunner/run.rb', line 338

def write_results
	logf(:write_results)
	Dir.chdir(@directory){File.open("code_runner_results.rb", 'w'){|file| file.puts results_file}}
end