<commit_before>import os
import uuid
import jinja2
from pkg_resources import resource_filename as pkgrf

import nibabel as nb
from nilearn import plotting
from nipype.interfaces import ants, fsl
from nipype.interfaces.base import File, traits
from nipype.utils import filemanip

class ReportCapableInterface(object):
    # constants
    ERROR_REPORT = 'error'
    SUCCESS_REPORT = 'success'

    def run(self):
        ''' delegates to base interface run method, then attempts to generate reports '''
        self.html_report = os.path.join(os.getcwd(), 'report.html')
        try:
            result = super(ReportCapableInterface, self).run()
            #  command line interfaces might not raise an exception, check return_code
            if result.runtime.returncode and result.runtime.returncode != 0:
                self._conditionally_generate_report(self.ERROR_REPORT)
            else:
                self._conditionally_generate_report(self.SUCCESS_REPORT)
        except:
            self._conditionally_generate_report(self.ERROR_REPORT)
            raise

    def _list_outputs(self):
        outputs = super(ReportCapableInterface, self)._list_outputs()
        if self.inputs.generate_report:
            outputs['html_report'] = self.html_report
        return outputs

    def _conditionally_generate_report(self, flag):
        ''' Do nothing if generate_report is not True.
        Otherwise delegate to a report generating method  '''

        # don't do anything unless the generate_report boolean is set to True
        if not self.inputs.generate_report:
            return

        if flag == self.SUCCESS_REPORT:
            self._generate_report()
        elif flag == self.ERROR_REPORT:
            self._generate_error_report()
        else:
            raise ValueError("Cannot generate report with flag {}. "
                             "Use constants SUCCESS_REPORT and ERROR_REPORT."
                             .format(flag))

    def _generate_report(self):
        ''' Saves an html snippet '''
        raise NotImplementedError

    def _generate_error_report(self):
        ''' Saves an html snippet '''
        # as of now we think this will be the same for every interface
        raise NotImplementedError


class RegistrationInputSpecRPT(ants.registration.RegistrationInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class RegistrationOutputSpecRPT(ants.registration.RegistrationOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class RegistrationRPT(ReportCapableInterface, ants.Registration):
    input_spec = RegistrationInputSpecRPT
    output_spec = RegistrationOutputSpecRPT

    def _generate_report(self):
        #  self.input_spec.fixed_image
        #  self.output_spec.warped_image
        with open(output_spec.html_report, 'w') as fp:
            pass

class FASTInputSpecRPT(fsl.preprocess.FASTInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class FASTOutputSpecRPT(fsl.preprocess.FASTOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class FASTRPT(ReportCapableInterface, fsl.FAST):
    input_spec = FASTInputSpecRPT
    output_spec = FASTOutputSpecRPT

    def _generate_report(self):
        raise NotImplementedError


class BETInputSpecRPT(fsl.preprocess.BETInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class BETOutputSpecRPT(fsl.preprocess.BETOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class BETRPT(ReportCapableInterface, fsl.BET):
    input_spec = BETInputSpecRPT
    output_spec = BETOutputSpecRPT

    def _overlay_file_name(self):
        ''' returns an overlay, in this order of preference: mask_file, outline_file,
        out_file, and the name of the output'''
        outputs = self.aggregate_outputs().get()

        for output_name in ['mask_file', 'outline_file', 'out_file']:
            if output_name:
                return outputs[output_name], output_name
        return None, None

    def _pick_output_file(self):
        for _, file_name in self.aggregate_outputs().get().items():
            if file_name and file_name.find('.nii') != -1: # rough check for nifti format
                return file_name
        raise Warning('Could not find outputs for BET; cannot generate report. Inputs are {} and'
                      ' outputs are {}.'.format(self.inputs, self.aggregate_outputs()))

    def _generate_report(self):
        ''' generates a report showing three orthogonal slices of an arbitrary
        volume of in_file, with the resulting binary brain mask overlaid '''

        overlay_file_name, overlay_label = self._overlay_file_name()
        if overlay_file_name:
            cut_coords = plotting.find_xyz_cut_coords(overlay_file_name)

            base_image = plotting.plot_anat(self.inputs.in_file, cut_coords=cut_coords, cmap="gray")
            overlay_image = plotting.plot_img(overlay_file_name, cut_coords=cut_coords)

            save_html(template='overlay_3d_report.tpl',
                      report_file_name=self.html_report,
                      unique_string='bet' + str(uuid.uuid4()),
                      base_image=as_svg(base_image),
                      overlay_image=as_svg(overlay_image),
                      inputs=self.inputs,
                      outputs=self.aggregate_outputs(),
                      title="BET: " + overlay_label + " over the input (anatomical)")

            base_image.close()
            overlay_image.close()
        else: # just print an output (no overlay)
            file_name = self._pick_output_file()
            image = plotting.plot_img(file_name)

            save_html(template='overlay_3d_report.tpl',
                      report_file_name=self.html_report,
                      unique_string='bet' + str(uuid.uuid4()),
                      base_image=as_svg(image),
                      title="BET: " + file_name,
                      inputs=inputs,
                      outputs=outputs)

            image.close()

    def _generate_error_report(self):
        pass

class FLIRTInputSpecRPT(fsl.preprocess.FLIRTInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"<commit_msg>make normal case very clear<commit_after>import os
import uuid
import jinja2
from pkg_resources import resource_filename as pkgrf

import nibabel as nb
from nilearn import plotting
from nipype.interfaces import ants, fsl
from nipype.interfaces.base import File, traits
from nipype.utils import filemanip

class ReportCapableInterface(object):
    # constants
    ERROR_REPORT = 'error'
    SUCCESS_REPORT = 'success'

    def run(self):
        ''' delegates to base interface run method, then attempts to generate reports '''
        self.html_report = os.path.join(os.getcwd(), 'report.html')
        try:
            result = super(ReportCapableInterface, self).run()
            #  command line interfaces might not raise an exception, check return_code
            if result.runtime.returncode and result.runtime.returncode != 0:
                self._conditionally_generate_report(self.ERROR_REPORT)
            else:
                self._conditionally_generate_report(self.SUCCESS_REPORT)
        except:
            self._conditionally_generate_report(self.ERROR_REPORT)
            raise

    def _list_outputs(self):
        outputs = super(ReportCapableInterface, self)._list_outputs()
        if self.inputs.generate_report:
            outputs['html_report'] = self.html_report
        return outputs

    def _conditionally_generate_report(self, flag):
        ''' Do nothing if generate_report is not True.
        Otherwise delegate to a report generating method  '''

        # don't do anything unless the generate_report boolean is set to True
        if not self.inputs.generate_report:
            return

        if flag == self.SUCCESS_REPORT:
            self._generate_report()
        elif flag == self.ERROR_REPORT:
            self._generate_error_report()
        else:
            raise ValueError("Cannot generate report with flag {}. "
                             "Use constants SUCCESS_REPORT and ERROR_REPORT."
                             .format(flag))

    def _generate_report(self):
        ''' Saves an html snippet '''
        raise NotImplementedError

    def _generate_error_report(self):
        ''' Saves an html snippet '''
        # as of now we think this will be the same for every interface
        raise NotImplementedError


class RegistrationInputSpecRPT(ants.registration.RegistrationInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class RegistrationOutputSpecRPT(ants.registration.RegistrationOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class RegistrationRPT(ReportCapableInterface, ants.Registration):
    input_spec = RegistrationInputSpecRPT
    output_spec = RegistrationOutputSpecRPT

    def _generate_report(self):
        #  self.input_spec.fixed_image
        #  self.output_spec.warped_image
        with open(output_spec.html_report, 'w') as fp:
            pass

class FASTInputSpecRPT(fsl.preprocess.FASTInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class FASTOutputSpecRPT(fsl.preprocess.FASTOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class FASTRPT(ReportCapableInterface, fsl.FAST):
    input_spec = FASTInputSpecRPT
    output_spec = FASTOutputSpecRPT

    def _generate_report(self):
        raise NotImplementedError


class BETInputSpecRPT(fsl.preprocess.BETInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
    )

class BETOutputSpecRPT(fsl.preprocess.BETOutputSpec):
    html_report = File(desc="Filename of report generated by node")

class BETRPT(ReportCapableInterface, fsl.BET):
    input_spec = BETInputSpecRPT
    output_spec = BETOutputSpecRPT

    def _overlay_file_name(self):
        ''' returns an overlay, in this order of preference: mask_file, outline_file,
        out_file, and the name of the output'''
        outputs = self.aggregate_outputs().get()

        for output_name in ['mask_file', 'outline_file', 'out_file']:
            if output_name:
                return outputs[output_name], output_name
        return None, None

    def _pick_output_file(self):
        for _, file_name in self.aggregate_outputs().get().items():
            if file_name and file_name.find('.nii') != -1: # rough check for nifti format
                return file_name
        raise Warning('Could not find outputs for BET; cannot generate report. Inputs are {} and'
                      ' outputs are {}.'.format(self.inputs, self.aggregate_outputs()))

    def _generate_report(self):
        ''' generates a report showing three orthogonal slices of an arbitrary
        volume of in_file, with the resulting binary brain mask overlaid '''

        try:
            # most of the time just do simple semi-transparent overlay of brain mask over input
            image = plotting.plot_roi(self.aggregate_outputs().mask_file,
                                      bg_img=self.inputs.in_file, alpha=0.5)
            save_html(template='overlay_3d_report.tpl',
                      report_file_name=self.html_report,
                      unique_string='bet' + str(uuid.uuid4()),
                      base_image=as_svg(image),
                      title="BET: brain mask over anatomical input",
                      inputs=self.inputs,
                      outputs=self.aggregate_outputs())
            image.close()
        except: # inc ase of weird outputs
            overlay_file_name, overlay_label = self._overlay_file_name()
            if overlay_file_name:
                cut_coords = plotting.find_xyz_cut_coords(overlay_file_name)

                base_image = plotting.plot_anat(self.inputs.in_file, cut_coords=cut_coords,
                                                cmap="gray")
                overlay_image = plotting.plot_img(overlay_file_name, cut_coords=cut_coords,
                                                  black_bg=True)

                save_html(template='overlay_3d_report.tpl',
                          report_file_name=self.html_report,
                          unique_string='bet' + str(uuid.uuid4()),
                          base_image=as_svg(base_image),
                          overlay_image=as_svg(overlay_image),
                          inputs=self.inputs,
                          outputs=self.aggregate_outputs(),
                          title="BET: " + overlay_label + " over the input (anatomical)")

                base_image.close()
                overlay_image.close()
            else: # just print an output (no overlay)
                file_name = self._pick_output_file()
                image = plotting.plot_img(file_name)

                save_html(template='overlay_3d_report.tpl',
                          report_file_name=self.html_report,
                          unique_string='bet' + str(uuid.uuid4()),
                          base_image=as_svg(image),
                          title="BET: " + file_name,
                          inputs=self.inputs,
                          outputs=self.aggregate_outputs())
                image.close()

    def _generate_error_report(self):
        pass

class FLIRTInputSpecRPT(fsl.preprocess.FLIRTInputSpec):
    generate_report = traits.Bool(
        desc="Set to true to enable report generation for node"
{'fraction_non_alphanumeric': 0.07685078079814922, 'fraction_numerical': 0.0013013302486986698, 'mean_word_length': 2.3962681070464034, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3842463', 'n_tokens_mistral': 3818, 'n_tokens_neox': 3638, 'n_words': 915}