File: filter_reslice.cpp

package info (click to toggle)
odin 2.0.5-8
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,196 kB
  • sloc: cpp: 62,638; sh: 4,541; makefile: 779
file content (148 lines) | stat: -rw-r--r-- 4,925 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include "filter_reslice.h"


bool swapdim(Data<float,4>& data, Geometry& geo,const direction newread,const direction newphase,const direction newslice,const int newread_mult,const int newphase_mult,const int newslice_mult) {
  Log<Filter> odinlog("","swapdim");

  ODINLOG(odinlog,normalDebug) << "newread/newphase/newslice=" << newread << "/" << newphase << "/" << newslice << STD_endl;

  // Checking input
  if(newread==newphase || newread==newslice || newphase==newslice) {
    ODINLOG(odinlog,errorLog) << "Direction used more than once: newread/newphase/newslice=" << newread << "/" << newphase << "/" << newslice << STD_endl;
    return false;
  }


  const dvector vects[n_directions]={geo.get_readVector(),geo.get_phaseVector(),geo.get_sliceVector()};
  double fov[n_directions];
  //store i,j and k of the image coordinate system in scanner coordinate system

  ODINLOG(odinlog,normalDebug) << "get_readVector:" << vects[readDirection] << " => " << (vects[newread]*newread_mult).printbody() << STD_endl;
  ODINLOG(odinlog,normalDebug) << "get_phaseVector:" << vects[phaseDirection] << " => " << (vects[newphase]*newphase_mult).printbody() << STD_endl;
  ODINLOG(odinlog,normalDebug) << "get_sliceVector:" << vects[sliceDirection] << " => " << (vects[newslice]*newslice_mult).printbody() << STD_endl;

  //switch to 3d mode (we cannot deal with slice gaps)
  geo.set_Mode(voxel_3d);

  //get the size of the image
  for(direction i=readDirection;i<n_directions;i=direction(i+1))
    fov[i]=geo.get_FOV(i);

  //transpose the data (data.transposeSelf(0,n_directions-sliceDirection,n_directions-phaseDirection,n_directions-readDirection) would do nothing
  data.transposeSelf(
      0,
      n_directions-newslice,
      n_directions-newphase,
      n_directions-newread
  );
  geo.set_orientation_and_offset(
      vects[newread]*newread_mult,
      vects[newphase]*newphase_mult,
      vects[newslice]*newslice_mult,
      geo.get_center()
  );

  geo.set_FOV(readDirection,fov[newread]);
  geo.set_FOV(phaseDirection,fov[newphase]);
  geo.set_FOV(sliceDirection,fov[newslice]);

  if(newread_mult<0)data.reverseSelf(3);
  if(newphase_mult<0)data.reverseSelf(2);
  if(newslice_mult<0)data.reverseSelf(1);

  return true;
}

/////////////////////////////////////////////////////////////////////////////

void FilterSwapdim::init(){
  newread.set_description("[rps][-]");
  newphase.set_description("[rps][-]");
  newslice.set_description("[rps][-]");

  append_arg(newslice,"slice");
  append_arg(newphase,"phase");
  append_arg(newread,"read");
}


bool FilterSwapdim::process(Data<float,4>& data, Protocol& prot)const{
  direction read,phase,slice;

  int swap[3];
  if(! (selChannel( newslice,slice,swap[0]) && selChannel( newphase,phase,swap[1]) && selChannel(newread,read,swap[2])) ) return false;

  return swapdim(data,prot.geometry,read,phase,slice,swap[2],swap[1],swap[0]);
}


bool FilterSwapdim::selChannel(STD_string name, direction &dir, int& sign){
  Log<Filter> odinlog("FilterSwapdim","selChannel");

  sign=1;
  dir=readDirection;
  bool result=true;
  if(name.length()>0) {
    size_t minus=name.find('-'),plus=name.find('+');
    if(plus!=STD_string::npos)name.erase(plus,1);
    else if(minus!=STD_string::npos){
      name.erase(minus,1);
      sign=-1;
    }
    if(name[0]=='r')dir=readDirection;
    else if(name[0] == 'p')dir=phaseDirection;
    else if(name[0] == 's')dir=sliceDirection;
    else result=false;
  } else {
    result=false;
  }

  if(!result) {
    ODINLOG(odinlog,errorLog) << "Error parsing direction string >" << name << "<" << STD_endl;
  }

  return result;
}

/////////////////////////////////////////////////////////////////////////////

void FilterReSlice::init(){
  orient.add_item("axial",axial);
  orient.add_item("sagittal",sagittal);
  orient.add_item("coronal",coronal);

  orient.set_description("requested orientation");
  append_arg(orient,"orientation");
}


bool FilterReSlice::process(Data<float,4>& data, Protocol& prot)const{
  sliceOrientation sorient=prot.geometry.get_orientation();

  if(sorient==int(orient)) return true;
  Geometry &geo=prot.geometry;

  switch(int(orient))
  {
  case axial:
    if(sorient == sagittal)
      return swapdim(data,geo,sliceDirection,readDirection,phaseDirection,1,1,1);
    else if(sorient == coronal)
      return swapdim(data,geo,readDirection,sliceDirection,phaseDirection,1,1,-1);
    break;
  case sagittal:
    if(sorient==axial)
      return swapdim(data,geo,phaseDirection,sliceDirection,readDirection,-1,-1,1);
    else if(sorient==coronal)
      return swapdim(data,geo,sliceDirection,phaseDirection,readDirection,-1,1,1);
    break;
  case coronal:
    if(sorient==axial)
      return swapdim(data,geo,readDirection,sliceDirection,phaseDirection,1,-1,1);
    else if(sorient==sagittal)
      return swapdim(data,geo,sliceDirection,phaseDirection,readDirection,-1,1,1);
    break;
  }
  return true;
}