require 'date' require 'nera_db_folders' require 'nera_simulator_records' require 'nera_parameter_records' require 'nera_run_records' require 'nera_job_records' module NERA class ParameterLayerController # instance of NERA::DbFolders @db_folders # simulator class @sim_class # instance of NERA::ParameterRecords @param_records def initialize( path_db_folder, sim_name) raise ArgumentError unless path_db_folder.is_a?(String) @db_folders = NERA::DbFolders.new( path_db_folder) sim_records = NERA::SimulatorRecords.new( @db_folders.path_to_simulators_table) sim_records.set_yaml_file( @db_folders.path_to_simulators_yaml ) found = sim_records.list.find do |rec| rec[:name] == sim_name.to_s end raise "No such simulator." unless found sim_id = found[:id] @sim_class = NERA::Simulator.inherited_simulators.find do |sim| sim.to_s == sim_name.to_s end raise "No such simulator." unless @sim_class p_tab_path = @db_folders.path_to_parameters_table( @sim_class) @param_records = NERA::ParameterRecords.new( p_tab_path, sim_records, sim_id) @param_records.set_yaml_file( @db_folders.path_to_parameters_yaml( @sim_class) ) convert_to_recent_format end # update the parameters table to the most recent one private def convert_to_recent_format @param_records.transaction do recs = @param_records.list_active found = recs.find_all do |rec| rec[:num_finished_runs] == nil or rec[:num_all_runs] == nil end found.each do |rec| param_id = rec[:id] run_records = NERA::RunRecords.new( @db_folders.path_to_runs_table( @sim_class, param_id), @param_records, param_id ) num_all_runs = run_records.list_all.size num_finished_runs = run_records.list_all_finished.size @param_records.update_num_runs( param_id, num_finished_runs, num_all_runs) end end end public def parameters_list @param_records.list_all end def parameters_list_in_csv l_active = @param_records.list_active header = @param_records.keys.dup header.delete( :in_trashbox?) csv_list = [] l_active.each do |p_hash| strings = [] header.each do |key| if p_hash[key].is_a?(DateTime) strings << p_hash[key].to_s.split('T')[0] elsif p_hash[key] strings << p_hash[key].to_s elsif p_hash[key] == nil found = @sim_class::Parameters.find do |p| p[0] == key end strings << found[2].to_s end end strings[1] = "#{strings[1]}/#{strings[2]}" strings.delete_at(2) csv_list << strings.join(", ") end header.delete( :num_finished_runs) header[1] = :num_runs return header.join(", "), csv_list end def get_id_from_csv_string( pstr) return pstr.split(',').first.to_i end def find_ids_by_parameter_hash( param_hash) found_ids = [] @param_records.list_all.each do |rec| matched = true param_hash.each_pair do |key,value| unless rec[key] == value matched = false break end end if matched found_ids << rec[:id] end end found_ids = nil unless found_ids.size > 0 return found_ids end def get_parameter( param_id = nil) param_list = [] @sim_class::Parameters.each do |elem| param_list << elem.dup end if param_id found = @param_records.list_all.find do |rec| rec[:id] == param_id end if found # load parameters param_list.each do |param| param[2] = found[ param[0] ] end end end return param_list end alias :list_of_parameters :get_parameter def path_to_param_layer return @db_folders.path_to_parameter_layer( @sim_class) end def create_a_new_parameter_set( p_hash) pid = nil @param_records.transaction { pid = @param_records.add( p_hash) return nil unless pid b = @db_folders.create_new_parameter_folder( @sim_class, pid) raise "Creation of a new folder for #{@sim_calss}, #{pid} failed." unless b path = @db_folders.path_to_runs_table( @sim_class, pid) c = NERA::RunRecords.create_table( path) raise "File #{path} already exists." unless c @db_folders.logger.info(self.class.to_s) { "created a new parameter set (#{@sim_class.to_s}/#{pid})" } } return pid end def move_a_parameter_set_into_trashbox( id) return nil unless @param_records.find_by_id(id) run_records = NERA::RunRecords.new( @db_folders.path_to_runs_table( @sim_class, id), @param_records, id ) return nil if run_records.list_all_not_finished.size > 0 job_records = NERA::JobRecords.new( @db_folders.path_to_jobs_table) job_records.transaction { # to lock the runs tables @param_records.transaction { flag = @param_records.update_to_state_trashbox(id) return nil unless flag r_path = @db_folders.path_to_run_layer( @sim_class, id).sub(/\/$/,'') cmd = "tar cjf #{File.basename(r_path)}.tar.bz2 #{File.basename(r_path)}" Dir.chdir( File.dirname(r_path)) { system(cmd) } raise "Command #{cmd} failed" unless $? == 0 FileUtils.rm_r(r_path) @db_folders.logger.info(self.class.to_s) { "moved a parameter set into the trashbox (#{@sim_class.to_s}/#{id})" } } } return true end def trashbox_parameter_list_in_csv lt = @param_records.list_trashbox header = @param_records.keys.dup header.delete( :in_trashbox?) csv_list = [] lt.each do |p_hash| strings = [] header.each do |key| if p_hash[key].is_a?(DateTime) strings << p_hash[key].to_s.split('T')[0] elsif p_hash[key] strings << p_hash[key].to_s elsif p_hash[key] == nil if key == :num_finished_runs or key == :num_all_runs strings << 0 else found = @sim_class::Parameters.find do |param| param[0] == key end strings << found[2].to_s end end end strings[1] = "#{strings[1].to_i}/#{strings[2].to_i}" strings.delete_at(2) csv_list << strings.join(", ") end header.delete( :num_finished_runs) header[1] = :num_runs return header.join(", "), csv_list end def revert_a_parameter_set_in_trashbox( id) @param_records.transaction { flag = @param_records.update_to_state_active(id) return nil unless flag r_path = @db_folders.path_to_run_layer( @sim_class, id).sub(/\/$/,'') cmd = "tar xjf #{File.basename(r_path)}.tar.bz2" Dir.chdir( File.dirname(r_path) ) { system(cmd) } raise "Command #{cmd} failed" unless $? == 0 FileUtils.rm(r_path+".tar.bz2") @db_folders.logger.info(self.class.to_s) { "reverted a parameter set in the trashbox (#{@sim_class.to_s}/#{id})" } convert_to_recent_format } return true end def delete_a_parameter_set( id) @param_records.transaction { flag = @param_records.destroy(id) return nil unless flag r_path = @db_folders.path_to_run_layer( @sim_class, id).sub(/\/$/,'') FileUtils.rm("#{r_path}.tar.bz2") @db_folders.logger.info(self.class.to_s) { "deleted a parameter set in the trashbox (#{@sim_class.to_s}/#{id})" } } return true end end end