
/*
# proc: readpatstreefile - read features, classes, and their NN tree from a
# proc:                    file that allows for fast binary block io.
# proc: writepatstreefile - write features, classes, and their NN tree to a
# proc:                     file for fast binary io.
*/

#include <stdio.h>
#include <stdlib.h>

#define TREEPATSFILE 5151
#define JUSTPATSFILE    0

readpatstreefile(fn, reqPats, reqInps, nPats, nInps, nOuts, nnodes, nchild,
                 class, set, feats, child, idiscr, npts, ipts, vmin, vmax)
char *fn, ***set; int  *nPats,  *nInps,  *nOuts, **class;
int  *nnodes, *nchild, **child, **idiscr, **npts, **ipts;
float **feats, **vmin, **vmax;
{
int n, m, i, j, diff; FILE *fp;
int idum, targ_typ, tree;
float *iptr, *optr;

    if ((fp = fopen(fn, "r")) == NULL)
       syserr("readpatstreefile", "fopen", fn);

    if ((n = fread(&idum, sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread idum1a");
    if ((n = fread(nPats,  sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread nPats");
    if ((n = fread(nInps,  sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread nInps");
    if ((n = fread(nOuts,  sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread nOuts");
    if ((n = fread(&targ_typ, sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread targ_typ");
    if ((n = fread(&tree, sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread dummy1");
    if ((n = fread(&idum, sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread dummy2");
    if ((n = fread(&idum, sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread idum1b");

    if (tree != TREEPATSFILE)
       fatalerr("readtreepatsfile", fn,
          "wrong code in head for tree's presence");



    m = *nPats * *nInps;
    if ((*feats = (float *)malloc(m * sizeof(float))) == NULL)
       syserr("readpatstreefile", "malloc", "space for feats");
    m = *nPats;
    if ((*class = (int   *)malloc(m * sizeof(int  ))) == NULL)
       syserr("readpatstreefile", "malloc", "space for class");
    m = *nOuts;
    if ((*set   = (char **)calloc(m, sizeof(char *))) == NULL)
       syserr("readpatstreefile", "malloc", "space for class set");

    if ((n = fread(&idum, sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "idum2a fread");
    for(i = 0; i < *nOuts; i++)
    {
       if (((*set)[i] = (char *)calloc(32, sizeof(char))) == NULL)
         syserr("readpatstreefile", "calloc", "space for set string");
       if ((n = fread((*set)[i], sizeof(char), 32, fp)) != 32)
         syserr("readpatstreefile", fn, "class_set fread");
    }
    if ((n = fread(&idum, sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "idum2b fread");



    m = *nPats * *nInps;
    if ((n = fread(*feats, sizeof(float), m, fp)) != m)
       syserr("readpatstreefile", fn, "fread feats");
    m = *nPats;
    if ((n = fread(*class, sizeof(int  ), m, fp)) != m)
       syserr("readpatstreefile", fn, "fread class");


    if (reqPats == 0) reqPats = *nPats;
    if (reqInps == 0) reqInps = *nInps;

    diff = *nInps - reqInps;
    if (diff < 0)
       fatalerr("readpatstreefile", "not coded to zero pad features", fn);

    if (diff)
       for ( i = 0, iptr = *feats, optr = *feats ; i < reqPats ; i++, iptr += diff )
          for ( j = 0 ; j < reqInps ; j++ )
             *optr++ = *iptr++;

    *nInps = reqInps;
    *nPats = reqPats;

    /* ------------------------------------------------------ */

    if ((n = fread(nnodes, sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread nnodes");
    if ((n = fread(nchild, sizeof(int), 1, fp)) != 1)
       syserr("readpatstreefile", fn, "fread nchild");

    m = *nnodes * *nchild;
    if ((*child = (int   *)malloc(m * sizeof(int  ))) == NULL)
       syserr("readpatstreefile", "malloc", "space for child");
    m = *nnodes;
    if ((*idiscr= (int   *)malloc(m * sizeof(int  ))) == NULL)
       syserr("readpatstreefile", "malloc", "space for idiscr");
    if ((*npts  = (int   *)malloc(m * sizeof(int  ))) == NULL)
       syserr("readpatstreefile", "malloc", "space for npts");
    if ((*ipts  = (int   *)malloc(m * sizeof(int  ))) == NULL)
       syserr("readpatstreefile", "malloc", "space for ipts");
    if ((*vmin  = (float *)malloc(m * sizeof(float))) == NULL)
       syserr("readpatstreefile", "malloc", "space for vmin");
    if ((*vmax  = (float *)malloc(m * sizeof(float))) == NULL)
       syserr("readpatstreefile", "malloc", "space for vmax");

    m = *nnodes * *nchild;
    if ((n = fread(*child, sizeof(int  ), m, fp)) != m)
       syserr("readpatstreefile", fn, "fread child");
    m = *nnodes;
    if ((n = fread(*idiscr,sizeof(int  ), m, fp)) != m)
       syserr("readpatstreefile", fn, "fread idiscr");
    if ((n = fread(*npts,  sizeof(int  ), m, fp)) != m)
       syserr("readpatstreefile", fn, "fread npts");
    if ((n = fread(*ipts,  sizeof(int  ), m, fp)) != m)
       syserr("readpatstreefile", fn, "fread ipts");
    if ((n = fread(*vmin,  sizeof(float), m, fp)) != m)
       syserr("readpatstreefile", fn, "fread vmin");
    if ((n = fread(*vmax,  sizeof(float), m, fp)) != m)
       syserr("readpatstreefile", fn, "fread vmax");

    fclose(fp);
}


writepatstreefile(fn, nPats, nInps, nOuts, nnodes, nchild, class, set,
                 feats, child, idiscr, npts, ipts, vmin, vmax)
char *fn, **set; int nPats, nInps, nOuts, nnodes, nchild;
int *class, *child, *idiscr, *npts, *ipts; float *feats, *vmin, *vmax;
{
int i, j, n, m; FILE *fp;
int tree, idum = 0, targ_typ = 0;

    if ((fp = fopen(fn, "w")) == NULL)
       syserr("writepatstreefile", "fopen", fn);

    m = 24; tree = TREEPATSFILE;
    if ((n = fwrite(&m,     sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite wsize1a");
    if ((n = fwrite(&nPats,    sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite nPats");
    if ((n = fwrite(&nInps,    sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite nInps");
    if ((n = fwrite(&nOuts,    sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite nOuts");
    if ((n = fwrite(&targ_typ, sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite targ_typ");
    if ((n = fwrite(&tree,     sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite dummy1");
    if ((n = fwrite(&idum,     sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite dummy2");
    if ((n = fwrite(&m,        sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite wsize1b");

    m = 32*nOuts;
    if ((n = fwrite(&m, sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "wsize2a fwrite");
    for (i = 0; i < nOuts; i++)
    {
       m = strlen(set[i]);
       if ((n = fwrite(set[i], sizeof(char), m, fp)) != m)
          syserr("writepatstreefile", fn, "string fwrite");
       for(j = 0; j < (32 - m); j++)
          if ((n = fwrite("\0", sizeof(char), 1, fp)) != 1)
             syserr("writepatstreefile", fn, "null fwrite");
    }
    if ((n = fwrite(&m, sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "wsize2b fwrite");


    m = nPats * nInps;
    if ((n = fwrite(feats,     sizeof(float), m, fp)) != m)
       syserr("writepatstreefile", fn, "write feats");
    m = nPats;
    if ((n = fwrite(class,     sizeof(int  ), m, fp)) != m)
       syserr("writepatstreefile", fn, "write class");

    if ((n = fwrite(&nnodes, sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite nnodes");
    if ((n = fwrite(&nchild, sizeof(int), 1, fp)) != 1)
       syserr("writepatstreefile", fn, "fwrite nchild");

    m = nnodes * nchild;
    if ((n = fwrite(child, sizeof(int  ), m, fp)) != m)
       syserr("writepatstreefile", fn, "write child");
    m = nnodes;
    if ((n = fwrite(idiscr, sizeof(int  ), m, fp)) != m)
       syserr("writepatstreefile", fn, "fwrite idiscr");
    if ((n = fwrite(npts,   sizeof(int  ), m, fp)) != m)
       syserr("writepatstreefile", fn, "fwrite npts");
    if ((n = fwrite(ipts,   sizeof(int  ), m, fp)) != m)
       syserr("writepatstreefile", fn, "fwrite ipts");
    if ((n = fwrite(vmin,   sizeof(float), m, fp)) != m)
       syserr("writepatstreefile", fn, "fwrite vmin");
    if ((n = fwrite(vmax,   sizeof(float), m, fp)) != m)
       syserr("writepatstreefile", fn, "fwrite vmax");

    fclose(fp);
}
