Skip to content
Snippets Groups Projects
parti_ieee.cc 7.57 KiB
#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.
 */

#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) {
	    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));
    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*/