Example #1
0
int Network3::run_PLA(double& time, double maxTime, double sampleTime,
					  double& step, double maxStep, double stepInterval,
					  mu::Parser& stop_condition, bool print_on_stop,
					  char* prefix,
					  bool print_cdat, bool print_func, bool print_save_net, bool print_end_net,
					  bool additional_pla_output,
					  bool verbose){

	// Output files
	string outpre(prefix);
	bool print_classif = additional_pla_output;
	// ...

	// Species file (must exist)
	FILE* cdat = NULL;
	string cFile = outpre + ".cdat";
	if ((cdat = fopen(cFile.c_str(),"r"))){
		fclose(cdat);
		cdat = fopen(cFile.c_str(),"a");
	}
	else {
		cout << "Error in Network3::run_PLA(): Concentrations file \"" << cFile << "\" doesn't exist. Exiting." << endl;
		exit(1);
	}

	// Observables file (optional)
	FILE* gdat = NULL;
	string gFile = outpre + ".gdat";
	if ((gdat = fopen(gFile.c_str(),"r"))){
		fclose(gdat);
		gdat = fopen(gFile.c_str(),"a");
	}
	else{
//		cout << "Warning: Groups file \"" << gFile << "\" doesn't exist." << endl;
	}

	// Functions file (optional)
/*	FILE* fdat = NULL;
	string fFile = outpre + ".fdat";
	if ((fdat = fopen(fFile.c_str(),"r"))){
		fclose(fdat);
		fdat = fopen(fFile.c_str(),"a");
	}
	else{
//		cout << "Warning: Functions file \"" << fFile << "\" doesn't exist." << endl;
	}*/

	// PLA-specific output files
	FILE* classif = NULL;
	if (print_classif){
		if ((classif = fopen((outpre+"_classif.pla").c_str(),"r"))){
			fclose(classif);
			classif = fopen((outpre+"_classif.pla").c_str(),"a");
		}
		else{
			cout << "Error in Network3::run_PLA(): 'print_classif' flag set but classifications file \""
				 << (outpre+"_classif.pla") << "\" doesn't exist. Exiting." << endl;
			exit(1);
		}
	}
	// ...

	// Identify observables involved in functions
	vector<unsigned int> funcObs;
	for (unsigned int i=0;i < FUNCTION.size();i++){
		map<string,double*> var = FUNCTION[i]->first->p->GetUsedVar();
		for (unsigned int j=0;j < OBSERVABLE.size();j++){
			if (var.find(OBSERVABLE[j]->first->name) != var.end()){
				bool already = false;
				for (unsigned int k=0;k < funcObs.size() && !already;k++){
					if (funcObs[k] == j){
						already = true;
					}
				}
				if (!already){ // add to the list
					funcObs.push_back(j);
				}
			}
		}
	}

	// Prepare for simulation
	double nextOutputTime = time + sampleTime;
	double nextOutputStep = stepInterval;
	while (nextOutputStep <= step) nextOutputStep += stepInterval;
	bool lastOut = true;

	// Simulation loop
//	PLA_SIM->rc.forceClassifications(RxnClassifier::EXACT_STOCHASTIC);
	string print_net_message;
	while (time < maxTime && step < maxStep && !stop_condition.Eval())
	{
		// Next step
		step++;
		PLA_SIM->nextStep();

		if (PLA_SIM->tau < INFINITY && PLA_SIM->tau > -INFINITY){
			time += PLA_SIM->tau;
		}
		else break;

		// Error check
		if (PLA_SIM->tau <= 0.0){
			cout << "Error in Network3::run_PLA(): tau = " << PLA_SIM->tau << ". Shouldn't happen. Exiting." << endl;
			exit(1);
		}

		// Is it time to output?
		lastOut = false;
		if (time >= nextOutputTime || step >= nextOutputStep) // YES
		{
			// Update all observables
			for (unsigned int i=0;i < OBSERVABLE.size();i++){
				OBSERVABLE[i]->second = OBSERVABLE[i]->first->getValue();
			}
			// Update all functions
			for (unsigned int i=0;i < FUNCTION.size();i++){
				FUNCTION[i]->second = FUNCTION[i]->first->Eval();
			}
			// Output to file
			if (print_cdat) Network3::print_species_concentrations(cdat,time);
			if (gdat) Network3::print_observable_concentrations(gdat,time,print_func);
			if (print_func) Network3::print_function_values(gdat,time);
			if (print_save_net){ // Write current system state to .net file
				// Collect species populations and update network concentrations vector
				double* pops = new double[SPECIES.size()];
				for (unsigned int j=0;j < SPECIES.size();j++){
					pops[j] = SPECIES[j]->population;
				}
				set_conc_network(pops);
				delete pops;
				// Print network w/ current species populations using network::print_network()
				char buf[1000];
				sprintf(buf, "%s_save.net", prefix);
				FILE* out = fopen(buf, "w");
				print_network(out);
				fclose(out);
				print_net_message = " Wrote NET file to " + (string)buf;
//				fprintf(stdout, " Wrote NET file to %s", buf);
			}
			if (print_classif){
				fprintf(classif,"%19.12e",time);
				fprintf(classif," %19.19g",step);
				for (unsigned int v=0;v < PLA_SIM->classif.size();v++){
					fprintf(classif, " %10d", PLA_SIM->classif[v]);
				}
				fprintf(classif,"\n");
				fflush(classif);
			}
			// Output to stdout
			if (verbose){
				cout << "\t" << fixed << setprecision(6) << time << "\t" << setprecision(0) << step;
//				for (unsigned int i=0;i < OBSERVABLE.size();i++){
//					cout << "\t" << OBSERVABLE[i]->second;
//				}
				if (print_save_net){
					fprintf(stdout, "%s", print_net_message.c_str());
				}
				cout << endl;
			}
			// Get next output time and step
			if (time >= nextOutputTime) nextOutputTime += sampleTime;
			if (step >= nextOutputStep) nextOutputStep += stepInterval;
			lastOut = true;
		}
		else{ // NO
			// Only update observables that are involved in functions
			for (unsigned int i=0;i < funcObs.size();i++){
				OBSERVABLE[funcObs[i]]->second = OBSERVABLE[funcObs[i]]->first->getValue();
			}
			// Update all functions
			for (unsigned int i=0;i < FUNCTION.size();i++){
				FUNCTION[i]->second = FUNCTION[i]->first->Eval();
			}
		}
	}

	// Final output
	if (!lastOut)
	{
		// Update all observables
		for (unsigned int i=0;i < OBSERVABLE.size();i++){
			OBSERVABLE[i]->second = OBSERVABLE[i]->first->getValue();
		}
		// Update all functions
		for (unsigned int i=0;i < FUNCTION.size();i++){
			FUNCTION[i]->second = FUNCTION[i]->first->Eval();
		}
		// Output to file
		if (print_cdat) Network3::print_species_concentrations(cdat,time);
		// Don't print if stopping condition met and !print_on_stop (must print to CDAT)
		if (!(stop_condition.Eval() && !print_on_stop)){
			if (gdat) Network3::print_observable_concentrations(gdat,time,print_func);
			if (print_func) Network3::print_function_values(gdat,time);
			string print_net_message;
			if (print_save_net){ // Write current system state to .net file
				// Collect species populations and update network concentrations vector
				double pops[SPECIES.size()];
				for (unsigned int j=0;j < SPECIES.size();j++){
					pops[j] = SPECIES[j]->population;
				}
				set_conc_network(pops);
				// Print network w/ current species populations using network::print_network()
				char buf[1000];
				sprintf(buf, "%s_save.net", prefix);
				FILE* out = fopen(buf, "w");
				print_network(out);
				fclose(out);
				print_net_message = " Wrote NET file to " + (string)buf;
			}
			if (print_classif){
				fprintf(classif,"%19.12e",time);
				for (unsigned int v=0;v < PLA_SIM->classif.size();v++){
					fprintf(classif, " %10d", PLA_SIM->classif[v]);
				}
				fprintf(classif,"\n");
				fflush(classif);
			}
		}
		// Output to stdout
		if (verbose){
			cout << "\t" << fixed << setprecision(6) << time << "\t" << setprecision(0) << step;
//			for (unsigned int i=0;i < OBSERVABLE.size();i++) cout << "\t" << OBSERVABLE[i]->second;
			if (print_save_net) fprintf(stdout, "%s", print_net_message.c_str());
			cout << endl;
		}
	}

	// Messages if stopping conditions met
	if (stop_condition.Eval()){ // Stop condition satisfied
		cout << "Stopping condition " << stop_condition.GetExpr() << "met in PLA simulation." << endl;
	}
//	else if (step >= startStep + maxSteps){ // maxSteps limit reached
//		cout << "Maximum step limit (" << maxSteps << ") reached in PLA simulation." << endl;
//	}

	// If print_end_net = true, collect species populations and update network concentrations vector
	if (print_end_net){
		double pops[SPECIES.size()];
		for (unsigned int j=0;j < SPECIES.size();j++){
			pops[j] = SPECIES[j]->population;
		}
		set_conc_network(pops);
	}

	// Close files
	fclose(cdat);
	if (gdat) fclose(gdat);
//	if (fdat) fclose(fdat);
	if (classif) fclose(classif);

	// Return value
	if (time >= maxTime) return 0;
	else if (step >= maxStep) return -1;
	else return -2; // stop condition met
}
Example #2
0
/*
 * Mail a message on standard input to the people indicated
 * in the passed header.  (Internal interface).
 */
void 
mail1(struct header *hp, int use_to, char *orig_to)
{
	pid_t p, pid;
	int i, s, gotcha;
	char **namelist, *deliver;
	struct name *to, *np;
	FILE *mtf, *fp;
	int remote = rflag != NOSTR || rmail;
	char **t;
	char *deadletter;
	char recfile[PATHSIZE];

	/*
	 * Collect user's mail from standard input.
	 * Get the result as mtf.
	 */

	pid = (pid_t)-1;
	if ((mtf = collect(hp)) == NULL)
		return;
	hp->h_seq = 1;
	if (hp->h_subject == NOSTR)
		hp->h_subject = sflag;
	if (fsize(mtf) == 0 && hp->h_subject == NOSTR) {
		printf(gettext("No message !?!\n"));
		goto out;
	}
	if (intty) {
		printf(gettext("EOT\n"));
		flush();
	}

	/*
	 * If we need to use the To: line to determine the record
	 * file, save a copy of it before it's sorted below.
	 */

	if (use_to && orig_to == NOSTR && hp->h_to != NOSTR)
		orig_to = strcpy((char *)salloc(strlen(hp->h_to)+1), hp->h_to);
	else if (orig_to == NOSTR)
		orig_to = "";

	/*
	 * Now, take the user names from the combined
	 * to and cc lists and do all the alias
	 * processing.
	 */

	senderr = 0;
	to = cat(extract(hp->h_bcc, GBCC),
	     cat(extract(hp->h_to, GTO),
	     extract(hp->h_cc, GCC)));
	to = translate(outpre(elide(usermap(to))));
	if (!senderr)
		mapf(to, myname);
	mechk(to);
	for (gotcha = 0, np = to; np != NIL; np = np->n_flink)
		if ((np->n_type & GDEL) == 0)
			gotcha++;
	hp->h_to = detract(to, GTO);
	hp->h_cc = detract(to, GCC);
	hp->h_bcc = detract(to, GBCC);
	if ((mtf = infix(hp, mtf)) == NULL) {
		fprintf(stderr, gettext(". . . message lost, sorry.\n"));
		return;
	}
	rewind(mtf);
	if (askme && isatty(0)) {
		char ans[64];
		puthead(hp, stdout, GTO|GCC|GBCC, 0);
		printf(gettext("Send? "));
		printf("[yes] ");
		if (fgets(ans, sizeof(ans), stdin) && ans[0] &&
				(tolower(ans[0]) != 'y' && ans[0] != '\n'))
			goto dead;
	}
	if (senderr)
		goto dead;
	/*
	 * Look through the recipient list for names with /'s
	 * in them which we write to as files directly.
	 */
	i = outof(to, mtf);
	rewind(mtf);
	if (!gotcha && !i) {
		printf(gettext("No recipients specified\n"));
		goto dead;
	}
	if (senderr)
		goto dead;

	getrecf(orig_to, recfile, use_to, sizeof (recfile));
	if (recfile != NOSTR && *recfile)
		savemail(safeexpand(recfile), hp, mtf);
	if (!gotcha)
		goto out;
	namelist = unpack(to);
	if (debug) {
		fprintf(stderr, "Recipients of message:\n");
		for (t = namelist; *t != NOSTR; t++)
			fprintf(stderr, " \"%s\"", *t);
		fprintf(stderr, "\n");
		return;
	}

	/*
	 * Wait, to absorb a potential zombie, then
	 * fork, set up the temporary mail file as standard
	 * input for "mail" and exec with the user list we generated
	 * far above. Return the process id to caller in case he
	 * wants to await the completion of mail.
	 */

#ifdef VMUNIX
	while (wait3((int *)0, WNOHANG, (struct rusage *)0) > 0)
		;
#else
#ifdef preSVr4
	wait((int *)0);
#else
	while (waitpid((pid_t)-1, (int *)0, WNOHANG) > 0)
		;
#endif
#endif
	rewind(mtf);
	pid = fork();
	if (pid == (pid_t)-1) {
		perror("fork");
dead:
		deadletter = Getf("DEAD");
		if (fp = fopen(deadletter,
		    value("appenddeadletter") == NOSTR ? "w" : "a")) {
			chmod(deadletter, DEADPERM);
			puthead(hp, fp, GMASK|GCLEN, fsize(mtf) - textpos);
			fseek(mtf, textpos, 0);
			lcwrite(deadletter, mtf, fp,
			    value("appenddeadletter") != NOSTR);
			fclose(fp);
		} else
			perror(deadletter);
		goto out;
	}
	if (pid == 0) {
		sigchild();
#ifdef SIGTSTP
		if (remote == 0) {
			sigset(SIGTSTP, SIG_IGN);
			sigset(SIGTTIN, SIG_IGN);
			sigset(SIGTTOU, SIG_IGN);
		}
#endif
		sigset(SIGHUP, SIG_IGN);
		sigset(SIGINT, SIG_IGN);
		sigset(SIGQUIT, SIG_IGN);
		s = fileno(mtf);
		(void) fdwalk(closefd_walk, &s);
		close(0);
		dup(s);
		close(s);
#ifdef CC
		submit(getpid());
#endif /* CC */
		if ((deliver = value("sendmail")) == NOSTR)
#ifdef SENDMAIL
			deliver = SENDMAIL;
#else
			deliver = MAIL;
#endif
		execvp(safeexpand(deliver), namelist);
		perror(deliver);
		exit(1);
	}

	if (value("sendwait")!=NOSTR)
		remote++;
out:
	if (remote) {
		while ((p = wait(&s)) != pid && p != (pid_t)-1)
			;
		if (s != 0)
			senderr++;
		pid = 0;
	}
	fclose(mtf);
	return;
}