@@ -594,12 +594,13 @@ def _get_vdatum_chain(self, datum_name, geoid_name):
594594 def _get_global_chain (self , datum_name , model = "fes2014" ):
595595 """Builds shift: Global Tidal -> WGS84 Native."""
596596
597- total_shift = np .zeros ((self .ny , self .nx ))
597+ tidal_shift = np .zeros ((self .ny , self .nx ))
598+ mss_shift = np .zeros ((self .ny , self .nx ))
598599 desc = []
599600
600601 model_def = Datums .MODELS .get (model )
601602 if not model_def :
602- return total_shift , "Error"
603+ return tidal_shift , "Error"
603604
604605 provider = model_def ["provider" ]
605606
@@ -608,26 +609,18 @@ def _get_global_chain(self, datum_name, model="fes2014"):
608609 grid_name = model_def ["grids" ].get ("lat" )
609610 if grid_name :
610611 grid = self ._get_grid (provider , grid_name )
611- # Sign Correction (LAT should be negative relative to MSS)
612612 if np .nanmean (grid ) > 0 :
613613 grid *= - 1.0
614-
615- total_shift += grid
614+ tidal_shift += grid
616615 desc .append ("LAT->MSS" )
617616
618617 elif datum_name == "hat" :
619618 lat_name = model_def ["grids" ].get ("lat" )
620619 if lat_name :
621- logger .info ("HAT requested. Computing FES deep-water symmetry..." )
622620 grid = self ._get_grid (provider , lat_name )
623-
624621 if np .nanmean (grid ) > 0 :
625622 grid *= - 1.0
626-
627- # Symmetry Math: HAT offset is the exact inverse of LAT offset
628- hat_grid = grid * - 1.0
629-
630- total_shift += hat_grid
623+ tidal_shift += grid * - 1.0
631624 desc .append ("HAT->MSS(Symmetry)" )
632625
633626 # MSS -> WGS84
@@ -640,23 +633,36 @@ def _get_global_chain(self, datum_name, model="fes2014"):
640633 else :
641634 desc .append ("MSS->Ellipsoid" )
642635
643- total_shift += mss_grid
644-
645- if np .isnan (total_shift ).any ():
646- coast_shapefiles = self ._fetch_coastline_shapefiles ()
647- land_mask = None
648- if coast_shapefiles :
649- land_mask = GridEngine .create_land_mask (
650- self .region , self .nx , self .ny , coast_shapefiles
651- )
636+ # --- MDT ---
637+ # Isolate the Mean Dynamic Topography (MDT) by subtracting EGM2008
638+ egm_grid , _ = self ._fetch_geoid_with_fallback ("egm2008" )
639+ mdt_grid = mss_grid - egm_grid
640+ desc .append ("MDT Decay -> EGM2008" )
641+
642+ coast_shapefiles = self ._fetch_coastline_shapefiles ()
643+ land_mask = None
644+ if coast_shapefiles :
645+ land_mask = GridEngine .create_land_mask (
646+ self .region , self .nx , self .ny , coast_shapefiles
647+ )
652648
653- total_shift = GridEngine .fill_nans (
654- total_shift ,
649+ if mss_name :
650+ mdt_decayed = GridEngine .fill_nans (
651+ mdt_grid ,
655652 decay_pixels = self .decay_pixels ,
656653 buffer_pixels = 10 ,
657654 land_mask = land_mask ,
658655 )
656+ mss_shift = mdt_decayed + egm_grid
659657
658+ tidal_shift = GridEngine .fill_nans (
659+ tidal_shift ,
660+ decay_pixels = self .decay_pixels ,
661+ buffer_pixels = 10 ,
662+ land_mask = land_mask ,
663+ )
664+
665+ total_shift = tidal_shift + mss_shift
660666 if not desc :
661667 return total_shift , "Global Chain (Empty)"
662668
@@ -764,7 +770,8 @@ def _step_from_hub(self, epsg, ref_type, geoid=None, epoch=None):
764770 s , d = self ._get_global_chain (datum_name )
765771 if s is not None :
766772 total_out -= s
767- desc_parts .append (f"Native -> Global({ datum_name } )" )
773+ # desc_parts.append(f"Native -> Global({datum_name})")
774+ desc_parts .append (d )
768775
769776 elif ref_type == "cdn" :
770777 target_geoid = geoid if geoid else "g2018"
0 commit comments