示例#1
0
/*! \libinternal \brief  Set the number of frames per frame
 * set according to output intervals.
 * The default is that 100 frames are written of the data
 * that is written most often. */
static void tng_set_frames_per_frame_set(tng_trajectory_t  tng,
                                         const gmx_bool    bUseLossyCompression,
                                         const t_inputrec *ir)
{
    int     gcd = -1;

    /* Set the number of frames per frame set to contain at least
     * defaultFramesPerFrameSet of the lowest common denominator of
     * the writing interval of positions and velocities. */
    /* FIXME after 5.0: consider nstenergy also? */
    if (bUseLossyCompression)
    {
        gcd = ir->nstxout_compressed;
    }
    else
    {
        gcd = greatest_common_divisor_if_positive(ir->nstxout, ir->nstvout);
        gcd = greatest_common_divisor_if_positive(gcd, ir->nstfout);
    }
    if (0 >= gcd)
    {
        return;
    }

    tng_num_frames_per_frame_set_set(tng, gcd * defaultFramesPerFrameSet);
}
void gmx_prepare_tng_writing(const char              *filename,
                             char                     mode,
                             tng_trajectory_t        *input,
                             tng_trajectory_t        *output,
                             int                      nAtoms,
                             const gmx_mtop_t        *mtop,
                             const int               *index,
                             const char              *indexGroupName)
{
#if GMX_USE_TNG
    /* FIXME after 5.0: Currently only standard block types are read */
    const int           defaultNumIds              = 5;
    static gmx_int64_t  fallbackIds[defaultNumIds] =
    {
        TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS,
        TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES,
        TNG_GMX_LAMBDA
    };
    static char         fallbackNames[defaultNumIds][32] =
    {
        "BOX SHAPE", "POSITIONS", "VELOCITIES",
        "FORCES", "LAMBDAS"
    };

    typedef tng_function_status (*set_writing_interval_func_pointer)(tng_trajectory_t,
                                                                     const gmx_int64_t,
                                                                     const gmx_int64_t,
                                                                     const gmx_int64_t,
                                                                     const char*,
                                                                     const char,
                                                                     const char);
#if GMX_DOUBLE
    set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_double_set;
#else
    set_writing_interval_func_pointer set_writing_interval = tng_util_generic_write_interval_set;
#endif

    gmx_tng_open(filename, mode, output);

    /* Do we have an input file in TNG format? If so, then there's
       more data we can copy over, rather than having to improvise. */
    if (*input)
    {
        /* Set parameters (compression, time per frame, molecule
         * information, number of frames per frame set and writing
         * intervals of positions, box shape and lambdas) of the
         * output tng container based on their respective values int
         * the input tng container */
        double      time, compression_precision;
        gmx_int64_t n_frames_per_frame_set, interval = -1;

        tng_compression_precision_get(*input, &compression_precision);
        tng_compression_precision_set(*output, compression_precision);
        // TODO make this configurable in a future version
        char compression_type = TNG_TNG_COMPRESSION;

        tng_molecule_system_copy(*input, *output);

        tng_time_per_frame_get(*input, &time);
        tng_time_per_frame_set(*output, time);

        tng_num_frames_per_frame_set_get(*input, &n_frames_per_frame_set);
        tng_num_frames_per_frame_set_set(*output, n_frames_per_frame_set);

        for (int i = 0; i < defaultNumIds; i++)
        {
            if (tng_data_get_stride_length(*input, fallbackIds[i], -1, &interval)
                == TNG_SUCCESS)
            {
                switch (fallbackIds[i])
                {
                    case TNG_TRAJ_POSITIONS:
                    case TNG_TRAJ_VELOCITIES:
                        set_writing_interval(*output, interval, 3, fallbackIds[i],
                                             fallbackNames[i], TNG_PARTICLE_BLOCK_DATA,
                                             compression_type);
                        break;
                    case TNG_TRAJ_FORCES:
                        set_writing_interval(*output, interval, 3, fallbackIds[i],
                                             fallbackNames[i], TNG_PARTICLE_BLOCK_DATA,
                                             TNG_GZIP_COMPRESSION);
                        break;
                    case TNG_TRAJ_BOX_SHAPE:
                        set_writing_interval(*output, interval, 9, fallbackIds[i],
                                             fallbackNames[i], TNG_NON_PARTICLE_BLOCK_DATA,
                                             TNG_GZIP_COMPRESSION);
                        break;
                    case TNG_GMX_LAMBDA:
                        set_writing_interval(*output, interval, 1, fallbackIds[i],
                                             fallbackNames[i], TNG_NON_PARTICLE_BLOCK_DATA,
                                             TNG_GZIP_COMPRESSION);
                    default:
                        continue;
                }
            }
        }

    }
    else
    {
        /* TODO after trjconv is modularized: fix this so the user can
           change precision when they are doing an operation where
           this makes sense, and not otherwise.

           char compression = bUseLossyCompression ? TNG_TNG_COMPRESSION : TNG_GZIP_COMPRESSION;
           gmx_tng_set_compression_precision(*output, ndec2prec(nDecimalsOfPrecision));
         */
        gmx_tng_add_mtop(*output, mtop);
        tng_num_frames_per_frame_set_set(*output, 1);
    }

    if (index && nAtoms > 0)
    {
        gmx_tng_setup_atom_subgroup(*output, nAtoms, index, indexGroupName);
    }

    /* If for some reason there are more requested atoms than there are atoms in the
     * molecular system create a number of implicit atoms (without atom data) to
     * compensate for that. */
    if (nAtoms >= 0)
    {
        tng_implicit_num_particles_set(*output, nAtoms);
    }
#else
    GMX_UNUSED_VALUE(filename);
    GMX_UNUSED_VALUE(mode);
    GMX_UNUSED_VALUE(input);
    GMX_UNUSED_VALUE(output);
    GMX_UNUSED_VALUE(nAtoms);
    GMX_UNUSED_VALUE(mtop);
    GMX_UNUSED_VALUE(index);
    GMX_UNUSED_VALUE(indexGroupName);
#endif
}