# Observing condition decision tool: monitor conditions and plan HETDEX
# observations
# Copyright (C) 2017, 2018 "The HETDEX collaboration"
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
'''OCD main entry point'''
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import argparse as ap
from tcs_lib import tcs_event
from . import allow_hetdex
from . import db_replay
from . import docker_mysql
from . import errors
from .orchestrator import Orchestrator
from . import config as ocd_config
from . import run_shot
from . import shots_db
from . import tcs_proxy
from . import utils
[docs]def parse(args=None):
'''The OCD command line parser.
Parameters
----------
args : list, optional
command to parse. If not given sys.argv is used
Returns
-------
:class:`argparse.Namespace`
parsed command line
'''
description = """Run OCD."""
parser = ap.ArgumentParser(description=description,
parents=[utils.common_parser_arguments(), ],
formatter_class=ap.ArgumentDefaultsHelpFormatter)
subparsers = parser.add_subparsers(title='Valid subcommands',
dest='subcommand',
description="""Type '%(prog)s cmd -h'
for detailed information about the
subcommands""")
subparsers.required = True
subparsers = run_parser(subparsers)
subparsers = ocd_config.config_subcommand(subparsers)
subparsers = run_shot.run_shot_parser(subparsers)
subparsers = allow_hetdex.allow_hetdex_parser(subparsers)
subparsers = db_replay.db_replay_parser(subparsers)
subparsers = docker_mysql.docker_subcommand(subparsers)
return parser.parse_args(args=args)
[docs]def run_parser(subparsers):
'''Add a ``run`` subcommand to run OCD and its arguments.
Parameters
----------
subparsers : argparse subparsers object
subparser to use to generate new parsers
Returns
-------
parser : :class:`argparse.ArgumentParser`
modified parser
'''
main_parser = subparsers.add_parser('run', help='Run OCD',
description='''Subcommand to run
OCD''',
formatter_class=ap.ArgumentDefaultsHelpFormatter)
main_parser.set_defaults(func=run_ocd)
main_parser = utils.override_epilog_msg(main_parser)
main_parser = ocd_config.config_file_argument(main_parser)
title = 'Override options in the [ulrs] section'
overrides_ulrs = main_parser.add_argument_group(title=title)
overrides_ulrs.add_argument('-u', '--event-urls', nargs='+',
dest='setting__urls__event_urls',
metavar='EVENT-URLS', help='''Address to which
to bind the ZMQ socket.''')
title = 'Override options in the [topics] section.'
overrides_topics = main_parser.add_argument_group(title=title)
overrides_topics.add_argument('-t', '--extra-topics', nargs='+',
dest='setting__topics__extra_topics',
metavar='EXTRA-TOPICS',
help='''Topics to subscribe to. OCD
automatically subscribe only to the topics
necessary for it to work. If for any reason
other topics are needed, add them here.''')
overrides_topics.add_argument('-a', '--auto-subscribe',
choices=['yes', 'no'],
dest='setting__topics__auto_subscribe',
help='''Do not subscribe to the topics used
by OCD but only to the ones given by
-t/--topic option.''')
title = 'Override options in the [run] section'
overrides_run = main_parser.add_argument_group(title=title)
for sn in ['ocd_main_loop', 'ocd_run_shot']:
overrides_run.add_argument('--n-{}'.format(sn.replace('_', '-')),
dest='setting__run__n_{}'.format(sn),
metavar='N_{}'.format(sn.upper()),
help='''Which of the urls for the ``{}``
option of the ``[urls]`` section use to
setup a ZMQ server'''.format(sn))
return subparsers
[docs]def main(args=None):
'''Entry point for the ``ocd`` executable.
Parameters
----------
args : list, optional
command line arguments
'''
# parse the command line and setup the configuration object
args = parse(args=args)
args.func(args)
[docs]def run_ocd(args):
'''Run OCD.
Parameters
----------
args : :class:`~argparse.Namespace`
parsed command line arguments
'''
config = ocd_config.load_config(config_file=args.config, args=args,
raise_serious=True)
# Check that the filter names make sense
run_shot.check_fiter_map(config)
# initialise the times
utils.init_times(config)
print("Welcome to OCD")
# get the urls to connect to and the topics to register to
event_urls = config.get_list('urls', 'event_urls', use_default=True)
extra_topics = config.get_list('topics', 'extra_topics', use_default=True)
# initialize various pieces and bits necessary to run OCD
# the proxy must always be the first one to initialize after loading the
# configuration file as it provides the logging functionality to the rest
# of the code
tcs_proxy.init(config)
# initialise the database and load the shot file
shots_db.init(config)
shots_db.store_shot_file(config)
tcs_proxy.tcs_log.log_info('Database initialized and shot file stored')
# initialize the ocd servers urls and collect them for the listener
utils.init_zmq_servers(args.subcommand, config)
tcs_proxy.tcs_log.log_info('OCD ZeroMQ servers initialized')
# listen to all the urls, except the one used to emit events within the
# Orchestrator
internal_urls = utils.get_zmq_server_urls()
# remove the urls emitted in the main loop
for ocd_main_url in utils.get_zmq_server_urls(name='ocd_main_loop'):
internal_urls.remove(ocd_main_url)
event_urls.extend(internal_urls)
tcs_event_listener = tcs_event.SafeTCSEvent(tcs_proxy.tcs_log.log_error,
[errors.TimeOutError, ],
urls=event_urls,
topics=extra_topics,
dates_to_float=True)
ocd = Orchestrator(tcs_event_listener, config)
print('Run OCD')
ocd.run()