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 (group.wants_minimum.value == False and group.wants_maximum.value == False): raise cps.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, instance: logger.warning("Failed to load rules: %s", str(instance), exc_info=True) raise cps.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 cps.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)
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): '''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, 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)
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, 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 self.module_num != len(pipeline.modules()): 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 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 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): '''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 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): '''Test the module settings to make sure they are internally consistent''' if (len(self.delimiter.value) != 1 and not self.delimiter.value in (DELIMITER_TAB, DELIMITER_COMMA)): raise cps.ValidationError( "The CSV field delimiter must be a single character", self.delimiter) '''Make sure metadata tags exist''' for group in self.object_groups: if not group.wants_automatic_file_name: 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 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): '''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): '''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): '''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): '''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_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 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): """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(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 != SCHEME_STACK: 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.value)
def validate_module(self, pipeline): '''Mark ClassifyPixels as invalid if Ilastik is not properly installed ''' if not has_ilastik: raise cps.ValidationError( "ClassifyPixels is not available on this platform.", self.no_ilastik_msg) if self.h5_directory.dir_choice != URL_FOLDER_NAME: fileName = os.path.join(self.h5_directory.get_absolute_path(), self.classifier_file_name.value) if not os.path.isfile(fileName): if len(self.classifier_file_name.value) == 0: msg = "Please select a classifier file" else: msg = "Could not find the classifier file, \"%s\"." % \ fileName raise cps.ValidationError(msg, self.classifier_file_name)
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): if hasattr(self, "object_fraction"): try: if self.object_fraction.value.endswith("%"): float(self.object_fraction.value[:-1]) else: float(self.object_fraction.value) except ValueError: raise cps.ValidationError( "%s is not a floating point value" % self.object_fraction.value, self.object_fraction)
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(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 validate_module(self, pipeline): '''Make sure that the user has selected some limits when filtering''' if (self.rules_or_measurement == ROM_MEASUREMENTS and self.filter_choice == FI_LIMITS): for group in self.measurements: if (group.wants_minimum.value == False and group.wants_maximum.value == False): raise cps.ValidationError( 'Please enter a minimum and/or maximum limit for your measurement', group.wants_minimum) if self.rules_or_measurement == ROM_RULES: try: rules = self.get_rules() except Exception, instance: logger.warning("Failed to load rules: %s", str(instance), exc_info=True) raise cps.ValidationError(str(instance), self.rules_file_name) if not np.all( [r.object_name == self.object_name.value for r in rules.rules]): raise cps.ValidationError( "%s do not match the objects listed in the rules" % self.object_name.value, self.rules_file_name)
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 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): '''Validate the module settings pipeline - current pipeline Metadata throws an exception if any of the metadata tags collide with tags that can be automatically extracted. ''' for group in self.extraction_methods: if group.extraction_method == X_MANUAL_EXTRACTION: re_setting = (group.file_regexp if group.source == XM_FILE_NAME else group.folder_regexp) for token in cpmeas.find_metadata_tokens(re_setting.value): if token in cpmeas.RESERVED_METADATA_TAGS: raise cps.ValidationError( 'The metadata tag, "%s", is reserved for use by CellProfiler. Please use some other tag name.' % token, re_setting)
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)