require "numru/ggraph" require "yaml" module NumRu class VizShot @@ms_windows = false def self.windows @@ms_windows = true end @@dumpdir = './' def self.dumpdir=(dirname) @@dumpdir = dirname.sub(/([^\/])$/,'\1/') # to end with '/' end @@basename_default = 'vizshot_dump' ## DCL::swcget('FNAME').strip def self.basename_default=(basename) @@basename_default = basename end ONED_METHODS = [:plot_1d, :line, :mark] TWOD_METHODS = [:tone_cont, :vector, :tone, :contour] def initialize(opt = nil) opt = opt ? opt.dup : Hash.new @set = Hash.new @set[:admin] = Hash.new @set[:admin][:iwidth] = ( opt.delete(:iwidth) || 700 ) @set[:admin][:iheight] = ( opt.delete(:iheight) || 700 ) @set[:admin][:xdiv] = ( opt.delete(:xdiv) || 1 ) @set[:admin][:ydiv] = ( opt.delete(:ydiv) || 1 ) @set[:admin][:basename] = ( opt.delete(:basename) || @@basename_default) if opt.length > 0 raise ArgumentError,"Unsupported option(s) #{opt.keys.inspect}" end @plots = Array.new end def plot(arg) arg[:file] = File.expand_path(arg[:file]) if arg[:file] && arg[:file].is_a?(String) arg[:file2] = File.expand_path(arg[:file2]) if arg[:file2] && arg[:file2].is_a?(String) @plots.push(arg) @plots.length - 1 # index of the current plot end def add(vizshot) viz_new = self.semi_deep_clone vizshot.plots.each{|plot| viz_new.plot(plot)} viz_new end def replace_plot!(index, arg) @plots[index].update(arg) end def set_fig(opt) @set[:fig] = opt end def set_map(opt) @set[:map] = opt end def set_axes(opt) @set[:axes] = opt end def set_tone(opt) @set[:tone] = opt end def set_contour(opt) @set[:contour] = opt end def execute(opt=nil) if opt # must be a Hash opt = opt.dup postscript = opt.delete(:postscript) image_dump = opt.delete(:image_dump) if opt.length > 0 raise ArgumentError,"Unsupported option(s) #{opt.keys.inspect}" end end setup(postscript,image_dump) first = true @plots.each do |p| exec_plot(p, first) first = false end finish end def dump_code(basename=nil, all_in_one=false, exec_opt=nil) @set[:admin][:basename] = basename if basename path = @@dumpdir + @set[:admin][:basename] + '.rb' File.open(path,'w'){|f| f.print(gen_code(all_in_one, exec_opt))} path end def dump_code_and_data(basename=nil, all_in_one=false, exec_opt=nil) @set[:admin][:basename] = basename if basename viz = self.dup data_paths = viz.cut_out_data(@set[:admin][:basename]) code_path = viz.dump_code(basename, all_in_one, exec_opt) [code_path] + data_paths end def gen_code(all_in_one = false, exec_opt=nil) if all_in_one libsrc = File.open(__FILE__) code = "" while (line=libsrc.gets) break if /^#.*ENDOFLIB/ =~ line code << line end code << "####################\n" else code = 'require "numru/vizshot"' end code += "\nset = <true,:contour=>false)) when :contour tone_cont(gphys, opt.update(:tone=>false,:contour=>true)) when :line plot_1d(gphys, opt.update(:line=>true,:mark=>false)) when :mark plot_1d(gphys, opt.update(:line=>false,:mark=>true)) else raise ArgumentError, "unsuppored draw method: "+method.to_s end end def setup(postscript=nil,image_dump=nil) DCL::swiset("iwidth", @set[:admin][:iwidth]) DCL::swiset("iheight", @set[:admin][:iheight]) if postscript raise "DCL on MS Windows does not support PostScript file O" if @@ms_windows DCL::gropn(2) else if image_dump if !@@ms_windows DCL::swcset("fname", @@dumpdir + @set[:admin][:basename]) DCL::swlset("lwnd", false) DCL::gropn(4) print "DUMP IMAGE FILE\n" else DCL::swlset("ldump", true) DCL::gropn(1) end else DCL::gropn(1) end end DCL::sglset("lfull", true) DCL::sgpset("isub", 96) DCL::gllset("lmiss", true) if ( @set[:admin][:xdiv] > 1 || @set[:admin][:ydiv] > 1) DCL::sldiv('y',@set[:admin][:xdiv],@set[:admin][:ydiv]) end GGraph::set_fig(@set[:fig]) if @set[:fig] GGraph::set_map(@set[:map]) if @set[:map] GGraph::set_axes(@set[:axes]) if @set[:axes] GGraph::set_contour(@set[:contour]) if @set[:contour] GGraph::set_tone(@set[:tone]) if @set[:tone] end def finish DCL::grcls end def tone_cont(gphys, opt) newfrm = opt.delete(:newfrm) contour = opt.delete(:contour) tone = opt.delete(:tone) color_bar = opt.delete(:color_bar) color_bar_options = opt.delete(:color_bar_options) if color_bar_options && !color_bar_options.is_a?(Hash) raise ":color_bar_options must be a Hash" end if @set[:fig] && (itr=@set[:fig]['itr']) && itr>=10 lon = gphys.coord(0) lat = gphys.coord(1) if lon.min >= 120 && lon.max <= 150 && lat.min >= 20 && lat.max <=50 GGraph::set_map({'coast_japan'=>true}) else GGraph::set_map({'coast_world'=>true}) end if itr==31 DCL.sgpset('lclip',true) GGraph.set_map('vpt_boundary'=>3) end end tone = contour = true if !tone && !contour # should be what is meant if tone GGraph::tone(gphys, newfrm, opt) newfrm = false end if contour GGraph::contour(gphys, newfrm, opt) newfrm = false end if tone && color_bar cbopt = color_bar_options || Hash.new cbopt['log'] = true if opt['log'] GGraph::color_bar(cbopt) end newfrm end def vector(gpx, gpy, opt) newfrm = opt.delete(:newfrm) GGraph::set_unit_vect_options('vyuoff'=>-0.1,'vxuoff'=>0.07) GGraph::vector(gpx, gpy, newfrm, opt) end def plot_1d(gphys, opt) newfrm = opt.delete(:newfrm) contour = opt.delete(:contour) line = opt.delete(:line) mark = opt.delete(:mark) line = mark = true if !line && !mark # should be what is meant if line GGraph::line(gphys, newfrm, opt) newfrm = false end if mark GGraph::mark(gphys, newfrm, opt) newfrm = false end newfrm end end end ########## ENDOFLIB ########## if __FILE__ == $0 if ARGV.length == 0 raise <<-EOS USAGE: % ruby #{__FILE__} menu [dumpdir] where menu=0,1,2,.. EOS end test_menu = ARGV[0].to_i NumRu::VizShot.dumpdir = ARGV[1] if ARGV[1] case test_menu when 0 viz = NumRu::VizShot.new(:iwidth=>700,:iheight=>500) viz.set_fig('viewport'=>[0.15,0.85,0.2,0.55]) viz.set_tone('tonc'=>true) viz.plot( :method => :tone_cont, :file => "../../testdata/T.jan.nc", :var=> "T", :cut => {'level'=>400}, :color_bar=>true, "title"=>"T and [U,V]" ) viz.plot( :method => :vector, :file => "../../testdata/UV.jan.nc", :var=> "U", :var2=> "V" , :cut => {'level'=>400}, "unit_vect" => true ) # You can give GGraph options using string keys. paths = viz.dump_code_and_data(nil, true) print "\n!!! Code and data stored in #{paths.inspect} !!!\n\n" viz.execute when 1 viz = NumRu::VizShot.new(:iwidth=>700,:iheight=>500) viz.set_fig('itr'=>10, 'viewport'=>[0.15,0.85,0.2,0.55]) viz.plot( :method => :tone_cont, :file => "../../testdata/T.jan.nc", :var=> "T", :cut => {'lon'=>90..270,'lat'=>0..90,'level'=>600}, :color_bar=>true) path = viz.dump_code(nil, true, :image_dump => true) print "\n!!! Code written in #{path} !!!\n\n" viz.execute(:image_dump => true) when 2 viz = NumRu::VizShot.new viz.set_fig('itr'=>31, 'viewport'=>[0.15,0.85,0.15,0.85]) viz.plot( :method => :tone_cont, :file => "../../testdata/T.jan.nc", :var=> "T", :cut => {'lat'=>10..90,'level'=>600}, :color_bar=>true) path = viz.dump_code print "\n!!! Code written in #{path} !!!\n\n" viz.execute when 3 viz = NumRu::VizShot.new viz.plot( :method => :plot_1d, :file => "../../testdata/T.jan.nc", :var=> "T", :cut => {'lon'=>135}, "index"=>2, :line => true, :mark => true ) path = viz.dump_code print "\n!!! Code written in #{path} !!!\n\n" viz.execute when 4 # you can use :method=>:line instead of :method=>:plot_1d && :line=>true viz = NumRu::VizShot.new viz.plot( :method => :line, :file => "../../testdata/T.jan.nc", :var=> "T", :cut => {'lon'=>135}, "index"=>2, "type"=>2 ) path = viz.dump_code print "\n!!! Code written in #{path} !!!\n\n" viz.execute when 5 viz = NumRu::VizShot.new(:iwidth=>700,:iheight=>500,:xdiv=>2,:ydiv=>2) viz.set_fig('viewport'=>[0.15,0.85,0.2,0.55]) [1000,600,400,200].each do |lev| viz.plot( :method => :tone_cont, :newfrm=>true, :file => "../../testdata/T.jan.nc", :var=> "T", :cut => {'level'=>lev}, :color_bar=>true) end path = viz.dump_code print "\n!!! Code written in #{path} !!!\n\n" viz.execute when 6 viz = NumRu::VizShot.new(:iwidth=>700,:iheight=>500,:xdiv=>2,:ydiv=>2) viz.set_fig('viewport'=>[0.2,0.8,0.27,0.6]) viz.plot( :method => :tone_cont, :newfrm=>true, :file => "../../testdata/T.jan.nc", :var=> "T", :cut => {'level'=>1000}, :color_bar=>true, :color_bar_options=>{'vlength'=>0.25}) viz.plot( :method => :tone_cont, :newfrm=>true, :file => "../../testdata/T.jan.nc", :var=> "T", :cut => {'level'=>1000}, :color_bar=>true, :color_bar_options=>{'labelintv'=>1}) viz.plot( :method => :tone_cont, :newfrm=>true, :file => "../../testdata/T.jan.nc", :var=> "T", :cut => {'level'=>1000}, :color_bar=>true, :color_bar_options=>{'landscape'=>true, 'labelintv'=>1, 'vlength'=>0.6}) path = viz.dump_code print "\n!!! Code written in #{path} !!!\n\n" viz.execute end end