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
data/ext/numru/gphys/interpo.c
CHANGED
@@ -520,6 +520,327 @@ interpo_find_loc_1D_MD(obj, X, x, dimc, missval, extrapo)
|
|
520
520
|
return rb_ary_new3(2, na_ids, na_f);
|
521
521
|
}
|
522
522
|
|
523
|
+
/**
|
524
|
+
* @brief interpolate missing
|
525
|
+
*
|
526
|
+
* @details
|
527
|
+
* input data is converted into double (NArray's Float) type. So unuable for
|
528
|
+
* complex data.
|
529
|
+
*
|
530
|
+
* Supports cyclic interpolation. Extrapolation is not supported (so far).
|
531
|
+
*
|
532
|
+
* Returned is a two-element Array consisting of the interpolated NArray (rval)
|
533
|
+
* and the updated mask (rmask).
|
534
|
+
*/
|
535
|
+
static VALUE
|
536
|
+
interpo_missing(obj, val, mask, dim, pos, cyclic, modulo)
|
537
|
+
VALUE obj;
|
538
|
+
VALUE val; // [NArray] real/int (not complex) NArray with data missing
|
539
|
+
VALUE mask; // [NArray (byte)] mask array (shape same as val)
|
540
|
+
VALUE dim; // [Integer] dimension along which missing is interpolated
|
541
|
+
VALUE pos; // [1D NArray] grid point positions alog dim
|
542
|
+
VALUE cyclic; // [false/true] whether cyclic extension is conducted
|
543
|
+
VALUE modulo; // [Float] modulo used when cyclic
|
544
|
+
// VALUE extrapo; // [false/true] whether to extrapolate when !cyclic
|
545
|
+
{
|
546
|
+
VALUE rval, rmask, rary; // result
|
547
|
+
struct NARRAY *na;
|
548
|
+
na_shape_t rank;
|
549
|
+
na_shape_t *sh, sh0=1, sh1, sh2=1, i, j, k, js, je;
|
550
|
+
int dm, d;
|
551
|
+
double *y, ys, ye, *x, xs, xe, xc, mod;
|
552
|
+
u_int8_t *mk;
|
553
|
+
|
554
|
+
rval = na_dup_w_type(val, NA_DFLOAT);
|
555
|
+
rank = NA_RANK(rval);
|
556
|
+
GetNArray(rval, na);
|
557
|
+
sh = na->shape;
|
558
|
+
y = NA_PTR_TYPE(rval, double *);
|
559
|
+
|
560
|
+
if ( NA_TOTAL(mask) != NA_TOTAL(val) )
|
561
|
+
rb_raise(rb_eArgError, "The lengths of val and mask disgagree.");
|
562
|
+
if ( na_get_typecode(mask) != NA_BYTE)
|
563
|
+
rb_raise(rb_eArgError, "mask must be a byte NArray");
|
564
|
+
rmask = na_clone(mask);
|
565
|
+
mk = NA_PTR_TYPE(rmask, u_int8_t *);
|
566
|
+
|
567
|
+
rary = rb_ary_new();
|
568
|
+
rb_ary_push(rary, rval);
|
569
|
+
rb_ary_push(rary, rmask);
|
570
|
+
|
571
|
+
if (cyclic == Qtrue) mod = NUM2DBL(modulo);
|
572
|
+
|
573
|
+
dm = NUM2INT(dim);
|
574
|
+
if (dm < 0) dm += rank;
|
575
|
+
if (dm < 0 || dm >= rank)
|
576
|
+
rb_raise(rb_eArgError, "dim %d does not exist in the rank %d array",
|
577
|
+
NUM2INT( dim ), rank);
|
578
|
+
for (d=0; d<dm; d++) sh0 *= sh[d];
|
579
|
+
sh1 = sh[dm];
|
580
|
+
for (d=dm+1; d<rank; d++) sh2 *= sh[d];
|
581
|
+
|
582
|
+
if ( NA_TOTAL(pos) != sh1 )
|
583
|
+
rb_raise(rb_eArgError, "len of pos (%d) != len along dim (%d)",
|
584
|
+
NA_TOTAL(rval), sh1);
|
585
|
+
pos = na_cast_object(pos, NA_DFLOAT);
|
586
|
+
x = NA_PTR_TYPE(pos, double *);
|
587
|
+
for (k=0; k<sh2; k++){
|
588
|
+
for (i=0; i<sh0; i++){
|
589
|
+
js = -1;
|
590
|
+
je = 0;
|
591
|
+
while ( je < sh1 ) {
|
592
|
+
for( j=je; j<sh1-1; j++ ) {
|
593
|
+
if ( mk[i+sh0*(j+sh1*k)] &&
|
594
|
+
!mk[i+sh0*((j+1)+sh1*k)] ) {
|
595
|
+
js = j;
|
596
|
+
break;
|
597
|
+
}
|
598
|
+
}
|
599
|
+
if (js >= je) {
|
600
|
+
for( j=js+1; j<sh1-1; j++ ) {
|
601
|
+
if ( !mk[i+sh0*(j+sh1*k)] &&
|
602
|
+
mk[i+sh0*((j+1)+sh1*k)] ){
|
603
|
+
je = j+1;
|
604
|
+
break;
|
605
|
+
}
|
606
|
+
}
|
607
|
+
if (je > js+1) {
|
608
|
+
// interpolate between js & je
|
609
|
+
xs = x[js];
|
610
|
+
xe = x[je];
|
611
|
+
ys = y[i+sh0*(js+sh1*k)];
|
612
|
+
ye = y[i+sh0*(je+sh1*k)];
|
613
|
+
for( j=js+1; j<je; j++ ) {
|
614
|
+
y[i+sh0*(j+sh1*k)] =
|
615
|
+
( (xe-x[j])*ys + (x[j]-xs)*ye ) / (xe-xs);
|
616
|
+
mk[i+sh0*(j+sh1*k)] = (u_int8_t) 1;
|
617
|
+
}
|
618
|
+
} else {
|
619
|
+
break; // no non-cyclic gap remains -> break
|
620
|
+
}
|
621
|
+
} else {
|
622
|
+
break; // no (further) non-cyclic gap found -> break
|
623
|
+
}
|
624
|
+
}
|
625
|
+
if (cyclic == Qtrue && ( !mk[i+sh0*(0 +sh1*k)] ||
|
626
|
+
!mk[i+sh0*(sh1-1 +sh1*k)] ) ) {
|
627
|
+
// the first or last element remains as missing
|
628
|
+
js = je = -1;
|
629
|
+
for( j=sh1-1; j>=0; j-- ) {
|
630
|
+
if ( mk[i+sh0*(j+sh1*k)] ) {
|
631
|
+
js = j;
|
632
|
+
break;
|
633
|
+
}
|
634
|
+
}
|
635
|
+
for( j=0; j<=js; j++ ) {
|
636
|
+
if ( mk[i+sh0*(j+sh1*k)] ) {
|
637
|
+
je = j+sh1;
|
638
|
+
break;
|
639
|
+
}
|
640
|
+
}
|
641
|
+
if (js>=0 && je>=sh1) {
|
642
|
+
xs = x[js];
|
643
|
+
xe = x[je-sh1] + mod;
|
644
|
+
ys = y[i+sh0*(js+sh1*k)];
|
645
|
+
ye = y[i+sh0*(je-sh1+sh1*k)];
|
646
|
+
for( j=js+1; j<je; j++ ) {
|
647
|
+
xc = x[j % sh1] + (j/sh1)*mod;
|
648
|
+
y[i+sh0*(j%sh1+sh1*k)] =
|
649
|
+
( (xe-xc)*ys + (xc-xs)*ye ) / (xe-xs) ;
|
650
|
+
mk[i+sh0*(j%sh1+sh1*k)] = (u_int8_t) 1;
|
651
|
+
}
|
652
|
+
}
|
653
|
+
}
|
654
|
+
}
|
655
|
+
}
|
656
|
+
return rary;
|
657
|
+
}
|
658
|
+
|
659
|
+
/**
|
660
|
+
* @brief multi-dimensional regrid for based on indices (which is essentially fro equally separated grid)
|
661
|
+
*
|
662
|
+
* @details
|
663
|
+
* input data is converted into double (NArray's Float) type. So unuable for
|
664
|
+
* complex data.
|
665
|
+
*
|
666
|
+
* * dims must be an Array containing integers (>=0 & < rank)
|
667
|
+
* * lengths of the Array arguments must be the same (rclen),
|
668
|
+
* and the rank of NArrays in scidxs must also be rclen.
|
669
|
+
* * shapes of the NArrays in scidxs must be the same
|
670
|
+
*
|
671
|
+
* Supports cyclic interpolation. Extrapolation is not supported.
|
672
|
+
*
|
673
|
+
* Returned is a two-element Array consisting of the interpolated NArray (rval)
|
674
|
+
* and the updated mask (rmask).
|
675
|
+
*
|
676
|
+
* @note
|
677
|
+
* implemntation strategy: make a consolidate single loop for the return
|
678
|
+
* value
|
679
|
+
*/
|
680
|
+
static VALUE
|
681
|
+
regrid2_w_idx(obj, val, mask, dims, scidxs, cyclics)
|
682
|
+
VALUE obj;
|
683
|
+
VALUE val; // [NArray] real/int (not complex) NArray with data missing
|
684
|
+
VALUE mask; // [NArray (byte)] mask array (shape same as val)
|
685
|
+
VALUE dims; // [Array of Integer] dimensions along which regrid is made
|
686
|
+
VALUE scidxs; // [Array of NArray] float index vals at which sampled (0..)
|
687
|
+
VALUE cyclics; // [Array of true/false or nil] wheather the dim is cyclic.
|
688
|
+
// modulo is assumed to be the dimension length, so
|
689
|
+
// available only when exactly 1-grid extension is needed
|
690
|
+
{
|
691
|
+
VALUE rval, rmask, rary; // result
|
692
|
+
VALUE scidx; // (work) one of scidxs
|
693
|
+
double *iv, *rv; // input & return values
|
694
|
+
double **sci; // sampling index values
|
695
|
+
int *cyc;
|
696
|
+
double a, c; // subgrid position and coefficient for linear interporation
|
697
|
+
u_int8_t *imsk, *rmsk; // input & return masks
|
698
|
+
struct NARRAY *na; // work
|
699
|
+
na_shape_t *ish, *rsh, *ssh; // shapes of input, retrun & sampling values
|
700
|
+
na_shape_t *icsh, *rcsh, *scsh; // cumulative shapes
|
701
|
+
na_shape_t i, j, k, m, si;
|
702
|
+
na_shape_t ii, ii0, dii; // related to 1D indices along input val
|
703
|
+
na_shape_t itot, rtot, stot; // total array lengths (input, return, sample)
|
704
|
+
int rank, ndims, d, dc, *dms, nd2p, kup;
|
705
|
+
int *dimmap; // to indicate dimensions to be sampled and left
|
706
|
+
|
707
|
+
ndims = RARRAY_LEN(dims);
|
708
|
+
if (ndims != RARRAY_LEN(scidxs))
|
709
|
+
rb_raise(rb_eArgError, "lens of dims & scidx do not agree");
|
710
|
+
if (!NIL_P(cyclics) && ndims != RARRAY_LEN(cyclics))
|
711
|
+
rb_raise(rb_eArgError, "lens of dims & cyclics do not agree");
|
712
|
+
|
713
|
+
val = na_cast_object(val, NA_DFLOAT);
|
714
|
+
rank = NA_RANK(val);
|
715
|
+
if (ndims>rank)
|
716
|
+
rb_raise(rb_eArgError, "# of dims exceeds val.rank (%d)", rank);
|
717
|
+
GetNArray(val, na);
|
718
|
+
ish = na->shape;
|
719
|
+
iv = NA_PTR_TYPE(val, double *);
|
720
|
+
itot = NA_TOTAL(val);
|
721
|
+
if (itot != NA_TOTAL(mask))
|
722
|
+
rb_raise(rb_eArgError, "lens of val and mask do not agree");
|
723
|
+
imsk = NA_PTR_TYPE(mask, u_int8_t *);
|
724
|
+
|
725
|
+
scidx = RARRAY_AREF(scidxs, 0);
|
726
|
+
if (NA_RANK(scidx) != ndims)
|
727
|
+
rb_raise(rb_eArgError, "rank of sampling indices != # of dims");
|
728
|
+
GetNArray(scidx, na);
|
729
|
+
ssh = na->shape;
|
730
|
+
stot = NA_TOTAL(scidx);
|
731
|
+
sci = ALLOCA_N(double *, ndims);
|
732
|
+
for (d=1; d<ndims; d++) {
|
733
|
+
if (NA_TOTAL(RARRAY_AREF(scidxs, d)) != stot)
|
734
|
+
rb_raise(rb_eArgError, "lens of scidxs are not uniform");
|
735
|
+
}
|
736
|
+
for (d=0; d<ndims; d++) {
|
737
|
+
sci[d] = NA_PTR_TYPE(RARRAY_AREF(scidxs, d), double *);
|
738
|
+
}
|
739
|
+
|
740
|
+
dms = ALLOCA_N(int, ndims);
|
741
|
+
for (d=0; d<ndims; d++) {
|
742
|
+
dms[d] = NUM2INT(RARRAY_AREF(dims, d));
|
743
|
+
if (dms[d] < 0 || dms[d]>=rank)
|
744
|
+
rb_raise(rb_eArgError, "values of dims is not within 0...rank(%d)",
|
745
|
+
rank);
|
746
|
+
}
|
747
|
+
cyc = ALLOCA_N(int, ndims);
|
748
|
+
for (d=0; d<ndims; d++) {
|
749
|
+
cyc[d] = !NIL_P(cyclics) && RARRAY_AREF(cyclics, d) == Qtrue;
|
750
|
+
}
|
751
|
+
|
752
|
+
dimmap = ALLOCA_N(int, rank); // e.g. [-1,0,-1,1,-1,-1,..] if dims==[1,3]
|
753
|
+
for (d=0; d<rank; d++) {
|
754
|
+
dimmap[d] = -1; // initialization (-1 indicates where dimension is left)
|
755
|
+
}
|
756
|
+
for (d=0; d<ndims; d++) {
|
757
|
+
dimmap[dms[d]] = d; // position (0...ndims) of dimension to be sampled
|
758
|
+
}
|
759
|
+
|
760
|
+
rsh = ALLOCA_N(na_shape_t, rank);
|
761
|
+
for (d=0; d<rank; d++) {
|
762
|
+
if (dimmap[d] < 0) {
|
763
|
+
rsh[d] = ish[d];
|
764
|
+
} else {
|
765
|
+
rsh[d] = ssh[dimmap[d]];
|
766
|
+
}
|
767
|
+
}
|
768
|
+
|
769
|
+
icsh = ALLOCA_N(na_shape_t, rank); // cumulative shape [1, sh0, sh0*sh1,..]
|
770
|
+
rcsh = ALLOCA_N(na_shape_t, rank); // cumulative shape [1, sh0, sh0*sh1,..]
|
771
|
+
scsh = ALLOCA_N(na_shape_t, ndims); // cumulative shape [1, sh0, sh0*sh1,..]
|
772
|
+
icsh[0] = rcsh[0] = scsh[0] = 1;
|
773
|
+
for (d=1; d<rank; d++) {
|
774
|
+
icsh[d] = icsh[d-1]*ish[d-1];
|
775
|
+
rcsh[d] = rcsh[d-1]*rsh[d-1];
|
776
|
+
}
|
777
|
+
for (d=1; d<ndims; d++) {
|
778
|
+
scsh[d] = scsh[d-1]*ssh[d-1];
|
779
|
+
}
|
780
|
+
|
781
|
+
rval = na_make_object(NA_DFLOAT, rank, rsh, cNArray);
|
782
|
+
rv = NA_PTR_TYPE(rval, double *);
|
783
|
+
rtot = NA_TOTAL(rval);
|
784
|
+
|
785
|
+
rmask = na_make_object(NA_BYTE, rank, rsh, cNArray);
|
786
|
+
rmsk = NA_PTR_TYPE(rmask, u_int8_t *);
|
787
|
+
|
788
|
+
rary = rb_ary_new();
|
789
|
+
rb_ary_push(rary, rval);
|
790
|
+
rb_ary_push(rary, rmask);
|
791
|
+
|
792
|
+
nd2p = 1 << ndims; // 2**ndims
|
793
|
+
for (j=0; j<rtot; j++) { // 1-dimensionalized loop for return values
|
794
|
+
rmsk[j] = 1; // (initialization) as all-valid
|
795
|
+
si = 0; // (initialization) 1-dimensionalized index of scidx
|
796
|
+
ii0 = 0; // (initialization) offset of ii for non-regrided dims
|
797
|
+
for (d=0; d<rank; d++) {
|
798
|
+
m = (j/rcsh[d]) % rsh[d]; // index along d-th dim of rv
|
799
|
+
if (dimmap[d] >= 0) {
|
800
|
+
si += m * scsh[dimmap[d]]; // for dim to regrid
|
801
|
+
} else {
|
802
|
+
ii0 += m * icsh[d]; // for dim not to regrid
|
803
|
+
}
|
804
|
+
}
|
805
|
+
rv[j] = 0.0; // (initialization) base of summation
|
806
|
+
for (i=0; i<nd2p; i++) { // loop for multi-D linear interpolation
|
807
|
+
dii = 0; //(initialization) 1-dimensionalized iv index diff from ii0
|
808
|
+
c = 1.0; //(initialization) fractional factor to sum up
|
809
|
+
for (d=0; d<rank; d++) {
|
810
|
+
dc = dimmap[d]; // if >0, dc-th sci is treated (dc: 0,1,..)
|
811
|
+
if (dc >= 0) {
|
812
|
+
k = floor(sci[dc][si]); // index along d-th dim of iv
|
813
|
+
a = sci[dc][si] - k; // subgrid fractional distance
|
814
|
+
kup = (i >> dc) % 2; // 0(1) to use the this(next) grid pt
|
815
|
+
// (note: i>>d is equal to i/2**d)
|
816
|
+
k += kup;
|
817
|
+
if (k<0 || k>=ish[d]) {
|
818
|
+
if (cyc[d]) {
|
819
|
+
k = k % ish[d];
|
820
|
+
if (k<0) k += ish[d]; // for negative mod of C lang
|
821
|
+
} else {
|
822
|
+
rmsk[j] = 0; // do not extrapolate
|
823
|
+
break;
|
824
|
+
}
|
825
|
+
}
|
826
|
+
dii += k * icsh[d];
|
827
|
+
c *= ( kup ? a : 1.0-a );
|
828
|
+
}
|
829
|
+
}
|
830
|
+
if (rmsk[j] == 0) {
|
831
|
+
break; // have been set in the d loop --> break the i loop
|
832
|
+
}
|
833
|
+
ii = ii0 + dii;
|
834
|
+
if ( imsk[ii] ) {
|
835
|
+
rv[j] += c*iv[ii];
|
836
|
+
} else {
|
837
|
+
rmsk[j] = 0;
|
838
|
+
break;
|
839
|
+
}
|
840
|
+
}
|
841
|
+
}
|
842
|
+
return rary;
|
843
|
+
}
|
523
844
|
|
524
845
|
void
|
525
846
|
init_gphys_interpo()
|
@@ -532,10 +853,12 @@ init_gphys_interpo()
|
|
532
853
|
cGPhys = rb_define_class_under(mNumRu, "GPhys", rb_cObject);
|
533
854
|
rb_define_private_method(cGPhys, "c_interpo_find_loc_1D", interpo_find_loc_1D, 4);
|
534
855
|
rb_define_private_method(cGPhys, "c_interpo_find_loc_1D_MD", interpo_find_loc_1D_MD, 5);
|
535
|
-
|
536
856
|
rb_define_private_method(cGPhys, "c_interpo_do", interpo_do, 5);
|
857
|
+
rb_define_private_method(cGPhys, "c_interpo_missing", interpo_missing, 6);
|
858
|
+
rb_define_private_method(cGPhys, "c_regrid2_w_idx", regrid2_w_idx, 5);
|
537
859
|
|
538
860
|
// to make "find loc" methods available outside GPhys as class methods
|
539
|
-
rb_define_singleton_method(cGPhys, "interpo_find_loc_1D", interpo_find_loc_1D,
|
540
|
-
rb_define_singleton_method(cGPhys, "interpo_find_loc_1D_MD", interpo_find_loc_1D_MD,
|
861
|
+
rb_define_singleton_method(cGPhys, "interpo_find_loc_1D", interpo_find_loc_1D, 4);
|
862
|
+
rb_define_singleton_method(cGPhys, "interpo_find_loc_1D_MD", interpo_find_loc_1D_MD, 5);
|
863
|
+
rb_define_singleton_method(cGPhys, "na_interpo_missing", interpo_missing, 6);
|
541
864
|
}
|
data/lib/numru/dclext.rb
CHANGED
@@ -725,7 +725,7 @@ module NumRu
|
|
725
725
|
|
726
726
|
#<<< udpack >>>
|
727
727
|
|
728
|
-
def ud_coloring(clr_min
|
728
|
+
def ud_coloring(clr_min, clr_max)
|
729
729
|
# change the colors of existing contours to make a gradation
|
730
730
|
# (rainbow colors with the default color map).
|
731
731
|
nlev = DCL.udqcln
|
@@ -736,7 +736,7 @@ module NumRu
|
|
736
736
|
DCL.udiclv # clear the contours
|
737
737
|
|
738
738
|
colors = clr_min +
|
739
|
-
NArray.
|
739
|
+
(NArray.float(nlev).indgen! * (clr_max-clr_min)/(nlev-1)).round
|
740
740
|
|
741
741
|
cont_params.sort!
|
742
742
|
for i in 0...nlev
|
@@ -777,8 +777,8 @@ module NumRu
|
|
777
777
|
DCL.uddclv(0.0)
|
778
778
|
end
|
779
779
|
if options['coloring']
|
780
|
-
clr_min = ( options['clr_min'] ||
|
781
|
-
clr_max = ( options['clr_max'] ||
|
780
|
+
clr_min = ( options['clr_min'] || DCL.uepget('icolor1') )
|
781
|
+
clr_max = ( options['clr_max'] || DCL.uepget('icolor2') )
|
782
782
|
ud_coloring( clr_min, clr_max )
|
783
783
|
end
|
784
784
|
end
|
@@ -1100,6 +1100,7 @@ module NumRu
|
|
1100
1100
|
["top", false, "place the bar at the top (effective if landscape)"],
|
1101
1101
|
["left", false, "place the bar in the left (effective if portrait)"],
|
1102
1102
|
["units", nil, "units of the axis of the color bar"],
|
1103
|
+
["unit_tidy", true, "reform units for DCL (by handling power etc)"],
|
1103
1104
|
["units_voff", 0.0, "offset value for units from the default position in the V coordinate (only for 'units' != nil)"],
|
1104
1105
|
["title", nil, "title of the color bar"],
|
1105
1106
|
["title_voff", 0.0, "offset value for title from the default position in the V coordinate (only for 'title' != nil)"],
|
@@ -1265,7 +1266,8 @@ module NumRu
|
|
1265
1266
|
end
|
1266
1267
|
|
1267
1268
|
DCLExt.color_bar_title_units(vxmin, vxmax, vymin, vymax, portrait, voff,
|
1268
|
-
opt['title'], opt['units'], opt['title_voff'], opt['units_voff']
|
1269
|
+
opt['title'], opt['units'], opt['title_voff'], opt['units_voff'],
|
1270
|
+
opt['unit_tidy'])
|
1269
1271
|
|
1270
1272
|
inffact = opt["inffact"]
|
1271
1273
|
if inf0
|
@@ -1422,6 +1424,15 @@ module NumRu
|
|
1422
1424
|
str.sub!(/^0/,'') if !opt['year'] && opt['month']
|
1423
1425
|
labels.push(str)
|
1424
1426
|
end
|
1427
|
+
if pos.length == 1
|
1428
|
+
u = pos[0]
|
1429
|
+
if u<u1 || u>u2
|
1430
|
+
pos[0] = (u1+u2)/2
|
1431
|
+
end
|
1432
|
+
else
|
1433
|
+
pos[0] = u1 if pos[0]<u1
|
1434
|
+
pos[-1] = u2 if pos[-1]>u2
|
1435
|
+
end
|
1425
1436
|
|
1426
1437
|
if xax
|
1427
1438
|
DCL.uxsaxz(cside,DCL.uzpget('roffx'+cside))
|
@@ -1456,9 +1467,14 @@ module NumRu
|
|
1456
1467
|
['cside', nil, '"b", "t", "l", "r", nil (=>left/bottom), or false (=>right/top)'],
|
1457
1468
|
['margin_factor', 0.9, 'Factor to control the extent to use UCPACK; The smaller, the less, requiring more space between year labels'],
|
1458
1469
|
['dtick1', nil, '(For long time series) small tick interval (years)'],
|
1459
|
-
['dtick2', nil, '(For long time series) large tick with year labels (years)']
|
1470
|
+
['dtick2', nil, '(For long time series) large tick with year labels (years)'],
|
1471
|
+
['noyear', false, 'do not show years']
|
1460
1472
|
)
|
1461
1473
|
|
1474
|
+
def set_date_ax_options(options)
|
1475
|
+
@@date_ax_options.set(options)
|
1476
|
+
end
|
1477
|
+
|
1462
1478
|
def date_ax(date_from, date_to, options=nil)
|
1463
1479
|
# < intepret the options >
|
1464
1480
|
opt = @@date_ax_options.interpret(options)
|
@@ -1498,9 +1514,19 @@ module NumRu
|
|
1498
1514
|
if use_ucpack
|
1499
1515
|
jd0 = date_from.strftime('%Y%m%d').to_i
|
1500
1516
|
if xax
|
1501
|
-
|
1517
|
+
if opt['noyear']
|
1518
|
+
DCL.ucxady(cside,jd0,nday)
|
1519
|
+
DCL.ucxamn(cside,jd0,nday)
|
1520
|
+
else
|
1521
|
+
DCL.ucxacl(cside,jd0,nday)
|
1522
|
+
end
|
1502
1523
|
else
|
1503
|
-
|
1524
|
+
if opt['noyear']
|
1525
|
+
DCL.ucyady(cside,jd0,nday)
|
1526
|
+
DCL.ucyamn(cside,jd0,nday)
|
1527
|
+
else
|
1528
|
+
DCL.ucyacl(cside,jd0,nday)
|
1529
|
+
end
|
1504
1530
|
end
|
1505
1531
|
else
|
1506
1532
|
year_ax(xax, cside, date_from, date_to)
|
@@ -1739,6 +1765,7 @@ module NumRu
|
|
1739
1765
|
['inplace',true, "Whether to print labels right by the unit vector (true) or below the x axis (false)"],
|
1740
1766
|
['rsizet', nil, "Label size(default taken from uz-parameter 'rsizel1')"],
|
1741
1767
|
['index', 3," Line index of the unit vector"],
|
1768
|
+
['units', nil, "units of the quantity"],
|
1742
1769
|
['vertical', true,"(used only in unit_vect_single) the unit vector is directed upward if true, to the right if not."]
|
1743
1770
|
)
|
1744
1771
|
|
@@ -1773,6 +1800,7 @@ module NumRu
|
|
1773
1800
|
vxuloc = opt['vxuloc']
|
1774
1801
|
vyuloc = opt['vyuloc']
|
1775
1802
|
rsizet = opt['rsizet']
|
1803
|
+
units = opt['units']
|
1776
1804
|
index = opt['index']
|
1777
1805
|
|
1778
1806
|
#< unit vector >
|
@@ -1805,6 +1833,8 @@ module NumRu
|
|
1805
1833
|
#< labelling >
|
1806
1834
|
sfxunit = sprintf("%.2g",fxunit)
|
1807
1835
|
sfyunit = sprintf("%.2g",fyunit)
|
1836
|
+
sfxunit += ' '+units if units
|
1837
|
+
sfyunit += ' '+units if units
|
1808
1838
|
rsizet = DCL.uzpget('rsizel1') if !rsizet
|
1809
1839
|
if opt['inplace']
|
1810
1840
|
if vxunit != 0
|
@@ -1837,6 +1867,7 @@ module NumRu
|
|
1837
1867
|
rsizet = opt['rsizet'] || DCL.uzpget('rsizel1')
|
1838
1868
|
index = opt['index']
|
1839
1869
|
vertical = opt['vertical']
|
1870
|
+
units = opt['units']
|
1840
1871
|
|
1841
1872
|
#< show the unit vector and the label >
|
1842
1873
|
|
@@ -1847,6 +1878,7 @@ module NumRu
|
|
1847
1878
|
end
|
1848
1879
|
vlen = vfratio * flen
|
1849
1880
|
label = DCL.chval("B",flen)
|
1881
|
+
label += ' '+units if units
|
1850
1882
|
|
1851
1883
|
lclip_bk = DCLExt.sg_set_params("lclip" => false)
|
1852
1884
|
if vertical
|
@@ -2154,6 +2186,7 @@ module NumRu
|
|
2154
2186
|
["top", false, "place the bar at the top (effective if landscape)"],
|
2155
2187
|
["left", false, "place the bar in the left (effective if portrait)"],
|
2156
2188
|
["units", nil, "units of the axis of the color bar"],
|
2189
|
+
["unit_tidy", true, "reform units for DCL (by handling power etc)"],
|
2157
2190
|
["units_voff", 0.0, "offset value for units from the default position in the V coordinate (only for 'units' != nil)"],
|
2158
2191
|
["title", nil, "title of the color bar"],
|
2159
2192
|
["title_voff", 0.0, "offset value for title from the default position in the V coordinate (only for 'title' != nil)"],
|
@@ -2307,28 +2340,51 @@ module NumRu
|
|
2307
2340
|
DCL.sgplzv(v3[0], v3[1], 1, index)
|
2308
2341
|
end
|
2309
2342
|
|
2310
|
-
def
|
2343
|
+
def format_units(units)
|
2344
|
+
units.to_s.split(/ +|\./).map{|s| s.sub(/1[eE](-?\d+)/,'10\^{\1}').sub(/([a-zA-Z]+)(-?\d+)$/,'\1\^{\2}')}.join('\_{ }')
|
2345
|
+
end
|
2346
|
+
|
2347
|
+
def color_bar_title_units(vxmin, vxmax, vymin, vymax, portrait, voff, title, units, title_voff, units_voff, unit_tidy=true, old_style=false)
|
2311
2348
|
rsizel1 = DCL::uzrget('rsizel1')
|
2312
2349
|
charindex = DCL::uziget('indexl1')
|
2313
2350
|
pad1 = DCL::uzrget('pad1')
|
2351
|
+
if units && unit_tidy
|
2352
|
+
units = format_units(units)
|
2353
|
+
end
|
2314
2354
|
if portrait
|
2315
2355
|
if voff > 0
|
2316
2356
|
# title
|
2317
|
-
|
2357
|
+
if title && old_style
|
2358
|
+
DCL::sgtxzr(vxmin - (0.5 + pad1) * rsizel1, (vymin + vymax) / 2.0 + title_voff, title, rsizel1, 90, 0, charindex)
|
2359
|
+
end
|
2318
2360
|
# units
|
2319
2361
|
DCL::sgtxzr(vxmax + pad1 * rsizel1, vymax + 2.6 * rsizel1 + units_voff, units, rsizel1, 0, -1, charindex) if units
|
2320
2362
|
else
|
2363
|
+
exit
|
2321
2364
|
# title
|
2322
|
-
|
2365
|
+
if title && old_style
|
2366
|
+
DCL::sgtxzr(vxmax + (0.5 + pad1) * rsizel1, (vymin + vymax) / 2.0 - title_voff, title, rsizel1, -90, 0, charindex)
|
2367
|
+
end
|
2323
2368
|
# units
|
2324
2369
|
DCL::sgtxzr(vxmin - pad1 * rsizel1, vymax + 2.6 * rsizel1 + units_voff, units, rsizel1, 0, 1, charindex) if units
|
2325
2370
|
end
|
2371
|
+
if title && !old_style
|
2372
|
+
sv = DCLExt.uz_set_params("rsizet1"=>rsizel1)
|
2373
|
+
DCL.uysttl("r",title,title_voff)
|
2374
|
+
DCLExt.uz_set_params(sv)
|
2375
|
+
end
|
2326
2376
|
else
|
2327
2377
|
spacer = (0.5 + pad1) * rsizel1
|
2328
2378
|
tmpvy = [vymin - spacer, vymax + spacer]
|
2329
2379
|
tmpvy = [tmpvy[1], tmpvy[0]] if voff <= 0
|
2330
2380
|
# title
|
2331
|
-
|
2381
|
+
if title && old_style
|
2382
|
+
DCL::sgtxzr((vxmin + vxmax) / 2.0 + title_voff, tmpvy[0], title, rsizel1, 0, 0, charindex)
|
2383
|
+
elsif title
|
2384
|
+
sv = DCLExt.uz_set_params("rsizet1"=>rsizel1)
|
2385
|
+
DCL.uxsttl("b",title,title_voff)
|
2386
|
+
DCLExt.uz_set_params(sv)
|
2387
|
+
end
|
2332
2388
|
# units
|
2333
2389
|
DCL::sgtxzr(vxmax + 2.6 * rsizel1 + units_voff, tmpvy[1], units, rsizel1, 0, -1, charindex) if units
|
2334
2390
|
end
|
@@ -2697,8 +2753,13 @@ module NumRu
|
|
2697
2753
|
end
|
2698
2754
|
end
|
2699
2755
|
|
2700
|
-
|
2701
|
-
|
2756
|
+
units = opt['units']
|
2757
|
+
if units && opt['unit_tidy']
|
2758
|
+
units = units.split(/ +|\./).map{|s| s.sub(/(-?\d)$/,'\^{\1}')}.join('\_{ }')
|
2759
|
+
end
|
2760
|
+
DCLExt.color_bar_title_units(vxmin, vxmax, vymin, vymax, portrait, voff,
|
2761
|
+
opt['title'], units, opt['title_voff'], opt['units_voff'],
|
2762
|
+
opt['unit_tidy'])
|
2702
2763
|
if portrait
|
2703
2764
|
cent = ((voff > 0) ? -1 : 1)
|
2704
2765
|
spacer = DCL::uzrget('pad1') * rsizel1
|
@@ -2836,8 +2897,9 @@ module NumRu
|
|
2836
2897
|
|
2837
2898
|
DCL::uxsfmt(cfmt_bk)
|
2838
2899
|
end
|
2839
|
-
DCLExt.color_bar_title_units(vxmin, vxmax, vymin, vymax, portrait, voff,
|
2840
|
-
|
2900
|
+
DCLExt.color_bar_title_units(vxmin, vxmax, vymin, vymax, portrait, voff,
|
2901
|
+
opt['title'], opt['units'], opt['title_voff'], opt['units_voff'],
|
2902
|
+
opt['unit_tidy'])
|
2841
2903
|
|
2842
2904
|
# RESTORE PARAMS
|
2843
2905
|
DCLExt.restore_proj_params(proj_params)
|
@@ -78,9 +78,10 @@ module NumRu
|
|
78
78
|
# RETURN VALUE
|
79
79
|
# * grad_x (GPhys objects)
|
80
80
|
def grad_x(gphys, x=nil)
|
81
|
-
lond, latd = Planet::find_lon_lat_dims
|
81
|
+
lond, latd = Planet::find_lon_lat_dims(gphys)
|
82
82
|
x, = get_x_y(gphys) if !x
|
83
|
-
|
83
|
+
bc = GPhys::Derivative::CYCLIC_OR_LINEAR
|
84
|
+
gphys.cderiv(lond,bc,x)
|
84
85
|
end
|
85
86
|
|
86
87
|
# Gradient in the y direction
|
@@ -93,9 +94,10 @@ module NumRu
|
|
93
94
|
# RETURN VALUE
|
94
95
|
# * grad_y (GPhys objects)
|
95
96
|
def grad_y(gphys, y=nil)
|
96
|
-
lond, latd = Planet::find_lon_lat_dims
|
97
|
+
lond, latd = Planet::find_lon_lat_dims(gphys)
|
97
98
|
x, y = get_x_y(gphys) if !y
|
98
|
-
|
99
|
+
bc = GPhys::Derivative::CYCLIC_OR_LINEAR
|
100
|
+
gphys.threepoint_O2nd_deriv(latd,bc,y)
|
99
101
|
end
|
100
102
|
|
101
103
|
end
|