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
|
#include "filter_splice.h"
#include "filter.h"
void FilterSplice::init() {
for(int i=0; i<n_dataDim; i++) dir.add_item(dataDimLabel[i]);
dir.add_item(ODIN_NONE_STR); // default to throw error when no dim is given
dir.set_actual(dir.n_items()-1);
dir.set_cmdline_option("dir").set_description("dimension of the data to be spliced");
append_arg(dir,"dir");
}
bool FilterSplice::process(FileIO::ProtocolDataMap& pdmap) const {
Log<Filter> odinlog(c_label(),"process");
if(dir==ODIN_NONE_STR) {
ODINLOG(odinlog,errorLog) << "no dimension given for splice" << STD_endl;
return false;
}
FileIO::ProtocolDataMap spliced_pdmap;
for(FileIO::ProtocolDataMap::const_iterator it=pdmap.begin();it!=pdmap.end();it++) {
const Protocol& prot=it->first;
const Data<float,4>& data=it->second;
STD_string serDesc;
int serNum;
prot.study.get_Series(serDesc,serNum);
if(serDesc!="") serDesc+="_";
TinyVector<int,4> shape(data.shape());
int nsplice = shape(dir);
TinyVector<int,4> newshape(shape);
newshape(dir)=1;
direction protdir=direction(3-dir);
dvector offsetvec;
if(dir==sliceDim && prot.geometry.get_Mode()==slicepack) offsetvec=prot.geometry.get_sliceOffsetVector(); // better accuracy in slicepack mode
float origoffset=0.0;
float voxelsize=0.0;
if(dir!=timeDim) {
origoffset=prot.geometry.get_offset(protdir);
voxelsize=FileFormat::voxel_extent(prot.geometry, protdir, nsplice);
ODINLOG(odinlog,normalDebug) << "origoffset/voxelsize=" << origoffset << "/" << voxelsize << STD_endl;
}
for(int isplice=0; isplice<nsplice; isplice++) {
Protocol protcopy(prot); // writable copy
Data<float,4> spliced(newshape);
TinyVector<int,4> lowerBounds;
TinyVector<int,4> upperBounds;
for(int i=0; i<4; i++) {
lowerBounds(i)=0;
upperBounds(i)=shape(i)-1;
}
lowerBounds(dir)=upperBounds(dir)=isplice;
spliced=data(RectDomain<4>(lowerBounds, upperBounds));
// Adjust series description
protcopy.study.set_Series(serDesc+dataDimLabel[dir]+itos(isplice,nsplice-1),serNum);
// Adjusting protocol
if(dir==timeDim) {
protcopy.seqpars.set_NumOfRepetitions(1);
protcopy.seqpars.set_AcquisitionStart(prot.seqpars.get_AcquisitionStart()+isplice*prot.seqpars.get_RepetitionTime());
} else {
if(dir==sliceDim) protcopy.geometry.set_nSlices(1);
protcopy.seqpars.set_MatrixSize(protdir,1);
protcopy.geometry.set_FOV(protdir,voxelsize);
if(offsetvec.size()) {
protcopy.geometry.set_offset(protdir, offsetvec[isplice]);
} else {
float ioffset=float(isplice)-0.5*float(nsplice-1);
protcopy.geometry.set_offset(protdir, origoffset+ioffset*voxelsize);
}
}
spliced_pdmap[protcopy].reference(spliced);
}
}
pdmap=spliced_pdmap;
return true;
}
|