@@ -333,7 +333,13 @@ def calc_costs(
333333 surge_noadapt = []
334334 surge = []
335335
336- def _check_vals (rh_diff_arr , lslr_arr , seg ):
336+ def _check_vals (rh_diff_arr , lslr_arr , seg , check_rh_diff_max = True ):
337+ # for surge_noadapt, rh_diff can be greater than max. This happens when
338+ # a segment chooses retreat10000 in their refA (initial adaptation) and
339+ # also has a declining no-climate-change SLR scenario (e.g. for
340+ # no-climate-change scenarios). However, we automatically assign 0
341+ # expected storm impacts for retreat10000, so this is acceptable and
342+ # does not need to exist in the surge lookup table.
337343 error_str = (
338344 "{0} value is {1} than {2} in storm damage lookup "
339345 f"table for segment { seg } . Please investigate why this is. You may "
@@ -343,7 +349,10 @@ def _check_vals(rh_diff_arr, lslr_arr, seg):
343349 )
344350 # lslr is allowed to be below min surge lookup value b/c we created
345351 # lookup such that < min value will be 0 impact
346- if rh_diff_arr .max () > this_surge_lookup .rh_diff .max ():
352+ if (
353+ check_rh_diff_max
354+ and rh_diff_arr .max () > this_surge_lookup .rh_diff .max ()
355+ ):
347356 raise ValueError (error_str .format ("rh_diff" , "higher" , "maximum" ))
348357 if rh_diff_arr .min () < this_surge_lookup .rh_diff .min ():
349358 raise ValueError (error_str .format ("rh_diff" , "lower" , "minimum" ))
@@ -357,13 +366,16 @@ def _check_vals(rh_diff_arr, lslr_arr, seg):
357366 .reset_coords (drop = True )
358367 .frac_losses .rename (lslr_by_seg = "lslr" , rh_diff_by_seg = "rh_diff" )
359368 )
360- lslr_too_low = lslr .sel (seg = seg ) < this_surge_lookup .lslr .min ()
361369 if this_surge_lookup .sum () == 0 :
362370 continue
363371
364372 this_rh_diff_noadapt = rh_diff_noadapt .sel (seg = seg , drop = True )
365373 this_lslr = lslr .sel (seg = seg , drop = True )
366- _check_vals (this_rh_diff_noadapt , this_lslr , seg )
374+ _check_vals (
375+ this_rh_diff_noadapt , this_lslr , seg , check_rh_diff_max = False
376+ )
377+
378+ lslr_too_low = this_lslr < this_surge_lookup .lslr .min ()
367379
368380 this_surge_noadapt = (
369381 this_surge_lookup .sel (adapttype = "retreat" , drop = True )
@@ -376,8 +388,13 @@ def _check_vals(rh_diff_arr, lslr_arr, seg):
376388 .expand_dims (seg = [seg ])
377389 )
378390
379- # ensure nans are only at the beginning
380- assert (this_surge_noadapt .notnull () | lslr_too_low ).all (), seg
391+ # ensure nans are only at the low end of LSLR or high end of rh_diff
392+ rh_diff_too_high = (
393+ this_rh_diff_noadapt > this_surge_lookup .rh_diff .max ()
394+ )
395+ assert (
396+ this_surge_noadapt .notnull () | lslr_too_low | rh_diff_too_high
397+ ).all (), seg
381398
382399 surge_noadapt .append (this_surge_noadapt .fillna (0 ))
383400
@@ -399,7 +416,7 @@ def _check_vals(rh_diff_arr, lslr_arr, seg):
399416 .reset_coords (drop = True )
400417 )
401418
402- # ensure nans are only at the beginning
419+ # ensure nans are only at the low end of lslr
403420 assert (this_surge_adapt .notnull () | lslr_too_low ).all (), seg
404421
405422 surge_adapt .append (this_surge_adapt .fillna (0 ))
@@ -1500,9 +1517,11 @@ def get_refA(
15001517 ** params .refA_scenario_selectors ,
15011518 )
15021519 slr = slr .unstack ("scen_mc" )
1503- slr = slr .squeeze (drop = True )
1520+ slr = slr .squeeze (
1521+ [d for d in slr .dims if len (slr [d ]) == 1 and d != "seg" ], drop = True
1522+ )
15041523
1505- costs , refA = calc_costs (
1524+ return calc_costs (
15061525 inputs , slr , surge_lookup = surge , return_year0_hts = True , ** model_kwargs
15071526 )
15081527
0 commit comments