diff --git a/Dockerfile b/Dockerfile index 4e7a0a3ab..c646637d5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -158,7 +158,6 @@ RUN echo "Running in testing environment - Installing Firefox and Gecko Driver" COPY /docker/server/run-server-tests.sh /usr/local/bin/run-server-tests RUN chmod +x /usr/local/bin/run-server-tests - # Test adding the git repo to the container for coveralls # The #TEST# will be removed in the travis test script to be run in the test container #TEST#COPY .git /opt/openstudio/.git diff --git a/docker/R/lib/sobol.R b/docker/R/lib/sobol.R index e03dac787..1958b0ce7 100644 --- a/docker/R/lib/sobol.R +++ b/docker/R/lib/sobol.R @@ -155,6 +155,7 @@ for (i in 1:ncol(vars)){ } if(!all(boundary_check)){ print('SOLUTION SPACE OUT OF BOUNDS, CHECK Grid Jump and Level Values and/or re-run') + print(paste("boundary_check:",boundary_check)) stop(options("show.error.messages"=TRUE),"SOLUTION SPACE OUT OF BOUNDS, CHECK Grid Jump and Level Values and/or re-run") } print("bounds are satisfied, continuing...") diff --git a/local_setup_scripts/docker-compose.yml b/local_setup_scripts/docker-compose.yml index df45f28f1..a2932f249 100644 --- a/local_setup_scripts/docker-compose.yml +++ b/local_setup_scripts/docker-compose.yml @@ -42,6 +42,7 @@ services: - REDIS_URL=redis://:openstudio@queue:6379 - MONGO_USER=openstudio - MONGO_PASSWORD=openstudio + - SECRET_KEY_BASE=c4ab6d293e4bf52ee92e8dda6e16dc9b5448d0c5f7908ee40c66736d515f3c29142d905b283d73e5e9cef6b13cd8e38be6fd3b5e25d00f35b259923a86c7c473 volumes: - osdata:/mnt/openstudio depends_on: @@ -63,6 +64,7 @@ services: - REDIS_URL=redis://:openstudio@queue:6379 - MONGO_USER=openstudio - MONGO_PASSWORD=openstudio + - SECRET_KEY_BASE=c4ab6d293e4bf52ee92e8dda6e16dc9b5448d0c5f7908ee40c66736d515f3c29142d905b283d73e5e9cef6b13cd8e38be6fd3b5e25d00f35b259923a86c7c473 volumes: - osdata:/mnt/openstudio depends_on: @@ -86,6 +88,7 @@ services: - REDIS_URL=redis://:openstudio@queue:6379 - MONGO_USER=openstudio - MONGO_PASSWORD=openstudio + - SECRET_KEY_BASE=c4ab6d293e4bf52ee92e8dda6e16dc9b5448d0c5f7908ee40c66736d515f3c29142d905b283d73e5e9cef6b13cd8e38be6fd3b5e25d00f35b259923a86c7c473 volumes: - /mnt/openstudio depends_on: @@ -120,6 +123,7 @@ services: - REDIS_URL=redis://:openstudio@queue:6379 - MONGO_USER=openstudio - MONGO_PASSWORD=openstudio + - SECRET_KEY_BASE=c4ab6d293e4bf52ee92e8dda6e16dc9b5448d0c5f7908ee40c66736d515f3c29142d905b283d73e5e9cef6b13cd8e38be6fd3b5e25d00f35b259923a86c7c473 volumes: osdata: external: true diff --git a/local_setup_scripts/rebuild_sr.sh b/local_setup_scripts/rebuild_sr.sh index fd8672160..8a0c6ce63 100755 --- a/local_setup_scripts/rebuild_sr.sh +++ b/local_setup_scripts/rebuild_sr.sh @@ -5,8 +5,8 @@ while [ $(docker ps -q | wc -l) != 1 ]; do sleep 5; done sleep 5 docker volume rm -f osdata || true docker volume rm -f dbdata || true -#docker image rm 127.0.0.1:5000/openstudio-server -f -docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.1.0 +docker image rm 127.0.0.1:5000/openstudio-server -f +docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.2.0 docker push 127.0.0.1:5000/openstudio-server cd docker/R/ #docker image rm 127.0.0.1:5000/openstudio-rserve -f diff --git a/local_setup_scripts/win64/docker-compose.yml b/local_setup_scripts/win64/docker-compose.yml index 964098f84..831ae15f8 100644 --- a/local_setup_scripts/win64/docker-compose.yml +++ b/local_setup_scripts/win64/docker-compose.yml @@ -36,6 +36,7 @@ services: - REDIS_URL=redis://:openstudio@queue:6379 - MONGO_USER=openstudio - MONGO_PASSWORD=openstudio + - SECRET_KEY_BASE=c4ab6d293e4bf52ee92e8dda6e16dc9b5448d0c5f7908ee40c66736d515f3c29142d905b283d73e5e9cef6b13cd8e38be6fd3b5e25d00f35b259923a86c7c473 volumes: - osdata:/mnt/openstudio depends_on: @@ -54,6 +55,7 @@ services: - REDIS_URL=redis://:openstudio@queue:6379 - MONGO_USER=openstudio - MONGO_PASSWORD=openstudio + - SECRET_KEY_BASE=c4ab6d293e4bf52ee92e8dda6e16dc9b5448d0c5f7908ee40c66736d515f3c29142d905b283d73e5e9cef6b13cd8e38be6fd3b5e25d00f35b259923a86c7c473 volumes: - osdata:/mnt/openstudio depends_on: @@ -74,6 +76,7 @@ services: - REDIS_URL=redis://:openstudio@queue:6379 - MONGO_USER=openstudio - MONGO_PASSWORD=openstudio + - SECRET_KEY_BASE=c4ab6d293e4bf52ee92e8dda6e16dc9b5448d0c5f7908ee40c66736d515f3c29142d905b283d73e5e9cef6b13cd8e38be6fd3b5e25d00f35b259923a86c7c473 volumes: - /mnt/openstudio depends_on: @@ -102,6 +105,7 @@ services: - REDIS_URL=redis://:openstudio@queue:6379 - MONGO_USER=openstudio - MONGO_PASSWORD=openstudio + - SECRET_KEY_BASE=c4ab6d293e4bf52ee92e8dda6e16dc9b5448d0c5f7908ee40c66736d515f3c29142d905b283d73e5e9cef6b13cd8e38be6fd3b5e25d00f35b259923a86c7c473 volumes: osdata: external: true diff --git a/local_setup_scripts/win64/rebuild_sr.sh b/local_setup_scripts/win64/rebuild_sr.sh index 2d504e0b0..e26acc558 100644 --- a/local_setup_scripts/win64/rebuild_sr.sh +++ b/local_setup_scripts/win64/rebuild_sr.sh @@ -6,7 +6,7 @@ sleep 5 docker volume rm -f osdata || true docker volume rm -f dbdata || true docker image rm 127.0.0.1:5000/openstudio-server -f -docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.1.0 +docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.2.0 docker push 127.0.0.1:5000/openstudio-server cd docker/R #docker image rm 127.0.0.1:5000/openstudio-rserve -f diff --git a/local_setup_scripts/win64/rebuild_sr_no_rm.sh b/local_setup_scripts/win64/rebuild_sr_no_rm.sh index d1520ebfa..359382a1d 100644 --- a/local_setup_scripts/win64/rebuild_sr_no_rm.sh +++ b/local_setup_scripts/win64/rebuild_sr_no_rm.sh @@ -6,7 +6,7 @@ sleep 5 docker volume rm -f osdata || true docker volume rm -f dbdata || true #docker image rm 127.0.0.1:5000/openstudio-server -f -docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.1.0 +docker build . -t="127.0.0.1:5000/openstudio-server" --build-arg OPENSTUDIO_VERSION=3.2.0 docker push 127.0.0.1:5000/openstudio-server cd docker/R #docker image rm 127.0.0.1:5000/openstudio-rserve -f diff --git a/server/Gemfile b/server/Gemfile index 5901be548..25a58dcb3 100644 --- a/server/Gemfile +++ b/server/Gemfile @@ -67,19 +67,16 @@ gem 'sassc', '~> 2.4.0' ## Commonly update gems for testing and development gem 'openstudio-workflow', '= 2.2.0' - #gem 'openstudio-analysis', :github => 'NREL/OpenStudio-analysis-gem', :ref => '270' gem 'openstudio-analysis', '= 1.2.0' gem 'urbanopt-cli', '= 0.6.0' -gem 'urbanopt-reporting', '= 0.4.0' - +gem 'urbanopt-reopt', '= 0.6.0' ## End commonly updated gems gem 'openstudio-aws' - # libxml 3.2.0 failing on windows gem 'bson', '~> 4.12.0' # bson 4.6.0 requires ruby >= 2.3.0 #gem 'libxml-ruby' @@ -93,9 +90,9 @@ gem 'rubyXL', '~> 3.4.17' # linux based js runtime libraries if RUBY_PLATFORM =~ /linux/ - gem 'execjs' - gem 'libv8' - gem 'therubyracer' + gem 'execjs', '=2.7.0' + gem 'libv8', '=3.16.14.19' + gem 'therubyracer', '=0.12.3' elsif RUBY_PLATFORM =~ /darwin/ gem 'execjs', github: 'NREL/execjs' end diff --git a/server/app/jobs/dj_jobs/run_simulate_data_point.rb b/server/app/jobs/dj_jobs/run_simulate_data_point.rb index be0c8f21e..55837f7cd 100644 --- a/server/app/jobs/dj_jobs/run_simulate_data_point.rb +++ b/server/app/jobs/dj_jobs/run_simulate_data_point.rb @@ -254,14 +254,20 @@ def perform @sim_logger.error "Workflow #{osw_path} failed with error #{e}" run_result = :errored ensure - if uo_simulation_log + if (!uo_simulation_log.nil? && File.exist?(uo_simulation_log)) @sim_logger.info "UrbanOpt simulation output: #{File.read(uo_simulation_log)}" + else + @sim_logger.warn "UrbanOpt simulation output: #{uo_simulation_log} does not exist" end - if uo_process_log + if (!uo_process_log.nil? && File.exist?(uo_process_log)) @sim_logger.info "UrbanOpt process output: #{File.read(uo_process_log)}" + else + @sim_logger.warn "UrbanOpt process output: #{uo_process_log} does not exist" end - if process_log + if (!process_log.nil? && File.exist?(process_log)) @sim_logger.info "Oscli output: #{File.read(process_log)}" + else + @sim_logger.warn "OSCLI output: #{process_log} does not exist" end #docker_log = File.join(APP_CONFIG['rails_log_path'], 'docker.log') #if File.exist? docker_log diff --git a/server/app/jobs/dj_jobs/urban_opt.rb b/server/app/jobs/dj_jobs/urban_opt.rb index b6dfe7c8f..db680e33a 100644 --- a/server/app/jobs/dj_jobs/urban_opt.rb +++ b/server/app/jobs/dj_jobs/urban_opt.rb @@ -104,7 +104,24 @@ def run_urbanopt(uo_simulation_log, uo_process_log) if !File.exist?(feature_file) raise "feature_file does not exist: #{feature_file}" end + scenario_file_override = "#{simulation_dir}/urbanopt/scenario_file_override.json" scenario_file = "#{simulation_dir}/urbanopt/#{@data_point.analysis.scenario_file}.csv" + #check if scenario_file_override exists + if File.exist?(scenario_file_override) + @sim_logger.info "found scenario_file_override.json file, parsing" + #parse file and look for scenario file + scenario_parse = JSON.parse(File.read(scenario_file_override), symbolize_names: true) + if scenario_parse['scenario_file'.to_sym] + if File.exist?("#{simulation_dir}/urbanopt/#{scenario_parse['scenario_file'.to_sym]}.csv") + @sim_logger.info "replacing scenario_file with #{simulation_dir}/urbanopt/#{scenario_parse['scenario_file'.to_sym]}.csv" + scenario_file = "#{simulation_dir}/urbanopt/#{scenario_parse['scenario_file'.to_sym]}.csv" + @sim_logger.info "updating analysis model @data_point.analysis.scenario_file: #{@data_point.analysis.scenario_file} to #{scenario_parse['scenario_file'.to_sym]}" + @data_point.analysis.scenario_file = scenario_parse['scenario_file'.to_sym] + end + else + raise ":scenario_file does not exist in: #{scenario_file_override}" + end + end if !File.exist?(scenario_file) raise "scenario_file does not exist: #{scenario_file}" end @@ -121,8 +138,61 @@ def run_urbanopt(uo_simulation_log, uo_process_log) raise "UrbanOpt run returned error code #{$?.exitstatus}" end - #run uo-cli process - cmd = "uo process --default --feature #{feature_file} --scenario #{scenario_file}" + #check run_status.json + run_status_json = "#{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file.downcase}/run_status.json" + @sim_logger.info "run_status_json location: #{run_status_json}" + if File.exist?(run_status_json) + run_status_result = JSON.parse(File.read(run_status_json), symbolize_names: true) + if !run_status_result[:results].nil? + if run_status_result[:results].any?{|hash| hash[:status] == 'Failed'} + @sim_logger.error "run_status.json has failures: #{run_status_result}" + raise "run_status.json has failures: #{run_status_result}" + else + @sim_logger.info "run_status_json no Failed: #{run_status_result}" + end + else + @sim_logger.error "run_status.json does not have results: #{run_status_result}" + raise "run_status.json does not have results: #{run_status_result}" + end + else + @sim_logger.error "run_status.json does not exist at: #{run_status_json}" + raise "run_status.json does not exist at: #{run_status_json}" + end + + #run uo-cli process + @sim_logger.info "Run ReOpt is: #{@data_point.analysis.reopt}" + if @data_point.analysis.reopt + #check for API key + #check ENV GEM_DEVELOPER_KEY + if !ENV['GEM_DEVELOPER_KEY'].nil? && !ENV['GEM_DEVELOPER_KEY'].empty? + @sim_logger.info "GEM_DEVELOPER_KEY is not empty" + #check reopt_key.txt file + elsif File.exist?("#{simulation_dir}/urbanopt/reopt_key.json") + @sim_logger.info "reopt_key.json is found" + key_json = JSON.parse(File.read("#{simulation_dir}/urbanopt/reopt_key.json"), symbolize_names: true) + ENV['GEM_DEVELOPER_KEY'] = key_json[:GEM_DEVELOPER_KEY] + if !ENV['GEM_DEVELOPER_KEY'].empty? + @sim_logger.info "GEM_DEVELOPER_KEY is not empty after reading reopt_key.json" + else + @sim_logger.error "GEM_DEVELOPER_KEY is empty after reading reopt_key.json" + raise "GEM_DEVELOPER_KEY is empty after reading reopt_key.json" + end + else + @sim_logger.error "reopt_key.json is NOT found and ENV not set" + raise "reopt_key.txt is NOT found and ENV not set" + end + + reopt_type = @data_point.analysis.reopt_type + @sim_logger.info "reopt_type is: #{reopt_type}" + if ['scenario', 'feature'].include?(reopt_type) + cmd = "uo process --reopt-#{reopt_type} --feature #{feature_file} --scenario #{scenario_file}" + else + @sim_logger.error "reopt_type is not scenario or feature its: #{reopt_type}" + raise "reopt_type is not scenario or feature its: #{reopt_type}" + end + else + cmd = "uo process --default --feature #{feature_file} --scenario #{scenario_file}" + end #uo_process_log = File.join(simulation_dir, 'urbanopt_process.log') @sim_logger.info "Running UrbanOpt workflow using cmd #{cmd} and writing log to #{uo_process_log}" pid = Process.spawn(cmd, [:err, :out] => [uo_process_log, 'w']) @@ -131,7 +201,8 @@ def run_urbanopt(uo_simulation_log, uo_process_log) end if $?.exitstatus != 0 - raise "UrbanOpt process returned error code #{$?.exitstatus}" + #raise "UrbanOpt process returned error code #{$?.exitstatus}" + @sim_logger.error "UrbanOpt process returned error code #{$?.exitstatus}" end #Run OSSCLI --postprocess_only to run reporting measures in UrbanOpt workflow if ReportingMeasure's are present in workflow @sim_logger.info "@data_point.analysis.problem['workflow'].empty?: #{@data_point.analysis.problem['workflow'].empty?}" @@ -173,10 +244,21 @@ def run_urbanopt(uo_simulation_log, uo_process_log) #uo_results[:feature_reports][0][:reporting_periods][0][:natural_gas] # # Save the objective functions + analysis = Analysis.find(@data_point.analysis.id) + objs = analysis.variables.where(objective_function: true) + #if objs + # objs.each do |variable| if @data_point.analysis.output_variables @data_point.analysis.output_variables.each do |variable| + @sim_logger.info "VARIABLE: #{variable}" uo_result = {} report_index = nil + reports_file = variable[:report_file] + @sim_logger.info "reports_file: #{reports_file} :#{variable[:report_file]}" + if reports_file.nil? + @sim_logger.error "reports_file is missing from output_variable: #{variable[:name]}." + raise "reports_file is missing from output_variable: #{variable[:name]}" + end if variable[:objective_function] @sim_logger.info "found variable[:objective_function]: #{variable[:objective_function]}" if variable[:report] == 'feature_reports' @@ -184,7 +266,7 @@ def run_urbanopt(uo_simulation_log, uo_process_log) if variable[:report_id] && variable[:reporting_periods] && variable[:var_name] @sim_logger.info "found variable[:report_id]:#{variable[:report_id]}, variable[:reporting_periods]:#{variable[:reporting_periods]}, variable[:var_name]: #{variable[:var_name]}." #get feature_reports results - uo_results_file = "#{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file}/default_scenario_report.json" + uo_results_file = "#{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file.downcase}/#{reports_file}.json" if File.exist? uo_results_file uo_result = JSON.parse(File.read(uo_results_file), symbolize_names: true) report_index = uo_result[variable[:report].to_sym].index {|h| h[:id] == variable[:report_id].to_s } if uo_result[variable[:report].to_sym] @@ -195,7 +277,9 @@ def run_urbanopt(uo_simulation_log, uo_process_log) if variable[:var_name] == "end_uses" #check end_uses and category exist if variable[:end_use] && variable[:end_use_category] && uo_result[variable[:report].to_sym][report_index][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym].has_key?(variable[:end_use].to_sym) if variable[:end_use] && variable[:end_use_category] && uo_result[variable[:report].to_sym][report_index][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym][variable[:end_use].to_sym].has_key?(variable[:end_use_category].to_sym) - results[variable[:name].split(".")[0]] = { "#{variable[:end_use]}_#{variable[:end_use_category]}".to_sym => uo_result[variable[:report].to_sym][report_index][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym][variable[:end_use].to_sym][variable[:end_use_category].to_sym], "applicable" => true } + results[variable[:name].split(/\./)[0].to_sym] = {} + results[variable[:name].split(/\./)[0].to_sym]["#{variable[:end_use]}_#{variable[:end_use_category]}".to_sym] = uo_result[variable[:report].to_sym][report_index][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym][variable[:end_use].to_sym][variable[:end_use_category].to_sym] + results[variable[:name].split(/\./)[0].to_sym][:applicable] = true else raise "MISSING output variable[:end_use_category]:#{variable[:end_use_category]}, when output variable[:var_name]:#{variable[:var_name]}, output variable[:end_use]:#{variable[:end_use]}" @sim_logger.error "MISSING output variable[:end_use_category]:#{variable[:end_use_category]}, when output variable[:var_name]:#{variable[:var_name]}, output variable[:end_use]:#{variable[:end_use]}" @@ -205,7 +289,9 @@ def run_urbanopt(uo_simulation_log, uo_process_log) @sim_logger.error "MISSING output variable[:end_use]:#{variable[:end_use]}, when output variable[:var_name]:#{variable[:var_name]}" end else #not end_uses - results[variable[:name].split(".")[0]] = { variable[:var_name].to_sym => uo_result[variable[:report].to_sym][report_index][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym], "applicable" => true } + results[variable[:name].split(/\./)[0].to_sym] = {} + results[variable[:name].split(/\./)[0].to_sym][variable[:var_name].to_sym] = uo_result[variable[:report].to_sym][report_index][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym] + results[variable[:name].split(/\./)[0].to_sym][:applicable] = true end else raise "Could not find output variable[:var_name]: #{variable[:var_name]} in reporting period: #{variable[:reporting_periods]}." @@ -220,8 +306,8 @@ def run_urbanopt(uo_simulation_log, uo_process_log) @sim_logger.error "Could not find the index for report id: #{variable[:report_id]} for report: #{variable[:report]}." end else - raise "Could not find results #{uo_results_file}" - @sim_logger.error "Could not find results #{uo_results_file}" + raise "Could not find results file: #{uo_results_file}" + @sim_logger.error "Could not find results file: #{uo_results_file}" end else raise "MISSING output variable[:report_id]:#{variable[:report_id]}, variable[:reporting_periods]:#{variable[:reporting_periods]}, variable[:var_name]: #{variable[:var_name]}." @@ -229,10 +315,10 @@ def run_urbanopt(uo_simulation_log, uo_process_log) end elsif variable[:report] == 'scenario_report' @sim_logger.info "found variable[:report]: #{variable[:report]}" - if variable[:reporting_periods] && variable[:var_name] + if (variable[:reporting_periods] && variable[:var_name]) @sim_logger.info "found variable[:reporting_periods]:#{variable[:reporting_periods]}, variable[:var_name]: #{variable[:var_name]}." - #get feature_reports results - uo_results_file = "#{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file}/default_scenario_report.json" + #get scenario_report results + uo_results_file = "#{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file.downcase}/#{reports_file}.json" if File.exist? uo_results_file uo_result = JSON.parse(File.read(uo_results_file), symbolize_names: true) if !uo_result[variable[:report].to_sym][:reporting_periods][variable[:reporting_periods]].nil? #reporting_periods exist @@ -241,7 +327,10 @@ def run_urbanopt(uo_simulation_log, uo_process_log) if variable[:var_name] == "end_uses" if variable[:end_use] && variable[:end_use_category] && uo_result[variable[:report].to_sym][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym].has_key?(variable[:end_use].to_sym) if variable[:end_use] && variable[:end_use_category] && uo_result[variable[:report].to_sym][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym][variable[:end_use].to_sym].has_key?(variable[:end_use_category].to_sym) - results[variable[:name].split(".")[0]] = { "#{variable[:end_use]}_#{variable[:end_use_category]}".to_sym => uo_result[variable[:report].to_sym][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym][variable[:end_use].to_sym][variable[:end_use_category].to_sym], "applicable" => true } + @sim_logger.info "setting results keys: #{variable[:name].split(/\./)[0]} AND: #{variable[:end_use]}_#{variable[:end_use_category]}" + results[variable[:name].split(/\./)[0].to_sym] = {} + results[variable[:name].split(/\./)[0].to_sym]["#{variable[:end_use]}_#{variable[:end_use_category]}".to_sym] = uo_result[variable[:report].to_sym][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym][variable[:end_use].to_sym][variable[:end_use_category].to_sym] + results[variable[:name].split(/\./)[0].to_sym][:applicable] = true else raise "MISSING output variable[:end_use_category]:#{variable[:end_use_category]}, when output variable[:var_name]:#{variable[:var_name]}, output variable[:end_use]:#{variable[:end_use]}" @sim_logger.error "MISSING output variable[:end_use_category]:#{variable[:end_use_category]}, when output variable[:var_name]:#{variable[:var_name]}, output variable[:end_use]:#{variable[:end_use]}" @@ -250,8 +339,22 @@ def run_urbanopt(uo_simulation_log, uo_process_log) raise "MISSING output variable[:end_use]:#{variable[:end_use]}, when output variable[:var_name]:#{variable[:var_name]}" @sim_logger.error "MISSING output variable[:end_use]:#{variable[:end_use]}, when output variable[:var_name]:#{variable[:var_name]}" end - else #not end_uses - results[variable[:name].split(".")[0]] = { variable[:var_name].to_sym => uo_result[variable[:report].to_sym][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym], "applicable" => true } + #check for comfort_result + elsif variable[:var_name] == "comfort_result" + if variable[:comfort_result_category] && uo_result[variable[:report].to_sym][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym].has_key?(variable[:comfort_result_category].to_sym) + @sim_logger.info "setting comfort_results keys: #{variable[:name].split(/\./)[0]} AND: #{variable[:var_name]}_#{variable[:comfort_result_category]}" + results[variable[:name].split(/\./)[0].to_sym] = {} + results[variable[:name].split(/\./)[0].to_sym]["#{variable[:var_name]}_#{variable[:comfort_result_category]}".to_sym] = uo_result[variable[:report].to_sym][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym][variable[:comfort_result_category].to_sym] + results[variable[:name].split(/\./)[0].to_sym][:applicable] = true + else + raise "MISSING output variable[:comfort_result_category]:#{variable[:comfort_result_category]}, when output variable[:var_name]:#{variable[:var_name]}" + @sim_logger.error "MISSING output variable[:comfort_result_category]:#{variable[:comfort_result_category]}, when output variable[:var_name]:#{variable[:var_name]}" + end + #not end_uses + else + results[variable[:name].split(/\./)[0].to_sym] = {} + results[variable[:name].split(/\./)[0].to_sym][variable[:var_name].to_sym] = uo_result[variable[:report].to_sym][:reporting_periods][variable[:reporting_periods]][variable[:var_name].to_sym] + results[variable[:name].split(/\./)[0].to_sym][:applicable] = true end else raise "Could not find output variable[:var_name]: #{variable[:var_name]} in reporting period: #{variable[:reporting_periods]}." @@ -262,27 +365,111 @@ def run_urbanopt(uo_simulation_log, uo_process_log) @sim_logger.error "Could not find output reporting period: #{variable[:reporting_periods]}." end else - raise "Could not find results #{uo_results_file}" - @sim_logger.error "Could not find results #{uo_results_file}" + raise "Could not find results file: #{uo_results_file}" + @sim_logger.error "Could not find results file: #{uo_results_file}" + end + #no reporting_period + elsif variable[:var_name] #TODO add check on distributed_generation_category + @sim_logger.info "found variable[:var_name]: #{variable[:var_name]} with NO REPORTING_PERIODS." + #get scenario_report results + #scenario_optimization.json + uo_results_file = "#{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file.downcase}/#{reports_file}.json" + if File.exist? uo_results_file + uo_result = JSON.parse(File.read(uo_results_file), symbolize_names: true) + + if uo_result[variable[:report].to_sym].has_key?(variable[:var_name].to_sym) # has var_name? + + if variable[:distributed_generation_category] && uo_result[variable[:report].to_sym][variable[:var_name].to_sym].has_key?(variable[:distributed_generation_category].to_sym) + @sim_logger.info "setting results keys: #{variable[:name].split(/\./)[0]} AND: #{variable[:var_name]}_#{variable[:distributed_generation_category]}" + results[variable[:name].split(/\./)[0].to_sym] = {} + results[variable[:name].split(/\./)[0].to_sym]["#{variable[:var_name]}_#{variable[:distributed_generation_category]}".to_sym] = uo_result[variable[:report].to_sym][variable[:var_name].to_sym][variable[:distributed_generation_category].to_sym] + results[variable[:name].split(/\./)[0].to_sym][:applicable] = true + else + raise "MISSING output variable[:distributed_generation_category]:#{variable[:distributed_generation_category]}, when output variable[:var_name]:#{variable[:var_name]}" + @sim_logger.error "MISSING output variable[:distributed_generation_category]:#{variable[:distributed_generation_category]}, when output variable[:var_name]:#{variable[:var_name]}" + end + + + else + raise "Could not find output variable[:var_name]: #{variable[:var_name]}." + @sim_logger.error "Could not find output variable[:var_name]: #{variable[:var_name]}." + end + + else + raise "Could not find results file: #{uo_results_file}" + @sim_logger.error "Could not find results file: #{uo_results_file}" end else raise "MISSING output variable[:reporting_periods]:#{variable[:reporting_periods]}, variable[:var_name]: #{variable[:var_name]}." @sim_logger.error "MISSING output variable[:reporting_periods]:#{variable[:reporting_periods]}, variable[:var_name]: #{variable[:var_name]}." end + elsif variable[:report] == 'reopt_report' + @sim_logger.info "found variable[:report]: #{variable[:report]}" + if variable[:reopt_category] && variable[:var_name] + @sim_logger.info "found variable[:reopt_category]:#{variable[:reopt_category]}, variable[:var_name]: #{variable[:var_name]}." + #get scenario_report results + uo_results_file = "#{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file.downcase}/reopt/scenario_report_#{@data_point.analysis.scenario_file.downcase}_reopt_run.json" + if File.exist? uo_results_file + @sim_logger.info "found REopt output json file" + uo_result = JSON.parse(File.read(uo_results_file), symbolize_names: true) + if uo_result[0].nil? #this checks if reopt json is formatted correctly + if !uo_result[:outputs][:Scenario][:Site][variable[:reopt_category].to_sym].nil? #reopt_category exist + if uo_result[:outputs][:Scenario][:Site][variable[:reopt_category].to_sym].has_key?(variable[:var_name].to_sym) #reopt_category has var_name? + if !uo_result[:outputs][:Scenario][:Site][variable[:reopt_category].to_sym][variable[:var_name].to_sym].nil? + results[variable[:name].split(/\./)[0].to_sym] = {} + results[variable[:name].split(/\./)[0].to_sym][variable[:var_name].to_sym] = uo_result[:outputs][:Scenario][:Site][variable[:reopt_category].to_sym][variable[:var_name].to_sym] + results[variable[:name].split(/\./)[0].to_sym][:applicable] = true + @sim_logger.info "setting results to: #{uo_result[:outputs][:Scenario][:Site][variable[:reopt_category].to_sym][variable[:var_name].to_sym]}" + else + results[variable[:name].split(/\./)[0].to_sym] = {} + results[variable[:name].split(/\./)[0].to_sym][variable[:var_name].to_sym] = @data_point.analysis.problem['algorithm']['failed_f_value'] + results[variable[:name].split(/\./)[0].to_sym][:applicable] = true + @sim_logger.error "setting results to FAILED_F_VALUE: #{@data_point.analysis.problem['algorithm']['failed_f_value']}" + end + else + raise "Could not find output variable[:var_name]: #{variable[:var_name]} in reopt_category: #{variable[:reopt_category]}." + @sim_logger.error "Could not find output variable[:var_name]: #{variable[:var_name]} in reopt_category: #{variable[:reopt_category]}." + end + else + raise "Could not find output reopt_category: #{variable[:reopt_category]}." + @sim_logger.error "Could not find output reopt_category: #{variable[:reopt_category]}." + end + else + @sim_logger.error "REopt Error: #{uo_result}." + results[variable[:name].split(/\./)[0].to_sym] = {} + results[variable[:name].split(/\./)[0].to_sym][variable[:var_name].to_sym] = @data_point.analysis.problem['algorithm']['failed_f_value'] + results[variable[:name].split(/\./)[0].to_sym][:applicable] = true + end + else + #raise "Could not find results file: #{uo_results_file}" + @sim_logger.error "Could not find results file: #{uo_results_file}" + end + else + raise "MISSING output variable[:reopt_category]:#{variable[:reopt_category]}, variable[:var_name]: #{variable[:var_name]}." + @sim_logger.error "MISSING output variable[:reopt_category]:#{variable[:reopt_category]}, variable[:var_name]: #{variable[:var_name]}." + end + #not feature_report, scenario_report or reopt_report else - raise "output variable '#{variable[:name]}' :report is not scenario_report or feature_reports. :report = '#{variable[:report]}'." - @sim_logger.error "output variable '#{variable[:name]}' :report is not scenario_report or feature_reports. :report = '#{variable[:report]}'." + raise "output variable '#{variable[:name]}' :report is not scenario_report or feature_reports or reopt_report. :report = '#{variable[:report]}'." + @sim_logger.error "output variable '#{variable[:name]}' :report is not scenario_report or feature_reports or reopt_report. :report = '#{variable[:report]}'." end @sim_logger.info "Looking in output variable #{variable[:name]} for objective function [#{variable[:report]}][#{variable[:report_id]}]{#{variable[:reporting_periods]}}[#{variable[:var_name]}]" # look for the objective function key and make sure that it is not nil. False is an okay obj function. + # this is similiar code to whats in workflow-gem but not called because of non-OS workflow. # check if "#{variable[:end_use]}_#{variable[:end_use_category]}" == variable[:name] somewhere?? -BLB - # results = {:"ffce3f6b-023a-46ab-89f2-4f8c692719dd"=>{:electricity=>39869197.34679705, :applicable=>true},:'uuid'...} - if !results[variable[:name].split(".")[0]].nil? && !results[variable[:name].split(".")[0]][variable[:name].split(".")[1].to_sym].nil? - #objective_functions["objective_function_#{variable[:objective_function_index] + 1}"] = results[variable[:name].split(".")[0]][variable[:var_name].to_sym] #no end_uses - objective_functions["objective_function_#{variable[:objective_function_index] + 1}"] = results[variable[:name].split(".")[0]][variable[:name].split(".")[1].to_sym] #end_uses_end_use_category + # results = {:"ffce3f6b-023a-46ab-89f2-4f8c692719dd"=>{:electricity_kwh=>39869197.34679705, :applicable=>true},:'uuid'...} + if !variable[:name].split(/\./)[0].nil? && !variable[:name].split(/\./)[1].nil? && !results[variable[:name].split(/\./)[0].to_sym].nil? && !results[variable[:name].split(/\./)[0].to_sym][variable[:name].split(/\./)[1].to_sym].nil? + #objective_functions["objective_function_#{variable[:objective_function_index] + 1}"] = results[variable[:name].split(/\./)[0]][variable[:var_name].to_sym] #no end_uses + if results[variable[:name].split(/\./)[0].to_sym][variable[:name].split(/\./)[1].to_sym].present? + @sim_logger.info "setting objective function #{variable[:name]} to: #{results[variable[:name].split(/\./)[0].to_sym][variable[:name].split(/\./)[1].to_sym]}" + objective_functions["objective_function_#{variable[:objective_function_index] + 1}"] = results[variable[:name].split(/\./)[0].to_sym][variable[:name].split(/\./)[1].to_sym] #end_uses_end_use_category + else + objective_functions["objective_function_#{variable[:objective_function_index] + 1}"] = @data_point.analysis.problem['algorithm']['failed_f_value'] + @sim_logger.error "No results for objective function #{variable[:name]}. results are NULL/not present. most likely REopt error." + end if variable[:objective_function_target] @sim_logger.info "Found objective function target for #{variable[:name]}" objective_functions["objective_function_target_#{variable[:objective_function_index] + 1}"] = variable[:objective_function_target].to_f @@ -297,12 +484,11 @@ def run_urbanopt(uo_simulation_log, uo_process_log) end else #make raise an option to continue with failures?? - raise "No results for objective function #{variable[:name]}" - @sim_logger.error "No results for objective function #{variable[:name]} in #{__FILE__} at #{__LINE__}" - objective_functions["objective_function_#{variable[:objective_function_index] + 1}"] = Float::MAX - objective_functions["objective_function_target_#{variable[:objective_function_index] + 1}"] = nil - objective_functions["scaling_factor_#{variable[:objective_function_index] + 1}"] = nil - objective_functions["objective_function_group_#{variable[:objective_function_index] + 1}"] = nil + #raise "No results for objective function #{variable[:name]}" + @sim_logger.error "No results for objective function #{variable[:name]}" + objective_functions["objective_function_#{variable[:objective_function_index] + 1}"] = @data_point.analysis.problem['algorithm']['failed_f_value'] + objective_functions["objective_function_target_#{variable[:objective_function_index] + 1}"] = variable[:objective_function_target].to_f + objective_functions["objective_function_group_#{variable[:objective_function_index] + 1}"] = variable[:objective_function_group].to_f end end end @@ -341,9 +527,9 @@ def run_urbanopt(uo_simulation_log, uo_process_log) #copy results to "#{simulation_dir}/urbanopt/run/reports/*" reports_dir = "#{simulation_dir}/reports/" - @sim_logger.info "copying #{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file}/*.{html,json,csv} to #{reports_dir}" + @sim_logger.info "copying #{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file.downcase}/*.{html,json,csv} to #{reports_dir}" FileUtils.mkdir_p reports_dir unless Dir.exist? reports_dir - Dir["#{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file}/*.{html,json,csv}"].each { |file| FileUtils.cp(file, reports_dir) } + Dir["#{simulation_dir}/urbanopt/run/#{@data_point.analysis.scenario_file.downcase}/*.{html,json,csv}"].each { |file| FileUtils.cp(file, reports_dir) } #zip reports @sim_logger.info "zipping up: #{simulation_dir}/urbanopt/run" @@ -417,4 +603,4 @@ def put_into_archive(disk_file_path, zipfile, zipfile_path) end end -end \ No newline at end of file +end diff --git a/server/app/models/analysis.rb b/server/app/models/analysis.rb index 5353f9953..def4468c5 100644 --- a/server/app/models/analysis.rb +++ b/server/app/models/analysis.rb @@ -74,7 +74,9 @@ class Analysis field :urbanopt_variables, type: Array, default: [] #array of UrbanOpt variables field :feature_file, type: String, default: '' # name of UrbanOpt Feature_file.json file field :scenario_file, type: String, default: '' # name of UrbanOpt Scenario.csv file - + field :reopt, type: Boolean, default: false # is ReOpt run? + field :reopt_type, type: String, default: '' # name of ReOpt run scenario or feature + # Temp location for these vas field :samples, type: Integer diff --git a/server/app/models/variable.rb b/server/app/models/variable.rb index 0bd3de9b0..6cb5a7688 100644 --- a/server/app/models/variable.rb +++ b/server/app/models/variable.rb @@ -75,12 +75,16 @@ class Variable field :mapper, type: String # UrbanOpt Mapper name field :uo_measure, type: String # UrbanOpt Measure name field :uo_variable, type: Boolean, default: false # UrbanOpt variable flag + field :report_file, type: String, default: 'default_scenario_report' # UrbanOpt output report name. field :report, type: String, default: 'scenario_report' # UrbanOpt output report name. either: scenario_report/feature_reports field :report_id, type: String, default: '' # UrbanOpt output report :id. either scenario id name or feature report id number field :reporting_periods, type: Integer, default: 0 # UrbanOpt output reporting_periods array index + field :reopt_category, type: String, default: '' # UrbanOpt output reopt_category field :var_name, type: String, default: '' # UrbanOpt output name, ex natural_gas field :end_use, type: String, default: '' # UrbanOpt output end_uses, ex electricity, natural_gas, district_cooling, etc field :end_use_category, type: String, default: '' # UrbanOpt output end_use category, ex heating, cooling, fans, etc + field :comfort_result_category, type: String, default: '' # UrbanOpt output comfort_result_category, ex time_setpoint_not_met_during_occupied_cooling + field :distributed_generation_category, type: String, default: '' # UrbanOpt output distributed_generation_category, ex total_solar_pv_kw # Relationships belongs_to :analysis, index: true @@ -136,6 +140,18 @@ def self.create_output_variable(analysis_id, json) else raise "var_name == end_uses but end_use and end_use_category are missing. check OSA output_variables" end + elsif json['var_name'] == 'comfort_result' #if var_name is comfort_result then name is uuid.comfort_result_comfort_result_category + if json['comfort_result_category'] + json['name'] = "#{SecureRandom.uuid}.#{json['var_name']}_#{json['comfort_result_category']}" + else + raise "var_name == comfort_result but comfort_result and comfort_result_category are missing. check OSA output_variables" + end + elsif json['var_name'] == 'distributed_generation' #if var_name is distributed_generation then name is uuid.distributed_generation_distributed_generation_category + if json['distributed_generation_category'] + json['name'] = "#{SecureRandom.uuid}.#{json['var_name']}_#{json['distributed_generation_category']}" + else + raise "var_name == distributed_generation but distributed_generation and distributed_generation_category are missing. check OSA output_variables" + end else json['name'] = "#{SecureRandom.uuid}.#{json['var_name']}" end @@ -180,14 +196,17 @@ def self.create_output_variable(analysis_id, json) var['objective_function_target'] = json['objective_function_target'] if json['objective_function_target'] var['scaling_factor'] = json['scaling_factor'] if json['scaling_factor'] var['objective_function_group'] = json['objective_function_group'] if json['objective_function_group'] - #set these for UrbanOpt + #set these for UrbanOpt + var.report_file = json['report_file'] if json['report_file'] var['report'] = json['report'] if json['report'] var['report_id'] = json['report_id'] if json['report_id'] var['reporting_periods'] = json['reporting_periods'] if json['reporting_periods'] + var['reopt_category'] = json['reopt_category'] if json['reopt_category'] var['var_name'] = json['var_name'] if json['var_name'] var['end_use'] = json['end_use'] if json['end_use'] var['end_use_category'] = json['end_use_category'] if json['end_use_category'] - + var['comfort_result_category'] = json['comfort_result_category'] if json['comfort_result_category'] + var['distributed_generation_category'] = json['distributed_generation_category'] if json['distributed_generation_category'] var.save! logger.info("output variable: '#{var.to_json}'") var diff --git a/server/spec/features/openstudio_urbanopt_algo_spec.rb b/server/spec/features/openstudio_urbanopt_algo_spec.rb index f78ec87f9..c5918e05a 100644 --- a/server/spec/features/openstudio_urbanopt_algo_spec.rb +++ b/server/spec/features/openstudio_urbanopt_algo_spec.rb @@ -95,8 +95,8 @@ natural_gas_kwh: 21731513.8888 } ] single_run_round = [ - { electricity_kwh: 19300000, - natural_gas_kwh: 21800000 } + { electricity_kwh: 19000000, + natural_gas_kwh: 22000000 } ] # setup bad results single_run_bad = [ @@ -118,7 +118,7 @@ analysis_id = analysis[:_id] status = 'queued' - timeout_seconds = 480 + timeout_seconds = 920 begin ::Timeout.timeout(timeout_seconds) do while status != 'completed' @@ -231,7 +231,7 @@ end sim = sim_result.slice(:electricity_kwh, :natural_gas_kwh) expect(sim.size).to eq(2) - sim = sim.transform_values { |x| x.round(-5) } + sim = sim.transform_values { |x| x.round(-6) } compare = single_run_round.include?(sim) expect(compare).to be true @@ -256,10 +256,10 @@ }] objectives_round = [{ - objective_function_1: 19300000, + objective_function_1: 19000000, objective_function_target_1: 0, objective_function_group_1: 1, - objective_function_2: 21800000, + objective_function_2: 22000000, objective_function_target_2: 0, objective_function_group_2: 2, objective_function_3: 500000, @@ -281,7 +281,11 @@ if key.to_s.include?("target") || key.to_s.include?("group") obj_json[key] = value.to_i else - obj_json[key] = value.round(-5) + if Math.log10(value) > 6 + obj_json[key] = value.round(-6) + else + obj_json[key] = value.round(-5) + end end end diff --git a/server/spec/files/URBANopt_NSGA.json b/server/spec/files/URBANopt_NSGA.json index 188c64f08..627933f63 100644 --- a/server/spec/files/URBANopt_NSGA.json +++ b/server/spec/files/URBANopt_NSGA.json @@ -109,9 +109,6 @@ "run_workflow_timeout": 28800, "upload_results_timeout": 28800, "initialize_worker_timeout": 28800, - "server_scripts": { - "worker_initialization": "./scripts/worker_initialization/initialize.sh" - }, "feature_file": "example_project", "scenario_file": "highefficiency_scenario", "urbanopt_variables": [ diff --git a/server/spec/files/URBANopt_NSGA.zip b/server/spec/files/URBANopt_NSGA.zip index dc1b6ab1f..24e2f268d 100644 Binary files a/server/spec/files/URBANopt_NSGA.zip and b/server/spec/files/URBANopt_NSGA.zip differ diff --git a/server/spec/files/URBANopt_NSGA_spaces_reopt.json b/server/spec/files/URBANopt_NSGA_spaces_reopt.json index 18fd517b0..f17f08054 100644 --- a/server/spec/files/URBANopt_NSGA_spaces_reopt.json +++ b/server/spec/files/URBANopt_NSGA_spaces_reopt.json @@ -16,7 +16,7 @@ "report": "feature_reports", "report_id": "1", "reporting_periods": 0, - "var_name": "electricity", + "var_name": "electricity_kwh", "visualize": true, "export": true, "variable_type": "double" @@ -33,7 +33,7 @@ "report": "feature_reports", "report_id": "1", "reporting_periods": 0, - "var_name": "natural_gas", + "var_name": "natural_gas_kwh", "visualize": true, "export": true, "variable_type": "double" @@ -51,7 +51,7 @@ "report_id": "1", "reporting_periods": 0, "var_name": "end_uses", - "end_use": "electricity", + "end_use": "electricity_kwh", "end_use_category": "fans", "visualize": true, "export": true, @@ -70,7 +70,7 @@ "report_id": "highefficiency_scenario", "reporting_periods": 0, "var_name": "end_uses", - "end_use": "electricity", + "end_use": "electricity_kwh", "end_use_category": "fans", "visualize": true, "export": true, @@ -366,9 +366,6 @@ "run_workflow_timeout": 28800, "upload_results_timeout": 28800, "initialize_worker_timeout": 28800, - "server_scripts": { - "worker_initialization": "./scripts/worker_initialization/initialize.sh" - }, "feature_file": "example_project", "scenario_file": "highefficiency_scenario", "urbanopt_variables": [ diff --git a/server/spec/files/URBANopt_NSGA_spaces_reopt.zip b/server/spec/files/URBANopt_NSGA_spaces_reopt.zip index 5ea02f538..7186dde31 100644 Binary files a/server/spec/files/URBANopt_NSGA_spaces_reopt.zip and b/server/spec/files/URBANopt_NSGA_spaces_reopt.zip differ diff --git a/server/spec/files/URBANopt_fast.zip b/server/spec/files/URBANopt_fast.zip index db3cfdd7b..fb67754db 100644 Binary files a/server/spec/files/URBANopt_fast.zip and b/server/spec/files/URBANopt_fast.zip differ diff --git a/server/spec/files/URBANopt_singlerun.json b/server/spec/files/URBANopt_singlerun.json index c836fd257..d408227df 100644 --- a/server/spec/files/URBANopt_singlerun.json +++ b/server/spec/files/URBANopt_singlerun.json @@ -1,7 +1,7 @@ { "analysis": { - "display_name": "URBANopt_NSGA", - "name": "URBANopt_NSGA", + "display_name": "URBANopt_singlerun", + "name": "URBANopt_singlerun", "urbanopt": true, "output_variables": [ { @@ -13,6 +13,7 @@ "display_name": "electricity", "display_name_short": "electricity", "metadata_id": null, + "report_file": "default_scenario_report", "report": "feature_reports", "report_id": "1", "reporting_periods": 0, @@ -30,6 +31,7 @@ "display_name": "natural_gas", "display_name_short": "natural_gas", "metadata_id": null, + "report_file": "default_scenario_report", "report": "feature_reports", "report_id": "1", "reporting_periods": 0, @@ -47,6 +49,7 @@ "display_name": "electricity_fans", "display_name_short": "electricity_fans", "metadata_id": null, + "report_file": "default_scenario_report", "report": "feature_reports", "report_id": "1", "reporting_periods": 0, @@ -66,6 +69,7 @@ "display_name": "electricity_fans", "display_name_short": "electricity_fans", "metadata_id": null, + "report_file": "default_scenario_report", "report": "scenario_report", "report_id": "highefficiency_scenario", "reporting_periods": 0, diff --git a/server/spec/files/URBANopt_singlerun_fast.json b/server/spec/files/URBANopt_singlerun_fast.json index 29eeb633d..6ae180ba3 100644 --- a/server/spec/files/URBANopt_singlerun_fast.json +++ b/server/spec/files/URBANopt_singlerun_fast.json @@ -1,7 +1,7 @@ { "analysis": { - "display_name": "UrbanOpt_NSGA", - "name": "UrbanOpt_NSGA", + "display_name": "URBANopt_singlerun_fast", + "name": "URBANopt_singlerun_fast", "urbanopt": true, "output_variables": [ {