Examples of contributions

How to add a new sub-command

You need first to clone and install the tool in develop mode

Let’s say that you want to add a new operation to mirtop, for instance, similar to the stats command to work with sGFF3 files. Assume a test function for this exmaple to just read the file and print Hello GFF3.

  • Create the folder inside mirtop/test. The create to empty files named:
  • test.py
  • __init__.py
  • Modify the test.py file with this content:
from mirtop.gff.body import read_gff_line

import mirtop.libs.logger as mylog
logger = mylog.getLogger(__name__)

def test(args):
	for fn in args.files:
		_test(fn)
		logger.info("Hello GFF3: %s" % fn)


def _test(fn):
	logger.debug("I am going to read this file: %s" % fn)
	for line in fn:
		read_gff_line(line)
  • Choose a sub_command name, in this case: test.
  • Add the arguments function at the end of this file: https://github.com/miRTop/mirtop/blob/dev/mirtop/libs/parse.py, using a naming following add_subparser_test.
def add_subparser_test(subparsers):
    parser = subparsers.add_parser("test", help="test function")
    parser.add_argument("files", nargs="*", help="GFF/GTF files.")
    parser = _add_debug_option(parser)
    return parser
  • Add the function name to parse_cl function, at the end of the sub_cmds array.
    sub_cmds = {"gff": add_subparser_gff,
                "stats": add_subparser_stats,
                "compare": add_subparser_compare,
                "target": add_subparser_target,
                "simulator": add_subparser_simulator,
                "counts": add_subparser_counts,
                "export": add_subparser_export,
                "test": add_subparser_test
                }
  • To get the function re-directed from the command line when you use the sub_cmd name, add a line to the command_line.py file, adding another else statement:
	elif "test" in kwargs:
        logger.info("Run test.")
        test(kwargs["args"])
  • The function you use to link to the operation added need to be imported at the beginning. Let’s say that the test function is at mirtop/test/test.py:
from mirtop.test import test

Try the new operation:

mirtop test data/examples/correct_file.gff

Add a unit test

for the internal function

Add to the end of test/test_functions.py, but inside class FunctionsTest(unittest.TestCase): this code:

    @attr(fn_test=True)
    def test_function_test(self):
        from mirtop import test
        test._test("data/examples/gff/correct_file.gff")

for the sub-command

Add to the end of test/test_function.py, but inside class AutomatedAnalysisTest(unittest.TestCase): this code:

    @attr(cmd_test=True)
    def test_srnaseq_annotation_bam(self):
        """Run test analysis
        """
        with make_workdir():
            clcode = ["mirtop",
                      "test",
                      "../../data/examples/gff/correct_file.gff"]
            print("")
            print(" ".join(clcode))
            subprocess.check_call(clcode)

test the unit

nose is needed: pip install nose

Run the function test from the top parent folder:

./run_test.sh fn_test

Run the command test from the top parent folder:

./run_test.sh cmd_test