Personal tools

Difference between revisions of "Ruby examples"

From MohidWiki

Jump to: navigation, search
(PatternTransform)
(PatternTransform)
Line 1: Line 1:
 
==PatternTransform==
 
==PatternTransform==
 
In this example, we'll see how to use a couple of classes in a ruby program in order to execute in a batch a series of actions to perform with the MOHID utility tools, such as [[ConvertToHdf5]] or [[Hdf5Extractor]].
 
In this example, we'll see how to use a couple of classes in a ruby program in order to execute in a batch a series of actions to perform with the MOHID utility tools, such as [[ConvertToHdf5]] or [[Hdf5Extractor]].
 +
 +
Concretely speaking, the example takes a template file with the configuration of the MOHID utility (such as ''ConvertToHdf5Action.dat'' or ''Hdf5Extractor.dat'') and file with a list of substitutions to perform on the template configuration file, one line per configuration file.
 +
 +
===Template file===
 +
Here is an example of the template file:
 +
#root_Hydro_HDF5Extractor.dat
 +
OUTPUTFILENAME          : MOHID_HYDRO_XX.hdf5
 +
 +
FILENAME                : ../Glue/MOHID_HYDRO_XX.hdf5
 +
 +
START_TIME              : 2004 MM SDD 0 0 0
 +
END_TIME                : 2004 MM EDD 0 0 0
 +
 +
CONVERT_V3_TO_V4        : 0
 +
 +
<BeginParameter>
 +
PROPERTY                : velocity U
 +
HDF_GROUP                : /Results/velocity U
 +
<EndParameter>
 +
 +
<BeginParameter>
 +
PROPERTY                : velocity V
 +
HDF_GROUP                : /Results/velocity V
 +
<EndParameter>
 +
 +
<BeginParameter>
 +
PROPERTY                : water level
 +
HDF_GROUP                : /Results/water level
 +
<EndParameter>
 +
 +
===Substitutions list===
 +
Here is the file containing the list of substitutions to perform on the above template:
 +
#List.txt
 +
(XX) (MM) (EDD) (SDD)
 +
01    1    31  2
 +
02    2    29  1
 +
03    3    31  1
 +
04    4    30  1
 +
05    5    31  1
 +
06    6    30  1
 +
07    7    31  1
 +
08    8    31  1
 +
09    9    30  1
 +
10    10    31  1
 +
11    11    30  1
 +
12    12    31  1
 +
 +
The first line contains the list of strings to match in the template file (such as ''XX'' or ''MM''). Each string to match is between parentheses. The strings to match are space-separated.
 +
The following lines containg the strings to substitute, space-separated. Each new line will correspond to a new configuration file.
 +
 +
===Program file===
 +
Here is the program code that will generate the suite of configuration files and run the batch of
 +
transformations with ''HDF5Extract'':
  
 
<htm>
 
<htm>

Revision as of 13:55, 27 March 2010

PatternTransform

In this example, we'll see how to use a couple of classes in a ruby program in order to execute in a batch a series of actions to perform with the MOHID utility tools, such as ConvertToHdf5 or Hdf5Extractor.

Concretely speaking, the example takes a template file with the configuration of the MOHID utility (such as ConvertToHdf5Action.dat or Hdf5Extractor.dat) and file with a list of substitutions to perform on the template configuration file, one line per configuration file.

Template file

Here is an example of the template file:

#root_Hydro_HDF5Extractor.dat
OUTPUTFILENAME           : MOHID_HYDRO_XX.hdf5

FILENAME                 : ../Glue/MOHID_HYDRO_XX.hdf5

START_TIME               : 2004 MM SDD 0 0 0
END_TIME                 : 2004 MM EDD 0 0 0

CONVERT_V3_TO_V4         : 0

<BeginParameter>
PROPERTY                 : velocity U
HDF_GROUP                : /Results/velocity U
<EndParameter>

<BeginParameter>
PROPERTY                 : velocity V
HDF_GROUP                : /Results/velocity V
<EndParameter>

<BeginParameter>
PROPERTY                 : water level
HDF_GROUP                : /Results/water level
<EndParameter>

Substitutions list

Here is the file containing the list of substitutions to perform on the above template:

#List.txt
(XX) (MM) (EDD) (SDD)
01    1     31  2
02    2     29  1
03    3     31  1
04    4     30  1
05    5     31  1
06    6     30  1
07    7     31  1
08    8     31  1
09    9     30  1
10    10    31  1
11    11    30  1
12    12    31  1

The first line contains the list of strings to match in the template file (such as XX or MM). Each string to match is between parentheses. The strings to match are space-separated. The following lines containg the strings to substitute, space-separated. Each new line will correspond to a new configuration file.

Program file

Here is the program code that will generate the suite of configuration files and run the batch of transformations with HDF5Extract:


require "patterntransform"

hextract = IsTheActionToPerformWithFiles.new("root_Hydro_HDF5Extractor.dat", "list.txt")
hextract.transformsInto("Hydro_HDF5Extractor")
hextract.usesAGenericMohidtoolBatchfile("HydroExtract.bat", "HDF5Extractor.exe", "HDF5Extractor.dat")
hextract.ing

wextract = IsTheActionToPerformWithFiles.new("root_Water_HDF5Extractor.dat", "list.txt")
wextract.transformsInto("Water_HDF5Extractor")
wextract.usesAGenericMohidtoolBatchfile("WaterExtract.bat", "HDF5Extractor.exe", "HDF5Extractor.dat")
wextract.ing


Class IsTheRootStringToTransform

class IsTheRootStringToTransform
  
  attr_reader :rootfilecontent, :list, :matches 
  attr_reader :matchexpr, :j, :outfilename, :batch
  
  def initialize (rootstring, list)
    @rootfilecontent, @list = rootstring, list
    @list = @list.to_a if !@list.is_a?(Array)
    @matchexpr = @list.shift
    @matches = @matchexpr.tr('()','').split(' ')
    @closings = @matchexpr.gsub(/\(.+?\)/, '*').split(/\*| /)
    puts @closings.join(' ')
  end
  
  def isTransformedByTheBlock
    @j = 1
    @list.each do |line|
      yield line
      @j = @j + 1
    end
  end
  
  def buildHashOfSubs(array)
    hash = Hash.new
    array.size.times { |i| hash.store(@matches[i], @closings[2*i].chomp + array[i] + @closings[2*i + 1].chomp) }
    return hash
  end
  
  def isTransformedIntoFile(filename)
    
    @outfilename = filename
    isTransformedByTheBlock{ |line|    
      filecontent = String.new( @rootfilecontent )
      
      tokens = line.split( ' ' )
      subhash = buildHashOfSubs(tokens)
      subhash.each { |match, sub| filecontent.replace filecontent.gsub(match, sub) }
      
      mytrgfile = File.new(filename + "_" + @j.to_s.rjust(3,"0") + ".dat", "w")
      mytrgfile.puts filecontent
      mytrgfile.close
      
      puts filecontent
    }
    
  end
  
  def hasTheFollowingBatchFileBlock(batchfilename)
    
    @batch = String.new
    
batchhead = <<HEAD
@echo off
for %%i in (#{@outfilename}_*.dat) do (
HEAD

    yield
    
batchfoot = <<FOOT
)
@echo on
FOOT

    batchfile = File.new(batchfilename, "w")
    batchfile.puts batchhead + @batch + batchfoot
    batchfile.close
    
  end

end


Class IsTheActionToPerformWith


class IsTheActionToPerformWith
  
  attr_reader :patterncontent, :listofsubs
  attr_reader :matchline, :batch
  
  def initialize (patterncontent, listofsubs)
    @patterncontent, @listofsubs = patterncontent, listofsubs
    @listofsubs = @listofsubs.to_a if !@listofsubs.is_a?(Array)
    @matchline = @listofsubs.shift
    @matches = @matchline.tr('()','').split(' ')
    @closings = @matchline.gsub(/\(.+?\)/, '*').split(/\*| /)
    puts @closings.join(' ')
  end
  
  #private
  def thePatternIsTransformedByTheBlock
    @j = 1
    @listofsubs.each do |line|
      yield line
      @j = @j + 1
    end
  end
  
  #private
  def buildHashOfSubs(array)
    hash = Hash.new
    array.size.times { |i| hash.store(@matches[i], @closings[2*i].chomp + array[i] + @closings[2*i + 1].chomp) }
    return hash
  end
  
  def usesTransformedFilesNamedAfter(filename)
    
    
    @outfilename = filename
    thePatternIsTransformedByTheBlock{ |line|    
      filecontent = String.new( @patterncontent )
      
      tokens = line.split( ' ' )
      subhash = buildHashOfSubs(tokens)
      subhash.each { |match, sub| filecontent.replace filecontent.gsub(match, sub) }
      
      mytrgfile = File.new(filename + "_" + @j.to_s.rjust(3,"0")  + ".dat", "w")
      mytrgfile.puts filecontent
      mytrgfile.close
      
      puts filecontent
    }
    
  end
  
  #Running
  def ing
    puts "Running #{@batchfilename}..."
  end
  
  #Running
  def ning
    ing
  end

#Method 1
  def usesTheFollowingBatchfileNameAndBlock(batchfilename)
    
    @batchfilename = batchfilename
    
    @batch = String.new
    
    batchhead = <<HEAD
    @echo off
    for %%i in (#{@outfilename}_*.dat) do (
HEAD

    yield
    
    batchfoot = <<FOOT
    )
    pause
    @echo on
FOOT

    batchfile = File.new(@batchfilename, "w")
    batchfile.puts batchhead + @batch + batchfoot
    batchfile.close
    
  end

  #Method 2
  def usesAGenericMohidtoolBatchfile(mohidtool, batchfilename, configfilename)
    usesTheFollowingBatchfileNameAndBlock(batchfilename){
      @batch = <<BATCH
      copy %%i #{configfilename}
      #{mohidtool}
BATCH
    }
  end
  
  def usesAGenericMohidtool(mohidtool, configfilename)
    usesAGenericMohidtoolBatchfile(mohidtool, "All_UseTool.bat", configfilename)
  end

#Methods 3
  def usesAConverttohdf5BatchfileNamed(batchfilename)
    usesAGenericMohidtoolBatchfile( "ConvertToHdf5.exe", batchfilename, "ConvertToHDF5Action.dat")
  end
  
  def usesAConvert2netcdfBatchfileNamed(batchfilename)
    usesAGenericMohidtoolBatchfile( "Convert2Netcdf.exe", batchfilename, "Convert2Netcdf.dat")
  end

end

class IsTheActionToPerformWithFiles < IsTheActionToPerformWith
  
  def initialize(patternfilename, listofsubsfilename)
    
    if File.exists?(patternfilename) and File.exists?(listofsubsfilename) then
      
      #patternfile = File.open(patternfilename)
      patterncontent = String.new( File.open(patternfilename).read )
      
      #listofsubsfile = File.open(listofsubsfilename)
      listofsubs = String.new( File.open(listofsubsfilename).read )
      
      super(patterncontent, listofsubs)
      
    else
      
      puts "Error: one or both of #{patternfilename} or #{listofsubsfilename} doesn't exist."
      
    end
    
  end
  
end

if __FILE__ == $0
  
mycontent = <<CONVERTTOHDF5ACTION
<begin_file>
ACTION                   : GLUES HDF5 FILES

OUTPUTFILENAME           : MOHID_WATER_01.hdf5
 
<<begin_listofsubs>>
..\\Extraction\\Stride_WaterProperties_1.hdf5
..\\Extraction\\Stride_WaterProperties_2.hdf5
<<end_listofsubs>>
<end_file>
CONVERTTOHDF5ACTION

mylistofsubs = <<listofsubs
_(01) s_(1). s_(2). (WATER) (WaterProperties)
   01      1        2    WATER   WaterProperties
   01      1        2    HYDRO   Hydrodynamic
   02      3        5    WATER   WaterProperties
   02      3        5    HYDRO   Hydrodynamic
listofsubs

  ## 1 Create ##########
  #You can create the class object with files ...
  glue = IsTheActionToPerformWithFiles.new("root_ConvertToHDF5Action.dat", "listofsubs.txt")  
  #... or with strings
  glue = IsTheActionToPerformWith.new(mycontent, mylistofsubs)  

  ## 2 Generate new files ##########
  glue.usesTransformedFilesNamedAfter("GlueAction")
  
  ## 3 Generate runscript ##########
  #You can easily customize the batchfile main loop ...
  glue.usesTheFollowingBatchfileNameAndBlock("GlueAllHdf5.bat") {
    glue.batch.replace <<BATCH
      copy %%i ConvertToHdf5Action.dat
      ConvertToHdf5.exe
BATCH
  }  
  #... or use a standard one
  glue.usesAConverttohdf5BatchfileNamed("GlueAllHdf5.bat")
  
  ## 4 Run ##########
  glue.ing
  
end