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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b307b715407bd74c16e687f0acfe025555e232cab093d493ddfec92930208928
4
- data.tar.gz: b03f1c1c73cbd0c7ec95033e91874d9a4ec6ff267ca038877a04d18ec8772f7d
3
+ metadata.gz: 8b57a1b469c94255be338f754cd6b450e3c059210ec05897d9b0d6825904e6f7
4
+ data.tar.gz: a663a6646924dde02c9b45ce6d9761d5b5aed59ef2f3067ceab4d6786c09259d
5
5
  SHA512:
6
- metadata.gz: ba82343b9d2bc7e35439d1583ee39b6938459e1fd0f83cd6993ab1e6e71dcf185f2da7fedb62d4b02267664576c42b941e22e3fcf673ac321812998ca60bd07d
7
- data.tar.gz: 4a8aad3e2348fa63e25c6aa07e496b75a79be7b9aa2af92075c1e63524296e60150169f0c9e732c13cd962b6c701e16a16b50474e7005fb3cbf7e090981ee7df
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
- self.weather_file = osw[:weather_file] ? osw[:weather_file] : nil
381
- self.seed_model = osw[:seed_file] ? osw[:seed_file] : nil
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
- measure_dir_abs_path = File.join(File.dirname(File.expand_path(osw_filename)),measure_dir)
399
- xml = parse_measure_xml(File.join(measure_dir_abs_path, '/measure.xml'))
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
- step[:arguments].each do |k,v|
421
- #check if argument is in measure, otherwise setting argument_value will crash
422
- raise "OSW arg: #{k} is not in Measure: #{name}" if m.arguments.find_all { |a| a[:name] == k.to_s }.empty?
423
- #set measure arg to match osw arg
424
- m.argument_value(k.to_s, v)
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
- ## Weather files
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 File.exists?(@weather_file[:file])
458
- puts " Adding #{@weather_file[:file]}"
459
- zf.add("weather/#{File.basename(@weather_file[:file])}", @weather_file[:file])
460
- #make absolute path and check for file
461
- elsif File.exists?(File.join(osw_full_path,@weather_file[:file].sub(/^\.\//, '')))
462
- puts " Adding #{File.join(osw_full_path,@weather_file[:file].sub(/^\.\//, ''))}"
463
- zf.add("weather/#{File.basename(@weather_file[:file])}", File.join(osw_full_path,@weather_file[:file].sub(/^\.\//, '')))
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
- raise "Weather file does not exist at: #{File.join(osw_full_path,@weather_file[:file].sub(/^\.\//, ''))}"
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 weather file exists. use abs path. remove leading ./ from @seed_model path if there.
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 File.exists?(@seed_model[:file])
473
- puts " Adding #{@seed_model[:file]}"
474
- zf.add("seeds/#{File.basename(@seed_model[:file])}", @seed_model[:file])
475
- #make absolute path and check for file
476
- elsif File.exists?(File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, '')))
477
- puts " Adding #{File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, ''))}"
478
- zf.add("seeds/#{File.basename(@seed_model[:file])}", File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, '')))
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
- raise "Seed file does not exist at: #{File.join(osw_full_path,@seed_model[:file].sub(/^\.\//, ''))}"
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]
@@ -37,6 +37,6 @@ module OpenStudio
37
37
  module Analysis
38
38
  # format should be ^.*\-{1}[a-z]+[0-9]+
39
39
  # for example: -rc1, -beta6, -customusecase0
40
- VERSION = '1.3.1'.freeze
40
+ VERSION = '1.3.3'.freeze
41
41
  end
42
42
  end
@@ -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'].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'] ? arg.elements['units'].text : ''
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.1
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-03-20 00:00:00.000000000 Z
11
+ date: 2023-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bcl