Пример #1
0
def process_options(options, gw_data_source_opts, pipeline, mainloop):
    # Locate and load the initialization file
    if not options.infile:
        print >> sys.stderr, "Initialization file required."
    elif not os.path.exists(options.infile):
        print >> sys.stderr, "Initialization file path is invalid."
        sys.exit(-1)

    cfg = SafeConfigParser()
    cfg.read(options.infile)

    #
    # This supplants the ligo_data_find step and is mostly convenience
    #
    # TODO: Move to a utility library

    if gw_data_source_opts.data_source == "frames" and gw_data_source_opts.frame_cache is None:
        if gw_data_source_opts.seg is None:
            sys.exit(
                "No frame cache present, and no GPS times set. Cannot query for data without an interval to query in."
            )

        # Shamelessly stolen from gw_data_find
        print "Querying LDR server for data location."
        try:
            server, port = os.environ["LIGO_DATAFIND_SERVER"].split(":")
        except ValueError:
            sys.exit("Invalid LIGO_DATAFIND_SERVER environment variable set")
        print "Server is %s:%s" % (server, port)

        try:
            frame_type = cfg.get("instrument", "frame_type")
        except ConfigParser.NoOptionError:
            sys.exit(
                "Invalid cache location, and no frame type set, so I can't query LDR for the file locations."
            )
        if frame_type == "":
            sys.exit("No frame type set, aborting.")

        print "Frame type is %s" % frame_type
        connection = datafind.GWDataFindHTTPConnection(host=server, port=port)
        print "Equivalent command line is "
        # FIXME: Multiple instruments?
        inst = gw_data_source_opts.channel_dict.keys()[0]
        print "gw_data_find -o %s -s %d -e %d -u file -t %s" % (
            inst[0], gw_data_source_opts.seg[0], gw_data_source_opts.seg[1],
            frame_type)
        cache = connection.find_frame_urls(inst[0],
                                           frame_type,
                                           gw_data_source_opts.seg[0],
                                           gw_data_source_opts.seg[1],
                                           urltype="file",
                                           on_gaps="error")

        tmpfile, tmpname = tempfile.mkstemp()
        print "Writing cache of %d files to %s" % (len(cache), tmpname)
        with open(tmpname, "w") as tmpfile:
            cache.tofile(tmpfile)
        connection.close()
        gw_data_source_opts.frame_cache = tmpname

    handler = EPHandler(mainloop, pipeline)

    # Enable the periodic output of trigger statistics
    if options.channel_monitoring:
        handler.channel_monitoring = True

    # If a sample rate other than the native rate is requested, we'll need to
    # keep track of it
    if options.sample_rate is not None:
        handler.rate = options.sample_rate

    # Does the user want a cache file to track the trigger files we spit out?
    # And if so, if you give us a name, we'll update it every time we output,
    # else only at the end of the run
    if options.file_cache_name is not None:
        handler.output_cache_name = options.file_cache_name

    # Clustering on/off
    handler.clustering = options.clustering
    # Be verbose?
    handler.verbose = options.verbose

    # Instruments and channels
    # FIXME: Multiple instruments
    if len(gw_data_source_opts.channel_dict.keys()) == 1:
        handler.inst = gw_data_source_opts.channel_dict.keys()[0]
    else:
        sys.exit("Unable to determine instrument.")

    # FIXME: Multiple instruments
    if gw_data_source_opts.channel_dict[handler.inst] is not None:
        handler.channel = gw_data_source_opts.channel_dict[handler.inst]
    else:
        # TODO: In the future, we may request multiple channels for the same
        # instrument -- e.g. from a single raw frame
        sys.exit("Unable to determine channel.")
    print "Channel name(s): " + handler.channel

    # FFT and time-frequency parameters
    # Low frequency cut off -- filter bank begins here
    handler.flow = cfg.getfloat("tf_parameters", "min-frequency")
    # High frequency cut off -- filter bank ends here
    handler.fhigh = cfg.getfloat("tf_parameters", "max-frequency")
    # Frequency resolution of the finest filters
    handler.base_band = cfg.getfloat("tf_parameters", "min-bandwidth")
    # Tile duration should not exceed this value
    handler.max_duration = cfg.getfloat("tf_parameters", "max-duration")
    # Number of resolutions levels. Can't be less than 1, and can't be greater
    # than log_2((fhigh-flow)/base_band)
    handler.max_bandwidth = cfg.getfloat("tf_parameters", "max-bandwidth")
    handler.max_level = int(
        math.floor(math.log(handler.max_bandwidth / handler.base_band, 2))) + 1
    # Frequency band overlap -- in our case, handler uses 1 - frequency overlap
    if options.frequency_overlap > 1 or options.frequency_overlap < 0:
        sys.exit("Frequency overlap must be between 0 and 1.")
    handler.frequency_overlap = options.frequency_overlap

    # DOF options -- this affects which tile types will be calculated
    if cfg.has_option("tf_parameters", "max-dof"):
        handler.max_dof = cfg.getint("tf_parameters", "max-dof")
    if cfg.has_option("tf_parameters", "fix-dof"):
        handler.fix_dof = cfg.getint("tf_parameters", "fix-dof")

    if cfg.has_option("tf_parameters", "fft-length"):
        handler.fft_length = cfg.getfloat("tf_parameters", "fft-length")

    if cfg.has_option("cache", "cache-psd-every"):
        handler.cache_psd = cfg.getint("cache", "cache-psd-every")
        print "PSD caching enabled. PSD will be recorded every %d seconds" % handler.cache_psd
    else:
        handler.cache_psd = None

    if cfg.has_option("cache", "cache-psd-dir"):
        handler.cache_psd_dir = cfg.get("cache", "cache-psd-dir")
        print "Caching PSD to %s" % handler.cache_psd_dir

    # Used to keep track if we need to lock the PSD into the whitener
    psdfile = None
    if cfg.has_option("cache", "reference-psd"):
        psdfile = cfg.get("cache", "reference-psd")
        try:
            handler.psd = lal.series.read_psd_xmldoc(
                ligolw_utils.load_filename(
                    psdfile,
                    contenthandler=lal.series.PSDContentHandler))[handler.inst]
            print "Reference PSD for instrument %s from file %s loaded" % (
                handler.inst, psdfile)
            # Reference PSD disables caching (since we already have it)
            handler.cache_psd = None
            handler.psd_mode = 1
        except KeyError:  # Make sure we have a PSD for this instrument
            sys.exit(
                "PSD for instrument %s requested, but not found in file %s. Available instruments are %s"
                % (handler.inst, psdfile, str(handler.psd.keys())))

    # Triggering options
    if cfg.has_option("triggering", "output-file-stride"):
        handler.dump_frequency = cfg.getint("triggering", "output-file-stride")
    if cfg.has_option("triggering", "output-directory"):
        handler.outdir = cfg.get("triggering", "output-directory")
    if cfg.has_option("triggering", "output-dir-format"):
        handler.outdirfmt = cfg.get("triggering", "output-dir-format")

    handler.output = not options.disable_triggers

    # FAP thresh overrides SNR thresh, because multiple resolutions will have
    # different SNR thresholds, nominally.
    if cfg.has_option("triggering", "snr-thresh"):
        handler.snr_thresh = cfg.getfloat("triggering", "snr-thresh")
    if cfg.has_option("triggering", "fap-thresh"):
        handler.fap = cfg.getfloat("triggering", "fap-thresh")

    if handler.fap is not None:
        print "False alarm probability threshold (in Gaussian noise) is %g" % handler.fap
    if handler.snr_thresh is not None:
        print "Trigger SNR threshold sqrt(E/ndof-1) is %f" % handler.snr_thresh

    # Maximum number of events (+/- a few in the buffer) before which we drop an
    # output file
    if cfg.has_option("triggering", "events_per_file"):
        handler.max_events = cfg.get_int("triggering", "events_per_file")

    return handler