Пример #1
0
//目标改变,生成新位置数据,可自由设置改变的幅度-----------------------------------------------------------------------
int Dmplwr::Reprolwr(double dtar,double dvel,string path){
	model.z = 1;
	model.x1 = 0;
	model.x2 = model.demo_d(0)*model.move_time;

	model.target_d +=dvel;
	model.target =model.target_f-model.move_time*model.target_d+dtar;

	//cout<<model.target_d<<endl<<model.target<<endl;

	model.rPos = zeros(1,model.nbData); 
	model.rVel = zeros(1,model.nbData);
	model.rAcc = zeros(1,model.nbData);
	model.rPos.col(0) = model.demo.col(0);
	model.rVel.col(0) = model.demo_d.col(0);
	model.rAcc.col(0) = model.demo_dd.col(0);

	//cout<<model.rPos.col(0)<<endl<<model.rVel.col(0)<<endl<<model.rAcc.col(0)<<endl;
	for(int i = 0;i<model.nbData;i++)
	{
		model.target += (model.target_d*model.dt);
		model.psi = exp(-model.h%(model.z-model.c)%(model.z-model.c));
		mat ftemp = sum(model.psi%model.w*model.z,0);
		ftemp = ftemp/sum(model.psi+REALMIN,0);
		double f = ftemp(0,0);
		model.x2_d = (model.alpha_g*(1-model.z)*(model.beta_g*(model.target-model.x1)+((model.target_d/model.tau)-model.x2))+model.A*f)*model.tau;
		model.x1_d = model.x2*model.tau;
		model.zd = -model.alpha_z*model.z*model.tau;
		model.x1_dd = model.x2_d*model.tau;

		model.x2 +=model.dt*model.x2_d;
		model.x1 +=model.dt*model.x1_d;
		model.z +=model.dt*model.zd;

		model.rPos(0,i) = model.x1;
		model.rVel(0,i) = model.x1_d;
		model.rAcc(0,i) = model.x1_dd;
	}
	cout<<"model.rPos:"<<model.rPos<<endl;
	model.rPos = trans(model.rPos);
	model.rVel = trans(model.rVel);
	model.rAcc = trans(model.rAcc);

// Saving the reproduction data
    string UpdatedPath;
    UpdatedPath = path + "data_rPos" + ".txt";
	model.rPos.save(UpdatedPath, raw_ascii);
                     
	UpdatedPath = path + "data_rVel" + ".txt";
	model.rVel.save(UpdatedPath, raw_ascii);

	UpdatedPath = path + "data_rAcc" + ".txt";
	model.rAcc.save(UpdatedPath, raw_ascii);

	cout<<"Reproduction to new target is finished"<<endl;

	return 1;
}
Пример #2
0
static int xmp_read(const char *path, char *buf, size_t size, off_t offset,
		    struct fuse_file_info *fi)
{
	(void)fi;
	int res=0;
	int action;
	ssize_t vsize = 0;
	char *tval = NULL;

	char fpath[PATH_MAX];
	xmp_getfullpath(fpath, path);

	vsize = getxattr(fpath, XATRR_ENCRYPTED_FLAG, NULL, 0);
	tval = malloc(sizeof(*tval)*(vsize));
	vsize = getxattr(fpath, XATRR_ENCRYPTED_FLAG, tval, vsize);

	fprintf(stderr, "Size: %zu, offset: %zu.\n", size, offset);

	/* If the specified attribute doesn't exist or it's set to false */
	if (vsize < 0 || memcmp(tval, "false", 5) == 0){
		if(errno == ENODATA){
			fprintf(stderr, "Read: No %s attribute set\n", XATRR_ENCRYPTED_FLAG);
		}
		action = COPY;
	}
	else if (memcmp(tval, "true", 4) == 0){
		action = DECRYPT;
		fprintf(stderr, "Read: file is encrypted, need to decrypt\n");
	}

	const char *tpath = ftemp(fpath, ".read");
	FILE *dfd = fopen(tpath, "wb+");
	FILE *fd = fopen(fpath, "rb");

	if(!do_crypt(fd, dfd, action, ENCFS_DATA->passkey)){
		fprintf(stderr, "Encryption failed, error code: %d\n", res);
    	}

    fseek(dfd, 0, SEEK_END);
   	size_t tflen = ftell(dfd);
    fseek(dfd, 0, SEEK_SET);

   	res = fread(buf, 1, tflen, dfd);
    	if (res == -1) res = -errno;

	fclose(fd);
	fclose(dfd);
	remove(tpath);
	free(tval);

	return res;
}
Пример #3
0
//ag_merge [-n _start_N_value_] [-a _start_alpha_value_] -d _directory1_ _directory2_ [_directory3_] 
//[_directory4_] ...
int main(int argc, char* argv[])
{	
	try{
//0. Set log file
	LogStream clog;
	LogStream::init(true);
	clog << "\n-----\nag_merge ";
	for(int argNo = 1; argNo < argc; argNo++)
		clog << argv[argNo] << " ";
	clog << "\n\n";

//1. Set input parameters from command line 

	int startTiGN = 1;
	double startAlpha = 0.5;
	int firstDirNo = 0;

	stringv args(argc); 
	for(int argNo = 0; argNo < argc; argNo++)
		args[argNo] = string(argv[argNo]);

	 //parse and save input parameters
	for(int argNo = 1; argNo < argc; argNo += 2)
	{
		if(!args[argNo].compare("-n"))
			startTiGN = atoiExt(argv[argNo + 1]);
		else if(!args[argNo].compare("-a"))
			startAlpha = atofExt(argv[argNo + 1]);
		else if(!args[argNo].compare("-d"))
		{
			firstDirNo = argNo + 1;
			break;
		}
		else
			throw INPUT_ERR;
	}

	//check that there are at least two directories 
	if(argc < (firstDirNo + 2))
		throw INPUT_ERR;

	//convert names of input directories to strings and check that they exist
	int folderN = argc - firstDirNo;
	stringv folders(folderN); 
	for(int argNo = firstDirNo; argNo < argc; argNo++)
	{
		folders[argNo - firstDirNo] = string(argv[argNo]);
		struct stat status;
		if((stat(argv[argNo], &status) != 0) || !(status.st_mode & S_IFDIR))
			throw DIR_ERR;
	}

//1.a) delete all temp files from the previous run and create a directory AGTemp
#ifdef _WIN32	//in windows
	CreateDirectory("AGTemp", NULL);
#else // in linux
	system("rm -rf ./AGTemp/");
	system("mkdir ./AGTemp/");
#endif

//2. Set parameters from AGTemp/params.txt from the first directory
	TrainInfo ti;			//set of model parameters in the current directory
	double prevBest;		//best value of performance achieved on the previous run
			
	fstream fparam;
	string paramPathName = folders[0] + "/AGTemp/params.txt";
	fparam.open(paramPathName.c_str(), ios_base::in); 
	string modeStr, metric;
	fparam >> ti.seed >> ti.trainFName >> ti.validFName >> ti.attrFName >> ti.minAlpha >> ti.maxTiGN 
		>> ti.bagN >> modeStr >> metric;	

	//modeStr should be "fast" or "slow" or "layered"	
	if(modeStr.compare("fast") == 0)
		ti.mode = FAST;
	else if(modeStr.compare("slow") == 0)
		ti.mode = SLOW;
	else if(modeStr.compare("layered") == 0)
		ti.mode = LAYERED;
	else
		throw TEMP_ERR;

	//metric should be "roc" or "rms"
	if(metric.compare("rms") == 0)
		ti.rms = true;
	else if(metric.compare("roc") == 0)
		ti.rms = false;
	else
		throw TEMP_ERR;

	if(fparam.fail())
		throw TEMP_ERR;
	fparam.close();
	fparam.clear();

	//read best value of performance on previous run
	fstream fbest;
	double stub;
	int itemN; // number of data points in the train set, need to calculate possible values of alpha
	string fbestPathName = folders[0] + "/AGTemp/best.txt";
	fbest.open(fbestPathName.c_str(), ios_base::in); 
	fbest >> prevBest >> stub >> stub >> stub >> itemN;
	if(fbest.fail())
		throw TEMP_ERR;
	fbest.close();

	int alphaN = getAlphaN(ti.minAlpha, itemN); //number of different alpha values
	int tigNN = getTiGNN(ti.maxTiGN);

	//direction of initialization (1 - up, 0 - right), used in fast mode only
	doublevv dir(tigNN, doublev(alphaN, 0)); 
	//outer array: column (by TiGN)
	//middle array: row	(by alpha)
	
	//direction of initialization (1 - up, 0 - right), collects average in the slow mode
	doublevv dirStat(tigNN, doublev(alphaN, 0));

	if(ti.mode == FAST)
	{//read part of the directions table from file
		fstream fdir;
		string fdirPathName = folders[0] + "/AGTemp/dir.txt";
		fdir.open(fdirPathName.c_str(), ios_base::in); 
		for(int tigNNo = 0; tigNNo < tigNN; tigNNo++)
			for(int alphaNo = 0; alphaNo < alphaN; alphaNo++)
				fdir >> dir[tigNNo][alphaNo];
		if(fdir.fail())
			throw TEMP_ERR;
		fdir.close();
	}

//3. Read main parameters from all other directories and check that they match

	int allBagN = ti.bagN;
	intv bagNs(folderN, 0);
	bagNs[0] = ti.bagN;
	intv prevBagNs(folderN + 1, 0); //sums of bagNs of all previous directories
	prevBagNs[1] = ti.bagN;
	int lastSeed = ti.seed;
	for(int folderNo = 1; folderNo < folderN; folderNo++)
	{
		TrainInfo extraTI;	//set of model parameters in the additional directory
		
		string fparamPathName = folders[folderNo] + "/AGTemp/params.txt";
		fparam.open(fparamPathName.c_str(), ios_base::in); 
		fparam >> extraTI.seed >> extraTI.trainFName >> extraTI.validFName >> extraTI.attrFName 
			>> extraTI.minAlpha >> extraTI.maxTiGN >> extraTI.bagN;	

		if(fparam.fail())
		{
			clog << fparamPathName << '\n';
			throw TEMP_ERR;
		}
		fparam.close();

		if((ti.minAlpha != extraTI.minAlpha) || (ti.maxTiGN != extraTI.maxTiGN))
		  {
		    clog << fparamPathName << '\n';
			throw MERGE_MISMATCH_ERR;
		  }
		if(extraTI.seed == ti.seed)
			throw SAME_SEED_ERR;
		if(folderNo == (folderN - 1))
			lastSeed = extraTI.seed;

		allBagN += extraTI.bagN;
		bagNs[folderNo] = extraTI.bagN;
		prevBagNs[folderNo + 1] = allBagN;

		string fdirStatPathName = folders[folderNo] + "/AGTemp/dirstat.txt";
		fstream fdirStat;	
		fdirStat.open("./AGTemp/dirstat.txt", ios_base::in);
		for(int alphaNo = 0; alphaNo < alphaN; alphaNo++)
			for(int tigNNo = 0; tigNNo < tigNN; tigNNo++)
			{
				double ds;
				fdirStat >> ds;
				dirStat[tigNNo][alphaNo] += ds * extraTI.bagN;
			}
	}

//4. Load data
	INDdata data("", ti.validFName.c_str(), "", ti.attrFName.c_str());
	CGrove::setData(data);
	CTreeNode::setData(data);

	doublev validTar;
	int validN = data.getTargets(validTar, VALID);

	clog << "Alpha = " << ti.minAlpha << "\nN = " << ti.maxTiGN << "\n" 
		<< allBagN << " bagging iterations\n";
	if(ti.mode == FAST)
		clog << "fast mode\n\n";
	else if(ti.mode == SLOW)
		clog << "slow mode\n\n";
	else //if(ti.mode == LAYERED)
		clog << "layered mode\n\n";

	//5. Initialize some internal process variables

	//surfaces of performance values for validation set. 
	//Always calculate rms (for convergence analysis), if needed, calculate roc
	doublevvv rmsV(tigNN, doublevv(alphaN, doublev(allBagN, 0))); 
	doublevvv rocV;
	if(!ti.rms)
		rocV.resize(tigNN, doublevv(alphaN, doublev(allBagN, 0))); 
	//outer array: column (by TiGN)
	//middle array: row (by alpha)
	//inner array: bagging iterations. Performance is kept for all iterations to create bagging curves

	//sums of predictions for each data point (raw material to calculate performance)
	doublevvv predsumsV(tigNN, doublevv(alphaN, doublev(validN, 0)));
	//outer array: column (by TiGN)
	//middle array: row	(by alpha)
	//inner array: data points in the validation set
	

//6. Read and merge models from the directories
	int startAlphaNo = getAlphaN(startAlpha, itemN) - 1; 
	int startTiGNNo = getTiGNN(startTiGN) - 1;

	for(int alphaNo = startAlphaNo; alphaNo < alphaN; alphaNo++)
	{
		double alpha;
		if(alphaNo < alphaN - 1)
			alpha = alphaVal(alphaNo);
		else	//this is a special case because minAlpha can be zero
			alpha = ti.minAlpha;

		cout << "Merging models with alpha = " << alpha << endl;

		for(int tigNNo = startTiGNNo; tigNNo < tigNN; tigNNo++) 
		{
			int tigN = tigVal(tigNNo);	//number of trees in the current grove

			//temp file in the extra directory that keeps models corresponding to alpha and tigN
			string prefix = string("/AGTemp/ag.a.") 
								+ alphaToStr(alpha)
								+ ".n." 
								+ itoa(tigN, 10);
			string tempFName = prefix + ".tmp";

			//this will kill the pre-existing file in the output directory
			fstream fsave((string(".") + tempFName).c_str(), ios_base::binary | ios_base::out);	

			for(int folderNo = 0; folderNo < folderN; folderNo++)
			{
				string inTempFName = folders[folderNo] + tempFName;
				fstream ftemp((inTempFName).c_str(), ios_base::binary | ios_base::in);
				if(ftemp.fail())
				{
				    clog << inTempFName << '\n';
					throw TEMP_ERR;
				}
			
				//merge all extra models with the same (alpha, tigN) parameter values into existing models
				for(int bagNo = prevBagNs[folderNo]; bagNo < prevBagNs[folderNo + 1]; bagNo++)
				{
					//retrieve next grove
					CGrove extraGrove(alpha, tigN);
					try{
					extraGrove.load(ftemp);
					}catch(TE_ERROR err){
					  clog << inTempFName << '\n';
					  throw err;
					}
					//add the loaded grove to a model file with alpha and tigN values in the name
					extraGrove.save((string(".") + tempFName).c_str());

					//generate predictions and performance for validation set
					doublev predictions(validN);
					for(int itemNo = 0; itemNo < validN; itemNo++)
					{
						predsumsV[tigNNo][alphaNo][itemNo] += extraGrove.predict(itemNo, VALID);
						predictions[itemNo] = predsumsV[tigNNo][alphaNo][itemNo] / (bagNo + 1);
					}
					if(bagNo == allBagN - 1)
					{
						string predsFName = prefix + ".preds.txt";
						fstream fpreds((string(".") + predsFName).c_str(), ios_base::out);
						for(int itemNo = 0; itemNo < validN; itemNo++)
							fpreds << predictions[itemNo] << endl;
						fpreds.close();
					}

					rmsV[tigNNo][alphaNo][bagNo] = rmse(predictions, validTar);
					if(!ti.rms)
						rocV[tigNNo][alphaNo][bagNo] = roc(predictions, validTar);

				}// end for(int bagNo = ti.bagN; bagNo < ti.bagN + extraTI.bagN; bagNo++)
				ftemp.close();
			}//end for(int folderNo = 0; folderNo < folderN; folderNo++)
		}//end for(int tigNNo = 0; tigNNo < tigNN; tigNNo++) 
	}//end for(int alphaNo = 0; alphaNo < alphaN; alphaNo++)

	//4. Output
	ti.bagN = allBagN;
	ti.seed = lastSeed;
	if(ti.rms)
		trainOut(ti, dir, rmsV, rmsV, predsumsV, itemN, dirStat, startAlphaNo, startTiGNNo);
	else
		trainOut(ti, dir, rmsV, rocV, predsumsV, itemN, dirStat, startAlphaNo, startTiGNNo);

	}catch(TE_ERROR err){
Пример #4
0
void 
remove_nodes(Bface_list& flist, ARRAY<Wvec>& blist, double min_dist, ARRAY<OctreeNode*>& t)
{
//    if (flist.num() != blist.num()) {
//       return;
//    }
   assert(flist.num() == blist.num());
   Wpt_list pts = get_pts(flist, blist);
   ARRAY< ARRAY<int> > N;
   ARRAY<bool> to_remove;
   for (int i = 0; i < pts.num(); i++) {
      N += ARRAY<int>();
      to_remove += false;
   }

   for (int i = 0; i < pts.num(); i++) {
      for (int j = 0; j < t[i]->neibors().num(); j++) {
         int index = t[i]->neibors()[j]->get_term_index();
         
         if (index < pts.num())
         {
            if (pts[i].dist(pts[index]) < min_dist) {
               N[i] += index;
               N[index] += i;
            }
         }
         else
         {
            //cerr << "Sps Warning, index > pts.num()" << endl;
         }

      }
   }

   priority_queue< Priority, vector<Priority> > queue;
   ARRAY<int> versions;
   for (int i = 0; i < pts.num(); i++) {
      if (!to_remove[i] && !N[i].empty()) {
         Priority p;
         p._priority = center(pts, N[i]).dist(pts[i]);
         p._index = i;
         p._version = 0;
         queue.push(p);
      }
      versions += 0;
   }

   while (!queue.empty()) {
      Priority p = queue.top();
      queue.pop();
      int r = p._index;
      if (p._version == versions[r]) {
         to_remove[r] = true;
         for (int i = 0; i < N[r].num(); i++) {
            N[N[r][i]] -= r;
            versions[N[r][i]]++;
            if (!N[N[r][i]].empty()) {
               Priority q;
               q._priority = center(pts, N[N[r][i]]).dist(pts[N[r][i]]);
               q._index = N[r][i];
               q._version = versions[N[r][i]];
               queue.push(q);
            }
         }
      }
   }
   versions.clear();

   Bface_list ftemp(flist);
   ARRAY<Wvec> btemp(blist);
   flist.clear();
   blist.clear();
   for (int i = 0; i < ftemp.num(); i++)
      if (!to_remove[i]) {
         flist += ftemp[i];
         blist += btemp[i];
      }
}
Пример #5
0
static int xmp_write(const char *path, const char *buf, size_t size,
		     off_t offset, struct fuse_file_info *fi)
{
	(void) fi;
	(void) offset;

	int res=0;
	int action = COPY;

	ssize_t vsize = 0;
	char *tval = NULL;

	char fpath[PATH_MAX];
	xmp_getfullpath(fpath, path);

	vsize = getxattr(fpath, XATRR_ENCRYPTED_FLAG, NULL, 0);
	tval = malloc(sizeof(*tval)*(vsize));
	vsize = getxattr(fpath, XATRR_ENCRYPTED_FLAG, tval, vsize);

	if (vsize < 0 || memcmp(tval, "false", 5) == 0){
		if(errno == ENODATA){
			fprintf(stderr, "Encryption flag not set, file cannot be read.\n");
		}
		fprintf(stderr, "File unencrypted, reading...\n");
	}
	/* If the attribute exists and is true get size of decrypted file */
	else if (memcmp(tval, "true", 4) == 0){
		fprintf(stderr, "File encrypted, decrypting...\n");
		action = DECRYPT;
	}


	/* If the file to be written to is encrypted */
	if (action == DECRYPT){
		
		FILE *fd = fopen(fpath, "rb+");
		const char *tpath = ftemp(fpath, ".write");
		FILE *dfd = fopen(tpath, "wb+");

		fseek(fd, 0, SEEK_END);
		fseek(fd, 0, SEEK_SET);

		if(!do_crypt(fd, dfd, DECRYPT, ENCFS_DATA->passkey)){
			fprintf(stderr, "Decryption failed, error code: %d\n", res);
    	}

    	fseek(fd, 0, SEEK_SET);

    	res = fwrite(buf, 1, size, dfd);
    	if (res == -1)
		res = -errno;

		fseek(dfd, 0, SEEK_SET);

		if(!do_crypt(dfd, fd, ENCRYPT, ENCFS_DATA->passkey)){
			fprintf(stderr, "Encryption failed, error code: %d\n", res);
		}

		fclose(fd);
		fclose(dfd);
		remove(tpath);
	}
	/* If the file to be written to is unencrypted */
	else if (action == COPY){
		int fd1;
		fprintf(stderr, "File unencrypted, reading...\n");

		fd1 = open(fpath, O_WRONLY);
		if (fd1 == -1)
			return -errno;

		res = pwrite(fd1, buf, size, offset);
		if (res == -1)
			res = -errno;

		close(fd1);
   	}
   	
	free(tval);
	return res;
}
Пример #6
0
static int xmp_getattr(const char *path, struct stat *stbuf)
{
	int res=0;
	int action = COPY;
	ssize_t vsize = 0;
	char *tval = NULL;

	time_t    atime;   	/* time of last access */
	time_t    mtime;   	/* time of last modification */
    time_t    tctime;   	/* time of last status change */
    dev_t     t_dev;     	/* ID of device containing file */
    ino_t     t_ino;     	/* inode number */
    mode_t    mode;    	/* protection */
    nlink_t   t_nlink;   	/* number of hard links */
    uid_t     t_uid;     	/* user ID of owner */
    gid_t     t_gid;     	/* group ID of owner */
    dev_t     t_rdev;    	/* device ID (if special file) */

	char fpath[PATH_MAX];
	xmp_getfullpath(fpath, path);

	res = lstat(fpath, stbuf);
	if (res == -1){
		return -errno;
	}
	
	/* is it a regular file? */
	if (S_ISREG(stbuf->st_mode)){

		/* These file characteristics don't change after decryption so just storing them */
		atime = stbuf->st_atime;
		mtime = stbuf->st_mtime;
		tctime = stbuf->st_ctime;
		t_dev = stbuf->st_dev;
		t_ino = stbuf->st_ino;
		mode = stbuf->st_mode;
		t_nlink = stbuf->st_nlink;
		t_uid = stbuf->st_uid;
		t_gid = stbuf->st_gid;
		t_rdev = stbuf->st_rdev;

		/* Get size of flag value and value itself */
		vsize = getxattr(fpath, XATRR_ENCRYPTED_FLAG, NULL, 0);
		tval = malloc(sizeof(*tval)*(vsize));
		vsize = getxattr(fpath, XATRR_ENCRYPTED_FLAG, tval, vsize);
		
		fprintf(stderr, "Xattr Value: %s\n", tval);

		/* If the specified attribute doesn't exist or it's set to false */
		if (vsize < 0 || memcmp(tval, "false", 5) == 0){
			if(errno == ENODATA){
				fprintf(stderr, "No %s attribute set\n", XATRR_ENCRYPTED_FLAG);
			}
			fprintf(stderr, "File unencrypted, reading...\n");
			action = COPY;
		}
		/* If the attribute exists and is true get size of decrypted file */
		else if (memcmp(tval, "true", 4) == 0){
			fprintf(stderr, "file encrypted, decrypting...\n");
			action = DECRYPT;
		}

		const char *tpath = ftemp(fpath, ".getattr");
		FILE *dfd = fopen(tpath, "wb+");
		FILE *fd = fopen(fpath, "rb");

		fprintf(stderr, "fpath: %s\ntpath: %s\n", fpath, tpath);

		if(!do_crypt(fd, dfd, action, ENCFS_DATA->passkey)){
			fprintf(stderr, "getattr do_crypt failed\n");
    		}

		fclose(fd);
		fclose(dfd);

		/* Get size of decrypted file and store in stat struct */
		res = lstat(tpath, stbuf);
		if (res == -1){
			return -errno;
		}

		/* Put info about file into stat struct*/
		stbuf->st_atime = atime;
		stbuf->st_mtime = mtime;
		stbuf->st_ctime = tctime;
		stbuf->st_dev = t_dev;
		stbuf->st_ino = t_ino;
		stbuf->st_mode = mode;
		stbuf->st_nlink = t_nlink;
		stbuf->st_uid = t_uid;
		stbuf->st_gid = t_gid;
		stbuf->st_rdev = t_rdev;

		free(tval);
		remove(tpath);
	}
	
	return 0;
}
Пример #7
0
int NanoShaperInterface::compute_from_file(int surftype, float gspacing,
                                           float probe_radius,
                                           float skin_parm,
                                           float blob_parm, 
                                           int n, int *ids, float *xyzr, 
                                           int *flgs) {
  const char *nsbin = "NanoShaper";

  // generate output file name and try to create
  char *dirname = vmd_tempfile("");

  int uid = vmd_getuid();
  int rnd = vmd_random() % 999;

  char *filebase = new char[strlen(dirname) + 100];
  sprintf(filebase, "%svmdns.u%d.%d.", dirname, uid, rnd);
  delete [] dirname;

  char *pfilename = new char[strlen(filebase) + 100];
  char *ofilename = new char[strlen(filebase) + 100];
  sprintf(pfilename, "%sprm", filebase);
  sprintf(ofilename, "%sxyzr", filebase);

  FILE *pfile = fopen(pfilename, "wt");
  if (!pfile) {
    delete [] filebase;
    delete [] pfilename;
    delete [] ofilename;
    msgErr << "Failed to create NanoShaper parameter input file" << sendmsg;
    return 0;  // failure
  }

  const char *surfstr = "ses";
  const char *modestr = "normal";
  switch(surftype) {
    case NS_SURF_SES:
      surfstr = "ses";
      modestr = "normal";
      break;

    case NS_SURF_SKIN:
      surfstr = "skin";
      modestr = "normal";
      break;

    case NS_SURF_BLOBBY:
      surfstr = "blobby";
      modestr = "normal";
      break;

    case NS_SURF_POCKETS:
      surfstr = "pockets";
      modestr = "pockets";
      break;
  }

  //
  // Emit surface calculation configuration into NS input file
  // 
  fprintf(pfile, "Operative_Mode = %s\n", modestr);
  fprintf(pfile, "Pocket_Radius_Small = %.1f\n", 1.4);
  fprintf(pfile, "Pocket_Radius_Big = %.1f\n", 3.0);
  fprintf(pfile, "Surface = %s\n", surfstr);

  if (gspacing < 0.05f)
    gspacing = 0.05f;
  fprintf(pfile, "Grid_scale = %.1f\n", 1.0f/gspacing);

  fprintf(pfile, "XYZR_FileName = %s\n", ofilename);
  fprintf(pfile, "Probe_Radius = %.1f\n", probe_radius);
  fprintf(pfile, "Skin_Surface_Parameter = %.2f\n", skin_parm);
  fprintf(pfile, "Blobbyness = %.1f\n", blob_parm);

  // enable all to emulate MSMS
  fprintf(pfile, "Compute_Vertex_Normals = true\n");
  fprintf(pfile, "Save_Mesh_MSMS_Format = true\n");
  fprintf(pfile, "Vertex_Atom_Info = true\n");
 
  // various parameters copied from example input file
  fprintf(pfile, "Grid_perfil = %.1f\n", 70.0);
  fprintf(pfile, "Build_epsilon_maps = false\n");
  fprintf(pfile, "Build_status_map = true\n");
  fprintf(pfile, "Smooth_Mesh = true\n");
  fprintf(pfile, "Triangulation = true\n");

  // SD: optimized value for big structures
  fprintf(pfile, "Max_Probes_Self_Intersections = 5000\n");

  fprintf(pfile, "Self_Intersections_Grid_Coefficient = 5.0\n");
  fprintf(pfile, "Accurate_Triangulation = true\n");

  // Tell NS to store all files by appending to a base filename provided
  // by the caller, so we don't end up with problems on multi-user systems
  // or when multiple VMD sessions are running concurrently on the same
  // machine.  VMD chooses the base filename via OS temp file APIs.
  fprintf(pfile, "Root_FileName = %s\n", filebase);

  // SD: optimized value for big structures
  fprintf(pfile, "Max_skin_patches_per_auxiliary_grid_2d_cell = 2000\n");

  fclose(pfile);

  FILE *ofile = fopen(ofilename, "wt");
  if (!ofile) {
    delete [] ofilename;
    msgErr << "Failed to create NanoShaper atom xyzr input file" << sendmsg;
    return 0;  // failure
  }

  char *facetfilename = new char[strlen(filebase) + 100];
  char *vertfilename = new char[strlen(filebase) + 100];
  char *errfilename = new char[strlen(filebase) + 100];
  char *expfilename = new char[strlen(filebase) + 100];
  char *expindfilename = new char[strlen(filebase) + 100];
  char *areafilename = new char[strlen(filebase) + 100];
  sprintf(facetfilename, "%striangulatedSurf.face", filebase);
  sprintf(vertfilename, "%striangulatedSurf.vert", filebase);
  sprintf(errfilename, "%sstderror.txt", filebase);
  sprintf(expfilename, "%sexposed.xyz", filebase);
  sprintf(expindfilename, "%sexposedIndices.txt", filebase);
  sprintf(areafilename, "%striangleAreas.txt", filebase);

  // temporary files we want to make sure to clean up
  VMDTempFile ptemp(pfilename);
  VMDTempFile otemp(ofilename);
  VMDTempFile ftemp(facetfilename);
  VMDTempFile vtemp(vertfilename);
  VMDTempFile errtemp(errfilename);
  VMDTempFile exptemp(expfilename);
  VMDTempFile expindtemp(expindfilename);
  VMDTempFile areatemp(areafilename);

  //
  // write atom coordinates and radii to the file we send to NanoShaper 
  //
  for (int i=0; i<n; i++) {
    fprintf(ofile, "%f %f %f %f\n", 
            xyzr[4L*i], xyzr[4L*i+1], xyzr[4L*i+2], xyzr[4L*i+3]);
  }
  fclose(ofile);

  //
  // call NanoShaper to calculate the surface for the given atoms
  //
  char *nscmd = new char[2*strlen(ofilename) + strlen(nsbin) + 100];
  sprintf(nscmd, "\"%s\" %s", nsbin, pfilename);
  vmd_system(nscmd);    
  delete [] nscmd;
  delete [] pfilename;

  // 
  // read NanoShaper output files
  //
  if (surftype == NS_SURF_POCKETS) {
    // XXX pockets feature not complete yet
    msgErr << "NanoShaper pockets mode currently unimplemented" << sendmsg;
    return 0;
  } else {
    // Read output files for one of the normal surface modes

    // read facets
    FILE *facetfile = fopen(facetfilename, "r");
    if (!facetfile) {
      msgErr << "Cannot read NanoShaper facet file: " << facetfilename << sendmsg;
      return 0;  // failed
    }
    NanoShaperFace face;

    char trash[256];
    fgets(trash, sizeof(trash), facetfile); // eat text comments and counts
    fgets(trash, sizeof(trash), facetfile);
    fgets(trash, sizeof(trash), facetfile);
    while (fscanf(facetfile, "%d %d %d %d %d",
          face.vertex+0, face.vertex+1, face.vertex+2, &face.surface_type,
          &face.anaface) == 5) {
      face.component = 0;  // XXX Unused by VMD, so why store?
      face.vertex[0]--;
      face.vertex[1]--;
      face.vertex[2]--;
      faces.append(face);
    }
    fclose(facetfile);

    msgInfo << "NanoShaper face count: " << faces.num() << sendmsg;

    // read verts
    FILE *vertfile = fopen(vertfilename, "r");
    if (!vertfile) {
      msgErr << "Cannot read NanoShaper vertex file: " << vertfilename << sendmsg;
      return 0;  // failed
    }
    NanoShaperCoord norm, coord;
    int atomid;  // 1-based atom index
    int l0fa;    // number of of the level 0 SES face
    int l;       // SES face level? (1/2/3)
    fgets(trash, sizeof(trash), vertfile);
    fgets(trash, sizeof(trash), vertfile);
    fgets(trash, sizeof(trash), vertfile);
    while (fscanf(vertfile, "%f %f %f %f %f %f %d %d %d",
          coord.x+0, coord.x+1, coord.x+2, 
          norm.x+0, norm.x+1, norm.x+2, 
          &l0fa, &atomid, &l) == 9) {
      norms.append(norm);
      coords.append(coord);
      atomids.append(atomid-1);
    }
    fclose(vertfile);

    msgInfo << "NanoShaper vert count: " << norms.num() << sendmsg;

    if (ids) {
      for (int i=0; i<atomids.num(); i++) {
        atomids[i] = ids[atomids[i]];
      }
    }
  } 


  return 1; // success
}