openstudio-analysis 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -2
- data/lib/openstudio/analysis/formulation.rb +146 -41
- data/lib/openstudio/analysis/version.rb +1 -1
- data/lib/openstudio/helpers/utils.rb +5 -5
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b57a1b469c94255be338f754cd6b450e3c059210ec05897d9b0d6825904e6f7
|
4
|
+
data.tar.gz: a663a6646924dde02c9b45ce6d9761d5b5aed59ef2f3067ceab4d6786c09259d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20acbefdd350cb6706814d39e513f92abee35dc32538e61aabc209b2c17b3059ecfe2c5ce1dd5489e15d5dd20d5c5af686c74228f54038e187b1956830de3012
|
7
|
+
data.tar.gz: c37631b399d554ba2115d1946280a20d40766a26e1521c0e301ed79722c5e77d05974140691823119e93d7b29d0a04765251ffb8089300e6444037b9ee4d1074
|
data/CHANGELOG.md
CHANGED
@@ -1,13 +1,34 @@
|
|
1
1
|
OpenStudio Analysis Gem Change Log
|
2
2
|
==================================
|
3
3
|
|
4
|
+
Version 1.3.3
|
5
|
+
-------------
|
6
|
+
* Add arguments to .save_osa_zip() to add all files in weather and/or seed directories to zip file. defaults to false.
|
7
|
+
|
8
|
+
Version 1.3.2
|
9
|
+
-------------
|
10
|
+
* Add array of search paths to .convert_osw() to find measures in various directories.
|
11
|
+
* warn if :weather_file and :seed_model are not defined.
|
12
|
+
* use :file_paths in the OSW to search for :seed_model and :weather_file.
|
13
|
+
* add .stat and .ddy files to analysis.zip if in same directory as .epw defined in :weather_file.
|
14
|
+
* use :measure_paths in OSW to search for measures.
|
15
|
+
|
4
16
|
Version 1.3.1
|
5
17
|
-------------
|
6
|
-
* Add method to delete a Variable
|
18
|
+
* Add method to delete a Variable: **analysis.remove_variable()**
|
19
|
+
* fix bug related to multiple calls to analysis.to_hash deleting variables
|
20
|
+
* Add PSO and Optim to allowed algorithms
|
7
21
|
|
8
22
|
Version 1.3.0
|
9
23
|
-------------
|
10
|
-
* Create an OSA from an OSW
|
24
|
+
* Create an OSA from an OSW: **analysis.convert_osw()**
|
25
|
+
* Add output variables and objective functions: **analysis.add_output()**
|
26
|
+
* Add server initialization and finalization scripts: **analysis.server_scripts.add()**
|
27
|
+
* Set algorithm attributes: **analysis.algorithm.set_attribute()**
|
28
|
+
* Set algorithm type: **analysis.analysis_type()**
|
29
|
+
* Add additional library/data files: **analysis.libraries.add()**
|
30
|
+
* create analysis.json: **File.write('analysis.json',JSON.pretty_generate(analysis.to_hash))**
|
31
|
+
* create analysis.zip: **analysis.save_osa_zip('analysis.zip')**
|
11
32
|
|
12
33
|
Version 1.2.0
|
13
34
|
-------------
|
@@ -351,12 +351,12 @@ module OpenStudio
|
|
351
351
|
end
|
352
352
|
|
353
353
|
|
354
|
-
def save_osa_zip(filename)
|
354
|
+
def save_osa_zip(filename, all_weather_files = false, all_seed_files = false)
|
355
355
|
filename += '.zip' if File.extname(filename) == ''
|
356
356
|
|
357
357
|
FileUtils.mkdir_p File.dirname(filename) unless Dir.exist? File.dirname(filename)
|
358
358
|
|
359
|
-
save_analysis_zip_osa(filename)
|
359
|
+
save_analysis_zip_osa(filename, all_weather_files, all_seed_files)
|
360
360
|
end
|
361
361
|
|
362
362
|
# convert an OSW to an OSA
|
@@ -367,8 +367,8 @@ module OpenStudio
|
|
367
367
|
# /seeds
|
368
368
|
# /weather
|
369
369
|
#
|
370
|
-
def convert_osw(osw_filename)
|
371
|
-
#load OSW so we can loop over [:steps]
|
370
|
+
def convert_osw(osw_filename, *measure_paths)
|
371
|
+
# load OSW so we can loop over [:steps]
|
372
372
|
if File.exist? osw_filename #will this work for both rel and abs paths?
|
373
373
|
osw = JSON.parse(File.read(osw_filename), symbolize_names: true)
|
374
374
|
@osw_path = File.expand_path(osw_filename)
|
@@ -376,10 +376,44 @@ module OpenStudio
|
|
376
376
|
raise "Could not find workflow file #{osw_filename}"
|
377
377
|
end
|
378
378
|
|
379
|
-
#set the weather and seed files if set in OSW
|
380
|
-
|
381
|
-
|
379
|
+
# set the weather and seed files if set in OSW
|
380
|
+
# use :file_paths and look for files to set
|
381
|
+
if osw[:file_paths]
|
382
|
+
# seed_model, check if in OSW and not found in path search already
|
383
|
+
if osw[:seed_file]
|
384
|
+
osw[:file_paths].each do |path|
|
385
|
+
puts "searching for seed at: #{File.join(File.expand_path(path), osw[:seed_file])}"
|
386
|
+
if File.exist?(File.join(File.expand_path(path), osw[:seed_file]))
|
387
|
+
puts "found seed_file: #{osw[:seed_file]}"
|
388
|
+
self.seed_model = File.join(File.expand_path(path), osw[:seed_file])
|
389
|
+
break
|
390
|
+
end
|
391
|
+
end
|
392
|
+
else
|
393
|
+
warn "osw[:seed_file] is not defined"
|
394
|
+
end
|
395
|
+
|
396
|
+
# weather_file, check if in OSW and not found in path search already
|
397
|
+
if osw[:weather_file]
|
398
|
+
osw[:file_paths].each do |path|
|
399
|
+
puts "searching for weather at: #{File.join(File.expand_path(path), osw[:weather_file])}"
|
400
|
+
if File.exist?(File.join(File.expand_path(path), osw[:weather_file]))
|
401
|
+
puts "found weather_file: #{osw[:weather_file]}"
|
402
|
+
self.weather_file = File.join(File.expand_path(path), osw[:weather_file])
|
403
|
+
break
|
404
|
+
end
|
405
|
+
end
|
406
|
+
else
|
407
|
+
warn "osw[:weather_file] is not defined"
|
408
|
+
end
|
382
409
|
|
410
|
+
# file_paths is not defined in OSW, so warn and try to set
|
411
|
+
else
|
412
|
+
warn ":file_paths is not defined in the OSW."
|
413
|
+
self.weather_file = osw[:weather_file] ? osw[:weather_file] : nil
|
414
|
+
self.seed_model = osw[:seed_file] ? osw[:seed_file] : nil
|
415
|
+
end
|
416
|
+
|
383
417
|
#set analysis_type default to Single_Run
|
384
418
|
self.analysis_type = 'single_run'
|
385
419
|
|
@@ -394,9 +428,26 @@ module OpenStudio
|
|
394
428
|
#get measure directory
|
395
429
|
measure_dir = step[:measure_dir_name]
|
396
430
|
measure_name = measure_dir.split("measures/").last
|
431
|
+
puts "measure_dir_name: #{measure_name}"
|
397
432
|
#get XML
|
398
|
-
|
399
|
-
|
433
|
+
# Loop over possible user defined *measure_paths, including the dir of the osw_filename path and :measure_paths, to find the measure,
|
434
|
+
# then set measure_dir_abs_path to that path
|
435
|
+
measure_dir_abs_path = ''
|
436
|
+
paths_to_parse = [File.dirname(osw_filename), osw[:measure_paths], *measure_paths].flatten.compact.map { |path| File.join(File.expand_path(path), measure_dir, 'measure.xml') }
|
437
|
+
puts "searching for xml's in: #{paths_to_parse}"
|
438
|
+
xml = {}
|
439
|
+
paths_to_parse.each do |path|
|
440
|
+
if File.exist?(path)
|
441
|
+
puts "found xml: #{path}"
|
442
|
+
xml = parse_measure_xml(path)
|
443
|
+
if !xml.empty?
|
444
|
+
measure_dir_abs_path = path
|
445
|
+
break
|
446
|
+
end
|
447
|
+
end
|
448
|
+
end
|
449
|
+
raise "measure #{measure_name} not found" if xml.empty?
|
450
|
+
puts ""
|
400
451
|
#add check for previous names _+1
|
401
452
|
count = 1
|
402
453
|
name = xml[:name]
|
@@ -417,13 +468,17 @@ module OpenStudio
|
|
417
468
|
#1. find measure in @workflow
|
418
469
|
m = @workflow.find_measure(name)
|
419
470
|
#2. loop thru osw args
|
420
|
-
|
421
|
-
|
422
|
-
raise "
|
423
|
-
|
424
|
-
|
471
|
+
#check if the :argument is missing from the measure step, it shouldnt be but just in case give a clean message
|
472
|
+
if step[:arguments].nil?
|
473
|
+
raise "measure #{name} step has no arguments: #{step}"
|
474
|
+
else
|
475
|
+
step[:arguments].each do |k,v|
|
476
|
+
#check if argument is in measure, otherwise setting argument_value will crash
|
477
|
+
raise "OSW arg: #{k} is not in Measure: #{name}" if m.arguments.find_all { |a| a[:name] == k.to_s }.empty?
|
478
|
+
#set measure arg to match osw arg
|
479
|
+
m.argument_value(k.to_s, v)
|
480
|
+
end
|
425
481
|
end
|
426
|
-
|
427
482
|
end
|
428
483
|
end
|
429
484
|
|
@@ -432,12 +487,11 @@ module OpenStudio
|
|
432
487
|
# New format for OSAs. Package up the seed, weather files, and measures
|
433
488
|
# filename is the name of the file to be saved. ex: analysis.zip
|
434
489
|
# it will parse the OSA and zip up all the files defined in the workflow
|
435
|
-
def save_analysis_zip_osa(filename)
|
490
|
+
def save_analysis_zip_osa(filename, all_weather_files = false, all_seed_files = false)
|
436
491
|
def add_directory_to_zip_osa(zipfile, local_directory, relative_zip_directory)
|
437
492
|
puts "Add Directory #{local_directory}"
|
438
493
|
Dir[File.join(local_directory.to_s, '**', '**')].each do |file|
|
439
494
|
puts "Adding File #{file}"
|
440
|
-
|
441
495
|
zipfile.add(file.sub(local_directory, relative_zip_directory), file)
|
442
496
|
end
|
443
497
|
zipfile
|
@@ -448,38 +502,89 @@ module OpenStudio
|
|
448
502
|
puts "osw_path: #{@osw_path}"
|
449
503
|
osw_full_path = File.dirname(File.expand_path(@osw_path))
|
450
504
|
puts "osw_full_path: #{osw_full_path}"
|
451
|
-
|
505
|
+
|
452
506
|
Zip::File.open(filename, create: true) do |zf|
|
453
|
-
|
507
|
+
## Weather files
|
454
508
|
puts 'Adding Support Files: Weather'
|
455
|
-
#check if weather file exists. use abs path. remove leading ./ from @weather_file path if there.
|
456
|
-
#check if path is already absolute
|
457
|
-
if
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
509
|
+
# check if weather file exists. use abs path. remove leading ./ from @weather_file path if there.
|
510
|
+
# check if path is already absolute
|
511
|
+
if @weather_file[:file]
|
512
|
+
if File.exists?(@weather_file[:file])
|
513
|
+
puts " Adding #{@weather_file[:file]}"
|
514
|
+
#zf.add("weather/#{File.basename(@weather_file[:file])}", @weather_file[:file])
|
515
|
+
base_name = File.basename(@weather_file[:file], ".*")
|
516
|
+
puts "base_name: #{base_name}"
|
517
|
+
# convert backslash on windows to forward slash so Dir.glob will work (in case user uses \)
|
518
|
+
weather_dirname = File.dirname(@weather_file[:file]).gsub("\\", "/")
|
519
|
+
puts "weather_dirname: #{weather_dirname}"
|
520
|
+
# If all_weather_files is true, add all files in the directory to the zip.
|
521
|
+
# Otherwise, add only files that match the base name.
|
522
|
+
file_pattern = all_weather_files ? "*" : "#{base_name}.*"
|
523
|
+
Dir.glob(File.join(weather_dirname, file_pattern)) do |file_path|
|
524
|
+
puts "file_path: #{file_path}"
|
525
|
+
puts "zip path: weather/#{File.basename(file_path)}"
|
526
|
+
zf.add("weather/#{File.basename(file_path)}", file_path)
|
527
|
+
end
|
528
|
+
# make absolute path and check for file
|
529
|
+
elsif File.exists?(File.join(osw_full_path,@weather_file[:file].sub(/^\.\//, '')))
|
530
|
+
puts " Adding: #{File.join(osw_full_path,@weather_file[:file].sub(/^\.\//, ''))}"
|
531
|
+
#zf.add("weather/#{File.basename(@weather_file[:file])}", File.join(osw_full_path,@weather_file[:file].sub(/^\.\//, '')))
|
532
|
+
base_name = File.basename(@weather_file[:file].sub(/^\.\//, ''), ".*")
|
533
|
+
puts "base_name2: #{base_name}"
|
534
|
+
weather_dirname = File.dirname(File.join(osw_full_path,@weather_file[:file].sub(/^\.\//, ''))).gsub("\\", "/")
|
535
|
+
puts "weather_dirname: #{weather_dirname}"
|
536
|
+
file_pattern = all_weather_files ? "*" : "#{base_name}.*"
|
537
|
+
Dir.glob(File.join(weather_dirname, file_pattern)) do |file_path|
|
538
|
+
puts "file_path2: #{file_path}"
|
539
|
+
puts "zip path2: weather/#{File.basename(file_path)}"
|
540
|
+
zf.add("weather/#{File.basename(file_path)}", file_path)
|
541
|
+
end
|
542
|
+
else
|
543
|
+
raise "weather_file[:file] does not exist at: #{File.join(osw_full_path,@weather_file[:file].sub(/^\.\//, ''))}"
|
544
|
+
end
|
464
545
|
else
|
465
|
-
|
466
|
-
end
|
546
|
+
warn "weather_file[:file] is not defined"
|
547
|
+
end
|
467
548
|
|
468
549
|
## Seed files
|
469
550
|
puts 'Adding Support Files: Seed Models'
|
470
|
-
#check if
|
551
|
+
#check if seed file exists. use abs path. remove leading ./ from @seed_model path if there.
|
471
552
|
#check if path is already absolute
|
472
|
-
if
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
553
|
+
if @seed_model[:file]
|
554
|
+
if File.exists?(@seed_model[:file])
|
555
|
+
puts " Adding #{@seed_model[:file]}"
|
556
|
+
zf.add("seeds/#{File.basename(@seed_model[:file])}", @seed_model[:file])
|
557
|
+
if all_seed_files
|
558
|
+
seed_dirname = File.dirname(@seed_model[:file]).gsub("\\", "/")
|
559
|
+
puts "seed_dirname: #{seed_dirname}"
|
560
|
+
Dir.glob(File.join(seed_dirname, '*')) do |file_path|
|
561
|
+
next if file_path == @seed_model[:file] # Skip if the file is the same as @seed_model[:file] so not added twice
|
562
|
+
puts "file_path: #{file_path}"
|
563
|
+
puts "zip path: seeds/#{File.basename(file_path)}"
|
564
|
+
zf.add("seeds/#{File.basename(file_path)}", file_path)
|
565
|
+
end
|
566
|
+
end
|
567
|
+
#make absolute path and check for file
|
568
|
+
elsif File.exists?(File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, '')))
|
569
|
+
puts " Adding #{File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, ''))}"
|
570
|
+
zf.add("seeds/#{File.basename(@seed_model[:file])}", File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, '')))
|
571
|
+
if all_seed_files
|
572
|
+
seed_dirname = File.dirname(File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, ''))).gsub("\\", "/")
|
573
|
+
puts "seed_dirname: #{seed_dirname}"
|
574
|
+
Dir.glob(File.join(seed_dirname, '*')) do |file_path|
|
575
|
+
next if file_path == File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, '')) # Skip if the file is the same as @seed_model[:file] so not added twice
|
576
|
+
puts "file_path: #{file_path}"
|
577
|
+
puts "zip path: seeds/#{File.basename(file_path)}"
|
578
|
+
zf.add("seeds/#{File.basename(file_path)}", file_path)
|
579
|
+
end
|
580
|
+
end
|
581
|
+
else
|
582
|
+
raise "seed_file[:file] does not exist at: #{File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, ''))}"
|
583
|
+
end
|
479
584
|
else
|
480
|
-
|
481
|
-
end
|
482
|
-
|
585
|
+
warn "seed_file[:file] is not defined"
|
586
|
+
end
|
587
|
+
|
483
588
|
puts 'Adding Support Files: Libraries'
|
484
589
|
@libraries.each do |lib|
|
485
590
|
raise "Libraries must specify their 'library_name' as metadata which becomes the directory upon zip" unless lib[:metadata][:library_name]
|
@@ -54,11 +54,11 @@ def parse_measure_xml(measure_xml_filename)
|
|
54
54
|
|
55
55
|
REXML::XPath.each(xml_root, '//measure/arguments/argument') do |arg|
|
56
56
|
measure_hash[:arguments] << {
|
57
|
-
name: arg.elements['name']
|
58
|
-
display_name: arg.elements['display_name']
|
59
|
-
variable_type: arg.elements['type']
|
60
|
-
default_value: arg.elements['default_value']
|
61
|
-
units: arg.elements['units']
|
57
|
+
name: arg.elements['name']&.text,
|
58
|
+
display_name: arg.elements['display_name']&.text,
|
59
|
+
variable_type: arg.elements['type']&.text.downcase,
|
60
|
+
default_value: arg.elements['default_value']&.text,
|
61
|
+
units: arg.elements['units']&.text || ''
|
62
62
|
}
|
63
63
|
end
|
64
64
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openstudio-analysis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nicholas Long
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-05-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bcl
|