RATES.C

/*
This program plots airport departures or arrivals.
*/

#include <graphic.h>

#if TCQ                                 /* Set stack for Borland (Turbo) C */
extern unsigned _stklen = 0x3000;
#endif

#define DEBUG 0
#define DIMX 96
#define DIMY 45

FILE *ifptr = NULL, *stdp = NULL, *cfptr = NULL;
float **griddat, *x, *y;
float *average;

/**********************************************************************/
int TDdate_to_coll_day(long TDdate);
void GPC_MAIN(int argc, char *argv[])
{
    int i, j, size, idate = 0, time = -1, ndays = 0;
    char tkfname[20], name[6], str[100], cfname[20];
    long departures = 0, todayl;
    char *cp;
    char datname[20];
    int sym;
    float max = 0.0f;
    long int count, timeslice;
    int depart = 1;


    x = (float *)gpcalloc(DIMX, sizeof(float));
    y = (float *)gpcalloc(DIMY, sizeof(float));
    average = (float *)gpcalloc(DIMX, sizeof(float));
    griddat = (float **)dim2(DIMY, DIMX, sizeof(float));
    if(x == (float *)NULL || y == (float *)NULL ||
        average == (float *)NULL || griddat == (float **)NULL) {
        GPC_PUTS("RATES: Could not allocate data arrays");
        goto EndOfApp;
    }

    for (i = 0; i < DIMX; i++) {
        for (j = 0; j < DIMY; j++) {
            griddat[j][i] = 0.0f;
        }
    }
    if (argc < 2)
        strcpy(datname, "arrvord.dat");
    else
        strcpy(datname, argv[1]);
      
    ifptr = gfopen(datname, "r", 0x3000);
    if (ifptr == NULL) {
        GPC_PUTS("RATES: Unable to open input data file.");
        goto EndOfApp;
    }
    /*
        Using GraphiC-286 in protected mode, stdprn is not opened
        by default. If you debug by sending messages to stdprn,
        here is how to open a file handle that can be used for that purpose.
    */
#if GPC_EX2
    stdp = fopen("LPT1", "w");         /* The printer is not actually used */
#endif
    /* CREATE A CONTEXT-DEPENDENT TKF FILE NAME AND TITLE */
    cp = strupr(datname);

    if (argc > 2) {                    /* make output comma-delimited file */
        strcpy(cfname, cp);
        strcpy(cfname + 7, ".CMA");
        cfptr = fopen(cfname, "w");
    }

    strcpy(tkfname, cp);
    if (strncmp(cp, "AR", 2) == 0)
        depart = 0;
    strcpy(tkfname + 7, ".TKF");
    strncpy(name, cp + 4, 3);
    name[3] = '\0';

    /* LOOP THROUGH THE DATA AND PLOT EACH POINT */
    for (;;) {
        /* GET DATA RECORD SIZE */
        fscanf(ifptr, "%d\n", &size);
        if (feof(ifptr))
            break;
        if (size == 2) {
            fscanf(ifptr, "%ld ", &timeslice);      /* timeslice */
            fscanf(ifptr, "%ld\n", &count);     /* count */
            if (timeslice >= 96 || timeslice < 0)
                continue;
            time = (int)timeslice;
            griddat[idate][time] = (float)(count << 2);     /* *4 to get per hour */
            if (griddat[idate][time] > max) {
                max = griddat[idate][time];
            }
            departures += (long)count;
        }
        else {                                             /* It is a date */
            fscanf(ifptr, "%ld\n", &todayl);
            idate = TDdate_to_coll_day(todayl);
            ndays++;
            if (idate < 0 || idate > DIMY)
                putchar('');
        }
    }
    gfclose(ifptr);
    if (cfptr != NULL) {
        /* Write date out with columns as time period */
        for (i = 0; i < DIMY; i++) {
            for (j = 0; j < DIMX; j++) {
                fprintf(cfptr, "%d", (int)griddat[i][j]);
                if (j < DIMX - 1)
                    fprintf(cfptr, ",");
                else
                    fprintf(cfptr, "\n");
            }
        }
        /* And write it out days as columns */
        for (i = 0; i < DIMX; i++) {
            for (j = 0; j < DIMY; j++) {
                fprintf(cfptr, "%d", (int)griddat[j][i]);
                if (j < DIMY - 1)
                    fprintf(cfptr, ",");
                else
                    fprintf(cfptr, "\n");
            }
        }
        gfclose(cfptr);
    }

    bgnplot(1, 'g', tkfname);                                     /* Start GraphiC */
    font(4, "simplex.fnt", '\310', "swiss.fnt", '\311',    /* Select fonts */
        "compgrma.fnt", '\312', "swissitl.fnt", '\313');
    fillfont(1);                                              /* Fill them */

    startplot(7);
    color(BLACK);
    page(9.0f, 6.844f);
    if (depart) {
        sprintf(str, "\311Departure Rate at %s", name);
        heading(str);
    }
    else {
        sprintf(str, "\311Arrival Rate at %s", name);
        heading(str);
    }
    xname("\311local time");
    yname("\311 planes/hour");
    area2d(8.0f, 5.0f);
    graf("%-1.0f", 3.0f, 1.0f, 27.0f, "%-1.0f", 0.0f, 20.0f, max);
    sym = 0;
    for (i = 0; i < DIMX; i++)
        average[i] = 0.0f;

    for (j = 0; j < DIMX; j++) {
        x[j] = 3.0f + (float)j * 0.25f;
        for (i = 0; i < DIMY; i++) {
            average[j] += griddat[i][j];
        }
    }
    for (i = 0; i < DIMX; i++) {
        if (ndays > 0)
            average[i] /= (float)ndays;
    }
    tcurve(10);
    color(YELLOW);
    curve(x, average, DIMX, 0);

    for (j = 0; j < DIMX; j++) {
        x[0] = 3.0f + (float)j * 0.25f;
        color(BLACK);
        for (i = 0; i < DIMY; i++) {
            y[i] = griddat[i][j];
            average[j] += griddat[i][j];
        }
        BoxPlot(x[0], y, DIMY, 0, sym, .07f);
    }
    endplot();
    stopplot();
    if (stdp != NULL)
        fclose(stdp);

EndOfApp:
    free2((void ***)&griddat);
    gpcfree((void **)&x);
    gpcfree((void **)&average);
    gpcfree((void **)&y);
}

/*********************************************************************/
/* Convert a Teradata date to a day of the year (< 2000) */
int TDdate_to_coll_day(long TDdate)
{
    char st[30], year[3], month[3], day[3];
    int m, d;

    sprintf(st, "%ld", TDdate);
    strncpy(year, st, 2);
    year[2] = '\0';
    strncpy(month, (st + 2), 2);
    month[2] = '\0';
    strncpy(day, (st + 4), 2);
    day[2] = '\0';
    m = atoi(month);
    d = atoi(day);
    if (m == 10)
        return(d - 19);
    else if (m == 12)
        return(9 + d - 14);
    else if (m == 1)
        return(27 + d - 1);            /* 1/1 is the 27th index = 28th day */
    else
        return(-1);
}