docs: def get_generalised_coordinates(self, lons, lats):
          """
          Transforms the site positions into the generalised coordinate form
          described by Spudich and Chiou (2015) for the multi-rupture and/or
          discordant case
  
          Spudich, Paul and Chiou, Brian (2015) Strike-parallel and strike-normal
          coordinate system around geometrically complicated rupture traces —
          Use by NGA-West2 and further improvements: U.S. Geological Survey
          Open-File Report 2015-1028
          """
          # If the GC2 configuration has not been setup already - do it!
          if not self.gc2_config:
              self._setup_gc2_framework()
          # Initially the weights are set to zero
          sx, sy = self.proj(lons, lats)
          sum_w_i = numpy.zeros_like(lons)
          sum_w_i_t_i = numpy.zeros_like(lons)
          sum_wi_ui_si = numpy.zeros_like(lons)
          # Find the cumulative length of the fault up until the given segment
          # Essentially calculating s_i
          general_t = numpy.zeros_like(lons)
          general_u = numpy.zeros_like(lons)
          on_segment = numpy.zeros_like(lons, dtype=bool)
          # Loop over the traces
          for j, edges in enumerate(self.cartesian_edges):
              # Loop over segments in trace
              # s_ij_total = 0.0
              for i in range(edges.shape[0] - 1):
                  # Get u_i and t_i
                  u_i, t_i = self._get_ut_i(edges[i:(i + 2), :], sx, sy)
                  # If t_i is 0 and u_i is within the section length then site is
                  # directly on the edge - therefore general_t is 0
                  w_i = numpy.zeros_like(lons)
                  ti0_check = numpy.fabs(t_i) < 1.0E-3  # < 1 m precision
                  on_segment_range = numpy.logical_and(
                      u_i >= 0.0,
                      u_i <= self.length_set[j][i])
                  # Deal with the case in which t_i is 0 and the site is inside
                  # of the segment
                  idx0 = numpy.logical_and(ti0_check, on_segment_range)
                  # In this null case w_i is ignored - however, null sites on
                  # previous segments would not be null sites on this segment,
                  # so we update the list of null sites
                  on_segment[numpy.logical_or(on_segment, idx0)] = True
                  # Also take care of the U case this time using
                  # equation 12 of Spudich and Chiou
                  s_ij = self.cum_length_set[j][i] + numpy.dot(
                      (edges[0, :2] - self.p0), self.gc2_config["b_hat"])
                  general_u[idx0] = u_i[idx0] + s_ij
  
                  # In the first case, ti = 0, u_i is outside of the segment
                  # this implements equation 5
                  idx1 = numpy.logical_and(ti0_check,
                                           numpy.logical_not(on_segment_range))
                  w_i[idx1] = ((1.0 / (u_i[idx1] - self.length_set[j][i])) -
                               (1.0 / u_i[idx1]))
  
                  # In the last case the site is not on the edge (t != 0)
                  # implements equation 4
                  idx2 = numpy.logical_not(ti0_check)
                  w_i[idx2] = ((1. / t_i[idx2]) * (numpy.arctan(
                               (self.length_set[j][i] - u_i[idx2]) / t_i[idx2]) -
                               numpy.arctan(-u_i[idx2] / t_i[idx2])))
  
                  idx = numpy.logical_or(idx1, idx2)
                  # Equation 3
                  sum_w_i[idx] += w_i[idx]
                  # Part of equation 2
                  sum_w_i_t_i[idx] += (w_i[idx] * t_i[idx])
                  # Part of equation 9
                  sum_wi_ui_si[idx] += (w_i[idx] * (u_i[idx] + s_ij))
  
          # For those sites not on the segment edge itself
          idx_t = numpy.logical_not(on_segment)
          general_t[idx_t] = (1.0 / sum_w_i[idx_t]) * sum_w_i_t_i[idx_t]
          general_u[idx_t] = (1.0 / sum_w_i[idx_t]) * sum_wi_ui_si[idx_t]
          return general_t, general_u