gphys 1.5.6 → 1.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/ChangeLog +0 -7672
- data/bin/gpcut +12 -0
- data/bin/gpvect +88 -77
- data/bin/gpview +200 -103
- data/ext/numru/gphys/dim_op.c +336 -44
- data/ext/numru/gphys/ext_init.c +6 -0
- data/ext/numru/gphys/interpo.c +326 -3
- data/lib/numru/dclext.rb +78 -16
- data/lib/numru/ganalysis/beta_plane.rb +6 -4
- data/lib/numru/ganalysis/eof.rb +61 -41
- data/lib/numru/ganalysis/fitting.rb +86 -23
- data/lib/numru/ganalysis/histogram.rb +3 -3
- data/lib/numru/ganalysis/log_p.rb +20 -0
- data/lib/numru/ganalysis/lomb_scargle.rb +205 -0
- data/lib/numru/ganalysis/met_z.rb +132 -3
- data/lib/numru/ganalysis/narray_ext.rb +1 -1
- data/lib/numru/ganalysis/pde.rb +20 -1
- data/lib/numru/ganalysis/planet.rb +136 -1
- data/lib/numru/ganalysis/qg.rb +224 -3
- data/lib/numru/ggraph.rb +89 -18
- data/lib/numru/gphys/axis.rb +4 -2
- data/lib/numru/gphys/gphys_dim_op.rb +69 -6
- data/lib/numru/gphys/gphys_fft.rb +30 -0
- data/lib/numru/gphys/gphys_io_common.rb +2 -0
- data/lib/numru/gphys/grads_gridded.rb +77 -29
- data/lib/numru/gphys/grib.rb +2 -2
- data/lib/numru/gphys/grib_params.rb +3 -3
- data/lib/numru/gphys/interpolate.rb +153 -1
- data/lib/numru/gphys/varraycomposite.rb +7 -4
- data/lib/numru/gphys/version.rb +1 -1
- data/testdata/pres.jan.nc +0 -0
- metadata +6 -4
@@ -340,6 +340,7 @@ module NumRu
|
|
340
340
|
"cray_32bit_ieee"=>nil,
|
341
341
|
"365_day_calendar"=>nil,
|
342
342
|
"pdef"=>nil,
|
343
|
+
"edef"=>nil,
|
343
344
|
}
|
344
345
|
|
345
346
|
case(@mode)
|
@@ -380,7 +381,7 @@ module NumRu
|
|
380
381
|
end
|
381
382
|
|
382
383
|
def ndims
|
383
|
-
4
|
384
|
+
@options["edef"] ? 5 : 4
|
384
385
|
end
|
385
386
|
|
386
387
|
def nvars
|
@@ -480,7 +481,7 @@ module NumRu
|
|
480
481
|
end
|
481
482
|
@title = "<no title>" if @title==""
|
482
483
|
@undef = -999.0 if @undef==nil
|
483
|
-
|
484
|
+
ctl = <<EOS
|
484
485
|
DSET #{if @dset[0]=="/" then @dset else "^"+@dset end}
|
485
486
|
TITLE #{@title}
|
486
487
|
UNDEF #{@undef}
|
@@ -489,15 +490,23 @@ XDEF #{@dimensions[0][:len]} #{@dimensions[0][:flag]} #{@dimensions[0][:spec]
|
|
489
490
|
YDEF #{@dimensions[1][:len]} #{@dimensions[1][:flag]} #{@dimensions[1][:spec]}
|
490
491
|
ZDEF #{@dimensions[2][:len]} #{@dimensions[2][:flag]} #{@dimensions[2][:spec]}
|
491
492
|
TDEF #{@dimensions[3][:len]} #{@dimensions[3][:flag]} #{@dimensions[3][:spec]}
|
493
|
+
EOS
|
494
|
+
if ( @options["edef"] )
|
495
|
+
ctl += <<EOS
|
496
|
+
EDEF #{@dimensions[4][:len]} #{@dimensions[4][:flag]} #{@dimensions[4][:spec]}
|
497
|
+
EOS
|
498
|
+
end
|
499
|
+
ctl += <<EOS
|
492
500
|
VARS #{nvars}
|
493
501
|
#{@variables.collect{|i| i[:name]+" "+i[:nlev].to_s+" "+i[:option].to_s+
|
494
502
|
" "+i[:description]}.join("\n")}
|
495
503
|
ENDVARS
|
496
504
|
EOS
|
505
|
+
return ctl
|
497
506
|
end
|
498
507
|
|
499
508
|
def inspect
|
500
|
-
|
509
|
+
str = <<EOS
|
501
510
|
#{self.class}
|
502
511
|
file: #{@ctlfile.path}
|
503
512
|
DSET #{@dset}
|
@@ -506,11 +515,19 @@ XDIM #{@dimensions[0].inspect}
|
|
506
515
|
YDIM #{@dimensions[1].inspect}
|
507
516
|
ZDIM #{@dimensions[2].inspect}
|
508
517
|
TDIM #{@dimensions[3].inspect}
|
518
|
+
EOS
|
519
|
+
if ( @options["edef"] )
|
520
|
+
str += <<EOS
|
521
|
+
EDEF #{@dimensions[4].inspect}
|
522
|
+
EOS
|
523
|
+
end
|
524
|
+
str += <<EOS
|
509
525
|
VARS
|
510
526
|
#{@variables.collect{|i| " "+i[:name]+"\t"+i[:nlev].to_s+"\t"+i[:option].to_s+
|
511
527
|
"\t"+i[:description]}.join("\n")}
|
512
528
|
ENDVARS
|
513
529
|
EOS
|
530
|
+
return str
|
514
531
|
end
|
515
532
|
|
516
533
|
def put(ary)
|
@@ -530,7 +547,7 @@ EOS
|
|
530
547
|
|
531
548
|
end
|
532
549
|
|
533
|
-
def get(name, z, t, lonlat=nil)
|
550
|
+
def get(name, z, t, lonlat=nil, ens=nil)
|
534
551
|
|
535
552
|
# t: [0,1,2,..] : record number
|
536
553
|
# time: [0,1/24,2/24,...] days since 00:00Z01jan2000 : Numeric with units
|
@@ -593,6 +610,9 @@ EOS
|
|
593
610
|
init_min = target_date.min
|
594
611
|
@dset_r.gsub!( /%n2/, sprintf("%02d",init_min) )
|
595
612
|
end
|
613
|
+
if ( ens && @dset_r =~ /%e(\d+)/ )
|
614
|
+
@dset_r.gsub!( /%e(\d+)/, sprintf("%0#{$1}d",ens) )
|
615
|
+
end
|
596
616
|
|
597
617
|
# find t in the first record in the target file (="init_t")
|
598
618
|
# and determine the record number in the target file
|
@@ -609,10 +629,10 @@ EOS
|
|
609
629
|
|
610
630
|
t_in_target_file = t - init_t
|
611
631
|
|
612
|
-
start_byte = start_byte(name, z, t_in_target_file)
|
632
|
+
start_byte = start_byte(name, z, t_in_target_file, 0)
|
613
633
|
@datafile = File.open(@dset_r,"rb")
|
614
634
|
else
|
615
|
-
start_byte = start_byte(name, z, t)
|
635
|
+
start_byte = start_byte(name, z, t, ens)
|
616
636
|
@datafile = File.open(@dset,"rb")
|
617
637
|
end
|
618
638
|
|
@@ -777,9 +797,8 @@ EOS
|
|
777
797
|
else
|
778
798
|
raise "Invalid line: "+line
|
779
799
|
end
|
780
|
-
when /^\s*[
|
781
|
-
|
782
|
-
/^\s*([XYZT])DEF\s+(\d+)\s+(\S+)+(.*)$/i =~ line
|
800
|
+
when /^\s*[XYZTE]DEF/i
|
801
|
+
/^\s*([XYZTE])DEF\s+(\d+)\s+(\S+)+(.*)$/i =~ line
|
783
802
|
if ( (len=$2) && (flag=$3) && (spec=$4))
|
784
803
|
dim = {:len=>len.to_i, :flag=>flag, :spec=>spec}
|
785
804
|
case $1
|
@@ -802,8 +821,13 @@ EOS
|
|
802
821
|
dim[:name] = 't'
|
803
822
|
dim[:description] = 'time'
|
804
823
|
idim=3
|
824
|
+
when /E/i
|
825
|
+
dim[:name] = 'e'
|
826
|
+
dim[:description] = 'ensemble'
|
827
|
+
idim=4
|
828
|
+
@options["edef"] = true
|
805
829
|
end
|
806
|
-
if (idim
|
830
|
+
if (idim<3)
|
807
831
|
if (dim[:flag] =~ /LINEAR/i)
|
808
832
|
begin
|
809
833
|
dim[:start],dim[:increment] = spec.split.collect!{|i| i.to_f}
|
@@ -833,7 +857,7 @@ EOS
|
|
833
857
|
else
|
834
858
|
raise "invalid or not-yet-supported dimension flag: "+dim[:flag]
|
835
859
|
end
|
836
|
-
|
860
|
+
elsif idim==3
|
837
861
|
# idim = 3 --- time
|
838
862
|
if (dim[:flag] =~ /LINEAR/i)
|
839
863
|
start,increment= spec.split
|
@@ -845,6 +869,8 @@ EOS
|
|
845
869
|
else
|
846
870
|
raise "invalid dimension flag(only LINEAR is available for time)"
|
847
871
|
end
|
872
|
+
else # idim==4 ensemble
|
873
|
+
dim[:levels] = NArray.sint(dim[:len]).indgen
|
848
874
|
end
|
849
875
|
@dimensions[idim]=dim
|
850
876
|
else
|
@@ -944,6 +970,7 @@ EOS
|
|
944
970
|
sy = sy*PI/180
|
945
971
|
sy2 = sy2*PI/180
|
946
972
|
xi = NArray.sfloat(imax).indgen(1) - bi
|
973
|
+
bj = jmax - bj if @options['yrev']
|
947
974
|
yj = NArray.sfloat(jmax).indgen(1) - bj
|
948
975
|
x = xi*dx
|
949
976
|
#y = -yj*dy
|
@@ -980,7 +1007,6 @@ EOS
|
|
980
1007
|
lon = NArray.sfloat(isize.to_i).indgen(1)
|
981
1008
|
lat = NArray.sfloat(jsize.to_i).indgen(1)
|
982
1009
|
end
|
983
|
-
p lon, lat
|
984
1010
|
|
985
1011
|
dim = {:len=>isize.to_i, :flag=>"levels"}
|
986
1012
|
dim[:name] = 'x'
|
@@ -1012,7 +1038,7 @@ EOS
|
|
1012
1038
|
|
1013
1039
|
end
|
1014
1040
|
|
1015
|
-
def start_byte(name, level, time)
|
1041
|
+
def start_byte(name, level, time, ens=0)
|
1016
1042
|
# offset to read an xy section of the variable with NAME
|
1017
1043
|
# at LEVEL(counted from 0) at TIME(conted from 0)
|
1018
1044
|
if (map = @map[name] )
|
@@ -1023,6 +1049,12 @@ EOS
|
|
1023
1049
|
raise "Time #{time} is not in the data period"
|
1024
1050
|
end
|
1025
1051
|
iblock = map[:start]+level*map[:zstep]+time*map[:tstep]
|
1052
|
+
if @options["edef"]
|
1053
|
+
if (ens<0 || ens>=@dimensions[4][:len])
|
1054
|
+
raise "Ens #{ens} is not in the data"
|
1055
|
+
end
|
1056
|
+
iblock += ens * map[:tstep] * @dimensions[3][:len]
|
1057
|
+
end
|
1026
1058
|
str_byte = map[:offset] + @dimensions[0][:len] * @dimensions[1][:len] * iblock
|
1027
1059
|
if( @options["sequential"] )
|
1028
1060
|
str_byte += iblock*2 + 4
|
@@ -1243,6 +1275,7 @@ EOS
|
|
1243
1275
|
@shape = [@dimensions[0][:len],@dimensions[1][:len],
|
1244
1276
|
@dimensions[2][:len],@dimensions[3][:len]]
|
1245
1277
|
@shape[2] = var[:nlev].to_i if( var[:nlev] )
|
1278
|
+
@shape[4] = @dimensions[4][:len] if @rank==5
|
1246
1279
|
|
1247
1280
|
@attr[:missing_value] = NArray.sfloat(1).fill!(@ctl.undef)
|
1248
1281
|
found = true
|
@@ -1414,8 +1447,8 @@ EOS
|
|
1414
1447
|
end
|
1415
1448
|
end
|
1416
1449
|
else
|
1417
|
-
h_sta = [0, 0, 0, 0]
|
1418
|
-
h_end = [-1, -1, -1, -1]
|
1450
|
+
h_sta = [0, 0, 0, 0, 0]
|
1451
|
+
h_end = [-1, -1, -1, -1, -1]
|
1419
1452
|
if hash == nil
|
1420
1453
|
# elsif hash.key?("index")==true
|
1421
1454
|
else
|
@@ -1439,12 +1472,27 @@ EOS
|
|
1439
1472
|
str_z = idx_z[h_sta[2]]; end_z = idx_z[h_end[2]]
|
1440
1473
|
str_t = idx_t[h_sta[3]]; end_t = idx_t[h_end[3]]
|
1441
1474
|
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1475
|
+
if @rank == 5 # has ensemble dimension
|
1476
|
+
idx_e = NArray.int(@shape[4]).indgen!
|
1477
|
+
str_e = idx_e[h_sta[4]]; end_e = idx_e[h_end[4]]
|
1478
|
+
na = NArrayMiss.new(vartype,end_x-str_x+1,end_y-str_y+1,end_z-str_z+1,end_t-str_t+1,end_e-str_e+1)
|
1479
|
+
for e in str_e..end_e
|
1480
|
+
for t in str_t..end_t
|
1481
|
+
for z in str_z..end_z
|
1482
|
+
na_xy = @ctl.get(@varname,z,t,[str_x,end_x,str_y,end_y],e)
|
1483
|
+
mask = ( na_xy.ne @ctl.undef )
|
1484
|
+
na[true,true,z-str_z,t-str_t,e-str_e] = NArrayMiss.to_nam(na_xy,mask)
|
1485
|
+
end
|
1486
|
+
end
|
1487
|
+
end
|
1488
|
+
else
|
1489
|
+
na = NArrayMiss.new(vartype,end_x-str_x+1,end_y-str_y+1,end_z-str_z+1,end_t-str_t+1)
|
1490
|
+
for t in str_t..end_t
|
1491
|
+
for z in str_z..end_z
|
1492
|
+
na_xy = @ctl.get(@varname,z,t,[str_x,end_x,str_y,end_y])
|
1493
|
+
mask = ( na_xy.ne @ctl.undef )
|
1494
|
+
na[true,true,z-str_z,t-str_t] = NArrayMiss.to_nam(na_xy,mask)
|
1495
|
+
end
|
1448
1496
|
end
|
1449
1497
|
end
|
1450
1498
|
end
|
@@ -1479,7 +1527,7 @@ EOS
|
|
1479
1527
|
stride = Array.new
|
1480
1528
|
set_stride = false
|
1481
1529
|
a.each{|i|
|
1482
|
-
if(i.is_a?(
|
1530
|
+
if(i.is_a?(Integer))
|
1483
1531
|
first.push(i)
|
1484
1532
|
last.push(i)
|
1485
1533
|
stride.push(1)
|
@@ -1511,7 +1559,7 @@ EOS
|
|
1511
1559
|
if n==0 then
|
1512
1560
|
k = at
|
1513
1561
|
if at > 0
|
1514
|
-
a[0..at-1].each{|x| if x.is_a?(
|
1562
|
+
a[0..at-1].each{|x| if x.is_a?(Integer) then k -= 1 end}
|
1515
1563
|
end
|
1516
1564
|
shape_tmp = na_tmp.shape
|
1517
1565
|
shape_tmp[k] = i.length
|
@@ -1523,7 +1571,7 @@ EOS
|
|
1523
1571
|
end
|
1524
1572
|
return na
|
1525
1573
|
else
|
1526
|
-
raise TypeError, "argument must be
|
1574
|
+
raise TypeError, "argument must be Integer, Range, Hash, TrueClass, Array, or NArray"
|
1527
1575
|
end
|
1528
1576
|
}
|
1529
1577
|
|
@@ -1534,7 +1582,7 @@ EOS
|
|
1534
1582
|
end
|
1535
1583
|
shape = na.shape
|
1536
1584
|
(a.length-1).downto(0){ |i|
|
1537
|
-
shape.delete_at(i) if a[i].is_a?(
|
1585
|
+
shape.delete_at(i) if a[i].is_a?(Integer)
|
1538
1586
|
}
|
1539
1587
|
na.reshape!( *shape )
|
1540
1588
|
na
|
@@ -1548,7 +1596,7 @@ EOS
|
|
1548
1596
|
stride = Array.new
|
1549
1597
|
set_stride = false
|
1550
1598
|
a.each{|i|
|
1551
|
-
if(i.is_a?(
|
1599
|
+
if(i.is_a?(Integer))
|
1552
1600
|
first.push(i)
|
1553
1601
|
last.push(i)
|
1554
1602
|
stride.push(1)
|
@@ -1575,13 +1623,13 @@ EOS
|
|
1575
1623
|
at = a.index(i)
|
1576
1624
|
i = NArray.to_na(i) if i.is_a?(Array)
|
1577
1625
|
val = NArray.to_na(val) if val.is_a?(Array)
|
1578
|
-
rank_of_subset = a.dup.delete_if{|v| v.is_a?(
|
1626
|
+
rank_of_subset = a.dup.delete_if{|v| v.is_a?(Integer)}.length
|
1579
1627
|
if val.rank != rank_of_subset
|
1580
1628
|
raise "rank of the rhs (#{val.rank}) is not equal to the rank "+
|
1581
1629
|
"of the subset specified by #{a.inspect} (#{rank_of_subset})"
|
1582
1630
|
end
|
1583
1631
|
k = at
|
1584
|
-
a[0..at-1].each{|x| if x.is_a?(
|
1632
|
+
a[0..at-1].each{|x| if x.is_a?(Integer) then k -= 1 end}
|
1585
1633
|
if i.length != val.shape[k]
|
1586
1634
|
raise "length of the #{k+1}-th dim of rhs is incorrect "+
|
1587
1635
|
"(#{i.length} for #{val.shape[k]})"
|
@@ -1598,7 +1646,7 @@ EOS
|
|
1598
1646
|
end
|
1599
1647
|
return self
|
1600
1648
|
else
|
1601
|
-
raise TypeError, "argument must be
|
1649
|
+
raise TypeError, "argument must be Integer, Range, Hash, TrueClass, Array, or NArray"
|
1602
1650
|
end
|
1603
1651
|
}
|
1604
1652
|
|
data/lib/numru/gphys/grib.rb
CHANGED
@@ -1229,7 +1229,7 @@ class GPhys
|
|
1229
1229
|
nlon,nlat = shape
|
1230
1230
|
(nlon*nlat)==nlen+nmiss || raise("length is not collect")
|
1231
1231
|
if index
|
1232
|
-
index = index.collect{|el|
|
1232
|
+
index = index.collect{|el| Integer===el ? el..el : el}
|
1233
1233
|
il = index[0]
|
1234
1234
|
i0 = il.first
|
1235
1235
|
i1 = il.last
|
@@ -1980,7 +1980,7 @@ even when the time is unique (i.e., length of the time coordinate is 1).
|
|
1980
1980
|
(0..dlen-1).each{|i| imap[n-2][i] = i}
|
1981
1981
|
end
|
1982
1982
|
next
|
1983
|
-
when
|
1983
|
+
when Integer
|
1984
1984
|
sha[n] = 1
|
1985
1985
|
imap[n-2][ind] = 0
|
1986
1986
|
dimdel.push(n)
|
@@ -706,8 +706,8 @@ NAMES_UNITS = {
|
|
706
706
|
#150 COVMZ m2/s2 Covariance between meridional and zonal components of the wind. Defined as [uv]-[u][v], where "[]" indicates the mean over the indicated time span.
|
707
707
|
#151 COVTZ1 K*m/s Covariance between temperature and zonal component of the wind. Defined as [uT]-[u][T], where "[]" indicates the mean over the indicated time span.
|
708
708
|
#152 COVTM K*m/s Covariance between temperature and meridional component of the wind. Defined as [vT]-[v][T], where "[]" indicates the mean over the indicated time span.
|
709
|
-
PARAM_CLWMR => ["Cloud water", "CLWMR", "
|
710
|
-
PARAM_O3MR => ["Ozone mixing ratio", "O3MR", "
|
709
|
+
PARAM_CLWMR => ["Cloud water", "CLWMR", "kg/kg", nil],
|
710
|
+
PARAM_O3MR => ["Ozone mixing ratio", "O3MR", "kg/kg", nil],
|
711
711
|
#155 GFLUX W/m2 Ground Heat Flux
|
712
712
|
PARAM_CIN => ["Convective inhibition", "CIN", "J/kg", nil],
|
713
713
|
PARAM_CAPE => ["Convective Available Potential Energy", "CAPE", "J/kg", nil],
|
@@ -941,7 +941,7 @@ PARAM_CWORK => ["Cloud work function", "CWORK", "J/kg", nil],
|
|
941
941
|
PARAM_FGLU => ["U sfc momentum flux by long gravity wave", "FGLU", "N/m^2", nil],
|
942
942
|
PARAM_FGLV => ["V sfc momentum flux by long gravity wave", "FGLV", "N/m^2", nil],
|
943
943
|
PARAM_ADVUA => ["Advective zonal acceleration", "ADVUA", "m/s/day", nil],
|
944
|
-
PARAM_VWV => ["Column total of meridional water vapor flux", "VWV", "
|
944
|
+
PARAM_VWV => ["Column total of meridional water vapor flux", "VWV", "kg/m/s", nil],
|
945
945
|
PARAM_FGSV => ["V sfc momentum flux by short gravity wave", "FGSV", "N/m^2", nil],
|
946
946
|
PARAM_GFLX => ["Ground heat flux", "GFLX", "W/m^2", nil],
|
947
947
|
PARAM_UWV => ["Column total of zonal water vapor flux", "UWV", "kg/m/s", nil],
|
@@ -210,6 +210,85 @@ module NumRu
|
|
210
210
|
interpolate(*coords)
|
211
211
|
end
|
212
212
|
|
213
|
+
# Regrid for equally spaced grid (or index based regrid)
|
214
|
+
#
|
215
|
+
# ARGUMENTS
|
216
|
+
# * axes [Array of Axis (or 1D VArray)] : if 1D VArray, an Axis is created
|
217
|
+
# * poses [Array of multi-D VArray (or GPhys)] : specifies where to
|
218
|
+
# regrid. lengths of poses and axes must agree. The shape of each of pos
|
219
|
+
# must be equal to the shape suggested by axes (i.e., corrected lengths
|
220
|
+
# of axes). poses must have non-overwrapping names.
|
221
|
+
# Each pos (an element of poses) must have a name equal to
|
222
|
+
# a main coordinate varible (or a coordinate variable plus "_index").
|
223
|
+
# E.g., if self has axes named ["x", "y", "t"], the name of a pos
|
224
|
+
# must be one of "x", "y", "t", "x_index", "y_index", "t_index".
|
225
|
+
# No two pos must share the coordinate name (w or wo _index).
|
226
|
+
def regrid2( axes, poses )
|
227
|
+
if axes.length != poses.length
|
228
|
+
raise(ArgumentError, "lengths of axes and poses do not agree")
|
229
|
+
end
|
230
|
+
axes = axes.map{|x| x.is_a?(VArray) ? Axis.new.set_pos(x) : x }
|
231
|
+
newshape = axes.map{|x| x.length}
|
232
|
+
dims = Array.new
|
233
|
+
cyclics = Array.new
|
234
|
+
axnms = axnames
|
235
|
+
eps = 1e-4
|
236
|
+
ndims = poses.length
|
237
|
+
scidxs = poses.map do |pos|
|
238
|
+
if pos.shape != newshape
|
239
|
+
raise(ArgumentError, "lengths of axes and poses do not agree")
|
240
|
+
end
|
241
|
+
nm = pos.name
|
242
|
+
index_type = false # initialization
|
243
|
+
d = axnms.index(nm)
|
244
|
+
if !d
|
245
|
+
d = axnms.index(nm.sub(/_index$/,''))
|
246
|
+
raise("pos #{nm} does not match any of the axis names") if !d
|
247
|
+
index_type = true
|
248
|
+
end
|
249
|
+
dims.push(d)
|
250
|
+
cyclics.push( axis(d).cyclic_extendible? )
|
251
|
+
v = pos.val
|
252
|
+
if v.is_a?(NArrayMiss)
|
253
|
+
if v.get_mask.count_false == 0
|
254
|
+
v = v.to_na
|
255
|
+
else
|
256
|
+
raise ArgumentError, "pos cannot have data missing"
|
257
|
+
end
|
258
|
+
end
|
259
|
+
if index_type
|
260
|
+
v
|
261
|
+
else
|
262
|
+
cval = coord(d).val
|
263
|
+
c0 = cval[0]
|
264
|
+
dc = (cval[-1] - cval[0])/(shape[d]-1.0)
|
265
|
+
if (cval[1]-cval[0] - dc).abs > eps*dc
|
266
|
+
raise("coordinate #{nm} is not equally spaced." +
|
267
|
+
" Use index based spacification if possible.")
|
268
|
+
end
|
269
|
+
(v - c0)/dc
|
270
|
+
end
|
271
|
+
end
|
272
|
+
na = val
|
273
|
+
if na.is_a?(NArrayMiss)
|
274
|
+
mask = na.get_mask
|
275
|
+
na = na.to_na
|
276
|
+
else
|
277
|
+
mask = NArray.byte( *na.shape )
|
278
|
+
mask = mask.fill!(1)
|
279
|
+
end
|
280
|
+
|
281
|
+
rval, rmask = c_regrid2_w_idx(na, mask, dims, scidxs, cyclics)
|
282
|
+
|
283
|
+
newdata = VArray.new( NArrayMiss.to_nam(rval, rmask), @data, name )
|
284
|
+
newaxes = (0...rank).map{|d| axis(d)}
|
285
|
+
(0...dims.length).each do |d|
|
286
|
+
newaxes[ dims[d] ] = axes[d]
|
287
|
+
end
|
288
|
+
newgrid = Grid.new( *newaxes )
|
289
|
+
GPhys.new( newgrid, newdata )
|
290
|
+
end
|
291
|
+
|
213
292
|
# Reverse the main data (i.e., the dependent variable) and one of the
|
214
293
|
# coordinates (an independent variable) through interpolation.
|
215
294
|
#
|
@@ -424,6 +503,50 @@ module NumRu
|
|
424
503
|
ret
|
425
504
|
end
|
426
505
|
|
506
|
+
# interpolate data missing alon dim's dimention
|
507
|
+
#
|
508
|
+
# ARGUMENTS:
|
509
|
+
# * dim [Integer or String] specifies the dimension
|
510
|
+
#
|
511
|
+
# * force_cyclic [nil, true, or Numeric] : if nil (default),
|
512
|
+
# cyclic interpolation is made only if the cyclic_extendible?
|
513
|
+
# applied to the dimension returns true (that is, the axis
|
514
|
+
# is cyclic and only one grid-point extension is needed).
|
515
|
+
# By setting true, cyclic extension is made as long as modulo
|
516
|
+
# is defined, irrespective of the remaining distances. By
|
517
|
+
# setting a Numeric, cyclic extension is forced by using its
|
518
|
+
# value as the modulo.
|
519
|
+
def interpolate_missing(dim, force_cyclic: nil)
|
520
|
+
dim = dim_index(dim)
|
521
|
+
ax = axis(dim)
|
522
|
+
modulo = nil
|
523
|
+
case force_cyclic
|
524
|
+
when nil
|
525
|
+
cyclic = ax.cyclic_extendible?
|
526
|
+
modulo = ax.modulo if cyclic
|
527
|
+
when true
|
528
|
+
modulo = ax.modulo
|
529
|
+
if modulo
|
530
|
+
cyclic = true
|
531
|
+
modulo = modulo[0]
|
532
|
+
else
|
533
|
+
cyclic = false
|
534
|
+
end
|
535
|
+
when Numeric
|
536
|
+
cyclic = true
|
537
|
+
modulo = force_cyclic
|
538
|
+
else
|
539
|
+
raise(ArgumentError, "force_cyclic must be nil, true, or Numeric")
|
540
|
+
end
|
541
|
+
v = self.val
|
542
|
+
na = v.to_na
|
543
|
+
mask = v.get_mask
|
544
|
+
x = ax.pos.val
|
545
|
+
ve, mask = c_interpo_missing(na,mask,dim,x,cyclic,modulo)
|
546
|
+
dat = VArray.new( NArrayMiss.to_nam(ve,mask), self.data, self.name )
|
547
|
+
GPhys.new(grid, dat)
|
548
|
+
end
|
549
|
+
|
427
550
|
private
|
428
551
|
|
429
552
|
def _interpo_find_position(crdmap)
|
@@ -987,7 +1110,36 @@ if $0 == __FILE__
|
|
987
1110
|
GGraph.tone gpcut,true,"int"=>0.15,"min"=>-1.05,"max"=>1.05
|
988
1111
|
GGraph.color_bar
|
989
1112
|
|
990
|
-
|
1113
|
+
GGraph::tone gdm,true,"color_bar"=>true, "title"=>"orig with missing"
|
1114
|
+
p gdm.coord(1).att_names, gdm.coord(1).val.to_a
|
1115
|
+
gde = gdm.interpolate_missing(1)
|
1116
|
+
GGraph::tone gde,true,"color_bar"=>true, "title"=>"missing interpolated (1, non-cyclic)"
|
1117
|
+
gde = gdm.interpolate_missing(1, force_cyclic: 2*Math::PI)
|
1118
|
+
GGraph::tone gde,true,"color_bar"=>true, "title"=>"missing interpolated (1, cyclic)"
|
1119
|
+
gde = gdm.interpolate_missing(0, force_cyclic: 2*Math::PI)
|
1120
|
+
GGraph::tone gde,true,"color_bar"=>true, "title"=>"missing interpolated (0, cyclic)"
|
1121
|
+
|
1122
|
+
nth = 40
|
1123
|
+
nr = 40
|
1124
|
+
theta = NArray.float(nth).indgen! * (Math::PI/2/(nth-1))
|
1125
|
+
#p "@@@@",gde.coord(0).val, gde.coord(1).val
|
1126
|
+
r = NArray.float(nr).indgen! * (8.0/nr)
|
1127
|
+
thax = Axis.new.set_pos( VArray.new(theta,
|
1128
|
+
{"long_name"=>"azimuth","units"=>"radian"}, "theta") )
|
1129
|
+
rax = Axis.new.set_pos( VArray.new(r,
|
1130
|
+
{"long_name"=>"r","units"=>"m"}, "r") )
|
1131
|
+
x = r.newdim(-1) * NMath.cos( theta.newdim(0) ) + gde.coord(0).val[0]
|
1132
|
+
y = r.newdim(-1) * NMath.sin( theta.newdim(0) ) + gde.coord(1).val[0]
|
1133
|
+
vx = VArray.new(x, {"long_name"=>"x","units"=>"m"}, "x")
|
1134
|
+
vy = VArray.new(y, {"long_name"=>"y","units"=>"m"}, "y")
|
1135
|
+
|
1136
|
+
GGraph::tone gdd[false,1],true,"color_bar"=>true
|
1137
|
+
gdr = gdd.regrid2( [rax, thax], [vx, vy] )
|
1138
|
+
GGraph::tone gdr[false,1],true,"color_bar"=>true, "keep"=>true, #"tonc"=>true,
|
1139
|
+
"title"=>"polar projected"
|
1140
|
+
#GGraph::contour gdr,false
|
1141
|
+
p "%%%", gdd, gdr
|
1142
|
+
|
991
1143
|
#< finish >
|
992
1144
|
DCL.grcls
|
993
1145
|
end
|
@@ -149,7 +149,9 @@ module NumRu
|
|
149
149
|
# p @bound_idx, @varrays
|
150
150
|
end
|
151
151
|
|
152
|
-
|
152
|
+
[:initialize_mapping, :mapping, :varray, :ary, :reshape].each do |method|
|
153
|
+
undef_method(method) if method_defined?(method)
|
154
|
+
end
|
153
155
|
|
154
156
|
def set_att(name,val)
|
155
157
|
@varrays.each{|va|
|
@@ -158,8 +160,6 @@ module NumRu
|
|
158
160
|
self
|
159
161
|
end
|
160
162
|
|
161
|
-
undef :mapping, :varray, :ary
|
162
|
-
|
163
163
|
def inspect
|
164
164
|
"<#{self.class.to_s} shape=#{shape.inspect} #_of_tiles=#{@bound_idx.collect{|b| b.length-1}.inspect}>"
|
165
165
|
# "bounds=#{@bound_idx.collect{|b| b[1..-2]}.inspect}"
|
@@ -203,6 +203,9 @@ module NumRu
|
|
203
203
|
raise TypeError, "Unexpected type #{v.class}"
|
204
204
|
end
|
205
205
|
end
|
206
|
+
if val.is_a?(NArray) && v.is_a?(NArrayMiss)
|
207
|
+
val = NArrayMiss.to_nam(val)
|
208
|
+
end
|
206
209
|
val[*vidx] = v
|
207
210
|
}
|
208
211
|
val
|
@@ -286,7 +289,7 @@ module NumRu
|
|
286
289
|
#def reshape!( *shape )
|
287
290
|
# raise "cannot reshape a #{class}. Use copy first to make it a VArray with NArray"
|
288
291
|
#end
|
289
|
-
undef reshape!
|
292
|
+
#undef reshape!
|
290
293
|
|
291
294
|
## Not needed, so far:
|
292
295
|
#def convention
|
data/lib/numru/gphys/version.rb
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gphys
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takeshi Horinouchi
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date:
|
15
|
+
date: 2025-10-13 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: narray
|
@@ -562,6 +562,7 @@ files:
|
|
562
562
|
- lib/numru/ganalysis/fitting.rb
|
563
563
|
- lib/numru/ganalysis/histogram.rb
|
564
564
|
- lib/numru/ganalysis/log_p.rb
|
565
|
+
- lib/numru/ganalysis/lomb_scargle.rb
|
565
566
|
- lib/numru/ganalysis/met.rb
|
566
567
|
- lib/numru/ganalysis/met_z.rb
|
567
568
|
- lib/numru/ganalysis/narray_ext.rb
|
@@ -630,6 +631,7 @@ files:
|
|
630
631
|
- testdata/UV.jan.nc
|
631
632
|
- testdata/assoc_crds.nc
|
632
633
|
- testdata/cira86.dat
|
634
|
+
- testdata/pres.jan.nc
|
633
635
|
homepage: http://www.gfd-dennou.org/arch/ruby/products/gphys/
|
634
636
|
licenses:
|
635
637
|
- BSD-2-Clause
|
@@ -651,8 +653,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
651
653
|
- !ruby/object:Gem::Version
|
652
654
|
version: '0'
|
653
655
|
requirements: []
|
654
|
-
|
655
|
-
rubygems_version: 2.5.2.1
|
656
|
+
rubygems_version: 3.2.5
|
656
657
|
signing_key:
|
657
658
|
specification_version: 4
|
658
659
|
summary: A multi-purpose class to handle Gridded Physical quantities
|
@@ -671,3 +672,4 @@ test_files:
|
|
671
672
|
- testdata/UV.jan.nc
|
672
673
|
- testdata/assoc_crds.nc
|
673
674
|
- testdata/cira86.dat
|
675
|
+
- testdata/pres.jan.nc
|