Skip to content

Commit 6bbe8f4

Browse files
2 parents 46ec6e6 + b17d1cc commit 6bbe8f4

28 files changed

+4131
-26
lines changed

OmopTransformer/ConceptResolver.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ and cr.relationship_id like '%device%'
7272

7373
private void EnsureMapping()
7474
{
75+
if (_mappings != null)
76+
return;
7577

7678
lock (_loadingLock)
7779
{

OmopTransformer/LabTestLookup.cs

Lines changed: 1861 additions & 0 deletions
Large diffs are not rendered by default.

OmopTransformer/OmopTransformer.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,9 @@
257257
<None Update="OxfordPrescribing\DrugExposure\OxfordPrescribingDrugExposure.xml">
258258
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
259259
</None>
260+
<None Update="OxfordLab\Measurements\OxfordLabMeasurement.xml">
261+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
262+
</None>
260263
<None Update="OxfordSpineDeath\Death\OxfordSpineDeath.xml">
261264
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
262265
</None>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using OmopTransformer.Annotations;
2+
using OmopTransformer.Omop.Measurement;
3+
using OmopTransformer.Transformation;
4+
5+
namespace OmopTransformer.OxfordLab.Measurements.OxfordLabMeasurement;
6+
7+
internal class OxfordLabMeasurement : OmopMeasurement<OxfordLabMeasurementRecord>
8+
{
9+
[CopyValue(nameof(Source.NHS_NUMBER))]
10+
public override string? nhs_number { get; set; }
11+
12+
[Transform(typeof(DateConverter), nameof(Source.EVENT_START_DT_TM))]
13+
public override DateTime? measurement_date { get; set; }
14+
15+
[Transform(typeof(DateConverter), nameof(Source.EVENT_START_DT_TM))]
16+
public override DateTime? measurement_datetime { get; set; }
17+
18+
[ConstantValue(32828, "EHR episode record")]
19+
public override int? measurement_type_concept_id { get; set; }
20+
21+
[Transform(typeof(LabTestLookup), nameof(Source.@EVENT))]
22+
public override int? measurement_source_concept_id { get; set; }
23+
24+
[CopyValue(nameof(Source.@EVENT))]
25+
public override string? measurement_source_value { get; set; }
26+
27+
[Transform(typeof(StandardMeasurementConceptSelector), useOmopTypeAsSource: true, nameof(measurement_source_concept_id))]
28+
public override int[]? measurement_concept_id { get; set; }
29+
30+
[Transform(typeof(DoubleParser), nameof(Source.NORMAL_LOW))]
31+
public override double? range_low { get; set; }
32+
33+
[Transform(typeof(DoubleParser), nameof(Source.NORMAL_HIGH))]
34+
public override double? range_high { get; set; }
35+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<Query>
2+
<Sql type="duckdb">
3+
select
4+
NHS_NUMBER,
5+
EVENT,
6+
EVENT_START_DT_TM,
7+
RESULT_VALUE,
8+
RESULT_UNITS,
9+
NORMAL_LOW,
10+
NORMAL_HIGH
11+
from ##duckdb_source##
12+
</Sql>
13+
<Explanations>
14+
<Explanation columnName="NHS_NUMBER">
15+
<Description>Patient NHS Number</Description>
16+
<Origin>NHS NUMBER</Origin>
17+
</Explanation>
18+
<Explanation columnName="EVENT">
19+
<Description>Lab test event</Description>
20+
<Origin></Origin>
21+
</Explanation>
22+
<Explanation columnName="EVENT_START_DT_TM">
23+
<Description>Lab test event start datetime</Description>
24+
<Origin></Origin>
25+
</Explanation>
26+
<Explanation columnName="RESULT_VALUE">
27+
<Description>Lab test event result</Description>
28+
<Origin></Origin>
29+
</Explanation>
30+
<Explanation columnName="RESULT_UNITS">
31+
<Description>Patient NHS Number</Description>
32+
<Origin>NHS NUMBER</Origin>
33+
</Explanation>
34+
<Explanation columnName="NORMAL_LOW">
35+
<Description>Lab test normal range (low)</Description>
36+
<Origin></Origin>
37+
</Explanation>
38+
<Explanation columnName="NORMAL_HIGH">
39+
<Description>Lab test normal range (high)</Description>
40+
<Origin></Origin>
41+
</Explanation>
42+
</Explanations>
43+
</Query>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using OmopTransformer.Annotations;
2+
3+
namespace OmopTransformer.OxfordLab.Measurements.OxfordLabMeasurement;
4+
5+
[DataOrigin("OxfordLab")]
6+
[Description("Oxford Lab Measurement")]
7+
[SourceQuery("OxfordLabMeasurement.xml")]
8+
internal class OxfordLabMeasurementRecord
9+
{
10+
public string? NHS_NUMBER { get; set; }
11+
public string? @EVENT { get; set; }
12+
public string? EVENT_START_DT_TM { get; set; }
13+
public string? RESULT_VALUE { get; set; }
14+
public string? RESULT_UNITS { get; set; }
15+
public string? NORMAL_LOW { get; set; }
16+
public string? NORMAL_HIGH { get; set; }
17+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Microsoft.Extensions.Hosting;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace OmopTransformer.OxfordLab;
5+
6+
internal class OxfordLabTransformHostedService : FinalHostedService
7+
{
8+
private readonly OxfordLabTransformer _transformer;
9+
10+
public OxfordLabTransformHostedService(IHostApplicationLifetime appLifetime, ILogger<FinalHostedService> logger, OxfordLabTransformer transformer) : base(appLifetime, logger)
11+
{
12+
_transformer = transformer;
13+
}
14+
15+
protected override async Task RunTask(CancellationToken cancellationToken)
16+
{
17+
await _transformer.Transform(cancellationToken);
18+
}
19+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using Microsoft.Extensions.Logging;
2+
using OmopTransformer.Omop;
3+
using OmopTransformer.OxfordLab.Measurements.OxfordLabMeasurement;
4+
using OmopTransformer.Transformation;
5+
using OmopTransformer.Omop.Measurement;
6+
7+
namespace OmopTransformer.OxfordLab;
8+
9+
internal class OxfordLabTransformer : Transformer
10+
{
11+
private readonly ConceptResolver _conceptResolver;
12+
private readonly IMeasurementRecorder _measurementRecorder;
13+
14+
public OxfordLabTransformer(
15+
IRecordTransformer recordTransformer,
16+
TransformOptions transformOptions,
17+
IRecordProvider recordProvider,
18+
IMeasurementRecorder measurementRecorder,
19+
ConceptResolver conceptResolver,
20+
IRunAnalysisRecorder runAnalysisRecorder,
21+
ILoggerFactory loggerFactory) : base(recordTransformer,
22+
transformOptions,
23+
recordProvider,
24+
"Oxford-Lab",
25+
runAnalysisRecorder,
26+
loggerFactory)
27+
{
28+
_measurementRecorder = measurementRecorder;
29+
_conceptResolver = conceptResolver;
30+
}
31+
32+
public async Task Transform(CancellationToken cancellationToken)
33+
{
34+
Guid runId = Guid.NewGuid();
35+
36+
await Transform<OxfordLabMeasurementRecord, OxfordLabMeasurement>(
37+
_measurementRecorder.InsertUpdateMeasurements,
38+
"Oxford Lab Measurements",
39+
runId,
40+
cancellationToken);
41+
42+
_conceptResolver.PrintErrors();
43+
}
44+
}

OmopTransformer/Program.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
using OmopTransformer.OxfordGP.Staging.Clearing;
4646
using OmopTransformer.OxfordPrescribing;
4747
using OmopTransformer.OxfordSpineDeath;
48+
using OmopTransformer.OxfordLab;
4849

4950
[assembly: InternalsVisibleTo("OmopTransformerTests")]
5051
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
@@ -324,6 +325,11 @@ private static async Task Main(string[] args)
324325
builder.Services.AddTransient<OxfordPrescribingTransformer>();
325326
builder.Services.AddHostedService<OxfordPrescribingTransformHostedService>();
326327
}
328+
else if (string.Equals(transformOptions.Type, "oxford-lab", StringComparison.OrdinalIgnoreCase))
329+
{
330+
builder.Services.AddTransient<OxfordLabTransformer>();
331+
builder.Services.AddHostedService<OxfordLabTransformHostedService>();
332+
}
327333
else if (string.Equals(transformOptions.Type, "oxford-death", StringComparison.OrdinalIgnoreCase))
328334
{
329335
builder.Services.AddTransient<OxfordSpineDeathTransformer>();
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using OmopTransformer.Annotations;
2+
3+
namespace OmopTransformer.Transformation;
4+
5+
internal class Attribute
6+
{
7+
private Attribute(object value, ILookup? lookup)
8+
{
9+
Value = value;
10+
Lookup = lookup;
11+
}
12+
13+
public static Attribute Create(object value)
14+
{
15+
ILookup lookup = null;
16+
17+
if (value is TransformAttribute transformAttribute && typeof(ILookup).IsAssignableFrom(transformAttribute.Type))
18+
{
19+
lookup = (ILookup)Activator.CreateInstance(transformAttribute.Type)!;
20+
}
21+
22+
return new Attribute(value, lookup);
23+
}
24+
25+
public object Value { get; }
26+
27+
public ILookup? Lookup { get; }
28+
}

0 commit comments

Comments
 (0)