gphys 1.5.5 → 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.
Files changed (41) hide show
  1. checksums.yaml +5 -5
  2. data/ChangeLog +0 -7595
  3. data/LICENSE.txt +1 -1
  4. data/bin/gpcut +12 -0
  5. data/bin/gpvect +88 -77
  6. data/bin/gpview +200 -103
  7. data/ext/numru/ganalysis/ext_init.c +9 -0
  8. data/ext/numru/ganalysis/extconf.rb +43 -0
  9. data/ext/numru/ganalysis/narray_ext_dfloat.c +84 -0
  10. data/ext/numru/ganalysis/pde_ext.c +130 -0
  11. data/ext/numru/gphys/dim_op.c +336 -44
  12. data/ext/numru/gphys/ext_init.c +6 -0
  13. data/ext/numru/gphys/interpo.c +326 -3
  14. data/gphys.gemspec +1 -0
  15. data/lib/numru/dclext.rb +78 -16
  16. data/lib/numru/ganalysis/beta_plane.rb +6 -4
  17. data/lib/numru/ganalysis/eof.rb +63 -41
  18. data/lib/numru/ganalysis/fitting.rb +109 -30
  19. data/lib/numru/ganalysis/histogram.rb +3 -3
  20. data/lib/numru/ganalysis/log_p.rb +20 -0
  21. data/lib/numru/ganalysis/lomb_scargle.rb +205 -0
  22. data/lib/numru/ganalysis/met_z.rb +132 -3
  23. data/lib/numru/ganalysis/narray_ext.rb +13 -0
  24. data/lib/numru/ganalysis/pde.rb +109 -0
  25. data/lib/numru/ganalysis/planet.rb +136 -1
  26. data/lib/numru/ganalysis/qg.rb +224 -3
  27. data/lib/numru/ggraph.rb +95 -23
  28. data/lib/numru/gphys/axis.rb +4 -2
  29. data/lib/numru/gphys/gphys.rb +6 -5
  30. data/lib/numru/gphys/gphys_dim_op.rb +69 -6
  31. data/lib/numru/gphys/gphys_fft.rb +30 -0
  32. data/lib/numru/gphys/gphys_io_common.rb +2 -0
  33. data/lib/numru/gphys/grads_gridded.rb +77 -29
  34. data/lib/numru/gphys/grib.rb +2 -2
  35. data/lib/numru/gphys/grib_params.rb +3 -3
  36. data/lib/numru/gphys/interpolate.rb +153 -1
  37. data/lib/numru/gphys/varraycomposite.rb +7 -4
  38. data/lib/numru/gphys/version.rb +1 -1
  39. data/lib/numru/gphys.rb +1 -0
  40. data/testdata/pres.jan.nc +0 -0
  41. metadata +13 -4
@@ -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, 2);
540
- rb_define_singleton_method(cGPhys, "interpo_find_loc_1D_MD", interpo_find_loc_1D_MD, 3);
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/gphys.gemspec CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.require_paths = ["ext","lib"]
26
26
  spec.test_files = spec.files.grep(%r{^(test|test_old|sample|testdata)/})
27
27
  spec.extensions << "ext/numru/gphys/extconf.rb"
28
+ spec.extensions << "ext/numru/ganalysis/extconf.rb"
28
29
 
29
30
  spec.post_install_message = "Thanks for installing! You can add extra libraries (i.e., ruby-lapack, rb-gsl) to enjoy powerful calculating and handling datasets."
30
31
 
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=13, clr_max=99)
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.int(nlev).indgen! * (clr_max-clr_min) / nlev
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'] || 13 )
781
- clr_max = ( options['clr_max'] || 99 )
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
- DCL.ucxacl(cside,jd0,nday)
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
- DCL.ucyacl(cside,jd0,nday)
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 color_bar_title_units(vxmin, vxmax, vymin, vymax, portrait, voff, title, units, title_voff, units_voff)
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
- DCL::sgtxzr(vxmin - (0.5 + pad1) * rsizel1, (vymin + vymax) / 2.0 + title_voff, title, rsizel1, 90, 0, charindex) if title
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
- DCL::sgtxzr(vxmax + (0.5 + pad1) * rsizel1, (vymin + vymax) / 2.0 - title_voff, title, rsizel1, -90, 0, charindex) if title
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
- DCL::sgtxzr((vxmin + vxmax) / 2.0 + title_voff, tmpvy[0], title, rsizel1, 0, 0, charindex) if title
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
- DCLExt.color_bar_title_units(vxmin, vxmax, vymin, vymax, portrait, voff,
2701
- opt['title'], opt['units'], opt['title_voff'], opt['units_voff'])
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
- opt['title'], opt['units'], opt['title_voff'], opt['units_voff'])
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
- gphys.cderiv(lond,x)
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
- gphys.threepoint_O2nd_deriv(latd,y)
99
+ bc = GPhys::Derivative::CYCLIC_OR_LINEAR
100
+ gphys.threepoint_O2nd_deriv(latd,bc,y)
99
101
  end
100
102
 
101
103
  end