//AnyOption for command-line processing //#include "anyoption.h" #include "rts/optics/material.h" #include "nearfield.h" #include "microscope.h" #include "colormap.h" #include "fileout.h" //extern nearfieldStruct* NF; extern microscopeStruct* SCOPE; extern fileoutStruct gFileOut; //default values #include "defaults.h" #include #include #include #include using namespace std; #include namespace po = boost::program_options; static void loadSpheres(string sphereList) { /*This function loads a list of sphere given in the string sphereList The format is: x y z a m where x, y, z = sphere position (required) a = sphere radius (required) m = material ID (optional) */ std::stringstream ss(sphereList); while(!ss.eof()) { //create a new sphere sphere newS; //get the sphere data ss>>newS.p[0]; ss>>newS.p[1]; ss>>newS.p[2]; ss>>newS.a; if(ss.peek() != '\n') ss>>newS.iMaterial; //add the new sphere to the sphere vector SCOPE->nf.sVector.push_back(newS); //ignore the rest of the line ss.ignore(std::numeric_limits::max(), '\n'); //check out the next element (this should set the EOF error flag) ss.peek(); } } static void loadSpheres(po::variables_map vm) { //if a files are specified if(vm.count("sphere-file")) { cout<<"Sphere files detected."< filenames = vm["sphere-file"].as< vector >(); //load each file for(int iS=0; iS(ifs)), std::istreambuf_iterator()); //load the list of spheres from a string loadSpheres(instr); } } //load the sphere from the command line if(vm.count("sx") || vm.count("sy") || vm.count("sz") || vm.count("s")) { //create a new sphere sphere newS; //set defaults if(vm.count("sx")) newS.p[0] = vm["sx"].as(); else newS.p[0] = DEFAULT_SPHERE_X; if(vm.count("sy")) newS.p[1] = vm["sy"].as(); else newS.p[1] = DEFAULT_SPHERE_Y; if(vm.count("sz")) newS.p[2] = vm["sz"].as(); else newS.p[2] = DEFAULT_SPHERE_Z; if(vm.count("radius")) newS.a = vm["radius"].as(); else newS.a = DEFAULT_SPHERE_A; //add the sphere to the sphere vector SCOPE->nf.sVector.push_back(newS); } } static void loadMaterials(po::variables_map vm) { //if materials are specified at the command line if(vm.count("materials")) { vector matVec = vm["materials"].as< vector >(); if(matVec.size() %2 != 0) { cout<<"BIMSim Error: materials must be specified in n, k pairs"< newM(vm["lambda"].as(), matVec[i], matVec[i+1]); SCOPE->nf.mVector.push_back(newM); } } else { //add the command line material as the default (material 0) rts::material newM(vm["lambda"].as(), vm["n"].as(), vm["k"].as()); SCOPE->nf.mVector.push_back(newM); } //if file names are specified, load the materials if(vm.count("material-file")) { vector filenames = vm["material-file"].as< vector >(); for(int i=0; i(ifs)), std::istreambuf_iterator()); //load the list of spheres from a string rts::material newM; newM.fromStr(instr, ""); SCOPE->nf.mVector.push_back(newM); } } } static void loadNearfieldParams(po::variables_map vm) { //test to see if we are simulating a plane wave bool planeWave = DEFAULT_PLANEWAVE; if(vm.count("plane-wave")) planeWave = !planeWave; SCOPE->nf.planeWave = planeWave; //get the wavelength SCOPE->nf.lambda = vm["lambda"].as(); //get the incident field amplitude SCOPE->nf.A = vm["amplitude"].as(); //get the condenser parameters SCOPE->nf.condenser[0] = vm["condenser-min"].as(); SCOPE->nf.condenser[1] = vm["condenser-max"].as(); //get the focal rtsPoint position SCOPE->nf.focus[0] = vm["fx"].as(); SCOPE->nf.focus[1] = vm["fy"].as(); SCOPE->nf.focus[2] = vm["fz"].as(); //get the incident light direction (k-vector) bsVector spherical; spherical[0] = 1.0; spherical[1] = vm["theta"].as(); spherical[2] = vm["phi"].as(); SCOPE->nf.k = spherical.sph2cart(); //incident field order SCOPE->nf.m = vm["field-order"].as(); //number of Monte-Carlo samples SCOPE->nf.nWaves = vm["samples"].as(); } static void loadSliceParams(po::variables_map vm) { //parameters for the sample plane //set the default values for the slice position and orientation bsPoint pMin(vm["plane-min-x"].as(), vm["plane-min-y"].as(), vm["plane-min-z"].as()); bsPoint pMax(vm["plane-max-x"].as(), vm["plane-max-y"].as(), vm["plane-max-z"].as()); bsVector normal(vm["plane-norm-x"].as(), vm["plane-norm-y"].as(), vm["plane-norm-z"].as()); SCOPE->setPos(pMin, pMax, normal); //resolution SCOPE->setRes(vm["resolution"].as(), vm["resolution"].as(), vm["padding"].as(), vm["supersample"].as()); SCOPE->setNearfield(); } static void loadMicroscopeParams(po::variables_map vm) { //objective SCOPE->objective[0] = vm["objective-min"].as(); SCOPE->objective[1] = vm["objective-max"].as(); } static void loadOutputParams(po::variables_map vm) { //append simulation results to previous binary files gFileOut.append = DEFAULT_APPEND; if(vm.count("append")) gFileOut.append = true; //image parameters //component of the field to be saved std::string fieldStr; fieldStr = vm["output-type"].as(); if(fieldStr == "magnitude") gFileOut.field = fileoutStruct::fieldMag; else if(fieldStr == "intensity") gFileOut.field = fileoutStruct::fieldIntensity; else if(fieldStr == "polarization") gFileOut.field = fileoutStruct::fieldPolar; else if(fieldStr == "imaginary") gFileOut.field = fileoutStruct::fieldImag; else if(fieldStr == "real") gFileOut.field = fileoutStruct::fieldReal; else if(fieldStr == "angular-spectrum") gFileOut.field = fileoutStruct::fieldAngularSpectrum; //image file names gFileOut.intFile = vm["intensity"].as(); gFileOut.absFile = vm["absorbance"].as(); gFileOut.transFile = vm["transmittance"].as(); gFileOut.nearFile = vm["near-field"].as(); gFileOut.farFile = vm["far-field"].as(); //colormap std::string cmapStr; cmapStr = vm["colormap"].as(); if(cmapStr == "brewer") gFileOut.colormap = rts::colormap::cmBrewer; else if(cmapStr == "gray") gFileOut.colormap = rts::colormap::cmGrayscale; else cout<<"color-map value not recognized (using default): "<nf.toStr(); } static void SetOptions(po::options_description &desc) { desc.add_options() ("help,h", "prints this help") ("plane-wave,P", "simulates an incident plane wave") ("intensity,I", po::value()->default_value(DEFAULT_INTENSITY_FILE), "output measured intensity (filename)") ("absorbance,A", po::value()->default_value(DEFAULT_ABSORBANCE_FILE), "output measured absorbance (filename)") ("transmittance,T", po::value()->default_value(DEFAULT_TRANSMITTANCE_FILE), "output measured transmittance (filename)") ("far-field,F", po::value()->default_value(DEFAULT_FAR_FILE), "output far-field at detector (filename)") ("near-field,N", po::value()->default_value(DEFAULT_NEAR_FILE), "output field at focal plane (filename)") ("extended-source,X", po::value()->default_value(DEFAULT_EXTENDED_SOURCE), "image of source at focus (filename)") //("sx,x", po::value()->default_value(DEFAULT_SPHERE_X), "sphere coordinates") //("sy,y", po::value()->default_value(DEFAULT_SPHERE_Y)) //("sz,z", po::value()->default_value(DEFAULT_SPHERE_Z)) ("sx,x", po::value(), "sphere coordinates") ("sy,y", po::value()) ("sz,z", po::value()) ("radius,r", po::value()->default_value(DEFAULT_SPHERE_A), "sphere radius") ("samples,s", po::value()->default_value(DEFAULT_SAMPLES), "Monte-Carlo samples used to compute Us") ("sphere-file,S", po::value< vector >()->multitoken(), "sphere file:\n [x y z radius material]") ("amplitude,a", po::value()->default_value(DEFAULT_AMPLITUDE), "incident field amplitude") ("n,n", po::value()->default_value(DEFAULT_N, "1.4"), "sphere phase speed") ("k,k", po::value()->default_value(DEFAULT_K), "sphere absorption coefficient") ("material-file,M", po::value< vector >()->multitoken(), "material file:\n [lambda n k]") ("materials", po::value< vector >()->multitoken(), "materials specified using n, k pairs:\n ex. --materials n1 k1 n2 k2\n (if used --n and --k are ignored)") ("lambda,l", po::value()->default_value(DEFAULT_LAMBDA), "incident wavelength") ("theta,t", po::value()->default_value(DEFAULT_K_THETA), "light direction (polar coords)") ("phi,p", po::value()->default_value(DEFAULT_K_PHI)) ("fx", po::value()->default_value(DEFAULT_FOCUS_X), "incident focal point") ("fy", po::value()->default_value(DEFAULT_FOCUS_Y)) ("fz", po::value()->default_value(DEFAULT_FOCUS_Z)) ("condenser-max,C", po::value()->default_value(DEFAULT_CONDENSER_MAX), "condenser numerical aperature") ("condenser-min,c", po::value()->default_value(DEFAULT_CONDENSER_MIN), "condenser obscuration NA") ("objective-max,O", po::value()->default_value(DEFAULT_OBJECTIVE_MAX), "objective numerical aperature") ("objective-min,o", po::value()->default_value(DEFAULT_OBJECTIVE_MIN), "objective obscuration NA") ("field-order", po::value()->default_value(DEFAULT_FIELD_ORDER), "order of the incident field") ("output-type,f", po::value()->default_value(DEFAULT_FIELD_TYPE), "output field value:\n magnitude, polarization, real, imaginary, angular-spectrum") ("resolution,R", po::value()->default_value(DEFAULT_SLICE_RES), "resolution of the detector") ("padding,d", po::value()->default_value(DEFAULT_PADDING), "FFT padding for the objective bandpass") ("supersample", po::value()->default_value(DEFAULT_SUPERSAMPLE), "super-sampling rate for the detector field") ("colormap", po::value()->default_value(DEFAULT_COLORMAP), "colormap: gray, brewer") ("append", "append result to an existing file\n (binary files only)") ("plane-min-x,u", po::value()->default_value(DEFAULT_SLICE_MIN_X), "lower-left corner of the field slice") ("plane-min-y,v", po::value()->default_value(DEFAULT_SLICE_MIN_Y)) ("plane-min-z,w", po::value()->default_value(DEFAULT_SLICE_MIN_Z)) ("plane-max-x,U", po::value()->default_value(DEFAULT_SLICE_MAX_X), "upper-right corner of the field slice") ("plane-max-y,V", po::value()->default_value(DEFAULT_SLICE_MAX_Y)) ("plane-max-z,W", po::value()->default_value(DEFAULT_SLICE_MAX_Z)) ("plane-norm-x", po::value()->default_value(DEFAULT_SLICE_NORM_X), "field slice normal") ("plane-norm-y", po::value()->default_value(DEFAULT_SLICE_NORM_Y)) ("plane-norm-z", po::value()->default_value(DEFAULT_SLICE_NORM_Z)); } static void LoadParameters(int argc, char *argv[]) { //create an option description po::options_description desc("Allowed options"); //fill it with options SetOptions(desc); po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); //display help and exit if(vm.count("help")) { cout<() != "") { //load the point sources string filename = vm["extended-source"].as(); SCOPE->LoadExtendedSource(filename); } }