Commit e1677041 authored by saeed's avatar saeed
Browse files

first commit

parents
#define NX (4020)
#define NY (1680)
#define NT (1)
#define NUM_THREADS (1)
#define WIDTH_INIT (1200)
#define HEIGHT_INIT (900)
#define SYM_SIZE (10)
#define WIDTH_TR1 (600)
#define HEIGHT_TR1 (600)
#define INCREASE_RADIUS (1.5)
#define VMAX (1.0)
#define VMIN (0.0)
#define useminmax 0
#define usesrgb 1
#define oceancolor 0xffffffff
#define landcolor 0xb1b1b1b1
#define stncolor 0x00bf0000
static void reverse(char *s, char *t, int sign, int npadzero){
char *tmp = s;
int len = 0;
while (*tmp !='\0' ){
tmp++;
len++;
}
tmp--;
if (sign < 0){
*t = '-';
t++;
}
while(npadzero--){
*t = '0';
t++;
}
while (len >0 ){
*t = *tmp;
tmp--;
len--;
t++;
}
*t = '\0';
}
static void intostr(int a, char *st){
int sign = 1;
if (a < 0){
sign = -1;
a = (-a);
}
int index = 0;
int r = -1 ;
int q = 0;
char cl[64] = {'\0'};
do {
r = a % 10;
q = (a - r) / 10;
*(cl+index) = (char)(r+'0');
a = q;
index++;
}while(a >0);
*(cl+index) = '\0';
reverse(cl,st,sign,0);
}
static void floatostr(float a, char *str, int nafterdecimalpoint){
int sign = 1;
long long int ia = (long long int) (a);
if (a < 0) {
//printf("we are here\n");
sign = -1;
a = (-a);
ia = (long long int) (a);
}
int npadzero = 0;
long long int n = 1;
float b = a - (float)ia;
float bt = b;
int hitnonzero = 0;
//printf("b is %f\n",b);
for(int i=0; i < nafterdecimalpoint;++i){
n *= 10L;
bt *= 10L;
if (((long long int)bt == 0) && (hitnonzero == 0)) npadzero++;
if ((long long int)bt != 0 ) hitnonzero = 1;
bt = bt - (long long int)bt;
}
if (nafterdecimalpoint == 1) npadzero = 0;
b *= n;
long long int ifrac = (long long int) b;
int index = 0;
long long int r = -1 ;
long long int q = 0;
char cl[64] = {'\0'};
char ctmp[64] = {'\0'};
do {
r = ia % 10;
q = (ia - r) / 10;
*(cl+index) = (char)(r+'0');
ia = q;
index++;
}while(ia >0);
*(cl+index) = '\0';
reverse(cl,ctmp,sign,0);
char ck[64] = {'\0'};
char ctmp1[64] = {'\0'};
r = -1 ;
q = 0;
index = 0;
do {
r = ifrac % 10;
q = (ifrac - r) / 10;
*(ck+index) = (char)(r+'0');
ifrac = q;
index++;
}while(ifrac >0);
*(ck+index) = '\0';
if (sign > 0){
reverse(ck,ctmp1,sign,npadzero);
}else{
reverse(ck,ctmp1,-sign,npadzero);
}
char *tmp = ctmp;
while(*tmp != '\0'){
*str = *tmp;
str++;
tmp++;
}
*str = '.';
str++;
tmp = ctmp1;
while(*tmp != '\0'){
*str = *tmp;
str++;
tmp++;
}
*str = '\0';
return;
}
static void colortoRGBA(uint32 color, uint8 *red, uint8 *green, uint8 *blue, uint8 *alpha){
*red = 0x0;
*green = 0x0;
*blue = 0x0;
*alpha = 0x0;
*alpha = (uint8)((color >> 24) & (0xff));
*red = (uint8)((color >> 16) & (0xff));
*green = (uint8)((color >> 8) & (0xff));
*blue = (uint8)((color) & (0xff));
return;
}
static void lineartosrgb(float *red, float *green, float *blue){
*red = sqrt(*red);
*green = sqrt(*green);
*blue = sqrt(*blue);
}
static void clamp(float *value, float min, float max){
if (*value <= min) *value = min;
if (*value >= max) *value = max;
}
static XImage *CreateTrueColorImage(Display *display, Visual *visual, int width, int height, struct field *FLD)
{
return XCreateImage(display, visual, 24, ZPixmap, 0, FLD->image32, width, height, 32, 0);
}
static struct Vis init_x(int w, int h){
struct Vis result = {0};
result.w = w;
result.h = h;
result.dsp = XOpenDisplay((char *)0);
result.screen_num = DefaultScreen(result.dsp);
result.visual=DefaultVisual(result.dsp, 0);
result.depth = DefaultDepth(result.dsp,result.screen_num);
XSetWindowAttributes attributes;
attributes.background_pixel = XWhitePixel(result.dsp,result.screen_num);
attributes.border_pixel = XWhitePixel(result.dsp,result.screen_num);
attributes.override_redirect = 0;
result.win = XCreateWindow(result.dsp,RootWindow(result.dsp,result.screen_num), 0, 0, w, h, 0, result.depth, InputOutput,result.visual ,CWBackPixel | CWBorderPixel | CWOverrideRedirect, &attributes);
XSelectInput(result.dsp, result.win, ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask | PointerMotionMask | FocusChangeMask);
result.fontinfo = XLoadQueryFont(result.dsp,"10x20");
result.gr_values.font = result.fontinfo->fid;
result.gr_values.function = GXcopy;
result.gr_values.plane_mask = AllPlanes;
result.gr_values.foreground = WhitePixel(result.dsp,result.screen_num);
result.gr_values.background = WhitePixel(result.dsp,result.screen_num);
result.gc=XCreateGC(result.dsp,result.win,GCFont | GCFunction | GCPlaneMask | GCForeground | GCBackground,&result.gr_values);
result.cmap = DefaultColormap(result.dsp, result.screen_num);
XStoreName( result.dsp, result.win, "ODBVIS" ) ;
XSetIconName( result.dsp, result.win, "ODBVIS" ) ;
// say window manager which position we would prefer
XSizeHints sizehints ;
sizehints.flags = USPosition | USSize ;
sizehints.x = 200 ; sizehints.y = 200 ;
sizehints.width = w ; sizehints.height = h ;
XSetWMNormalHints( result.dsp, result.win, &sizehints ) ;
return result;
}
static void map_window(struct Vis *Vis){
XMapWindow(Vis->dsp, Vis->win);
for(;;){XEvent e; XNextEvent(Vis->dsp,&e); if(e.type == MapNotify) break;} //Wait for the MapNotify event
XFlush(Vis->dsp);
}
static void get2dfield_binary(char *filename,struct field *fld){
FILE *file = fopen(filename,"rb");
if (file){
(void)fread(fld->SSH,sizeof(fld->SSH),1,file);
(void)fread(fld->lat,sizeof(fld->lat),1,file);
(void)fread(fld->lon,sizeof(fld->lon),1,file);
(void)fclose(file);
}
}
static struct dsp_field adjusttowindowsize(struct Vis *vis, struct field *FLD){
struct dsp_field result = {NULL,NULL,vis->w,vis->h};
result.SSH = (float *)malloc(sizeof(float) *vis->h * vis->w);
result.image32 = (uint8 *)malloc(sizeof(uint8) *vis->h * vis->w * 4);
for (int j=0; j < NY;++j){
for (int i=0; i < NX;++i){
struct Index index = map(i, j, vis->w, vis->h, NX, NY);
*(result.SSH + index.j * vis->w + index.i) = (float)FLD->SSH[j *NX + i];
}
}
return result;
}
static void free_dsp_field(struct dsp_field *dspf){
if (dspf->SSH) free(dspf->SSH);
if (dspf->image32)free(dspf->image32);
}
static int isinsymbol(int i, int j,float radius, int x, int y){
int result = (sqrt((float)( x -i) * (float)( x -i) + (float)( y -j) * (float)( y -j)) <= (float)(radius)) ? 1 : 0;
return result;
}
static void getminmax(float *min, float *max, struct dsp_field *dspf){
if (useminmax){
*min = VMIN;
*max = VMAX;
}
else{
*min = minvall(dspf->SSH, dspf->nx *dspf->ny);
*max = maxvall(dspf->SSH, dspf->nx *dspf->ny);
}
}
static void drawonscreen_expose(struct Vis *vis,struct dsp_field *dspf,struct Colort *scolor, int ncolor, struct obs *obsp, struct screen_dim *scdim){
float minv = 0.0f, maxv = 0.0f;
uint8 ured = 0x0, ugreen = 0x0, ublue = 0x0, ualpha = 0x0;
uint32 pcolor = 0x0;
float value =0.0f;
XImage *ximage = NULL;
uint32 *pimage = NULL;
struct symbol symb = {10};
symb.radius = getradius(vis->w,vis->h,scdim);
struct mousepose mspose = {0,0};
Pixmap pixmap = XCreatePixmap(vis->dsp, vis->win, vis->w, vis->h, vis->depth);
XSetForeground(vis->dsp, vis->gc, 0xffffffff);
XFillRectangle(vis->dsp, pixmap, vis->gc, 0, 0, vis->w, vis->h);
XFlush(vis->dsp);
pimage = (uint32 *)dspf->image32;
for (int j=0; j < dspf->ny; ++j){
for (int i=0; i < dspf->nx;++i){
if (dspf->SSH[(dspf->ny -j -1)*dspf->nx+i] == 0.0){
pcolor=landcolor;
}
else{
pcolor=oceancolor;
}
*pimage++ = pcolor;
}
}
ximage = XCreateImage(vis->dsp, vis->visual, 24, ZPixmap, 0, dspf->image32, vis->w, vis->h, 32, 0);
XPutImage(vis->dsp, pixmap, vis->gc, ximage, 0, 0, 0, 0, vis->w, vis->h);
XSetForeground(vis->dsp, vis->gc, stncolor);
for (int i=0; i< obsp->npy;++i){
if (obsp->iindex[i] != -1 && obsp->jindex[i] != -1){
struct Index index = map(obsp->iindex[i], obsp->jindex[i], vis->w, vis->h, NX, NY);
XFillArc (vis->dsp, pixmap, vis->gc,index.i - (int)(symb.radius *0.50), vis->h - index.j -1 - (int)(symb.radius *0.50), (int)(symb.radius),(int)(symb.radius), 0, 360 * 64);
XFlush(vis->dsp);
}
}
XCopyArea (vis->dsp, pixmap, vis->win, vis->gc,0, 0,vis->w, vis->h,0, 0);
XFreePixmap(vis->dsp,pixmap);
XFree(ximage);
XFlush(vis->dsp);
free_dsp_field(dspf);
}
static void drawonscreen_configure(struct Vis *vis,XEvent *e,struct Colort *scolor, int ncolor, struct obs *obsp, struct screen_dim *scdim){
while(XCheckTypedEvent(vis->dsp,ConfigureNotify,e));
XConfigureEvent xce = e->xconfigure;
vis->w = (int)xce.width;
vis->h = (int)xce.height;
struct dsp_field *dspf = NULL;
struct dsp_field dspf_t = adjusttowindowsize(vis, &FLD);
dspf = &dspf_t;
drawonscreen_expose(vis,dspf,scolor,ncolor,obsp,scdim);
}
static void drawonscreen_changecolormap(struct Vis *vis,XEvent *e,struct Colort *scolor, int ncolor, struct obs *obsp, struct screen_dim *scdim){
struct dsp_field *dspf = NULL;
struct dsp_field dspf_t = adjusttowindowsize(vis, &FLD);
dspf = &dspf_t;
drawonscreen_expose(vis,dspf,scolor,ncolor,obsp,scdim);
}
static XColor setcolorcursor(struct Vis *vis, short r, short g, short b){
XColor result;
result.red = r;
result.green = g;
result.blue = b;
result.flags = DoRed | DoGreen | DoBlue;
XAllocColor(vis->dsp, vis->cmap, &result);
return result;
}
static int changecolorcursor(Display *dsp, Cursor *cursor, XColor* cfg, XColor* cbg){
int result = XRecolorCursor(dsp,*cursor,cfg,cbg);
return result;
}
static void drawonscreen_motion(struct Vis *vis,struct Colort *scolor, int ncolor,struct obs *obsp, XEvent *e,struct screen_dim *scdim){
while(XCheckTypedEvent(vis->dsp,MotionNotify,e));
struct dsp_field *dspf = NULL;
int x = e->xmotion.x;
int y = vis->h - e->xmotion.y -1;
float minv = 0.0f, maxv = 0.0f;
uint8 ured = 0x0, ugreen = 0x0, ublue = 0x0, ualpha = 0x0;
uint32 pcolor = 0x0;
float value =0.0f;
float increase_radius = INCREASE_RADIUS;
XImage *ximage = NULL;
uint32 *pimage = NULL;
struct symbol symb = {10};
symb.radius = getradius(vis->w,vis->h,scdim);
Pixmap pixmap = XCreatePixmap(vis->dsp, vis->win, vis->w, vis->h, vis->depth);
XSetForeground(vis->dsp, vis->gc, 0xffffffff);
XSetBackground(vis->dsp, vis->gc, 0xffffffff);
XFillRectangle(vis->dsp, pixmap, vis->gc, 0, 0, vis->w, vis->h);
XFlush(vis->dsp);
int istn = -1;
int ipos = -1;
int jpos = -1;
for (int i=0; i< obsp->npy;++i){
if (obsp->iindex[i] != -1 && obsp->jindex[i] != -1){
struct Index index = map(obsp->iindex[i], obsp->jindex[i], vis->w, vis->h, NX, NY);
if (isinsymbol(index.i,index.j,symb.radius *0.5,x,y)){
istn = i;
ipos = index.i;
jpos = index.j;
break;
}
}
}
while(XCheckTypedEvent(vis->dsp,MotionNotify,e));
if (istn >= 0){
XSetForeground(vis->dsp, vis->gc, 0xffffffff);
XFillRectangle(vis->dsp, pixmap, vis->gc, 0, 0, vis->w, vis->h);
vis->font_cursor = XCreateFontCursor(vis->dsp, XC_hand2);
XDefineCursor(vis->dsp, vis->win, vis->font_cursor);
XSync(vis->dsp, False);
struct dsp_field dspf_t = adjusttowindowsize(vis, &FLD);
dspf = &dspf_t;
pimage = (uint32 *)dspf->image32;
for (int j=0; j < dspf->ny; ++j){
for (int i=0; i < dspf->nx;++i){
if (dspf->SSH[(dspf->ny -j -1)*dspf->nx+i] == 0.0){
pcolor=landcolor;
}
else{
pcolor=oceancolor;
}
*pimage++ = pcolor;
}
}
ximage = XCreateImage(vis->dsp, vis->visual, 24, ZPixmap, 0, dspf->image32, vis->w, vis->h, 32, 0);
XPutImage(vis->dsp, pixmap, vis->gc, ximage, 0, 0, 0, 0, vis->w, vis->h);
XSetForeground(vis->dsp, vis->gc, 0x00bf0000);
for (int i=0; i< obsp->npy;++i){
if (obsp->iindex[i] != -1 && obsp->jindex[i] != -1){
if (i != istn){
struct Index index = map(obsp->iindex[i], obsp->jindex[i], vis->w, vis->h, NX, NY);
XFillArc (vis->dsp, pixmap, vis->gc,index.i - (int)(symb.radius *0.50), vis->h - index.j -1 - (int)(symb.radius *0.50), (int)(symb.radius),(int)(symb.radius), 0, 360 * 64);
XFlush(vis->dsp);
}
}
}
if (obsp->iindex[istn] != -1 && obsp->jindex[istn] != -1){
struct Index index = map(obsp->iindex[istn], obsp->jindex[istn], vis->w, vis->h, NX, NY);
XSetForeground(vis->dsp, vis->gc, 0x00bf0000);
XFillArc (vis->dsp, pixmap, vis->gc,index.i - (int)(symb.radius *0.50*increase_radius), vis->h - index.j -1 - (int)(symb.radius *0.50*increase_radius), (int)(symb.radius *increase_radius),(int)(symb.radius * increase_radius), 0, 360 * 64);
XFlush(vis->dsp);
}
XSetForeground(vis->dsp, vis->gc, 0x0);
int txw = XTextWidth(vis->fontinfo,stns[istn].name,lenstring(stns[istn].name));
int direction;
int ascent;
int descent;
XCharStruct overall;
XTextExtents(vis->fontinfo,stns[istn].name,lenstring(stns[istn].name),&direction, &ascent, &descent, &overall);
int txh = (int)(ascent + descent);
int radi = symb.radius;
radi = 0;
XFillRectangle(vis->dsp, pixmap, vis->gc, ipos + radi, vis->h - jpos -1 + radi / 2, (int)(1.20 *txw), 3 * txh);
XFlush(vis->dsp);
XSetForeground(vis->dsp, vis->gc, 0xffffff);
XDrawString(vis->dsp, pixmap, vis->gc,(int)(ipos + radi + 0.1 *txw),vis->h - jpos -1 + radi / 2 + txh + ascent ,stns[istn].name,lenstring(stns[istn].name));
XFlush(vis->dsp);
XCopyArea (vis->dsp, pixmap, vis->win, vis->gc,0, 0,vis->w, vis->h,0, 0);
free_dsp_field(dspf);
XFree(ximage);
}
else{
XUndefineCursor(vis->dsp, vis->win);
XSetForeground(vis->dsp, vis->gc, 0xffffffff);
XFillRectangle(vis->dsp, pixmap, vis->gc, 0, 0, vis->w, vis->h);
struct dsp_field dspf_t = adjusttowindowsize(vis, &FLD);
dspf = &dspf_t;
pimage = (uint32 *)dspf->image32;
for (int j=0; j < dspf->ny; ++j){
for (int i=0; i < dspf->nx;++i){
if (dspf->SSH[(dspf->ny -j -1)*dspf->nx+i] == 0.0){
pcolor=landcolor;
}
else{
pcolor=oceancolor;
}
*pimage++ = pcolor;
}
}
ximage = XCreateImage(vis->dsp, vis->visual, 24, ZPixmap, 0, dspf->image32, vis->w, vis->h, 32, 0);
XPutImage(vis->dsp, pixmap, vis->gc, ximage, 0, 0, 0, 0, vis->w, vis->h);
XSetForeground(vis->dsp, vis->gc, stncolor);
for (int i=0; i< obsp->npy;++i){
if (obsp->iindex[i] != -1 && obsp->jindex[i] != -1){
struct Index index = map(obsp->iindex[i], obsp->jindex[i], vis->w, vis->h, NX, NY);
XFillArc (vis->dsp, pixmap, vis->gc,index.i - (int)(symb.radius *0.50), vis->h - index.j -1 - (int)(symb.radius*0.50), (int)(symb.radius),(int)(symb.radius), 0, 360 * 64);
XFlush(vis->dsp);
}
}
XCopyArea (vis->dsp, pixmap, vis->win, vis->gc,0, 0,vis->w, vis->h,0, 0);
free_dsp_field(dspf);
XFree(ximage);
}
XFreePixmap(vis->dsp,pixmap);
}
static void showinfoonsecondwindow(struct Vis *vis, char *info){
Pixmap pixmap = XCreatePixmap(vis->dsp, vis->win, vis->w, vis->h, vis->depth);
XSetForeground(vis->dsp, vis->gc, 0xffffffff);
XFillRectangle(vis->dsp, pixmap, vis->gc, 0, 0, vis->w, vis->h);
int txw = XTextWidth(vis->fontinfo,info,lenstring(info));
int direction;
int ascent;
int descent;
XCharStruct overall;
XTextExtents(vis->fontinfo,info,lenstring(info),&direction, &ascent, &descent, &overall);
int txh = (int)(ascent + descent);
XSetForeground(vis->dsp, vis->gc, 0x0);
XDrawString(vis->dsp, pixmap, vis->gc,vis->w / 2 - txw,vis->h / 2,info,lenstring(info));
XCopyArea (vis->dsp, pixmap, vis->win, vis->gc,0, 0,vis->w, vis->h,0, 0);
XFreePixmap(vis->dsp,pixmap);
XFlush(vis->dsp);
}
static int heightpos(int h, float spacing, int nb){
int result = (int)(h * spacing) *nb;
return result;
}
static void odbinfo_onotherwindow(struct Vis *vis, struct odbinfo *odbinfo){
Pixmap pixmap = XCreatePixmap(vis->dsp, vis->win, vis->w, vis->h, vis->depth);
XSetForeground(vis->dsp, vis->gc, 0xffffffff);
XFillRectangle(vis->dsp, pixmap, vis->gc, 0, 0, vis->w, vis->h);
int txw = XTextWidth(vis->fontinfo,odbinfo->filename,lenstring(odbinfo->filename));
int direction;
int ascent;
int descent;
XCharStruct overall;
XTextExtents(vis->fontinfo,odbinfo->filename,lenstring(odbinfo->filename),&direction, &ascent, &descent, &overall);
int txh = (int)(ascent + descent);
XSetForeground(vis->dsp, vis->gc, 0x0);
float spacing = 0.060;
int nb = 1;
int indent = 20;
char *info = "filename:";
txw = XTextWidth(vis->fontinfo,info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent,heightpos(vis->h,spacing,nb) ,info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent + txw,heightpos(vis->h,spacing,nb) ,odbinfo->filename,lenstring(odbinfo->filename));
nb++;
info = "report type:";
txw = XTextWidth(vis->fontinfo,info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent,heightpos(vis->h,spacing,nb),info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent+txw,heightpos(vis->h,spacing,nb),odbinfo->reportype,lenstring(odbinfo->reportype));
nb++;
info = "description:";
txw = XTextWidth(vis->fontinfo,info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent,heightpos(vis->h,spacing,nb),info,lenstring(info));
if (odbinfo->desc)XDrawString(vis->dsp, pixmap, vis->gc,indent+txw,heightpos(vis->h,spacing,nb),odbinfo->desc,lenstring(odbinfo->desc));
nb++;
info = "group:";
txw = XTextWidth(vis->fontinfo,info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent,heightpos(vis->h,spacing,nb),info,lenstring(info));
if (odbinfo->group)XDrawString(vis->dsp, pixmap, vis->gc,indent+txw,heightpos(vis->h,spacing,nb),odbinfo->group,lenstring(odbinfo->group));
nb++;
info = "number of observation:";
txw = XTextWidth(vis->fontinfo,info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent,heightpos(vis->h,spacing,nb),info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent+txw,heightpos(vis->h,spacing,nb),odbinfo->ntotal,lenstring(odbinfo->ntotal));
nb++;
info = "cycle:";
txw = XTextWidth(vis->fontinfo,info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent,heightpos(vis->h,spacing,nb),info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent+txw,heightpos(vis->h,spacing,nb),odbinfo->cycle,lenstring(odbinfo->cycle));
nb++;
info = "start_date:";
txw = XTextWidth(vis->fontinfo,info,lenstring(info));
XDrawString(vis->dsp, pixmap, vis->gc,indent,heightpos(vis->h,spacing,nb),info,lenstring(info));