Created
March 17, 2021 08:45
-
-
Save halcwb/49624106b8e5f702f7e051d10d9ea261 to your computer and use it in GitHub Desktop.
OncoSepsis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#r "nuget: SqlProvider" | |
#r "nuget: FSharp.Stats" | |
#r "nuget: Plotly.NET, 2.0.0-beta5" | |
#r "nuget: Informedica.Utils.Lib" | |
open System | |
open System.Text | |
open FSharp.Data.Sql | |
open FSharp.Stats | |
open Plotly.NET | |
open Informedica.Utils.Lib | |
Environment.CurrentDirectory <- __SOURCE_DIRECTORY__ | |
fsi.AddPrinter<DateTime> (fun dt -> dt.ToString("dd-MM-yyyy HH:mm")) | |
module StringBuilder = | |
let builder (s : string) = StringBuilder(s) | |
let append (s : string) (sb : StringBuilder) = sb.Append(s) | |
let appendLine (s : string) (sb : StringBuilder) = sb.AppendLine(s) | |
let newLine = appendLine "" | |
let newLine2 sb = | |
sb | |
|> appendLine "" | |
|> appendLine "" | |
let appendFormat (fs : string) vs (sb : StringBuilder) = sb.AppendFormat(fs, (vs |> List.toArray)) | |
let appendLineFormat (fs : string) vs (sb : StringBuilder) = sb.AppendFormat(fs + "\n", (vs |> List.toArray)) | |
let replace (s1 : string) s2 (sb : StringBuilder) = sb.Replace(s1, s2) | |
let toString (sb : StringBuilder) = sb.ToString() | |
module File = | |
open System | |
open System.IO | |
let appendTextToFile path (s : string) = | |
File.AppendAllText(path, s) | |
[<Literal>] | |
let resolutionPath = __SOURCE_DIRECTORY__ + "\libs" | |
[<Literal>] | |
let connString = @"Data Source=VOXDB-PICURED01;Initial Catalog=PICURED;Persist Security Info=True;Integrated Security=SSPI;Connection Timeout=0;Command Timeout=0;" | |
[<Literal>] | |
let schemaPath = __SOURCE_DIRECTORY__ + "\schema\picured.schema" | |
type NumericalData = | |
{ | |
Name : string | |
Label : string | |
Values : (DateTime * float) [] | |
} | |
type Patient = | |
{ | |
HospNum : string | |
BirthDate : DateTime | |
Gender : string | |
Weight : float option | |
AdmNo : int | |
AdmTime : DateTime | |
DisTime : DateTime | |
EndTime : DateTime | |
Data : NumericalData [] | |
Sepsis : bool | |
Specialism : string | |
Diagnoses : string [] | |
PIM2 : float option | |
PIM3 : float option | |
PRISMIV : float option | |
Outcome : string | |
} | |
let addPatientData (pat: Patient) label name values = | |
{ pat with | |
Data = | |
[| | |
{ | |
Name = name | |
Label = label | |
Values = values | |
} | |
|] | |
|> Array.append pat.Data | |
} | |
type sql = SqlDataProvider<Common.DatabaseProviderTypes.MSSQLSERVER_DYNAMIC, | |
connString, | |
ResolutionPath = resolutionPath, | |
UseOptionTypes = true, | |
ContextSchemaPath = schemaPath, | |
CaseSensitivityChange = Common.CaseSensitivityChange.ORIGINAL> | |
let getPatientHospAdmissions (ctx: sql.dataContext) = | |
query { | |
for r in ctx.Dbo.DataOncoSepsis do | |
where (r.PatAdmNo.IsSome && r.PatBirthdate.IsSome) | |
distinct | |
select ( | |
{| | |
hospnum = r.PatHospId | |
birthDate = r.PatBirthdate.Value | |
gender = r.PatSex | |
weight = r.PatAdmWeight | |
admno = r.PatAdmNo.Value | |
pim2 = r.PatAdmPim2 | |
pim3 = r.PatAdmPim3 | |
prismIV = r.PatAdmPrismIv | |
outcome = r.PatAdmOutcome |> Option.defaultValue "" | |
|} | |
) | |
} | |
|> Seq.toArray | |
|> Array.sortBy (fun x -> x.hospnum, x.admno) | |
let calcGCS (e : string option) (m: string option) (v: string option) = | |
let toInt d (s : string option) = | |
match s with | |
| None -> d | |
| Some s -> | |
s.Split('-') | |
|> Array.toList | |
|> function | |
| h::_ -> | |
h | |
|> Int32.TryParse | |
|> function | |
| true, i -> i | |
| false, _ -> 0 | |
| _ -> d | |
let e = e |> toInt 5 | |
let m = m |> toInt 6 | |
let v = v |> toInt 4 | |
e + m + v | |
let mapPatients (ctx: sql.dataContext) (pats : {| hospnum : string; | |
birthDate : DateTime; | |
gender : string option; | |
weight : float option; | |
admno : int | |
pim2 : float option | |
pim3 : float option | |
prismIV : float option | |
outcome : string |} []) = | |
pats | |
|> Array.sortBy (fun r -> r.hospnum, r.admno) | |
|> Array.map (fun r -> | |
let admTime = | |
query { | |
for x in ctx.Dbo.DataOncoSepsis do | |
where (x.PatHospId = r.hospnum && x.PatAdmNo.Value = r.admno) | |
sortBy x.PatDatetime | |
take 1 | |
select x.PatDatetime | |
} | |
|> Seq.tryHead | |
let disTime = | |
query { | |
for x in ctx.Dbo.DataOncoSepsis do | |
where (x.PatHospId = r.hospnum && x.PatAdmNo.Value = r.admno) | |
sortByDescending x.PatDatetime | |
take 1 | |
select x.PatDatetime | |
} | |
|> Seq.tryHead | |
let endTime = admTime |> Option.map (fun dt -> dt.AddHours(24.)) | |
{| | |
hospnum = r.hospnum | |
birthDate = r.birthDate | |
gender = r.gender |> Option.defaultValue "" | |
weight = r.weight | |
admno = r.admno | |
admTime = admTime | |
disTime = disTime | |
endTime = endTime | |
pim2 = r.pim2 | |
pim3 = r.pim3 | |
prismIV = r.prismIV | |
outcome = r.outcome | |
|} | |
) | |
|> Array.filter (fun x -> x.admTime.IsSome && x.disTime.IsSome) | |
|> Array.map (fun x -> | |
{ | |
HospNum = x.hospnum | |
BirthDate = x.birthDate | |
Gender = x.gender | |
Weight = x.weight | |
AdmNo = x.admno | |
AdmTime = x.admTime.Value | |
DisTime = x.disTime.Value | |
EndTime = x.endTime.Value | |
Data = [||] | |
Sepsis = false | |
Specialism = "" | |
Diagnoses = [||] | |
PIM2 = x.pim2 | |
PIM3 = x.pim3 | |
PRISMIV = x.prismIV | |
Outcome = x.outcome | |
} | |
|> fun p -> | |
p, | |
query { | |
for d in ctx.Dbo.DataOncoSepsis do | |
where ( | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select d | |
} | |
|> Seq.toArray | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonIbpSys.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonIbpSys.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Systolic invasive blood pressure" "sbp", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonIbpDia.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonIbpDia.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Diastolic invasive blood pressure" "dbp", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonIbpMean.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonIbpMean.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Mean invasive blood pressure" "mbp", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonNibpSys.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonNibpSys.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Systolic non-invasive blood pressure" "nibps", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonNibpDia.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonNibpDia.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Diastolic non-invasive blood pressure" "nibpd", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonNibpMean.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonNibpMean.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Mean non-invasive blood pressure" "nibpm", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonRr.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonRr.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Respiratory rate" "rr", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonCvp.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonCvp.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Central venuous pressure" "cvp", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBgPo2.IsSome && d.MonIbpMean.IsSome && // arterial bg if invasive bp | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBgPo2.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Arterial pO2" "pO2", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBgSat.IsSome && d.MonIbpMean.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBgSat.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Arterial bloodgas oxygen saturation" "bgsat", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBgPo2.IsSome && d.LabBgPo2.Value <> 0. && d.MonIbpMean.IsSome && | |
d.VentSetFiO2.IsSome && d.VentSetFiO2.Value <> 0. && | |
d.VentMMean.IsSome && d.VentMMean.Value <> 0. && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.VentSetFiO2.Value * d.VentMMean.Value / d.LabBgPo2.Value ) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Oxygenation Index" "oi", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.VentSetFiO2.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.VentSetFiO2.Value / 100.) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Ventilator FiO2 setting" "fio2", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.VentMMean.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.VentMMean.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Ventilator mean airway pressure" "map", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonSat.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonSat.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Monitor oxygen saturation" "sat", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.MonTemp.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.MonTemp.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Temperature" "temp", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.ObsFbUrine.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.ObsFbUrine.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Urine output" "urine", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.ObsGcsE, d.ObsGcsM, d.ObsGcsV) | |
} | |
|> Seq.toArray | |
|> Array.map (fun (dt, e, m, v) -> dt, calcGCS e m v |> float) | |
|> addPatientData p "Glascow coma score" "gcs", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlLactate.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlLactate.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Lactate" "lact", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlGluc.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlGluc.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Glucose" "gluc", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlNa.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlNa.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Sodium" "na", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlCl.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlCl.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Chloride" "cl", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBgHco3.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBgHco3.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Bicarbonate" "bic", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlCr.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlCr.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Creatinine" "creat", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlUr.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlUr.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Urea" "urea", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlLeuco.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlLeuco.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Leucocyte count" "leuco", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlNeutro.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlNeutro.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Neutrophil count" "neutro", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlHb.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlHb.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Hemoglobin" "hb", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlTr.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlTr.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Platelets" "trombo", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlAlat.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlAlat.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Alanine aminotransferase" "alat", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlAsat.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlAsat.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Aspartate aminotransferase" "asat", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlGgt.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlGgt.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Gamma-glutamyl transferase" "ggt", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlAlp.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlAlp.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Alkaline phosphatase" "alp", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlLdh.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlLdh.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "LDH" "ldh", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlBilI.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlBilI.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Bilirubin" "bili", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlAlb.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlAlb.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Albumin" "alb", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlTg.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlTg.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Triglyceride" "tg", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlFibrinogen.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlFibrinogen.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Fibrinogen" "fibr", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlInr.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlInr.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "INR" "inr", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlPt.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlPt.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Prothrombin time" "pt", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlCrp.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlCrp.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "C Reactive Protein" "crp", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlFerritin.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlFerritin.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Ferritine" "ferri", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlIl2.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlIl2.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Soluble IL-2 receptor" "sIL2", data | |
|> fun (p, data) -> | |
query { | |
for d in data do | |
where ( | |
d.LabBlTropo.IsSome && | |
d.PatHospId = x.hospnum && | |
d.PatDatetime >= x.admTime.Value && | |
d.PatDatetime <= x.endTime.Value | |
) | |
select (d.PatDatetime, d.LabBlTropo.Value) | |
} | |
|> Seq.toArray | |
|> addPatientData p "Troponine" "tropo" | |
) | |
let getData (ctx: sql.dataContext) = | |
ctx | |
|> getPatientHospAdmissions | |
|> fun pats -> | |
let noPats = pats |> Array.map (fun p -> p.hospnum) |> Array.distinct |> Array.length | |
let noAdms = pats |> Array.length | |
printfn "No of patients: %i\nNo of admissions: %i" noPats noAdms | |
pats | |
let smoothData ns (pat: Patient) = | |
let window = 31 | |
pat.Data | |
|> Array.filter (fun d -> ns |> Seq.exists ((=) d.Name)) | |
|> fun xs -> | |
{ | |
pat with | |
Data = | |
xs | |
|> Array.map (fun nd -> | |
{ | |
Name = nd.Name + "_sm" | |
Label = nd.Label + " smoothed" | |
Values = | |
let dts = nd.Values |> Array.map fst | |
let vs = | |
nd.Values | |
|> Array.map snd | |
|> fun xs -> | |
if xs |> Seq.length < window then xs | |
else | |
xs | |
|> Signal.Filtering.savitzkyGolay window 1 0 1 | |
Array.zip dts vs | |
} | |
) | |
|> Array.append pat.Data | |
} | |
let calcStats (xs : float seq) = | |
let xs = xs |> Seq.filter ((<>) 0.) | |
if xs |> Seq.isEmpty then None | |
else | |
{| | |
mean = xs |> Seq.mean | |
median = xs |> Seq.median | |
min = xs |> Seq.min | |
max = xs |> Seq.max | |
sd = xs |> Seq.stDev | |
|} | |
|> Some | |
let statsToStr n (stats: {| max: float; mean: float; median: float; min: float; sd: float |} option) = | |
match stats with | |
| None -> sprintf "%40s\tno data" n | |
| Some stats -> | |
sprintf "%40s\tmean: %8.2f\tmedian: %8.2f\tmin: %8.2f\tmax %8.2f" | |
n | |
stats.mean | |
stats.median | |
stats.min | |
stats.max | |
let report (pat : Patient) = | |
let wght = | |
if pat.Weight.IsSome then sprintf "%.1f" pat.Weight.Value | |
else "" | |
let dtToStr (dt: DateTime) = dt.ToString("dd-MM-yyyy HH:mm") | |
let start, stop = | |
pat.AdmTime |> dtToStr, | |
pat.DisTime |> dtToStr | |
let age = (pat.AdmTime - pat.BirthDate).TotalDays / 365. | |
StringBuilder.builder (sprintf "=== Patient: %s, admission: %i %s - %s" pat.HospNum pat.AdmNo start stop) | |
|> StringBuilder.appendLine "=== Demographics:" | |
|> StringBuilder.appendLine (sprintf "Age at PICU admission(years) : %.1f" age) | |
|> StringBuilder.appendLine (sprintf "Gender: %s" pat.Gender) | |
|> StringBuilder.appendLine (sprintf "Gewicht: %s" wght) | |
|> StringBuilder.appendLine "=== Data:" | |
|> fun sb -> | |
pat.Data | |
|> Array.sortBy (fun d -> d.Label) | |
|> Array.fold (fun sb d -> | |
let stats = | |
d.Values | |
|> Seq.map snd | |
|> calcStats | |
sb | |
|> StringBuilder.appendLine (stats |> statsToStr (d.Label.Trim())) | |
) sb | |
|> StringBuilder.appendLine (sprintf "Sepsis: %s" (if pat.Sepsis then "Ja" else "Nee" )) | |
|> StringBuilder.appendLine (sprintf "Diagnoses: %s" (pat.Diagnoses |> String.concat ", ")) | |
|> StringBuilder.appendLine (sprintf "Outcome: %s" pat.Outcome) | |
|> StringBuilder.appendLine "" | |
|> StringBuilder.appendLine "" | |
|> StringBuilder.toString | |
let createCSV (pats : Patient[]) = | |
let wght pat = | |
if pat.Weight.IsSome then sprintf "%.1f" pat.Weight.Value | |
else "" | |
let dtToStr (dt: DateTime) = dt.ToString("dd-MM-yyyy HH:mm") | |
let age pat = (pat.AdmTime - pat.BirthDate).TotalDays / 365. | |
let headers = | |
pats | |
|> Array.head | |
|> fun pat -> | |
pat.Data | |
|> Array.collect (fun nd -> | |
[| | |
nd.Name + "_mean" | |
nd.Name + "_median" | |
nd.Name + "_min" | |
nd.Name + "_max" | |
|] | |
) | |
|> Array.append [| | |
"hospNum" | |
"admNo" | |
"start" | |
"stop" | |
"age" | |
"gender" | |
"weight" | |
"sepsis" | |
"diagns" | |
"outcome" | |
"pim2" | |
"pim3" | |
"prismIV" | |
|] | |
[| | |
headers | |
for pat in pats do | |
let stats = | |
pat.Data | |
|> Array.map (fun nd -> nd.Values |> Array.map snd |> calcStats) | |
|> Array.collect (fun st -> | |
match st with | |
| None -> [|""; ""; ""; ""|] | |
| Some nd -> | |
[| | |
nd.mean |> sprintf "%A" | |
nd.median |> sprintf "%A" | |
nd.min |> sprintf "%A" | |
nd.max |> sprintf "%A" | |
|] | |
) | |
stats | |
|> Array.append [| | |
pat.HospNum | |
pat.AdmNo |> string | |
pat.AdmTime |> dtToStr | |
pat.DisTime |> dtToStr | |
pat |> age |> sprintf "%A" | |
pat.Gender | |
pat |> wght | |
pat.Sepsis |> sprintf "%A" | |
pat.Diagnoses |> String.concat ";" | |
pat.Outcome | |
pat.PIM2 |> Option.map (sprintf "%A") |> Option.defaultValue "" | |
pat.PIM3 |> Option.map (sprintf "%A") |> Option.defaultValue "" | |
pat.PRISMIV |> Option.map (sprintf "%A") |> Option.defaultValue "" | |
|] | |
|] | |
[<Literal>] | |
let connString2 = @"Data Source=VOXDB-PICURED01;Initial Catalog=PICE_MRDM;Persist Security Info=True;Integrated Security=SSPI;Connection Timeout=0;Command Timeout=0;" | |
[<Literal>] | |
let schemaPath2 = __SOURCE_DIRECTORY__ + "\schema\pice.schema" | |
type sql2 = SqlDataProvider<Common.DatabaseProviderTypes.MSSQLSERVER_DYNAMIC, | |
connString2, | |
ResolutionPath = resolutionPath, | |
UseOptionTypes = true, | |
ContextSchemaPath = schemaPath2, | |
CaseSensitivityChange = Common.CaseSensitivityChange.ORIGINAL> | |
let addPICEData (pat: Patient) = | |
let ctx = sql2.GetDataContext(SelectOperations.DatabaseSide) | |
query { | |
for pd in ctx.Dbo.PimPrism2103111003 do | |
where ( | |
pd.HospitalNumber.Trim() = pat.HospNum.Trim() && | |
pat.AdmTime >= pd.AdmissionDate.AddDays(-1.) && | |
pat.AdmTime <= pd.AdmissionDate.AddDays(1.) | |
) | |
select pd | |
} | |
|> Seq.toList | |
|> function | |
| h::[] -> | |
{ | |
pat with | |
Sepsis = | |
h.Sepsis | |
|> Option.map (fun s -> if s = "True" then true else false) | |
|> Option.defaultValue false | |
Specialism = h.Specialism |> Option.defaultValue "" | |
Diagnoses = | |
[| | |
h.Diagnosis1 |> Option.defaultValue "" | |
h.Diagnosis2 |> Option.defaultValue "" | |
h.DiagnosesOther |> Option.defaultValue "" | |
|] | |
|> Array.filter (String.IsNullOrWhiteSpace >> not) | |
|> Array.distinct | |
Outcome = h.Status |> Option.defaultValue "" | |
} | |
| _ -> pat | |
let processPatients n = | |
let smd = | |
[ | |
"sbp" | |
"dbp" | |
"mbp" | |
"cvp" | |
"sat" | |
] | |
let ctx = sql.GetDataContext(SelectOperations.DatabaseSide) | |
ctx | |
|> getData | |
|> fun d -> | |
if n = 0 then d | |
else | |
d |> Array.take n | |
|> fun d -> | |
printfn "going to map %i admissions" (d |> Seq.length) | |
d | |
|> Array.collect (fun d -> | |
printfn "now mapping %s, admission %i" d.hospnum d.admno | |
[| d |] | |
|> mapPatients ctx | |
|> Array.map ((smoothData smd) >> (addPICEData)) | |
) | |
let saveReports n = | |
processPatients n | |
|> Array.iter (report >> (sprintf "%s") >> (File.appendTextToFile "./download/patients.txt")) | |
let saveCSV n = | |
processPatients n | |
|> createCSV | |
|> Array.map (String.concat "\t") | |
|> String.concat "\n" | |
|> File.writeTextToFile "./download/patients.csv" | |
let getSinglePatient n = | |
processPatients n | |
|> Array.item (n - 1) | |
let plotPatient pat = | |
do | |
let mbp = | |
pat.Data | |
|> Array.find (fun d -> d.Name = "mbp") | |
let xs = | |
mbp.Values | |
|> Array.map fst | |
let ys = | |
mbp.Values | |
|> Array.map snd | |
let ys_sm = | |
pat.Data | |
|> Array.find (fun d -> d.Name = "mbp_sm") | |
|> fun x -> x.Values |> Array.map snd | |
[ | |
Chart.Point(xs, ys, Name="raw") | |
Chart.Line(xs, ys_sm, Name="smoothed") | |
] | |
|> Chart.Combine | |
|> Chart.withTitle ("Mean Invasive Blood Pressure") | |
|> Chart.withSize (1000., 800.) | |
|> Chart.Show | |
// |> Chart.SaveHtmlAs "smoothed" | |
let xs = ["1"; 1 ] | |
let pat = getSinglePatient "a" | |
plotPatient pat |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment