/// <summary> /// Create the protocol data from the protocol instance /// </summary> public void Load(Core.Model.Acts.Protocol protocolData) { if (protocolData == null) { throw new ArgumentNullException(nameof(protocolData)); } using (MemoryStream ms = new MemoryStream(protocolData.Definition)) this.Definition = ProtocolDefinition.Load(ms); var context = new CdssContext <Patient>(); context.Declare("index", typeof(Int32)); // Add callback rules foreach (var rule in this.Definition.Rules) { for (var index = 0; index < rule.Repeat; index++) { foreach (var itm in rule.Variables) { context.Declare(itm.VariableName, itm.VariableType); } } } this.Definition.When?.Compile <Patient>(context); foreach (var wc in this.Definition.Rules) { wc.When.Compile <Patient>(context); } }
/// <summary> /// Calculate the protocol against a atient /// </summary> public List <Act> Calculate(Patient triggerPatient, IDictionary <String, Object> parameters) { try { #if DEBUG Stopwatch sw = new Stopwatch(); sw.Start(); #endif if (parameters == null) { parameters = new Dictionary <String, Object>(); } // Get a clone to make decisions on Patient patient = null; lock (triggerPatient) { patient = triggerPatient.Clone() as Patient; patient.Participations = new List <ActParticipation>(triggerPatient.Participations); } this.m_tracer.TraceInfo("Calculate ({0}) for {1}...", this.Name, patient); var context = new CdssContext <Patient>(patient); context.Set("index", 0); context.Set("parameters", parameters); foreach (var itm in parameters) { context.Set(itm.Key, itm.Value); } // Evaluate eligibility if (this.Definition.When?.Evaluate(context) == false && !parameters.ContainsKey("ignoreEntry")) { this.m_tracer.TraceInfo("{0} does not meet criteria for {1}", patient, this.Id); return(new List <Act>()); } List <Act> retVal = new List <Act>(); // Rules int step = 0; foreach (var rule in this.Definition.Rules) { for (var index = 0; index < rule.Repeat; index++) { context.Set("index", index); foreach (var itm in rule.Variables) { var value = itm.GetValue(null, context, new Dictionary <String, Object>()); context.Declare(itm.VariableName, itm.VariableType); context.Set(itm.VariableName, value); } // TODO: Variable initialization if (rule.When.Evaluate(context) && !parameters.ContainsKey("ignoreWhen")) { var acts = rule.Then.Evaluate(context); retVal.AddRange(acts); // Assign protocol foreach (var itm in acts) { itm.Protocols.Add(new ActProtocol() { ProtocolKey = this.Id, Protocol = this.GetProtocolData(), Sequence = step }); } } else { this.m_tracer.TraceInfo("{0} does not meet criteria for rule {1}.{2}", patient, this.Name, rule.Name ?? rule.Id); } step++; } } // Now we want to add the stuff to the patient lock (triggerPatient) triggerPatient.Participations.AddRange(retVal.Where(o => o != null).Select(o => new ActParticipation(ActParticipationKey.RecordTarget, triggerPatient) { Act = o, ParticipationRole = new Core.Model.DataTypes.Concept() { Key = ActParticipationKey.RecordTarget, Mnemonic = "RecordTarget" }, Key = Guid.NewGuid() })); #if DEBUG sw.Stop(); this.m_tracer.TraceVerbose("Protocol {0} took {1} ms", this.Name, sw.ElapsedMilliseconds); #endif return(retVal); } catch (Exception e) { throw new CdssEvaluationException($"Error applying protocol {this.Definition.Id}", this.Definition, e); } }