Module: Cdo

Defined in:
lib/cdo.rb

Overview

CDO calling mechnism

Constant Summary collapse

State =
{}
@@CDO =
ENV['CDO'].nil? ? '/usr/bin/cdo' : ENV['CDO']
@@undocumentedOperators =

Only operators with documentation are accessible vie the build-in help. Other have to be added manually

%w[geopotheight pressure_fl pressure_hl]
@@addOperators =
%w[boundaryLevels thicknessOfLevels]

Class Method Summary collapse

Class Method Details

.boundaryLevels(args) ⇒ Object



90
91
92
93
94
95
96
97
98
# File 'lib/cdo.rb', line 90

def Cdo.boundaryLevels(args)
  ilevels         = Cdo.showlevel(:in => args[:in]).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

.call(cmd) ⇒ Object



49
50
51
52
53
54
55
56
57
58
# File 'lib/cdo.rb', line 49

def Cdo.call(cmd)
  if (State[:debug])
    puts '# DEBUG ====================================================================='
    puts cmd
    puts '# DEBUG ====================================================================='
    puts IO.popen(cmd).read
  else
    system(cmd + ' 1>/dev/null 2>&1 ')
  end
end

.chainCall(chain, *args) ⇒ Object

Call an operator chain without checking opeartors



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/cdo.rb', line 74

def Cdo.chainCall(chain,*args)
  io = args.find {|a| a.class == Hash}
  args.delete_if {|a| a.class == Hash}

  chain   = chain.strip
  firstOp = chain
  firstOp = chain[0...[chain.index(','),chain.index(' ')].min] unless chain.index(',').nil?
  firstOp = firstOp[1..-1] if firstOp[0] == '-'
  if /(info|show|griddes)/.match(firstOp)
    Cdo.run(" #{chain} #{io[:in]} ",$stdout)
  else
    opts = args.empty? ? '' : ',' + args.reject {|a| a.class == Hash}.join(',')
    Cdo.run(" #{chain}#{opts} #{io[:in]} ",io[:out],io[:options])
  end
end

.checkCdoObject

test if @@CDO can be used



22
23
24
25
26
27
28
29
30
# File 'lib/cdo.rb', line 22

def Cdo.checkCdo
  unless (File.exists?(@@CDO) and File.executable?(@@CDO))
    warn "Testing application #@@CDO is not available!"
    exit 1
  else
    puts "Using CDO: #@@CDO"
    puts IO.popen(@@CDO + " -V").readlines
  end
end

.DebugObject



17
18
19
# File 'lib/cdo.rb', line 17

def Cdo.Debug
  State[:debug]
end

.Debug=(value) ⇒ Object



14
15
16
# File 'lib/cdo.rb', line 14

def Cdo.Debug=(value)
  State[:debug] = value
end

.getOperatorsObject



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/cdo.rb', line 38

def Cdo.getOperators
  cmd       = @@CDO + ' 2>&1'
  help      = IO.popen(cmd).readlines.map {|l| l.chomp.lstrip}
  if 5 >= help.size
    warn "Operators could not get listed by running the CDO binary (#{@@CDO})"
    pp help if Cdo.Debug
    exit
  else
    help[help.index("Operators:")+1].split
  end
end

.method_missing(sym, *args, &block) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/cdo.rb', line 110

def Cdo.method_missing(sym, *args, &block)
  # args is expected to look like [opt1,...,optN,:in => iStream,:out => oStream] where
  # iStream could be another CDO call (timmax(selname(Temp,U,V,ifile.nc))
  puts "Operator #{sym.to_s} is called" if State[:debug]
  if getOperators.include?(sym.to_s) or @@undocumentedOperators.include?(sym.to_s)
    io = args.find {|a| a.class == Hash}
    args.delete_if {|a| a.class == Hash}
    if /(info|show|griddes)/.match(sym)
      run(" -#{sym.to_s} #{io[:in]} ",$stdout)
    else
      opts = args.empty? ? '' : ',' + args.reject {|a| a.class == Hash}.join(',')
      run(" -#{sym.to_s}#{opts} #{io[:in]} ",io[:out],io[:options])
    end
  else
    warn "Operator #{sym.to_s} not found"
  end
end

.run(cmd, ofile = nil, options = '') ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/cdo.rb', line 59

def Cdo.run(cmd,ofile=nil,options='')
  cmd = "#{@@CDO} -O #{options} #{cmd} "
  case ofile
  when $stdout
    cmd << " 2>/dev/null"
    return IO.popen(cmd).readlines.map {|l| l.chomp.strip}
  when nil
    ofile = Tempfile.new("Cdo.rb").path
  end
  cmd << "#{ofile}"
  call(cmd)
  return ofile
end

.setCdo(cdo) ⇒ Object



32
33
34
35
# File 'lib/cdo.rb', line 32

def Cdo.setCdo(cdo)
  puts "Will use #{cdo} instead of #@@CDO" if Cdo.Debug
  @@CDO = cdo
end

.thicknessOfLevels(args) ⇒ Object



100
101
102
103
104
105
106
107
108
# File 'lib/cdo.rb', line 100

def Cdo.thicknessOfLevels(args)
  bound_levels = Cdo.boundaryLevels(args)
  delta_levels    = []
  bound_levels.each_with_index {|v,i| 
    next if i == 0
    delta_levels << v - bound_levels[i-1]
  }
  delta_levels
end