<commit_before>#include <stdio.h>
#include <stdint.h>
#include <locale.h>
#include <string.h>
#include <stdbool.h>

#include <sys/stat.h>

/*
 * Program for finding the number of frames and atoms in a GROMACS XTC file.
 * Inspired by a post on the gmx-developers mailing list in 2012:
 * https://mailman-1.sys.kth.se/pipermail/gromacs.org_gmx-developers/2012-June/005937.html
 */

long file_size(const char *filename){
    struct stat buffer;
    int rc = stat(filename, &buffer);
    return rc == 0 ? buffer.st_size : -1;
}

uint32_t u4_from_buffer(const uint8_t *b){
    return b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3] << 0;
}

void print_header(const uint8_t header[92]){
    printf("%4d", u4_from_buffer(header+0));
    printf("%8d", u4_from_buffer(header+4));
    printf("%12d", u4_from_buffer(header+8));
    printf("\n");
}

int get_xtc_num_frames(const char *filename, int *nframes, int *natoms, float *psec, bool quiet){
    long size = file_size(filename);

    FILE *xtc = fopen(filename, "rb");
    if(!xtc) return -1;

    uint8_t header[92];

    *nframes = 0;
    double avg_frame_size = 0.;
    int est_nframes = 0;
    while(fread(header, 92, 1, xtc)){                       // Loop over frames
        (*nframes)++;
        *natoms = u4_from_buffer(header+4);
        uint32_t frame_size = u4_from_buffer(header+88);    // Read frame size from header
        uint32_t skip = (frame_size+3) & ~((uint32_t)3);    // Round up to 4 bytes
        avg_frame_size += (skip - avg_frame_size + 92) / *nframes;
        if(!quiet && *nframes % 10 == 0){
            est_nframes = size / avg_frame_size;
            uint32_t ps_tmp = u4_from_buffer(header+12);
            memcpy(psec, &ps_tmp, 4);
            *psec *= (double)est_nframes / *nframes;
            printf("\rEstimated %'d frames (%'d ns) of %'d atoms. - %d%%",
                    est_nframes, (int)(*psec/1000), *natoms, (int)(100. * *nframes) / est_nframes);
            fflush(stdout);
        }
        fseeko(xtc, skip, SEEK_CUR);                         // Skip to next header
    }
    uint32_t ps_tmp = u4_from_buffer(header+12);
    memcpy(psec, &ps_tmp, 4);

    fclose(xtc);
    return 0;
}

int main(const int argc, const char *argv[]){
    const char *help_text = "Count number of frames and simulation time of GROMACS XTC file\n"
                            "Usage: xtc-length <.xtc> [-q]\n\n"
                            "Default behaviour is to provide running estimate of file length\n"
                            "This can be suppressed using the '-q' flag\n";

    setlocale(LC_ALL, "");

    if(argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")){
        printf("%s", help_text);
        return 0;
    }
    bool quiet = false;
    if(argc >= 3 && !strcmp(argv[2], "-q")) quiet = true;

    int nframes, natoms;
    float psec;
    if(get_xtc_num_frames(argv[1], &nframes, &natoms, &psec, quiet)){
        printf("ERROR: Error reading XTC file\n");
        return -1;
    }

    if(!quiet) printf("\r");
    printf("Trajectory contains %'d frames (%'.2f ns) of %'d atoms.\n", nframes, psec/1000, natoms);
    return 0;
}
<commit_msg>Allow reading multiple xtc files - can use bash star<commit_after>#include <stdio.h>
#include <stdint.h>
#include <locale.h>
#include <string.h>
#include <stdbool.h>

#include <sys/stat.h>

/*
 * Program for finding the number of frames and atoms in a GROMACS XTC file.
 * Inspired by a post on the gmx-developers mailing list in 2012:
 * https://mailman-1.sys.kth.se/pipermail/gromacs.org_gmx-developers/2012-June/005937.html
 */

long file_size(const char *filename){
    struct stat buffer;
    int rc = stat(filename, &buffer);
    return rc == 0 ? buffer.st_size : -1;
}

uint32_t u4_from_buffer(const uint8_t *b){
    return b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3] << 0;
}

void print_header(const uint8_t header[92]){
    printf("%4d", u4_from_buffer(header+0));
    printf("%8d", u4_from_buffer(header+4));
    printf("%12d", u4_from_buffer(header+8));
    printf("\n");
}

int get_xtc_num_frames(const char *filename, int *nframes, int *natoms, float *psec, bool quiet){
    long size = file_size(filename);

    FILE *xtc = fopen(filename, "rb");
    if(!xtc) return -1;

    uint8_t header[92];

    *nframes = 0;
    double avg_frame_size = 0.;
    int est_nframes = 0;
    while(fread(header, 92, 1, xtc)){                       // Loop over frames
        (*nframes)++;
        *natoms = u4_from_buffer(header+4);
        uint32_t frame_size = u4_from_buffer(header+88);    // Read frame size from header
        uint32_t skip = (frame_size+3) & ~((uint32_t)3);    // Round up to 4 bytes
        avg_frame_size += (skip - avg_frame_size + 92) / *nframes;
        if(!quiet && *nframes % 10 == 0){
            est_nframes = (int)(size / avg_frame_size);
            uint32_t ps_tmp = u4_from_buffer(header+12);
            memcpy(psec, &ps_tmp, 4);
            *psec *= (double)est_nframes / *nframes;
            printf("\rEstimated %'d frames (%'d ns) of %'d atoms. - %d%%",
                    est_nframes, (int)(*psec/1000), *natoms, (int)(100. * *nframes) / est_nframes);
            fflush(stdout);
        }
        fseeko(xtc, skip, SEEK_CUR);                         // Skip to next header
    }
    uint32_t ps_tmp = u4_from_buffer(header+12);
    memcpy(psec, &ps_tmp, 4);

    fclose(xtc);
    return 0;
}

int main(const int argc, const char *argv[]){
    const char *help_text = "Count number of frames and simulation time of GROMACS XTC files\n"
                            "Usage: xtc-length [-q] xtc [xtc]...\n\n"
                            "Default behaviour is to provide running estimate of file length\n"
                            "This can be suppressed using the '-q' flag\n";

    setlocale(LC_ALL, "");

    if(argc < 2 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")){
        printf("%s", help_text);
        return 0;
    }
    bool quiet = false;
    if(argc >= 2 && !strcmp(argv[1], "-q")) quiet = true;

    int i;
    for(i = quiet ? 2 : 1; i < argc; i++){
        int nframes, natoms;
        float psec;
        printf("%s\n", argv[i]);
        if(get_xtc_num_frames(argv[i], &nframes, &natoms, &psec, quiet)){
            printf("ERROR: Error reading XTC file\n");
            return -1;
        }

        if(!quiet) printf("\r");
        printf("Trajectory contains %'d frames (%'.2f ns) of %'d atoms.\n\n", nframes, psec / 1000, natoms);
    }
    return 0;
}

{'fraction_non_alphanumeric': 0.15321583178726036, 'fraction_numerical': 0.033240568954854666, 'mean_word_length': 2.444621938232162, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 18, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1143686', 'n_tokens_mistral': 2441, 'n_tokens_neox': 2289, 'n_words': 593}