FHIR to CDISC Joint Mapping Implementation Guide, published by HL7 International - BR&R Work Group. This guide is not an authorized publication; it is the continuous build for version 1.0.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/HL7/fhir-cdisc-mapping/ and changes regularly. See the Directory of published versions
Contents:
This domain contains two mapping tables. The first is similar to the other domains and covers the SDTM and CDASH specification. The second covers the CDISC LAB specification. It is handled as a separate table because it has a significantly larger number of data elements than the other two specifications and the element names have less correlation. Readability of the mappings was enhanced by moving the content to a separate specification.
Lab data in FHIR is handled by two primary resources:
The CDISC specifications focus almost exclusively on the latter. As a result, mappings in both tables are expressed from the perspective of an Observation-rooted transformation. (I.e. All paths are rooted in Observation or are driven by a search based on Observation.) For studies interested in the retrieval of legacy lab information, it may in some cases be necessary to retrieve the DiagnosticReport and manually extract information from a PDF or other report representation. Obviously no standardized mapping can be provided here to assist with that.
In FHIR, the Observation resource is used for a wide range of data collection purposes. In addition to lab data, it is also used to capture vital signs, patient symptoms, psychological assessments, device data, and others. Ideally, lab data can be distinguished from types of Observations using the Observation.category element which should, ideally, have a code of laboratory
drawn from the http://terminology.hl7.org/CodeSystem/observation-category. However, the core FHIR specification does not mandate the use of this code or system. (The U.S. Realm implementation guide and several other national implementation guides do mandate the use of this category.)
The 'laboratory' category encompasses both simple chemical measurements as well as complex assessments including the description of genetic variants, microbiology tests, etc. This implementation guide focuses only on simple measurements and does not attempt to map more complex structures - which in some cases correspond to distinct CDISC domains. In part, this is because FHIR has not yet tried to enforce standardized representation of more complex areas, though initial work has been completed on the capture of genetic findings. Future versions of this implementation guide will likely tackle more complex lab structures.
Guidance on interpreting the tables can be found here.
Guidance on interpreting the tables can be found here.
CDISC | FHIR map (or gap) | Comment | ||
---|---|---|---|---|
Label | LAB | Element | FHIRPath | |
Study ID or Number | /GTP/Study/@ID |
ResearchStudy.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).study.resolve().partOf.resolve().identifier Observation.extension(workflow-researchstudy).valueReference.resolve().partOf.resolve().identifier |
Mapping is based on presumption that research subject will be tied to site-specific ResearchStudy, which will then be part of overall ResearchStudy. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Study Name | /GTP/Study/@Name |
ResearchStudy.title
0..1 string |
ResearchSubject.where(subject=Observation.subject).study.resolve()partOf.resolve().title Observation.extension(workflow-researchstudy).valueReference.resolve().partOf.resolve().title |
Mapping is based on presumption that research subject will be tied to site-specific ResearchStudy, which will then be part of overall ResearchStudy. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Transmission Type | /GTP/Study/@TransmissionType | Determine from type of call to service (requesting all data vs incremental data - e.g. filtering by _lastUpdated). NOTE: If data are not persisted between FHIR and LAB, cannot do incremental data processing (due to lack of delta detection). | If the data is being 'pushed' in a message, this could also be conveyed in the MessageHeader.event | |
Study Transaction Type | /GTP/Study/TransactionType | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | This would be conveyed using a transaction Bundle - specifically the Bundle.entry.request.method | |
Site ID or Number | /GTP/Study/Site/@ID |
ResearchStudy.site
0..* Reference |
ResearchSubject.where(subject=Observation.subject).study.resolve().identifier Observation.extension(workflow-researchstudy).valueReference.resolve().identifier |
Mapping is based on presumption that research subject will be tied to site-specific ResearchStudy, which will then be part of overall ResearchStudy. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Site Transaction Type | /GTP/Study/Site/TransactionType | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Investigator ID or Number | /GTP/Study/Site/Investigator/@ID |
Practitioner.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).study.resolve().principleInvestigator.resolve().identifier Observation.extension(workflow-researchstudy).valueReference.resolve().principleInvestigator.resolve().identifier |
Will need to decide which id to expose or may need to map to one recognized by the sponsor. If you want the PI for the overall study rather than just for the site associated with the Observation, you'll need to traverse the partOf.resolve() from the study-specific ResearchStudy. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Investigator Name | /GTP/Study/Site/Investigator/@Name |
Practitioner.name
0..* HumanName |
ResearchSubject.where(subject=Observation.subject).study.resolve().principleInvestigator.resolve().name.text Observation.extension(workflow-researchstudy).valueReference.resolve().principleInvestigator.resolve().name.text |
Will need to decide which name to expose if there are multiples. Can also extract the prefix, given and family names if text isn't specified. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Investigator Transaction Type | /GTP/Study/Site/Investigator/TransactionType | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Screen ID or Number | /GTP/Study/Site/Investigator/Subject/ScreenID |
ResearchSubject.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).identifier |
Study subject is found by finding the StudySubject that corresponds to the same Patient and ResearchStudy as the Observation. Use the identifier.type to differentiate subject identifiers. No standard way to decide which subject identifier to use. Also no standard way to differentiate subject id from screening id from spare subject id. |
Subject ID or Number | /GTP/Study/Site/Investigator/Subject/SubjectID |
ResearchSubject.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).identifier |
Study subject is found by finding the StudySubject that corresponds to the same Patient and ResearchStudy as the Observation. Use the identifier.type to differentiate subject identifiers. No standard way to decide which subject identifier to use. Also no standard way to differentiate subject id from screening id from spare subject id. |
Spare subject level ID or Number | /GTP/Study/Site/Investigator/Subject/SpareSubjectID |
ResearchSubject.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).identifier |
Study subject is found by finding the StudySubject that corresponds to the same Patient and ResearchStudy as the Observation. Use the identifier.type to differentiate subject identifiers. No standard way to decide which subject identifier to use. Also no standard way to differentiate subject id from screening id from spare subject id. |
Subject Sex | /GTP/Study/Site/Investigator/Subject/Sex/@Value |
Patient.gender
0..1 code Binding: AdministrativeGender required |
Observation.subject.resolve().gender |
Consider whether patient personal information is required for sponsor to perform patient reconciliation. If not, do not send this data element. The US-core birth-sex extension (if it is present) may be more consistently populated than Patient.gender. If patient gender is sent, the values must be mapped from the FHIR vocabulary to the LAB standard: male -> M female -> F other -> U unknown -> U |
Subject Sex Code List ID | /GTP/Study/Site/Investigator/Subject/Sex/@CodeListID | For FHIR, the administrative gender code list is fixed, so no need to send it in the instance. If there's a need to convey alternate gender codes, then those would appear either as Observation values or as extension values on Patient (the former for clinical information, the latter for administrative purposes). In either event, the code would be in CodeableConcept.coding which allows identifying both the code system and (if relevant), the version | ||
Subject Race | /GTP/Study/Site/Investigator/Subject/Race/@Value | There's an US-core extension (us-core-race) for capturing this in the U.S. and the possibility that other countries will define their own extensions. Note that this is for administrative, not clinical purposes. Genetic heritage would typically be captured as an Observation | Consider whether patient personal information is required for the sponsor to perform patient reconciliation. If not, do not send this data element. If patient race is sent, use the us-core-race extension in FHIR. |
|
Subject Race Code List ID | /GTP/Study/Site/Investigator/Subject/Race/@CodeListID | Race, whether captured as an extension or observation value is generally a CodeableConcept allowing capturing both code system and (if relevant) version. Race is highly variable from country to country (both whether it's allowed and how it's coded), so there's no standard element for this in the core spec. | ||
Subject Initials | /GTP/Study/Site/Investigator/Subject/Confidential/@Initials |
Patient.name
0..* HumanName |
ResearchSubject.where(subject=Observation.subject).individual.resolve().name.text |
Note that name.text will typically contain the full name, but *can* contain initials only. If the full name is present, initials can be extracted by looking at the given and family name components and converting to initials Consider whether patient personal information is required for the sponsor to perform patient reconciliation. If not, do not send this data element. If required, be sure to send only the initials, derived from the name. |
Subject Date Of Birth | /GTP/Study/Site/Investigator/Subject/Confidential/@Birthdate |
Patient.birthDate
0..1 date |
ResearchSubject.where(subject=Observation.subject).individual.resolve().birthDate |
Note that precision can vary (YYYY, YYYY-MM or YYYY-MM-DD) Consider whether patient personal information is required for the sponsor to perform patient reconciliation. If not, do not send this data element. |
Visit ID or Number | /GTP/Study/Site/Investigator/Subject/Visit/@ID |
Encounter.identifier
0..* Identifier |
Observation.encounter.resolve().identifier |
No standard way to decide which identifier to use if multiples are present |
Visit Name | /GTP/Study/Site/Investigator/Subject/Visit/@Name | In practice, visit name would be the ActivityDefinition.title for the activity in the protocol associated with the encounter. There is no standard extension for this link (though one will be defined). Most clinical systems won't actually capture this, so the determination will need to be made at time of data extraction based on the protocol | See LB mapping comment | |
Visit Type | /GTP/Study/Site/Investigator/Subject/Visit/@Type | This is essentially whether the visit is tied to a particular activity within the PlanDefinition (study protocol) or not. Given that in non-study-specific systems, there won't typically be a linkage even when the encounter *is* driven by the study, this will generally need to be populated algorithmically on extension | This could theoretically be distinguished by whether there was a link to a CarePlan activity or ActivityDefinition. Alternatively, you could use an extension or tag. (What's 'planned' for one study might be unplanned for another) This would be Encounter.reasonCode |
|
Visit Type Modifier | /GTP/Study/Site/Investigator/Subject/Visit/@TypeModifier |
Encounter.reasonCode
0..* CodeableConcept Binding: EncounterReason preferred |
Observation.encounter.resolve().reasonCode |
This would be Encounter.reasonCode |
Subject Transaction Type | /GTP/Study/Site/Investigator/Subject/TransactionType | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Accession ID or Number | /GTP/Study/Site/Investigator/Subject/Visit/Accession/@ID |
Specimen.accessionIdentifier
0..1 Identifier |
Observation.resolve().accessionIdentifier |
|
Last Active Date and Time | /GTP/Study/Site/Investigator/Subject/Visit/Accession/@LastActiveDateTime | FHIR allows capture meta.lastUpdated which reflects when the data last changed on the server in question, but would need to look at Provenance to see when data last changed on a particular system. This typically won't be available. | ||
Visit Transaction Type | /GTP/Study/Site/Investigator/Subject/Visit/Accession/TransactionType | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Central Laboratory ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/CentralLab/@ID |
Organization.identifier
0..* Identifier org-1 |
Observation.performer.resolve().identifier |
Will need to look at identifier.type or identifier.system to know which identifier to use. In some cases, performer might be PractitionerRole, in which case, will need to map through PractitionerRole.organization. If there are multiple performers that link to multiple organizations, converter will need to look at Organization.type or have other rules to decide amongst the candidates. |
Central Laboratory Name | /GTP/Study/Site/Investigator/Subject/Visit/Accession/CentralLab/@Name |
Organization.name
0..1 string org-1 |
Observation.performer.resolve().name |
If there are multiple performers that link to multiple organizations, converter will need to look at Organization.type or have other rules to decide amongst the candidates. |
Specimen ID or Number | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/@ID |
Specimen.identifier
0..* Identifier |
Observation.specimen.resolve().identifier |
If there are multiple identifiers, need to look at identifier.system or identifier.type to determine |
Actual Collection Date and Time | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenCollection/@ActualCollectionDateTime |
Specimen.collection.collectedDateTime
0..1 dateTime |
Observation.specimen.resolve().collection.collectedDateTime |
Most of the time there'll only be a single dateTime. If collected over a period of time (e.g. urine), use the end. |
Specimen.collection.collectedPeriod
0..1 Period |
Observation.specimen.resolve().collection.collectedPeriod.end |
|||
Planned Collection Time Elapsed | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenCollection/@PlannedCollectionTimeElapsed |
Specimen.extension
0..* Extension |
Observation.specimen.resolve().extension(cqf-relativeDateTime).valueDuration |
Will need to convert value + units into an ISO duration |
Planned Collection Time Elapsed Description | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenCollection/@PlannedCollectionTimeElapsedDescription |
Specimen.extension
0..* Extension |
Observation.specimen.resolve().extension(cqf-relativeDateTime).valueReference.reference |
The event would be in extension('target').valueReference.display and the time would be in extension('offset').valueDuration value and unit. |
Collection End Date and Time | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenCollection/@CollectionEndDateTime |
Specimen.collection.collectedPeriod
0..1 Period |
Observation.specimen.resolve().collection.collectedPeriod.end |
|
Received Date and Time | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenTransport/@ReceivedDateTime |
Specimen.receivedTime
0..1 dateTime |
Observation.specimen.resolve().receivedTime |
|
Specimen Condition | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenTransport/@SpecimenCondition |
Specimen.condition
0..* CodeableConcept Binding: SpecimenCondition extensible |
Observation.specimen.resolve().condition.coding.code |
Will need to choose which coding to extract the code for |
Investigator - Specimen Comment Source | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenComment/@Source |
Practitioner.identifier
0..* Identifier |
Observation.specimen.resolve().note.author.resolve().where($thisisPractitioner).identifier |
Note that practitioners can have multiple identifiers - use type or system to decide which identifier to expose |
Investigator - Specimen Comment Text | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenComment/@Text |
Specimen.note
0..* Annotation |
Observation.specimen.resolve().where($author.resolve()isPractitioner).note.text |
|
Lab - Specimen Comment Source | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenComment/@Source |
Observation.identifier
0..* Identifier |
Observation.specimen.resolve().note.author.resolve().where($thisisOrganization).identifier |
Note that organizations can have multiple identifiers - use type or system to decide which identifier to expose |
Lab - Specimen Comment Text | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenComment/@Text |
Specimen.note
0..* Annotation |
Observation.specimen.resolve().where($author.resolve() isOrganization).note.text |
|
Specimen Material ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenMaterial/@ID |
Specimen.type
0..1 CodeableConcept Binding: SpecimenType example |
Observation.specimen.resolve().where($author.resolve() isOrganization).type.coding.code |
If multiple codes are present, filter based on system |
Specimen Material Name | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenMaterial/@Name |
Specimen.type
0..1 CodeableConcept Binding: SpecimenType example |
Observation.specimen.resolve().where($author.resolve() isOrganization).type.coding.display |
If multiple codes are present, filter based on system. Translation may be required |
Specimen Material Code List ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenMaterial/@CodeListID |
Specimen.type
0..1 CodeableConcept Binding: SpecimenType example |
Observation.specimen.resolve().where($author.resolve() isOrganization).type.coding.system |
If multiple codings are present, will need to decide which to use |
Subject Age at Collection | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SubjectAtCollection/@AgeAtCollection | If captured as an Observation, this would be in the ValueQuantity.code derived from the patient.birthDate(Observation.subject (ref:Patient.birthDate). If the full birthdate cannot be shared, due to country restrictions, use the birth year to derive age information. Due to lost accuracy in having only the year of birth, 'years' would be the default unit. As an alternative use the cqf-relativeTime extension on Patient.birthDate and convey as a relative time to study enrollment |
||
Subject Age Units | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SubjectAtCollection/@AgeUnits | If captured as an Observation, this would be in the ValueQuantity.code derived from the patient.birthDate(Observation.subject (ref:Patient.birthDate). If the full birthdate cannot be shared, due to country restrictions, use the birth year to derive age information. Due to lost accuracy in having only the year of birth, 'years' would be the default unit. |
||
Fasting Status | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SubjectAtCollection/@FastingStatus |
Specimen.collection.fastingStatusCodeableConcept
0..1 CodeableConcept Binding: FastingStatus extensible |
Observation.specimen.resolve().collection.fastingStatusCodeableConcept.coding.code |
FHIR to CDISC mapping as follows:
F -> Y; NF -> N; FNA -> N/A; NG -> Not Applicable (blank) If fastingStatusDuration is present and non-zero, that would also map to 'Y'. There are times where this can be inferred from the Observation.code. |
Battery ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/@ID |
DiagnosticReport.identifier
0..* Identifier |
DiagnosticReport.identifier |
|
Battery Name | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/@Name |
DiagnosticReport.code
1..1 CodeableConcept Binding: DiagnosticReportCodes preferred |
DiagnosticReport.code.text |
|
Battery Transaction Type | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/TransactionType | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Test Status | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/@Status |
ServiceRequest.doNotPerform
0..1 boolean |
Observation.basedOn.resolve().doNotPerform |
Multiple fields are required to populate this value per the standard. Use ServiceRequest.status and ServiceRequest.doNotPerform (doNotPerform will only be true if the test is not to be performed) to represent the test status. From these two fields, sponsors will need to translate to the CDISC test statuses: D - Done N - Not Performed X - Cancelled. |
ServiceRequest.status
1..1 code Binding: ServiceRequestStatus required |
Observation.basedon.resolve().status |
|||
Testing Date and Time | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/@TestingDateTime |
Observation.effectiveDateTime
0..1 dateTime |
Observation.effectiveDateTime |
|
Test Type | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/@TestType | The normal transmission of data, via FHIR, is for study tests. If non-study test results are required (e.g., AdverseEvent follow-up), these would be obtained via a special request from the data provider. Alternatively, if the system requires this field to be populated, derive whether the test was for the study or not, use the ServiceRequest resource. | Differentiation would be whether the Observation was basedOn a particular activity in the CarePlan (scheduled) or tied to a particular ActivityDefinition (Study test) | |
Performing Laboratory ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/PerformingLab/@ID |
Organization.identifier
0..* Identifier org-1 |
Observation.performer.resolve().identifier |
Use "Organization/type" to pick the type of Organization that represents "Performing Lab" |
Performing Laboratory Name | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/PerformingLab/@Name |
Organization.name
0..1 string org-1 |
Observation.performer.resolve().name |
|
Lab Test ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LabTest/@ID |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.where(system = 'Lab Test') |
Since this is a codeable concept, there may be multiple codes for a test. The sponsor will have to determine which is the "lab's" code vs. "receiver's" code vs. others. |
Lab Test Name | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LabTest/@Name |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.display |
|
Additional Test Description | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LabTest/@AdditionalDescription |
Observation.note
0..* Annotation |
Observation.note.text |
Not all notes will necessarily be appropriate to map here. Would need to decide whether to also bring across authors and dates and would need to combined multiple repetitions into a single string. |
Receiver Test ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/ReceiverTest/@ID |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.where (system = [Recipient Test]) |
Observation/code/coding/system/@value ("system" element used to designate the type of code that is being represented (in this case the "ReceiverTest") by the "code" element) |
Receiver Test Name | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/ReceiverTest/@Name |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.display where (coding system = 'Recipient Test') |
|
LOINC Code | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LOINCTestCode/@Value |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.where (coding system = 'http://loinc.org') |
|
LOINC Code List ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LOINCTestCode/@CodeListID |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.where(system = 'http://loinc.org') |
This will always be 'LOINC' |
Test Level Comments | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/TestLevelComment |
Observation.extension
0..* Extension |
Observation.note.text |
Will need to determine whether to also incude date and author. |
Reported Result Status | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@ReportedResultStatus |
Observation.status
1..1 code Binding: ObservationStatus required |
Observation.status |
This has two possible values: P for Preliminary and F for Final. |
Alert Flag | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@AlertFlag |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where(system='Alert Flag') |
The alert flag generated by the reference ranges applied and tied to the reported result. There are 9 alert flag values: LP - Low Panic LT - Low Telephone LN - Low Normal N - Normal HN - High Normal HT - High Telephone HP - High Panic AB - Abnormal and blank when not used. It may be necessary to translate from other interpretation codings. |
Delta Flag | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@DeltaFlag |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where (system = 'Delta Flag') |
The delta flag generated by the reference ranges applied and tied to the reported result. There are three delta flags: D+ for an increase in value D- for a decrease in value and blank for no flag. It may be necessary to translate from other interpretation codings. |
Exclusion Flag | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@ExclusionFlag |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where (system = 'Exclusion Flag') |
The exclusion flag generated by the reference ranges applied and tied to the reported result. There are four exclusion flag values: LX - Low Exclusion HX - High Exclusion EX - Excluded (for exclusions not falling under high or low) and blank for no flag. It may be necessary to translate from other |
Blinding Flag | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@BlindingFlag |
Observation.meta
0..1 Meta |
Observation.meta.security.code |
A new code would likely be needed to specifically designate 'blinded'. |
Reported Date and Time | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@ReportedDateTime |
Observation.issued
0..1 instant |
Observation.issued |
|
Test Transaction Type | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/TransactionType | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Toxicity Grade | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/ToxicityGrade/@Value |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where (system = 'Toxicity Grade').code |
If there are multiple possible systems, the sponsor will have to determine which interpretation corresponds to toxicity grade |
Toxicity Grade Code List ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/ToxicityGrade/@CodeListID |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where (system = 'Toxicity Grade') |
May need to translate the URI to a CDISC Code List id |
Reported Result Type (C=coded; N=numeric; T=text; R=range; G = GT; L = LT) | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/@ResultType | Determine from the field in which the result resides. valueCodeableConcept vs. valueQuantity vs. valueString Greater than and less than can be determined by valueQuantity.qualifier | ||
Text Result | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/TextResult/@Value |
Observation.valueCodeableConcept
0..1 CodeableConcept obs-7 |
Observation.valueCodeableConcept.text |
|
Text Result Code List ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/TextResult/@CodeListID |
Observation.valueCodeableConcept
0..1 CodeableConcept obs-7 |
Observation.valueCodeableConcept.coding.system |
May need to convert from URI to CDISC-recognized 'ID' |
Conventional Numeric Result | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Value |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
If the reported result isn't in conventional units, can use the PQ-translation extension to convey a translation. |
Reported Numeric Result | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Value |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
|
SI Numeric Result | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Value |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
If the reported result isn't in SI units, can use the PQ-translation extension to convey a translation. |
Conventional Numeric Result Precision | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Precision |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
Determine the precision from the value. Precision is implicitly determined from the attribute Observation/valueQuantity/value/@value If the reported result isn't in conventional units, can use the PQ-translation extension to convey a translation. |
Reported Numeric Result Precision | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Precision |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
Determine the precision from the value. Precision is implicitly determined from the attribute Observation/valueQuantity/value/@value |
SI Numeric Result Precision | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Precision |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
Determine the precision from the value. Precision is implicitly determined from the attribute Observation/valueQuantity/value/@value If the reported result isn't in SI units, can use the PQ-translation extension to convey a translation. |
Conventional Reference Range Low | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeLow |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.low.value Observation.referenceRange.low.unit |
Will need to combine value and unit into a string. If the reported units aren't 'conventional, can use the PQ-translation extension on Quantity to convey a translation. |
Reported Reference Range Low | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeLow |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.low.value Observation.referenceRange.low.unit |
Will need to combine value and unit into a string. |
SI Reference Range Low | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeLow |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.low.value Observation.referenceRange.low.unit |
Will need to combine value and unit into a string. If the reported units aren't SI, can use the PQ-translation extension on Quantity to convey a translation. |
Conventional Reference Range High | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeHigh |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.high.value Observation.referenceRange.high.unit |
Will need to combine value and unit into a string. If the reported units aren't 'conventional, can use the PQ-translation extension on Quantity to convey a translation. |
Reported Reference Range High | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeHigh |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.high.value Observation.referenceRange.high.unit |
Will need to combine value and unit into a string. |
SI Reference Range High | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeHigh |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.high.value Observation.referenceRange.high.unit |
Will need to combine value and unit into a string. If the reported units aren't SI, can use the PQ-translation extension on Quantity to convey a translation. |
Conventional Units | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@Value |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.code Observation.valueQuantity.extension('PQ-translation').code |
If the reported units are not the same as conventional, can convey with the translation extension. Translation to CDISC terminology may be required. |
Reported Units | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@Value |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.code |
This may require translation to CDISC terminology |
SI Units | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@Value |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.code Observation.valueQuantity.extensoin('PQ-translation').code |
If the reported units are not SI units, can convey with the translation extension. Translation to CDISC terminology may be required. |
Conventional Units Code List ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@CodeListID |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.system |
|
Reported Units Code List ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@CodeListID |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.system |
|
SI Units Code List ID | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@CodeListID |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.system |
|
Record Extension Type | Populate with a default value, depending on the type of data being transmitted. E.g., "BASE" |
|||
Result Class | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultClass/@Value | In FHIR, the value will always be 'reported', with the ability to convey translations in an extension. Nothing will differentiate whether a translation is considered 'conventional' or not, so if there are multiple translations present and the receiver can't figure it out by looking, an additional extension may be necessary to differentiate. This can sometimes also be inferred from the Observation.code. | ||
Model Version | /GTP/@ModelVersion | Populate with a default value. | The version of FHIR in use is conveyed using Resource.meta.profile | |
File Creation Date and Time | /GTP/@CreationDateTime | Pull from the message wrapper. (file creation date) | Bundle.timestamp | |
Transaction Type | /GTP/TransactionType | No mitigation. If required, fill with a default value. | As per study.transaction | |
Transmission Source ID | /GTP/TransmissionSource/@ID | Pull from the message wrapper. | MessageHeader.source.endpoint if using messaging, otherwise determined out of band based on sender authentication process | |
Transmission Source Name | /GTP/TransmissionSource/@Name | Pull from the message wrapper. | MessageHeader.source.name if using messaging, otherwise determined out of band based on sender authentication process |
FHIR map (or gap) | CDISC | Comment | ||
---|---|---|---|---|
Label | Element | FHIRPath | LAB | |
Study ID or Number |
ResearchStudy.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).study.resolve().partOf.resolve().identifier Observation.extension(workflow-researchstudy).valueReference.resolve().partOf.resolve().identifier |
/GTP/Study/@ID | Mapping is based on presumption that research subject will be tied to site-specific ResearchStudy, which will then be part of overall ResearchStudy. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Study Name |
ResearchStudy.title
0..1 string |
ResearchSubject.where(subject=Observation.subject).study.resolve()partOf.resolve().title Observation.extension(workflow-researchstudy).valueReference.resolve().partOf.resolve().title |
/GTP/Study/@Name | Mapping is based on presumption that research subject will be tied to site-specific ResearchStudy, which will then be part of overall ResearchStudy. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Transmission Type | Determine from type of call to service (requesting all data vs incremental data - e.g. filtering by _lastUpdated). NOTE: If data are not persisted between FHIR and LAB, cannot do incremental data processing (due to lack of delta detection). | /GTP/Study/@TransmissionType | If the data is being 'pushed' in a message, this could also be conveyed in the MessageHeader.event | |
Study Transaction Type | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | /GTP/Study/TransactionType | This would be conveyed using a transaction Bundle - specifically the Bundle.entry.request.method | |
Site ID or Number |
ResearchStudy.site
0..* Reference |
ResearchSubject.where(subject=Observation.subject).study.resolve().identifier Observation.extension(workflow-researchstudy).valueReference.resolve().identifier |
/GTP/Study/Site/@ID | Mapping is based on presumption that research subject will be tied to site-specific ResearchStudy, which will then be part of overall ResearchStudy. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Site Transaction Type | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | /GTP/Study/Site/TransactionType | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Investigator ID or Number |
Practitioner.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).study.resolve().principleInvestigator.resolve().identifier Observation.extension(workflow-researchstudy).valueReference.resolve().principleInvestigator.resolve().identifier |
/GTP/Study/Site/Investigator/@ID | Will need to decide which id to expose or may need to map to one recognized by the sponsor. If you want the PI for the overall study rather than just for the site associated with the Observation, you'll need to traverse the partOf.resolve() from the study-specific ResearchStudy. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Investigator Name |
Practitioner.name
0..* HumanName |
ResearchSubject.where(subject=Observation.subject).study.resolve().principleInvestigator.resolve().name.text Observation.extension(workflow-researchstudy).valueReference.resolve().principleInvestigator.resolve().name.text |
/GTP/Study/Site/Investigator/@Name | Will need to decide which name to expose if there are multiples. Can also extract the prefix, given and family names if text isn't specified. The path using the extension will only exist if the system maintaining the Observation is aware of its relevance to the Study. |
Investigator Transaction Type | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | /GTP/Study/Site/Investigator/TransactionType | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Screen ID or Number |
ResearchSubject.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).identifier |
/GTP/Study/Site/Investigator/Subject/ScreenID | Study subject is found by finding the StudySubject that corresponds to the same Patient and ResearchStudy as the Observation. Use the identifier.type to differentiate subject identifiers. No standard way to decide which subject identifier to use. Also no standard way to differentiate subject id from screening id from spare subject id. |
Subject ID or Number |
ResearchSubject.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).identifier |
/GTP/Study/Site/Investigator/Subject/SubjectID | Study subject is found by finding the StudySubject that corresponds to the same Patient and ResearchStudy as the Observation. Use the identifier.type to differentiate subject identifiers. No standard way to decide which subject identifier to use. Also no standard way to differentiate subject id from screening id from spare subject id. |
Spare subject level ID or Number |
ResearchSubject.identifier
0..* Identifier |
ResearchSubject.where(subject=Observation.subject).identifier |
/GTP/Study/Site/Investigator/Subject/SpareSubjectID | Study subject is found by finding the StudySubject that corresponds to the same Patient and ResearchStudy as the Observation. Use the identifier.type to differentiate subject identifiers. No standard way to decide which subject identifier to use. Also no standard way to differentiate subject id from screening id from spare subject id. |
Subject Sex |
Patient.gender
0..1 code Binding: AdministrativeGender required |
Observation.subject.resolve().gender |
/GTP/Study/Site/Investigator/Subject/Sex/@Value | Consider whether patient personal information is required for sponsor to perform patient reconciliation. If not, do not send this data element. The US-core birth-sex extension (if it is present) may be more consistently populated than Patient.gender. If patient gender is sent, the values must be mapped from the FHIR vocabulary to the LAB standard: male -> M female -> F other -> U unknown -> U |
Subject Sex Code List ID | For FHIR, the administrative gender code list is fixed, so no need to send it in the instance. If there's a need to convey alternate gender codes, then those would appear either as Observation values or as extension values on Patient (the former for clinical information, the latter for administrative purposes). In either event, the code would be in CodeableConcept.coding which allows identifying both the code system and (if relevant), the version | /GTP/Study/Site/Investigator/Subject/Sex/@CodeListID | ||
Subject Race | There's an US-core extension (us-core-race) for capturing this in the U.S. and the possibility that other countries will define their own extensions. Note that this is for administrative, not clinical purposes. Genetic heritage would typically be captured as an Observation | /GTP/Study/Site/Investigator/Subject/Race/@Value | Consider whether patient personal information is required for the sponsor to perform patient reconciliation. If not, do not send this data element. If patient race is sent, use the us-core-race extension in FHIR. |
|
Subject Race Code List ID | Race, whether captured as an extension or observation value is generally a CodeableConcept allowing capturing both code system and (if relevant) version. Race is highly variable from country to country (both whether it's allowed and how it's coded), so there's no standard element for this in the core spec. | /GTP/Study/Site/Investigator/Subject/Race/@CodeListID | ||
Subject Initials |
Patient.name
0..* HumanName |
ResearchSubject.where(subject=Observation.subject).individual.resolve().name.text |
/GTP/Study/Site/Investigator/Subject/Confidential/@Initials | Note that name.text will typically contain the full name, but *can* contain initials only. If the full name is present, initials can be extracted by looking at the given and family name components and converting to initials Consider whether patient personal information is required for the sponsor to perform patient reconciliation. If not, do not send this data element. If required, be sure to send only the initials, derived from the name. |
Subject Date Of Birth |
Patient.birthDate
0..1 date |
ResearchSubject.where(subject=Observation.subject).individual.resolve().birthDate |
/GTP/Study/Site/Investigator/Subject/Confidential/@Birthdate | Note that precision can vary (YYYY, YYYY-MM or YYYY-MM-DD) Consider whether patient personal information is required for the sponsor to perform patient reconciliation. If not, do not send this data element. |
Visit ID or Number |
Encounter.identifier
0..* Identifier |
Observation.encounter.resolve().identifier |
/GTP/Study/Site/Investigator/Subject/Visit/@ID | No standard way to decide which identifier to use if multiples are present |
Visit Name | In practice, visit name would be the ActivityDefinition.title for the activity in the protocol associated with the encounter. There is no standard extension for this link (though one will be defined). Most clinical systems won't actually capture this, so the determination will need to be made at time of data extraction based on the protocol | /GTP/Study/Site/Investigator/Subject/Visit/@Name | See LB mapping comment | |
Visit Type | This is essentially whether the visit is tied to a particular activity within the PlanDefinition (study protocol) or not. Given that in non-study-specific systems, there won't typically be a linkage even when the encounter *is* driven by the study, this will generally need to be populated algorithmically on extension | /GTP/Study/Site/Investigator/Subject/Visit/@Type | This could theoretically be distinguished by whether there was a link to a CarePlan activity or ActivityDefinition. Alternatively, you could use an extension or tag. (What's 'planned' for one study might be unplanned for another) This would be Encounter.reasonCode |
|
Visit Type Modifier |
Encounter.reasonCode
0..* CodeableConcept Binding: EncounterReason preferred |
Observation.encounter.resolve().reasonCode |
/GTP/Study/Site/Investigator/Subject/Visit/@TypeModifier | This would be Encounter.reasonCode |
Subject Transaction Type | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | /GTP/Study/Site/Investigator/Subject/TransactionType | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Accession ID or Number |
Specimen.accessionIdentifier
0..1 Identifier |
Observation.resolve().accessionIdentifier |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/@ID | |
Last Active Date and Time | FHIR allows capture meta.lastUpdated which reflects when the data last changed on the server in question, but would need to look at Provenance to see when data last changed on a particular system. This typically won't be available. | /GTP/Study/Site/Investigator/Subject/Visit/Accession/@LastActiveDateTime | ||
Visit Transaction Type | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | /GTP/Study/Site/Investigator/Subject/Visit/Accession/TransactionType | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Central Laboratory ID |
Organization.identifier
0..* Identifier org-1 |
Observation.performer.resolve().identifier |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/CentralLab/@ID | Will need to look at identifier.type or identifier.system to know which identifier to use. In some cases, performer might be PractitionerRole, in which case, will need to map through PractitionerRole.organization. If there are multiple performers that link to multiple organizations, converter will need to look at Organization.type or have other rules to decide amongst the candidates. |
Central Laboratory Name |
Organization.name
0..1 string org-1 |
Observation.performer.resolve().name |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/CentralLab/@Name | If there are multiple performers that link to multiple organizations, converter will need to look at Organization.type or have other rules to decide amongst the candidates. |
Specimen ID or Number |
Specimen.identifier
0..* Identifier |
Observation.specimen.resolve().identifier |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/@ID | If there are multiple identifiers, need to look at identifier.system or identifier.type to determine |
Actual Collection Date and Time |
Specimen.collection.collectedDateTime
0..1 dateTime |
Observation.specimen.resolve().collection.collectedDateTime |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenCollection/@ActualCollectionDateTime | Most of the time there'll only be a single dateTime. If collected over a period of time (e.g. urine), use the end. |
Specimen.collection.collectedPeriod
0..1 Period |
Observation.specimen.resolve().collection.collectedPeriod.end |
|||
Planned Collection Time Elapsed |
Specimen.extension
0..* Extension |
Observation.specimen.resolve().extension(cqf-relativeDateTime).valueDuration |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenCollection/@PlannedCollectionTimeElapsed | Will need to convert value + units into an ISO duration |
Planned Collection Time Elapsed Description |
Specimen.extension
0..* Extension |
Observation.specimen.resolve().extension(cqf-relativeDateTime).valueReference.reference |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenCollection/@PlannedCollectionTimeElapsedDescription | The event would be in extension('target').valueReference.display and the time would be in extension('offset').valueDuration value and unit. |
Collection End Date and Time |
Specimen.collection.collectedPeriod
0..1 Period |
Observation.specimen.resolve().collection.collectedPeriod.end |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenCollection/@CollectionEndDateTime | |
Received Date and Time |
Specimen.receivedTime
0..1 dateTime |
Observation.specimen.resolve().receivedTime |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenTransport/@ReceivedDateTime | |
Specimen Condition |
Specimen.condition
0..* CodeableConcept Binding: SpecimenCondition extensible |
Observation.specimen.resolve().condition.coding.code |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenTransport/@SpecimenCondition | Will need to choose which coding to extract the code for |
Investigator - Specimen Comment Source |
Practitioner.identifier
0..* Identifier |
Observation.specimen.resolve().note.author.resolve().where($thisisPractitioner).identifier |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenComment/@Source | Note that practitioners can have multiple identifiers - use type or system to decide which identifier to expose |
Investigator - Specimen Comment Text |
Specimen.note
0..* Annotation |
Observation.specimen.resolve().where($author.resolve()isPractitioner).note.text |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenComment/@Text | |
Lab - Specimen Comment Source |
Observation.identifier
0..* Identifier |
Observation.specimen.resolve().note.author.resolve().where($thisisOrganization).identifier |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenComment/@Source | Note that organizations can have multiple identifiers - use type or system to decide which identifier to expose |
Lab - Specimen Comment Text |
Specimen.note
0..* Annotation |
Observation.specimen.resolve().where($author.resolve() isOrganization).note.text |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenComment/@Text | |
Specimen Material ID |
Specimen.type
0..1 CodeableConcept Binding: SpecimenType example |
Observation.specimen.resolve().where($author.resolve() isOrganization).type.coding.code |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenMaterial/@ID | If multiple codes are present, filter based on system |
Specimen Material Name |
Specimen.type
0..1 CodeableConcept Binding: SpecimenType example |
Observation.specimen.resolve().where($author.resolve() isOrganization).type.coding.display |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenMaterial/@Name | If multiple codes are present, filter based on system. Translation may be required |
Specimen Material Code List ID |
Specimen.type
0..1 CodeableConcept Binding: SpecimenType example |
Observation.specimen.resolve().where($author.resolve() isOrganization).type.coding.system |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SpecimenMaterial/@CodeListID | If multiple codings are present, will need to decide which to use |
Subject Age at Collection | If captured as an Observation, this would be in the ValueQuantity.code derived from the patient.birthDate(Observation.subject (ref:Patient.birthDate). If the full birthdate cannot be shared, due to country restrictions, use the birth year to derive age information. Due to lost accuracy in having only the year of birth, 'years' would be the default unit. As an alternative use the cqf-relativeTime extension on Patient.birthDate and convey as a relative time to study enrollment |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SubjectAtCollection/@AgeAtCollection | ||
Subject Age Units | If captured as an Observation, this would be in the ValueQuantity.code derived from the patient.birthDate(Observation.subject (ref:Patient.birthDate). If the full birthdate cannot be shared, due to country restrictions, use the birth year to derive age information. Due to lost accuracy in having only the year of birth, 'years' would be the default unit. |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SubjectAtCollection/@AgeUnits | ||
Fasting Status |
Specimen.collection.fastingStatusCodeableConcept
0..1 CodeableConcept Binding: FastingStatus extensible |
Observation.specimen.resolve().collection.fastingStatusCodeableConcept.coding.code |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/SubjectAtCollection/@FastingStatus | FHIR to CDISC mapping as follows:
F -> Y; NF -> N; FNA -> N/A; NG -> Not Applicable (blank) If fastingStatusDuration is present and non-zero, that would also map to 'Y'. There are times where this can be inferred from the Observation.code. |
Battery ID |
DiagnosticReport.identifier
0..* Identifier |
DiagnosticReport.identifier |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/@ID | |
Battery Name |
DiagnosticReport.code
1..1 CodeableConcept Binding: DiagnosticReportCodes preferred |
DiagnosticReport.code.text |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/@Name | |
Battery Transaction Type | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/TransactionType | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Test Status |
ServiceRequest.doNotPerform
0..1 boolean |
Observation.basedOn.resolve().doNotPerform |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/@Status | Multiple fields are required to populate this value per the standard. Use ServiceRequest.status and ServiceRequest.doNotPerform (doNotPerform will only be true if the test is not to be performed) to represent the test status. From these two fields, sponsors will need to translate to the CDISC test statuses: D - Done N - Not Performed X - Cancelled. |
ServiceRequest.status
1..1 code Binding: ServiceRequestStatus required |
Observation.basedon.resolve().status |
|||
Testing Date and Time |
Observation.effectiveDateTime
0..1 dateTime |
Observation.effectiveDateTime |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/@TestingDateTime | |
Test Type | The normal transmission of data, via FHIR, is for study tests. If non-study test results are required (e.g., AdverseEvent follow-up), these would be obtained via a special request from the data provider. Alternatively, if the system requires this field to be populated, derive whether the test was for the study or not, use the ServiceRequest resource. | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/@TestType | Differentiation would be whether the Observation was basedOn a particular activity in the CarePlan (scheduled) or tied to a particular ActivityDefinition (Study test) | |
Performing Laboratory ID |
Organization.identifier
0..* Identifier org-1 |
Observation.performer.resolve().identifier |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/PerformingLab/@ID | Use "Organization/type" to pick the type of Organization that represents "Performing Lab" |
Performing Laboratory Name |
Organization.name
0..1 string org-1 |
Observation.performer.resolve().name |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/PerformingLab/@Name | |
Lab Test ID |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.where(system = 'Lab Test') |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LabTest/@ID | Since this is a codeable concept, there may be multiple codes for a test. The sponsor will have to determine which is the "lab's" code vs. "receiver's" code vs. others. |
Lab Test Name |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.display |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LabTest/@Name | |
Additional Test Description |
Observation.note
0..* Annotation |
Observation.note.text |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LabTest/@AdditionalDescription | Not all notes will necessarily be appropriate to map here. Would need to decide whether to also bring across authors and dates and would need to combined multiple repetitions into a single string. |
Receiver Test ID |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.where (system = [Recipient Test]) |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/ReceiverTest/@ID | Observation/code/coding/system/@value ("system" element used to designate the type of code that is being represented (in this case the "ReceiverTest") by the "code" element) |
Receiver Test Name |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.display where (coding system = 'Recipient Test') |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/ReceiverTest/@Name | |
LOINC Code |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.where (coding system = 'http://loinc.org') |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LOINCTestCode/@Value | |
LOINC Code List ID |
Observation.code
1..1 CodeableConcept Binding: ObservationCode example |
Observation.code.coding.where(system = 'http://loinc.org') |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/LOINCTestCode/@CodeListID | This will always be 'LOINC' |
Test Level Comments |
Observation.extension
0..* Extension |
Observation.note.text |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/TestLevelComment | Will need to determine whether to also incude date and author. |
Reported Result Status |
Observation.status
1..1 code Binding: ObservationStatus required |
Observation.status |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@ReportedResultStatus | This has two possible values: P for Preliminary and F for Final. |
Alert Flag |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where(system='Alert Flag') |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@AlertFlag | The alert flag generated by the reference ranges applied and tied to the reported result. There are 9 alert flag values: LP - Low Panic LT - Low Telephone LN - Low Normal N - Normal HN - High Normal HT - High Telephone HP - High Panic AB - Abnormal and blank when not used. It may be necessary to translate from other interpretation codings. |
Delta Flag |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where (system = 'Delta Flag') |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@DeltaFlag | The delta flag generated by the reference ranges applied and tied to the reported result. There are three delta flags: D+ for an increase in value D- for a decrease in value and blank for no flag. It may be necessary to translate from other interpretation codings. |
Exclusion Flag |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where (system = 'Exclusion Flag') |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@ExclusionFlag | The exclusion flag generated by the reference ranges applied and tied to the reported result. There are four exclusion flag values: LX - Low Exclusion HX - High Exclusion EX - Excluded (for exclusions not falling under high or low) and blank for no flag. It may be necessary to translate from other |
Blinding Flag |
Observation.meta
0..1 Meta |
Observation.meta.security.code |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@BlindingFlag | A new code would likely be needed to specifically designate 'blinded'. |
Reported Date and Time |
Observation.issued
0..1 instant |
Observation.issued |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/@ReportedDateTime | |
Test Transaction Type | Determining whether transactions are insert or update is a task for the data consumer. (NOTE: This requires persistent storage to compare current data with data in the incoming file) | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/TransactionType | As per study transaction type (not clear why it happens at both levels - what would it mean to 'delete' at the study level and 'update at the site level?) | |
Toxicity Grade |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where (system = 'Toxicity Grade').code |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/ToxicityGrade/@Value | If there are multiple possible systems, the sponsor will have to determine which interpretation corresponds to toxicity grade |
Toxicity Grade Code List ID |
Observation.interpretation
0..* CodeableConcept Binding: ObservationInterpretation extensible |
Observation.interpretation.coding.where (system = 'Toxicity Grade') |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/ToxicityGrade/@CodeListID | May need to translate the URI to a CDISC Code List id |
Reported Result Type (C=coded; N=numeric; T=text; R=range; G = GT; L = LT) | Determine from the field in which the result resides. valueCodeableConcept vs. valueQuantity vs. valueString Greater than and less than can be determined by valueQuantity.qualifier | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/@ResultType | ||
Text Result |
Observation.valueCodeableConcept
0..1 CodeableConcept obs-7 |
Observation.valueCodeableConcept.text |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/TextResult/@Value | |
Text Result Code List ID |
Observation.valueCodeableConcept
0..1 CodeableConcept obs-7 |
Observation.valueCodeableConcept.coding.system |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/TextResult/@CodeListID | May need to convert from URI to CDISC-recognized 'ID' |
Conventional Numeric Result |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Value | If the reported result isn't in conventional units, can use the PQ-translation extension to convey a translation. |
Reported Numeric Result |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Value | |
SI Numeric Result |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Value | If the reported result isn't in SI units, can use the PQ-translation extension to convey a translation. |
Conventional Numeric Result Precision |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Precision | Determine the precision from the value. Precision is implicitly determined from the attribute Observation/valueQuantity/value/@value If the reported result isn't in conventional units, can use the PQ-translation extension to convey a translation. |
Reported Numeric Result Precision |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Precision | Determine the precision from the value. Precision is implicitly determined from the attribute Observation/valueQuantity/value/@value |
SI Numeric Result Precision |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.value |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/NumericResult/@Precision | Determine the precision from the value. Precision is implicitly determined from the attribute Observation/valueQuantity/value/@value If the reported result isn't in SI units, can use the PQ-translation extension to convey a translation. |
Conventional Reference Range Low |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.low.value Observation.referenceRange.low.unit |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeLow | Will need to combine value and unit into a string. If the reported units aren't 'conventional, can use the PQ-translation extension on Quantity to convey a translation. |
Reported Reference Range Low |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.low.value Observation.referenceRange.low.unit |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeLow | Will need to combine value and unit into a string. |
SI Reference Range Low |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.low.value Observation.referenceRange.low.unit |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeLow | Will need to combine value and unit into a string. If the reported units aren't SI, can use the PQ-translation extension on Quantity to convey a translation. |
Conventional Reference Range High |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.high.value Observation.referenceRange.high.unit |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeHigh | Will need to combine value and unit into a string. If the reported units aren't 'conventional, can use the PQ-translation extension on Quantity to convey a translation. |
Reported Reference Range High |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.high.value Observation.referenceRange.high.unit |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeHigh | Will need to combine value and unit into a string. |
SI Reference Range High |
Observation.referenceRange
0..* BackboneElement |
Observation.referenceRange.high.value Observation.referenceRange.high.unit |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultReferenceRange/@ReferenceRangeHigh | Will need to combine value and unit into a string. If the reported units aren't SI, can use the PQ-translation extension on Quantity to convey a translation. |
Conventional Units |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.code Observation.valueQuantity.extension('PQ-translation').code |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@Value | If the reported units are not the same as conventional, can convey with the translation extension. Translation to CDISC terminology may be required. |
Reported Units |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.code |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@Value | This may require translation to CDISC terminology |
SI Units |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.code Observation.valueQuantity.extensoin('PQ-translation').code |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@Value | If the reported units are not SI units, can convey with the translation extension. Translation to CDISC terminology may be required. |
Conventional Units Code List ID |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.system |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@CodeListID | |
Reported Units Code List ID |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.system |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@CodeListID | |
SI Units Code List ID |
Observation.valueQuantity
0..1 Quantity obs-7 |
Observation.valueQuantity.system |
/GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultUnits/@CodeListID | |
Record Extension Type | Populate with a default value, depending on the type of data being transmitted. E.g., "BASE" |
|||
Result Class | In FHIR, the value will always be 'reported', with the ability to convey translations in an extension. Nothing will differentiate whether a translation is considered 'conventional' or not, so if there are multiple translations present and the receiver can't figure it out by looking, an additional extension may be necessary to differentiate. This can sometimes also be inferred from the Observation.code. | /GTP/Study/Site/Investigator/Subject/Visit/Accession/BaseSpecimen/BaseBattery/BaseTest/BaseResult/SingleResult/ResultClass/@Value | ||
Model Version | Populate with a default value. | /GTP/@ModelVersion | The version of FHIR in use is conveyed using Resource.meta.profile | |
File Creation Date and Time | Pull from the message wrapper. (file creation date) | /GTP/@CreationDateTime | Bundle.timestamp | |
Transaction Type | No mitigation. If required, fill with a default value. | /GTP/TransactionType | As per study.transaction | |
Transmission Source ID | Pull from the message wrapper. | /GTP/TransmissionSource/@ID | MessageHeader.source.endpoint if using messaging, otherwise determined out of band based on sender authentication process | |
Transmission Source Name | Pull from the message wrapper. | /GTP/TransmissionSource/@Name | MessageHeader.source.name if using messaging, otherwise determined out of band based on sender authentication process |