snoplusuk / echidna

MIT License
4 stars 12 forks source link

echidna scripts #146

Open ashleyrback opened 8 years ago

ashleyrback commented 8 years ago

I wanted to make some general comment about the scripts in echidna/scripts for discussion and to think keep in mind. We've recently added lots of cool features, which I think the scripts are in general not taking full advantage of, so I wanted to highlight how this could be achieved as well.

Role of the scripts

Given the above role, I've come up with what I think would be the best structure for all echidna scripts to adopt, in order to achieve this role.

Preamble

""" Module-level documentation.

Most of the scripts are pretty good at this. I think it very useful for scripts to have:

This script:

  * A few bullet points summarising what the script does and what the outputs are

Examples:

  * Example of how to run the script

.. note:: accompanied by a note of any usage features that should be described
  in more detail.
"""
# imports

Logger

All scripts can make use of echidna's logging. The start_logging function from utilities will initiate the logger if this is the base script and in all cases returns a logger with the same name as the module, so it is clear where the message is coming from.

_logger = utilities.start_logging()

Main function

Most of the script should be in a main function

def main(args):

so that it can be imported into other scripts if required. In most cases these scripts will just be run as they are but you may wish to run the script with some pre or post processing, or call it in a loop. Putting the majority of the contents in a separate function makes this easier to achieve.

Note, you can always recreate the command line args in another script using the Namespace object, and pass this too the function.

Also consider if there are any inputs that a user may often wish to pre-process e.g. input spectra. these could then be passed as named kwargs or kwargs in general e.g.

def main(args, **kwargs):
def main(args, signals=[]):
    # Overrides signals passed via argparse

End block

The script would then continue as follows:

if __name__ == "__main__":
    import argparse
    # Set up parser

    args = parser.parse_args()

    try:
        main(args)
    except Exception:
        _logger.exception("echidna terminated because of the following error.")
        # will automatically format exception and traceback nicely in log file,
        # if any exception is raised

Conclusions

Many of these aren't yet implemented in scripts, including scripts that I've written. I'm just posting this to let you know of some of the things you cool things you can now do in echidna and also to outline some ideas of how we may want to structure scripts.

Just some ideas to keep in mind next time you are adding/editing a script.