Beispiel #1
0
def test_track_event():
    """
    Test that event tracking goes through
    """
    r = popylar.track_event("UA-86484662-2", 'test', 'test_track_event',
                            thread=False)
    # When not threading, we can can check the status of the request:
    assert r.status_code == 200, "response is not OK"

    r = popylar.track_event("UA-86484662-2", 'test', 'test_track_event',
                            thread=True)
    # Otherwise the return value is none
    assert r is None, "There should be nothing to see here"
Beispiel #2
0
def test_track_event_with_version():
    """
    Test recording the software version (in this case, popylar version)
    """
    from popylar.version import VERSION
    r = popylar.track_event("UA-86484662-2", 'test',
                            'test_track_event_with_version',
                            software_version=VERSION, thread=False)
    # When not threading, we can can check the status of the request:
    assert r.status_code == 200, "response is not OK"

    r = popylar.track_event("UA-86484662-2", 'test',
                            'test_track_event_with_version',
                            software_version=VERSION, thread=True)
    # Otherwise the return value is none
    assert r is None, "There should be nothing to see here"
Beispiel #3
0
def test_track_event_with_version():
    """
    Test recording the software version (in this case, popylar version)
    """
    from popylar.version import VERSION
    r = popylar.track_event("UA-86484662-2",
                            'test',
                            'test_track_event_with_version',
                            software_version=VERSION)
    assert r.status_code == 200, "response is not OK"
Beispiel #4
0
def main():
    """Entry point."""
    import os
    import sys
    import gc
    from multiprocessing import Process, Manager
    from .parser import parse_args
    from ..utils.bids import write_derivative_description

    parse_args()

    popylar = None
    if not config.execution.notrack:
        import popylar
        from ..__about__ import __ga_id__
        config.loggers.cli.info(
            "Your usage of dmriprep is being recorded using popylar (https://popylar.github.io/). ",  # noqa
            "For details, see https://nipreps.github.io/dmriprep/usage.html. ",
            "To opt out, call dmriprep with a `--notrack` flag")
        popylar.track_event(__ga_id__, 'run', 'cli_run')

    # CRITICAL Save the config to a file. This is necessary because the execution graph
    # is built as a separate process to keep the memory footprint low. The most
    # straightforward way to communicate with the child process is via the filesystem.
    config_file = config.execution.work_dir / '.dmriprep.toml'
    config.to_filename(config_file)

    # CRITICAL Call build_workflow(config_file, retval) in a subprocess.
    # Because Python on Linux does not ever free virtual memory (VM), running the
    # workflow construction jailed within a process preempts excessive VM buildup.
    with Manager() as mgr:
        from .workflow import build_workflow
        retval = mgr.dict()
        p = Process(target=build_workflow, args=(str(config_file), retval))
        p.start()
        p.join()

        retcode = p.exitcode or retval.get('return_code', 0)
        dmriprep_wf = retval.get('workflow', None)

    # CRITICAL Load the config from the file. This is necessary because the ``build_workflow``
    # function executed constrained in a process may change the config (and thus the global
    # state of dMRIPrep).
    config.load(config_file)

    if config.execution.reports_only:
        sys.exit(int(retcode > 0))

    if dmriprep_wf and config.execution.write_graph:
        dmriprep_wf.write_graph(graph2use="colored",
                                format='svg',
                                simple_form=True)

    retcode = retcode or (dmriprep_wf is None) * os.EX_SOFTWARE
    if retcode != 0:
        sys.exit(retcode)

    # Generate boilerplate
    with Manager() as mgr:
        from .workflow import build_boilerplate
        p = Process(target=build_boilerplate,
                    args=(str(config_file), dmriprep_wf))
        p.start()
        p.join()

    if config.execution.boilerplate_only:
        sys.exit(int(retcode > 0))

    # Clean up master process before running workflow, which may create forks
    gc.collect()

    if popylar is not None:
        popylar.track_event(__ga_id__, 'run', 'started')

    config.loggers.workflow.log(
        15, '\n'.join(['dMRIPrep config:'] +
                      ['\t\t%s' % s for s in config.dumps().splitlines()]))
    config.loggers.workflow.log(25, 'dMRIPrep started!')
    errno = 1  # Default is error exit unless otherwise set
    try:
        dmriprep_wf.run(**config.nipype.get_plugin())
    except Exception as e:
        if not config.execution.notrack:
            popylar.track_event(__ga_id__, 'run', 'error')
        config.loggers.workflow.critical('dMRIPrep failed: %s', e)
        raise
    else:
        config.loggers.workflow.log(25, 'dMRIPrep finished successfully!')

        # Bother users with the boilerplate only iff the workflow went okay.
        if (config.execution.output_dir / 'dmriprep' / 'logs' /
                'CITATION.md').exists():
            config.loggers.workflow.log(
                25, 'Works derived from this dMRIPrep execution should '
                'include the following boilerplate:\n\n%s',
                (config.execution.output_dir / 'dmriprep' / 'logs' /
                 'CITATION.md').read_text())

        if config.workflow.run_reconall:
            from templateflow import api
            from niworkflows.utils.misc import _copy_any
            dseg_tsv = str(
                api.get('fsaverage', suffix='dseg', extension=['.tsv']))
            _copy_any(
                dseg_tsv,
                str(config.execution.output_dir / 'dmriprep' /
                    'desc-aseg_dseg.tsv'))
            _copy_any(
                dseg_tsv,
                str(config.execution.output_dir / 'dmriprep' /
                    'desc-aparcaseg_dseg.tsv'))
        errno = 0
    finally:
        from niworkflows.reports import generate_reports
        from pkg_resources import resource_filename as pkgrf

        # Generate reports phase
        failed_reports = generate_reports(config.execution.participant_label,
                                          config.execution.output_dir,
                                          config.execution.work_dir,
                                          config.execution.run_uuid,
                                          config=pkgrf(
                                              'dmriprep',
                                              'config/reports-spec.yml'),
                                          packagename='dmriprep')
        write_derivative_description(config.execution.bids_dir,
                                     config.execution.output_dir / 'dmriprep')

        if failed_reports and not config.execution.notrack:
            popylar.track_event(__ga_id__, 'run', 'reporting_error')
        sys.exit(int((errno + failed_reports) > 0))
Beispiel #5
0
def test_track_event():
    """
    Test that event tracking goes through
    """
    r = popylar.track_event("UA-86484662-2", 'test', 'test_track_event')
    assert r.status_code == 200, "response is not OK"
Beispiel #6
0
def main():
    """Entry point"""
    from nipype import logging as nlogging
    from multiprocessing import set_start_method, Process, Manager
    from ..utils.bids import write_derivative_description, validate_input_dir
    from ..__about__ import __ga_id__
    set_start_method('forkserver')
    warnings.showwarning = _warn_redirect
    opts = get_parser().parse_args()

    exec_env = os.name

    # special variable set in the container
    if os.getenv('IS_DOCKER_8395080871'):
        exec_env = 'singularity'
        cgroup = Path('/proc/1/cgroup')
        if cgroup.exists() and 'docker' in cgroup.read_text():
            exec_env = 'docker'
            if os.getenv('DOCKER_VERSION_8395080871'):
                exec_env = 'dmriprep-docker'

    if not opts.notrack:
        import popylar
        popylar.track_event(__ga_id__, 'run', 'cli_run')

    # Validate inputs
    if not opts.skip_bids_validation:
        print("Making sure the input data is BIDS compliant (warnings can be ignored in most "
              "cases).")
        validate_input_dir(exec_env, opts.bids_dir, opts.participant_label)

    # FreeSurfer license
    default_license = str(Path(os.getenv('FREESURFER_HOME')) / 'license.txt')
    # Precedence: --fs-license-file, $FS_LICENSE, default_license
    license_file = opts.fs_license_file or Path(os.getenv('FS_LICENSE', default_license))
    if not license_file.exists():
        raise RuntimeError("""\
ERROR: a valid license file is required for FreeSurfer to run. dMRIPrep looked for an existing \
license file at several paths, in this order: 1) command line argument ``--fs-license-file``; \
2) ``$FS_LICENSE`` environment variable; and 3) the ``$FREESURFER_HOME/license.txt`` path. Get it \
(for free) by registering at https://surfer.nmr.mgh.harvard.edu/registration.html""")
    os.environ['FS_LICENSE'] = str(license_file.resolve())

    # Retrieve logging level
    log_level = int(max(25 - 5 * opts.verbose_count, logging.DEBUG))
    # Set logging
    logger.setLevel(log_level)
    nlogging.getLogger('nipype.workflow').setLevel(log_level)
    nlogging.getLogger('nipype.interface').setLevel(log_level)
    nlogging.getLogger('nipype.utils').setLevel(log_level)

    # Call build_workflow(opts, retval)
    with Manager() as mgr:
        retval = mgr.dict()
        p = Process(target=build_workflow, args=(opts, retval))
        p.start()
        p.join()

        retcode = p.exitcode or retval.get('return_code', 0)

        bids_dir = Path(retval.get('bids_dir'))
        output_dir = Path(retval.get('output_dir'))
        work_dir = Path(retval.get('work_dir'))
        plugin_settings = retval.get('plugin_settings', None)
        subject_list = retval.get('subject_list', None)
        dmriprep_wf = retval.get('workflow', None)
        run_uuid = retval.get('run_uuid', None)

    if opts.reports_only:
        sys.exit(int(retcode > 0))

    if opts.boilerplate:
        sys.exit(int(retcode > 0))

    if dmriprep_wf and opts.write_graph:
        dmriprep_wf.write_graph(graph2use="colored", format='svg', simple_form=True)

    retcode = retcode or int(dmriprep_wf is None)
    if retcode != 0:
        sys.exit(retcode)

    # Check workflow for missing commands
    missing = check_deps(dmriprep_wf)
    if missing:
        print("Cannot run dMRIPrep. Missing dependencies:", file=sys.stderr)
        for iface, cmd in missing:
            print("\t{} (Interface: {})".format(cmd, iface))
        sys.exit(2)
    # Clean up master process before running workflow, which may create forks
    gc.collect()

    errno = 1  # Default is error exit unless otherwise set
    try:
        dmriprep_wf.run(**plugin_settings)
    except Exception as e:
        if not opts.notrack:
            popylar.track_event(__ga_id__, 'run', 'cli_error')
        logger.critical('dMRIPrep failed: %s', e)
        raise e
    else:
        if opts.run_reconall:
            from templateflow import api
            from niworkflows.utils.misc import _copy_any
            dseg_tsv = str(api.get('fsaverage', suffix='dseg', extension=['.tsv']))
            _copy_any(dseg_tsv,
                      str(output_dir / 'dmriprep' / 'desc-aseg_dseg.tsv'))
            _copy_any(dseg_tsv,
                      str(output_dir / 'dmriprep' / 'desc-aparcaseg_dseg.tsv'))
        errno = 0
        logger.log(25, 'dMRIPrep finished without errors')
        if not opts.notrack:
            popylar.track_event(__ga_id__, 'run', 'cli_finished')

    finally:
        from niworkflows.reports import generate_reports
        from subprocess import check_call, CalledProcessError, TimeoutExpired
        from pkg_resources import resource_filename as pkgrf
        from shutil import copyfile

        citation_files = {
            ext: output_dir / 'dmriprep' / 'logs' / ('CITATION.%s' % ext)
            for ext in ('bib', 'tex', 'md', 'html')
        }

        if citation_files['md'].exists():
            # Generate HTML file resolving citations
            cmd = ['pandoc', '-s', '--bibliography',
                   pkgrf('dmriprep', 'data/boilerplate.bib'),
                   '--filter', 'pandoc-citeproc',
                   '--metadata', 'pagetitle="dMRIPrep citation boilerplate"',
                   str(citation_files['md']),
                   '-o', str(citation_files['html'])]

            logger.info('Generating an HTML version of the citation boilerplate...')
            try:
                check_call(cmd, timeout=10)
            except (FileNotFoundError, CalledProcessError, TimeoutExpired):
                logger.warning('Could not generate CITATION.html file:\n%s',
                               ' '.join(cmd))

            # Generate LaTex file resolving citations
            cmd = ['pandoc', '-s', '--bibliography',
                   pkgrf('dmriprep', 'data/boilerplate.bib'),
                   '--natbib', str(citation_files['md']),
                   '-o', str(citation_files['tex'])]
            logger.info('Generating a LaTeX version of the citation boilerplate...')
            try:
                check_call(cmd, timeout=10)
            except (FileNotFoundError, CalledProcessError, TimeoutExpired):
                logger.warning('Could not generate CITATION.tex file:\n%s',
                               ' '.join(cmd))
            else:
                copyfile(pkgrf('dmriprep', 'data/boilerplate.bib'),
                         citation_files['bib'])
        else:
            logger.warning('dMRIPrep could not find the markdown version of '
                           'the citation boilerplate (%s). HTML and LaTeX versions'
                           ' of it will not be available', citation_files['md'])

        # Generate reports phase
        failed_reports = generate_reports(
            subject_list, output_dir, work_dir, run_uuid,
            config=pkgrf('dmriprep', 'config/reports-spec.yml'),
            packagename='dmriprep')
        write_derivative_description(bids_dir, output_dir / 'dmriprep')

        sys.exit(int((errno + failed_reports) > 0))