File Coverage

blib/lib/PDL/IO/Dcm/Plugins/Primitive.pm
Criterion Covered Total %
statement 12 38 31.5
branch 0 6 0.0
condition n/a
subroutine 4 7 57.1
pod 3 3 100.0
total 19 54 35.1


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2              
3             package PDL::IO::Dcm::Plugins::Primitive;
4 1     1   819 use Exporter;
  1         2  
  1         32  
5 1     1   3 use PDL;
  1         1  
  1         4  
6 1     1   2231 use strict;
  1         1  
  1         15  
7 1     1   3 use PDL::NiceSlice;
  1         5  
  1         4  
8             #use 5.10.0;
9              
10              
11             our @ISA=qw/Exporter/;
12             our @EXPORT_OK=qw/populate_header setup_dcm/;
13              
14             sub setup_dcm {
15 0     0 1   my $opt=shift;
16 0 0         $opt={} unless (ref($opt) eq 'HASH'); # ensure hash context
17             # split on series number by default
18 0           $$opt{id}=\&PDL::IO::Dcm::sort_series;
19 0           $$opt{dim_order}=[0,1];
20 0           $$opt{sort}=\&populate_header;
21 0           $$opt{duplicates}=\&handle_duplicates;
22 0           $$opt{delete_raw}=1; # deletes the raw_dicom structure after parsing
23 0           $$opt{Dimensions}=[qw/x y InstanceNumber n/];
24 0           $opt;
25             }
26              
27             sub populate_header {
28 0     0 1   my $dicom =shift;
29 0           my $piddle=shift;
30 0           my $in=$dicom->getValue('InstanceNumber');
31 0           $piddle->hdr->{dcm_key}=$piddle->hdr->{dicom}->{'SOP Instance UID'};
32 0           my $pos=pdl(ushort,$in-1,0);
33 0           $piddle->hdr->{dim_idx}=$pos;
34 0           return $in;
35             }
36              
37             sub handle_duplicates {
38 0     0 1   my $stack=shift;
39 0           my $dcm=shift;
40             #my $str=',,'.$dcm->hdr->{dim_idx}->(0);
41             #say "duplicate ",$dcm->hdr->{dim_idx}, $stack->info;
42 0           my $idx=$dcm->hdr->{dim_idx};
43 0           my $n=$idx(1);
44             #say "$n - idx: ",$idx->info;
45             # increase the second index until we find an empty space
46             # data flow should store
47 0           do {
48             #say "$idx ",$stack(list ($idx);-),"; ";
49             #print "$idx n $n exists? ",$stack(list($idx);-),"\n";
50             #say $n," >= shape ",$stack->shape->(-1);
51 0           $n++;
52 0 0         if (sclr $stack->shape->(-1) <= ($n)) {
53             #say "growing $n",$stack->shape->(-1);
54 0           $stack=$stack->mv(-1,0)->append(0)->mv(0,-1);
55             }
56 0 0         barf "This is impossible $n, $idx, ",$stack($idx(0),;-) if $n>2;
57             } while ($stack(list ($idx)));
58             #say "new dim_dix ",$dcm->hdr->{dim_idx}, $stack->info;
59             #$dcm->hdr->{dim_idx}=
60             #$stack->(,,list($dcm->hdr->{dim_idx}),$n).=$dcm;
61             #"This entry (". $dcm->hdr->{dim_idx}->($order).
62             #max ($data{$pid}->(,,list $dcm->hdr->{dim_idx}->($order))).
63             #") is already set! This should not happen, please file a bug report!\n";
64 0           $stack;
65             }
66             =head1 General
67              
68             This module provides simple splitting based on intance number and should be used
69             as template when writing more specific plugin modules.
70              
71             The setup_dcm creates a template options hash.
72              
73             =head1 FUNCTIONS
74              
75             =head2 handle_duplicates
76              
77             If more data with the same series/instance number arrive -- can happen -- the second
78             index is incremented until a free slot is found. It is up to the user to sort the mess,
79             i.e. write/use a more sophisticated plugin.
80              
81             =head2 populate_header
82              
83             Here happens the vendor/modallity specific stuff like parsing private fields.
84             It is required to set the IcePos and dcm_key fields in the piddle header. dcm_key
85             serves mainly as a unique identifier, IcePos is an index piddle.
86              
87             =head2 setup_dcm
88              
89             sets useful options for this modality. Should accept a hash ref and return one.
90              
91             =head2 sort_protid
92              
93             alternative to split based on lProtID (matches raw data key)
94              
95             =cut
96              
97             1;