Convert-Pheno

 view release on metacpan or  search on metacpan

lib/Convert/Pheno.pm  view on Meta::CPAN

Mapping-file conversions use the Mapping V2 contract and require
C<mappingVersion: 2>; pre-V2 mapping files are rejected.

=head1 METHODS

=head2 new

 my $converter = Convert::Pheno->new(\%arguments);

Creates a converter. C<method> identifies the public conversion method.
In-memory routes receive decoded input under C<data>; file-based routes use
the arguments documented for that conversion.

=head2 Conversion methods

 my $result = $converter->$method;

In-memory conversions return Perl data structures. Streaming and file-output
routes write to their configured destinations and may instead return a
completion status. See the module guide for supported methods, arguments,
multi-entity results, and Python interoperability.

lib/Convert/Pheno/CDISC/SDTM/Normalizer.pm  view on Meta::CPAN

        die "$format_name domain <$domain> was supplied more than once\n"
          if exists $documents{$domain};

        my $current_study = _trim( $dataset->{studyOID} );
        if ( defined $current_study && length $current_study ) {
            $study_oid //= $current_study;
            die "$format_name files contain inconsistent studyOID values <$study_oid> and <$current_study>\n"
              if $current_study ne $study_oid;
        }

        my $decoded = _decode_dataset(
            $dataset,
            $domain,
            $label,
            $format_name,
        );
        $documents{$domain} = {
            dataset => $dataset,
            rows    => $decoded,
            label   => $label,
        };
        push @domain_order, $domain;
    }

    die "$format_name SDTM input requires exactly one <DM> dataset\n"
      unless exists $documents{DM};

    my ( %subjects, @subject_order );
    for my $row ( @{ $documents{DM}{rows} } ) {

lib/Convert/Pheno/CDISC/SDTM/Normalizer.pm  view on Meta::CPAN

        die "$format_name domain <$domain> contains duplicate column <$name>\n"
          if $seen{$name}++;
        push @names, $name;
    }

    my $rows = $dataset->{rows} || [];
    die "$format_name domain <$domain> declares $dataset->{records} records but contains "
      . scalar( @{$rows} ) . " rows\n"
      unless $dataset->{records} == @{$rows};

    my @decoded;
    for my $row_index ( 0 .. $#{$rows} ) {
        my $row = $rows->[$row_index];
        my $number = $row_index + 1;
        die "$format_name domain <$domain> row $number must contain an array\n"
          unless ref($row) eq 'ARRAY';
        die "$format_name domain <$domain> row $number has " . scalar( @{$row} )
          . ' values but ' . scalar(@names) . " columns are defined\n"
          unless @{$row} == @names;

        my %record;

lib/Convert/Pheno/CDISC/SDTM/Normalizer.pm  view on Meta::CPAN

        }

        if ( exists $record{DOMAIN}
            && defined $record{DOMAIN}
            && length( _trim( $record{DOMAIN} ) // q{} )
            && uc( _trim( $record{DOMAIN} ) ) ne $domain )
        {
            die "$format_name domain <$domain> row $number contains DOMAIN <$record{DOMAIN}>\n";
        }

        push @decoded, \%record;
    }

    return \@decoded;
}

sub _validate_value_type {
    my ( $value, $type, $where, $format_name ) = @_;

    return 1 if !defined $value || ( !ref($value) && $value eq q{} );

    if ( $type eq 'integer' ) {
        die "$format_name $where must contain an integer\n"
          unless !ref($value) && looks_like_number($value) && int($value) == $value;

lib/Convert/Pheno/IO/FileIO.pm  view on Meta::CPAN

#########################
#########################
#  SUBROUTINES FOR I/O  #
#########################
#########################

sub _slurp_text {
    my ($file) = @_;

    if ( $file =~ /\.gz$/ ) {
        # Gzipped text has to be decoded explicitly because Path::Tiny only
        # covers plain files. Keep this logic isolated so plain-file semantics
        # stay unchanged elsewhere.
        my $fh = IO::Uncompress::Gunzip->new( $file, MultiStream => 1 )
          or die "Cannot gunzip <$file>: $GunzipError";
        binmode( $fh, ':encoding(UTF-8)' );
        return do { local $/; <$fh> };
    }

    return path($file)->slurp_utf8;
}

t/25-json-bridge.t  view on Meta::CPAN

                    }
                }
            }
        }
    )
);

is( $exit_ok, 0, 'bridge exits successfully for valid payload' );
is( $stderr_ok, q{}, 'bridge keeps stderr empty on success' );

my $decoded = eval { $json->decode($stdout_ok) };
ok( !$@, 'bridge returns valid JSON on success' );
is( $decoded->{id}, 'P0007500', 'bridge returns converted BFF payload' );

my ( $exit_fhir, $stdout_fhir, $stderr_fhir ) = run_bridge(
    $json->encode(
        {
            method => 'fhir2bff',
            data   => load_json_file('t/fhir2bff/in/patient-bundle.json'),
            test   => 1,
        }
    )
);



( run in 2.480 seconds using v1.01-cache-2.11-cpan-bbc515a03b3 )