class MesaReader::MesaLogDir
The MesaLogDir
class is meant to be an all-encompassing class that deals with history and profile files through one interface. If this file is located in your work directory, many defaults are set already to make things easier.
Examples:
>>> include MesaReader
>>> l = MesaLogDir.new
(:log_path => '~/mesa/star/work/LOGS',
:profile_prefix => 'profile', :profile_suffix => 'data', :history_file => 'history.data', :index_file => 'profiles.index')
NOTE: All values of the intitialization hash have default values as shown
in the next five accessor methods. You should only have to set the last four values if you have made specific changes, are reading data from an old (or new, I suppose) version of MESA that has different default file names.
>>> l.log_path # returns the path string; what you used to initialize >>> l.profile_prefix # prefix for profile files (default is 'profile') >>> l.profile_suffix # suffix for profile files (default is 'data') >>> l.history_file # name of history file (default is 'history.data') >>> l.index_file # name of profile index file (default is
'profiles.index')
>>> l.contents # returns array of strings containing names of all
files in log_path
>>> l.profiles # returns a MesaProfileIndex
object built from
index_file
NOTE: ALL MesaProfileIndex
METHODS ARE AVAILABLE TO MesaLogDir
OBJECTS, TOO
>>> l.history_data # returns MesaData
instance from history_file
same as doing MesaData.new(log_path + '/' + history_file)
>>> l.history # alias of l.history_data
>>> l.select_models(keys) { |val1, val2, …| test(val1, val2, …)} # =>
Dvector of model numbers whose history values of the given key categories pass the test in the block. For example,
>>> late_time_model_nums = l.select_models('star_age', 'log_L') do |age, l| >>> age > 1e5 and l > 2
should return a Dvector of all model numbers where the age is greater than 1e5 AND log_L > 2 AND there is an available profile in log_path>>> l.profile_data(params) # =>
MesaData
instance for profile specifiedin params>>> params = {:profile_number => num1, :model_number => num2}
If no parameters are given, it defaults to the profile with the largest model number (i.e. the latest profile saved). If a model number is given, the profile that corresponds to that profile number is used, unless there is no such profile, in which case it will default to the last one saved. If an explicit profile number is given, it is used, even if a model number is given. An explicit profile number must be correct or else it will fail (no falling back to the default).
Attributes
Public Class Methods
# File lib/mesa_reader.rb, line 285 def initialize(params = {}) params = {'log_path' => 'LOGS', 'profile_prefix' => 'profile', 'profile_suffix' => 'data', 'history_file' => 'history.data', 'index_file' => 'profiles.index'}.merge(params) @log_path = params['log_path'] @profile_prefix = params['profile_prefix'] @profile_suffix = params['profile_suffix'] @history_file = params['history_file'] @index_file = params['index_file'] @contents = Dir.entries(@log_path) raise "No profile index file, #{@index_file}, in #{@log_path}." unless @contents.include?(@index_file) raise "No history file, #{@history_file}, in #{@log_path}." unless @contents.include?(@history_file) @profiles = MesaProfileIndex.new(File.join(@log_path, @index_file)) @h = MesaData.new(File.join(log_path, history_file)) end
Public Instance Methods
# File lib/mesa_reader.rb, line 311 def have_profile_with_model_number?(model_number) model_numbers.include?(model_number) end
# File lib/mesa_reader.rb, line 315 def have_profile_with_profile_number?(profile_number) profile_numbers.include?(profile_number) end
# File lib/mesa_reader.rb, line 323 def history_data @h end
# File lib/mesa_reader.rb, line 307 def model_numbers profiles.model_numbers end
# File lib/mesa_reader.rb, line 344 def profile_data(params = {}) # default behavior is to load profile of last model available, next # preferred number is a specified profile number, and final preference is # the profile that corresponds with the given model number, if there is # one. params = {'model_number' => model_numbers.max, 'profile_number' => nil}.merge(params) model_number = params['model_number'].to_i profile_number = params['profile_number'].to_i if params['profile_number'] if (model_numbers.include?(model_number) and not profile_number) profile_number = profile_with_model_number(model_number) end unless profile_number unless @profiles.have_profile_with_model_number?(model_number) raise "No profile corresponding to model number #{model_number} in" + "#{index_file}." end profile_number = profile_with_model_number(model_number) end file_name = "#{profile_prefix}#{profile_number}.#{profile_suffix}" unless contents.include?(file_name) raise "No profile file, #{file_name}, in #{log_path}." end MesaData.new(File.join(log_path, file_name)) end
# File lib/mesa_reader.rb, line 303 def profile_numbers profiles.profile_numbers end
# File lib/mesa_reader.rb, line 319 def profile_with_model_number(model_number) profiles.profile_with_model_number(model_number.to_i) end
# File lib/mesa_reader.rb, line 329 def select_models(*keys) keys.each do |key| raise "#{key} not a recognized data category." unless history.data? key end unless block_given? raise "Must provide a block for SELECT_MODELS to test values of" + " provided keys." end model_numbers.select do |num| params = keys.map { |key| @h.data_at_model_number(key, num) } yield(*params) end end