openstudio-analysis 1.3.1 → 1.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|