<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def piecewise(target, throat_endpoints='throat.endpoints', throat_centroid='throat.centroid'):
 r""" Calculate throat length from end points and optionally a centroid Parameters target : OpenPNM Object The object which this model is associated with. This controls the length of the calculated array, and also provides access to other necessary properties. throat_endpoints : string Dictionary key of the throat endpoint values. throat_centroid : string Dictionary key of the throat centroid values, optional. Returns ------- Lt : ndarray Array containing throat lengths for the given geometry. Notes ----- (1) By default, the model assumes that the centroids of pores and the connecting throat in each conduit are colinear. (2) If `throat_centroid` is passed, the model accounts for the extra length. This could be useful for Voronoi or extracted networks. """

    _np.warnings.filterwarnings('ignore', category=RuntimeWarning)
    network = target.project.network
    throats = network.map_throats(throats=target.Ts, origin=target)
    # Get throat endpoints
    EP1 = network[throat_endpoints + '.head'][throats]
    EP2 = network[throat_endpoints + '.tail'][throats]
    # Calculate throat length
    Lt = _sqrt(((EP1 - EP2)**2).sum(axis=1))
    # Handle the case where pores & throat centroids are not colinear
    try:
        Ct = network[throat_centroid][throats]
        Lt = _sqrt(((Ct - EP1)**2).sum(axis=1)) + \
            _sqrt(((Ct - EP2)**2).sum(axis=1))
    except KeyError:
        pass

    _np.warnings.filterwarnings('default', category=RuntimeWarning)

    return Lt