Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
bdb238d
Map unknown concepts to 0 rather than null. When mapping from known c…
james-cockayne Nov 4, 2025
26c7b73
Initial plan
Copilot Nov 4, 2025
d90282c
Fix syntax
james-cockayne Nov 4, 2025
3fabb9b
Initial plan
Copilot Nov 4, 2025
b7f9794
Merge pull request #281 from answerdigital/copilot/sub-pr-279-again
james-cockayne Nov 4, 2025
b1954c9
Merge pull request #280 from answerdigital/copilot/sub-pr-279
james-cockayne Nov 4, 2025
fd25997
Fix syntax
james-cockayne Nov 4, 2025
b824f68
Merge branch 'feature/map_to_unknown_concept' of https://github.com/a…
james-cockayne Nov 4, 2025
037d73b
Extend concept zero recording to Drug and Device exposure.
james-cockayne Nov 5, 2025
42bfc5b
Added missing parentheses
james-cockayne Nov 7, 2025
95a598c
Track the eventual domain of a source concept when it is mapped to a …
james-cockayne Nov 10, 2025
a585597
Added Measurement source value to SUS APC/OP
khayamAmin Nov 16, 2025
c18fcda
Updated concept resolution logic to accomodate concept zero more grac…
james-cockayne Dec 2, 2025
7e5fb3b
Merge branch 'feature/map_to_unknown_concept' of https://github.com/a…
james-cockayne Dec 2, 2025
52a203e
Rebuild documentation
james-cockayne Dec 2, 2025
d964ab4
Merge remote-tracking branch 'origin/main' into feature/map_to_unknow…
james-cockayne Dec 3, 2025
a9348d1
Merge remote-tracking branch 'origin/main' into feature/map_to_unknow…
james-cockayne Dec 4, 2025
0f10a6f
Fix bug where concept domain logging was disabled.
james-cockayne Dec 4, 2025
4e0642a
Merge main into feature branch
james-cockayne Dec 10, 2025
d8df297
Merge main into fetaure branch.
james-cockayne Dec 10, 2025
3e017af
Fix build
james-cockayne Dec 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<Query>
<Sql>
-- fail
with cosddates as (
select
Record ->> '$.LinkagePatientId.NhsNumber.@extension' as NhsNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ select
ProcedureOpcsCode
from co
where co.ProcedureOpcsCode is not null;
-- fail
</Sql>
</Sql>
<Explanations>
<Explanation columnName="NhsNumber">
<Description>Patient NHS Number</Description>
Expand Down
2 changes: 1 addition & 1 deletion OmopTransformer/ConceptDeviceSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
namespace OmopTransformer;

[Description("Finds related devices for a concept.")]
internal class ConceptDeviceSelector(int? conceptId, ConceptResolver resolver) : ISelector
internal class ConceptDeviceSelector(int? conceptId, StandardConceptResolver resolver) : ISelector
{
public object? GetValue()
{
Expand Down
15 changes: 10 additions & 5 deletions OmopTransformer/ConceptLookup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,21 @@ private Dictionary<string, int> GetCodes()

public virtual string FormatCode(string code) => code;

public int? GetConceptCode(string? code)
public int GetConceptCode(string? code)
{
lock (_loadingLock)
const int unknownConceptId = 0;

if (_mappings == null)
{
_mappings ??= GetCodes();
lock (_loadingLock)
{
_mappings ??= GetCodes();
}
}

if (code == null)
{
return null;
return unknownConceptId;
}

var formatCode = FormatCode(code);
Expand All @@ -70,7 +75,7 @@ private Dictionary<string, int> GetCodes()
}
}

return null;
return unknownConceptId;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ where r.RecordConnectionIdentifier is not null
and co.person_id = p.person_id
and co.RecordConnectionIdentifier = r.RecordConnectionIdentifier
and co.condition_concept_id = r.condition_concept_id
and (co.condition_concept_id != 0 or co.condition_source_value = r.condition_source_value)
)
and not exists (
select 1
Expand All @@ -130,6 +131,7 @@ where r.RecordConnectionIdentifier is null
and co.condition_concept_id = r.condition_concept_id
and co.condition_start_date = r.condition_start_date
and co.person_id = p.person_id
and (co.condition_concept_id != 0 or co.condition_source_value = r.condition_source_value)
);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ from cdm.device_exposure vo
and vo.device_concept_id = r.device_concept_id
and vo.device_exposure_start_date = r.device_exposure_start_date
and vo.device_exposure_end_date = r.device_exposure_end_date
and (vo.device_concept_id != 0 or ((vo.device_source_value is null and r.device_source_value is null) or vo.device_source_value = r.device_source_value))
)
);

Expand Down
2 changes: 2 additions & 0 deletions OmopTransformer/Omop/DrugExposure/DrugExposureRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ from cdm.drug_exposure vo
where vo.RecordConnectionIdentifier = r.RecordConnectionIdentifier
and vo.person_id = p.person_id
and vo.drug_concept_id = r.drug_concept_id

)
)
or
Expand All @@ -167,6 +168,7 @@ from cdm.drug_exposure vo
where vo.person_id = p.person_id
and vo.drug_concept_id = r.drug_concept_id
and vo.drug_exposure_start_date = r.drug_exposure_start_date
and (vo.drug_concept_id != 0 or ((vo.drug_source_value is null and r.drug_source_value is null) or vo.drug_source_value = r.drug_source_value))
)
);

Expand Down
3 changes: 3 additions & 0 deletions OmopTransformer/Omop/Measurement/MeasurementRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ from cdm.measurement m
and (r.measurement_source_concept_id is null or m.measurement_source_concept_id = r.measurement_source_concept_id)
and r.RecordConnectionIdentifier is null
and r.HospitalProviderSpellNumber is null
and (m.measurement_concept_id != 0 or ((m.value_source_value is null and r.value_source_value is null) or m.value_source_value = r.value_source_value))
)
and not exists (
select 1
Expand All @@ -153,6 +154,7 @@ from cdm.measurement m
and (r.measurement_source_concept_id is null or m.measurement_source_concept_id = r.measurement_source_concept_id)
and r.RecordConnectionIdentifier is not null
and m.RecordConnectionIdentifier = r.RecordConnectionIdentifier
and (m.measurement_concept_id != 0 or ((m.value_source_value is null and r.value_source_value is null) or m.value_source_value = r.value_source_value))
)
and not exists (
select 1
Expand All @@ -163,6 +165,7 @@ from cdm.measurement m
and (r.measurement_source_concept_id is null or m.measurement_source_concept_id = r.measurement_source_concept_id)
and r.HospitalProviderSpellNumber is not null
and m.HospitalProviderSpellNumber = r.HospitalProviderSpellNumber
and (m.measurement_concept_id != 0 or ((m.value_source_value is null and r.value_source_value is null) or m.value_source_value = r.value_source_value))
);

truncate table omop_staging.measurement_row;",
Expand Down
6 changes: 4 additions & 2 deletions OmopTransformer/Omop/Observation/ObservationRecorder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,17 @@ r.RecordConnectionIdentifier is not null and
o.observation_concept_id = r.observation_concept_id and
o.RecordConnectionIdentifier = r.RecordConnectionIdentifier and
(r.HospitalProviderSpellNumber is null or o.HospitalProviderSpellNumber = r.HospitalProviderSpellNumber) and
(r.observation_source_concept_id is null or o.observation_source_concept_id = r.observation_source_concept_id)
(r.observation_source_concept_id is null or o.observation_source_concept_id = r.observation_source_concept_id) and
(o.observation_concept_id != 0 or ((o.value_as_string is null and r.value_as_string is null) or o.value_as_string = r.value_as_string))
)
or
(
r.RecordConnectionIdentifier is null and
o.person_id = p.person_id and
o.observation_date = r.observation_date and
o.observation_concept_id = r.observation_concept_id and
o.observation_source_concept_id = r.observation_source_concept_id
o.observation_source_concept_id = r.observation_source_concept_id and
(o.observation_concept_id != 0 or ((o.value_as_string is null and r.value_as_string is null) or o.value_as_string = r.value_as_string))
)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,17 @@ r.RecordConnectionIdentifier is not null and
vo.RecordConnectionIdentifier = r.RecordConnectionIdentifier and
vo.person_id = p.person_id and
vo.procedure_date = r.procedure_date and
vo.procedure_concept_id = r.procedure_concept_id
vo.procedure_concept_id = r.procedure_concept_id and
(vo.procedure_concept_id != 0 or ((vo.procedure_source_value is null and r.procedure_source_value is null) or vo.procedure_source_value = r.procedure_source_value))

)
or
(
r.RecordConnectionIdentifier is null and
vo.procedure_date = r.procedure_date and
vo.procedure_concept_id = r.procedure_concept_id and
vo.person_id = p.person_id
vo.person_id = p.person_id and
(vo.procedure_concept_id != 0 or ((vo.procedure_source_value is null and r.procedure_source_value is null) or vo.procedure_source_value = r.procedure_source_value))
)
);

Expand Down
6 changes: 2 additions & 4 deletions OmopTransformer/OxfordGP/OxfordGPTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal class OxfordGPTransformer : Transformer
private readonly ILocationRecorder _locationRecorder;
private readonly IPersonRecorder _personRecorder;
private readonly IDeathRecorder _deathRecorder;
private readonly ConceptResolver _conceptResolver;
private readonly StandardConceptResolver _conceptResolver;
private readonly IProcedureOccurrenceRecorder _procedureOccurrenceRecorder;
private readonly IConditionOccurrenceRecorder _conditionOccurrenceRecorder;
private readonly IVisitOccurrenceRecorder _visitOccurrenceRecorder;
Expand All @@ -42,7 +42,7 @@ public OxfordGPTransformer(
ILocationRecorder locationRecorder,
IPersonRecorder personRecorder,
IDeathRecorder deathRecorder,
ConceptResolver conceptResolver,
StandardConceptResolver conceptResolver,
IRunAnalysisRecorder runAnalysisRecorder,
ILoggerFactory loggerFactory,
IProcedureOccurrenceRecorder procedureOccurrenceRecorder,
Expand Down Expand Up @@ -126,7 +126,5 @@ await Transform<OxfordGPDeviceExposureRecord, OxfordGPDeviceExposure>(
"Oxford GP Device Exposure",
runId,
cancellationToken);

_conceptResolver.PrintErrors();
}
}
6 changes: 2 additions & 4 deletions OmopTransformer/OxfordLab/OxfordLabTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace OmopTransformer.OxfordLab;

internal class OxfordLabTransformer : Transformer
{
private readonly ConceptResolver _conceptResolver;
private readonly StandardConceptResolver _conceptResolver;
private readonly IMeasurementRecorder _measurementRecorder;
private readonly IObservationRecorder _observationRecorder;

Expand All @@ -20,7 +20,7 @@ public OxfordLabTransformer(
IRecordProvider recordProvider,
IMeasurementRecorder measurementRecorder,
IObservationRecorder observationRecorder,
ConceptResolver conceptResolver,
StandardConceptResolver conceptResolver,
IRunAnalysisRecorder runAnalysisRecorder,
ILoggerFactory loggerFactory) : base(recordTransformer,
transformOptions,
Expand Down Expand Up @@ -49,7 +49,5 @@ await Transform<OxfordLabGeneralCommentRecord, OxfordLabGeneralComment>(
"Oxford Lab General Comments",
runId,
cancellationToken);

_conceptResolver.PrintErrors();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ namespace OmopTransformer.OxfordPrescribing;

internal class OxfordPrescribingTransformer : Transformer
{
private readonly ConceptResolver _conceptResolver;
private readonly StandardConceptResolver _conceptResolver;
private readonly IDrugExposureRecorder _drugExposureRecorder;

public OxfordPrescribingTransformer(
IRecordTransformer recordTransformer,
TransformOptions transformOptions,
IRecordProvider recordProvider,
IDrugExposureRecorder drugExposureRecorder,
ConceptResolver conceptResolver,
StandardConceptResolver conceptResolver,
IRunAnalysisRecorder runAnalysisRecorder,
ILoggerFactory loggerFactory) : base(recordTransformer,
transformOptions,
Expand Down Expand Up @@ -45,7 +45,5 @@ await Transform<OxfordPrescribingDrugExposureRecord, OxfordPrescribingDrugExposu
"Oxford Prescribing Drugs",
runId,
cancellationToken);

_conceptResolver.PrintErrors();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ namespace OmopTransformer.OxfordSpineDeath;

internal class OxfordSpineDeathTransformer : Transformer
{
private readonly ConceptResolver _conceptResolver;
private readonly StandardConceptResolver _conceptResolver;
private readonly IDeathRecorder _deathRecorder;

public OxfordSpineDeathTransformer(
IRecordTransformer recordTransformer,
TransformOptions transformOptions,
IRecordProvider recordProvider,
ConceptResolver conceptResolver,
StandardConceptResolver conceptResolver,
IRunAnalysisRecorder runAnalysisRecorder,
ILoggerFactory loggerFactory, IDeathRecorder deathRecorder) : base(recordTransformer,
transformOptions,
Expand All @@ -37,7 +37,5 @@ public async Task Transform(CancellationToken cancellationToken)
"Oxford Spine Death",
runId,
cancellationToken);

_conceptResolver.PrintErrors();
}
}
2 changes: 1 addition & 1 deletion OmopTransformer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ private static async Task Main(string[] args)
builder.Services.AddSingleton<Opcs4Resolver>();
builder.Services.AddSingleton<Icdo3Resolver>();
builder.Services.AddSingleton<SnomedResolver>();
builder.Services.AddSingleton<ConceptResolver>();
builder.Services.AddSingleton<StandardConceptResolver>();
builder.Services.AddSingleton<MeasurementMapsToValueResolver>();

IHostEnvironment env = builder.Environment;
Expand Down
6 changes: 2 additions & 4 deletions OmopTransformer/SUS/AE/SusAETransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ internal class SusAETransformer : Transformer
private readonly IProcedureOccurrenceRecorder _procedureOccurrenceRecorder;
private readonly IDeviceExposureRecorder _deviceExposureRecorder;
private readonly IObservationRecorder _observationRecorder;
private readonly ConceptResolver _conceptResolver;
private readonly StandardConceptResolver _conceptResolver;
private readonly ICareSiteRecorder _careSiteRecorder;

public SusAETransformer(
Expand All @@ -52,7 +52,7 @@ public SusAETransformer(
IVisitDetailRecorder visitDetailRecorder,
IDeathRecorder deathRecorder,
IProcedureOccurrenceRecorder procedureOccurrenceRecorder,
ConceptResolver conceptResolver,
StandardConceptResolver conceptResolver,
IDeviceExposureRecorder deviceExposureRecorder,
IObservationRecorder observationRecorder,
IRunAnalysisRecorder runAnalysisRecorder,
Expand Down Expand Up @@ -157,7 +157,5 @@ await Transform<SusAECareSiteRecord, SusAECareSite>(
"SUS AE CareSite",
runId,
cancellationToken);

_conceptResolver.PrintErrors();
}
}
6 changes: 2 additions & 4 deletions OmopTransformer/SUS/APC/SusAPCTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ internal class SusAPCTransformer : Transformer
private readonly IDeathRecorder _deathRecorder;
private readonly IProcedureOccurrenceRecorder _procedureOccurrenceRecorder;
private readonly IObservationRecorder _observationRecorder;
private readonly ConceptResolver _conceptResolver;
private readonly StandardConceptResolver _conceptResolver;
private readonly ICareSiteRecorder _careSiteRecorder;
private readonly IProviderRecorder _providerRecorder;
private readonly IDeviceExposureRecorder _deviceExposureRecorder;
Expand All @@ -71,7 +71,7 @@ public SusAPCTransformer(
IVisitDetailRecorder visitDetailRecorder,
IDeathRecorder deathRecorder,
IProcedureOccurrenceRecorder procedureOccurrenceRecorder,
ConceptResolver conceptResolver,
StandardConceptResolver conceptResolver,
IDeviceExposureRecorder deviceExposureRecorder,
IObservationRecorder observationRecorder,
IRunAnalysisRecorder runAnalysisRecorder,
Expand Down Expand Up @@ -258,7 +258,5 @@ await Transform<SusAPCReferralReceivedDateForInpatientsRecord, SusAPCReferralRec
"SUS APC ReferralReceivedDateForInpatients",
runId,
cancellationToken);

_conceptResolver.PrintErrors();
}
}
6 changes: 2 additions & 4 deletions OmopTransformer/SUS/OP/SusOPTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ internal class SusOPTransformer : Transformer
private readonly IDeathRecorder _deathRecorder;
private readonly IProcedureOccurrenceRecorder _procedureOccurrenceRecorder;
private readonly IObservationRecorder _observationRecorder;
private readonly ConceptResolver _conceptResolver;
private readonly StandardConceptResolver _conceptResolver;
private readonly ICareSiteRecorder _careSiteRecorder;
private readonly IProviderRecorder _providerRecorder;
private readonly IDeviceExposureRecorder _deviceExposureRecorder;
Expand All @@ -59,7 +59,7 @@ public SusOPTransformer(
IVisitDetailRecorder visitDetailRecorder,
IDeathRecorder deathRecorder,
IProcedureOccurrenceRecorder procedureOccurrenceRecorder,
ConceptResolver conceptResolver,
StandardConceptResolver conceptResolver,
IObservationRecorder observationRecorder,
IDeviceExposureRecorder deviceExposureRecorder,
IRunAnalysisRecorder runAnalysisRecorder,
Expand Down Expand Up @@ -172,7 +172,5 @@ await Transform<SusOPDeviceExposureRecord, SusOPDeviceExposure>(
"SUS OP DeviceExposure",
runId,
cancellationToken);

_conceptResolver.PrintErrors();
}
}
Loading