00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "colvarmodule.h"
00011 #include "colvarproxy.h"
00012 #include "colvar.h"
00013 #include "colvarbias_histogram.h"
00014
00015
00016 colvarbias_histogram::colvarbias_histogram(char const *key)
00017 : colvarbias(key),
00018 grid(NULL), out_name("")
00019 {
00020 provide(f_cvb_bypass_ext_lagrangian);
00021 }
00022
00023
00024 int colvarbias_histogram::init(std::string const &conf)
00025 {
00026 colvarbias::init(conf);
00027 cvm::main()->cite_feature("Histogram colvar bias implementation");
00028
00029 enable(f_cvb_scalar_variables);
00030 enable(f_cvb_history_dependent);
00031
00032 size_t i;
00033
00034 get_keyval(conf, "outputFile", out_name, "");
00035
00036 std::string default_name_dx = this->num_variables() > 2 ? "" : "none";
00037 get_keyval(conf, "outputFileDX", out_name_dx, default_name_dx);
00038
00040
00041
00042
00043
00044 colvar_array_size = 0;
00045 {
00046 bool colvar_array = false;
00047 get_keyval(conf, "gatherVectorColvars", colvar_array, colvar_array);
00048
00049 if (colvar_array) {
00050 for (i = 0; i < num_variables(); i++) {
00051 if (colvars[i]->value().type() != colvarvalue::type_vector) {
00052 cvm::error("Error: used gatherVectorColvars with non-vector colvar.\n", COLVARS_INPUT_ERROR);
00053 return COLVARS_INPUT_ERROR;
00054 }
00055 if (i == 0) {
00056 colvar_array_size = colvars[i]->value().size();
00057 if (colvar_array_size < 1) {
00058 cvm::error("Error: vector variable has dimension less than one.\n", COLVARS_INPUT_ERROR);
00059 return COLVARS_INPUT_ERROR;
00060 }
00061 } else {
00062 if (colvar_array_size != colvars[i]->value().size()) {
00063 cvm::error("Error: trying to combine vector colvars of different lengths.\n", COLVARS_INPUT_ERROR);
00064 return COLVARS_INPUT_ERROR;
00065 }
00066 }
00067 }
00068 } else {
00069 for (i = 0; i < num_variables(); i++) {
00070 if (colvars[i]->value().type() != colvarvalue::type_scalar) {
00071 cvm::error("Error: only scalar colvars are supported when gatherVectorColvars is off.\n", COLVARS_INPUT_ERROR);
00072 return COLVARS_INPUT_ERROR;
00073 }
00074 }
00075 }
00076 }
00077
00078 if (colvar_array_size > 0) {
00079 weights.assign(colvar_array_size, 1.0);
00080 get_keyval(conf, "weights", weights, weights);
00081 }
00082
00083 for (i = 0; i < num_variables(); i++) {
00084 colvars[i]->enable(f_cv_grid);
00085 }
00086
00087 grid = new colvar_grid_scalar();
00088 grid->init_from_colvars(colvars);
00089
00090 if (is_enabled(f_cvb_bypass_ext_lagrangian)) {
00091 grid->request_actual_value();
00092 }
00093
00094 {
00095 std::string grid_conf;
00096 if (key_lookup(conf, "histogramGrid", &grid_conf)) {
00097 grid->parse_params(grid_conf);
00098 grid->check_keywords(grid_conf, "histogramGrid");
00099 }
00100 }
00101
00102 return COLVARS_OK;
00103 }
00104
00105
00106 colvarbias_histogram::~colvarbias_histogram()
00107 {
00108 if (grid) {
00109 delete grid;
00110 grid = NULL;
00111 }
00112 }
00113
00114
00115 int colvarbias_histogram::update()
00116 {
00117 int error_code = COLVARS_OK;
00118
00119 error_code |= colvarbias::update();
00120
00121 if (cvm::debug()) {
00122 cvm::log("Updating histogram bias " + this->name);
00123 }
00124
00125
00126 bin.assign(num_variables(), 0);
00127
00128 if (out_name.size() == 0) {
00129
00130
00131 if (cvm::step_relative() == 0) {
00132 out_name = cvm::output_prefix() + "." + this->name + ".dat";
00133 cvm::log("Histogram " + this->name + " will be written to file \"" + out_name + "\"\n");
00134 }
00135 }
00136
00137 if (out_name_dx.size() == 0) {
00138 if (cvm::step_relative() == 0) {
00139 out_name_dx = cvm::output_prefix() + "." + this->name + ".dx";
00140 cvm::log("Histogram " + this->name + " will be written to file \"" + out_name_dx + "\"\n");
00141 }
00142 }
00143
00144 if (colvar_array_size == 0) {
00145
00146 size_t i;
00147 for (i = 0; i < num_variables(); i++) {
00148 bin[i] = grid->current_bin_scalar(i);
00149 }
00150
00151 if (can_accumulate_data()) {
00152 if (grid->index_ok(bin)) {
00153 grid->acc_value(bin, 1.0);
00154 }
00155 }
00156 } else {
00157
00158 size_t iv, i;
00159 for (iv = 0; iv < colvar_array_size; iv++) {
00160 for (i = 0; i < num_variables(); i++) {
00161 bin[i] = grid->current_bin_scalar(i, iv);
00162 }
00163
00164 if (grid->index_ok(bin)) {
00165 grid->acc_value(bin, weights[iv]);
00166 }
00167 }
00168 }
00169
00170 error_code |= cvm::get_error();
00171 return error_code;
00172 }
00173
00174
00175 int colvarbias_histogram::write_output_files()
00176 {
00177 if (!has_data) {
00178
00179 return COLVARS_OK;
00180 }
00181
00182 int error_code = COLVARS_OK;
00183
00184 if (out_name.size() && out_name != "none") {
00185 cvm::log("Writing the histogram file \""+out_name+"\".\n");
00186 error_code |= grid->write_multicol(out_name, "histogram output file");
00187 }
00188
00189 if (out_name_dx.size() && out_name_dx != "none") {
00190 cvm::log("Writing the histogram file \""+out_name_dx+"\".\n");
00191 error_code |= grid->write_opendx(out_name_dx, "histogram DX output file");
00192 }
00193
00194 return error_code;
00195 }
00196
00197
00198 std::istream & colvarbias_histogram::read_state_data(std::istream& is)
00199 {
00200 if (! read_state_data_key(is, "grid")) {
00201 return is;
00202 }
00203 if (! grid->read_raw(is)) {
00204 return is;
00205 }
00206
00207 return is;
00208 }
00209
00210
00211 std::ostream & colvarbias_histogram::write_state_data(std::ostream& os)
00212 {
00213 std::ios::fmtflags flags(os.flags());
00214 os.setf(std::ios::fmtflags(0), std::ios::floatfield);
00215 os << "grid\n";
00216 grid->write_raw(os, 8);
00217 os.flags(flags);
00218 return os;
00219 }