예제 #1
0
        public override bool contains(String value, Dictionary<String, String> context)
        {
            // make null values match the same as if they were blank
            if (value == null)
                value = "";

            if (_usesContext)
                return (matchesAll() || (DecisionEngineFuncs.translateValue(_low, context).CompareTo(value) <= 0 && DecisionEngineFuncs.translateValue(_high, context).CompareTo(value) >= 0));
            else
                return (matchesAll() || (_low.CompareTo(value) <= 0 && _high.CompareTo(value) >= 0));
        }
        // Parses a string in having lists of ranges into a List of Range objects
        // @param values String representing sets value ranges
        // @return a parsed list of string Range objects
        public static List <Range> splitValues(String values)
        {
            List <Range> convertedRanges = new List <Range>();

            if (values != null)
            {
                // if the value of the string is "*", then consider it as matching anything
                if (values == "*")
                {
                    convertedRanges.Add(_MATCH_ALL_ENDPOINT);
                }
                else
                {
                    // split the string; the "9999" makes sure to not discard empty strings
                    String[] ranges = values.Split(",".ToCharArray(), 9999);

                    foreach (String range in ranges)
                    {
                        // Not sure if this is the best way to handle this, but I ran into a problem when I converted the CS data.  One of the tables had
                        // a value of "N0(mol-)".  This fails since it considers it a range and we require our ranges to have the same size on both sides.
                        // The only thing I can think of is for cases like this, assume it is not a range and use the whole string as a non-range value.
                        // The problem is that if something is entered incorrectly and was supposed to be a range, we will not process it correctly.  We
                        // may need to revisit this issue later.
                        String[] parts = range.Split("-".ToCharArray());
                        if (parts.Length == 2)
                        {
                            String low  = parts[0].Trim();
                            String high = parts[1].Trim();

                            // check if both sides of the range are numeric values; if so the length does not have to match
                            bool isNumericRange = StagingRange.isNumeric(low) && StagingRange.isNumeric(high);

                            // if same length, a numeric range, or one of the parts is a context variable, use the low and high as range.  Otherwise consier
                            // a single value (i.e. low = high)
                            if (low.Length == high.Length || isNumericRange || DecisionEngineFuncs.isReferenceVariable(low) || DecisionEngineFuncs.isReferenceVariable(high))
                            {
                                convertedRanges.Add(new StagingRange(low, high));
                            }
                            else
                            {
                                convertedRanges.Add(new StagingRange(range.Trim(), range.Trim()));
                            }
                        }
                        else
                        {
                            convertedRanges.Add(new StagingRange(range.Trim(), range.Trim()));
                        }
                    }
                }
            }

            return(convertedRanges);
        }
예제 #3
0
        // For a given table, return the index of the row that matches supplied context.
        // @param tableId table identifier
        // @param context context of input key/values to use to match
        // @return the index of the matching table row or null if no match was found
        public int findMatchingTableRow(String tableId, Dictionary <String, String> context)
        {
            int rowIndex = -1;

            // add the context keys
            addContextKeys(context);

            ITable table = getTable(tableId);

            if (table != null)
            {
                rowIndex = DecisionEngineFuncs.findMatchingTableRow(table, context);
            }

            return(rowIndex);
        }
예제 #4
0
        // Check the validity of a single field of a schema based on the supplied context.  The value of this key should be in the context as well
        // as any other properties needed to evaluation validity.  If the schema or field do no exist, false will be returned.
        // @param schemaId schema identifier
        // @param key input key
        // @param context Map of keys/values to validate against
        // @return a boolean indicating whether the code exists for the the passed schema field
        public bool isContextValid(String schemaId, String key, Dictionary <String, String> context)
        {
            // first get the algorithm
            StagingSchema schema = getSchema(schemaId);

            if (schema == null)
            {
                return(false);
            }

            // get the table id from the schema
            IInput input = null;

            if (!schema.getInputMap().TryGetValue(key, out input))
            {
                input = null;
            }

            if (input == null)
            {
                return(false);
            }

            // missing context will always return false
            if (context == null || context.Count == 0)
            {
                return(false);
            }

            // all context input needs to be trimmed
            Dictionary <String, String> testContext = new Dictionary <String, String>(20, StringComparer.Ordinal);

            foreach (KeyValuePair <String, String> entry in context)
            {
                testContext[entry.Key] = (entry.Value != null ? entry.Value.Trim() : "");
            }

            // if the input specifies a table for validation, test against it
            if (input.getTable() != null)
            {
                ITable table = getTable(input.getTable());

                return(table != null && (DecisionEngineFuncs.matchTable(table, testContext) != null));
            }

            return(true);
        }
        // Look up a schema based on site, histology and an optional discriminator.
        // @param lookup schema lookup input
        // @return a list of StagingSchemaInfo objects
        private List <StagingSchema> getSchemas(SchemaLookup lookup)
        {
            List <StagingSchema> matchedSchemas = new List <StagingSchema>(5);

            String site             = lookup.getInput(StagingData.PRIMARY_SITE_KEY);
            String histology        = lookup.getInput(StagingData.HISTOLOGY_KEY);
            bool   hasDiscriminator = lookup.hasDiscriminator();

            // site or histology must be supplied and they must be valid; I am assuming that all algorithms must have tables that validate
            // both site and histology
            if ((site != null && !isValidSite(site)) || (histology != null && !isValidHistology(histology)))
            {
                return(matchedSchemas);
            }

            // searching on a discriminator is only supported if also searching on site and histology; if ssf25 supplied without either
            // of those fields, return no results
            if (hasDiscriminator && (site == null || (site.Length == 0) || histology == null || (histology.Length == 0)))
            {
                return(matchedSchemas);
            }

            // site or histology must be supplied
            if (site != null || histology != null)
            {
                HashSet <String> lstSchemaIds = getSchemaIds();

                // loop over selection table and match using only the supplied keys
                foreach (String schemaId in lstSchemaIds)
                {
                    StagingSchema schema = (StagingSchema)(getDefinition(schemaId));

                    if (schema.getSchemaSelectionTable() != null)
                    {
                        StagingTable table = (StagingTable)(getTable(schema.getSchemaSelectionTable()));
                        if (table != null && DecisionEngineFuncs.matchTable(table, lookup.getInputs(), lookup.getKeys()) != null)
                        {
                            matchedSchemas.Add(schema);
                        }
                    }
                }
            }

            return(matchedSchemas);
        }
        /**
         * Initialize a table.
         * @param table a BasicTable
         */
        public void initTable(BasicTable table)
        {
            HashSet <String> extraInputs = new HashSet <String>();

            if (table.getRawRows() != null)
            {
                foreach (List <String> row in table.getRawRows())
                {
                    BasicTableRow tableRowEntity = new BasicTableRow();

                    // make sure the number of cells in the row matches the number of columns defined
                    if (table.getColumnDefinitions().Count != row.Count)
                    {
                        throw new InvalidOperationException("Table '" + table.getId() + "' has a row with " + row.Count + " values but should have " + table.getColumnDefinitions().Count + ": " + row);
                    }

                    // loop over the column definitions in order since the data needs to retrieved by array position
                    for (int i = 0; i < table.getColumnDefinitions().Count; i++)
                    {
                        IColumnDefinition col       = table.getColumnDefinitions()[i];
                        String            cellValue = row[i];

                        switch (col.getType())
                        {
                        case ColumnType.INPUT:
                            // if there are no ranges in the list, that means the cell was "blank" and is not needed in the table row
                            List <BasicRange> ranges = splitValues(cellValue);
                            if (!(ranges.Count == 0))
                            {
                                tableRowEntity.addInput(col.getKey(), ranges);

                                // if there are key references used (values that reference other inputs) like {{key}}, then add them to the extra inputs list
                                foreach (BasicRange range in ranges)
                                {
                                    if (DecisionEngineFuncs.isReferenceVariable(range.getLow()))
                                    {
                                        extraInputs.Add(DecisionEngineFuncs.trimBraces(range.getLow()));
                                    }
                                    if (DecisionEngineFuncs.isReferenceVariable(range.getHigh()))
                                    {
                                        extraInputs.Add(DecisionEngineFuncs.trimBraces(range.getHigh()));
                                    }
                                }
                            }
                            break;

                        case ColumnType.ENDPOINT:
                            BasicEndpoint endpoint = parseEndpoint(cellValue);
                            endpoint.setResultKey(col.getKey());
                            tableRowEntity.addEndpoint(endpoint);

                            // if there are key references used (values that reference other inputs) like {{key}}, then add them to the extra inputs list
                            if (EndpointType.VALUE == endpoint.getType() && DecisionEngineFuncs.isReferenceVariable(endpoint.getValue()))
                            {
                                extraInputs.Add(DecisionEngineFuncs.trimBraces(endpoint.getValue()));
                            }
                            break;

                        case ColumnType.DESCRIPTION:
                            // do nothing
                            break;

                        default:
                            throw new InvalidOperationException("Table '" + table.getId() + " has an unknown column type: '" + col.getType() + "'");
                        }
                    }

                    table.getTableRows().Add(tableRowEntity);
                }
            }

            // add extra inputs, if any; do not include context variables since they are not user input
            foreach (String s in TNMStagingCSharp.Src.Staging.Staging.CONTEXT_KEYS)
            {
                extraInputs.Remove(s);
            }

            table.GenerateInputColumnDefinitions();

            table.setExtraInput(extraInputs.Count == 0 ? null : extraInputs);
        }