void mcx_set_field(const mxArray *root,const mxArray *item,int idx, Config *cfg){ const char *name=mxGetFieldNameByNumber(root,idx); const int *arraydim; char *jsonshapes=NULL; int i,j; cfg->flog=stderr; GET_1ST_FIELD(cfg,nphoton) GET_ONE_FIELD(cfg,nblocksize) GET_ONE_FIELD(cfg,nthread) GET_ONE_FIELD(cfg,seed) GET_ONE_FIELD(cfg,tstart) GET_ONE_FIELD(cfg,tstep) GET_ONE_FIELD(cfg,tend) GET_ONE_FIELD(cfg,maxdetphoton) GET_ONE_FIELD(cfg,sradius) GET_ONE_FIELD(cfg,maxgate) GET_ONE_FIELD(cfg,respin) GET_ONE_FIELD(cfg,gpuid) GET_ONE_FIELD(cfg,isreflect) GET_ONE_FIELD(cfg,isref3) GET_ONE_FIELD(cfg,isrefint) GET_ONE_FIELD(cfg,isnormalized) GET_ONE_FIELD(cfg,issavedet) GET_ONE_FIELD(cfg,issave2pt) GET_ONE_FIELD(cfg,isgpuinfo) GET_ONE_FIELD(cfg,issrcfrom0) GET_ONE_FIELD(cfg,autopilot) GET_ONE_FIELD(cfg,minenergy) GET_ONE_FIELD(cfg,unitinmm) GET_VEC3_FIELD(cfg,srcpos) GET_VEC3_FIELD(cfg,srcdir) GET_VEC3_FIELD(cfg,steps) GET_VEC3_FIELD(cfg,crop0) GET_VEC3_FIELD(cfg,crop1) else if(strcmp(name,"vol")==0){ if(!mxIsUint8(item) || mxGetNumberOfDimensions(item)!=3 ) mexErrMsgTxt("the 'vol' field must be a 3D uint8 array"); arraydim=mxGetDimensions(item); for(i=0;i<3;i++) ((unsigned int *)(&cfg->dim))[i]=arraydim[i]; if(cfg->vol) free(cfg->vol); cfg->vol=(unsigned char *)malloc(cfg->dim.x*cfg->dim.y*cfg->dim.z); memcpy(cfg->vol,mxGetData(item),cfg->dim.x*cfg->dim.y*cfg->dim.z); printf("mcx.dim=[%d %d %d];\n",cfg->dim.x,cfg->dim.y,cfg->dim.z); }else if(strcmp(name,"detpos")==0){ arraydim=mxGetDimensions(item); if(arraydim[0]>0 && arraydim[1]!=4) mexErrMsgTxt("the 'detpos' field must have 4 columns (x,y,z,radius)"); double *val=mxGetPr(item); cfg->detnum=arraydim[0]; if(cfg->detpos) free(cfg->detpos); cfg->detpos=(float4 *)malloc(cfg->detnum*sizeof(float4)); for(j=0;j<4;j++) for(i=0;i<cfg->detnum;i++) ((float *)(&cfg->detpos[i]))[j]=val[j*cfg->detnum+i]; printf("mcx.detnum=%d;\n",cfg->detnum); }else if(strcmp(name,"prop")==0){ arraydim=mxGetDimensions(item); if(arraydim[0]>0 && arraydim[1]!=4) mexErrMsgTxt("the 'prop' field must have 4 columns (mua,mus,g,n)"); double *val=mxGetPr(item); cfg->medianum=arraydim[0]; if(cfg->prop) free(cfg->prop); cfg->prop=(Medium *)malloc(cfg->medianum*sizeof(Medium)); for(j=0;j<4;j++) for(i=0;i<cfg->medianum;i++) ((float *)(&cfg->prop[i]))[j]=val[j*cfg->medianum+i]; printf("mcx.medianum=%d;\n",cfg->medianum); }else if(strcmp(name,"session")==0){ int len=mxGetNumberOfElements(item); if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'session' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'session' field is too long"); int status = mxGetString(item, cfg->session, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); printf("mcx.session='%s';\n",cfg->session); }else if(strcmp(name,"shapes")==0){ int len=mxGetNumberOfElements(item); if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'shapes' field must be a non-empty string"); jsonshapes=new char[len+1]; mxGetString(item, jsonshapes, len+1); jsonshapes[len]='\0'; }else{ printf("WARNING: redundant field '%s'\n",name); } if(jsonshapes){ Grid3D grid={&(cfg->vol),&(cfg->dim),{1.f,1.f,1.f},0}; if(cfg->issrcfrom0) memset(&(grid.orig.x),0,sizeof(float3)); int status=mcx_parse_shapestring(&grid,jsonshapes); delete [] jsonshapes; if(status){ mexErrMsgTxt(mcx_last_shapeerror()); } } }
void mcx_set_field(const mxArray *root,const mxArray *item,int idx, Config *cfg){ const char *name=mxGetFieldNameByNumber(root,idx); const int *arraydim; char *jsonshapes=NULL; int i,j; if(strcmp(name,"nphoton")==0 && cfg->replay.seed!=NULL) return; cfg->flog=stderr; GET_1ST_FIELD(cfg,nphoton) GET_ONE_FIELD(cfg,nblocksize) GET_ONE_FIELD(cfg,nthread) GET_ONE_FIELD(cfg,tstart) GET_ONE_FIELD(cfg,tstep) GET_ONE_FIELD(cfg,tend) GET_ONE_FIELD(cfg,maxdetphoton) GET_ONE_FIELD(cfg,sradius) GET_ONE_FIELD(cfg,maxgate) GET_ONE_FIELD(cfg,respin) GET_ONE_FIELD(cfg,isreflect) GET_ONE_FIELD(cfg,isref3) GET_ONE_FIELD(cfg,isrefint) GET_ONE_FIELD(cfg,isnormalized) GET_ONE_FIELD(cfg,isgpuinfo) GET_ONE_FIELD(cfg,issrcfrom0) GET_ONE_FIELD(cfg,autopilot) GET_ONE_FIELD(cfg,minenergy) GET_ONE_FIELD(cfg,unitinmm) GET_ONE_FIELD(cfg,reseedlimit) GET_ONE_FIELD(cfg,printnum) GET_ONE_FIELD(cfg,voidtime) GET_ONE_FIELD(cfg,issaveseed) GET_ONE_FIELD(cfg,replaydet) GET_ONE_FIELD(cfg,faststep) GET_ONE_FIELD(cfg,maxvoidstep) GET_ONE_FIELD(cfg,maxjumpdebug) GET_VEC3_FIELD(cfg,srcpos) GET_VEC3_FIELD(cfg,srcdir) GET_VEC3_FIELD(cfg,steps) GET_VEC3_FIELD(cfg,crop0) GET_VEC3_FIELD(cfg,crop1) GET_VEC4_FIELD(cfg,srcparam1) GET_VEC4_FIELD(cfg,srcparam2) else if(strcmp(name,"vol")==0){ if(!mxIsUint8(item) || mxGetNumberOfDimensions(item)!=3 ) mexErrMsgTxt("the 'vol' field must be a 3D uint8 array"); arraydim=mxGetDimensions(item); for(i=0;i<3;i++) ((unsigned int *)(&cfg->dim))[i]=arraydim[i]; if(cfg->vol) free(cfg->vol); cfg->vol=(unsigned char *)malloc(cfg->dim.x*cfg->dim.y*cfg->dim.z); memcpy(cfg->vol,mxGetData(item),cfg->dim.x*cfg->dim.y*cfg->dim.z); printf("mcx.dim=[%d %d %d];\n",cfg->dim.x,cfg->dim.y,cfg->dim.z); }else if(strcmp(name,"detpos")==0){ arraydim=mxGetDimensions(item); if(arraydim[0]>0 && arraydim[1]!=4) mexErrMsgTxt("the 'detpos' field must have 4 columns (x,y,z,radius)"); double *val=mxGetPr(item); cfg->detnum=arraydim[0]; if(cfg->detpos) free(cfg->detpos); cfg->detpos=(float4 *)malloc(cfg->detnum*sizeof(float4)); for(j=0;j<4;j++) for(i=0;i<cfg->detnum;i++) ((float *)(&cfg->detpos[i]))[j]=val[j*cfg->detnum+i]; printf("mcx.detnum=%d;\n",cfg->detnum); }else if(strcmp(name,"prop")==0){ arraydim=mxGetDimensions(item); if(arraydim[0]>0 && arraydim[1]!=4) mexErrMsgTxt("the 'prop' field must have 4 columns (mua,mus,g,n)"); double *val=mxGetPr(item); cfg->medianum=arraydim[0]; if(cfg->prop) free(cfg->prop); cfg->prop=(Medium *)malloc(cfg->medianum*sizeof(Medium)); for(j=0;j<4;j++) for(i=0;i<cfg->medianum;i++) ((float *)(&cfg->prop[i]))[j]=val[j*cfg->medianum+i]; printf("mcx.medianum=%d;\n",cfg->medianum); }else if(strcmp(name,"session")==0){ int len=mxGetNumberOfElements(item); if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'session' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'session' field is too long"); int status = mxGetString(item, cfg->session, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); printf("mcx.session='%s';\n",cfg->session); }else if(strcmp(name,"srctype")==0){ int len=mxGetNumberOfElements(item); const char *srctypeid[]={"pencil","isotropic","cone","gaussian","planar","pattern","fourier","arcsine","disk","fourierx","fourierx2d","zgaussian","line","slit", "rectangular",""}; char strtypestr[MAX_SESSION_LENGTH]={'\0'}; if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'srctype' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'srctype' field is too long"); int status = mxGetString(item, strtypestr, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); cfg->srctype=mcx_keylookup(strtypestr,srctypeid); if(cfg->srctype==-1) mexErrMsgTxt("the specified source type is not supported"); printf("mcx.srctype='%s';\n",strtypestr); }else if(strcmp(name,"outputtype")==0){ int len=mxGetNumberOfElements(item); const char *outputtype[]={"flux","fluence","energy","jacobian",""}; char outputstr[MAX_SESSION_LENGTH]={'\0'}; if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'outputtype' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'outputtype' field is too long"); int status = mxGetString(item, outputstr, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); cfg->outputtype=mcx_keylookup(outputstr,outputtype); if(cfg->outputtype==-1) mexErrMsgTxt("the specified output type is not supported"); printf("mcx.outputtype='%s';\n",outputstr); }else if(strcmp(name,"debuglevel")==0){ int len=mxGetNumberOfElements(item); const char debugflag[]={'R','M','P','\0'}; char debuglevel[MAX_SESSION_LENGTH]={'\0'}; if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'debuglevel' field must be a non-empty string"); if(len>MAX_SESSION_LENGTH) mexErrMsgTxt("the 'debuglevel' field is too long"); int status = mxGetString(item, debuglevel, MAX_SESSION_LENGTH); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); cfg->debuglevel=mcx_parsedebugopt(debuglevel,debugflag); if(cfg->debuglevel==0) mexWarnMsgTxt("the specified debuglevel is not supported"); printf("mcx.debuglevel='%d';\n",cfg->debuglevel); }else if(strcmp(name,"srcpattern")==0){ arraydim=mxGetDimensions(item); double *val=mxGetPr(item); if(cfg->srcpattern) free(cfg->srcpattern); cfg->srcpattern=(float*)malloc(arraydim[0]*arraydim[1]*sizeof(float)); for(i=0;i<arraydim[0]*arraydim[1];i++) cfg->srcpattern[i]=val[i]; printf("mcx.srcpattern=[%d %d];\n",arraydim[0],arraydim[1]); }else if(strcmp(name,"shapes")==0){ int len=mxGetNumberOfElements(item); if(!mxIsChar(item) || len==0) mexErrMsgTxt("the 'shapes' field must be a non-empty string"); jsonshapes=new char[len+1]; mxGetString(item, jsonshapes, len+1); jsonshapes[len]='\0'; }else if(strcmp(name,"detphotons")==0){ arraydim=mxGetDimensions(item); dimdetps[0]=arraydim[0]; dimdetps[1]=arraydim[1]; detps=(float *)malloc(arraydim[0]*arraydim[1]*sizeof(float)); memcpy(detps,mxGetData(item),arraydim[0]*arraydim[1]*sizeof(float)); printf("mcx.detphotons=[%d %d];\n",arraydim[0],arraydim[1]); }else if(strcmp(name,"seed")==0){ arraydim=mxGetDimensions(item); if(MAX(arraydim[0],arraydim[1])==0) mexErrMsgTxt("the 'seed' field can not be empty"); if(!mxIsUint8(item)){ double *val=mxGetPr(item); cfg->seed=val[0]; printf("mcx.seed=%d;\n",cfg->seed); }else{ seedbyte=arraydim[0]; cfg->replay.seed=malloc(arraydim[0]*arraydim[1]); if(arraydim[0]!=sizeof(float)*RAND_BUF_LEN) mexErrMsgTxt("the row number of cfg.seed does not match RNG seed byte-length"); memcpy(cfg->replay.seed,mxGetData(item),arraydim[0]*arraydim[1]); cfg->seed=SEED_FROM_FILE; cfg->nphoton=arraydim[1]; printf("mcx.nphoton=%d;\n",cfg->nphoton); } }else if(strcmp(name,"gpuid")==0){ int len=mxGetNumberOfElements(item); if(mxIsChar(item)){ if(len==0) mexErrMsgTxt("the 'gpuid' field must be an integer or non-empty string"); if(len>MAX_DEVICE) mexErrMsgTxt("the 'gpuid' field is too long"); int status = mxGetString(item, cfg->deviceid, MAX_DEVICE); if (status != 0) mexWarnMsgTxt("not enough space. string is truncated."); printf("mcx.gpuid='%s';\n",cfg->deviceid); }else{ double *val=mxGetPr(item); cfg->gpuid=val[0]; memset(cfg->deviceid,0,MAX_DEVICE); if(cfg->gpuid<MAX_DEVICE){ memset(cfg->deviceid,'0',cfg->gpuid-1); cfg->deviceid[cfg->gpuid-1]='1'; }else mexErrMsgTxt("GPU id can not be more than 256"); printf("mcx.gpuid=%d;\n",cfg->gpuid); } for(int i=0;i<MAX_DEVICE;i++) if(cfg->deviceid[i]=='0') cfg->deviceid[i]='\0'; }else if(strcmp(name,"workload")==0){ double *val=mxGetPr(item); arraydim=mxGetDimensions(item); if(arraydim[0]*arraydim[1]>MAX_DEVICE) mexErrMsgTxt("the workload list can not be longer than 256"); for(i=0;i<arraydim[0]*arraydim[1];i++) cfg->workload[i]=val[i]; printf("mcx.workload=<<%d>>;\n",arraydim[0]*arraydim[1]); }else{ printf("WARNING: redundant field '%s'\n",name); } if(jsonshapes){ Grid3D grid={&(cfg->vol),&(cfg->dim),{1.f,1.f,1.f},0}; if(cfg->issrcfrom0) memset(&(grid.orig.x),0,sizeof(float3)); int status=mcx_parse_shapestring(&grid,jsonshapes); delete [] jsonshapes; if(status){ mexErrMsgTxt(mcx_last_shapeerror()); } } }