PDL-IO-Dcm

 view release on metacpan or  search on metacpan

lib/PDL/IO/Dcm/Plugins/MRSSiemens.pm  view on Meta::CPAN

	use PDL::NiceSlice;
	my $self=shift;
	my $opt=shift;
	# we need these modules, return undef otherwise.
	require PDL::Dims || return;
	require PDL::Transform || return;
	PDL::Dims->import(qw/is_equidistant dmin dmax vals hpar dinc initdim dimsize drot idx diminfo /);
	#say "init_dims: ",$self->hdr->{dcm_key};
	#say "init_dims: ",$self->hdr->{dicom}->{Rows} ;
	#say "init_dims: hpar ",hpar($self,'dicom','Rows');
	PDL::Transform->import(qw/t_linear/);
	#say diminfo ($self),$self->hdr->{ascconv}->{sGroupArray_asGroup_1__nSize};
# center=inner(rot*scale,dim/2)+Image Position (Patient)
# xf=t_linear(matrix=>Pixel Scale*$rot->transpose,post=>Image Position (Patient))
	if (hpar($self,'ascconv','sGroupArray_asGroup_1__nSize')){
		warn "Multiple slice groups, support dubious!";
	}
	say "Dims for scan ",$self->hdr->{dicom}->{"Series Number"};
	my $pos_d=zeroes(3);
	my $fov=zeroes(3);
	$fov(0).=hpar($self,'csa','VoiReadoutFoV');
	$fov(1).=hpar($self,'csa','VoiPhaseFoV');
	$fov(2).=hpar($self,'csa','VoiThickness');
	my $t=hpar($self,'csa','VoiInPlaneRotation');
	#$v.=hpar($self,'csa','sSliceArray_asSlice_0__sPosition_dSag') ||0; #x
	$pos_d.=pdl (hpar($self,'csa','VoiPosition')); # ||0; #y
	my $nv=pdl (hpar($self,'csa','VoiOrientation')); # ||0; #y
	my $av=pdl([[0,-$nv(2),$nv(1)],[$nv(2),0,-$nv(0)],[-$nv(1),$nv(0),0]])->squeeze;
	my $srot=identity(3)*cos($t)+sin($t)*$av+(1-cos($t))*$nv->transpose*$nv;
	my $rot=identity($self->ndims);
	say $srot;
	my $s=zeroes(3);
	# This is apparently not so easy to get right ...
	# May be it has to do with phase encoding direction ...
	# or software version ..
	#$s(0).=(hpar($self,'csa','SpectroscopyAcquisitionPhaseColumns')); # ||0; #y
	#$s(1).=(hpar($self,'csa','SpectroscopyAcquisitionPhaseRows')); # ||0; #y
	#$s(0).=(hpar($self,'dicom','Columns')); # ||0; #y
	#$s(1).=(hpar($self,'dicom','Rows')); # ||0; #y
	$s(0).=hpar($self,'ascconv','sSpecPara_lFinalMatrixSizePhase')||1;
	$s(1).=hpar($self,'ascconv','sSpecPara_lFinalMatrixSizeRead')||1;
	$s(2).=hpar($self,'ascconv','sSpecPara_lFinalMatrixSizeSlice')||1;
	#$s(2).=(hpar($self,'csa','SpectroscopyAcquisitionOut-of-planePhaseSteps')); # ||0; #y
	my $pe=hpar($self,'csa','PhaseEncodingDirection');
# Calculate and initialise the transformation
	my @ors=qw/Sag Cor Tra/;
	say $srot;
	$self->hdr->{orientation}=$ors[maximum_ind(abs($srot(2;-)))];  # normal vector lookup

	if ($self->hdr->{orientation} eq 'Tra'){ # transversal slice
		#say $self->hdr->{orientation}. " Orientation";
		$self->hdr->{sl}='z';
		if ($pe eq 'COL'){
			$self->hdr->{ro}='x'; 
			$self->hdr->{pe}='y';
		} else { 
			$self->hdr->{ro}='y'; 
			$self->hdr->{pe}='x';
		}
	}
	if ($self->hdr->{orientation} eq 'Cor'){ # coronal slice
		$self->hdr->{sl}='y';
		if ($pe eq 'COL') {
			$self->hdr->{ro}='x'; 
			$self->hdr->{pe}='z';
		} else { 
			$self->hdr->{ro}='z'; 
			$self->hdr->{pe}='x';
		}
	}
	if ($self->hdr->{orientation} eq 'Sag'){ # sagittal slice
		$self->hdr->{sl}='x';
		if ($pe eq 'COL') {
			$self->hdr->{ro}='y'; 
			$self->hdr->{pe}='z';
		} else { 
			$self->hdr->{ro}='z'; 
			$self->hdr->{pe}='y';
		}
	}
	# Slice groups! Does that make sense?
	if ($$opt{split}) {
		my ($sg,$size)=PDL::IO::Dcm::Plugins::MRISiemens::map_slicegroup($self);
		$s(2)*=$size;
	} else {
		#$s(2)*=$self->hdr->{csa}->{'NumberOfFrames'};
		$s(2)*=$self->hdr->{ascconv}->{'sSliceArray_lSize'};
	}	
	#$s(2).=1 if ($s(2)<1);
	say "FOV $fov matrix $s";
	my $inc_d=zeroes(3);
	$inc_d=$fov/$s;
	#say $srot;
	$rot(2:4,2:4).=$srot;
	#say "FOV $fov matrix $s, pixels $inc_d";
	barf $self->hdr->{dicom}->{'Series Number'},": dims don't fit! $s vs. ",$self->shape->(:4) if any($self->shape->(2:4)-$s);
	#say "Rot: $rot";
	#if ($pe eq 'COL') {
	initdim($self,'c');
	initdim($self,'fid'	,min=>0,inc=>$self->hdr->{ascconv}->{sRXSPEC_alDwellTime_0_},unit=>'us');
	initdim($self,getx($self->hdr),size=>sclr($s(0)),min=>sclr($pos_d(0)),inc=>sclr($inc_d(0)),unit=>'mm');
	initdim($self,gety($self->hdr),size=>sclr($s(1)),min=>sclr($pos_d(1)),inc=>sclr($inc_d(1)),unit=>'mm');
	#} else {
	#initdim($self,getx($self->hdr),size=>$s(0),min=>sclr($pos_d(0)),inc=>sclr($inc_d(0)),unit=>'mm');
	#initdim($self,gety($self->hdr),size=>$s(1),min=>sclr($pos_d(1)),inc=>sclr($inc_d(1)),unit=>'mm');
	#}
	initdim($self,getz($self->hdr),size=>sclr($s(2)),min=>sclr($pos_d(2)),inc=>sclr($inc_d(2)),unit=>'mm',);
	#say "initdim for x,y,z done.";
	#say "after init dim ",(diminfo ($self));
	#say "size $s min $pos_d inc $inc_d rot $rot";
	idx($self,'x',sclr(dimsize($self,'x')/2));
	idx($self,'y',sclr(dimsize($self,'y')/2));
	idx($self,'z',sclr(dimsize($self,'z')/2));
	say "Index x ",idx($self,'x');
	say "Dimsize ",dimsize($self);
	# other dimensions
	for my $n (5..$#{$$opt{MRSSiemens}->{Dimensions}}) { # x,y,z are handled above
		my $dim=$$opt{MRSSiemens}->{Dimensions}->[$n];
		print "Init Dim $dim - $n\n";
		my $str=('(0),' x ($n-2)).','.('(0),' x ($#{$$opt{Dimensions}}-$n));
		#say "$str ";



( run in 0.604 second using v1.01-cache-2.11-cpan-5a3173703d6 )