@@ -355,42 +355,42 @@ def resample(x, y, xi, w=None, dx=1/12., window=3/12, weights=False, median=Fals
355
355
# Window of data centered on time index
356
356
idx = (x >= (xi [i ] - 0.5 * window )) & \
357
357
(x <= (xi [i ] + 0.5 * window ))
358
-
358
+
359
359
# Get weights and data
360
360
ybv = y [idx ]
361
361
wbv = w [idx ]
362
-
362
+
363
363
# Skip if no data
364
364
if len (ybv ) == 0 : continue
365
-
365
+
366
366
# Check use for median or mean (weighted)
367
367
if median is not True :
368
-
368
+
369
369
# Compute initial stats
370
370
m0 = np .median (ybv )
371
371
s0 = 1.4826 * np .median (np .abs (ybv - m0 ))
372
372
373
373
# Index of outliers using 3.5 robust sigma rule
374
374
ind = np .abs (ybv - m0 ) > 3.5 * s0
375
-
375
+
376
376
# Check for issues
377
377
if len (ybv [~ ind ]) == 0 : continue
378
-
378
+
379
379
# Weighted (spatially) or raw average
380
380
if weights :
381
381
ybi = np .sum (wbv [~ ind ] * ybv [~ ind ]) / np .sum (wbv [~ ind ])
382
382
ebi = np .sum (wbv [~ ind ] * (ybv [~ ind ] - ybi )** 2 ) / np .sum (wbv [~ ind ])
383
-
383
+
384
384
else :
385
385
ybi = np .mean (ybv [~ ind ])
386
386
ebi = np .std (ybv [~ ind ])
387
-
387
+
388
388
else :
389
-
389
+
390
390
# Median and error for all points
391
391
ybi = np .median (ybv )
392
392
ebi = np .std (ybv )
393
-
393
+
394
394
# Save values and error
395
395
xb [i ] = xi [i ]
396
396
yb [i ] = ybi
@@ -431,25 +431,25 @@ def resample(x, y, xi, w=None, dx=1/12., window=3/12, weights=False, median=Fals
431
431
432
432
# Start of main function
433
433
def main (file ,cdr , n = '' ):
434
-
434
+
435
435
# Ignore warnings
436
436
import warnings
437
437
warnings .filterwarnings ("ignore" )
438
-
438
+
439
439
# Check if we have processed it
440
440
f_check = file .replace ('.h5' ,'_SEC.h5' )
441
-
441
+
442
442
# Don't read our output
443
443
if "SEC" in file : return
444
-
444
+
445
445
# Check if file exists
446
446
if os .path .exists (f_check ) is True :
447
447
print ("File processed:" , file )
448
448
return
449
-
449
+
450
450
# Global to local inside function
451
451
dx , dy = dx_ , dy_
452
-
452
+
453
453
print ('loading data ...' )
454
454
455
455
# Get variable names
@@ -466,7 +466,7 @@ def main(file,cdr, n=''):
466
466
lew = f [wlvar ][:] if wlvar in f else np .zeros (lon .shape )
467
467
tes = f [wtvar ][:] if wtvar in f else np .zeros (lon .shape )
468
468
bias = f [bvar ][:] if bvar in f else np .zeros (lon .shape )
469
-
469
+
470
470
# Check for NaN's in waveform parmeters
471
471
if len (bsc [np .isnan (bsc )]) > 0 :
472
472
print ("You have Nan's in BSC parameter that you plan on using - you need fill or remove them." )
@@ -476,7 +476,7 @@ def main(file,cdr, n=''):
476
476
sys .exit ()
477
477
if len (tes [np .isnan (tes )]) > 0 :
478
478
print ("You have Nan's in TES parameter that you plan on using - you need fill or remove them." )
479
-
479
+
480
480
# Converte data to wanted projection
481
481
x , y = transform_coord ('4326' , proj , lon , lat )
482
482
@@ -516,7 +516,7 @@ def main(file,cdr, n=''):
516
516
517
517
# Flatten grid coordinates 2d -> 1d
518
518
xi , yi = Xi .ravel (), Yi .ravel ()
519
-
519
+
520
520
# Convert centroid location to latitude and longitude
521
521
lonc , latc = transform_coord (proj , '4326' , xi , yi )
522
522
@@ -539,7 +539,7 @@ def main(file,cdr, n=''):
539
539
# Time vector
540
540
tbin = np .arange (tmin , tmax , tstep ) + 0.5 * tstep
541
541
#tbin = make_time(tmin,tmax)
542
-
542
+
543
543
# Prediction loop
544
544
for i in range (len (xi )):
545
545
@@ -584,94 +584,94 @@ def main(file,cdr, n=''):
584
584
585
585
# Variance of provided error
586
586
sv = sc ** 2
587
-
587
+
588
588
# Apply distance weighting
589
589
if weight :
590
-
590
+
591
591
# Multiply to meters
592
592
cdr = cdr * 1e3
593
-
593
+
594
594
# Weights using distance and error
595
595
wc = 1. / (sv * (1. + (dr / cdr ) ** 2 ))
596
596
wbool = True
597
-
597
+
598
598
else :
599
-
599
+
600
600
# Set weighets
601
601
wc = np .ones (dr .shape )
602
602
wbool = False
603
-
603
+
604
604
# Set correct model for each solution
605
605
Ac = model_order (order .copy (), dt , bc , pxy = [dx ,dy ], wf = [bs ,lw ,ts ])
606
-
606
+
607
607
try :
608
608
# Solve system and invert for model parameters
609
609
xhat , ehat = lstsq (Ac .copy (), zc .copy (),
610
610
n_iter = niter , n_sigma = nsig ,
611
611
ylim = rlim , cov = True )[0 :2 ]
612
-
612
+
613
613
except :
614
614
print ("Can't solve least-squares system ..." )
615
615
continue
616
-
616
+
617
617
# Check if rate is within bounds or nan
618
618
if np .abs (xhat [1 ]) > dhlim or np .isnan (xhat [1 ]): continue
619
619
620
620
# Residuals to model
621
621
dz = zc - np .dot (Ac , xhat )
622
-
622
+
623
623
# Filter residuals - robust MAD
624
624
ibad = np .abs (dz ) > nsig * mad_std (dz )
625
-
625
+
626
626
# Remove bad data from solution
627
627
dz [ibad ] = np .nan
628
-
628
+
629
629
# RMS error of residuals
630
630
rms = np .nanstd (dz )
631
631
632
632
# Time columns in design matrix
633
633
cols = [1 ,2 ,3 ,4 ]
634
-
634
+
635
635
# Set residual offset to zero
636
636
res_offset = np .nan
637
-
637
+
638
638
# Check and add offsets to residuals
639
639
if order [- 1 ] > 1 :
640
640
try :
641
641
# Get overlapping window for missions
642
642
tmin_ , tmax_ = tc [bc == 1 ].min (), tc [bc == 0 ].max ()
643
-
643
+
644
644
# Get overlapping data points
645
645
dz0 = dz [bc == 0 ][(tc [bc == 0 ] > tmin_ ) & (tc [bc == 0 ] < tmax_ )]
646
646
dz1 = dz [bc == 1 ][(tc [bc == 1 ] > tmin_ ) & (tc [bc == 1 ] < tmax_ )]
647
-
647
+
648
648
# Check that we have enough points for overlap
649
649
if len (dz0 ) > zlim and len (dz1 ) > zlim :
650
-
650
+
651
651
# Compute median values over both overlapping parts of data
652
652
b0 = np .nanmedian (dz0 )
653
653
b1 = np .nanmedian (dz1 )
654
-
654
+
655
655
else :
656
656
# Dont use
657
657
b0 = np .nan
658
658
b1 = np .nan
659
-
659
+
660
660
# Compute offset
661
661
res_offset = b1 - b0
662
-
662
+
663
663
# Check if any sub offset is NaN
664
664
if ~ np .isnan (res_offset ):
665
-
665
+
666
666
# Apply offset to index=1
667
667
dz [bc == 1 ] -= res_offset
668
-
668
+
669
669
except :
670
670
pass
671
-
671
+
672
672
# Recover temporal trends
673
673
hc = dz + np .dot (Ac [:,cols ], xhat [cols ])
674
-
674
+
675
675
# Initialze them
676
676
s_amp = np .nan
677
677
s_phs = np .nan
@@ -689,19 +689,19 @@ def main(file,cdr, n=''):
689
689
690
690
# Maks sure phase is from 0-365 days
691
691
if s_phs < 0 : s_phs += 365
692
-
692
+
693
693
# Identify NaN values in array
694
694
inan = ~ np .isnan (hc )
695
-
695
+
696
696
# Bin data to wanted resolution
697
697
tb , zb , eb = resample (tc [inan ].copy (), hc [inan ].copy (), xi = tbin ,\
698
698
w = wc [inan ].copy (), dx = tstep , window = tres ,
699
699
weights = weight , median = False )
700
700
701
- # Convert relocated position to geographical coords.
702
- if nrel > 0 :
703
- lonc [i ], latc [i ] = transform_coord (proj ,'4326' , x_i , y_i )
704
-
701
+ # Convert relocated position to geographical coords.
702
+ if nrel > 0 :
703
+ lonc [i ], latc [i ] = transform_coord (proj ,'4326' , x_i , y_i )
704
+
705
705
# Output data
706
706
f0 [i ,0 ] = lonc [i ]
707
707
f0 [i ,1 ] = latc [i ]
@@ -718,12 +718,12 @@ def main(file,cdr, n=''):
718
718
f0 [i ,12 ] = np .min (dr )
719
719
f0 [i ,13 ] = t_span
720
720
f0 [i ,14 ] = xhat [- 1 ] if order [- 1 ] > 0 else np .nan
721
-
721
+
722
722
# Stack time series
723
723
geo .append ([lonc [i ], latc [i ]])
724
724
sec .append (zb )
725
725
err .append (eb )
726
-
726
+
727
727
# Print progress (every n-th iterations)
728
728
if (i % 1 ) == 0 :
729
729
print ('cell#' , str (i ) + "/" + str (len (xi )), \
@@ -739,7 +739,7 @@ def main(file,cdr, n=''):
739
739
geo = np .vstack (geo )
740
740
except :
741
741
return
742
-
742
+
743
743
# Name of output variables
744
744
vars = ['lon' , 'lat' , 'p0' , 'p1' , 'p2' , 'p0_error' ,
745
745
'p1_error' , 'p2_error' ,'amplitude' ,'phase' ,
@@ -754,10 +754,10 @@ def main(file,cdr, n=''):
754
754
# Output file names - strings
755
755
path , ext = os .path .splitext (outfile )
756
756
ofile0 = path + '_SEC.h5'
757
-
757
+
758
758
# Find NaNs in height vector
759
759
inan = np .isnan (f0 [:,2 ])
760
-
760
+
761
761
# Remove all NaNs from data sets
762
762
f0 = f0 [~ inan ,:]
763
763
@@ -767,7 +767,7 @@ def main(file,cdr, n=''):
767
767
# Save model solutions
768
768
for v , g in zip (vars , f0 .T ):
769
769
foo [v ] = g
770
-
770
+
771
771
# Save binned time series
772
772
foo ['lon(t)' ] = geo [:,0 ]
773
773
foo ['lat(t)' ] = geo [:,1 ]
@@ -791,5 +791,3 @@ def main(file,cdr, n=''):
791
791
with parallel_backend ("loky" , inner_max_num_threads = 1 ):
792
792
Parallel (n_jobs = njobs , verbose = 5 )(delayed (main )(f ,cdr , n ) \
793
793
for n , f in enumerate (files ))
794
-
795
-
0 commit comments