Class: AMEE::DataAbstraction::CalculationSet

Inherits:
Object
  • Object
show all
Defined in:
lib/amee-data-abstraction/calculation_set.rb

Overview

The CalculationSet class represents a collection of prototype calculations (of the class ProtptypeCalculation.

Prototype calculations are contained within the @calculations instance variable ordered hash. Calculations can be added manually to the @calculations hash or initialized in place using the #calculation method which takes an options hash or block for specifying the prototype calculation properties.

Typical usage is to initialize the CalculationSet and its daughter prototype calculations together using block syntax, thus:

Calculations = CalculationSet.new {

  calculation {
    label :electricity
    path "/some/path/for/electricity"
    ...
  }

  calculation {
    label :transport
    path "a/transport/path"
    ...
  }

  ...
}

Constant Summary collapse

DEFAULT_RAILS_CONFIG_DIR =
"config/calculations"
@@sets =

Class variable holding all instantiated calculation sets keyed on the set name.

{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, options = {}, &block) ⇒ CalculationSet

Initialise a new Calculation set. Specify the name of the calculation set as the first argument. This name is used as the set key within the class variable @@sets hash.

Raises:

  • (ArgumentError)


123
124
125
126
127
128
129
130
131
132
# File 'lib/amee-data-abstraction/calculation_set.rb', line 123

def initialize(name,options={},&block)
  raise ArgumentError, "Calculation set must have a name" unless name
  @name = name
  @file = CalculationSet.find_config_file(options[:file]) if options[:file]
  @calculations = ActiveSupport::OrderedHash.new
  @all_blocks=[]
  @all_options={}
  instance_eval(&block) if block
  @@sets[@name.to_sym] = self
end

Instance Attribute Details

#calculationsObject

Returns the value of attribute calculations.



117
118
119
# File 'lib/amee-data-abstraction/calculation_set.rb', line 117

def calculations
  @calculations
end

#fileObject

Returns the value of attribute file.



117
118
119
# File 'lib/amee-data-abstraction/calculation_set.rb', line 117

def file
  @file
end

#nameObject

Returns the value of attribute name.



117
118
119
# File 'lib/amee-data-abstraction/calculation_set.rb', line 117

def name
  @name
end

Class Method Details

.find(name) ⇒ Object

Retrieve a calculation set on the basis of a configuration file name or relatiev/absolute file path. If configuration files are location within the default Rails location under ‘/config/calculations’ then the path and the .rb extenstion can be omitted from the name.



54
55
56
# File 'lib/amee-data-abstraction/calculation_set.rb', line 54

def self.find(name)
  @@sets[name.to_sym] or load_set(name)
end

.find_prototype_calculation(label) ⇒ Object

Find a specific prototype calculation instance without specifying the set to which it belongs.



73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/amee-data-abstraction/calculation_set.rb', line 73

def self.find_prototype_calculation(label)
  # Make sure all sets are loaded first
  default_config_dir = defined?(::Rails) ? "#{::Rails.root}/#{DEFAULT_RAILS_CONFIG_DIR}" : DEFAULT_RAILS_CONFIG_DIR
  Dir.glob(default_config_dir + "/*.rb").each do |name|
    find(name)
  end
  # Then search them
  @@sets.each_pair do |name,set|
    set = find(name)
    return set[label] if set[label]
  end
  return nil
end

.regenerate_lock_file(name, output_path = nil) ⇒ Object

Regenerate a configuration lock file assocaited with the master configuration file name. Optionally set a custom path for the lock file as output_path, otherwise the lock file path and filename will be based upon the master file with the extension .lock.rb.



63
64
65
66
# File 'lib/amee-data-abstraction/calculation_set.rb', line 63

def self.regenerate_lock_file(name,output_path=nil)
  set = CalculationSet.find(name)
  set.generate_lock_file(output_path)
end

.setsObject

Convenience method for accessing the @@sets class variable



45
46
47
# File 'lib/amee-data-abstraction/calculation_set.rb', line 45

def self.sets
  @@sets
end

Instance Method Details

#[](sym) ⇒ Object

Shorthand method for returning the prototype calculation which is represented by a label matching sym



137
138
139
# File 'lib/amee-data-abstraction/calculation_set.rb', line 137

def [](sym)
  @calculations[sym.to_sym]
end

#all_calculations(options = {}, &dsl_block) ⇒ Object

Append the supplied block to the DSL block of ALL calculations in this calculation set. This is useful for configuration which is required across all calculations (e.g. overriding human readable names or adding globally applicable metadatum)



157
158
159
160
# File 'lib/amee-data-abstraction/calculation_set.rb', line 157

def all_calculations(options={},&dsl_block)
  @all_blocks.push dsl_block
  @all_options.merge(options)
end

#calculation(options = {}, &block) ⇒ Object

Instantiate a PrototypeCalculation within this calculation set, initializing with the supplied DSL block to be evaluated in the context of the newly created calculation



145
146
147
148
149
150
# File 'lib/amee-data-abstraction/calculation_set.rb', line 145

def calculation(options={},&block)
  new_content=PrototypeCalculation.new(options.merge(@all_options),&block)
  @all_blocks.each {|all_block| new_content.instance_eval(&all_block) }
  new_content.name new_content.label.to_s.humanize unless new_content.name
  @calculations[new_content.label]=new_content
end

#calculations_all_usages(apath, options = {}, &dsl_block) ⇒ Object

Instantiate several prototype calculations, by loading each possible usage for the category with path given in apath.

Each instantiated calculation is customised on the basis of the supplied DSL block. The usage is given as a parameter to the DSL block



168
169
170
171
172
173
174
175
176
# File 'lib/amee-data-abstraction/calculation_set.rb', line 168

def calculations_all_usages(apath,options={},&dsl_block)
  dummycalc=PrototypeCalculation.new{path apath}
  dummycalc.amee_usages.each do |usage|
    calculation(options){
      path apath
      instance_exec(usage,&dsl_block)
    }
  end
end

#config_pathObject

Returns the path to the configuration file for self. If a .lock file exists, this takes precedence, otherwise the master config file described by the #file attribute is returned.



182
183
184
# File 'lib/amee-data-abstraction/calculation_set.rb', line 182

def config_path
  lock_file_exists? ? lock_file_path : @file
end

#generate_lock_file(output_path = nil) ⇒ Object

Generates a lock file for the calcuation set configuration. If no argument is provided the, the lock file is generated using the filename and path described by the #lock_file_path method. If a custom output location is required, this can be provided optionally as an argument.



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/amee-data-abstraction/calculation_set.rb', line 203

def generate_lock_file(output_path=nil)
  file = output_path || lock_file_path or raise ArgumentError,
    "No path for lock file known. Either set path for the master config file using the #file accessor method or provide as an argument"
  string = ""
  @calculations.values.each do |prototype_calculation|
    string += "calculation {\n\n"
    string += "  name \"#{prototype_calculation.name}\"\n"
    string += "  label :#{prototype_calculation.label}\n"
    string += "  path \"#{prototype_calculation.path}\"\n\n"
    prototype_calculation.terms.each do |term|
      string += "  #{term.class.to_s.split("::").last.downcase} {\n"
      string += "    name \"#{term.name}\"\n" unless term.name.blank?
      string += "    label :#{term.label}\n" unless term.label.blank?
      string += "    path \"#{term.path}\"\n" unless term.path.blank?
      string += "    value \"#{term.value}\"\n" unless term.value.blank?

      if term.is_a?(AMEE::DataAbstraction::Input)
        string += "    fixed \"#{term.value}\"\n" if term.fixed? && !term.value.blank?
        if term.is_a?(AMEE::DataAbstraction::Drill)
          string += "    choices \"#{term.choices.join('","')}\"\n" if term.instance_variable_defined?("@choices")  && !term.choices.blank?
        elsif term.is_a?(AMEE::DataAbstraction::Profile)
          string += "    choices [\"#{term.choices.join('","')}\"]\n" if term.instance_variable_defined?("@choices")  && !term.choices.blank?
        end
        string += "    optional!\n" if term.optional?
      end

      string += "    default_unit :#{term.default_unit.label}\n" unless term.default_unit.blank?
      string += "    default_per_unit :#{term.default_per_unit.label}\n" unless term.default_per_unit.blank?
      string += "    alternative_units :#{term.alternative_units.map(&:label).join(', :')}\n" unless term.alternative_units.blank?
      string += "    alternative_per_units :#{term.alternative_per_units.map(&:label).join(', :')}\n" unless term.alternative_per_units.blank?
      string += "    unit :#{term.unit.label}\n" unless term.unit.blank?
      string += "    per_unit :#{term.per_unit.label}\n" unless term.per_unit.blank?
      string += "    type :#{term.type}\n" unless term.type.blank?
      string += "    interface :#{term.interface}\n" unless term.interface.blank?
      string += "    note \"#{term.note}\"\n" unless term.note.blank?
      string += "    disable!\n" if !term.is_a?(AMEE::DataAbstraction::Drill) && term.disabled?
      string += "    hide!\n" if term.hidden?
      string += "  }\n\n"
    end
    string += "}\n\n"
  end
  File.open(file,'w') { |f| f.write string }
end

#lock_file_exists?Boolean

Returns true if a configuration lock file exists. Otherwise, returns false.

Returns:

  • (Boolean)


194
195
196
# File 'lib/amee-data-abstraction/calculation_set.rb', line 194

def lock_file_exists?
  File.exists?(lock_file_path)
end

#lock_file_pathObject

Returns the path to the configuration lock file



187
188
189
# File 'lib/amee-data-abstraction/calculation_set.rb', line 187

def lock_file_path
  @file.gsub(".rb",".lock.rb") rescue nil
end