Skip to content
Snippets Groups Projects
parti_ieee.cc 7.57 KiB
Newer Older
  • Learn to ignore specific revisions
  • slevy's avatar
    slevy committed
    #ifdef USE_IEEEIO
    
    
    /*
     * Reader for John Shalf's FlexIO data for partiview.
     *
     * Stuart Levy, slevy@ncsa.uiuc.edu
     * National Center for Supercomputing Applications,
     * University of Illinois 2001.
    
     * This file is part of partiview, released under the
     * Illinois Open Source License; see the file LICENSE.partiview for details.
    
    slevy's avatar
    slevy committed
    #include <stdio.h>
    #include <stdlib.h>
    #include <IEEEIO.hh>
    
    #include "shmem.h"
    #include <GL/glu.h>
    #include "specks.h"
    
    #include <unistd.h>
    #include <getopt.h>
    #include <math.h>
    
    #include "partiviewc.h"
    #include "findfile.h"
    
    static int elements(int rank, int dims[]) {
      int i, n;
      for(i=0, n=1; i < rank; i++)
        n *= dims[i];
      return n;
    }
    
    extern "C" {
    
    extern void strncpyt( char *dst, char *src, int dstsize );
    
    int parti_ieee_read( struct stuff **stp, int argc, char *argv[], char *fname, void * ) {
        static char Usage[] = "ieee file.amr";
    
        if(argc < 1 || strcmp(argv[0], "ieee"))
    	return 0;
    
        if(argc <= 1) {
    	msg(Usage);
    	return 1;
        }
    
        struct stuff *st = *stp;
        int timestepno = st->datatime;
        char *realfile;
        int i = 1;
    
        if(argc>2 && !strcmp(argv[1], "-t")) {
    
    	if((timestepno = (int) getfloat(argv[2], st->datatime)) < 0) {
    
    slevy's avatar
    slevy committed
    	    msg("ieee -t: expected timestepnumber(0-based), not %s", argv[2]);
    	    return 1;
    	}
    	i = 3;
        }
        realfile = findfile( fname, argv[i] );
        if(realfile == NULL) {
    	msg("%s: ieee: can't find file %s", fname, argv[i]);
        } else {
    	/* Load IEEE dataset into time slot */
    	specks_ieee_open( st, realfile, st->curdata, timestepno );
        }
        return 1;
    }
    
    void parti_ieee_init(void) {
        parti_add_reader( parti_ieee_read, "ieee", NULL );
    }
    
    void specks_ieee_open( struct stuff *st, char *fname, int dataset, int starttime )
    {
    
      if(st->ndata >= MAXFILES) {
        fprintf(stderr, "Oops, already read limit of %d data files, ignoring %s\n",
    	MAXFILES, fname);
        return;
      }
    
      IObase *infile = new IEEEIO( fname, IObase::Read );
    
      if(!infile->isValid()) {
        msg("Couldn't open IEEEIO file %s", fname);
        return;
      }
    
      if(starttime < 0) starttime = 0;
    
      int ntimes = infile->nDatasets();		/* time steps */
    
      int nd = (dataset < 0) ? st->curdata : dataset;
    
      char *dupfname = NewN( char, strlen(fname)+1 );
      strcpy(dupfname, fname);
    
      /* Preallocate room for timesteps */
      (void) specks_timespecksptr( st, nd, starttime + ntimes - 1 );
    
      for(int i = 0; i < ntimes; i++) {
    
        specks_discard( st, &st->anima[nd][i+starttime] );	/* free any scrap */
        /* st->anima[nd][i+starttime] = NULL; */
        st->datafile[nd][i+starttime] = (void *)infile;
        st->fname[nd][i+starttime] = dupfname;
      }
    if(getenv("DBG")) fprintf(stderr, "<p%d>d%d t%d..%d <= %lx %s\n", getpid(), nd, starttime, starttime+ntimes-1, infile, fname );
    }
    
    struct specklist *
    specks_ieee_read_timestep( struct stuff *st, int subsample, int dataset, int timestep )
    {
      int curdata = dataset;
      int curtime = timestep;
      int timebase;
      float spacescale = st->spacescale;
      int skips[64], skinx, skip;
      int outnel;
    
      if(st->ndata == 0)
        return NULL;
    
      if(curdata >= st->ndata) curdata = st->ndata-1;
      if(curdata < 0) curdata = 0;
    
      if(curtime >= st->ntimes) curtime = st->ntimes-1;
      if(curtime < 0) curtime = 0;
    
      IObase *infile = (IObase *)st->datafile[curdata][curtime];
    
      if(infile == NULL)
        return NULL;
    
      if(!infile->isValid()) {
        fprintf(stderr, "<p%d>d%d t%d infile %x invalid!\n", getpid(), dataset, timestep, infile);
        fprintf(stderr, "sleeping 10 secs -- to look around,   dbx -p %d\n", getpid());
        sleep(10);
        return NULL;
      }
    
      for(timebase = timestep;
    	timebase > 0 && (IObase *)st->datafile[curdata][timebase-1] == infile;
    	timebase--) 
        ;
    
    
      IObase::DataType dt;
      int rank, dims[3];
    
      infile->seek( curtime - timebase );
      dims[1]=dims[2]=1;
      infile->readInfo(dt, rank, dims);
    
      int i, k, anel;
      int nel = dims[rank-1];
    
      if(dims[0] != 3 || rank != 2) {
        fprintf(stderr, "%s<%lx> dataset %d (timestep %d): expected 3xN data organization, not %dx%d!\n",
    	st->fname[curdata][curtime], infile, curtime - timebase, curtime, dims[0],dims[1]);
        fprintf(stderr, "sleeping 10 secs -- to look around,   dbx -p %d\n", getpid());
        sleep(10);
        return NULL;
      }
    
      if(subsample < 1)
        subsample = 1;
    
      int sktotal = 0;
      for(skinx = 0; skinx < 64; skinx++) {
    
        skips[skinx] = subsample + (int) ((drand48() - .5)*sqrt(subsample-1));
    
    slevy's avatar
    slevy committed
        if(skips[skinx] <= 0) skips[skinx] = 1;
        sktotal += skips[skinx];
      }
    
      float *xyz = new float[ elements(rank,dims) ];
      infile->read(xyz);
    
      int nattr = infile->nAttributes();
      if(nattr > MAXVAL) nattr = MAXVAL;
    
      outnel = (nel / sktotal) * 64;
      for(i = 0, skinx = 0; i < nel % sktotal; ) {
        skip = skips[skinx++ & (64-1)];
        i += skip;
        outnel++;
      }
      struct specklist *sl = NewN( struct specklist, 1 );
      memset( sl, 0, sizeof(*sl) );
      sl->bytesperspeck = SMALLSPECKSIZE( nattr );
    
      struct speck *sp = (struct speck *)NewN( char, outnel*sl->bytesperspeck );
      sl->sel = NewN( SelMask, outnel );
      memset( sl->sel, 0, outnel*sizeof(SelMask) );
    
    
      sl->specks = sp;
      sl->nspecks = outnel;
      sl->scaledby = st->spacescale;
      sl->coloredby = -1;
      sl->sizedby = -1;
    
      sl->subsampled = subsample;
    
      register struct speck *tsp = sp;
      float *ap = xyz;
    
    float x0=1e8,x1=-1e8,y0=1e8,y1=-1e8,z0=1e8,z1=-1e8;
      for(skinx = 0, i = 0; i < nel; ) {
        tsp->p.x[0] = ap[0] * spacescale;
        tsp->p.x[1] = ap[1] * spacescale;
        tsp->p.x[2] = ap[2] * spacescale;
    if(x0>tsp->p.x[0]) x0 = tsp->p.x[0]; if(x1<tsp->p.x[0]) x1=tsp->p.x[0];
    if(y0>tsp->p.x[1]) y0 = tsp->p.x[1]; if(y1<tsp->p.x[1]) y1=tsp->p.x[1];
    if(z0>tsp->p.x[2]) z0 = tsp->p.x[2]; if(z1<tsp->p.x[2]) z1=tsp->p.x[2];
        tsp->size = 1;
        tsp->rgba = 0xFFFFFF00;
        skip = skips[skinx++ & (64-1)];
        tsp = NextSpeck(tsp, sl, 1);
        i += skip;
        ap += 3*skip;
      }
    
    if(getenv("RANGE"))
      printf("range (scaled by %g): %g..%g %g..%g %g..%g\n",
    	spacescale, x0,x1, y0,y1, z0,z1);
    
      delete xyz;
    
      float *attr = new float[nel];
    
      for(i = 0; i < nattr && i < MAXVAL; i++) {
        char aname[128];
        char *myname;
        float min = 1e20, max = -1e20, mean = 0;
        struct valdesc *vd = &st->vdesc[curdata][i];
    
        if(vd->nsamples > 0)
    	min = vd->min, max = vd->max;
    
        infile->readAttributeInfo(i, aname, dt, anel);
        myname = aname;
        if(!strncmp(aname, "particle_", 9)) myname += 9;
    
        strncpyt(st->vdesc[curdata][i].name, myname, sizeof(st->vdesc[0][0].name));
    
        if(anel != nel) {
    	fprintf(stderr, "Hey, attribute %d (%s) of file %s has %d elements, not %d!\n",
    	    i, aname, st->fname[curdata][curtime], anel, nel);
    	memset(attr, 0, nel*sizeof(*attr));
        } else {
    	infile->readAttribute(i, attr);
        }
    
        struct speck *peak = NULL;
        for(k = 0, skinx = 0, tsp = sp, ap = attr; k < nel; ) {
    	register float a = *ap;
    	tsp->val[i] = a;
    	if(min > a) min = a;
    	if(max < a) {
    	    max = a;
    	    peak = tsp;
    	}
    	mean += a;
    	skip = skips[skinx++ & (64-1)];
    	tsp = NextSpeck( tsp, sl, 1 );
    	ap += skip;
    	k += skip;
        }
        if((char *)tsp - (char *)sp != outnel * sl->bytesperspeck) {
    	fprintf(stderr, "panic: copying attr %d: subsampled into %ld, expected %d of %d\n",
    		i, ((char *)tsp - (char *)sp) / sl->bytesperspeck, outnel, anel);
        }
        if(nel > 0) {
    	vd->min = min;
    	vd->max = max;
    	vd->mean = (mean + vd->mean*vd->nsamples) / (outnel + vd->nsamples);
    	vd->nsamples += outnel;
    	vd->sum = vd->mean * vd->nsamples;
    	if(aname[0] == 'd' && peak != NULL) {
    	    sl->interest = peak->p;
    	}
        }
      }
      delete attr;
    
      /* If we had any data in this slot before, scrap it now. */
    
      specks_discard( st, &st->anima[curdata][curtime] );
    		/* Is this safe?  Do we need an interlock? */
    
      st->anima[curdata][curtime] = sl;
    
      return sl;
    }
    
    } // end extern "C"
    
    #endif /*USE_IEEEIO*/