1 #include <odinpara/reco.h>
3 #include <odindata/image.h>
4 #include <odindata/data.h>
5 #include <odindata/gridding.h>
6 #include <odindata/fitting.h>
16 STD_cout <<
"gencoil: Generates a virtual coil suitable for sequence simulation in ODIN" << STD_endl;
19 STD_cout <<
"Usage and options:" << STD_endl;
20 STD_cout <<
" Generate a radially inhomogenous coil:" << STD_endl;
21 STD_cout <<
" gencoil -rad -n <inplane-size> -fov <FOV> -R <radial-inhomogeneity[%]> -o <Coil-file>" << STD_endl;
22 STD_cout <<
" Generate an array coil by rotating pre-existing image file:" << STD_endl;
23 STD_cout <<
" gencoil -rot -n <inplane-size> -fov <FOV> -nc <numof-rotated-subcoils> -i <input-image> -sl <selected-slice> -o <Coil-file>" << STD_endl;
24 STD_cout <<
" Generate an array coil consisting of simple loops:" << STD_endl;
25 STD_cout <<
" gencoil -arr -n <inplane-size> -nc <numof-rotated-loops> -fov <FOV> -R <array-radius> -o <Coil-file>" << STD_endl;
26 STD_cout <<
" Generate coil with a B1 gradient:" << STD_endl;
27 STD_cout <<
" gencoil -grad -n <inplane-size> -fov <FOV> -g <B1-gradient-endpoint> -o <Coil-file>" << STD_endl;
28 STD_cout <<
"Other options:" << STD_endl;
30 STD_cout <<
"\t" <<
helpUsage() << STD_endl;
33 int main(
int argc,
char* argv[]) {
39 Range all=Range::all();
41 char optval[ODIN_MAXCHAR];
43 STD_string coil_fname;
44 if(
getCommandlineOption(argc,argv,
"-o",optval,ODIN_MAXCHAR)) coil_fname=optval;
else {usage();exit(0);}
48 bool valid_mode=
false;
57 if(
getCommandlineOption(argc,argv,
"-n",optval,ODIN_MAXCHAR)) n=atoi(optval);
else {usage();exit(0);}
58 if(
getCommandlineOption(argc,argv,
"-R",optval,ODIN_MAXCHAR)) R=0.01*atof(optval);
else {usage();exit(0);}
59 if(
getCommandlineOption(argc,argv,
"-fov",optval,ODIN_MAXCHAR)) fov=atof(optval);
else {usage();exit(0);}
71 ndim nn=sens_map.get_extent();
74 for(
unsigned int i=0; i<nn.
total(); i++) {
82 double radius=sqrt(rx*rx+ry*ry);
84 double re=a*radius*radius+c;
87 b1factor=STD_complex(re,0.0);
88 sens_map(indexvec)=b1factor;
91 sens.set_sensitivity_map(sens_map,fov,fov,fov);
102 STD_string input_fname;
103 if(
getCommandlineOption(argc,argv,
"-n",optval,ODIN_MAXCHAR)) n=atoi(optval);
else {usage();exit(0);}
104 if(
getCommandlineOption(argc,argv,
"-nc",optval,ODIN_MAXCHAR)) nc=atoi(optval);
else {usage();exit(0);}
105 if(
getCommandlineOption(argc,argv,
"-fov",optval,ODIN_MAXCHAR)) fov=atof(optval);
else {usage();exit(0);}
106 if(
getCommandlineOption(argc,argv,
"-i",optval,ODIN_MAXCHAR)) input_fname=optval;
else {usage();exit(0);}
107 if(
getCommandlineOption(argc,argv,
"-sl",optval,ODIN_MAXCHAR)) sl=atoi(optval);
else {usage();exit(0);}
110 ODINLOG(odinlog,infoLog) <<
"Loading image file ... " << STD_endl;
111 if(img.
load(input_fname)<0) {
112 ODINLOG(odinlog,errorLog) <<
"unable to load ODIN image file " << input_fname << STD_endl;
116 TinyMatrix<float,2,2> rotation;
117 TinyVector<float,2> offset;
120 carray sens_map(nc,1,n,n);
124 TinyVector<int,2> newshape(n,n);
126 ODINLOG(odinlog,infoLog) <<
"Congridding map ... " << STD_endl;
129 float maxmap=max(onecoil);
132 for(
unsigned int i=0; i<onecoil.numElements(); i++) {
139 float mean=sum/nvals;
143 ODINLOG(odinlog,infoLog) <<
"Polynomial fit ... " << STD_endl;
149 for(
int ic=0; ic<nc; ic++) {
150 ODINLOG(odinlog,infoLog) <<
"Rotating coil " << ic <<
" ... " << STD_endl;
151 float phi=2.0*PII*float(ic)/float(nc);
152 rotation(0,0)=cos(phi); rotation(0,1)=sin(phi);
153 rotation(1,0)=-sin(phi); rotation(1,1)=cos(phi);
156 onecoil_transform=rotate(onecoil);
158 for(
int iy=0; iy<n; iy++) {
159 for(
int ix=0; ix<n; ix++) {
160 sens_map(ic,0,iy,ix)=STD_complex(onecoil_transform(iy,ix));
165 sens.set_sensitivity_map(sens_map,fov,fov,fov);
178 if(
getCommandlineOption(argc,argv,
"-n",optval,ODIN_MAXCHAR)) n=atoi(optval);
else {usage();exit(0);}
179 if(
getCommandlineOption(argc,argv,
"-nc",optval,ODIN_MAXCHAR)) nc=atoi(optval);
else {usage();exit(0);}
180 if(
getCommandlineOption(argc,argv,
"-fov",optval,ODIN_MAXCHAR)) fov=atof(optval);
else {usage();exit(0);}
181 if(
getCommandlineOption(argc,argv,
"-R",optval,ODIN_MAXCHAR)) R=atof(optval);
else {usage();exit(0);}
184 carray sens_map(nc,1,n,n);
189 ndim nn=sens_map.get_extent();
193 float loopR=overlap*PII*R/float(nc);
196 Array<float,2> rotmat[nc];
197 Array<float,1> offset[nc];
199 ODINLOG(odinlog,infoLog) <<
"Preparing rotmat/offset ... " << STD_endl;
200 for(
int icoil=0; icoil<nc; icoil++) {
201 float ang=2.0*PII*float(icoil)/float(nc);
203 rotmat[icoil].resize(3,3);
205 rotmat[icoil](0,0)=cos(ang); rotmat[icoil](0,1)=-sin(ang);
206 rotmat[icoil](1,0)=sin(ang); rotmat[icoil](1,1)=cos(ang);
207 rotmat[icoil](2,2)=1.0;
209 offset[icoil].resize(3);
210 offset[icoil](0)=R*cos(ang);
211 offset[icoil](1)=R*sin(ang);
212 offset[icoil](2)=0.0;
216 ODINLOG(odinlog,infoLog) <<
"Calculating sens_map ..." << STD_endl;
217 for(
unsigned int i=0; i<nn.
total(); i++) {
220 int icoil=indexvec[0];
230 int nloopsegments=100;
231 float dphi=2.0*PII/nloopsegments;
232 Array<float,1> dl(3);
234 Array<float,1> r0(3);
235 Array<float,1> dB(3);
237 for(
int iseg=0; iseg<nloopsegments; iseg++) {
238 float phi=2.0*PII*float(iseg)/float(nloopsegments);
240 dl(1)= loopR*cos(phi)*dphi;
241 dl(2)=-loopR*sin(phi)*dphi;
246 r0(1)=loopR*sin(phi);
247 r0(2)=loopR*cos(phi);
257 B1+=STD_complex(dB(0),dB(1))/r2;
261 sens_map(indexvec)=B1/float(2.0*PII);
264 sens.set_sensitivity_map(sens_map,fov,fov,fov);
278 if(
getCommandlineOption(argc,argv,
"-n",optval,ODIN_MAXCHAR)) n=atoi(optval);
else {usage();exit(0);}
279 if(
getCommandlineOption(argc,argv,
"-g",optval,ODIN_MAXCHAR)) grad=atof(optval);
else {usage();exit(0);}
280 if(
getCommandlineOption(argc,argv,
"-fov",optval,ODIN_MAXCHAR)) fov=atof(optval);
else {usage();exit(0);}
286 ndim nn=sens_map.get_extent();
289 for(
unsigned int i=0; i<nn.
total(); i++) {
292 sens_map(indexvec)=STD_complex(1.0+grad*
float(ix-nx_center)/
float(nx_center),0.0);
295 sens.set_sensitivity_map(sens_map,fov,fov,fov);
302 if(!valid_mode) {usage();exit(0);}
304 ODINLOG(odinlog,infoLog) <<
"Writing coil file ... " << STD_endl;
305 sens.write(coil_fname);
void congrid(const TinyVector< int, N_rank > &newshape, const TinyVector< float, N_rank > *subpixel_shift=0, bool left_to_right=false)
TinyVector< int, N_rank > create_index(unsigned long index) const
const farray & get_magnitude() const
int load(const STD_string &filename, const LDRserBase &serializer=LDRserJDX())
static bool set_log_levels(int argc, char *argv[], bool trigger_error=true)
static STD_string get_usage()
unsigned long total() const
ndim index2extent(unsigned long index) const
Array< float, N_rank > polyniomial_fit(const Array< float, N_rank > &value_map, const Array< float, N_rank > &reliability_map, unsigned int polynom_order, float kernel_size, bool only_zero_reliability=false)
Array< T, 1 > vector_product(const Array< T, 1 > &u, const Array< T, 1 > &v)
Array< T, 1 > matrix_product(const Array< T, 2 > &matrix, const Array< T, 1 > &vector)
const char * configInfo()
int isCommandlineOption(int argc, char *argv[], const char *option, bool modify=true)
double secureDivision(double numerator, double denominator)
int hasHelpOption(int argc, char *argv[])
int getCommandlineOption(int argc, char *argv[], const char *option, char *returnvalue, int maxchar, bool modify=true)