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 cps.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 cps.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(): cps.AlphanumericText.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 cps.ValidationError( "Custom thresholds must be a comma-separated list " 'of numbers (example: "1.0, 2.3, 4.5")', group.custom_thresholds, )
def validate_module(self, pipeline): # Keep users from using LoadSingleImage to define image sets if not any([x.is_load_module() for x in pipeline.modules()]): raise cps.ValidationError( "LoadSingleImage cannot be used to run a pipeline on one " "image file. Please use LoadImages or LoadData instead.", self.directory) # Make sure LoadSingleImage appears after all other load modules after = False for module in pipeline.modules(): if module is self: after = True elif after and module.is_load_module(): raise cps.ValidationError( "LoadSingleImage must appear after all other Load modules in your pipeline\n" "Please move %s before LoadSingleImage" % module.module_name, self.directory) # Make sure metadata tags exist for group in self.file_settings: text_str = group.file_name.value undefined_tags = pipeline.get_undefined_metadata_tags(text_str) if len(undefined_tags) > 0: raise cps.ValidationError( "%s is not a defined metadata tag. Check the metadata specifications in your load modules" % undefined_tags[0], group.file_name)
def validate_module(self, pipeline): """Make sure chosen objects and images are selected only once""" settings = {} for group in self.images: if ( group.image_name.value, group.wants_objects.value, group.object_name.value, ) in settings: if not group.wants_objects.value: raise cps.ValidationError( "%s has already been selected" % group.image_name.value, group.image_name, ) else: raise cps.ValidationError( "%s has already been selected with %s" % (group.object_name.value, group.image_name.value), group.object_name, ) settings[ ( group.image_name.value, group.wants_objects.value, group.object_name.value, ) ] = True
def validate_module(self, pipeline): """Make sure chosen objects, images and scales are selected only once""" images = set() for group in self.image_groups: if group.image_name.value in images: raise cps.ValidationError( "%s has already been selected" % group.image_name.value, group.image_name) images.add(group.image_name.value) objects = set() for group in self.object_groups: if group.object_name.value in objects: raise cps.ValidationError( "%s has already been selected" % group.object_name.value, group.object_name) objects.add(group.object_name.value) scales = set() for group in self.scale_groups: if group.scale.value in scales: raise cps.ValidationError( "%s has already been selected" % group.scale.value, group.scale) scales.add(group.scale.value)
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 cps.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 cps.ValidationError("The CreateBatchFiles module must be " "the last in the pipeline.", self.wants_default_output_directory)
def validate_module(self, pipeline): '''Make sure the module settings are valid''' # This must be the last module in the pipeline if id(self) != id(pipeline.modules()[-1]): raise cps.ValidationError( "The RunOnCluster module must be " "the last in the pipeline.", self.runname) max_runtime = int(cluster_max_runtime()) if self.max_walltime.value >= max_runtime: raise cps.ValidationError( "The maximum runtime must be less than " + str(max_runtime) + " hours.", self.max_walltime)
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 cps.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 cps.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(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: logger.warning("Failed to load rules: %s", str(instance), exc_info=True) raise cps.ValidationError( str(instance), measurement_setting.rules_file_name) if not np.all( [r.object_name == cpmeas.IMAGE for r in rules.rules]): raise cps.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 cps.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 cps.ValidationError( "Failed to load classifier file %s" % measurement_setting.rules_file_name.value, measurement_setting.rules_file_name, ) except: raise cps.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): """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 cps.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 cps.ValidationError("You must output at least one of the color images when in split mode", self.use_hue)
def validate_module_warnings(self, pipeline): """Warn user re: Test mode """ if pipeline.test_mode: raise cps.ValidationError( "CalculateStatistics will not produce any output in test mode", self.grouping_values, )
def validate_module_warnings(self, pipeline): """Warn user re: Test mode """ if pipeline.test_mode: raise cps.ValidationError( "CreateBatchFiles will not produce output in Test Mode", self.wants_default_output_directory, )
def validate_module(self, pipeline): '''Make sure settings are compatible. In particular, we make sure that no measurements are duplicated''' measurements, sources = self.get_measurement_columns(pipeline, return_sources=True) d = {} for m, s in zip(measurements, sources): if m in d: raise cps.ValidationError("Measurement %s made twice." % (m[1]), s[0]) d[m] = True
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 cps.ValidationError("At least one of the operands must be an image", op.image_or_measurement)
def validate_module(self, pipeline): '''Validate a module's settings''' for setting in (self.omero_host, self.omero_port, self.omero_username, self.omero_password): if setting.value == '': raise cps.ValidationError( "Cannot continue if \"%s\" is not set." % setting.get_text(), setting)
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 cps.ValidationError("You must supply at least one grayscale input", self.wants_red_input)
def validate_module(self, pipeline): '''Make sure metadata tags exist''' for cntrl in (self.web_page_file_name, self.title): undefined_tags = pipeline.get_undefined_metadata_tags(cntrl.value) if len(undefined_tags) > 0: raise cps.ValidationError( "%s is not a defined metadata tag. Check the metadata specifications in your load modules" % undefined_tags[0], cntrl)
def validate_module(self, pipeline): """Make sure chosen objects are selected only once""" objects = set() for group in self.object_groups: if group.name.value in objects: raise cps.ValidationError( "%s has already been selected" % group.name.value, group.name) objects.add(group.name.value)
def validate_module(self, pipeline: cpp.Pipeline) -> None: objects = set() for group in self.object_groups: if group.name.value in objects: raise cps.ValidationError( "{group_name} has already been selected".format( group_name=group.name.value), group.name, ) objects.add(group.name.value)
def validate_module(self, pipeline): """Make sure chosen objects and images are selected only once""" settings = {} for group in self.operands: if (group.operand_choice.value, group.operand_objects.value) in settings: if group.operand_choice.value == O_OBJECTS: raise cps.ValidationError( "%s has already been selected" % group.operand_objects.value, group.operand_objects) settings[(group.operand_choice.value, group.operand_objects.value)] = True settings = {} for group in self.operands: if (group.operand_choice.value, group.binary_name.value) in settings: if group.operand_choice.value == O_BINARY_IMAGE: raise cps.ValidationError( "%s has already been selected" % group.binary_name.value, group.binary_name) settings[(group.operand_choice.value, group.binary_name.value)] = True
def validate_module_warnings(self, pipeline): '''Check for potentially dangerous settings''' # Check that user-specified names don't have bad characters invalid_chars_pattern = "^[A-Za-z][A-Za-z0-9_]+$" warning_text = "The image name has questionable characters. The pipeline can use this name " \ "and produce results, but downstream programs that use this data (e.g, MATLAB, MySQL) may error." for file_setting in self.file_settings: if file_setting.image_objects_choice == IO_IMAGES: if not re.match(invalid_chars_pattern, file_setting.image_name.value): raise cps.ValidationError(warning_text, file_setting.image_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 cps.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 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 cps.ValidationError("No such rules file: %s" % path, rules_file) else: rules = cprules.Rules() rules.parse(path) return rules
def validate_module(self, pipeline): """Validate a module's settings""" for setting in ( self.omero_host, self.omero_port, self.omero_username, self.omero_password, ): if setting.value == "": raise cps.ValidationError( 'Cannot continue if "%s" is not set.' % setting.get_text(), setting)
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 cps.ValidationError( "At least one of the images must not be blank", self.color_scheme_settings[0].image_name)
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.sub_object_name.value, "Parent") if self.parent_name.value in parent_features: raise cps.ValidationError( "%s and %s were related by the %s module" % (self.sub_object_name.value, self.parent_name.value, module.module_name), self.parent_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 cps.ValidationError( "%s has already been chosen" % group.step_parent_name.value, group.step_parent_name) step_parents.add(group.step_parent_name.value)
def test_valid(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. """ try: for setting in self.visible_settings(): setting.test_valid(pipeline) self.validate_module(pipeline) except cps.ValidationError as instance: raise instance except Exception as e: raise cps.ValidationError("Exception in cpmodule.test_valid %s" % e, self.visible_settings()[0])
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 cps.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 test_module_warnings(self, pipeline): """Test to see if there are any troublesome setting values in the module Throw a ValidationError exception with an explanation if a module is likely to be misconfigured. An example is if ExportToDatabase is not the last module. """ try: for setting in self.visible_settings(): setting.test_setting_warnings(pipeline) self.validate_module_warnings(pipeline) except cps.ValidationError as instance: raise instance except Exception as e: raise cps.ValidationError("Exception in cpmodule.test_valid %s" % e, self.visible_settings()[0])
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 cps.ValidationError("No such rules file: %s" % path_, self.rules_file_name) else: from sklearn.externals import joblib d[path_] = joblib.load(path_) return d[path_]
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 != cpmeas.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 cps.ValidationError( 'The feature, "%s", was already defined in module # %d' % (self.output_feature_name.value, module.module_num), self.output_feature_name)