Wednesday, October 10, 2012

Implementing a Rule Based System for First Aid Prescriptions

A rule based system for the calculation of medication to be used in an APLS (Acute Pediatric Life Support) setting follows can be nicely implemented using a functional approach.

F# is a relatively new .net family member is the .net version of a functional programming language. Functional programming languages are particularly suitable to solve data processing and decision support problems. So, I decided to give it a go.

First of all, the problem. As medication in children has to applied to a broad range of age and weight categories, different medication solutions have to be applied. For example, for midazolam we use the following solutions:


Weight Category Solution
< 5.0 kg 50 mg/ 50 mL
5.0 - 15 kg 100 mg/ 50 mL
15 - 23 kg 150 mg/ 50 mL
> 23 kg 200 mg/ 50 mL

In 'normal' C# this would require a lot of if then constructs. In F# the initial solution already looks nicer:

[<Measure>] type kg
[<Measure>] type mg

let selectMidazolamQuantity (weight: float<kg>) :float<mg> =
    match weight with
    | w when w < 0.0<kg> || w > 200.0<kg> -> failwith "Not a valid weight"
    | w when w < 5.0<kg> -> 50.0<mg>
    | w when w >= 5.0<kg> && w < 15.0<kg> -> 100.0<mg>
    | w when w >= 15.0<kg> && w < 23.0<kg> -> 150.0<mg>
    | w when w >= 23.0<kg> -> 200.0<mg>

let qty = selectMidazolamQuantity(23.0<kg>)
qty

In F# instead of if then constructs, pattern matching can be used. The correctness of the pattern is checked at compiler time. So, for example when the pattern is incomplete, this is immediately shown in the editor. Also, primitive values can be decorated with a measure attribute.

When the above code is send to F# interactive this will have the following result:


Script.fsx(40,11): warning FS0025: Incomplete pattern matches on this expression.
val selectMidazolamQuantity : float<kg> -> float<mg>
val qty : float<mg> = 200.0
This code can be further improved by matching against a list of categories:



let milrinoneRules = [| 
    (0.4<kg>, 5.0<kg>, 5.0<mg>); 
    (5.0<kg>, 10.0<kg>, 10.0<mg>);
    (10.0<kg>, 200.0<kg>, 15.0<mg>) 
    |]

let selectQuantity (weight: float<kg>, rules: (float<kg>*float<kg>*float<mg>)[]) : float<mg> =
    match weight with
    | w when w < 0.0<kg> || w > 200.0<kg> -> failwith "Not a valid weight"
    | w ->  
        let rule = Array.find(fun (lower, upper, _) -> w > lower && w <= upper) rules
        let _, _, quantity = rule
        printf "quantity is %s\n" (quantity.ToString())
        quantity

selectQuantity (12.0<kg>, milrinoneRules)

Next step is to annotate the rules set with the medication for wich it is used.

Monday, October 8, 2012

Setting up a SoapClient to use Windows Authentication

Setting up a soap client to use windows authentication is rather tricky as there many configuration options concerning ASP.NET security.

First of all make sure that IIS 7.0 is correctly configured to use Windows authentication instead of default anonymous user login. Therefore, the following has to be applied to the


This effectively forces IIS to use an authenticated windows user. If a user is already windows authenticated, the user does not need to log in. So, this setting is appropriate for use in intranet environments, not in intranet environments.

However, users do not interact with webservices, code interacts with webservices. To consume a web service a service reference has to be added to the project:


Adding a service reference to a project creates an app.config describing the binding of that service including the security settings. Default security settings only enable anonymous user to consume the code. If IIS is configured to use windows security this will result in a HTTP 401 error.

Therefore, the following section has to be modified:


                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
To:

                    <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>

Note: this section resides in the:

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>

After adjusting the security section the code when run using an authorized windows user should work. But for an application with a web based user interface this is not required! The user will be prompted to log in, if required. So then the code is run with the authenticated user and the webservices can be consumed. I use the above to enable test code to run.


Wednesday, September 5, 2012

How complex can a fluid balance be?

In critical patient care we want to monitor the patient's fluid balance. The fluid balance is an important aspect in assessing a patient and to treat a patient. But what is a fluid balance exactly? Simply put fluid balance can be summarized by the following formula:

balance = fluid in - fluid out

When fluid balance is positive, this means the patient is accumulating fluid, when the fluid balance is negative, the patient is losing fluid. However, this simple notion is complicated by the following factors:

1. What is the time frame of the balance?
There are different possibilities:
  • Balance from start of the day until current time 
  • Balance from 24 hours ago until current time 
  • Balance from date time of admission 
  • -Balance between from date time and to date time 
So, in general a fluid balance always refers to a time frame.

2. Insensible loss
Normally, when a fluid balance is calculated this will yield a positive estimate. This is due to the fact that the human body loses fluid through transpiration and by breathing. This undetected loss is called: insensible loss.

An estimation of insensible loss is:
500 mL/m2/day

Fever increases insensible water losses by
10% per degree Celsius above 38°, or 100-150 mL/day increase per degree Celsius above 37°.

3. Fluid balance has to be related to patient size
What does it mean if the fluid balance is, say +300 mL? If this is an adult patient, this is less than the estimated 500-1000 mL insensible loss per day, so this patient loses fluid. However, in a neonate of with a body weight of 3 kg, this means that this patients accumulates 100 mL/kg/day!

So, size matters. the fluid balance has to be related to body size. Body weight is the most convenient adjustment measure.

4. What goes in and what goes out?
To further analyze a fluid balance it is important to know the amount of what goes in (intake) and what goes out (particularly urine output).

Intake can be categorized as:
  • enteral
  • intravenous
  • dialysis
Fluids can be further categorized as:
  • crystalloids
  • colloid
 Likewise, what goes out can be through:
  • insensible loss
  • urine
  • stool
  • gastric
  • blood loss
  • dialysis
So, in the end the fluid balance is a more complex concept which can be summarized by the folowing formula:




In which there are
  • i to j intake parameters, 
  • and k to l output parameters
  • to is the end date time of the interval and from is the start of the interval, so
  • the interval = to - from, i.e. the time difference between from and to
  • BSA is the body surface area
  • and temp is the body temperature with a minimum of 37
This formula still simplifies the insensible loss by assuming a constant temperature during the interval.

Saturday, January 21, 2012

StructureMap DI Constructor Injection

I spent some considerable time figuring out how the h*** I did this:
public class Repository: NHibernateRepository
{
        public Repository(ISessionFactory factory): base(fact)


        // Etc….
}
public class SomeOtherClass

{
        public IRepository GetRepository()
        {
                return ObjectFactory.GetInstance<IRepository>();
        }
}
The repository class was dependent on a SessionFactory, so in the constructor of that class this was injected. This enables testing code like:
[TestMethod]
public void TestTheRepository()
{
        var repos = new Repository(CreateSomeTestFactory());
        // perform the tests
}
However, in the production code I could not find a single line that did the same as in the above test code. So, how did StructureMap create the Repository class, i.e. how did it inject the required factory??

Turned out that I had written the following sort of code:
public void DoSomeThingWithRepository()
{
        // First tell StructureMap what factory to use
        ObjectFactory.Configure(x => x.For<ISessionFactory>().Use(new ProductionFactory());
        // Now I can let StructureMap get the repository, and have it constructed with the factory I just configured
        var repos = ObjectFactory.GetInstance<IRepository>();
}
That means that the following should be regarded as an anti-pattern:
public class Repository
{
        public Repository()
        {
                base.SetFactory(ObjectFactory.GetInstance<ISessionFactory>());
        }
}
Besides the ugliness of the code, it creates an unnecessary dependance on StructureMap. In general, classes that rely on other classes should be constructed with those classes. Preferably, interfaces of those classes so the constructed class can remain blissfully unaware about the implementation details of the classes it depends on.

See also blog by Jeremy Miller: IOC antipattern