Class: NumRu::AssocCoords
- Inherits:
-
Object
- Object
- NumRu::AssocCoords
- Defined in:
- lib/numru/gphys/assoccoords.rb,
ext/numru/gphys/ext_coord.c
Overview
Associated coordinates
To use in a Grid in order to support non-rectangular coordnate systems
Instance Attribute Summary collapse
-
#axlens ⇒ Object
readonly
Returns the value of attribute axlens.
Instance Method Summary collapse
-
#[](*args) ⇒ Object
slicing in terms of the original axes.
- #coord(name) ⇒ Object
- #coord_gphys(name) ⇒ Object
- #coordnames ⇒ Object
- #copy ⇒ Object
-
#cut(hash) ⇒ Object
assoc_crds に関する座標値ベースの切り出し : 引数は Hash のみ.
- #has_coord?(name) ⇒ Boolean
-
#initialize(assoc_crds, axnames) ⇒ AssocCoords
constructor
-
assoc_crds : Array of GPhys * axnames : Array of axis names of the original Grid.
-
- #inspect ⇒ Object
- #lost_coords ⇒ Object
- #merge(other) ⇒ Object
- #replace(gphys) ⇒ Object
- #set_lost_coords(lost_assoc_crds) ⇒ Object
-
#subset_having_axnames(axnames) ⇒ Object
make a subset with assoc coords related only to axnames.
Constructor Details
#initialize(assoc_crds, axnames) ⇒ AssocCoords
-
assoc_crds : Array of GPhys
-
axnames : Array of axis names of the original Grid
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 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 86 87 |
# File 'lib/numru/gphys/assoccoords.rb', line 16 def initialize(assoc_crds, axnames) # < argument check > if assoc_crds.uniq.length != assoc_crds.length raise ArgumentError, "Names are not uniq: #{assoc_crds.inspect}." end assoc_crds.each do |gp| raise(ArgumentError,"Non-GPhys included") if !gp.is_a?(GPhys) if axnames.include?(gp.name) raise ArgumentError, "'#{gp.name}' overwraps an axis name #{axnames.inspect}." end end # < some internal variables > @assoc_crds = Hash.new assoc_crds.each{|gp| @assoc_crds[gp.name] = gp} @axnames = axnames.dup @lost_assoc_crds = nil # < lengths of original axes > @axlens = Hash.new @axnames.each do |nm| len = nil lens = nil assoc_crds.each do |gp| if gp.axnames.include?(nm) len = gp.axis(nm).length if lens && len!=lens raise("Inconsistency in assoc coord length for ax #{nm}: #{len} (#{gp.name}) vs #{lens}") end lens = len end end @axlens[nm] = len # can be nil end # < grouping in terms of original-dimension sharing > @groups = Hash.new # axnames => assoc coord names assoc_crds.each do |gp| pushed = false axnames_sv = acnames_sv = nil @groups.each do | axnames, acnames | a = gp.axnames if (axnames - a).length < axnames.length # included? unless pushed # first time in this loop axnames.concat(a).uniq! acnames.push(gp.name) axnames_sv = axnames acnames_sv = acnames else # second or greater time in this loop --> need merger to the first @groups.delete(axnames) axnames_sv.concat(axnames).uniq! acnames_sv.concat(acnames).uniq! end pushed = true #break # <-- old code; this doesn't work end end @groups[ gp.axnames ] = [gp.name] if !pushed # new group end # < sort keys in @groups in the order of original axes > # -- though its necesity was not originally supposed, but... @groups.each_key do |axnames| axnames.replace( @axnames - (@axnames - axnames) ) end end |
Instance Attribute Details
#axlens ⇒ Object (readonly)
Returns the value of attribute axlens.
89 90 91 |
# File 'lib/numru/gphys/assoccoords.rb', line 89 def axlens @axlens end |
Instance Method Details
#[](*args) ⇒ Object
slicing in terms of the original axes
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/numru/gphys/assoccoords.rb', line 216 def [](*args) return self.dup if args.length == 0 args = __rubber_expansion( args ) slicer = Hash.new @axnames.each_with_index{|nm,i| slicer[nm] = args[i]} new_assoc_crds = Array.new lost_assoc_crds = Array.new @assoc_crds.each do |dummy, gp| sub = gp[ *( gp.axnames.collect{|nm| slicer[nm] || true} ) ] if sub.rank > 0 new_assoc_crds.push( sub ) else lost_assoc_crds.push( "#{sub.name}=#{sub.val}" ) end end axnames = Array.new args.each_with_index do |a, i| axnames.push @axnames[i] unless Numeric === a end ret = self.class.new( new_assoc_crds, axnames ) ret.set_lost_coords( lost_assoc_crds ) if !lost_assoc_crds.empty? ret end |
#coord(name) ⇒ Object
110 111 112 |
# File 'lib/numru/gphys/assoccoords.rb', line 110 def coord(name) @assoc_crds[name].data # return a VArray end |
#coord_gphys(name) ⇒ Object
123 124 125 |
# File 'lib/numru/gphys/assoccoords.rb', line 123 def coord_gphys(name) @assoc_crds[name] # return a GPhys end |
#coordnames ⇒ Object
131 132 133 |
# File 'lib/numru/gphys/assoccoords.rb', line 131 def coordnames @assoc_crds.keys end |
#copy ⇒ Object
106 107 108 |
# File 'lib/numru/gphys/assoccoords.rb', line 106 def copy self.class.new( @assoc_crds.values.collect{|gp| gp.copy}, @axnames ) end |
#cut(hash) ⇒ Object
assoc_crds に関する座標値ベースの切り出し : 引数は Hash のみ
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/numru/gphys/assoccoords.rb', line 136 def cut(hash) cutaxnms = hash.keys newcrds = Array.new slicer_hash = Hash.new @groups.each do |orgaxnms, group| ca2 = cutaxnms - group if ca2.length < cutaxnms.length # Some of cutaxnms are included in group # --> Do cutting regarding this group crds = Array.new crdnms = Array.new crdaxexist = Array.new masks = Array.new # for NArrayMiss cuts = Array.new group.each do |nm| cutter = hash[nm] if !cutter.nil? && cutter!=true && cutter!=(0..-1) crdnms.push( nm ) cuts.push( hash[nm] ) anms = @assoc_crds[nm].axnames crdaxexist.push( NArray.to_na( orgaxnms.collect{|a| anms.include?(a) ? 1 : 0} ) ) v = @assoc_crds[nm].val # 座標値 (NArray or NArrayMiss) if v.is_a?(NArrayMiss) crds.push(v.to_na) masks.push(v.get_mask) else crds.push(v) masks.push(nil) end end end cuttype = cuts.collect{|x| x.class}.uniq if cuttype.length == 1 orgaxlens = @axlens.values_at(*orgaxnms) if cuttype[0] == Range vmins = Array.new vmaxs = Array.new cuts.each do |range| a = range.first b = range.last if (b<a) vmins.push(b) vmaxs.push(a) else vmins.push(a) vmaxs.push(b) end end idxs = cut_range(vmins,vmaxs,crds,masks,crdaxexist,orgaxlens) elsif cuttype[0] == Numeric raise "SORRY! cut_nearest is yet to be implemented." idxs = cut_nearest() # YET TO BE IMPLEMENT else raise ArgumentError, "Not allowed cutting type (#{cuttype[0]})" end ncrds = group.collect{ |nm| gp = @assoc_crds[nm] sl = gp.axnames.collect{|anm| idxs[orgaxnms.index(anm)]} gp[ *sl ] } newcrds.concat( ncrds ) orgaxnms.each_with_index{|nm,i| slicer_hash[nm] = idxs[i]} else raise "Cutting specification for a group of assoc coords (here, #{group.inspect}) must be uniformly set to either by range or by point -- Cannot mix." end else # None of cutaxnms are included in group --> just copy ncrds = group.collect{ |nm| @assoc_crds[nm] } newcrds.concat( ncrds ) end cutaxnms = ca2 break if cutaxnms.length == 0 # cutting finished end new_assocoords = self.class.new( newcrds, @axnames ) [ new_assocoords, slicer_hash ] end |
#has_coord?(name) ⇒ Boolean
127 128 129 |
# File 'lib/numru/gphys/assoccoords.rb', line 127 def has_coord?(name) @assoc_crds.has_key?(name) end |
#inspect ⇒ Object
102 103 104 |
# File 'lib/numru/gphys/assoccoords.rb', line 102 def inspect "<AssocCoords #{@assoc_crds.collect{|nm,gp| gp.data.inspect}.join("\n\t")}\n\t#{@groups.inspect}>" end |
#lost_coords ⇒ Object
259 260 261 |
# File 'lib/numru/gphys/assoccoords.rb', line 259 def lost_coords @lost_assoc_crds.dup end |
#merge(other) ⇒ Object
92 93 94 95 96 97 98 99 100 |
# File 'lib/numru/gphys/assoccoords.rb', line 92 def merge(other) if other.nil? self else ac = self.assoc_crds.merge(other.assoc_crds) an = (self.axnames + other.axnames).uniq self.class.new(ac,an) end end |
#replace(gphys) ⇒ Object
114 115 116 117 118 119 120 121 |
# File 'lib/numru/gphys/assoccoords.rb', line 114 def replace(gphys) raise(ArgumentError,"not a GPhys") unless gphys.is_a?(GPhys) nm = gphys.name raise("assoc coord '#{nm}' is not found") unless (old=@assoc_crds[nm]) raise("shapes of the current and new '#{nm}' are different") unless old.shape==gphys.shape @assoc_crds[nm] = gphys self end |
#set_lost_coords(lost_assoc_crds) ⇒ Object
254 255 256 257 |
# File 'lib/numru/gphys/assoccoords.rb', line 254 def set_lost_coords( lost_assoc_crds ) @lost_assoc_crds = lost_assoc_crds # Array of String self end |
#subset_having_axnames(axnames) ⇒ Object
make a subset with assoc coords related only to axnames
245 246 247 248 249 250 251 252 |
# File 'lib/numru/gphys/assoccoords.rb', line 245 def subset_having_axnames( axnames ) acnms = Array.new @groups.each do |ks,vs| acnms.concat(vs) if ( (ks-axnames).length == 0 ) # all of ks present end assoc_crds = acnms.collect{|nm| @assoc_crds[nm]} self.class.new(assoc_crds, axnames) end |