Convert-Pheno
view release on metacpan or search on metacpan
lib/Convert/Pheno/CLI/Args.pm view on Meta::CPAN
my %supported_for_route =
map { $_ => 1 } @{ $conversion_spec->{entities}{supported} };
for my $entity (@entity_list) {
$usage_error->(
"The entity <$entity> is not supported by conversion <$method>"
) unless $supported_for_route{$entity};
}
}
$usage_error->("The conversion <$method> does not support --stream")
if $stream && !$conversion_spec->{streaming};
my $id = time . substr( "00000$$", -5 );
my %data = (
out_dir => $out_dir,
in_textfile => 1,
method => $method,
sql2csv => $sql2csv ? 1 : 0,
exposures_file => $exposures_file,
search => $search,
lib/Convert/Pheno/Operations.pm view on Meta::CPAN
die "Public conversion registry <$registry_file> must define HTTP request fields\n"
unless ref( $registry->{http_request_fields} ) eq 'HASH';
my %PUBLIC_CONVERSION = %{ $registry->{conversions} };
for my $name ( keys %PUBLIC_CONVERSION ) {
my $spec = $PUBLIC_CONVERSION{$name};
die "Conversion <$name> must contain an object specification\n"
unless ref($spec) eq 'HASH';
for my $field (qw(source target operation pipeline resources entities streaming http_enabled)) {
die "Conversion <$name> is missing registry field <$field>\n"
unless exists $spec->{$field};
}
die "Conversion <$name> has an invalid operation type\n"
unless $spec->{operation} =~ /\A(?:bundle|direct|pipeline)\z/;
die "Conversion <$name> must define a non-empty pipeline\n"
unless ref( $spec->{pipeline} ) eq 'ARRAY' && @{ $spec->{pipeline} };
die "Conversion <$name> must define SQLite resource requirements\n"
unless ref( $spec->{resources} ) eq 'HASH'
lib/Convert/Pheno/Pipeline.pm view on Meta::CPAN
our @EXPORT_OK = qw(run_conversion_pipeline);
sub run_conversion_pipeline {
my ($converter) = @_;
my $request = Convert::Pheno::ConversionRequest->from_converter($converter);
my $spec = $request->spec;
die "Conversion <$spec->{name}> is not a compound pipeline\n"
unless $spec->{operation} eq 'pipeline';
die "Conversion <$spec->{name}> does not support streaming\n"
if $converter->{stream} && !$spec->{streaming};
my $execution = Convert::Pheno::ExecutionContext->new(
{ request => $request }
);
# OMOP file input is already emitted one participant at a time. Preserve
# that bounded-memory path while applying the downstream BFF-to-PXF stage
# in the output sink rather than materializing the full BFF intermediate.
if ( $spec->{name} eq 'omop2pxf' && !$request->has_data ) {
my ( $stage, $arguments ) = $execution->begin_next_stage;
share/schema/public-conversions.json view on Meta::CPAN
]
},
"conversions": {
"bff2csv": {
"source": "beacon",
"target": "csv",
"operation": "direct",
"pipeline": ["bff2csv"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"bff2jsonf": {
"source": "beacon",
"target": "jsonf",
"operation": "direct",
"pipeline": ["bff2jsonf"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"bff2jsonld": {
"source": "beacon",
"target": "jsonld",
"operation": "direct",
"pipeline": ["bff2jsonld"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"bff2omop": {
"source": "beacon",
"target": "omop",
"operation": "direct",
"pipeline": ["bff2omop"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"bff2pxf": {
"source": "beacon",
"target": "pxf",
"operation": "direct",
"pipeline": ["bff2pxf"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"cbioportal2bff": {
"source": "cbioportal",
"target": "beacon",
"operation": "bundle",
"pipeline": ["cbioportal2bff"],
"resources": { "sqlite": true },
"entities": { "default": ["individuals"], "supported": ["individuals", "biosamples", "datasets", "cohorts"], "primary": "individuals" },
"streaming": false,
"http_enabled": false
},
"cbioportal2omop": {
"source": "cbioportal",
"target": "omop",
"operation": "pipeline",
"pipeline": ["cbioportal2bff", "bff2omop"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"cbioportal2pxf": {
"source": "cbioportal",
"target": "pxf",
"operation": "pipeline",
"pipeline": ["cbioportal2bff", "bff2pxf"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"cdiscodm2bff": {
"source": "cdisc-odm",
"target": "beacon",
"operation": "bundle",
"pipeline": ["cdiscodm2bff"],
"resources": { "sqlite": true },
"entities": { "default": ["individuals"], "supported": ["individuals", "datasets", "cohorts"], "primary": "individuals" },
"streaming": false,
"http_enabled": false
},
"cdiscodm2omop": {
"source": "cdisc-odm",
"target": "omop",
"operation": "pipeline",
"pipeline": ["cdiscodm2bff", "bff2omop"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"cdiscodm2pxf": {
"source": "cdisc-odm",
"target": "pxf",
"operation": "pipeline",
"pipeline": ["cdiscodm2bff", "bff2pxf"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"datasetjson2bff": {
"source": "dataset-json",
"target": "beacon",
"operation": "bundle",
"pipeline": ["datasetjson2bff"],
"resources": { "sqlite": false },
"entities": { "default": ["individuals"], "supported": ["individuals", "datasets", "cohorts"], "primary": "individuals" },
"streaming": false,
"http_enabled": false
},
"datasetjson2omop": {
"source": "dataset-json",
"target": "omop",
"operation": "pipeline",
"pipeline": ["datasetjson2bff", "bff2omop"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"datasetjson2pxf": {
"source": "dataset-json",
"target": "pxf",
"operation": "pipeline",
"pipeline": ["datasetjson2bff", "bff2pxf"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"datasetxml2bff": {
"source": "dataset-xml",
"target": "beacon",
"operation": "bundle",
"pipeline": ["datasetxml2bff"],
"resources": { "sqlite": false },
"entities": { "default": ["individuals"], "supported": ["individuals", "datasets", "cohorts"], "primary": "individuals" },
"streaming": false,
"http_enabled": false
},
"datasetxml2omop": {
"source": "dataset-xml",
"target": "omop",
"operation": "pipeline",
"pipeline": ["datasetxml2bff", "bff2omop"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"datasetxml2pxf": {
"source": "dataset-xml",
"target": "pxf",
"operation": "pipeline",
"pipeline": ["datasetxml2bff", "bff2pxf"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"fhir2bff": {
"source": "fhir",
"target": "beacon",
"operation": "bundle",
"pipeline": ["fhir2bff"],
"resources": { "sqlite": false },
"entities": { "default": ["individuals"], "supported": ["individuals", "biosamples", "datasets", "cohorts"], "primary": "individuals" },
"streaming": false,
"http_enabled": true
},
"fhir2omop": {
"source": "fhir",
"target": "omop",
"operation": "pipeline",
"pipeline": ["fhir2bff", "bff2omop"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"fhir2pxf": {
"source": "fhir",
"target": "pxf",
"operation": "pipeline",
"pipeline": ["fhir2bff", "bff2pxf"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"csv2bff": {
"source": "csv",
"target": "beacon",
"operation": "bundle",
"pipeline": ["csv2bff"],
"resources": { "sqlite": true },
"entities": { "default": ["individuals"], "supported": ["individuals", "datasets", "cohorts"], "primary": "individuals" },
"streaming": false,
"http_enabled": false
},
"csv2omop": {
"source": "csv",
"target": "omop",
"operation": "pipeline",
"pipeline": ["csv2bff", "bff2omop"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"csv2pxf": {
"source": "csv",
"target": "pxf",
"operation": "pipeline",
"pipeline": ["csv2bff", "bff2pxf"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"omop2bff": {
"source": "omop",
"target": "beacon",
"operation": "bundle",
"pipeline": ["omop2bff"],
"resources": { "sqlite": true },
"entities": { "default": ["individuals"], "supported": ["individuals", "biosamples", "datasets", "cohorts"], "primary": "individuals" },
"streaming": true,
"http_enabled": true
},
"omop2pxf": {
"source": "omop",
"target": "pxf",
"operation": "pipeline",
"pipeline": ["omop2bff", "bff2pxf"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"openehr2bff": {
"source": "openehr",
"target": "beacon",
"operation": "bundle",
"pipeline": ["openehr2bff"],
"resources": { "sqlite": false },
"entities": { "default": ["individuals"], "supported": ["individuals", "datasets", "cohorts"], "primary": "individuals" },
"streaming": false,
"http_enabled": true
},
"openehr2pxf": {
"source": "openehr",
"target": "pxf",
"operation": "pipeline",
"pipeline": ["openehr2bff", "bff2pxf"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"pxf2bff": {
"source": "pxf",
"target": "beacon",
"operation": "bundle",
"pipeline": ["pxf2bff"],
"resources": { "sqlite": true },
"entities": { "default": ["individuals"], "supported": ["individuals", "biosamples", "datasets", "cohorts"], "primary": "individuals" },
"streaming": false,
"http_enabled": true
},
"pxf2csv": {
"source": "pxf",
"target": "csv",
"operation": "direct",
"pipeline": ["pxf2csv"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"pxf2jsonf": {
"source": "pxf",
"target": "jsonf",
"operation": "direct",
"pipeline": ["pxf2jsonf"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"pxf2jsonld": {
"source": "pxf",
"target": "jsonld",
"operation": "direct",
"pipeline": ["pxf2jsonld"],
"resources": { "sqlite": false },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"pxf2omop": {
"source": "pxf",
"target": "omop",
"operation": "pipeline",
"pipeline": ["pxf2bff", "bff2omop"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": true
},
"redcap2bff": {
"source": "redcap",
"target": "beacon",
"operation": "bundle",
"pipeline": ["redcap2bff"],
"resources": { "sqlite": true },
"entities": { "default": ["individuals"], "supported": ["individuals", "datasets", "cohorts"], "primary": "individuals" },
"streaming": false,
"http_enabled": false
},
"redcap2omop": {
"source": "redcap",
"target": "omop",
"operation": "pipeline",
"pipeline": ["redcap2bff", "bff2omop"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
},
"redcap2pxf": {
"source": "redcap",
"target": "pxf",
"operation": "pipeline",
"pipeline": ["redcap2bff", "bff2pxf"],
"resources": { "sqlite": true },
"entities": { "default": [], "supported": [], "primary": null },
"streaming": false,
"http_enabled": false
}
}
}
t/15-convertpheno-orchestration.t view on Meta::CPAN
my ( undef, $tmp_file ) = tempfile();
my $convert = Convert::Pheno->new(
{
method => 'omop2bff',
out_file => $tmp_file,
in_textfile => 0,
}
);
$convert->{omop_cli} = 1;
my $stream = Convert::Pheno::_dispatcher_open_stream_out($convert);
ok( $stream->{fh}, '_dispatcher_open_stream_out opens output file in streaming mode' );
close $stream->{fh};
}
{
my $convert = Convert::Pheno->new(
{
method => 'bff2pxf',
in_textfile => 0,
data => { inline => 1 },
}
t/23-cli-help.t view on Meta::CPAN
'-o', 'pxf', 'output.json' ],
[ 'rejects comma-separated entities', qr/space-separated list/,
'-ipxf', 't/pxf2bff/in/pxf.json', '-obff',
'--entities', 'individuals,biosamples' ],
[ 'rejects unknown BFF entities', qr/Unsupported entity <unknown>/,
'-ipxf', 't/pxf2bff/in/pxf.json', '-obff', '--entities', 'unknown' ],
[ 'rejects entity selection for non-BFF output',
qr/<--entities> is only valid with BFF output/,
'-ipxf', 't/pxf2bff/in/pxf.json', '-opxf', 'output.json',
'--entities', 'individuals' ],
[ 'rejects streaming for non-OMOP input',
qr/<--stream> is only valid with <-iomop> and <-obff>/,
'-ipxf', 't/pxf2bff/in/pxf.json', '-obff', 'output.json', '--stream' ],
[ 'rejects unsupported openEHR to OMOP output',
qr/openEHR input path currently supports only BFF or PXF output/,
'-i', 'openehr', 't/openehr2bff/in/gecco_personendaten_patient.json',
'-o', 'omop', '--ohdsi-db' ],
[ 'rejects invalid default vital status values', qr/Unsupported value <MISSING>/,
'-ibff', 't/bff2pxf/in/individuals.json', '-opxf', 'output.json',
'--default-vital-status', 'MISSING' ],
[ 'rejects malformed output-name overrides', qr/Invalid <--out-name> value/,
t/27-operation-registry.t view on Meta::CPAN
[ 'fhir2bff', 'bff2pxf' ],
'registry defines FHIR to PXF as a compound conversion'
);
is_deeply(
conversion_spec('fhir2omop')->{pipeline},
[ 'fhir2bff', 'bff2omop' ],
'registry defines FHIR to OMOP as a compound conversion'
);
my $omop_to_bff = conversion_spec('omop2bff');
ok( $omop_to_bff->{streaming}, 'registry defines streaming capability' );
is_deeply(
$omop_to_bff->{entities}{supported},
[ 'individuals', 'biosamples', 'datasets', 'cohorts' ],
'registry defines supported Beacon entities'
);
ok( is_http_conversion('pxf2bff'), 'registry exposes in-memory PXF conversion over HTTP' );
ok( !is_http_conversion('redcap2bff'), 'registry keeps file-based REDCap conversion on the CLI' );
my $http_fields = http_request_fields();
ok(
( run in 1.561 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )