def validate_module(self, pipeline): images = set() if len(self.images_list.value) == 0: raise ValidationError("No images selected", self.images_list) for image_name in self.images_list.value: if image_name in images: raise ValidationError( "%s has already been selected" % image_name, image_name) images.add(image_name) if self.wants_object_measurements(): objects = set() if len(self.objects_list.value) == 0: raise ValidationError("No objects selected", self.objects_list) for object_name in self.objects_list.value: if object_name in objects: raise ValidationError( "%s has already been selected" % object_name, object_name) objects.add(object_name) scales = set() for group in self.scale_groups: if group.scale.value in scales: raise ValidationError( "{} has already been selected".format(group.scale.value), group.scale, ) scales.add(group.scale.value)
def validate_module(self, pipeline): """Validate the module's settings Relate will complain if the children and parents are related by a prior module or if a step-parent is named twice""" for module in pipeline.modules(): if module == self: break parent_features = module.get_measurements(pipeline, self.y_name.value, "Parent") if self.x_name.value in parent_features: raise ValidationError( "{} and {} were related by the {} module".format( self.y_name.value, self.x_name.value, module.module_name), self.x_name, ) if self.has_step_parents and self.wants_step_parent_distances: step_parents = set() for group in self.step_parent_names: if group.step_parent_name.value in step_parents: raise ValidationError( "{} has already been chosen".format( group.step_parent_name.value), group.step_parent_name, ) step_parents.add(group.step_parent_name.value)
def validate_module(self, pipeline): if self.initialization_failed: raise ValidationError( "Error starting ImageJ. Please check your initialization settings and try again.", self.init_choice ) no_script_msg = "Please select a valid ImageJ script and use the \"Get parameters from script\" button." if not self.parsed_params or not self.script_directory or not self.script_file.value: raise ValidationError( no_script_msg, self.script_file ) script_filepath = path.join(self.script_directory.get_absolute_path(), self.script_file.value) if not path.exists(script_filepath): raise ValidationError( "The script you have selected is not a valid path. " + no_script_msg, self.script_file ) if self.init_choice.get_value() == INIT_LOCAL: app_path = self.get_init_string() if not path.exists(app_path): raise ValidationError( "The local application you have selected is not a valid path.", self.app_directory )
def validate_module(self, pipeline): """Make sure chosen objects are selected only once""" objects = set() if len(self.objects_list.value) == 0: raise ValidationError("No object sets selected", self.objects_list) for object_name in self.objects_list.value: if object_name in objects: raise ValidationError( "%s has already been selected" % object_name, object_name) objects.add(object_name)
def validate_module(self, pipeline): """Make sure that the user has selected some limits when filtering""" if self.mode == MODE_MEASUREMENTS and self.filter_choice == FI_LIMITS: for group in self.measurements: if not (group.wants_minimum.value or group.wants_maximum.value): raise ValidationError( "Please enter a minimum and/or maximum limit for your measurement", group.wants_minimum, ) if self.mode == MODE_RULES: try: rules = self.get_rules() except Exception as instance: logging.warning( "Failed to load rules: %s", str(instance), exc_info=True ) raise ValidationError(str(instance), self.rules_file_name) measurement_columns = pipeline.get_measurement_columns(self) for r in rules.rules: if not any( [ mc[0] == r.object_name and mc[1] == r.feature for mc in measurement_columns ] ): raise ValidationError( ( "The rules file, %s, uses the measurement, %s " "for object %s, but that measurement is not available " "at this stage of the pipeline. Consider editing the " "rules to match the available measurements or adding " "measurement modules to produce the measurement." ) % (self.rules_file_name, r.feature, r.object_name), self.rules_file_name, ) elif self.mode == MODE_CLASSIFIERS: try: self.get_classifier() self.get_bin_labels() self.get_classifier_features() except IOError: raise ValidationError( "Failed to load classifier file %s" % self.rules_file_name.value, self.rules_file_name, ) except: raise ValidationError( "Unable to load %s as a classifier file" % self.rules_file_name.value, self.rules_file_name, )
def validate_module_warnings(self, pipeline): global imagej_process """Warn user if the specified FIJI executable directory is not found, and warn that a copy of FIJI will be downloaded""" warn_msg = "Please note: any initialization method except \"Local\", a new Fiji may be downloaded" " to your machine if cached dependencies not found." init_type = self.init_choice.get_value() if init_type != INIT_LOCAL: # The component we attach the error to depends on if initialization has happened or not if not imagej_process: raise ValidationError(warn_msg, self.init_choice) else: raise ValidationError(warn_msg + " If re-initialization is required, please restart CellProfiler.", self.initialized_method)
def validate_module(self, pipeline): """If using rules, validate them""" for flag in self.flags: for measurement_setting in flag.measurement_settings: if measurement_setting.source_choice == S_RULES: try: rules = self.get_rules(measurement_setting) except Exception as instance: logging.warning("Failed to load rules: %s", str(instance), exc_info=True) raise ValidationError( str(instance), measurement_setting.rules_file_name) if not numpy.all( [r.object_name == IMAGE for r in rules.rules]): raise ValidationError( "The rules listed in %s describe objects instead of images." % measurement_setting.rules_file_name.value, measurement_setting.rules_file_name, ) rule_features = [r.feature for r in rules.rules] measurement_cols = [ c[1] for c in pipeline.get_measurement_columns(self) ] undef_features = list( set(rule_features).difference(measurement_cols)) if len(undef_features) > 0: raise ValidationError( "The rule described by %s has not been measured earlier in the pipeline." % undef_features[0], measurement_setting.rules_file_name, ) elif measurement_setting.source_choice == S_CLASSIFIER: try: self.get_classifier(measurement_setting) self.get_classifier_features(measurement_setting) self.get_bin_labels(measurement_setting) except IOError: raise ValidationError( "Failed to load classifier file %s" % measurement_setting.rules_file_name.value, measurement_setting.rules_file_name, ) except: raise ValidationError( "Unable to load %s as a classifier file" % measurement_setting.rules_file_name.value, measurement_setting.rules_file_name, )
def validate_module(self, pipeline): """Make sure that the row and column are different""" if self.auto_or_manual == AM_MANUAL and self.manual_choice == MAN_COORDINATES: if self.first_spot_row.value == self.second_spot_row.value: raise ValidationError( "The first and second row numbers must be different in " "order to calculate the distance between rows.", self.second_spot_row, ) if self.first_spot_col.value == self.second_spot_col.value: raise ValidationError( "The first and second column numbers must be different " "in order to calculate the distance between columns.", self.second_spot_col, )
def validate_module_warnings(self, pipeline): """Warn user re: Test mode """ if pipeline.test_mode: raise ValidationError( "CreateBatchFiles will not produce output in Test Mode", self.wants_default_output_directory, )
def validate_module(self, pipeline): """Make sure the module settings are valid""" # Ensure we're not an un-updatable version of the module from way back. if self.from_old_matlab.value: raise ValidationError( "The pipeline you loaded was from an old version of CellProfiler 1.0, " "which could not be made compatible with this version of CellProfiler.", self.acknowledge_old_matlab, ) # This must be the last module in the pipeline if id(self) != id(pipeline.modules()[-1]): raise ValidationError( "The CreateBatchFiles module must be " "the last in the pipeline.", self.wants_default_output_directory, )
def validate_module_warnings(self, pipeline): """Warn user re: Test mode """ if pipeline.test_mode: raise ValidationError( "CalculateStatistics will not produce any output in test mode", self.grouping_values, )
def validate_module(self, pipeline): """Guarantee that at least one operand is an image""" for i in range(self.operand_count): op = self.images[i] if op.image_or_measurement == IM_IMAGE: return raise ValidationError("At least one of the operands must be an image", op.image_or_measurement)
def validate_module(self, pipeline): """Make sure settings are compatible. In particular, we make sure that no measurements are duplicated""" if len(self.images_list.value) == 0: raise ValidationError("No images selected", self.images_list) if self.wants_objects.value: if len(self.objects_list.value) == 0: raise ValidationError("No object sets selected", self.objects_list) measurements, sources = self.get_measurement_columns( pipeline, return_sources=True ) d = {} for m, s in zip(measurements, sources): if m in d: raise ValidationError("Measurement %s made twice." % (m[1]), s[0]) d[m] = True
def validate_module(self, pipeline): """Make sure the user has at least one of the grayscale boxes checked""" if (self.input_color_choice == CC_GRAYSCALE and (not self.wants_red_input.value) and (not self.wants_green_input.value) and (not self.wants_blue_input.value)): raise ValidationError( "You must supply at least one grayscale input", self.wants_red_input)
def validate_module(self, pipeline): '''Test the module settings to make sure they are internally consistent''' '''Make sure metadata tags exist''' if self.wants_file_name_suffix.value: text_str = self.file_name_suffix.value undefined_tags = pipeline.get_undefined_metadata_tags(text_str) if len(undefined_tags) > 0: raise ValidationError( "%s is not a defined metadata tag. Check the metadata specifications in your load modules" % undefined_tags[0], self.file_name_suffix)
def validate_module(self, pipeline): if self.save_image_or_figure in ( IF_IMAGE, IF_MASK, IF_CROPPING, ) and self.when_to_save in (WS_FIRST_CYCLE, WS_EVERY_CYCLE): # # Make sure that the image name is available on every cycle # for setting in get_name_providers(pipeline, self.image_name): if setting.provided_attributes.get("available_on_last"): # # If we fell through, then you can only save on the last cycle # raise ValidationError( "%s is only available after processing all images in an image group" % self.image_name.value, self.when_to_save, ) # XXX - should check that if file_name_method is # FN_FROM_IMAGE, that the named image actually has the # required path measurement # Make sure metadata tags exist if self.file_name_method == FN_SINGLE_NAME or ( self.file_name_method == FN_FROM_IMAGE and self.wants_file_name_suffix.value ): text_str = ( self.single_file_name.value if self.file_name_method == FN_SINGLE_NAME else self.file_name_suffix.value ) undefined_tags = pipeline.get_undefined_metadata_tags(text_str) if len(undefined_tags) > 0: raise ValidationError( "%s is not a defined metadata tag. Check the metadata specifications in your load modules" % undefined_tags[0], self.single_file_name if self.file_name_method == FN_SINGLE_NAME else self.file_name_suffix, )
def get_rules(self): """Read the rules from a file""" rules_file = self.rules_file_name.value rules_directory = self.rules_directory.get_absolute_path() path = os.path.join(rules_directory, rules_file) if not os.path.isfile(path): raise ValidationError("No such rules file: %s" % path, self.rules_file_name) else: rules = cellprofiler.utilities.rules.Rules() rules.parse(path) return rules
def get_rules(self, measurement_group): """Read the rules from a file""" rules_file = measurement_group.rules_file_name.value rules_directory = measurement_group.rules_directory.get_absolute_path() path = os.path.join(rules_directory, rules_file) if not os.path.isfile(path): raise ValidationError("No such rules file: %s" % path, rules_file) else: rules = Rules() rules.parse(path) return rules
def validate_module(self, pipeline): """Make sure chosen objects and images are selected only once""" images = set() if len(self.images_list.value) == 0: raise ValidationError("No images selected", self.images_list) for image_name in self.images_list.value: if image_name in images: raise ValidationError( "%s has already been selected" % image_name, image_name) images.add(image_name) if self.wants_objects: objects = set() if len(self.objects_list.value) == 0: raise ValidationError("No objects selected", self.objects_list) for object_name in self.objects_list.value: if object_name in objects: raise ValidationError( "%s has already been selected" % object_name, object_name) objects.add(object_name)
def validate_module_warnings(self, pipeline): """If a CP 1.0 pipeline used a rescaling option other than 'No rescaling', warn the user.""" for j, image in enumerate(self.images): if image.rescale_option != RE_NONE: raise ValidationError( ("Your original pipeline used '%s' to rescale the final image, " "but the rescaling option has been removed. Please use " "RescaleIntensity to rescale your output image. Save your " "pipeline to get rid of this warning.") % image.rescale_option, image.divide_or_subtract, )
def validate_module(self, pipeline): """Test to see if the module is in a valid state to run Throw a ValidationError exception with an explanation if a module is not valid. Make sure that we output at least one image if split """ if self.should_split(): if (self.rgb_or_channels == CH_RGB) and not any( [self.use_red.value, self.use_blue.value, self.use_green.value] ): raise ValidationError( "You must output at least one of the color images when in split mode", self.use_red, ) if (self.rgb_or_channels == CH_HSV) and not any( [self.use_hue.value, self.use_saturation.value, self.use_value.value] ): raise ValidationError( "You must output at least one of the color images when in split mode", self.use_hue, )
def validate_group(): bin_name_count = len(bin_feature_names()) bin_count = number_of_bins() if bin_count < 1: bad_setting = (group.bin_count if group.bin_choice == BC_EVEN else group.custom_thresholds) raise ValidationError( "You must have at least one bin in order to take measurements. " "Either add more bins or ask for bins for objects above or below threshold", bad_setting, ) if bin_name_count != number_of_bins(): raise ValidationError( "The number of bin names (%d) does not match the number of bins (%d)." % (bin_name_count, bin_count), group.bin_names, ) for bin_feature_name in bin_feature_names(): Alphanumeric.validate_alphanumeric_text( bin_feature_name, group.bin_names, True) if group.bin_choice == BC_CUSTOM: try: [ float(x.strip()) for x in group.custom_thresholds.value.split(",") ] except ValueError: raise ValidationError( "Custom thresholds must be a comma-separated list " 'of numbers (example: "1.0, 2.3, 4.5")', group.custom_thresholds, ) elif group.bin_choice == BC_EVEN: if group.low_threshold.value >= group.high_threshold.value: raise ValidationError( "Lower Threshold must be less than Upper Threshold", group.low_threshold, )
def validate_module(self, pipeline): """Make sure that the module's settings are consistent We need at least one image name to be filled in """ if self.scheme_choice not in (SCHEME_STACK, SCHEME_COMPOSITE): if all([ color_scheme_setting.image_name.is_blank for color_scheme_setting in self.color_scheme_settings ]): raise ValidationError( "At least one of the images must not be blank", self.color_scheme_settings[0].image_name, )
def load_classifier(self, measurement_group): """Load the classifier pickle if not cached returns classifier, bin_labels, name and features """ d = self.get_dictionary() file_ = measurement_group.rules_file_name.value directory_ = measurement_group.rules_directory.get_absolute_path() path_ = os.path.join(directory_, file_) if path_ not in d: if not os.path.isfile(path_): raise ValidationError("No such rules file: %s" % path_, self.rules_file_name) else: import joblib d[path_] = joblib.load(path_) return d[path_]
def validate_module(self, pipeline): """Make sure the settings are consistent Check to make sure that we have enough rows and columns if we are in PlaceAdjacent mode. """ if (self.tile_method == T_WITHIN_CYCLES and (not self.wants_automatic_rows) and (not self.wants_automatic_columns) and self.rows.value * self.columns.value < len(self.additional_images) + 1): raise ValidationError( "There are too many images (%d) for a %d by %d grid" % ( len(self.additional_images) + 1, self.columns.value, self.rows.value, ), self.rows, )
def validate_module(self, pipeline): """Make sure chosen objects and images are selected only once""" images = set() if len(self.images_list.value) == 0: raise ValidationError("No images selected", self.images_list) for image_name in self.images_list.value: if image_name in images: raise ValidationError( "%s has already been selected" % image_name, image_name ) images.add(image_name) if self.wants_objects: objects = set() if len(self.objects_list.value) == 0: raise ValidationError("No objects selected", self.objects_list) for object_name in self.objects_list.value: if object_name in objects: raise ValidationError( "%s has already been selected" % object_name, object_name ) objects.add(object_name) if self.wants_percentiles: percentiles = self.percentiles.value.replace(" ", "") if len(percentiles) == 0: raise ValidationError( "No percentiles have been specified", self.percentiles ) for percentile in percentiles.split(","): if percentile == "": continue elif percentile.isdigit(): percentile = int(percentile) else: raise ValidationError( "Percentile was not a valid integer", self.percentiles ) if not 0 <= percentile <= 100: raise ValidationError( "Percentile not within valid range (0-100)", self.percentiles )
def validate_module(self, pipeline): """Do further validation on this module's settings pipeline - this module's pipeline Check to make sure the output measurements aren't duplicated by prior modules. """ all_object_names = [ operand.operand_objects.value for operand in self.operands if operand.object != IMAGE ] for module in pipeline.modules(): if module.module_num == self.module_num: break for name in all_object_names: features = module.get_measurements(pipeline, name, C_MATH) if self.output_feature_name.value in features: raise ValidationError( 'The feature, "%s", was already defined in module # %d' % (self.output_feature_name.value, module.module_num), self.output_feature_name, )
def test_valid(self, pipeline): if self.dir_choice not in self.dir_choices: raise ValidationError( "%s is not a valid directory option" % self.dir_choice, self )
def validate_module_warnings(self, pipeline): '''Warn user re: Test mode ''' if pipeline.test_mode: raise ValidationError( "ExportToACC will not produce output in Test Mode", self.directory)
def validate_module(self, pipeline): if (self.relabel_option == OPTION_MERGE and self.merge_option == UNIFY_PARENT and self.parent_object.value == "None"): raise ValidationError("%s is not a valid object name" % "None", self.parent_object)