def parse_psd_file(filestr, fvals):
    """
    Map the user-provided PSD file string into a function to be called as PSD(f).
    """

    if not os.path.isfile(filestr):
        try:
            psd_func = getattr(lalsimulation, filestr)
            return numpy.array(map(psd_func, fvals))
        except AttributeError:
            pass

    try:
        xmldoc = utils.load_filename(filestr,
                                     contenthandler=LIGOLWContentHandler)
        psd = read_psd_xmldoc(xmldoc).values()[0]
        f = numpy.arange(0, len(psd.data) * psd.deltaF, psd.deltaF)
        psd = psd.data
    except:
        # FIXME: ugh!
        try:
            f, psd = numpy.loadtxt(filestr, unpack=True)
        except:
            exit("Can't parse PSD specifier %s as function or file." % filestr)

    def anon_interp(newf):
        return numpy.interp(newf, f, psd)

    return numpy.array(map(anon_interp, fvals))
def parse_psd_file(filestr, fvals):
    """
    Map the user-provided PSD file string into a function to be called as PSD(f).
    """ 
  
    if not os.path.isfile(filestr):
        try:
            psd_func = getattr(lalsimulation, filestr)
            return numpy.array(map(psd_func, fvals))
        except AttributeError:
            pass

    try:
        xmldoc = utils.load_filename(filestr, contenthandler=LIGOLWContentHandler)
        psd = read_psd_xmldoc(xmldoc).values()[0]
        f = numpy.arange(0, len(psd.data)*psd.deltaF, psd.deltaF)
        psd = psd.data
    except:
        # FIXME: ugh!
        try:
            f, psd = numpy.loadtxt(filestr, unpack=True)
        except:
           exit("Can't parse PSD specifier %s as function or file." % filestr)

    def anon_interp(newf):
        return numpy.interp(newf, f, psd)
    return numpy.array(map(anon_interp, fvals))
    eff_fisher_psd = lal.LIGOIPsd
    analyticPSD_Q = True
else:
    psd_map = common_cl.parse_cl_key_value(opts.psd_file)
    for inst, psdfile in psd_map.items():
        if psd_map.has_key(psdfile):
            psd_map[psdfile].add(inst)
        else:
            psd_map[psdfile] = set([inst])
        del psd_map[inst]

    for psdf, insts in psd_map.iteritems():
        xmldoc = utils.load_filename(psdf, contenthandler=series.LIGOLWContentHandler)
        # FIXME: How to handle multiple PSDs
        for inst in insts:
            psd = series.read_psd_xmldoc(xmldoc)[inst]
            psd_f_high = len(psd.data)*psd.deltaF
            f = np.arange(0, psd_f_high, psd.deltaF)
            fvals = np.arange(0, psd_f_high, PSIG.deltaF)

            def anon_interp(newf):
                return np.interp(newf, f, psd.data)
            eff_fisher_psd = np.array(map(anon_interp, fvals))

    analyticPSD_Q = False

IP = lsu.Overlap(fLow = ip_min_freq,
        deltaF = PSIG.deltaF,
        psd = eff_fisher_psd,
        analyticPSD_Q = analyticPSD_Q
        )
    analyticPSD_Q = True
else:
    psd_map = common_cl.parse_cl_key_value(opts.psd_file)
    for inst, psdfile in psd_map.items():
        if psd_map.has_key(psdfile):
            psd_map[psdfile].add(inst)
        else:
            psd_map[psdfile] = set([inst])
        del psd_map[inst]

    for psdf, insts in psd_map.iteritems():
        xmldoc = utils.load_filename(
            psdf, contenthandler=series.LIGOLWContentHandler)
        # FIXME: How to handle multiple PSDs
        for inst in insts:
            psd = series.read_psd_xmldoc(xmldoc)[inst]
            psd_f_high = len(psd.data) * psd.deltaF
            f = np.arange(0, psd_f_high, psd.deltaF)
            fvals = np.arange(0, psd_f_high, PSIG.deltaF)

            def anon_interp(newf):
                return np.interp(newf, f, psd.data)

            eff_fisher_psd = np.array(map(anon_interp, fvals))

    analyticPSD_Q = False

IP = lsu.Overlap(fLow=ip_min_freq,
                 deltaF=PSIG.deltaF,
                 psd=eff_fisher_psd,
                 analyticPSD_Q=analyticPSD_Q)