code: def reconstruct_survival_function(
      probabilities: np.ndarray,
      turnbull_intervals: List[interval],
      timeline=None,
      label="NPMLE",
  ) -> pd.DataFrame:
      if timeline is None:
          timeline = []
  
      index = np.unique(np.concatenate((turnbull_intervals, [(0, 0)])))
      label_upper = label + "_upper"
      label_lower = label + "_lower"
      df = pd.DataFrame(
          [], index=index, columns=[label_upper, label_lower]
      )
  
      running_sum = 1.0
      # the below values may be overwritten later, but we
      # always default to starting at point (0, 1)
      df.loc[0, label_upper] = running_sum
      df.loc[0, label_lower] = running_sum
  
      for p, (left, right) in zip(probabilities, turnbull_intervals):
          df.loc[left, label_upper] = running_sum
          df.loc[left, label_lower] = running_sum
  
          if left != right:
              df.loc[right, label_upper] = running_sum
              df.loc[right, label_lower] = running_sum - p
  
          running_sum -= p
  
      full_dataframe = pd.DataFrame(index=timeline, columns=df.columns)
  
      # First backfill at events between known observations
      # Second fill all events _outside_ known obs with running_sum
      return (
          full_dataframe.combine_first(df)
          .bfill()
          .fillna(running_sum)
          .clip(lower=0.0)
      )
  
imports: from collections import defaultdict, namedtuple
  import warnings
  import numpy
  from numpy.linalg import norm
  import pandas
  from lifelines.exceptions import ConvergenceWarning
  from typing import *
label_desc: Use image node_id 15 for calling a global function with example usage: reconstruct_survival_function(probabilities, turnbull_intervals, timeline, label) and returns: full_dataframe