The Perl and Raku Conference 2025: Greenville, South Carolina - June 27-29 Learn more

use strict;
use autodie;
use feature qw(say);
use Exporter 'import';
our @EXPORT = qw(do_bff2pxf);
my $DEFAULT_timestamp = '1900-01-01T00:00:00Z';
#############
#############
# BFF2PXF #
#############
#############
sub do_bff2pxf {
my ( $self, $data ) = @_;
# Premature return
return unless defined($data);
#########################################
# START MAPPING TO PHENOPACKET V2 TERMS #
#########################################
# We need to shuffle a bit some Beacon v2 properties to be Phenopacket compliant
my $pxf;
# ==
# id
# ==
$pxf->{id} = $self->{test} ? undef : 'phenopacket_id.' . randStr(8);
# =======
# subject
# =======
$pxf->{subject} = {
id => $data->{id},
#alternateIds => [],
#_age => $data->{info}{age}
#timeAtLastEncounter => {},
vitalStatus => { status => 'ALIVE' }
, #["UNKNOWN_STATUS", "ALIVE", "DECEASED"]
sex => uc( $data->{sex}{label} ),
#taxonomy => {}
#_age => $data->{info}{age}
};
for (qw(dateOfBirth karyotypicSex)) {
$pxf->{subject}{$_} = $data->{info}{$_} if exists $data->{info}{$_};
}
# ===================
# phenotypic_features
# ===================
$pxf->{phenotypicFeatures} = [
map {
{
type => $_->{featureType}
#_notes => $_->{notes}
}
} @{ $data->{phenotypicFeatures} }
]
if defined $data->{phenotypicFeatures};
# ============
# measurements
# ============
$pxf->{measurements} = [
map {
{
assay => $_->{assayCode},
#timeObserved => exists $_->{date} ? $_->{date} : undef, # Not valid in v2
value => $_->{measurementValue}
}
} @{ $data->{measures} }
]
if defined $data->{measures}; # Only 1 element at $_->{measurementValue}
# ==========
# biosamples
# ==========
# ===============
# interpretations
# ===============
#$data->{interpretation} = {};
# ========
# diseases
# ========
$pxf->{diseases} =
[ map { { term => $_->{diseaseCode}, onset => $_->{ageOfOnset} } }
@{ $data->{diseases} } ];
# ===============
# medical_actions
# ===============
# **** procedures ****
my @procedures = map {
{
procedure => {
code => $_->{procedureCode},
performed => {
timestamp => exists $_->{dateOfProcedure}
? _map2iso8601( $_->{dateOfProcedure} )
: $DEFAULT_timestamp
}
}
}
} @{ $data->{interventionsOrProcedures} };
# **** treatments ****
my @treatments = map {
{
treatment => {
agent => $_->{treatmentCode},
routeOfAdministration => $_->{routeOfAdministration},
doseIntervals => $_->{doseIntervals}
#performed => { timestamp => exists $_->{dateOfProcedure} ? $_->{dateOfProcedure} : undef}
}
}
} @{ $data->{treatments} };
# Load
push @{ $pxf->{medicalActions} }, @procedures if @procedures;
push @{ $pxf->{medicalActions} }, @treatments if @treatments;
# =====
# files
# =====
# =========
# meta_data
# =========
# Depending on the origion (redcap) , _info and resources may exist
$pxf->{metaData} =
$self->{test} ? undef
: exists $data->{info}{metaData} ? $data->{info}{metaData}
: get_metaData($self);
#######################################
# END MAPPING TO PHENOPACKET V2 TERMS #
#######################################
return $pxf;
}
1;