def setup(self, ctx): if (not hasattr(ctx.spec.features[-1], "contrasts") or ctx.spec.features[-1].contrasts is None): ctx.spec.features[-1].contrasts = [] if len(ctx.spec.features[-1].contrasts) == 0: self._append_view(TextView("Specify contrasts")) self._append_view(SpacerView(1)) self.names = set( contrast.get("name") for contrast in ctx.spec.features[-1].contrasts) base = "contrast" index = 1 suggestion = f"{base}{index}" while suggestion in self.names: suggestion = f"{base}{index}" index += 1 self._append_view(TextView("Specify contrast name")) self.input_view = TextInputView( text=suggestion, isokfun=lambda text: forbidden_chars.search(text) is None) self._append_view(self.input_view) self._append_view(SpacerView(1))
def _should_run(self, ctx): if "grand_mean_scaling" not in ctx.spec.settings[-1]: return True self.choice = "Yes" grand_mean_scaling = ctx.spec.settings[-1]["grand_mean_scaling"] if grand_mean_scaling is None: self.choice = "No" message = "No grand mean scaling will be done" self._append_view(TextView(message)) self._append_view(SpacerView(1)) else: mean = grand_mean_scaling.get("mean") message = "Grand mean scaling will be applied" if mean is not None: self.choice = "No" assert isinstance(mean, float) message = f"{message} with a mean of {mean:f}" self._append_view(TextView(message)) self._append_view(SpacerView(1)) return False
def _should_run(self, ctx): if "smoothing" not in ctx.spec.settings[-1]: return True self.choice = "Yes" smoothing = ctx.spec.settings[-1]["smoothing"] if smoothing is None: self.choice = "No" message = "No smoothing will be applied" self._append_view(TextView(message)) self._append_view(SpacerView(1)) else: fwhm = smoothing.get("fwhm") message = "Smoothing will be applied" if fwhm is not None: self.choice = "No" message = f"{message} with an FWHM of {fwhm} mm" self._append_view(TextView(message)) self._append_view(SpacerView(1)) return False
def setup(self, ctx): self.result = None self._append_view( TextView(f"Specify {self.noun} by individual brain mask")) self._append_view( TextView( "Atlas region signals that do not reach the requirement are set to n/a" )) self.valset = set() for feature in ctx.spec.features[:-1]: if feature.type == "atlas_based_connectivity": min_region_coverage = getattr(feature, "min_region_coverage", None) if min_region_coverage is not None: self.valset.add(min_region_coverage) suggestion = self.suggestion if len(self.valset) > 0: suggestion = first(self.valset) self.input_view = NumberInputView(number=suggestion, min=0, max=1.0) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): instruction_str0 = "Contrasts for the mean across all subjects, and for all variables " self._append_view(TextView(instruction_str0)) self._append_view(TextView("will be generated automatically")) self._append_view(SpacerView(1)) super(HaveContrastsStep, self).setup(ctx)
def setup(self, ctx): self.is_first_run = True self.is_missing = False self.variables = [ variable for variable in ctx.spec.analyses[-1].variables if variable.type == "categorical" ] if len(self.variables) > 0: self.is_missing = True self._append_view(TextView("Specify the subjects to use")) self._append_view(SpacerView(1)) self._append_view( TextView( "Select the subjects to include in this analysis by their categorical variables" ) ) self._append_view( TextView("If you specify selections across different categorical variables, ") ) self._append_view(TextView("the intersection of the groups will be used")) options = [_format_column(variable.name) for variable in self.variables] values = [variable.levels for variable in self.variables] self.input_view = MultiMultipleChoiceInputView(options, values, checked=values) self._append_view(self.input_view) self._append_view(SpacerView(1))
def _should_run(self, ctx): if "bandpass_filter" not in ctx.spec.settings[-1]: return True bandpass_filter = ctx.spec.settings[-1]["bandpass_filter"] self.choice = "Yes" type = bandpass_filter.get("type") if type == "gaussian": self.yes_step_type = GaussianWeightedBandpassSettingStep message = "Temporal filtering will be applied using a gaussian-weighted filter" self._append_view(TextView(message)) lp_sigma, hp_sigma = ( bandpass_filter.get("lp_sigma"), bandpass_filter.get("hp_sigma"), ) strings = [] if lp_sigma is not None: strings.append( f"a low-pass filter width of {lp_sigma} seconds") if hp_sigma is not None: strings.append( f"a high-pass filter width of {hp_sigma} seconds") if len(strings) > 0: self.choice = "No" self._append_view(TextView(f"with {p.join(strings)}")) self._append_view(SpacerView(1)) elif type == "frequency_based": self.yes_step_type = FrequencyBasedBandpassSettingStep message = "Temporal filtering will be applied using a frequency-based filter" self._append_view(TextView(message)) low, high = bandpass_filter.get("low"), bandpass_filter.get( "high") strings = [] if low is not None: strings.append(f"a low cutoff of {low} Hz") if low is not None: strings.append(f"a high cutoff of {high} Hz") if len(strings) > 0: self.choice = "No" self._append_view(TextView(f"with {p.join(strings)}")) self._append_view(SpacerView(1)) return False
def setup(self, ctx): self._append_view( TextView(f"The spatial map has {self.nvol} components")) self._append_view(TextView("Specify the spatial map component names")) self.options = [f"Component {i+1}" for i in range(self.nvol)] suggestion = [ make_name_suggestion(self.desc, "component", index=i + 1) for i in range(self.nvol) ] self.input_view = MultiTextInputView(self.options, suggestion) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self._append_view(GiantTextView("Halfpipe")) self._append_view(SpacerView(2)) self._append_view(TextView("Welcome to ENIGMA Halfpipe!")) self._append_view(TextView(f"You are using version {__version__}")) self._append_view(SpacerView(1)) self._append_view( TextView("Please report any problems or leave suggestions at")) self._append_view( TextView("https://github.com/mindandbrain/halfpipe/issues")) self._append_view(SpacerView(1)) self.is_first_run = True
def setup(self, ctx): self.file_obj = None if hasattr(self, "header_str") and self.header_str is not None: self._append_view(TextView(self.header_str)) self._append_view(SpacerView(1)) self._append_view(TextView(f"Specify the path of the {self.filetype_str} files")) schema_entities = self.schema().fields["tags"].nested().fields.keys() schema_entities = [ entity for entity in reversed(entities) if entity in schema_entities ] # keep order # need original entities for this entity_colors_list = [entity_colors[entity] for entity in schema_entities] # convert to display schema_entities = [ self.entity_display_aliases[entity] if entity in self.entity_display_aliases else entity for entity in schema_entities ] required_entities = [*self.ask_if_missing_entities, *self.required_in_path_entities] entity_instruction_strs = [] optional_entity_strs = [] for entity in schema_entities: if entity in required_entities: entity_instruction_strs.append(f"Put {{{entity}}} in place of the {entity} names") else: optional_entity_strs.append(f"{{{entity}}}") if len(optional_entity_strs) > 0: entity_instruction_strs.append(f"You can also use {p.join(optional_entity_strs)}") entity_instruction_views = [TextView("") for str in entity_instruction_strs] for view in entity_instruction_views: self._append_view(view) self.file_pattern_input_view = FilePatternInputView( schema_entities, entity_colors_list=entity_colors_list, required_entities=self.required_in_path_entities, ) self._append_view(self.file_pattern_input_view) for str, view in zip(entity_instruction_strs, entity_instruction_views): view.text = self.file_pattern_input_view._tokenize(str, addBrackets=False) self._append_view(SpacerView(1))
def setup(self, ctx): if ctx.spec.analyses[-1].contrasts is None: self._append_view(TextView("Specify contrasts")) self._append_view(SpacerView(1)) index = 1 else: index = max(1, len(ctx.spec.analyses[-1].contrasts)) if ctx.spec.analyses[-1].contrasts is None: ctx.spec.analyses[-1].contrasts = [] ctx.spec.analyses[-1].contrasts.append(Contrast(type="t")) suggestion = make_name_suggestion("contrast", index=index) self._append_view(TextView("Specify contrast name")) self.input_view = TextInputView(text=suggestion) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self.choice = None self.is_first_run = True if self.header_str is not None: self._append_view(TextView(self.header_str)) filepaths = ctx.database.get(**self.filters) tagvals = ctx.database.tagvalset(self.entity, filepaths=filepaths) self.is_missing = True self.choice = None if tagvals is not None and len(tagvals) > 0: self.is_missing = False self.add_file_str = f"Add {self.filetype_str} file" dsp_values = [f'"{value}"' for value in tagvals] self.tagval_by_str = dict(zip(dsp_values, tagvals)) self.input_view = CombinedMultipleAndSingleChoiceInputView( dsp_values, [self.add_file_str], checked=dsp_values, isVertical=True) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self._append_view(TextView(f"Remove {self.noun}?")) featuresettings = set(feature.setting for feature in ctx.spec.features if hasattr(feature, "setting")) self.confs = set( frozenset( setting.get("confounds_removal", []) + (["ICA-AROMA"] if setting.get("ica_aroma") is True else []) ) for setting in ctx.spec.settings[:-1] # only include active settings if setting.get("output_image", False) or setting["name"] in featuresettings) suggestion = ["ICA-AROMA"] if len(self.confs) > 0: inverse_options = {v: k for k, v in self.options.items()} suggestion = [ inverse_options[s] for s in first(self.confs) if s in inverse_options ] self.input_view = MultipleChoiceInputView(list( self.options.keys()), checked=suggestion, isVertical=True) self._append_view(self.input_view) self._append_view(SpacerView(1)) self.valuedict = None
def setup(self, ctx): self.choice = None self._append_view( TextView( "Specify the variables for which to calculate interaction terms" )) self.variables = ctx.database.metadata(ctx.spec.models[-1].spreadsheet, "variables") self.variables = apply_filters_to_variables( ctx.spec.models[-1].filters, self.variables) contrastvariables = set( ravel(contrast["variable"] for contrast in ctx.spec.models[-1].contrasts if contrast.get("type") == "infer") ) # names of all variables added to the model in the previous step self.variables = [ variable for variable in self.variables if variable["name"] in contrastvariables ] assert len( self.variables) > 0, "No variables to calculate interaction terms" varnames = [variable["name"] for variable in self.variables] options = [format_column(varname) for varname in varnames] self.str_by_varname = dict(zip(varnames, options)) self.input_view = MultipleChoiceInputView(options, isVertical=True) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self.is_first_run = True gen = ctx.database.get(**bold_tags_dict) assert gen is not None self.filepaths = list(gen) assert len(self.filepaths) > 0, "No BOLD images for analysis" db_entities, db_tags_set = ctx.database.get_multi_tagval_set( self.entities, filepaths=self.filepaths) dsp_entities = [] self.tagval_by_str = [] dsp_values = [] options = [] for entity, tagvals in zip(db_entities, zip(*db_tags_set)): tagvals_set = set(tagvals) if len(tagvals_set) > 1: dsp_entities.append(entity) filterval_by_value = [("Use all", None)] filterval_by_value += [ ("Use {}".format(self._format_tag(tagval)), tagval) for tagval in tagvals_set ] self.tagval_by_str.append(dict(filterval_by_value)) value_strs, _ = zip(*filterval_by_value) dsp_values.append(list(value_strs)) options.append(self._tokenize_entity(entity)) self.entities = dsp_entities self.should_run = True if len(options) == 0: self.should_run = False return self._append_view(TextView("Specify scans to use for this analysis")) self.input_view = MultiSingleChoiceInputView(options, dsp_values) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self._append_view( TextView("Specify the categorical variable for this contrast")) self.variables = ctx.database.metadata(ctx.spec.models[-1].spreadsheet, "variables") self.variables = apply_filters_to_variables( ctx.spec.models[-1].filters, self.variables) contrastvariables = set( ravel(contrast["variable"] for contrast in ctx.spec.models[-1].contrasts if contrast.get("type") == "infer") ) # names of all variables added to the model in the previous step self.variables = [ variable for variable in self.variables if variable["type"] == "categorical" and variable["name"] in contrastvariables ] varnames = [variable["name"] for variable in self.variables] options = [format_column(varname) for varname in varnames] self.varname_by_str = dict(zip(options, varnames)) self.input_view = SingleChoiceInputView(options) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self._name = None self.is_first_run = True self.should_run = False assert ctx.spec.settings is not None self.names = set(setting["name"] for setting in ctx.spec.settings) if "name" in settingdict: pass elif namefun is not None: self._name = namefun(ctx) else: self.should_run = True self._append_view(TextView(self.header_str)) base = "preproc" suggestion = base index = 1 while suggestion in self.names: suggestion = f"{base}{index}" index += 1 self.input_view = TextInputView( text=suggestion, isokfun=lambda text: forbidden_chars.search(text) is None) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self.is_first_run = True self.should_run = True self.choice = None if not hasattr(ctx.spec.files[-1], "metadata") or ctx.spec.files[-1].metadata is None: ctx.spec.files[-1].metadata = dict() if ctx.spec.files[-1].metadata.get("variables") is None: ctx.spec.files[-1].metadata["variables"] = [] if any( variable["type"] == "id" for variable in ctx.spec.files[-1].metadata["variables"] ): self.should_run = False if self.should_run: self._append_view(TextView("Specify the column containing subject names")) already_used = set(v["name"] for v in ctx.spec.files[-1].metadata["variables"]) df = loadspreadsheet(ctx.spec.files[-1].path) columns = [column for column in df if column not in already_used] options = [format_column(column) for column in columns] self.varname_by_str = dict(zip(options, columns)) self.input_view = SingleChoiceInputView(options, isVertical=True) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): if not hasattr(ctx.spec.models[-1], "contrasts") or ctx.spec.models[-1].contrasts is None: ctx.spec.models[-1].contrasts = [] self.names = set(contrast["name"] for contrast in ctx.spec.models[-1].contrasts if "name" in contrast) base = "contrast" index = 1 suggestion = f"{base}{index}" while suggestion in self.names: suggestion = f"{base}{index}" index += 1 self._append_view(TextView("Specify contrast name")) self.input_view = TextInputView( text=suggestion, isokfun=lambda text: forbidden_chars.search(text) is None) self._append_view(self.input_view) self._append_view(SpacerView(1)) self.value = None
def setup(self, ctx): self._append_view( TextView("Contrasts for the mean across all subjects, and for all variables ") ) self._append_view(TextView("will be generated automatically")) self._append_view(SpacerView(1)) # generate contrasts automatically if ctx.spec.analyses[-1].contrasts is None: ctx.spec.analyses[-1].contrasts = [] for variable in ctx.spec.analyses[-1].variables: if variable.type != "id": ctx.spec.analyses[-1].contrasts.append( Contrast(variable=[variable.name], type="infer") ) self._append_view(TextView("Specify additional contrasts for categorical variables?")) super(HaveContrastsStep, self).setup(ctx)
def setup(self, ctx): self._append_view(TextView("Specify the action for missing values")) self.variables = ctx.database.metadata(ctx.spec.models[-1].spreadsheet, "variables") self.variables = apply_filters_to_variables( ctx.spec.models[-1].filters, self.variables) self.variables = [ variable for variable in self.variables if variable["type"] != "id" ] contrastvariables = set( ravel(contrast["variable"] for contrast in ctx.spec.models[-1].contrasts if contrast.get("type") == "infer")) self.variables = [ variable for variable in self.variables if variable["name"] in contrastvariables ] varnames = [variable["name"] for variable in self.variables] options = [format_column(varname) for varname in varnames] self.varname_by_str = dict(zip(options, varnames)) self.input_view = MultiSingleChoiceInputView(options, self.values) self._append_view(self.input_view) self._append_view(SpacerView(1))
def _setup_options(self, ctx, filepaths, header_nchr_prepend=0): color_obj = self.app.layout.color self.entities, self.tags_set = ctx.database.get_multi_tagval_set( self.entities, filepaths=filepaths ) colwidths = [ max( len(self._format_entity(entity)), max(len(self._format_tag(tagval)) for tagval in tagvals), ) for entity, tagvals in zip(self.entities, zip(*self.tags_set)) ] entity_strs = [self._format_entity(entity) for entity in self.entities] entity_colors_list = [entity_colors[entity] for entity in self.entities] self._append_view( TextView( self._make_table_row( entity_strs, colwidths, color_obj, offset=header_nchr_prepend, color_list=entity_colors_list, ) ) ) options = [] self.tags_by_str = {} for tags in self.tags_set: option = self._make_table_row( [self._format_tag(tag) for tag in tags], colwidths, color_obj ) self.tags_by_str[str(option)] = tags options.append(option) return options
def setup(self, ctx): self._append_view(TextView("Specify the analysis type")) self.input_view = SingleChoiceInputView( list(self.options.keys()), isVertical=self.is_vertical ) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self._append_view(TextView("Scans will be smoothed before feature extraction")) self._append_view(TextView("Specify the smoothing FWHM in mm")) suggestion = 6.0 self.fwhms = set( analysis.tags.smoothed.as_tupl() for analysis in ctx.spec.analyses if analysis.tags is not None and analysis.tags.smoothed is not None and analysis.type != "image_output" ) if len(self.fwhms) > 0: suggestion = float(first(self.fwhms)[-1]) self.input_view = NumberInputView(number=suggestion, min=0) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self._append_view(TextView(f"Specify {self.noun}")) suggestion = 10000.0 featuresettings = set(feature.setting for feature in ctx.spec.features if hasattr(feature, "setting")) self.means = set() for setting in ctx.spec.settings: if not setting.get( "output_image", False) and setting["name"] not in featuresettings: continue grand_mean_scaling = setting.get("grand_mean_scaling") if grand_mean_scaling is not None: mean = grand_mean_scaling.get("mean") if mean is not None: self.means.add(mean) if len(self.means) > 0: suggestion = float(first(self.means)) self.input_view = NumberInputView(number=suggestion, min=0) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self.choice = None self.is_first_run = True filepaths = ctx.database.get(datatype="spreadsheet") self.is_missing = True self.choice = None if filepaths is not None and len(filepaths) > 0: self.is_missing = False self._append_view(TextView("Select the covariates/group data spreadsheet file")) self.add_file_str = "Add spreadsheet file" dsp_values = [f'"{value}"' for value in filepaths] dsp_values = [*dsp_values, self.add_file_str] self.filepath_by_str = dict(zip(dsp_values, filepaths)) self.input_view = SingleChoiceInputView(dsp_values, isVertical=True) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): self._append_view(TextView(f"Specify {self.noun} in mm")) suggestion = 6.0 featuresettings = set(feature.setting for feature in ctx.spec.features if hasattr(feature, "setting")) self.fwhms = set() for setting in ctx.spec.settings: if not setting.get( "output_image", False) and setting["name"] not in featuresettings: continue smoothing = setting.get("smoothing") if smoothing is not None: fwhm = smoothing["fwhm"] self.fwhms.add(fwhm) if len(self.fwhms) > 0: suggestion = float(first(self.fwhms)) self.input_view = NumberInputView(number=suggestion, min=0) self._append_view(self.input_view) self._append_view(SpacerView(1))
def __call__(self, ctx): try: if not self.was_setup: self.setup(ctx) self.was_setup = True if len(self.views) > 0: self.views[0].focus() # make sure entire step is visible while True: if not self.run(ctx): self.teardown() return try: new_ctx = self.next(deepcopy(ctx)) if new_ctx is not None: return new_ctx # only exit loop when we finish except Exception as e: logging.getLogger("halfpipe.ui").exception("Exception: %s", e) error_color = self.app.layout.color.red self._append_view(TextView(TextElement(str(e), color=error_color))) self._append_view(SpacerView(1)) if ctx.debug: raise except Exception as e: self.teardown() raise e # go back to previous step
def setup(self, ctx): self._append_view(TextView("Specify the feature type")) self.input_view = SingleChoiceInputView(list(self.options.keys()), isVertical=True) self._append_view(self.input_view) self._append_view(SpacerView(1))
def setup(self, ctx): file_obj = ctx.spec.files[-1] self.tags_obj = file_obj.tags assert hasattr(self.tags_obj, self.entity) self._append_view(TextView(self.header_str)) self.number_input_view = NumberInputView(self.initial_value, min=self.min, max=self.max) self._append_view(self.number_input_view) self._append_view(SpacerView(1))