void mde_delta_h_coll_handle_block(t_mde_delta_h_coll *dhc, t_enxframe *fr, int nblock) { int i; t_enxblock *blk; /* add one block with one subblock as the collection's own data */ nblock++; add_blocks_enxframe(fr, nblock); blk=fr->block + (nblock-1); add_subblocks_enxblock(blk, 1); dhc->subblock_d[0] = dhc->temperature; /* temperature */ dhc->subblock_d[1] = dhc->start_time; /* time of first sample */ dhc->subblock_d[2] = dhc->delta_time; /* time difference between samples */ dhc->subblock_d[3] = dhc->start_lambda; /* lambda at starttime */ dhc->subblock_d[4] = dhc->delta_lambda; /* lambda diff. between samples */ blk->id=enxDHCOLL; blk->sub[0].nr=5; blk->sub[0].type=xdr_datatype_double; blk->sub[0].dval=dhc->subblock_d; for(i=0;i<dhc->ndh;i++) { nblock++; add_blocks_enxframe(fr, nblock); blk=fr->block + (nblock-1); mde_delta_h_handle_block(dhc->dh+i, blk); } }
void print_ebin(ener_file_t fp_ene, gmx_bool bEne, gmx_bool bDR, gmx_bool bOR, FILE *log, gmx_int64_t step, double time, int mode, t_mdebin *md, t_fcdata *fcd, gmx_groups_t *groups, t_grpopts *opts) { /*static char **grpnms=NULL;*/ char buf[246]; int i, j, n, ni, nj, b; int ndisre = 0; real *disre_rm3tav, *disre_rt; /* these are for the old-style blocks (1 subblock, only reals), because there can be only one per ID for these */ int nr[enxNR]; int id[enxNR]; real *block[enxNR]; t_enxframe fr; switch (mode) { case eprNORMAL: init_enxframe(&fr); fr.t = time; fr.step = step; fr.nsteps = md->ebin->nsteps; fr.dt = md->delta_t; fr.nsum = md->ebin->nsum; fr.nre = (bEne) ? md->ebin->nener : 0; fr.ener = md->ebin->e; ndisre = bDR ? fcd->disres.npair : 0; disre_rm3tav = fcd->disres.rm3tav; disre_rt = fcd->disres.rt; /* Optional additional old-style (real-only) blocks. */ for (i = 0; i < enxNR; i++) { nr[i] = 0; } if (fcd->orires.nr > 0 && bOR) { diagonalize_orires_tensors(&(fcd->orires)); nr[enxOR] = fcd->orires.nr; block[enxOR] = fcd->orires.otav; id[enxOR] = enxOR; nr[enxORI] = (fcd->orires.oinsl != fcd->orires.otav) ? fcd->orires.nr : 0; block[enxORI] = fcd->orires.oinsl; id[enxORI] = enxORI; nr[enxORT] = fcd->orires.nex*12; block[enxORT] = fcd->orires.eig; id[enxORT] = enxORT; } /* whether we are going to wrte anything out: */ if (fr.nre || ndisre || nr[enxOR] || nr[enxORI]) { /* the old-style blocks go first */ fr.nblock = 0; for (i = 0; i < enxNR; i++) { if (nr[i] > 0) { fr.nblock = i + 1; } } add_blocks_enxframe(&fr, fr.nblock); for (b = 0; b < fr.nblock; b++) { add_subblocks_enxblock(&(fr.block[b]), 1); fr.block[b].id = id[b]; fr.block[b].sub[0].nr = nr[b]; #if !GMX_DOUBLE fr.block[b].sub[0].type = xdr_datatype_float; fr.block[b].sub[0].fval = block[b]; #else fr.block[b].sub[0].type = xdr_datatype_double; fr.block[b].sub[0].dval = block[b]; #endif } /* check for disre block & fill it. */ if (ndisre > 0) { int db = fr.nblock; fr.nblock += 1; add_blocks_enxframe(&fr, fr.nblock); add_subblocks_enxblock(&(fr.block[db]), 2); fr.block[db].id = enxDISRE; fr.block[db].sub[0].nr = ndisre; fr.block[db].sub[1].nr = ndisre; #if !GMX_DOUBLE fr.block[db].sub[0].type = xdr_datatype_float; fr.block[db].sub[1].type = xdr_datatype_float; fr.block[db].sub[0].fval = disre_rt; fr.block[db].sub[1].fval = disre_rm3tav; #else fr.block[db].sub[0].type = xdr_datatype_double; fr.block[db].sub[1].type = xdr_datatype_double; fr.block[db].sub[0].dval = disre_rt; fr.block[db].sub[1].dval = disre_rm3tav; #endif } /* here we can put new-style blocks */ /* Free energy perturbation blocks */ if (md->dhc) { mde_delta_h_coll_handle_block(md->dhc, &fr, fr.nblock); } /* we can now free & reset the data in the blocks */ if (md->dhc) { mde_delta_h_coll_reset(md->dhc); } /* do the actual I/O */ do_enx(fp_ene, &fr); if (fr.nre) { /* We have stored the sums, so reset the sum history */ reset_ebin_sums(md->ebin); } } free_enxframe(&fr); break; case eprAVER: if (log) { pprint(log, "A V E R A G E S", md); } break; case eprRMS: if (log) { pprint(log, "R M S - F L U C T U A T I O N S", md); } break; default: gmx_fatal(FARGS, "Invalid print mode (%d)", mode); } if (log) { for (i = 0; i < opts->ngtc; i++) { if (opts->annealing[i] != eannNO) { fprintf(log, "Current ref_t for group %s: %8.1f\n", *(groups->grpname[groups->grps[egcTC].nm_ind[i]]), opts->ref_t[i]); } } if (mode == eprNORMAL && fcd->orires.nr > 0) { print_orires_log(log, &(fcd->orires)); } fprintf(log, " Energies (%s)\n", unit_energy); pr_ebin(log, md->ebin, md->ie, md->f_nre+md->nCrmsd, 5, mode, TRUE); fprintf(log, "\n"); if (mode == eprAVER) { if (md->bDynBox) { pr_ebin(log, md->ebin, md->ib, md->bTricl ? NTRICLBOXS : NBOXS, 5, mode, TRUE); fprintf(log, "\n"); } if (md->bConstrVir) { fprintf(log, " Constraint Virial (%s)\n", unit_energy); pr_ebin(log, md->ebin, md->isvir, 9, 3, mode, FALSE); fprintf(log, "\n"); fprintf(log, " Force Virial (%s)\n", unit_energy); pr_ebin(log, md->ebin, md->ifvir, 9, 3, mode, FALSE); fprintf(log, "\n"); } fprintf(log, " Total Virial (%s)\n", unit_energy); pr_ebin(log, md->ebin, md->ivir, 9, 3, mode, FALSE); fprintf(log, "\n"); fprintf(log, " Pressure (%s)\n", unit_pres_bar); pr_ebin(log, md->ebin, md->ipres, 9, 3, mode, FALSE); fprintf(log, "\n"); if (md->bMu) { fprintf(log, " Total Dipole (%s)\n", unit_dipole_D); pr_ebin(log, md->ebin, md->imu, 3, 3, mode, FALSE); fprintf(log, "\n"); } if (md->nE > 1) { if (md->print_grpnms == NULL) { snew(md->print_grpnms, md->nE); n = 0; for (i = 0; (i < md->nEg); i++) { ni = groups->grps[egcENER].nm_ind[i]; for (j = i; (j < md->nEg); j++) { nj = groups->grps[egcENER].nm_ind[j]; sprintf(buf, "%s-%s", *(groups->grpname[ni]), *(groups->grpname[nj])); md->print_grpnms[n++] = gmx_strdup(buf); } } } sprintf(buf, "Epot (%s)", unit_energy); fprintf(log, "%15s ", buf); for (i = 0; (i < egNR); i++) { if (md->bEInd[i]) { fprintf(log, "%12s ", egrp_nm[i]); } } fprintf(log, "\n"); for (i = 0; (i < md->nE); i++) { fprintf(log, "%15s", md->print_grpnms[i]); pr_ebin(log, md->ebin, md->igrp[i], md->nEc, md->nEc, mode, FALSE); } fprintf(log, "\n"); } if (md->nTC > 1) { pr_ebin(log, md->ebin, md->itemp, md->nTC, 4, mode, TRUE); fprintf(log, "\n"); } if (md->nU > 1) { fprintf(log, "%15s %12s %12s %12s\n", "Group", "Ux", "Uy", "Uz"); for (i = 0; (i < md->nU); i++) { ni = groups->grps[egcACC].nm_ind[i]; fprintf(log, "%15s", *groups->grpname[ni]); pr_ebin(log, md->ebin, md->iu+3*i, 3, 3, mode, FALSE); } fprintf(log, "\n"); } } } }
/* write the metadata associated with all the du blocks, and call handle_block to write out all the du blocks */ void mde_delta_h_coll_handle_block(t_mde_delta_h_coll *dhc, t_enxframe *fr, int nblock) { int i; t_enxblock *blk; /* add one block with one subblock as the collection's own data */ nblock++; add_blocks_enxframe(fr, nblock); blk = fr->block + (nblock-1); /* only allocate lambda vector component blocks if they must be written out for backward compatibility */ if (dhc->native_lambda_components != NULL) { add_subblocks_enxblock(blk, 2); } else { add_subblocks_enxblock(blk, 1); } dhc->subblock_d[0] = dhc->temperature; /* temperature */ dhc->subblock_d[1] = dhc->start_time; /* time of first sample */ dhc->subblock_d[2] = dhc->delta_time; /* time difference between samples */ dhc->subblock_d[3] = dhc->start_lambda; /* old-style lambda at starttime */ dhc->subblock_d[4] = dhc->delta_lambda; /* lambda diff. between samples */ /* set the lambda vector components if they exist */ if (dhc->native_lambda_components != NULL) { for (i = 0; i < dhc->n_lambda_vec; i++) { dhc->subblock_d[5+i] = dhc->native_lambda_vec[i]; } } blk->id = enxDHCOLL; blk->sub[0].nr = 5 + dhc->n_lambda_vec; blk->sub[0].type = xdr_datatype_double; blk->sub[0].dval = dhc->subblock_d; if (dhc->native_lambda_components != NULL) { dhc->subblock_i[0] = dhc->lambda_index; /* set the lambda vector component IDs if they exist */ dhc->subblock_i[1] = dhc->n_lambda_vec; for (i = 0; i < dhc->n_lambda_vec; i++) { dhc->subblock_i[i+2] = dhc->native_lambda_components[i]; } blk->sub[1].nr = 2 + dhc->n_lambda_vec; blk->sub[1].type = xdr_datatype_int; blk->sub[1].ival = dhc->subblock_i; } for (i = 0; i < dhc->ndh; i++) { nblock++; add_blocks_enxframe(fr, nblock); blk = fr->block + (nblock-1); mde_delta_h_handle_block(dhc->dh+i, blk); } }
void mde_delta_h_handle_block(t_mde_delta_h *dh, t_enxblock *blk) { /* first check which type we should use: histogram or raw data */ if (dh->nhist == 0) { int i; /* We write raw data. Raw data consists of 3 subblocks: an int metadata block with type and derivative index, a foreign lambda block and and the data itself */ add_subblocks_enxblock(blk, 3); blk->id = enxDH; /* subblock 1 */ dh->subblock_meta_i[0] = dh->type; /* block data type */ dh->subblock_meta_i[1] = dh->derivative; /* derivative direction if applicable (in indices starting from first coord in the main delta_h_coll) */ blk->sub[0].nr = 2; blk->sub[0].type = xdr_datatype_int; blk->sub[0].ival = dh->subblock_meta_i; /* subblock 2 */ for (i = 0; i < dh->nlambda; i++) { dh->subblock_meta_d[i] = dh->lambda[i]; } blk->sub[1].nr = dh->nlambda; blk->sub[1].type = xdr_datatype_double; blk->sub[1].dval = dh->subblock_meta_d; /* subblock 3 */ /* check if there's actual data to be written. */ /*if (dh->ndh > 1)*/ if (dh->ndh > 0) { unsigned int i; blk->sub[2].nr = dh->ndh; /* For F@H for now. */ #undef GMX_DOUBLE #ifndef GMX_DOUBLE blk->sub[2].type = xdr_datatype_float; for (i = 0; i < dh->ndh; i++) { dh->dhf[i] = (float)dh->dh[i]; } blk->sub[2].fval = dh->dhf; #else blk->sub[2].type = xdr_datatype_double; blk->sub[2].dval = dh->dh; #endif dh->written = TRUE; } else { blk->sub[2].nr = 0; #ifndef GMX_DOUBLE blk->sub[2].type = xdr_datatype_float; blk->sub[2].fval = NULL; #else blk->sub[2].type = xdr_datatype_double; blk->sub[2].dval = NULL; #endif } } else { int nhist_written = 0; int i; int k; /* TODO histogram metadata */ /* check if there's actual data to be written. */ if (dh->ndh > 1) { gmx_bool prev_complete = FALSE; /* Make the histogram(s) */ for (i = 0; i < dh->nhist; i++) { if (!prev_complete) { /* the first histogram is always normal, and the second one is always reverse */ mde_delta_h_make_hist(dh, i, i == 1); nhist_written++; /* check whether this histogram contains all data: if the last bin is 0, it does */ if (dh->bin[i][dh->nbins-1] == 0) { prev_complete = TRUE; } if (!dh->derivative) { prev_complete = TRUE; } } } dh->written = TRUE; } /* A histogram consists of 2, 3 or 4 subblocks: the foreign lambda value + histogram spacing, the starting point, and the histogram data (0, 1 or 2 blocks). */ add_subblocks_enxblock(blk, nhist_written+2); blk->id = enxDHHIST; /* subblock 1: the lambda value + the histogram spacing */ if (dh->nlambda == 1) { /* for backward compatibility */ dh->subblock_meta_d[0] = dh->lambda[0]; } else { dh->subblock_meta_d[0] = -1; for (i = 0; i < dh->nlambda; i++) { dh->subblock_meta_d[2+i] = dh->lambda[i]; } } dh->subblock_meta_d[1] = dh->dx; blk->sub[0].nr = 2+ ((dh->nlambda > 1) ? dh->nlambda : 0); blk->sub[0].type = xdr_datatype_double; blk->sub[0].dval = dh->subblock_meta_d; /* subblock 2: the starting point(s) as a long integer */ dh->subblock_meta_l[0] = nhist_written; dh->subblock_meta_l[1] = dh->type; /*dh->derivative ? 1 : 0;*/ k = 2; for (i = 0; i < nhist_written; i++) { dh->subblock_meta_l[k++] = dh->x0[i]; } /* append the derivative data */ dh->subblock_meta_l[k++] = dh->derivative; blk->sub[1].nr = nhist_written+3; blk->sub[1].type = xdr_datatype_large_int; blk->sub[1].lval = dh->subblock_meta_l; /* subblock 3 + 4 : the histogram data */ for (i = 0; i < nhist_written; i++) { blk->sub[i+2].nr = dh->maxbin[i]+1; /* it's +1 because size=index+1 in C */ blk->sub[i+2].type = xdr_datatype_int; blk->sub[i+2].ival = dh->bin[i]; } } }
static gmx_bool do_eheader(ener_file_t ef,int *file_version,t_enxframe *fr, int nre_test,gmx_bool *bWrongPrecision,gmx_bool *bOK) { int magic=-7777777; real first_real_to_check; int b,i,zero=0,dum=0; gmx_bool bRead = gmx_fio_getread(ef->fio); int tempfix_nr=0; int ndisre=0; int startb=0; #ifndef GMX_DOUBLE xdr_datatype dtreal=xdr_datatype_float; #else xdr_datatype dtreal=xdr_datatype_double; #endif if (nre_test >= 0) { *bWrongPrecision = FALSE; } *bOK=TRUE; /* The original energy frame started with a real, * so we have to use a real for compatibility. * This is VERY DIRTY code, since do_eheader can be called * with the wrong precision set and then we could read r > -1e10, * while actually the intention was r < -1e10. * When nre_test >= 0, do_eheader should therefore terminate * before the number of i/o calls starts depending on what has been read * (which is the case for for instance the block sizes for variable * number of blocks, where this number is read before). */ first_real_to_check = -2e10; if (!gmx_fio_do_real(ef->fio, first_real_to_check)) { return FALSE; } if (first_real_to_check > -1e10) { /* Assume we are reading an old format */ *file_version = 1; fr->t = first_real_to_check; if (!gmx_fio_do_int(ef->fio, dum)) *bOK = FALSE; fr->step = dum; } else { if (!gmx_fio_do_int(ef->fio, magic)) *bOK = FALSE; if (magic != -7777777) { enx_warning("Energy header magic number mismatch, this is not a GROMACS edr file"); *bOK=FALSE; return FALSE; } *file_version = enx_version; if (!gmx_fio_do_int(ef->fio, *file_version)) *bOK = FALSE; if (*bOK && *file_version > enx_version) { gmx_fatal(FARGS,"reading tpx file (%s) version %d with version %d program",gmx_fio_getname(ef->fio),file_version,enx_version); } if (!gmx_fio_do_double(ef->fio, fr->t)) *bOK = FALSE; if (!gmx_fio_do_gmx_large_int(ef->fio, fr->step)) *bOK = FALSE; if (!bRead && fr->nsum == 1) { /* Do not store sums of length 1, * since this does not add information. */ if (!gmx_fio_do_int(ef->fio, zero)) *bOK = FALSE; } else { if (!gmx_fio_do_int(ef->fio, fr->nsum)) *bOK = FALSE; } if (*file_version >= 3) { if (!gmx_fio_do_gmx_large_int(ef->fio, fr->nsteps)) *bOK = FALSE; } else { fr->nsteps = max(1,fr->nsum); } if (*file_version >= 5) { if (!gmx_fio_do_double(ef->fio, fr->dt)) *bOK = FALSE; } else { fr->dt = 0; } } if (!gmx_fio_do_int(ef->fio, fr->nre)) *bOK = FALSE; if (*file_version < 4) { if (!gmx_fio_do_int(ef->fio, ndisre)) *bOK = FALSE; } else { /* now reserved for possible future use */ if (!gmx_fio_do_int(ef->fio, dum)) *bOK = FALSE; } if (!gmx_fio_do_int(ef->fio, fr->nblock)) *bOK = FALSE; if (fr->nblock < 0) *bOK=FALSE; if (ndisre!=0) { if (*file_version >= 4) { enx_warning("Distance restraint blocks in old style in new style file"); *bOK=FALSE; return FALSE; } fr->nblock+=1; } /* Frames could have nre=0, so we can not rely only on the fr->nre check */ if (bRead && nre_test >= 0 && ((fr->nre > 0 && fr->nre != nre_test) || fr->nre < 0 || ndisre < 0 || fr->nblock < 0)) { *bWrongPrecision = TRUE; return *bOK; } /* we now know what these should be, or we've already bailed out because of wrong precision */ if ( *file_version==1 && (fr->t < 0 || fr->t > 1e20 || fr->step < 0 ) ) { enx_warning("edr file with negative step number or unreasonable time (and without version number)."); *bOK=FALSE; return FALSE; } if (*bOK && bRead) { add_blocks_enxframe(fr, fr->nblock); } startb=0; if (ndisre>0) { /* sub[0] is the instantaneous data, sub[1] is time averaged */ add_subblocks_enxblock(&(fr->block[0]), 2); fr->block[0].id=enxDISRE; fr->block[0].sub[0].nr=ndisre; fr->block[0].sub[1].nr=ndisre; fr->block[0].sub[0].type=dtreal; fr->block[0].sub[1].type=dtreal; startb++; } /* read block header info */ for(b=startb; b<fr->nblock; b++) { if (*file_version<4) { /* blocks in old version files always have 1 subblock that consists of reals. */ int nrint; if (bRead) { add_subblocks_enxblock(&(fr->block[b]), 1); } else { if (fr->block[b].nsub != 1) { gmx_incons("Writing an old version .edr file with too many subblocks"); } if (fr->block[b].sub[0].type != dtreal) { gmx_incons("Writing an old version .edr file the wrong subblock type"); } } nrint = fr->block[b].sub[0].nr; if (!gmx_fio_do_int(ef->fio, nrint)) { *bOK = FALSE; } fr->block[b].id = b - startb; fr->block[b].sub[0].nr = nrint; fr->block[b].sub[0].type = dtreal; } else { int i; /* in the new version files, the block header only contains the ID and the number of subblocks */ int nsub=fr->block[b].nsub; *bOK = *bOK && gmx_fio_do_int(ef->fio, fr->block[b].id); *bOK = *bOK && gmx_fio_do_int(ef->fio, nsub); fr->block[b].nsub=nsub; if (bRead) add_subblocks_enxblock(&(fr->block[b]), nsub); /* read/write type & size for each subblock */ for(i=0;i<nsub;i++) { t_enxsubblock *sub=&(fr->block[b].sub[i]); /* shortcut */ int typenr=sub->type; *bOK=*bOK && gmx_fio_do_int(ef->fio, typenr); *bOK=*bOK && gmx_fio_do_int(ef->fio, sub->nr); sub->type = (xdr_datatype)typenr; } } } if (!gmx_fio_do_int(ef->fio, fr->e_size)) *bOK = FALSE; /* now reserved for possible future use */ if (!gmx_fio_do_int(ef->fio, dum)) *bOK = FALSE; /* Do a dummy int to keep the format compatible with the old code */ if (!gmx_fio_do_int(ef->fio, dum)) *bOK = FALSE; if (*bOK && *file_version == 1 && nre_test < 0) { #if 0 if (fp >= ener_old_nalloc) { gmx_incons("Problem with reading old format energy files"); } #endif if (!ef->eo.bReadFirstStep) { ef->eo.bReadFirstStep = TRUE; ef->eo.first_step = fr->step; ef->eo.step_prev = fr->step; ef->eo.nsum_prev = 0; } fr->nsum = fr->step - ef->eo.first_step + 1; fr->nsteps = fr->step - ef->eo.step_prev; fr->dt = 0; } return *bOK; }