From 00ed20cc083430c2ec8c1cd8afd58741871b36ed Mon Sep 17 00:00:00 2001
From: Saad Jbabdi <saad@fmrib.ox.ac.uk>
Date: Fri, 15 Aug 2014 12:01:19 +0000
Subject: [PATCH] Added fslselectvols

---
 Makefile         |   8 ++-
 fslselectvols.cc | 179 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 184 insertions(+), 3 deletions(-)
 create mode 100644 fslselectvols.cc

diff --git a/Makefile b/Makefile
index abf96c5..181d6c2 100644
--- a/Makefile
+++ b/Makefile
@@ -6,15 +6,15 @@ PROJNAME = avwutils
 USRINCFLAGS = -I${INC_NEWMAT} -I${INC_PROB} -I${INC_ZLIB}
 USRLDFLAGS = -L${LIB_NEWMAT} -L${LIB_PROB} -L${LIB_ZLIB}
 
-LIBS = -lnewimage -lmiscmaths -lprob -lfslio -lNewNifti -lnewmat -lutils -lniftiio -lznz -lm -lz
+LIBS = -lnewimage -lmiscmaths -lprob -lfslio -lnewmat -lutils -lniftiio -lznz -lm -lz
 
 IOLIBS = -lfslio -lniftiio -lznz -lm -lz
 
 XFILES = fslorient fslstats fslmerge \
          fslpspec fslroi fslnvols fsl2ascii fslascii2img  \
          fslsplit fslcc fslinterleave \
-         fslhd fslcpgeom fslcreatehd fslcorrecthd \
-         fslmeants fslslice fslswapdim_exe fslchfiletype_exe fslmaths fslcomplex fslfft fslsmoothfill
+         fslhd fslcpgeom fslcreatehd fslcorrecthd fslmaths \
+         fslcomplex fslfft fslmeants fslslice fslswapdim_exe fslchfiletype_exe calc_grad_perc_dev fslsmoothfill fslselectvols
 
 SCRIPTS = fslval fslchpixdim fslanimate fslsize sliceanimate fslinfo fsledithd avw2fsl fslswapdim fslchfiletype fslreorient2std fslmodhd fsladd
 
@@ -102,3 +102,5 @@ calc_grad_perc_dev: calc_grad_perc_dev.o
 fslsmoothfill: fslsmoothfill.o
 	${CXX} ${CXXFLAGS} ${LDFLAGS} -o $@ fslsmoothfill.o ${LIBS}
 
+fslselectvols: fslselectvols.o
+	${CXX} ${CXXFLAGS} ${LDFLAGS} -o $@ fslselectvols.o ${LIBS}
diff --git a/fslselectvols.cc b/fslselectvols.cc
new file mode 100644
index 0000000..d77c5b2
--- /dev/null
+++ b/fslselectvols.cc
@@ -0,0 +1,179 @@
+/*  fslselectvols.cc
+
+    Saad Jbabdi, FMRIB Image Analysis Group
+
+    Copyright (C) 2012 University of Oxford */
+
+/*  CCOPYRIGHT */
+
+#include "miscmaths/miscmaths.h"
+#include "newimage/newimageall.h"
+#include "utils/options.h"
+
+using namespace MISCMATHS;
+using namespace NEWIMAGE;
+using namespace Utilities;
+
+
+int parse_filterstring(vector<int>& comps,const string& vols){
+  int ctr=0;    
+  char *p;
+  char t[1024];
+  const char *discard = ", [];{(})abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*_-=+|\':><./?";
+  comps.clear();
+
+  strcpy(t, vols.c_str());
+  p=strtok(t,discard);
+  ctr = atoi(p);
+  if(ctr>=0)
+    comps.push_back(ctr);
+  do{
+    p=strtok(NULL,discard);
+    if(p){
+      ctr = atoi(p);
+      if(ctr>0){
+	comps.push_back(ctr);
+      }
+    }
+  }while(p);
+  return 0;
+}
+bool file_exists (const std::string& name) {
+    ifstream f(name.c_str());
+    if (f.good()) {
+        f.close();
+        return true;
+    } else {
+        f.close();
+        return false;
+    }   
+}
+
+int get_vols(Matrix& id_vols,const string& vols){
+  vector<int> comps;
+  if(file_exists(vols)){
+    id_vols = read_ascii_matrix(vols);
+    if(id_vols.Ncols()==1){id_vols=id_vols.t();}
+
+    comps.resize(id_vols.Ncols());
+    for(int i=0;i<(int)comps.size();i++){
+      comps[i]=id_vols(1,i+1);
+    }
+  }
+  else{
+    if(vols.length()>0 && parse_filterstring(comps,vols)){
+      return 1;		
+    }
+  }
+
+  //sort and remove duplicates 
+  sort (comps.begin(), comps.end());
+  vector<int>::iterator it = unique (comps.begin(), comps.end());
+  comps.resize( it - comps.begin() );
+    
+  id_vols.ReSize(1,comps.size());
+  for(int i=0;i<(int)comps.size();i++){
+    id_vols(1,i+1)=comps[i];
+  }
+  
+  
+  return 0;
+}
+
+
+
+string title=string("fslselectvols\n")+
+  string(" Select volumes from a 4D time series and output a subset 4D volume\n");
+string examples=string("fslselectvols -i <input> -o <output> --vols=0,1,6,7\n")+
+  string("fslselectvols -i <input> -o <output> --vols=volumes_list.txt");
+
+Option<bool> help(string("-h,--help"), false,
+		string("display this help text"),
+		false,no_argument);
+Option<string> ifilename(string("-i,--in"), string(""),
+		string("\tinput file name (4D image)"),
+		true, requires_argument);
+Option<string> ofilename(string("-o,--out"), string(""),
+		string("output file name (4D image)"),
+		true, requires_argument);
+Option<string> vols(string("--vols"), string(""),
+		string("\tlist of volumes to extract (comma-separated list or ascii file)"),
+		true, requires_argument);
+Option<bool>   calc_mean(string("-m"), false,
+		string("\toutput mean instead of concat"),
+		false, no_argument);
+Option<bool>   calc_var(string("-v"), false,
+		string("\toutput variance instead of concat"),
+		false, no_argument);
+
+
+int main(int argc,char *argv[]){
+  OptionParser options(title, examples);
+  try{
+    options.add(help);
+    options.add(ifilename);
+    options.add(ofilename);
+    options.add(vols);
+    options.add(calc_mean);
+    options.add(calc_var);
+    options.parse_command_line(argc, argv);
+    if ( (help.value()) || (!options.check_compulsory_arguments(true)) ){
+      options.usage();
+      exit(EXIT_FAILURE);
+    }
+    else{
+      
+      volume4D<float> data;
+      volume4D<float> subdata;
+      read_volume4D(data,ifilename.value());
+
+      Matrix list;
+      get_vols(list,vols.value());
+
+      bool meancalc=calc_mean.value(), varcalc=calc_var.value();
+
+      if(!meancalc && !varcalc)
+	subdata.reinitialize(data[0].xsize(),data[0].ysize(),data[0].zsize(),list.Ncols());
+      else
+	subdata.reinitialize(data[0].xsize(),data[0].ysize(),data[0].zsize(),1);
+      subdata=0;
+      copybasicproperties(data[0],subdata[0]);
+      
+      float v,v2;
+      for(int z=0;z<data[0].zsize();z++){
+	for(int y=0;y<data[0].ysize();y++){
+	  for(int x=0;x<data[0].xsize();x++){
+	    v=0;v2=0;
+	    for(int i=1;i<=list.Ncols();i++){	  
+	      v += data[list(1,i)](x,y,z);
+	      v2 += v*v;
+	      if(!meancalc && !varcalc)
+		subdata[i-1](x,y,z)= data[list(1,i)](x,y,z);
+	    }
+	    if(meancalc)
+	      subdata(x,y,z,0)= v/float(list.Ncols());
+	    if(varcalc)
+	      subdata(x,y,z,0)= v2/float(list.Ncols()) -v*v/float(list.Ncols()*list.Ncols());
+	  }
+	}
+      }
+      
+      save_volume4D(subdata,ofilename.value());
+      return 0;
+
+    }
+  }catch(X_OptionError& e) {
+    options.usage();
+    cerr << endl << e.what() << endl;
+    exit(EXIT_FAILURE);
+  }catch(std::exception &e) {
+    cerr << e.what() << endl;
+  } 
+  // either mean or variance but not both
+  if(calc_mean.value() && calc_var.value()){
+    cerr<<" Cannot output mean *and* variance. Please choose one or the other but not both"<<endl;
+    exit(1);
+  }
+  
+  
+}
-- 
GitLab