urbanopt-cli 0.1.0 → 0.2.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ {
2
+ "file_version": "0.1.0",
3
+ "max_datapoints": 1000000000,
4
+ "num_parallel": 2,
5
+ "run_simulations": true,
6
+ "verbose": false
7
+ }
@@ -1,5 +1,5 @@
1
1
  module URBANopt
2
2
  module CLI
3
- VERSION = "0.1.0"
3
+ VERSION = "0.2.0.pre1"
4
4
  end
5
5
  end
data/lib/uo_cli.rb CHANGED
@@ -45,38 +45,52 @@ module URBANopt
45
45
  # Set up user interface
46
46
  @user_input = {}
47
47
  the_parser = OptionParser.new do |opts|
48
- opts.banner = "Usage: uo [-pmradsfv]\n" +
48
+ opts.banner = "Usage: uo [-pmradsfiv]\n" +
49
49
  "\n" +
50
- "URBANopt CLI. \n" +
51
- "First create a project folder with -p, then run additional commands as desired \n"
50
+ "URBANopt CLI\n" +
51
+ "First create a project folder with -p, then run additional commands as desired\n" +
52
+ "Additional config options can be set with the 'runner.conf' file inside your new project folder"
52
53
  opts.separator ""
53
54
 
54
- opts.on("-p", "--project_folder <DIR>",String, "Create project directory named <DIR> in your current folder") do |folder|
55
+ opts.on("-p", "--project_folder <DIR>",String, "Create project directory named <DIR> in your current folder\n" +
56
+ " You must be insde the project directory you just created for all following commands to work") do |folder|
55
57
  @user_input[:project_folder] = folder
56
58
  end
59
+
57
60
  opts.on("-m", "--make_scenario", String, "Create ScenarioCSV files for each MapperFile using the Feature file path. Must specify -f argument\n" +
58
61
  " Example: uo -m -f example_project.json\n" +
59
- " You must be insde the project directory you just created for this to work") do
60
- @user_input[:make_scenario_from] = "Create scenario files from FeatureFiles according to the MapperFiles in the 'mappers' directory" # This text does not get displayed to the user
62
+ " Or, Create Scenario CSV for each MapperFile for a single Feature from Feature File. Must specify -f and -i argument\n" +
63
+ " Example: uo -m -f example_project.json -i 1") do
64
+ @user_input[:make_scenario_from] = "Create scenario files from FeatureFiles or for single Feature according to the MapperFiles in the 'mappers' directory" # This text does not get displayed to the user
61
65
  end
66
+
62
67
  opts.on("-r", "--run", String, "Run simulations. Must specify -s & -f arguments\n" +
63
68
  " Example: uo -r -s baseline_scenario.csv -f example_project.json") do
64
69
  @user_input[:run_scenario] = "Run simulations" # This text does not get displayed to the user
65
70
  end
71
+
66
72
  opts.on("-a", "--aggregate", String, "Aggregate individual feature results to scenario-level results. Must specify -s & -f arguments\n" +
67
73
  " Example: uo -a -s baseline_scenario.csv -f example_project.json") do
68
74
  @user_input[:aggregate] = "Aggregate all features to a whole Scenario" # This text does not get displayed to the user
69
75
  end
76
+
70
77
  opts.on("-d", "--delete_scenario", String, "Delete results from scenario. Must specify -s argument\n" +
71
78
  " Example: uo -d -s baseline_scenario.csv") do
72
79
  @user_input[:delete_scenario] = "Delete scenario results that were created from <SFP>" # This text does not get displayed to the user
73
80
  end
81
+
74
82
  opts.on("-s", "--scenario_file <SFP>", String, "Specify <SFP> (ScenarioCSV file path). Used as input for other commands") do |scenario|
75
83
  @user_input[:scenario] = scenario
76
84
  end
85
+
77
86
  opts.on("-f", "--feature_file <FFP>", String, "Specify <FFP> (Feature file path). Used as input for other commands") do |feature|
78
87
  @user_input[:feature] = feature
79
88
  end
89
+
90
+ opts.on("-i", "--feature_id <FID>", Integer, "Specify <FID> (Feature ID). Used as input for other commands") do |feature_id|
91
+ @user_input[:feature_id] = feature_id
92
+ end
93
+
80
94
  opts.on("-v", "--version", "Show CLI version and exit") do
81
95
  @user_input[:version_request] = VERSION
82
96
  end
@@ -88,19 +102,27 @@ module URBANopt
88
102
  puts e
89
103
  end
90
104
 
91
-
92
- # Simulate energy usage for each Feature in the Scenario\
105
+ # Simulate energy usage for each Feature or for single feature as defined by ScenarioCSV\
93
106
  # params\
94
107
  # +scenario+:: _string_ Path to csv file that defines the scenario\
95
108
  # +feature_file_path+:: _string_ Path to Feature File used to describe set of features in the district
96
109
  #
97
110
  # FIXME: This only works when scenario_file and feature_file are in the project root directory
98
111
  # Also, feels a little weird that now I'm only using instance variables and not passing anything to this function. I guess it's ok?
99
- def self.run_func
100
- name = "#{@scenario_name.split('.')[0].capitalize}"
101
- root_dir = File.absolute_path(@scenario_root)
112
+ def self.run_func
113
+ name = "#{@scenario_folder}"
114
+ root_dir = File.dirname(File.absolute_path(@user_input[:scenario]))
102
115
  run_dir = File.join(root_dir, 'run', name.downcase)
103
- csv_file = File.join(root_dir, @scenario_name)
116
+
117
+ if @feature_id
118
+ feature_run_dir = File.join(run_dir,@feature_id)
119
+ # If run folder for feature exists, remove it
120
+ if File.exist?(feature_run_dir)
121
+ FileUtils.rm_rf(feature_run_dir)
122
+ end
123
+ end
124
+
125
+ csv_file = File.join(root_dir, @user_input[:scenario])
104
126
  featurefile = File.join(root_dir, @feature_name)
105
127
  mapper_files_dir = File.join(root_dir, "mappers")
106
128
  num_header_rows = 1
@@ -113,16 +135,29 @@ module URBANopt
113
135
  # Create a scenario csv file from a FeatureFile
114
136
  # params\
115
137
  # +feature_file_path+:: _string_ Path to a FeatureFile
116
- def self.create_scenario_csv_file(feature_file_path)
138
+ def self.create_scenario_csv_file(feature_file_path, feature_id)
117
139
  feature_file_json = JSON.parse(File.read(feature_file_path), :symbolize_names => true)
118
- Dir["#{@feature_root}/mappers/*.rb"].each do |mapper_file|
119
- mapper_root, mapper_base = File.split(mapper_file)
120
- mapper_name = mapper_base.split('.')[0]
121
- scenario_file_name = "#{mapper_name.downcase}_scenario.csv"
122
- CSV.open(File.join(@feature_root, scenario_file_name), "wb", :write_headers => true,
140
+ Dir["#{@feature_path}/mappers/*.rb"].each do |mapper_file|
141
+ mapper_path, mapper_name = File.split(mapper_file)
142
+ mapper_name = mapper_name.split('.')[0]
143
+ unless feature_id == 'SKIP'
144
+ scenario_file_name = "#{mapper_name.downcase}_scenario-#{feature_id}.csv"
145
+ else
146
+ scenario_file_name = "#{mapper_name.downcase}_scenario.csv"
147
+ end
148
+ CSV.open(File.join(@feature_path, scenario_file_name), "wb", :write_headers => true,
123
149
  :headers => ["Feature Id","Feature Name","Mapper Class"]) do |csv|
124
150
  feature_file_json[:features].each do |feature|
125
- csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"]
151
+ if feature_id == 'SKIP'
152
+ csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"]
153
+ elsif feature_id == feature[:properties][:id].to_i
154
+ csv << [feature[:properties][:id], feature[:properties][:name], "URBANopt::Scenario::#{mapper_name}Mapper"]
155
+ elsif
156
+ # If Feature ID specified does not exist in the Feature File raise error
157
+ unless feature_file_json[:features].any? {|hash| hash[:properties][:id].include?(feature_id.to_s)}
158
+ abort("\nYou must provide Feature ID from FeatureFile!\n---\n\n")
159
+ end
160
+ end
126
161
  end
127
162
  end
128
163
  end
@@ -143,10 +178,14 @@ module URBANopt
143
178
  Dir.mkdir dir_name
144
179
  Dir.mkdir File.join(dir_name, 'mappers')
145
180
  Dir.mkdir File.join(dir_name, 'weather')
181
+ Dir.mkdir File.join(dir_name, 'osm_building')
146
182
  mappers_dir_abs_path = File.absolute_path(File.join(dir_name, 'mappers/'))
147
183
  weather_dir_abs_path = File.absolute_path(File.join(dir_name, 'weather/'))
184
+ osm_dir_abs_path = File.absolute_path(File.join(dir_name, 'osm_building/'))
148
185
 
149
186
  # FIXME: When residential hpxml flow is implemented (https://github.com/urbanopt/urbanopt-example-geojson-project/pull/24 gets merged) these files will change
187
+ config_file = "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/runner.conf"
188
+
150
189
  example_feature_file = "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/example_project.json"
151
190
  example_gem_file = "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/Gemfile"
152
191
  remote_mapper_files = [
@@ -159,25 +198,40 @@ module URBANopt
159
198
  "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.ddy",
160
199
  "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.stat",
161
200
  ]
201
+
202
+ osm_files = [
203
+ "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/osm_building/7.osm",
204
+ "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/osm_building/8.osm",
205
+ "https://raw.githubusercontent.com/urbanopt/urbanopt-cli/master/example_files/osm_building/9.osm"
206
+ ]
162
207
 
163
208
  # Download files to user's local machine
164
209
  remote_mapper_files.each do |mapper_file|
165
- mapper_root, mapper_base = File.split(mapper_file)
210
+ mapper_path, mapper_name = File.split(mapper_file)
166
211
  mapper_download = open(mapper_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
167
- IO.copy_stream(mapper_download, File.join(mappers_dir_abs_path, mapper_base))
212
+ IO.copy_stream(mapper_download, File.join(mappers_dir_abs_path, mapper_name))
168
213
  end
169
214
  remote_weather_files.each do |weather_file|
170
- weather_root, weather_base = File.split(weather_file)
215
+ weather_path, weather_name = File.split(weather_file)
171
216
  weather_download = open(weather_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
172
- IO.copy_stream(weather_download, File.join(weather_dir_abs_path, weather_base))
217
+ IO.copy_stream(weather_download, File.join(weather_dir_abs_path, weather_name))
218
+ end
219
+ osm_files.each do |osm_file|
220
+ osm_path, osm_name = File.split(osm_file)
221
+ osm_download = open(osm_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
222
+ IO.copy_stream(osm_download, File.join(osm_dir_abs_path, osm_name))
173
223
  end
174
- gem_root, gem_base = File.split(example_gem_file)
224
+ gem_path, gem_name = File.split(example_gem_file)
175
225
  example_gem_download = open(example_gem_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
176
- IO.copy_stream(example_gem_download, File.join(dir_name, gem_base))
226
+ IO.copy_stream(example_gem_download, File.join(dir_name, gem_name))
177
227
 
178
- feature_root, feature_base = File.split(example_feature_file)
228
+ feature_path, feature_name = File.split(example_feature_file)
179
229
  example_feature_download = open(example_feature_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
180
- IO.copy_stream(example_feature_download, File.join(dir_name, feature_base))
230
+ IO.copy_stream(example_feature_download, File.join(dir_name, feature_name))
231
+
232
+ config_path, config_name = File.split(config_file)
233
+ config_download = open(config_file, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE})
234
+ IO.copy_stream(config_download, File.join(dir_name, config_name))
181
235
  end
182
236
  end
183
237
 
@@ -193,12 +247,20 @@ module URBANopt
193
247
 
194
248
  if @user_input[:make_scenario_from]
195
249
  if @user_input[:feature].nil?
196
- abort("\nYou must provide the '-s' flag and a valid path to a FeatureFile!\n---\n\n")
250
+ abort("\nYou must provide the '-f' flag and a valid path to a FeatureFile!\n---\n\n")
251
+ end
252
+
253
+ @feature_path, @feature_name = File.split(@user_input[:feature])
254
+ if @user_input[:feature_id]
255
+ puts "\nBuilding sample ScenarioFiles, assigning mapper classes to Feature ID #{@user_input[:feature_id]}..."
256
+ create_scenario_csv_file(@user_input[:feature], @user_input[:feature_id])
257
+ puts "Done"
258
+ else
259
+ puts "\nBuilding sample ScenarioFiles, assigning mapper classes to each feature from #{@feature_name}..."
260
+ # Skip Feature ID argument if not present
261
+ create_scenario_csv_file(@user_input[:feature], 'SKIP')
262
+ puts "Done"
197
263
  end
198
- @feature_root, @feature_name = File.split(@user_input[:feature])
199
- puts "\nBuilding sample ScenarioFiles, assigning mapper classes to each feature from #{@feature_name}..."
200
- create_scenario_csv_file(@user_input[:feature])
201
- puts "Done"
202
264
  end
203
265
 
204
266
  if @user_input[:run_scenario]
@@ -208,9 +270,14 @@ module URBANopt
208
270
  if @user_input[:feature].nil?
209
271
  abort("\nYou must provide '-f' flag and a valid path to a FeatureFile!\n---\n\n")
210
272
  end
211
- @scenario_root, @scenario_name = File.split(@user_input[:scenario])
212
- @feature_root, @feature_name = File.split(@user_input[:feature])
213
- puts "\nSimulating features of '#{@feature_name}' as directed by '#{@scenario_name}'...\n\n"
273
+ if @user_input[:scenario].include? "-"
274
+ @scenario_folder = "#{@user_input[:scenario].split(/\W+/)[0].capitalize}"
275
+ @feature_id = "#{@user_input[:scenario].split(/\W+/)[1]}"
276
+ else
277
+ @scenario_folder = "#{@user_input[:scenario].split('.')[0].capitalize}"
278
+ end
279
+ @feature_path, @feature_name = File.split(@user_input[:feature])
280
+ puts "\nSimulating features of '#{@feature_name}' as directed by '#{@user_input[:scenario]}'...\n\n"
214
281
  scenario_runner = URBANopt::Scenario::ScenarioRunnerOSW.new
215
282
  scenario_runner.run(run_func())
216
283
  puts "Done"
@@ -223,9 +290,10 @@ module URBANopt
223
290
  if @user_input[:feature].nil?
224
291
  abort("\nYou must provide '-f' flag and a valid path to a FeatureFile!\n---\n\n")
225
292
  end
226
- @scenario_root, @scenario_name = File.split(@user_input[:scenario])
227
- @feature_root, @feature_name = File.split(@user_input[:feature])
228
- puts "\nAggregating results across all features of #{@feature_name} according to '#{@scenario_name}'..."
293
+ @scenario_folder = "#{@user_input[:scenario].split('.')[0].capitalize}"
294
+ @scenario_path, @scenario_name = File.split(@user_input[:scenario])
295
+ @feature_path, @feature_name = File.split(@user_input[:feature])
296
+ puts "\nAggregating results across all features of #{@feature_name} according to '#{@scenario_name}'...\n"
229
297
  scenario_result = URBANopt::Scenario::ScenarioDefaultPostProcessor.new(run_func()).run
230
298
  scenario_result.save
231
299
  puts "Done"
@@ -235,10 +303,10 @@ module URBANopt
235
303
  if @user_input[:scenario].nil?
236
304
  abort("\nYou must provide '-s' flag and a valid path to a ScenarioFile!\n---\n\n")
237
305
  end
238
- @scenario_root, @scenario_name = File.split(@user_input[:scenario])
306
+ @scenario_path, @scenario_name = File.split(@user_input[:scenario])
239
307
  scenario_name = @scenario_name.split('.')[0]
240
- scenario_root = File.absolute_path(@scenario_root)
241
- scenario_results_dir = File.join(scenario_root, 'run', scenario_name)
308
+ scenario_path = File.absolute_path(@scenario_path)
309
+ scenario_results_dir = File.join(scenario_path, 'run', scenario_name)
242
310
  puts "\nDeleting previous results from '#{@scenario_name}'..."
243
311
  FileUtils.rm_rf(scenario_results_dir)
244
312
  puts "Done"
data/uo_cli.gemspec CHANGED
@@ -29,16 +29,18 @@ Gem::Specification.new do |spec|
29
29
  # spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.executables = ["uo"]
31
31
  spec.require_paths = ["lib"]
32
+ spec.required_ruby_version = '~> 2.2.4'
32
33
 
33
- spec.add_dependency "urbanopt-scenario", "~> 0.1.1"
34
- spec.add_dependency "urbanopt-geojson", "~> 0.1.0"
34
+ # use specific versions of these dependencies while using Ruby 2.2
35
+ spec.add_development_dependency "rack", "2.1.2"
36
+
37
+ # use specific versions of urbanopt and openstudio dependencies while under heavy development
38
+ spec.add_dependency "urbanopt-scenario", "0.2.0.pre1"
39
+ spec.add_dependency "urbanopt-geojson", "0.2.0.pre1"
35
40
 
36
41
  spec.add_development_dependency "bundler", "~> 1.17"
37
42
  spec.add_development_dependency "rake", "~> 12.3"
38
43
  spec.add_development_dependency "rspec", "~> 3.0"
39
- spec.add_development_dependency "github_api", "~> 0.18.0"
40
-
41
- # Set specific version while we are on Ruby 2.2.4
42
- spec.add_development_dependency "rack", "2.1.2"
44
+ spec.add_development_dependency "github_api", "~> 0.18"
43
45
 
44
46
  end
metadata CHANGED
@@ -1,43 +1,57 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: urbanopt-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0.pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Moore
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-14 00:00:00.000000000 Z
11
+ date: 2020-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.2
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.2
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: urbanopt-scenario
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - "~>"
31
+ - - '='
18
32
  - !ruby/object:Gem::Version
19
- version: 0.1.1
33
+ version: 0.2.0.pre1
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - "~>"
38
+ - - '='
25
39
  - !ruby/object:Gem::Version
26
- version: 0.1.1
40
+ version: 0.2.0.pre1
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: urbanopt-geojson
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
45
+ - - '='
32
46
  - !ruby/object:Gem::Version
33
- version: 0.1.0
47
+ version: 0.2.0.pre1
34
48
  type: :runtime
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - "~>"
52
+ - - '='
39
53
  - !ruby/object:Gem::Version
40
- version: 0.1.0
54
+ version: 0.2.0.pre1
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: bundler
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,28 +100,14 @@ dependencies:
86
100
  requirements:
87
101
  - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: 0.18.0
103
+ version: '0.18'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: 0.18.0
97
- - !ruby/object:Gem::Dependency
98
- name: rack
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - '='
102
- - !ruby/object:Gem::Version
103
- version: 2.1.2
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - '='
109
- - !ruby/object:Gem::Version
110
- version: 2.1.2
110
+ version: '0.18'
111
111
  description: Interfacing with URBANopt
112
112
  email:
113
113
  - nathan.moore@nrel.gov
@@ -116,6 +116,9 @@ executables:
116
116
  extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
+ - ".github/ISSUE_TEMPLATE/bug_report.md"
120
+ - ".github/ISSUE_TEMPLATE/feature_request.md"
121
+ - ".github/pull_request_template.md"
119
122
  - ".gitignore"
120
123
  - ".rspec"
121
124
  - ".ruby-version"
@@ -134,6 +137,10 @@ files:
134
137
  - example_files/mappers/Baseline.rb
135
138
  - example_files/mappers/HighEfficiency.rb
136
139
  - example_files/mappers/base_workflow.osw
140
+ - example_files/osm_building/7.osm
141
+ - example_files/osm_building/8.osm
142
+ - example_files/osm_building/9.osm
143
+ - example_files/runner.conf
137
144
  - example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.ddy
138
145
  - example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.epw
139
146
  - example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3.stat
@@ -152,14 +159,14 @@ require_paths:
152
159
  - lib
153
160
  required_ruby_version: !ruby/object:Gem::Requirement
154
161
  requirements:
155
- - - ">="
162
+ - - "~>"
156
163
  - !ruby/object:Gem::Version
157
- version: '0'
164
+ version: 2.2.4
158
165
  required_rubygems_version: !ruby/object:Gem::Requirement
159
166
  requirements:
160
- - - ">="
167
+ - - ">"
161
168
  - !ruby/object:Gem::Version
162
- version: '0'
169
+ version: 1.3.1
163
170
  requirements: []
164
171
  rubyforge_project:
165
172
  rubygems_version: 2.4.5.1