/* Log an error due to failed memory allocation, but do not exit (va_list * version). */ void mcell_allocfailedv_nodie(char const *fmt, va_list args) { fprintf(mcell_get_error_file(), "Fatal error: "); mcell_errorv_raw(fmt, args); fprintf(mcell_get_error_file(), "\n"); fprintf(mcell_get_error_file(), "Fatal error: Out of memory\n\n"); mem_dump_stats(mcell_get_error_file()); }
/* Log an error due to a failed standard library call, and exit (va_list * version). */ void mcell_perrorv_nodie(int err, char const *fmt, va_list args) { char buffer[2048]; fprintf(mcell_get_error_file(), "Fatal error: "); mcell_errorv_raw(fmt, args); #ifdef STRERROR_R_CHAR_P fprintf(mcell_get_error_file(), ": %s\n", strerror_r(err, buffer, sizeof(buffer))); #else if (strerror_r(err, buffer, sizeof(buffer)) == 0) fprintf(mcell_get_error_file(), ": %s\n", buffer); else fprintf(mcell_get_error_file(), "\n"); #endif }
static void emergency_output_signal_handler(int signo) { fprintf(mcell_get_error_file(), "*****************************\n" "MCell dying due to signal %d.\n" "Please report this to the mcell developers by emailing <%s>.\n" "*****************************\n", signo, PACKAGE_BUGREPORT); if (emergency_output_hook_enabled) { emergency_output_hook_enabled = 0; int n_errors = flush_reaction_output(global_state); if (n_errors == 0) mcell_error_raw("Reaction output was successfully flushed to disk.\n"); else if (n_errors == 1) mcell_error_raw( "An error occurred while flushing reaction output to disk.\n"); else mcell_error_raw( "%d errors occurred while flushing reaction output to disk.\n", n_errors); } raise(signo); /* We shouldn't get here, but we might if, for instance, SA_NODEFER is * unsupported. */ _exit(128 + signo); }
/* Log an error and exit (va_list version). */ void mcell_internal_errorv_(char const *file, unsigned int line, char const *func, char const *fmt, va_list args) { fprintf(mcell_get_error_file(), "****************\n"); fprintf(mcell_get_error_file(), "INTERNAL ERROR at %s:%u [%s]: ", file, line, func); mcell_errorv_raw(fmt, args); fprintf(mcell_get_error_file(), "\n"); fprintf(mcell_get_error_file(), "MCell has detected an internal program error.\n"); fprintf(mcell_get_error_file(), "Please report this error to the MCell developers at <%s>.\n", PACKAGE_BUGREPORT); fprintf(mcell_get_error_file(), "****************\n"); mcell_die(); }
/************************************************************************* * * function printing warnings for high reaction probabilties (if * requested) for the given reaction. * *************************************************************************/ void issue_reaction_probability_warnings( struct notifications *notify, struct rxn *rx) { if (rx->cum_probs[rx->n_pathways - 1] > notify->reaction_prob_warn) { FILE *warn_file = mcell_get_log_file(); if (notify->high_reaction_prob != WARN_COPE) { if (notify->high_reaction_prob == WARN_ERROR) { warn_file = mcell_get_error_file(); fprintf(warn_file, "Error: High "); } else { fprintf(warn_file, "Warning: High "); } if (rx->n_reactants == 1) { fprintf(warn_file, "total probability %.4e for %s[%d] -> ...\n", rx->cum_probs[rx->n_pathways - 1], rx->players[0]->sym->name, rx->geometries[0]); } else if (rx->n_reactants == 2) { fprintf(warn_file, "total probability %.4e for %s[%d] + %s[%d] " "-> ...\n", rx->cum_probs[rx->n_pathways - 1], rx->players[0]->sym->name, rx->geometries[0], rx->players[1]->sym->name, rx->geometries[1]); } else { fprintf(warn_file, "total probability %.4e for %s[%d] + %s[%d] + " "%s[%d] -> ...\n", rx->cum_probs[rx->n_pathways - 1], rx->players[0]->sym->name, rx->geometries[0], rx->players[1]->sym->name, rx->geometries[1], rx->players[2]->sym->name, rx->geometries[2]); } } if (notify->high_reaction_prob == WARN_ERROR) { mcell_die(); } } return; }
// This will either be called by mcell_errorv (which dies) or mcell_error_nodie // (which obviously doesn't die), so we shouldn't list this as a fatal error. void mcell_errorv_nodie(char const *fmt, va_list args) { fprintf(mcell_get_error_file(), "Error: "); mcell_errorv_raw(fmt, args); fprintf(mcell_get_error_file(), "\n"); }
/* Log a warning (va_list version). */ void mcell_warnv(char const *fmt, va_list args) { fprintf(mcell_get_error_file(), "Warning: "); mcell_errorv_raw(fmt, args); fprintf(mcell_get_error_file(), "\n"); }
/* Log a message (va_list version). */ void mcell_errorv_raw(char const *fmt, va_list args) { vfprintf(mcell_get_error_file(), fmt, args); }
/************************************************************************* check_probs: In: A reaction struct The current time Out: No return value. Probabilities are updated if necessary. Memory isn't reclaimed. Note: This isn't meant for really heavy-duty use (multiple pathways with rapidly changing rates)--if you want that, the code should probably be rewritten to accumulate probability changes from the list as it goes (and the list should be sorted by pathway, too). Note: We're still displaying geometries here, rather than orientations. Perhaps that should be fixed. *************************************************************************/ void update_probs(struct volume *world, struct rxn *rx, double t) { int j, k; double dprob; struct t_func *tv; int did_something = 0; double new_prob = 0; for (tv = rx->prob_t; tv != NULL && tv->time < t; tv = tv->next) { j = tv->path; if (j == 0) dprob = tv->value - rx->cum_probs[0]; else dprob = tv->value - (rx->cum_probs[j] - rx->cum_probs[j - 1]); for (k = tv->path; k < rx->n_pathways; k++) rx->cum_probs[k] += dprob; rx->max_fixed_p += dprob; rx->min_noreaction_p += dprob; did_something++; /* Changing probabilities is easy. Now lots of logic to notify user, or * not. */ if (world->notify->time_varying_reactions == NOTIFY_FULL && rx->cum_probs[j] >= world->notify->reaction_prob_notify) { if (j == 0) new_prob = rx->cum_probs[0]; else new_prob = rx->cum_probs[j] - rx->cum_probs[j - 1]; if (world->chkpt_seq_num > 1) { if (tv->next != NULL) { if (tv->next->time < t) continue; /* do not print messages */ } } if (rx->n_reactants == 1) { mcell_log_raw("Probability %.4e set for %s[%d] -> ", new_prob, rx->players[0]->sym->name, rx->geometries[0]); } else if (rx->n_reactants == 2) { mcell_log_raw("Probability %.4e set for %s[%d] + %s[%d] -> ", new_prob, rx->players[0]->sym->name, rx->geometries[0], rx->players[1]->sym->name, rx->geometries[1]); } else { mcell_log_raw("Probability %.4e set for %s[%d] + %s[%d] + %s[%d] -> ", new_prob, rx->players[0]->sym->name, rx->geometries[0], rx->players[1]->sym->name, rx->geometries[1], rx->players[2]->sym->name, rx->geometries[2]); } for (unsigned int n_product = rx->product_idx[j]; n_product < rx->product_idx[j + 1]; n_product++) { if (rx->players[n_product] != NULL) mcell_log_raw("%s[%d] ", rx->players[n_product]->sym->name, rx->geometries[n_product]); } mcell_log_raw("\n"); } if ((new_prob > 1.0) && (!world->reaction_prob_limit_flag)) { world->reaction_prob_limit_flag = 1; } } rx->prob_t = tv; if (!did_something) return; /* Now we have to see if we need to warn the user. */ if (rx->cum_probs[rx->n_pathways - 1] > world->notify->reaction_prob_warn) { FILE *warn_file = mcell_get_log_file(); if (world->notify->high_reaction_prob != WARN_COPE) { if (world->notify->high_reaction_prob == WARN_ERROR) { warn_file = mcell_get_error_file(); fprintf(warn_file, "Error: High "); } else fprintf(warn_file, "Warning: High "); if (rx->n_reactants == 1) { fprintf(warn_file, "total probability %.4e for %s[%d] -> ...\n", rx->cum_probs[rx->n_pathways - 1], rx->players[0]->sym->name, rx->geometries[0]); } else if (rx->n_reactants == 2) { fprintf( warn_file, "total probability %.4e for %s[%d] + %s[%d] -> ...\n", rx->cum_probs[rx->n_pathways - 1], rx->players[0]->sym->name, rx->geometries[0], rx->players[1]->sym->name, rx->geometries[1]); } else { fprintf(warn_file, "total probability %.4e for %s[%d] + %s[%d] + %s[%d] -> ...\n", rx->cum_probs[rx->n_pathways - 1], rx->players[0]->sym->name, rx->geometries[0], rx->players[1]->sym->name, rx->geometries[1], rx->players[2]->sym->name, rx->geometries[2]); } } if (world->notify->high_reaction_prob == WARN_ERROR) mcell_die(); } return; }