public bool DoesRuleMatch(RoutedItem rr, DestRule rule) { RoutedItemEx routedItem = (RoutedItemEx)rr; // Connection source, DestRule rule, DicomDataset dataSet //routedItem.sourceDicomFile?.Dataset //2017-10-09 sbh I was running into "hard to debug" npe so I broke out the logic for easier debugging //The idea here is to fail fast on rules and return false //If a rule field is specified it is "engaged" and must be satisfied //If a rule field is not specified ie null then it does not have to be satisfied //near future: We might like to introspect any rule class to make this more dynamic //all we need is a fieldmatch table between hl7 and DICOM and other sources //then we can introspect class or JSON and loop the specifiers and compare to match //otherwise the Rule class itself can grow ridiculously large. try { return(DoesRuleMatchImpl(routedItem, rule)); } catch (Exception e) { _logger.LogFullException(e); } return(false); }
private bool DoesRuleMatchImpl(RoutedItemEx routedItem, DestRule rule) { //rules requiring DICOM dataset if (routedItem.sourceDicomFile?.Dataset != null) { if (rule.modality != null) { if (routedItem.sourceDicomFile.Dataset.Contains(DicomTag.Modality)) { if (Regex.Matches(routedItem.sourceDicomFile.Dataset.GetValue <string>(DicomTag.Modality, 0), rule.modality, RegexOptions.IgnoreCase).Count == 0) { _logger.Log(LogLevel.Debug, $"rule {rule.name} fails because modality {rule.modality} !matches {routedItem.sourceDicomFile.Dataset.GetValue<string>(DicomTag.Modality, 0)}"); return(false); } } else { _logger.Log(LogLevel.Debug, $"rule {rule.name} fails because DicomTag.Modality missing."); return(false); } } if (rule.referringPhysician != null) { if (routedItem.sourceDicomFile.Dataset.Contains(DicomTag.ReferringPhysicianName)) { if (Regex.Matches(rule.referringPhysician, routedItem.sourceDicomFile.Dataset.GetValue <string>(DicomTag.ReferringPhysicianName, 0), RegexOptions.IgnoreCase).Count == 0) { _logger.Log(LogLevel.Debug, $"rule {rule.name} fails because referringPhysician {rule.referringPhysician} !matches {routedItem.sourceDicomFile.Dataset.GetValue<string>(DicomTag.ReferringPhysicianName, 0)}"); return(false); } } else { _logger.Log(LogLevel.Debug, $"rule {rule.name} fails because DicomTag.ReferringPhysicianName missing."); return(false); } } } if (rule.ruleTags != null && rule.ruleTags.Count > 0) { routedItem = (RoutedItemEx)_doTagsMatchService.DoTagsMatch(rule, routedItem); if (!routedItem.RuleMatch) { _logger.Log(LogLevel.Debug, $"rule {rule.name} fails because Tags {rule.ruleTags} !matches {routedItem.sourceDicomFile.Dataset}"); return(false); } } _logger.Log(LogLevel.Debug, $"rule {rule.name} id: {routedItem.id} succeeds!"); return(true); }
private async Task ProcessDestRule(Rules Item, RoutedItem routedItem, DestRule destRule, string taskInfo) { Throw.IfNull(destRule); _logger.Log(LogLevel.Debug, $"{taskInfo} rule {destRule.name}"); //run the scripts for this rule foreach (var scriptname in destRule.preProcessFromConnectionScriptNames) { _logger.Log(LogLevel.Debug, $"{taskInfo} script {scriptname}"); await ProcessScripts(scriptname, Item.scripts, routedItem, destRule); } }
private RoutedItemEx Hl7Matching(RoutedItemEx ri, DestRule rule) { if (ri.sourceFileName == null || !ri.sourceFileName.EndsWith(".hl7")) { return(null); } foreach (Tag tag in rule.ruleTags) { var segments = ri.hl7.FindAll(e => e.Key == tag.tag.Split(",")[0]); var elementNum = int.Parse(tag.tag.Split(",")[1]); foreach (var segment in segments) { if (segment.Value.Count >= elementNum + 1) { var data = segment.Value[elementNum]; ri.matches.AddRange(Regex.Matches(data, tag.tagValue, RegexOptions.IgnoreCase)); if (ri.matches.Count == 0) { _logger.Log(LogLevel.Debug, $"rule {rule.name} fails this segment because data {data} !matches {tag.tagValue}"); } } } if (ri.matches.Count == 0) { if (!tag.tagValue.Equals("\\0*")) { _logger.Log(LogLevel.Debug, $"rule {rule.name} fails because {tag} missing. Use \"\\0*\" for tagValue if you want to include missing and null tag values."); return(ri); } } _logger.Log(LogLevel.Debug, $"rule {rule.name} succeeds in Tag Match!"); } return(null); }
/// <summary> /// Determines whether all tags specified in the rule are satisfied in the dataSet. If a tagValue can be anything but must be present, use "+." regex /// </summary> /// <param name="rule"></param> /// <param name="rr"></param> /// <returns></returns> public RoutedItem DoTagsMatch(DestRule rule, RoutedItem rr) { RoutedItemEx ri = (RoutedItemEx)rr; //dicom tag matching RoutedItemEx result = DicomMatching(ri, rule); if (result != null) { return(result); } result = Hl7Matching(ri, rule); if (result != null) { return(result); } ri.RuleMatch = true; return(ri); }
private RoutedItemEx DicomMatching(RoutedItemEx ri, DestRule rule) { var dataset = ri.sourceDicomFile?.Dataset; if (dataset == null) { return(null); } foreach (Tag tag in rule.ruleTags) { DicomTag dtTag = DicomTag.Parse(tag.tag); if (dataset.Contains(dtTag)) //if tagvalue can be null it doesn't have to exist { _logger.Log(LogLevel.Debug, $"tag {tag.tag} {dtTag} exists, now getting value..."); string tagValue = dataset.GetValue <string>(dtTag, 0); ri.matches.AddRange(Regex.Matches(tagValue, tag.tagValue, RegexOptions.IgnoreCase)); if (ri.matches.Count == 0) { _logger.Log(LogLevel.Debug, $"rule {rule.name} fails because tag.tagValue {tag.tagValue} !matches {tagValue}"); return(ri); } } else if (!tag.tagValue.Equals("\\0*")) { _logger.Log(LogLevel.Debug, $"rule {rule.name} fails because {dtTag} missing. Use \"\\0*\" for tagValue if you want to include missing and null tag values."); return(ri); } } _logger.Log(LogLevel.Debug, $"rule {rule.name} succeeds in Tag Match!"); return(null); }
private async Task ProcessScripts(string scriptname, List <Script> scripts, RoutedItem routedItem, DestRule destRule) { Throw.IfNull(destRule); var taskInfo = GetTaskInfo(routedItem); _logger.Log(LogLevel.Debug, $"{taskInfo} script {scriptname}"); if (!scriptname.Equals("ruleTags")) { var script = scripts.Find(e => e.name == scriptname); _logger.Log(LogLevel.Debug, $"{taskInfo} running script {script.name}"); await _scriptService.RunAsync(script, routedItem); return; } //run the scripts for the rule tags foreach (Tag ruleTag in destRule.ruleTags) { await ProcessScriptFromTag(ruleTag, routedItem, scripts); } }