Execute the shanum program to determine the optimum qmax
    according to an estimation of the optimum number of Shannon
    channels.
    
    Inputs:
        filename: either a name of an ascii file, or an instance
            of Curve
        dmax: the cut-off of the P(r) function, if known. If None,
            this will be determined by the shanum program
        noprint: if the printout of the program is to be suppressed.
    
    Outputs: dmax, nsh, nopt, qmaxopt
        dmax: the cut-off of the P(r) function.
        nsh: the estimated number of Shannon channels
        nopt: the optimum number of Shannon channels
        qmaxopt: the optimum value of the high-q cutoff

def shanum(filename, dmax=None, noprint=True):
    """Execute the shanum program to determine the optimum qmax
    according to an estimation of the optimum number of Shannon
    channels.
    
    Inputs:
        filename: either a name of an ascii file, or an instance
            of Curve
        dmax: the cut-off of the P(r) function, if known. If None,
            this will be determined by the shanum program
        noprint: if the printout of the program is to be suppressed.
    
    Outputs: dmax, nsh, nopt, qmaxopt
        dmax: the cut-off of the P(r) function.
        nsh: the estimated number of Shannon channels
        nopt: the optimum number of Shannon channels
        qmaxopt: the optimum value of the high-q cutoff
    """
    if isinstance(filename, Curve):
        curve = filename
        with tempfile.NamedTemporaryFile('w+b', delete=False) as f:
            curve.save(f)
            filename = f.name
    cmdline = ['shanum', filename]
    if dmax is not None:
        cmdline.append(str(float(dmax)))
    result = execute_command(cmdline, noprint=noprint)
    for l in result:
        l = l.strip()
        if l.startswith('Dmax='):
            dmax = float(l.split('=')[1])
        elif l.startswith('Smax='):
            qmax = float(l.split('=')[1])
        elif l.startswith('Nsh='):
            nsh = float(l.split('=')[1])
        elif l.startswith('Nopt='):
            nopt = float(l.split('=')[1])
        elif l.startswith('Sopt='):
            qmaxopt = float(l.split('=')[1])

    return dmax, nsh, nopt, qmaxopt