Question-and-Answer Resource for the Building Energy Modeling Community
Get started with the Help page
Ask Your Question

Revision history [back]

Have you looked at the documentation for Design Alternatives for a manual analysis? I think that is what you are looking for. The design alternatives can be run locally or on Amazon EC2.

Have you looked at the documentation for Design Alternatives for a manual analysis? I think that is what you are looking for. The design alternatives can be run locally or on Amazon EC2.

Update: (calling earlier measure argument values from within a measure) @Alex Bennett, I don't think this will fit in comment so I updated my answer.

The following method will loop through all upstream measure arguments, stopping at the first argument matching the requested name. It will then return the value of that measure.

def self.check_upstream_measure_for_arg(runner,arg_name)

# 2.x methods (currently setup for measure display name but snake_case arg names)
arg_name_value = {}
runner.workflow.workflowSteps.each do |step|
  if step.to_MeasureStep.is_initialized
    measure_step = step.to_MeasureStep.get

    measure_name = measure_step.measureDirName
    if measure_step.name.is_initialized
      measure_name = measure_step.name.get # this is instance name in PAT
    end
    if measure_step.result.is_initialized
      result = measure_step.result.get
      result.stepValues.each do |arg|
        name = arg.name
        value = arg.valueAsVariant.to_s
        if name == arg_name
          arg_name_value[:value] = value
          arg_name_value[:measure_name] = measure_name
          return arg_name_value # stop after find first one
        end
      end
    else
      #puts "No result for #{measure_name}"
    end
  else
    #puts "This step is not a measure"
  end
end

return arg_name_value

end

One example is that two or more measures have an argument or a specific 90.1 standards. In our measures this measure is often named "template". I would call this code in each measure to override the user entered value. with the value from the first instance of "template" as a measure argument. So if measures "A,C,X and Y" all called for "template" I would setup "template" as a variable for "A" and add code to "C,X, and Y" to use whatever was used for "A". This code is shown below.

# look at upstream measure for 'template' argument
# todo - in future make template in this measure an optional argument and only override value when it is not initialized. There may be valid use cases for using different template values in different measures within the same workflow.
template_value_from_osw  = OsLib_HelperMethods.check_upstream_measure_for_arg(runner, 'template')
if template_value_from_osw.size > 0
  runner.registerInfo("Replacing argument named 'template' from current measure with a value of #{template_value_from_osw[:value]} from #{template_value_from_osw[:measure_name]}.")
  args['template'] = template_value_from_osw[:value]
end

Another possible use case, if Measure "C" has not been run, or has not been run with specific measure arguments, then don't run measures "X,Y, and Z". While you can't really skip them on the fly, you can add a test at the very beginning of the run section, with a return true within the if statement if the test is true.

For some tests, you wouldn't even need upstream measures. You can directly check the model for building type, size, number of stories, climate zone etc. This gives you a lot of control to minimize variables, and use embedded logic to control the rest of the workflow. This would be good topic for advanced measure writing class.

Have you looked at the documentation for Design Alternatives for a manual analysis? I think that is what you are looking for. The design alternatives can be run locally or on Amazon EC2.

Update: (calling earlier measure argument values from within a measure) @Alex Bennett, I don't think this will fit in comment so I updated my answer.

The following method will loop through all upstream measure arguments, stopping at the first argument matching the requested name. It will then return the value of that measure.

def self.check_upstream_measure_for_arg(runner,arg_name)

# 2.x methods (currently not setup for measure display name but for snake_case arg names)
arg_name_value = {}
runner.workflow.workflowSteps.each do |step|
  if step.to_MeasureStep.is_initialized
    measure_step = step.to_MeasureStep.get

    measure_name = measure_step.measureDirName
    if measure_step.name.is_initialized
      measure_name = measure_step.name.get # this is instance name in PAT
    end
    if measure_step.result.is_initialized
      result = measure_step.result.get
      result.stepValues.each do |arg|
        name = arg.name
        value = arg.valueAsVariant.to_s
        if name == arg_name
          arg_name_value[:value] = value
          arg_name_value[:measure_name] = measure_name
          return arg_name_value # stop after find first one
        end
      end
    else
      #puts "No result for #{measure_name}"
    end
  else
    #puts "This step is not a measure"
  end
end

return arg_name_value

end

One example is that two or more measures have an argument or a specific 90.1 standards. In our measures this measure is often named "template". I would call this code in each measure to override the user entered value. with the value from the first instance of "template" as a measure argument. So if measures "A,C,X and Y" all called for "template" I would setup "template" as a variable for "A" and add code to "C,X, and Y" to use whatever was used for "A". This code is shown below.

# look at upstream measure for 'template' argument
# todo - in future make template in this measure an optional argument and only override value when it is not initialized. There may be valid use cases for using different template values in different measures within the same workflow.
template_value_from_osw  = OsLib_HelperMethods.check_upstream_measure_for_arg(runner, 'template')
if template_value_from_osw.size > 0
  runner.registerInfo("Replacing argument named 'template' from current measure with a value of #{template_value_from_osw[:value]} from #{template_value_from_osw[:measure_name]}.")
  args['template'] = template_value_from_osw[:value]
end

Another possible use case, if Measure "C" has not been run, or has not been run with specific measure arguments, then don't run measures "X,Y, and Z". While you can't really skip them on the fly, you can add a test at the very beginning of the run section, with a return true within the if statement if the test is true.

For some tests, you wouldn't even need upstream measures. You can directly check the model for building type, size, number of stories, climate zone etc. This gives you a lot of control to minimize variables, and use embedded logic to control the rest of the workflow. This would be good topic for advanced measure writing class.