Class: Cdo
- Inherits:
-
Object
- Object
- Cdo
- Defined in:
- lib/cdo.rb
Constant Summary collapse
- NoOutputOperators =
hardcoded fallback list of output operators - from 1.8.0 there is an options for this: –operators_no_output this list works for cdo-1.6.4
%w[cdiread cmor codetab conv_cmor_table diff diffc diffn diffp diffv dump_cmor_table dumpmap filedes gmtcells gmtxyz gradsdes griddes griddes2 gridverify info infoc infon infop infos infov map ncode ndate ngridpoints ngrids nlevel nmon npar ntime nvar nyear output outputarr outputbounds outputboundscpt outputcenter outputcenter2 outputcentercpt outputext outputf outputfld outputint outputkey outputsrv outputtab outputtri outputts outputvector outputvrml outputxyz pardes partab partab2 seinfo seinfoc seinfon seinfop showattribute showatts showattsglob showattsvar showcode showdate showformat showgrid showlevel showltype showmon showname showparam showstdname showtime showtimestamp showunit showvar showyear sinfo sinfoc sinfon sinfop sinfov spartab specinfo tinfo vardes vct vct2 verifygrid vlist xinfon zaxisdes]
- TwoOutputOperators =
%w[trend samplegridicon mrotuv eoftime eofspatial eof3dtime eof3dspatial eof3d eof complextorect complextopol]
- MoreOutputOperators =
%w[distgrid eofcoeff eofcoeff3d intyear scatter splitcode splitday splitgrid splithour splitlevel splitmon splitname splitparam splitrec splitseas splitsel splittabnum splitvar splityear splityearmon splitzaxis]
Instance Attribute Summary collapse
-
#cdo ⇒ Object
Returns the value of attribute cdo.
-
#debug ⇒ Object
Returns the value of attribute debug.
-
#env ⇒ Object
Returns the value of attribute env.
-
#filetypes ⇒ Object
readonly
Returns the value of attribute filetypes.
-
#forceOutput ⇒ Object
Returns the value of attribute forceOutput.
-
#hasNetcdf ⇒ Object
readonly
Returns the value of attribute hasNetcdf.
-
#logFile ⇒ Object
Returns the value of attribute logFile.
-
#logging ⇒ Object
Returns the value of attribute logging.
-
#operators ⇒ Object
readonly
Returns the value of attribute operators.
-
#returnCdf ⇒ Object
Returns the value of attribute returnCdf.
Instance Method Summary collapse
-
#boundaryLevels(args) ⇒ Object
compute vertical boundary levels from full levels.
-
#check ⇒ Object
check if cdo backend is working.
-
#cleanTempDir ⇒ Object
remove tempfiles created from this or previous runs.
-
#collectLogs ⇒ Object
collect logging messages.
-
#hasCdo(path = @cdo) ⇒ Object
check if the CDO binary is present and works.
-
#help(operator = nil) ⇒ Object
show Cdo’s built-in help for given operator.
-
#initialize(cdo: 'cdo', returnFalseOnError: false, returnNilOnError: false, forceOutput: true, env: {}, debug: false, tempdir: Dir.tmpdir, logging: false, logFile: StringIO.new) ⇒ Cdo
constructor
A new instance of Cdo.
-
#openCdf(iFile) ⇒ Object
return cdf handle opened in append more.
-
#readArray(iFile, varname) ⇒ Object
return narray for given variable name.
-
#readCdf(iFile, mode = 'r') ⇒ Object
return cdf handle to given file readonly.
-
#readMaArray(iFile, varname) ⇒ Object
return a masked array for given variable name.
-
#showLog ⇒ Object
print the loggin messaged.
-
#thicknessOfLevels(args) ⇒ Object
compute level thicknesses from given full levels.
-
#version(verbose = false) ⇒ Object
return CDO version string.
Constructor Details
#initialize(cdo: 'cdo', returnFalseOnError: false, returnNilOnError: false, forceOutput: true, env: {}, debug: false, tempdir: Dir.tmpdir, logging: false, logFile: StringIO.new) ⇒ Cdo
Returns a new instance of Cdo.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/cdo.rb', line 40 def initialize(cdo: 'cdo', returnFalseOnError: false, returnNilOnError: false, forceOutput: true, env: {}, debug: false, tempdir: Dir.tmpdir, logging: false, logFile: StringIO.new) # setup path to cdo executable @cdo = ENV.has_key?('CDO') ? ENV['CDO'] : cdo @operators = getOperators(@cdo) @noOutputOperators = @operators.select {|op,io| 0 == io}.keys @hasNetcdf = loadOptionalLibs @forceOutput = forceOutput @env = env @debug = ENV.has_key?('DEBUG') ? true : debug @returnNilOnError = returnNilOnError @returnFalseOnError = returnFalseOnError @tempStore = CdoTempfileStore.new(tempdir) @logging = logging @logFile = logFile @logger = Logger.new(@logFile,'a') @logger.level = Logger::INFO @config = getFeatures # create methods to descibe what can be done with the binary @config.each {|k,v| self.class.send :define_method, k.tr('-','_') do v end } # ignore return code 1 for diff operators (from 1.9.6 onwards) @exit_success = lambda {|operatorName| return 0 if version < '1.9.6' return 0 if 'diff' != operatorName[0,4] return 1 } end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args, &block) ⇒ Object (private)
Implementation of operator calls using ruby’s meta programming skills
args is expected to look like
[opt1,...,optN,:input => iStream,:output => oStream, :options => ' ']
where iStream could be another CDO call (timmax(selname(Temp,U,V,ifile.nc))
334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 |
# File 'lib/cdo.rb', line 334 def method_missing(sym, *args, &block) operatorName = sym.to_s puts "Operator #{operatorName} is called" if @debug # exit eary on missing operator unless @operators.include?(operatorName) return false if @returnFalseOnError raise ArgumentError,"Operator #{operatorName} not found" end io, operatorParameters = Cdo.parseArgs(args) # mark calls for operators without output files io[:output] = $stdout if @noOutputOperators.include?(operatorName) _run(operatorName,operatorParameters,io) end |
Instance Attribute Details
#cdo ⇒ Object
Returns the value of attribute cdo.
37 38 39 |
# File 'lib/cdo.rb', line 37 def cdo @cdo end |
#debug ⇒ Object
Returns the value of attribute debug.
37 38 39 |
# File 'lib/cdo.rb', line 37 def debug @debug end |
#env ⇒ Object
Returns the value of attribute env.
37 38 39 |
# File 'lib/cdo.rb', line 37 def env @env end |
#filetypes ⇒ Object (readonly)
Returns the value of attribute filetypes.
38 39 40 |
# File 'lib/cdo.rb', line 38 def filetypes @filetypes end |
#forceOutput ⇒ Object
Returns the value of attribute forceOutput.
37 38 39 |
# File 'lib/cdo.rb', line 37 def forceOutput @forceOutput end |
#hasNetcdf ⇒ Object (readonly)
Returns the value of attribute hasNetcdf.
38 39 40 |
# File 'lib/cdo.rb', line 38 def hasNetcdf @hasNetcdf end |
#logFile ⇒ Object
Returns the value of attribute logFile.
37 38 39 |
# File 'lib/cdo.rb', line 37 def logFile @logFile end |
#logging ⇒ Object
Returns the value of attribute logging.
37 38 39 |
# File 'lib/cdo.rb', line 37 def logging @logging end |
#operators ⇒ Object (readonly)
Returns the value of attribute operators.
38 39 40 |
# File 'lib/cdo.rb', line 38 def operators @operators end |
#returnCdf ⇒ Object
Returns the value of attribute returnCdf.
37 38 39 |
# File 'lib/cdo.rb', line 37 def returnCdf @returnCdf end |
Instance Method Details
#boundaryLevels(args) ⇒ Object
compute vertical boundary levels from full levels
465 466 467 468 469 470 471 472 473 |
# File 'lib/cdo.rb', line 465 def boundaryLevels(args) ilevels = self.showlevel(:input => args[:input])[0].split.map(&:to_f) bound_levels = Array.new(ilevels.size+1) bound_levels[0] = 0 (1..ilevels.size).each {|i| bound_levels[i] =bound_levels[i-1] + 2*(ilevels[i-1]-bound_levels[i-1]) } bound_levels end |
#check ⇒ Object
check if cdo backend is working
401 402 403 404 405 406 407 408 |
# File 'lib/cdo.rb', line 401 def check return false unless hasCdo retval = _call("#{@cdo} -V") pp retval if @debug return true end |
#cleanTempDir ⇒ Object
remove tempfiles created from this or previous runs
457 458 459 |
# File 'lib/cdo.rb', line 457 def cleanTempDir @tempStore.cleanTempDir end |
#collectLogs ⇒ Object
collect logging messages
378 379 380 381 382 383 384 385 |
# File 'lib/cdo.rb', line 378 def collectLogs if @logger.instance_variable_get(:'@logdev').filename.nil? @logFile.rewind return @logFile.read else return File.open(@logFile).readlines end end |
#hasCdo(path = @cdo) ⇒ Object
check if the CDO binary is present and works
393 394 395 396 397 398 |
# File 'lib/cdo.rb', line 393 def hasCdo(path=@cdo) executable = system("#{path} -V >/dev/null 2>&1") fullpath = File.exists?(path) and File.executable?(path) return (executable or fullpath) end |
#help(operator = nil) ⇒ Object
show Cdo’s built-in help for given operator
368 369 370 371 372 373 374 375 |
# File 'lib/cdo.rb', line 368 def help(operator=nil) if operator.nil? puts _call([@cdo,'-h'].join(' '))[:stderr] else operator = operator.to_s puts _call([@cdo,'-h',operator].join(' ')).values_at(:stdout,:stderr) end end |
#openCdf(iFile) ⇒ Object
return cdf handle opened in append more
430 431 432 |
# File 'lib/cdo.rb', line 430 def openCdf(iFile) readCdf(iFile,'r+') end |
#readArray(iFile, varname) ⇒ Object
return narray for given variable name
435 436 437 438 439 440 441 442 443 |
# File 'lib/cdo.rb', line 435 def readArray(iFile,varname) filehandle = readCdf(iFile) if filehandle.var_names.include?(varname) # return the data array filehandle.var(varname).get else raise ArgumentError, "Cannot find variable '#{varname}'" end end |
#readCdf(iFile, mode = 'r') ⇒ Object
return cdf handle to given file readonly
421 422 423 424 425 426 427 |
# File 'lib/cdo.rb', line 421 def readCdf(iFile,mode='r') if @hasNetcdf then NumRu::NetCDF.open(iFile,mode) else raise LoadError,"Could not load ruby-netcdf" end end |
#readMaArray(iFile, varname) ⇒ Object
return a masked array for given variable name
446 447 448 449 450 451 452 453 454 |
# File 'lib/cdo.rb', line 446 def readMaArray(iFile,varname) filehandle = readCdf(iFile) if filehandle.var_names.include?(varname) # return the data array filehandle.var(varname).get_with_miss else raise ArgumentError,"Cannot find variable '#{varname}'" end end |
#showLog ⇒ Object
print the loggin messaged
388 389 390 |
# File 'lib/cdo.rb', line 388 def showLog puts collectLogs end |
#thicknessOfLevels(args) ⇒ Object
compute level thicknesses from given full levels
476 477 478 479 480 481 482 483 484 |
# File 'lib/cdo.rb', line 476 def thicknessOfLevels(args) bound_levels = self.boundaryLevels(args) delta_levels = [] bound_levels.each_with_index {|v,i| next if 0 == i delta_levels << v - bound_levels[i-1] } delta_levels end |
#version(verbose = false) ⇒ Object
return CDO version string
411 412 413 414 415 416 417 418 |
# File 'lib/cdo.rb', line 411 def version(verbose=false) info = IO.popen("#{@cdo} -V 2>&1").readlines if verbose then return info.join else return info.first.split(/version/i).last.strip.split(' ').first end end |