aboutsummaryrefslogtreecommitdiff
path: root/src/AVSreadcpp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/AVSreadcpp.cc')
-rw-r--r--src/AVSreadcpp.cc216
1 files changed, 216 insertions, 0 deletions
diff --git a/src/AVSreadcpp.cc b/src/AVSreadcpp.cc
new file mode 100644
index 0000000..eb5f139
--- /dev/null
+++ b/src/AVSreadcpp.cc
@@ -0,0 +1,216 @@
+#include <stdio.h>
+#include <avs/avs.h>
+#include <avs/port.h>
+#include <avs/field.h>
+/* John's Includes */
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+/* Local Includes */
+#include <IO.hh>
+#include <IEEEIO.hh>
+#ifdef WITH_HDF
+#include <HDFIO.hh>
+#endif
+// #include <Reader.hh> // an even higher level interface, but must skip for now
+
+extern "C" {
+int readIEEE(AVSfield **out,char *Filename,int RecordNumber,
+ int SetExtents,char *SetCoordinates);
+}
+
+int readIEEE(AVSfield **out,char *Filename,int RecordNumber,
+ int SetExtents,char *SetCoordinates){
+ static IObase *infile=0;
+ // Handle case where Filename has changed
+ if(AVSparameter_changed("Filename") || !infile){
+ // Filename has changed, so close any currently open data files
+ // (this is done by delete'ing here.)
+ if(infile) delete infile;
+ infile=0;
+ // Just in case the new file is bogus, hide the dial widgets so
+ // that they can't be messed with if the data isn't valid.
+ AVSparameter_visible("RecordNumber",0);
+#ifdef WITH_HDF
+ if(strstr(strchr(Filename,','),"hdf"))
+ infile = new HDFIO(Filename,IObase::Read);
+ else
+#endif
+ infile = new IEEEIO(Filename,IObase::Read); // open the datafile
+
+ if(!infile->isValid()){ // if the file is not IEEEIO, exit
+ delete infile;
+ infile=0;
+ fprintf(stderr,"%s is not an IEEEIO file",Filename);
+ return 0;
+ }
+ if(infile->nDatasets()>1){// don't set widget dial for min=max=0
+ AVSmodify_parameter("RecordNumber",AVS_VALUE|AVS_MAXVAL,
+ 0,0,infile->nDatasets()-1);
+ AVSparameter_visible("RecordNumber",1);
+ } // so dial widget remains hidden if dataset contains 1 or fewer datasets
+ RecordNumber=0;
+ }
+ // Failsafe sanity check (things are really hosed if this check fails)
+ if(!infile) {
+ puts("Not an IEEEIO file");
+ AVSparameter_visible("RecordNumber",0);
+ return 0;
+ }
+
+ // now do memory allocation for AVS
+ char AllocationDescription[64];
+ char *typname;
+ IObase::DataType datatype;
+ int rank,dims[5];
+ int nelements;
+
+ infile->seek(RecordNumber); // seek to desired record
+ infile->readInfo(datatype,rank,dims); // get info about the dataset
+ // we are building the AVS memory description text string to do the allocation.
+ switch(datatype){
+ case IObase::Float32:
+ puts("Data Type float");
+ typname="float";
+ break;
+ case IObase::Float64:
+ puts("Data Type double");
+ typname="double";
+ break;
+ case IObase::Int32:
+ typname="integer";
+ break;
+ case IObase::uChar:
+ case IObase::Int8:
+ typname="byte";
+ break;
+ }
+
+ if(!strcmp("Set Edges",SetCoordinates))
+ sprintf(AllocationDescription,"field %uD %u-space scalar rectilinear %s",
+ rank,rank,typname); // put it all together into the allocation string
+ else
+ sprintf(AllocationDescription,"field %uD %u-space scalar uniform %s",
+ rank,rank,typname); // put it all together into the allocation string
+
+ //printf("AVS allocating %s\n",AllocationDescription);
+ //printf("With dims[0]=%d dims[1]=%d dims[2]=%d\n",dims[0],dims[1],dims[2]);
+ if(*out) AVSfield_free(*out); // free old memory if its still around
+ *out = (AVSfield *)AVSdata_alloc(AllocationDescription,dims); // and allocate!
+ if(!*out){
+ fprintf(stderr,"Allocation of %s failed\n",
+ AllocationDescription);
+ return 0; // allocation failed
+ }
+
+ /*---
+ Note: So if this read doesn't work, you'll need to use a switch statement
+ with exact casts to the proper datatypes.
+ I skipped using the switch statement because it looks really stupid
+ but its necessary for some machines which align vectors
+ differently depending on the size of the type the vector
+ points to. (yes folks... this is what the "align" keyword is about)
+ Hopefully we won't use such poorly designed machines.
+
+ This need not be done for the parameters though since that field
+ of the avsfld is always float.
+ ---*/
+ AVSfield_float *fld=(AVSfield_float*)(*out);
+ puts("Preparing to read data");
+ infile->read(fld->data); // read the data
+ puts("read data");
+ int minindex,maxindex;
+ /*---
+ In this section we are just setting the extents and edge points information
+ for AVS (the physical size of the dataset in floating point coordinates).
+ There are just two Attribute pairs that it will recognize to do this.
+
+ 1) min_ext,max_ext
+ These are vectors of size <rank of dataset> which contain the
+ coordinates of the minimum and maximum corners of the bounding box.
+ 2) origin,delta
+ The GR people seem to like this. Its the origin (same as the min_ext)
+ of the dataset and then the delta (or "dx") between grid points in the
+ dataset.
+
+ It is now able to handle these parameters as Float32 or Float64 data.
+ Integer is ignored. The dataset will simply be ranged from 0-dim[x]
+ if the above Attributes are not found.
+ ---*/
+ {
+ float min_ext[5],max_ext[5];
+
+ if((minindex=infile->readAttributeInfo("min_ext",datatype,nelements))>0 &&
+ (maxindex=infile->readAttributeInfo("max_ext",datatype,nelements))>0 &&
+ (datatype==IObase::Float32 || datatype==IObase::Float64)) {
+ if(datatype==IObase::Float32){
+ infile->readAttribute(maxindex,min_ext);
+ infile->readAttribute(minindex,max_ext);
+ }
+ else if(datatype==IObase::Float64){
+ double maxext[5],minext[5];
+ infile->readAttribute(maxindex,maxext);
+ infile->readAttribute(minindex,minext);
+ for(int i=0;i<rank;i++){
+ min_ext[i]=(float)(minext[i]);
+ max_ext[i]=(float)(maxext[i]);
+ }
+ }
+
+ } //***** OK, if we cant find extents, then try origin & delta
+ else if((minindex=infile->readAttributeInfo("origin",datatype,nelements))>0 &&
+ (maxindex=infile->readAttributeInfo("delta",datatype,nelements))>0 &&
+ (datatype==IObase::Float32 || datatype==IObase::Float64)) {
+ if(datatype==IObase::Float32){
+ infile->readAttribute(maxindex,fld->min_extent);
+ infile->readAttribute(minindex,fld->max_extent);
+ for(int i=0;i<rank;i++){
+ max_ext[i]*=(float)dims[i];
+ max_ext[i]+=min_ext[i];
+ }
+ }
+ else if(datatype==IObase::Float64){
+ double maxext[5],minext[5];
+ infile->readAttribute(maxindex,maxext);
+ infile->readAttribute(minindex,minext);
+ for(int i=0;i<rank;i++){
+ maxext[i]*=(double)dims[i];
+ maxext[i]+=minext[i];
+ min_ext[i]=(float)(minext[i]);
+ max_ext[i]=(float)(maxext[i]);
+ }
+ }
+ }
+ else { // No information about edges.
+ for(int i=0;i<rank;i++){
+ min_ext[i]=0.0;
+ max_ext[i]=(float)(dims[i]-1);
+ }
+ }
+ if(SetExtents){
+ for(int i=0;i<rank;i++){
+ fld->min_extent[i]=min_ext[i];
+ fld->max_extent[i]=max_ext[i];
+ }
+ }
+ if(!strcmp("Set Min/Max",SetCoordinates)){
+ for(int i=0;i<rank;i++){
+ fld->points[i*2]=min_ext[i];
+ fld->points[i*2 + 1]=max_ext[i];
+ }
+ }
+ else if(!strcmp("Set Edges",SetCoordinates)){
+ for(int index=0,i=0;i<rank;i++){
+ double dx = (max_ext[i]-min_ext[i])/((float)(fld->dimensions[i]));
+ printf("SetEdges[%u]: dx=%lf\n",i,dx);
+ for(int j=0;j<fld->dimensions[i];j++,index++){
+ fld->points[index] = min_ext[i] + ((double)j)*dx;
+ }
+ }
+ }
+ }
+ return 1; // for now
+}
+
+