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 88 89 90 |
# 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 @axnames = axnames.dup 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 if (gp.axnames - @axnames).length > 0 raise ArgumentError, "Provided assoc coord '#{gp.name}' has an axis (axes) #{gp.axnames - @axnames} not in the present object #{@axnames}" end end # < some internal variables > @assoc_crds = Hash.new assoc_crds.each{|gp| @assoc_crds[gp.name] = gp} @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.
92 93 94 |
# File 'lib/numru/gphys/assoccoords.rb', line 92 def axlens @axlens end |
Instance Method Details
#[](*args) ⇒ Object
slicing in terms of the original axes
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/numru/gphys/assoccoords.rb', line 219 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
113 114 115 |
# File 'lib/numru/gphys/assoccoords.rb', line 113 def coord(name) @assoc_crds[name].data # return a VArray end |
#coord_gphys(name) ⇒ Object
126 127 128 |
# File 'lib/numru/gphys/assoccoords.rb', line 126 def coord_gphys(name) @assoc_crds[name] # return a GPhys end |
#coordnames ⇒ Object
134 135 136 |
# File 'lib/numru/gphys/assoccoords.rb', line 134 def coordnames @assoc_crds.keys end |
#copy ⇒ Object
109 110 111 |
# File 'lib/numru/gphys/assoccoords.rb', line 109 def copy self.class.new( @assoc_crds.values.collect{|gp| gp.copy}, @axnames ) end |
#cut(hash) ⇒ Object
assoc_crds に関する座標値ベースの切り出し : 引数は Hash のみ
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 213 214 215 |
# File 'lib/numru/gphys/assoccoords.rb', line 139 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
130 131 132 |
# File 'lib/numru/gphys/assoccoords.rb', line 130 def has_coord?(name) @assoc_crds.has_key?(name) end |
#inspect ⇒ Object
105 106 107 |
# File 'lib/numru/gphys/assoccoords.rb', line 105 def inspect "<AssocCoords #{@assoc_crds.collect{|nm,gp| gp.data.inspect}.join("\n\t")}\n\t#{@groups.inspect}>" end |
#lost_coords ⇒ Object
262 263 264 |
# File 'lib/numru/gphys/assoccoords.rb', line 262 def lost_coords @lost_assoc_crds.dup end |
#merge(other) ⇒ Object
95 96 97 98 99 100 101 102 103 |
# File 'lib/numru/gphys/assoccoords.rb', line 95 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
117 118 119 120 121 122 123 124 |
# File 'lib/numru/gphys/assoccoords.rb', line 117 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
257 258 259 260 |
# File 'lib/numru/gphys/assoccoords.rb', line 257 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
248 249 250 251 252 253 254 255 |
# File 'lib/numru/gphys/assoccoords.rb', line 248 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 |