def l1Wshape(W, cri):
    """Get internal shape for an :math:`\\ell_1` norm weight array.

    Get appropriate internal shape (see
    :class:`CSC_ConvRepIndexing`) for an :math:`\\ell_1` norm weight
    array `W`, as in option ``L1Weight`` in
    :class:`.admm.cbpdn.ConvBPDN.Options` and related options classes.
    The external shape of `W` depends on the external shape of input
    data array `S` and the size of the final axis (i.e. the number of
    filters) in dictionary array `D`.  The internal shape of the
    weight array `W` is required to be compatible for multiplication
    with the internal sparse representation array `X`.  The simplest
    criterion for ensuring that the external `W` is compatible with
    `S` is to ensure that `W` has shape ``S.shape + D.shape[-1:]``,
    except that non-singleton dimensions may be replaced with
    singleton dimensions.  If `W` has a single additional axis that is
    neither a spatial axis nor a filter axis, it is assigned as a
    channel or multi-signal axis depending on the corresponding
    assignement in `S`.

    Parameters
    ----------
    W : array_like
      Weight array
    cri : :class:`CSC_ConvRepIndexing` object
      Object specifying convolutional representation dimensions

    Returns
    -------
    shp : tuple
      Appropriate internal weight array shape
    """
    sdim = cri.dimN + cri.dimC + cri.dimK
    if W.ndim < sdim:
        if W.size == 1:
            shpW = (1,) * (cri.dimN + 3)
        else:
            raise ValueError(
                'weight array must be scalar or have at least the same number of dimensions as input array'
                )
    elif W.ndim == sdim:
        shpW = W.shape + (1,) * (3 - cri.dimC - cri.dimK)
    elif W.ndim == cri.dimN + 3:
        shpW = W.shape
    else:
        shpW = W.shape[0:-1] + (1,) * (2 - cri.dimC - cri.dimK) + W.shape[-1:]
    return shpW
