/* extmain.c */ /* * Vis5D system for visualizing five dimensional gridded data sets. * Copyright (C) 1990 - 2000 Bill Hibbard, Johan Kellum, Brian Paul, * Dave Santek, and Andre Battaiola. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * As a special exception to the terms of the GNU General Public * License, you are permitted to link Vis5D with (and distribute the * resulting source and executables) the LUI library (copyright by * Stellar Computer Inc. and licensed for distribution with Vis5D), * the McIDAS library, and/or the NetCDF library, where those * libraries are governed by the terms of their own licenses. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "../config.h" /* This is the wrapper for Vis5D external analysis functions. */ #include #include #include #include #include /* must be before sys/resource.h */ #include #include #include #include "socketio.h" #include "v5d.h" /* To get MAXTIMES, etc */ static int Nr, Nc, Nl[MAXLEVELS], LowLev[MAXLEVELS], MaxNl; static int NumTimes, NumVars; static int Projection, Vertical; static float Proj_Args[100], Vert_Args[MAXLEVELS]; static float ProbeRow, ProbeCol, ProbeLev; static float ProbeLat, ProbeLon, ProbeHgt; static float ProbeValue[MAXVARS]; #define NUMARGS 5 static float Argument[NUMARGS]; /* only use is commented out; argument function not called */ /* Define this if using McIDAS library */ #define LIB_MCIDAS /* * Create a socket with the given Unix-domain name. * Input: socket name * Return: socket number or -1 if error. */ static int create_socket( char *name ) { struct sockaddr_un addr; int len, sock; int tries; /* create socket */ sock = socket( PF_UNIX, SOCK_STREAM, 0 ); if (sock<0) { perror("function creating socket"); return -1; } /* try to connect socket to given name */ /*printf("EXTMAIN: creating socket named: %s\n", name );*/ strcpy( addr.sun_path, name ); addr.sun_family = AF_UNIX; len = strlen(addr.sun_path)+sizeof(addr.sun_family); for (tries=0;tries<5;tries++) { if (connect(sock, (struct sockaddr *) &addr, len) < 0) { perror("External Function Error: function connect failed"); /*printf(" failed on try %d\n", tries );*/ } else { /* success !*/ return sock; } } /* error */ return -1; } /*** call_user_function *********************************************** Get arguments from Vis5D, compute new grid data by calling user function and return results back to Vis5D. Input: sock - socket number Return: 1 = OK, 0 = error. **********************************************************************/ static int call_user_function( int sock ) { int it, iv, i; float *ingrid, *outgrid; char names[MAXVARS][8]; int error_flag; int outnl, outlowlev; /*** First we get the parameter which won't change for each timestep ***/ /* get number of time steps and variables */ receive_int( sock, &NumTimes ); receive_int( sock, &NumVars ); /*printf("EXTMAIN: times:%d vars:%d\n", NumTimes, NumVars);*/ /* Receive size of grids */ receive_int( sock, &Nr ); receive_int( sock, &Nc ); MaxNl = 0; for (iv=0;ivMaxNl) { MaxNl = Nl[iv]; } } for (iv=0;ivMaxNl) outnl = MaxNl; send_int( sock, outnl ); send_int( sock, outlowlev ); /* we used to return compressed data...oh well */ send_data( sock, outgrid, Nr*Nc*outnl*sizeof(float) ); } } free(ingrid); free(outgrid); return 1; } /* * * main() * */ #ifdef LIB_MCIDAS extern int Argc; extern char **Argvector; F77_FUNC(main0,MAIN0)() { int argc = Argc; char **argv = Argvector; #else /* Not using McIDAS lib */ main( int argc, char *argv[] ) { #endif int sock; if (argc!=2) { printf("Parameter Error: no socket name.\n"); printf("This is a Vis5D external function. It can only be used\n"); printf("via vis5d.\n"); exit(1); } sleep(1); sock = create_socket( argv[1] ); if (sock>=0) { /* send an acknowledgment signal */ send_int( sock, 0x1234 ); /* call user function */ call_user_function( sock ); /* finish up */ close(sock); } return 0; } /*** get_mcgrid ******************************************************* Get a McIDAS grid. Input: file - number of the McIDAS grid file. grid - which grid in the file. data - pointer to buffer to put data. var - which variable this grid is. Output: data - read from the file. Return: 1 = ok, 0 = error. **********************************************************************/ int get_mcgrid( int file, int grid, float *data, int var ) { int result, max, nr, nc, nl, table[64]; printf("Getting McIDAS grid %d %d 0x%x\n", file, grid, data ); if (file==0 && grid==0) { memset( data, 0, Nr*Nc*MaxNl*sizeof(float) ); printf("Filling grid with zeros\n"); } else { max = Nr*Nc*MaxNl; memset( data, 0, Nr*Nc*MaxNl*sizeof(float) ); result = F77_FUNC(iggt3d,IGGT3D) ( &file, &grid, &max, data, &nr, &nc, &nl, table ); /*printf("result=%d nr=%d nc=%d nl=%d\n", result, nr, nc, nl );*/ if (result!=0 || nr!=Nr || nc!=Nc || nl!=Nl[var]) { printf("External Function Error: get_mcgrid error: result=%d\n", result); return 0; } } return 1; } void F77_FUNC(pf,PF)( float *x ) { printf("%g\n", *x); } /* * Return the current probe position in (row,column,level) and * (latitude, longitude, altitude km). */ void F77_FUNC(probepos,PROBEPOS)( float *row, float *col, float *lev, float *lat, float *lon, float *alt ) { *row = ProbeRow + 1.0; *col = ProbeCol + 1.0; *lev = ProbeLev + 1.0; *lat = ProbeLat; *lon = ProbeLon; *alt = ProbeHgt; } /* * Return the value of a variable at the probe's location. * Input: var - which variable [1..NumVars] */ float F77_FUNC(probeval,PROBEVAL)( int *var ) { if (*var>0 && *var<=NumVars) { return ProbeValue[ *var-1 ]; } else { return 1.0e30; /* MISSING VALUE */ } } /* * Return the value of a user-specified argument. The argument(s) are * entered by the user into a GUI form when invoking the function. * Input: n - an argument number in [1..] * Return: the value of the argument or 0 if n is bad. */ float F77_FUNC(argument,ARGUMENT)( int *n ) { if (*n<=0 || *n>NUMARGS) { return 0.0; } else { return Argument[*n-1]; } }