#ifdef _CVI_
 
#  include <ansi_c.h>
 
# else _CVI_
 
#  include <stdlib.h>
 
#  include <stdio.h>
 
#  include <string.h>
 
#endif _CVI_
 
 
 
#include "H3D.h"
 
#include "H2D.h"
 
#include "H1D.h" 
 
 
 
#define H3DMAX 500
 
H3D *h3[H3DMAX];
 
//int Printf(char *format, ...);
 
 
 
int _VI_FUNC  H3D_Clear(int h3d) {
 
  if (!h3[h3d]) return -1;
 
  memset(h3
[h3d
]->data
, 0,h3
[h3d
]->size 
);  
  h3[h3d]->min=0;
 
  h3[h3d]->max=0;
 
  h3[h3d]->nentries=0;
 
  return  0;
 
 
 
}
 
 
 
int _VI_FUNC  H3D_Print(int h3d) {
 
  if (!h3[h3d]) return -1;
 
//Printf("PrintH3D nx=%d minx=%f stepx=%f ny=%d miny=%f stepy=%f size=%d\n", h3[h3d]->nx, h3[h3d]->minx, h3[h3d]->stepx, h3[h3d]->ny, h3[h3d]->miny, h3[h3d]->stepy, h3[h3d]->size ) ;
 
  return  0;
 
 
 
}
 
 
 
int _VI_FUNC  H3D_Exist(int h) {
 
  if (h3[h]) return 1;
 
  else return 0;
 
}
 
 
 
 
 
int _VI_FUNC  H3D_CalculateBin(int h, int axis, double value) {
 
  int nx=1,xmin=0,dx=0;
 
  int bin;
 
  switch (axis) {
 
    case 0:
 
      nx = H3D_GetNbinsX(h);
 
      xmin= H3D_GetMinX(h);
 
      dx = H3D_GetStepX(h);
 
      break;
 
    case 1:
 
      nx = H3D_GetNbinsY(h);
 
      xmin= H3D_GetMinY(h);
 
      dx = H3D_GetStepY(h);
 
      break;
 
    case 2:
 
      nx = H3D_GetNbinsZ(h);
 
      xmin= H3D_GetMinZ(h);
 
      dx = H3D_GetStepZ(h);
 
      break;
 
 
 
  }
 
  if (dx==0) return -1;
 
  if (value<xmin) return -1;
 
  bin = (int)((value-xmin)/dx);
 
  if (bin>=nx) return -1;
 
  else return bin;
 
}
 
 
 
int _VI_FUNC  H3D_Fill(int h3d,double x, double y, double z, double val) {
 
 
 
  int ix,iy, iz;
 
  if (!h3[h3d]) return -1;
 
 
 
  ix = H3D_CalculateBin(h3d,0,x);
 
  if (ix<0) return ix;
 
 
 
  iy = H3D_CalculateBin(h3d,1,y);
 
  if (iy<0) return iy;
 
 
 
  iz = H3D_CalculateBin(h3d,2,z);
 
  if (iz<0) return iz;
 
 
 
 
 
  H3D_FillBin(h3d, ix, iy, iz, val);
 
  return 0;
 
}
 
 
 
int _VI_FUNC  H3D_GetBin(int h3d,int x, int y, int z) {
 
  return x+h3[h3d]->nx *(y+z*h3[h3d]->ny);
 
}
 
 
 
int _VI_FUNC  H3D_FillBin(int h3d,int x, int y, int z, double val) {
 
 
 
  int idx;
 
  if (!h3[h3d]) {
 
//Printf("FillH3D error h3d is not initialized\n");
 
    return -1;
 
  }
 
 
 
  idx = H3D_GetBin(h3d,x,y,z);
 
  h3[h3d]->data[idx]+=val;
 
//Printf("%d %d data %f %f\n",x,y,val, h3[h3d]->data[idx]);
 
  if (h3[h3d]->data[idx]>h3[h3d]->max) h3[h3d]->max= h3[h3d]->data[idx];
 
  if (h3[h3d]->data[idx]<h3[h3d]->min) h3[h3d]->min= h3[h3d]->data[idx];
 
  h3[h3d]->nentries++;
 
  return 0;
 
}
 
 
 
double _VI_FUNC  H3D_GetBinContent(int h3d,int atx, int aty, int atz) {
 
 
 
  int idx;
 
  if (!h3[h3d]) return 0;
 
  if (h3[h3d]->nx <= atx)  return 0;
 
  if (h3[h3d]->ny <= aty)  return 0;
 
  if (h3[h3d]->nz <= atz)  return 0;
 
  idx = H3D_GetBin(h3d,atx,aty,atz);
 
  if (idx*sizeof(double) < h3[h3d]->size ) return h3[h3d]->data[idx];
 
 
 
 
 
  return 0;
 
}
 
 
 
 
 
int _VI_FUNC  H3D_Init(int h3d,char *name, char *title,
 
                       int nx, double minx, double maxx, 
 
                       int ny, double miny, double maxy, 
 
                       int nz, double minz, double maxz) {
 
 
 
  if (h3[h3d]) {
 
 
 
    h3[h3d] = NULL;
 
  }
 
  //printf("InitH3D hID=%d\n",h3d);
 
  h3
[h3d
] = (H3D 
*) malloc(sizeof(H3D
)); 
//h2  =h3d;
 
 
 
  H3D_SetTitle(h3d,title);
 
  H3D_SetName(h3d,name);
 
  h3[h3d]->id=H3D_ID;
 
  h3[h3d]->nx = nx;
 
  h3[h3d]->ny = ny;
 
  h3[h3d]->nz = nz;
 
 
 
  h3[h3d]->minx = minx;
 
  h3[h3d]->miny = miny;
 
  h3[h3d]->minz = minz;
 
 
 
  h3[h3d]->stepx = (nx>1)?(maxx-minx)/(nx):0;
 
  h3[h3d]->stepy = (nx>1)?(maxy-miny)/(ny):0;
 
  h3[h3d]->stepz = (nx>1)?(maxz-minz)/(nz):0;
 
 
 
  h3[h3d]->size = h3[h3d]->nx*h3[h3d]->ny*h3[h3d]->nz*sizeof(double);
 
  h3
[h3d
]->data 
= (double *) malloc(h3
[h3d
]->size
); 
  h3[h3d]->len=sizeof(H3D)-sizeof(double *)+h3[h3d]->size;
 
  H3D_Clear(h3d);
 
  H3D_Print(h3d);
 
//Printf("InitH3D 0x%x\n", h3d );
 
  return  0;
 
 
 
}
 
 
 
 
 
int _VI_FUNC  H3D_SliXY(int histogram,int slice, int direction) {      
 
  
 
if (!H3D_Exist(histogram)) {
 
    printf("3D Histogram %d does not exist!\n",histogram
);  
    return -1;
 
  }
 
 
 
  int hid=499;
 
  switch (direction){
 
    case 0:// xy
 
      H2D_Init(hid,"projectionXY","projectionXY", 
 
               H3D_GetNbinsX(histogram), H3D_GetMinX(histogram),H3D_GetMaxX(histogram),
 
               H3D_GetNbinsY(histogram), H3D_GetMinY(histogram),H3D_GetMaxY(histogram)
 
              );
 
      for (int i=0; i < H3D_GetNbinsX(histogram); i++ ) 
 
        for (int j=0; j < H3D_GetNbinsY(histogram); j++ ) 
 
          H2D_SetBinContent(hid,i,j,H3D_GetBinContent(histogram,i,j,slice));
 
      break;
 
    case 1:// xz
 
      H2D_Init(hid,"projectionXZ","projectionXZ", 
 
               H3D_GetNbinsX(histogram), H3D_GetMinX(histogram),H3D_GetMaxX(histogram),
 
               H3D_GetNbinsZ(histogram), H3D_GetMinZ(histogram),H3D_GetMaxZ(histogram)
 
              );
 
      for (int i=0; i < H3D_GetNbinsX(histogram); i++ ) 
 
        for (int j=0; j < H3D_GetNbinsZ(histogram); j++ ) 
 
          H2D_SetBinContent(hid,i,j,H3D_GetBinContent(histogram,i,slice,j));
 
      break;
 
    case 2:// yz
 
    default:
 
      H2D_Init(hid,"projectionYZ","projectionYZ", 
 
               H3D_GetNbinsY(histogram), H3D_GetMinY(histogram),H3D_GetMaxY(histogram),
 
               H3D_GetNbinsZ(histogram), H3D_GetMinZ(histogram),H3D_GetMaxZ(histogram)
 
              );
 
      for (int i=0; i < H3D_GetNbinsY(histogram); i++ ) 
 
        for (int j=0; j < H3D_GetNbinsZ(histogram); j++ ) 
 
          H2D_SetBinContent(hid,i,j,H3D_GetBinContent(histogram,slice,i,j));
 
      
 
      break;
 
  }
 
  return hid;
 
}
 
 
 
double  _VI_FUNC H3D_GetMaxX(int h){
 
  return h3[h]->minx+(h3[h]->nx)*h3[h]->stepx;
 
}
 
 
 
double  _VI_FUNC H3D_GetMaxY(int h){
 
  return h3[h]->miny+(h3[h]->ny)*h3[h]->stepy;
 
}
 
 
 
double  _VI_FUNC H3D_GetMaxZ(int h){
 
  return h3[h]->minz+(h3[h]->nz)*h3[h]->stepz;
 
}
 
 
 
double _VI_FUNC  H3D_GetXBinCenter(int h3d,int xbin) {
 
  return h3[h3d]->minx+(xbin+0.5)*h3[h3d]->stepx;
 
}
 
 
 
double _VI_FUNC  H3D_GetYBinCenter(int h3d,int ybin) {
 
  return h3[h3d]->miny+(ybin+0.5)*h3[h3d]->stepy;
 
}
 
 
 
double _VI_FUNC  H3D_GetZBinCenter(int h3d,int zbin) {
 
  return h3[h3d]->minz+(zbin+0.5)*h3[h3d]->stepz;
 
}
 
 
 
 
 
int _VI_FUNC  H3D_Write2File(int h3d,FILE *fp) {
 
 
 
  if (!fp) return -1;
 
//printf("H3D sizeof(H3D)=%lu len-datasize=%d len=%lu datasize=%d\t",sizeof(H3D)-sizeof(double *),h3[h3d]->len-h3[h3d]->size,h3[h3d]->len,h3[h3d]->size);
 
//printf("H3D sz=%d %d\n",sizeof(double),sizeof(double *));
 
  fwrite (h3
[h3d
], 1, sizeof(H3D
)-sizeof(double *), fp
);  
  fwrite (h3
[h3d
]->data
, 1, h3
[h3d
]->size
, fp
);  
  return  0;
 
}
 
 
 
int _VI_FUNC  H3D_Write(int h3d,const char *fname,const char *opt) {
 
  FILE 
*fp
=fopen(fname
,opt
); 
  H3D_Write2File(h3d,fp);
 
  return  0;
 
}
 
 
 
 
 
 
 
 
 
int _VI_FUNC  H3D_SetTitle(int h3d,char *title) {
 
  sprintf(h3
[h3d
]->title
,"%s",title
);  
  return 0;
 
}
 
 
 
 
 
int _VI_FUNC  H3D_SetTitleX(int h3d,char *title) {
 
  sprintf(h3
[h3d
]->titlex
,"%s",title
);  
  return 0;
 
}
 
 
 
 
 
int _VI_FUNC  H3D_SetTitleY(int h3d,char *title) {
 
  sprintf(h3
[h3d
]->titley
,"%s",title
);  
  return 0;
 
}
 
 
 
int _VI_FUNC  H3D_SetTitleZ(int h3d,char *title) {
 
  sprintf(h3
[h3d
]->titlez
,"%s",title
);  
  return 0;
 
}
 
 
 
 
 
int _VI_FUNC  H3D_SetName(int h3d,char *title) {
 
  return 0;
 
}
 
 
 
int _VI_FUNC  H3D_GetNbinsY(int h) {
 
  if (h3[h]) return h3[h]->ny;
 
  else return 0;
 
}
 
 
 
int _VI_FUNC  H3D_GetNbinsX(int h) {
 
  if (h3[h]) return h3[h]->nx;
 
  else return 0;
 
}
 
 
 
int _VI_FUNC  H3D_GetNbinsZ(int h) {
 
  if (h3[h]) return h3[h]->nz;
 
  else return 0;
 
}
 
 
 
 
 
 
 
double _VI_FUNC  H3D_GetMinX(int h) {
 
  if (h3[h]) return h3[h]->minx;
 
  else return 0;
 
}
 
 
 
double _VI_FUNC  H3D_GetMinY(int h) {
 
  if (h3[h]) return h3[h]->miny;
 
  else return 0;
 
}
 
 
 
double _VI_FUNC  H3D_GetMinZ(int h) {
 
  if (h3[h]) return h3[h]->minz;
 
  else return 0;
 
}
 
 
 
 
 
 
 
 
 
double _VI_FUNC  H3D_GetStepX(int h) {
 
  if (h3[h]) return h3[h]->stepx;
 
  else return 0;
 
}
 
 
 
double _VI_FUNC  H3D_GetStepY(int h) {
 
  if (h3[h]) return h3[h]->stepy;
 
  else return 0;
 
}
 
 
 
double _VI_FUNC  H3D_GetStepZ(int h) {
 
  if (h3[h]) return h3[h]->stepz;
 
  else return 0;
 
}
 
 
 
 
 
 
 
 
 
double _VI_FUNC  H3D_GetMin(int h) {
 
  if (h3[h]) return h3[h]->min;
 
  else return 0;
 
}
 
 
 
double _VI_FUNC  H3D_GetMax(int h) {
 
  if (h3[h]) return h3[h]->max;
 
  else return 0;
 
}
 
 
 
double *  _VI_FUNC  H3D_GetSliceXYData(int h, int slice) {
 
  if (h3[h]) return (h3[h]->data+slice*h3[h]->nx*h3[h]->ny);
 
  else return NULL;
 
}
 
 
 
double *  _VI_FUNC  H3D_GetData(int h) {
 
  if (h3[h]) return h3[h]->data;
 
  else return NULL;
 
}
 
 
 
 
 
#ifdef _CVI_
 
// defined only in CVI
 
static HColorMap *colormap = NULL;
 
 
 
 
 
HColorMap * _VI_FUNC  H3D_GetColorMap(void) {
 
  return colormap;
 
}
 
 
 
 
 
int _VI_FUNC  H3D_SetRangeColors( double min, double max) {
 
  int i;
 
 
 
 
 
  if (colormap == NULL) {
 
    colormap 
= malloc(sizeof(HColorMap
)); 
 
 
    colormap->numberofColors = 5;
 
    colormap
->array 
= malloc(colormap
->numberofColors
*sizeof(ColorMapEntry
)); 
 
 
    colormap->array[0].color = 0x0000ff; //BLUE
 
    colormap->array[1].color = 0x00ff00; //GREEN
 
    colormap->array[2].color = 0xffff00; //YELLOW
 
    colormap->array[3].color = 0xff8000; //ORANGE
 
    colormap->array[4].color = 0xff0000; //RED
 
 
 
    colormap->HiColor =colormap->array[colormap->numberofColors-1].color ;
 
  }
 
  if (colormap->numberofColors<2) return -1;
 
  double fx = (max-min)/(colormap->numberofColors-1);
 
  for  (i=0; i<colormap->numberofColors; i++) {
 
    colormap->array[i].dataValue.valDouble=i*fx+min;
 
  }
 
  return 0;
 
}
 
 
 
int  _VI_FUNC  H3D_DrawSliceXY(int histogram,int slice,int direction, int panel, int control, int *plothandle) {
 
  
 
  
 
  
 
  if (H3D_GetNbinsY(histogram)==1|| H3D_GetNbinsX(histogram)==1) {
 
    if (H3D_GetNbinsY(histogram)==1) {
 
      H1D_Init(499,"projection","projection", H3D_GetNbinsX(histogram), H3D_GetMinX(histogram),H3D_GetMaxX(histogram));
 
      for (int i=0; i < H3D_GetNbinsX(histogram); i++ ) H1D_SetBinContent(499,i,H3D_GetBinContent(histogram,i,0,slice));
 
    } else {
 
      H1D_Init(499,"projection","projection", H3D_GetNbinsY(histogram), H3D_GetMinY(histogram),H3D_GetMaxY(histogram));
 
      for (int i=0; i < H3D_GetNbinsY(histogram); i++ ) H1D_SetBinContent(499,i,H3D_GetBinContent(histogram,0,i,slice));
 
    }
 
    H1D_Draw(499, panel, control, plothandle);
 
  } else {
 
 
 
    if (*plothandle> 0 ) DeleteGraphPlot (panel, control, *plothandle, VAL_IMMEDIATE_DRAW);
 
    H3D_SetRangeColors(H3D_GetMin(histogram),H3D_GetMax(histogram));
 
    *plothandle = PlotScaledIntensity (panel, control,
 
                                       H3D_GetSliceXYData(histogram, slice),
 
                                       H3D_GetNbinsX(histogram),
 
                                       H3D_GetNbinsY(histogram),
 
                                       VAL_DOUBLE,
 
                                       H3D_GetStepY(histogram),
 
                                       H3D_GetYBinCenter(histogram,0),
 
                                       H3D_GetStepX(histogram),
 
                                       H3D_GetXBinCenter(histogram,0),
 
                                       colormap->array,
 
                                       colormap->HiColor,
 
                                       colormap->numberofColors, 1, 0);
 
  }
 
  ProcessSystemEvents ();
 
  return *plothandle;
 
 
 
}
 
#endif