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 }
/* * 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; }