lib/measures/TimeseriesObjectiveFunction/measure.rb in openstudio-calibration-0.8.0 vs lib/measures/TimeseriesObjectiveFunction/measure.rb in openstudio-calibration-0.9.0

- old
+ new

@@ -13,21 +13,21 @@ # start the measure class TimeseriesObjectiveFunction < OpenStudio::Measure::ReportingMeasure # human readable name def name - 'TimeSeries Objective Function' + return 'TimeSeries Objective Function' end # human readable description def description - 'Creates Objective Function from Timeseries Data' + return 'Creates Objective Function from Timeseries Data' end # human readable description of modeling approach def modeler_description - "Creates Objective Function from Timeseries Data. The measure applies a Norm at each timestep between the difference of CSV metered data and SQL model data. A timeseries plot can also be created. Possible outputs are 'cvrmse', 'nmbe', 'simdata' = sum of the simulated data, 'csvdata' = sum of metered data, 'diff' = P Norm between the metered and simulated data if Norm is 1 or 2, else its just the Difference." + return "Creates Objective Function from Timeseries Data. The measure applies a Norm at each timestep between the difference of CSV metered data and SQL model data. A timeseries plot can also be created. Possible outputs are 'cvrmse', 'nmbe', 'simdata' = sum of the simulated data, 'csvdata' = sum of metered data, 'diff' = P Norm between the metered and simulated data if Norm is 1 or 2, else its just the Difference." end # define the arguments that the user will input def arguments(model = nil) args = OpenStudio::Measure::OSArgumentVector.new @@ -69,35 +69,35 @@ csv_var_dn.setDefaultValue('') args << csv_var_dn years = OpenStudio::Measure::OSArgument.makeBoolArgument('year', true) years.setDisplayName('Year in csv data timestamp') - years.setDescription('Is the Year in the csv data timestamp => mm:dd:yy or mm:dd (true/false)') + years.setDescription('Is the Year in the csv data timestamp => mm/dd/yyyy or mm/dd (true/false)') years.setDefaultValue(true) args << years seconds = OpenStudio::Measure::OSArgument.makeBoolArgument('seconds', true) seconds.setDisplayName('Seconds in csv data timestamp') seconds.setDescription('Is the Seconds in the csv data timestamp => hh:mm:ss or hh:mm (true/false)') seconds.setDefaultValue(true) args << seconds sql_key = OpenStudio::Measure::OSArgument.makeStringArgument('key_value', true) - sql_key.setDisplayName('SQL key value') + sql_key.setDisplayName('SQL key value. use no_key if there is no key, i.e. Electricity:Facility') sql_key.setDescription('SQL key value for the SQL query to find the variable in the SQL file') - sql_key.setDefaultValue('') + sql_key.setDefaultValue('no_key') args << sql_key sql_var = OpenStudio::Measure::OSArgument.makeStringArgument('timeseries_name', true) sql_var.setDisplayName('TimeSeries Name') sql_var.setDescription('TimeSeries Name for the SQL query to find the variable in the SQL file') sql_var.setDefaultValue('Facility Total Electric Demand Power') args << sql_var reportfreq_chs = OpenStudio::StringVector.new reportfreq_chs << 'Detailed' - reportfreq_chs << 'Timestep' + reportfreq_chs << 'Zone Timestep' reportfreq_chs << 'Hourly' reportfreq_chs << 'Daily' reportfreq_chs << 'Monthly' reportfreq_chs << 'RunPeriod' reporting_frequency = OpenStudio::Measure::OSArgument.makeChoiceArgument('reporting_frequency', reportfreq_chs, true) @@ -143,11 +143,11 @@ args << plot_flag plot_name = OpenStudio::Measure::OSArgument.makeStringArgument('plot_name', true) plot_name.setDisplayName('Plot name') plot_name.setDescription('Name to include in reporting file name.') - plot_name.setDefaultValue('') + plot_name.setDefaultValue('plot_name') args << plot_name verbose_messages = OpenStudio::Measure::OSArgument.makeBoolArgument('verbose_messages', true) verbose_messages.setDisplayName('verbose_messages') verbose_messages.setDescription('verbose messages. Useful for debugging but MAJOR Performance Hit.') @@ -260,10 +260,15 @@ environment_period = runner.getStringArgumentValue('environment_period', user_arguments) reporting_frequency = runner.getStringArgumentValue('reporting_frequency', user_arguments) convert_data = runner.getStringArgumentValue('convert_data', user_arguments) last_zero = runner.getBoolArgumentValue('add_last_zero_for_plots', user_arguments) first_zero = runner.getBoolArgumentValue('add_first_zero_for_plots', user_arguments) + + # remove leading and trailing double quotes + # windows users can shift + right click a file to copy as path, which has double quotes + csv_name.gsub!('"', '') + @name = plot_name # Method to translate from OpenStudio's time formatting # to Javascript time formatting # OpenStudio time # 2009-May-14 00:10:00 Raw string @@ -336,79 +341,79 @@ envs.each do |env_s| freqs = sql.availableReportingFrequencies(env_s) runner.registerInfo("available EnvPeriod: #{env_s}, available ReportingFrequencies: #{freqs}") freqs.each do |freq| vn = sql.availableVariableNames(env_s, freq.to_s) - runner.registerInfo("available variable names: #{vn}") + runner.registerInfo(" available ReportingFrequency: #{freq}, available variable names: #{vn}") vn.each do |v| kv = sql.availableKeyValues(env_s, freq.to_s, v) - runner.registerInfo("variable names: #{v}") - runner.registerInfo("available key value: #{kv}") + runner.registerInfo(" variable names: #{v}") + runner.registerInfo(" available key value: #{kv}") end end end end runner.registerInfo("year: #{years}") runner.registerInfo("seconds: #{seconds}") if !years && seconds - # mm:dd hh:mm:ss + # mm/dd hh:mm:ss # check day time splits into two valid parts if !csv[1][0].split(' ')[0].nil? && !csv[1][0].split(' ')[1].nil? # check remaining splits are valid if !csv[1][0].split(' ')[0].split('/')[0].nil? && !csv[1][0].split(' ')[0].split('/')[1].nil? && !csv[1][0].split(' ')[1].split(':')[0].nil? && !csv[1][0].split(' ')[1].split(':')[1].nil? && !csv[1][0].split(' ')[1].split(':')[2].nil? - runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm:dd hh:mm:ss") + runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm/dd hh:mm:ss") else - runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm:dd hh:mm:ss") + runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm/dd hh:mm:ss") return false end else - runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm:dd hh:mm:ss") + runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm/dd hh:mm:ss") return false end elsif !years && !seconds - # mm:dd hh:mm + # mm/dd hh:mm # check day time splits into two valid parts if !csv[1][0].split(' ')[0].nil? && !csv[1][0].split(' ')[1].nil? # check remaining splits are valid if !csv[1][0].split(' ')[0].split('/')[0].nil? && !csv[1][0].split(' ')[0].split('/')[1].nil? && !csv[1][0].split(' ')[1].split(':')[0].nil? && !csv[1][0].split(' ')[1].split(':')[1].nil? - runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm:dd hh:mm") + runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm/dd hh:mm") else - runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm:dd hh:mm") + runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm/dd hh:mm") return false end else - runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm:dd hh:mm") + runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm/dd hh:mm") return false end elsif years && !seconds - # mm:dd:yy hh:mm + # mm/dd/yyyy hh:mm # check day time splits into two valid parts if !csv[1][0].split(' ')[0].nil? && !csv[1][0].split(' ')[1].nil? # check remaining splits are valid if !csv[1][0].split(' ')[0].split('/')[0].nil? && !csv[1][0].split(' ')[0].split('/')[1].nil? && !csv[1][0].split(' ')[0].split('/')[2].nil? && !csv[1][0].split(' ')[1].split(':')[0].nil? && !csv[1][0].split(' ')[1].split(':')[1].nil? - runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm:dd:yy hh:mm") + runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm/dd/yyyy hh:mm") else - runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm:dd:yy hh:mm") + runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm/dd/yyyy hh:mm") return false end else - runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm:dd:yy hh:mm") + runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm/dd/yyyy hh:mm") return false end elsif years && seconds - # mm:dd:yy hh:mm:ss + # mm/dd/yyyy hh:mm:ss # check day time splits into two valid parts if !csv[1][0].split(' ')[0].nil? && !csv[1][0].split(' ')[1].nil? # check remaining splits are valid if !csv[1][0].split(' ')[0].split('/')[0].nil? && !csv[1][0].split(' ')[0].split('/')[1].nil? && !csv[1][0].split(' ')[0].split('/')[2].nil? && !csv[1][0].split(' ')[1].split(':')[0].nil? && !csv[1][0].split(' ')[1].split(':')[1].nil? && !csv[1][0].split(' ')[1].split(':')[2].nil? - runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm:dd:yy hh:mm:ss") + runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm/dd/yyyy hh:mm:ss") else - runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm:dd:yy hh:mm:ss") + runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm/dd/yyyy hh:mm:ss") return false end else - runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm:dd:yy hh:mm:ss") + runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm/dd/yyyy hh:mm:ss") return false end end temp_sim = [] @@ -509,13 +514,11 @@ min = csv[row][0].split(' ')[1].split(':')[1].to_i sec = csv[row][0].split(' ')[1].split(':')[2]&.to_i if year.nil? dat = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(cal[mon]), day) else - # dat = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(cal[mon]),day,year) - # hack since year is not in the sql file correctly - dat = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(cal[mon]), day) + dat = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(cal[mon]),day,year) end tim = if sec.nil? OpenStudio::Time.new(0, hou, min, 0) else OpenStudio::Time.new(0, hou, min, sec) @@ -627,11 +630,11 @@ series2['cvrmse'] = cvrmse.round(6) series2['nmbe'] = nmbe.round(6) if algorithm_download require 'csv' - CSV.open("timeseries#{plot_name}.csv", 'wb') do |csv| + CSV.open("timeseries_#{plot_name}.csv", 'wb') do |csv| csv << ['Simulation Time', 'Simulated Value', 'Metered time', 'Metered Value'] data.size.times do |i| csv << [data[i]['time'], data[i]['y'], data2[i]['time'], data2[i]['y']] end end @@ -656,10 +659,10 @@ runner.registerInfo("Copying timeseries_#{csv_var}.json to downloads directory") directory_name = File.expand_path(File.join(Dir.pwd, '../../../downloads')) Dir.mkdir(directory_name) unless File.exist?(directory_name) FileUtils.cp("timeseries_#{csv_var}.json", directory_name) FileUtils.cp("allseries_#{csv_var}.json", directory_name) - FileUtils.cp("timeseries#{plot_name}.csv", directory_name) + FileUtils.cp("timeseries_#{plot_name}.csv", directory_name) end end diff = Math.sqrt(diff) if norm == 2 runner.registerInfo("results: #{results}") if verbose_messages