File: filter_range.h

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 (91 lines) | stat: -rw-r--r-- 3,239 bytes parent folder | download | duplicates (3)
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
/***************************************************************************
                          filter_range.h  -  description
                             -------------------
    begin                : Tue Jan 29 2008
    copyright            : (C) 2000-2021 by Thies Jochimsen
    email                : thies@jochimsen.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef FILTER_RANGE_H
#define FILTER_RANGE_H

#include <odindata/filter_step.h>


bool str2range(const STD_string& str, Range& range, int srcsize);
STD_string str2range_usage();


template<int Dir>
class FilterRange : public FilterStep {

  LDRstring range;

  STD_string label() const {return STD_string(1,STD_string(dataDimLabel[Dir])[0])+"range";} // Use only 1st letter
  STD_string description() const {return "Select range in "+STD_string(dataDimLabel[Dir])+" direction";}

  bool process(Data<float,4>& data, Protocol& prot) const {
    Range all=Range::all();

    Range rng[4];
    for(int i=0; i<4; i++) rng[i]=Range::all();

    if(!str2range(range,rng[Dir],data.extent(Dir))) return false;

    TinyVector<int,4> newshape=data.shape();
    int oldsize=newshape(Dir);

    newshape(Dir)=rng[Dir].length();


    float fovfraction=secureDivision(rng[Dir].last()-rng[Dir].first()+1, oldsize);

    float offsetfactor=secureDivision(0.5*(rng[Dir].first()+rng[Dir].last()), oldsize)-0.5;

    Data<float,4> data_copy(data.copy());
    data.resize(newshape);
    data(all,all,all,all)=data_copy(rng[timeDim],rng[sliceDim],rng[phaseDim],rng[readDim]);

    // adapt protocol
    int stride=rng[Dir].stride();
    if(Dir==timeDim) {
      prot.seqpars.set_NumOfRepetitions(newshape(timeDim));
      if(stride>1) prot.seqpars.set_RepetitionTime(prot.seqpars.get_RepetitionTime()*stride);

    } else {

      direction geodir=direction(3-Dir);
      prot.geometry.set_offset(geodir,prot.geometry.get_offset(geodir)+offsetfactor*prot.geometry.get_FOV(geodir));
      prot.geometry.set_FOV(geodir,fovfraction*prot.geometry.get_FOV(geodir));
      prot.seqpars.set_MatrixSize(geodir,newshape(Dir));

      if(Dir==sliceDim) {
        if(prot.geometry.get_Mode()==slicepack) {
          prot.geometry.set_nSlices(newshape(sliceDim));
          if(stride>1) prot.geometry.set_sliceDistance(prot.geometry.get_sliceDistance()*stride);
          prot.seqpars.set_MatrixSize(sliceDirection,1);
        }
      }
    }

    return true;
  }

  FilterStep*  allocate() const {return new FilterRange<Dir>();}

  void init() {
    range.set_description(str2range_usage());
    append_arg(range,"range");
  }
};

#endif