00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef FILTER_RANGE_H
00019 #define FILTER_RANGE_H
00020
00021 #include <odindata/filter.h>
00022
00023
00024 bool str2range(const STD_string& str, Range& range, int srcsize);
00025
00026
00027 template<int Dir>
00028 class FilterRange : public FilterStep {
00029
00030 JDXstring range;
00031
00032 STD_string label() const {return STD_string(1,STD_string(dataDimLabel[Dir])[0])+"range";}
00033 STD_string description() const {return "Select range in "+STD_string(dataDimLabel[Dir])+" direction";}
00034
00035 bool process(Data<float,4>& data, Protocol& prot) const {
00036 Range all=Range::all();
00037
00038 Range rng[4];
00039 for(int i=0; i<4; i++) rng[i]=Range::all();
00040
00041 if(!str2range(range,rng[Dir],data.extent(Dir))) return false;
00042
00043 TinyVector<int,4> newshape=data.shape();
00044 newshape(Dir)=rng[Dir].length();
00045
00046 float fovfraction=secureDivision(rng[Dir].last()-rng[Dir].first()+1, data.shape()[Dir]);
00047
00048 float offsetfactor=secureDivision(0.5*(rng[Dir].first()+rng[Dir].last()), data.shape()[Dir])-0.5;
00049
00050 Data<float,4> data_copy(data.copy());
00051 data.resize(newshape);
00052 data(all,all,all,all)=data_copy(rng[timeDim],rng[sliceDim],rng[phaseDim],rng[readDim]);
00053
00054
00055 int stride=rng[Dir].stride();
00056 if(Dir==timeDim) {
00057 prot.seqpars.set_NumOfRepetitions(newshape(timeDim));
00058 if(stride>1) prot.seqpars.set_RepetitionTime(prot.seqpars.get_RepetitionTime()*stride);
00059
00060 } else {
00061
00062 direction geodir=direction(3-Dir);
00063 prot.geometry.set_offset(geodir,prot.geometry.get_offset(geodir)+offsetfactor*prot.geometry.get_FOV(geodir));
00064 prot.geometry.set_FOV(geodir,fovfraction*prot.geometry.get_FOV(geodir));
00065 prot.seqpars.set_MatrixSize(geodir,newshape(Dir));
00066
00067 if(Dir==sliceDim) {
00068 if(prot.geometry.get_Mode()==slicepack) {
00069 prot.geometry.set_nSlices(newshape(sliceDim));
00070 if(stride>1) prot.geometry.set_sliceDistance(prot.geometry.get_sliceDistance()*stride);
00071 prot.seqpars.set_MatrixSize(sliceDirection,1);
00072 }
00073 }
00074 }
00075
00076 return true;
00077 }
00078
00079 FilterStep* allocate() const {return new FilterRange<Dir>();}
00080
00081 void init() {
00082 range.set_description("Single value or range, optionally with increment (e.g. 1-10:3)");
00083 append_arg(range,"range");
00084 }
00085 };
00086
00087 #endif