SPModel: postProcessing/NodeHistoryViewer/NodeHistoryViewer.c Source File
VPAC - Computational Software Development
Main | SPModel | StGermain FrameWork |
Main Page | Alphabetical List | Class List | Directories | File List | Class Members | File Members

NodeHistoryViewer.c

Go to the documentation of this file.
00001 #include "mpi.h"
00002 #include <math.h>
00003 #include <sys/time.h>
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <limits.h>
00007 #include <string.h>
00008 #include <unistd.h>
00009 #include <sys/types.h>
00010 #include <sys/time.h>
00011 #include <sys/resource.h>
00012 #include <sys/errno.h>
00013 
00014 #if defined(__APPLE__) && defined(__MACH__)
00015 #include <OpenGL/gl.h>  // Header File For The OpenGL32 Library
00016 #include <OpenGL/glu.h> // Header File For The GLu32 Library
00017 #else
00018 #include <GL/gl.h>  // Header File For The OpenGL32 Library
00019 #include <GL/glu.h> // Header File For The GLu32 Library
00020 #endif
00021 
00022 #include <StGermain/StGermain.h>
00023 #include <SDL/SDL.h>    
00024 
00025 static int displayOn = 0;
00026 
00027 double maxX=0, maxY=0, maxH=0;
00028 double minX=LONG_MAX, minY=LONG_MAX, minH=LONG_MAX;
00029 GLuint selectionBuffer[1024];
00030 
00031 #define WIDTH 800
00032 #define HEIGHT 600
00033 #define BPP 16
00034 int DATA_PER_NODE  = 0;
00035 int LOAD_NODES = 0;
00036 
00037 int scaled;
00038 float ratio;
00039 int         oldMouseX;
00040 int         oldMouseY;
00041 GLdouble        xRot = 0.0;
00042 GLdouble        yRot = 0.0;
00043 int         motionOn = 0;
00044 int         zoomOn = 0;
00045 int         oldZoomY = 0;
00046 double      zoomFactor = 1.0f;
00047 int         showReceivers = 0;
00048 int drawingModeIndex = 0;
00049 int drawingModes[] ={GL_TRIANGLES, GL_LINE_LOOP, GL_POINTS};
00050 
00051 int SetMaximumFiles(long filecount)
00052 {
00053     struct rlimit lim;
00054     
00055     lim.rlim_cur = lim.rlim_max = (rlim_t)filecount;
00056     if ( setrlimit(RLIMIT_NOFILE, &lim) == 0 )
00057         return 1;
00058     else return 0;
00059 }
00060 
00061 int GetMaximumFiles(long *filecount)
00062 {
00063     struct rlimit lim;
00064     
00065     if ( getrlimit(RLIMIT_NOFILE, &lim) == 0 ){
00066         *filecount = (long)lim.rlim_max;
00067         return 1;
00068     } 
00069     else return 0;
00070 }
00071 
00072 void processDumpFiles( char *path )
00073 {
00074     FILE *fileNames = NULL;
00075     FILE *outputFile = NULL;
00076     FILE **dataFiles = NULL;
00077     char buffer[1024] = {0};
00078     char pathPlusFileName[1024] = {0};
00079     char **dataBuffers = NULL;
00080     int numFiles = 0, i = 0, quit = 0;
00081     FILE *tempFile;
00082     char perlCommand[1024] = {0};
00083     char directoryCheck[1024] = {0};
00084     long            maxFileCount = 0;
00085     
00086     /* This function will check if a mergedOutput.txt file already exists in the given directory. The files in the directory
00087      * will only be processed to create mergedOutput.txt if it does not exist */
00088     memset( pathPlusFileName, 0, sizeof( pathPlusFileName ) );
00089     sprintf(  pathPlusFileName, "%s/%s", path, "mergedOutput.txt" );
00090     tempFile = fopen( pathPlusFileName, "r" );
00091     if( tempFile == NULL ){
00092         printf( "processing files in %s/..\n", path );
00093 
00094         if( GetMaximumFiles( &maxFileCount ) ){
00095             if( maxFileCount < DATA_PER_NODE ){
00096                 if( SetMaximumFiles( (int)(DATA_PER_NODE * 1.5) ) ){
00097                     printf( "Successfully increased the maximum number of files that can be opened simultaneously to %d\n", 
00098                             (int)(DATA_PER_NODE * 1.5) );
00099                 }
00100                 else{
00101                     printf( "Cannot open %d files simultaneously\n", DATA_PER_NODE );
00102                     exit( 0 );
00103                 }
00104             }
00105         }
00106         else{
00107             printf( "Could not retrieve the maximum number of files that can be opened simultaneously\n" );
00108             exit(0);
00109         }
00110     }
00111     else{
00112         printf( "mergedOutput.txt already exists in %s/..\nskipping file processing..\n", path );
00113         return;
00114     }
00115 
00116     memset( directoryCheck, 0, sizeof(directoryCheck) );
00117     sprintf( directoryCheck, "%s/%s", path, "fileNames.txt" );
00118     tempFile = fopen( directoryCheck, "w+" );
00119     
00120     if(tempFile){
00121         memset(perlCommand, 0, sizeof(perlCommand));
00122         sprintf( perlCommand, "%s%s", "perl postAnalyzer.pl --path ", path );
00123     
00124         system(perlCommand);
00125     }
00126     else{
00127         printf( "invalid directory..\n" );
00128         exit(0);
00129     }
00130     fclose(tempFile);
00131     
00132 
00133     memset( pathPlusFileName, 0, sizeof(pathPlusFileName) );
00134     sprintf( pathPlusFileName, "%s/%s", path, "fileNames.txt" );
00135     fileNames = fopen( pathPlusFileName, "r" );
00136     
00137     memset( pathPlusFileName, 0, sizeof(pathPlusFileName) );
00138     sprintf( pathPlusFileName, "%s/%s", path, "mergedOutput.txt" );
00139     outputFile = fopen(pathPlusFileName, "w+");
00140     
00141     numFiles = atoi( fgets(buffer, 1024, fileNames) );
00142     dataFiles = malloc(sizeof(FILE*)*numFiles);
00143     dataBuffers = malloc(sizeof(char*)*numFiles);
00144 
00145     for(i=0; i<numFiles; i++){
00146         dataBuffers[i] = malloc(sizeof(char)*1024);
00147     }
00148 
00149     i = 0;
00150     while(fgets(buffer, 1024, fileNames) != NULL){
00151         buffer[strlen(buffer)-1] = '\0';
00152         dataFiles[i++] = fopen(buffer, "r+");
00153     }
00154 
00155     while(!quit){
00156         for(i=0; i<numFiles; i++){
00157             if(fgets(dataBuffers[i], 1024, dataFiles[i]) == NULL){
00158                 quit = 1;
00159                 break;
00160             }
00161             fputs(dataBuffers[i], outputFile);
00162         }
00163         fputs("\n", outputFile);
00164     }
00165 
00166     fclose(fileNames);
00167     fclose(outputFile);
00168     for(i=0; i<numFiles; i++){
00169         fclose(dataFiles[i]);
00170     }
00171 }
00172 
00173 
00174 void clearDepthColor (void)
00175 {
00176     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00177 }
00178 
00179 void mouseClick( int button, int state, int x, int y ) {
00180     if( button == SDL_BUTTON_LEFT ) {
00181         if( state == SDL_PRESSED ) {
00182             oldMouseX = x;
00183             oldMouseY = y;
00184             motionOn = 1;
00185         }
00186         else if ( state == SDL_RELEASED ) {
00187             motionOn = 0;
00188         }
00189     }
00190     else if( button == SDL_BUTTON_RIGHT ) {
00191         if( state == SDL_PRESSED ) {
00192             zoomOn = 1;
00193             oldZoomY = y;
00194         }
00195         else if ( state == SDL_RELEASED ) {
00196             zoomOn = 0;
00197         }
00198     }
00199 }
00200 
00201 
00202 void mouseMotion( int x, int y ) {
00203     if( motionOn ) {
00204         int dx = x - oldMouseX;
00205         int dy = y - oldMouseY;
00206         
00207         xRot += (GLdouble)dx * 0.3;
00208         yRot += (GLdouble)dy * 0.3;
00209         
00210         oldMouseX = x;
00211         oldMouseY = y;
00212     }
00213     if( zoomOn ){
00214         int dy = y - oldZoomY;
00215         
00216         if (zoomFactor+dy*0.03 > 0.0)
00217             zoomFactor += dy*0.03; 
00218         
00219         oldZoomY = y;
00220     }
00221 }
00222 
00223 
00224 int windowEvents() {
00225     SDL_Event   event;
00226     int quit = 0;
00227     
00228     if( SDL_PollEvent( &event ) ) {
00229         switch( event.type ) {
00230             case SDL_QUIT:
00231                 return (quit = 1);
00232                 break;
00233             
00234             case SDL_KEYDOWN:
00235                 switch( event.key.keysym.sym ) {
00236                     case SDLK_ESCAPE:
00237                         return (quit = 1);
00238                     break;
00239                     
00240                     case SDLK_o:
00241                         xRot = 0.0;
00242                         yRot = 0.0;
00243                     break;
00244                     
00245                     case SDLK_m:
00246                         drawingModeIndex = (drawingModeIndex+1) % 3;
00247                     break;
00248                     
00249                     default:
00250                     break;
00251                 }
00252                 break;
00253 
00254             case SDL_MOUSEMOTION:
00255                 mouseMotion( event.motion.x, event.motion.y );
00256             break;
00257             
00258             case SDL_MOUSEBUTTONDOWN:
00259                 mouseClick( event.button.button, event.button.state, event.button.x, event.button.y );
00260             break;
00261             
00262             case SDL_MOUSEBUTTONUP:
00263                 mouseClick( event.button.button, event.button.state, event.button.x, event.button.y );
00264             break;
00265             
00266             default:
00267             break;
00268         }
00269     }
00270     return 0;
00271 }
00272 
00273 void drawCircle (double x, double y, double z, double radius)
00274 {
00275     glPointSize(radius);
00276 
00277     glBegin( GL_POINTS );
00278         glVertex3f( x, y, z );
00279     glEnd();
00280 }
00281 
00282 void dumpNodes (double **data, int from, int to, int range)
00283 {
00284     int i = 0, j = 0;
00285     double maxH = 0, minH = LONG_MAX;
00286 
00287     clearDepthColor();
00288 
00289     for(i=from; i<to; i++){
00290         for(j=0; j<range; j++){
00291             if(maxH<data[i][j])
00292                 maxH = data[i][j];
00293             if(minH>data[i][j])
00294                 minH = data[i][j];
00295         }
00296     }
00297     glMatrixMode(GL_PROJECTION);
00298     glLoadIdentity();
00299     glOrtho( -1, range, minH, maxH, -100, 100 );
00300     glMatrixMode( GL_MODELVIEW ); 
00301     glLoadIdentity();
00302 
00303 
00304     glColor3f(1,1,1);
00305     for(i=from; i<to; i++){
00306         glBegin(GL_LINES);
00307         for(j=0; j<range-1; j++){
00308             glVertex3f( (double)j, data[i][j], -10 );
00309             glVertex3f( (double)j+1, data[i][j+1], -10 );
00310         }
00311         glEnd();
00312     }
00313     
00314     SDL_GL_SwapBuffers();
00315 }
00316 
00317 void initializeGL(void)
00318 {
00319     
00320     glShadeModel(GL_SMOOTH);
00321     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00322     glClearDepth(1.0f);
00323 
00324     glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00325     glEnable (GL_NORMALIZE);
00326     glEnable (GL_DEPTH_TEST);
00327     glDepthFunc(GL_LEQUAL);
00328 
00329     glViewport( 0, 0, WIDTH, HEIGHT ); 
00330     glMatrixMode(GL_PROJECTION);
00331     glLoadIdentity();
00332     glOrtho( -1, 100, -1, 1000, -100, 100 );
00333     glMatrixMode( GL_MODELVIEW ); 
00334     glLoadIdentity();
00335 }
00336 
00337 void createGLWindow ()
00338 {
00339 
00340     /* Flags to pass to SDL_SetVideoMode */
00341     int videoFlags;
00342     const SDL_VideoInfo *videoInfo;
00343     SDL_Surface *surface;
00344 
00345 
00346     /* initialize SDL */
00347     if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
00348     {
00349         fprintf( stderr, "Video initialization failed: %s\n",
00350              SDL_GetError( ) );
00351         exit(0);
00352     }
00353 
00354     /* Fetch the video info */
00355     videoInfo = SDL_GetVideoInfo( );
00356 
00357     if ( !videoInfo )
00358     {
00359         fprintf( stderr, "Video query failed: %s\n",
00360              SDL_GetError( ) );
00361         exit(0);
00362     }
00363 
00364     /* the flags to pass to SDL_SetVideoMode */
00365     videoFlags  = SDL_OPENGL;          /* Enable OpenGL in SDL */
00366     videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
00367     videoFlags |= SDL_HWPALETTE;       /* Store the palette in hardware */
00368 
00369     /* This checks to see if surfaces can be stored in memory */
00370     if ( videoInfo->hw_available )
00371     videoFlags |= SDL_HWSURFACE;
00372     else
00373     videoFlags |= SDL_SWSURFACE;
00374 
00375     /* This checks if hardware blits can be done */
00376     if ( videoInfo->blit_hw )
00377     videoFlags |= SDL_HWACCEL;
00378 
00379     /* Sets up OpenGL double buffering */
00380     SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
00381 
00382     /* get a SDL surface */
00383     surface = SDL_SetVideoMode( WIDTH, HEIGHT, BPP,
00384                 videoFlags );
00385 
00386     /* Verify there is a surface */
00387     if ( !surface )
00388     {
00389         fprintf( stderr,  "Video mode set failed: %s\n", SDL_GetError( ) );
00390         exit(0);
00391     }
00392     initializeGL();
00393     displayOn = 1;
00394     
00395 }
00396 
00397 int main (int argc, char **argv)
00398 {
00399     FILE *inputFile = 0;
00400     double **data;
00401     char buffer[1024];
00402     char *ptr;
00403     int count = 0, i = 0;
00404     int from, to;
00405     int done = 0;
00406     unsigned int maxTimeSteps = 0;
00407     char pathPlusFileName[1024] = {0};
00408     Dictionary          *dictionary;
00409     Dictionary          *meshDict;
00410     XML_IO_Handler*         ioHandler;
00411     char*               filename;
00412     Dictionary_Entry_Value* dictEntryVal = NULL;
00413     MPI_Comm            CommWorld;
00414     int             rank;
00415     int             numProcessors;
00416 
00417     /* Initialise MPI, get world info */
00418     MPI_Init( &argc, &argv );
00419     MPI_Comm_dup( MPI_COMM_WORLD, &CommWorld );
00420     MPI_Comm_size( CommWorld, &numProcessors );
00421     MPI_Comm_rank( CommWorld, &rank );
00422 
00423     if( argc < 3 ){
00424         printf ( "Usage: ./SPModelNodeHistoryViewer input.xml path_to_dump_files\n" );
00425         exit( 0 );
00426     }
00427 
00428     if (!StGermain_Init( &argc, &argv )) {
00429         fprintf(stderr, "Error initialising StGermain, exiting.\n" );
00430         exit(EXIT_FAILURE);
00431     }
00432     
00433     /* Create the dictionary, and some fixed values */
00434     dictionary = Dictionary_New();
00435     Dictionary_Add( dictionary, "rank", Dictionary_Entry_Value_FromUnsignedInt( rank ) );
00436     Dictionary_Add( dictionary, "numProcessors", Dictionary_Entry_Value_FromUnsignedInt( numProcessors ) );
00437 
00438     /* Read input */
00439     ioHandler = XML_IO_Handler_New();
00440     filename = strdup( argv[1] );
00441     
00442     if ( False == IO_Handler_ReadAllFromFile( ioHandler, filename, dictionary ) )
00443     {
00444         fprintf( stderr, "Error: SPModel couldn't find specified input file %s. Exiting.\n", filename );
00445         exit( EXIT_FAILURE );
00446     }
00447     Journal_ReadFromDictionary( dictionary );
00448     
00449     /* maxTimeSteps of 0 means no maximum applied */
00450     /* Note: these try for deprecated key "maxLoops" as well as new one "maxTimeSteps" - Main.PatrickSunter - 4 November 2004 */
00451     dictEntryVal = Dictionary_Get( dictionary, "maxLoops" );
00452     if ( NULL == dictEntryVal ) {
00453         dictEntryVal = Dictionary_GetDefault( dictionary, "maxTimeSteps",
00454             Dictionary_Entry_Value_FromUnsignedInt( 0 ) );
00455     }
00456     maxTimeSteps = Dictionary_Entry_Value_AsUnsignedInt( dictEntryVal );
00457 
00458     DATA_PER_NODE = maxTimeSteps / Dictionary_GetDouble_WithDefault( dictionary, "dumpEvery", 500 );
00459     meshDict = Dictionary_Entry_Value_AsDictionary( Dictionary_Get( dictionary, "mesh" ) );
00460     LOAD_NODES = Dictionary_GetUnsignedInt_WithDefault( meshDict, "nx", 6) * Dictionary_GetUnsignedInt_WithDefault( meshDict, "ny", 6);
00461 
00462     printf ( "Total Number of Nodes - %d\n", LOAD_NODES );
00463     printf ( "Height values per Node - %d\n", DATA_PER_NODE );
00464 
00465     processDumpFiles( argv[2] );
00466 
00467     data = malloc(sizeof(double*)*LOAD_NODES);
00468     for(i=0; i<LOAD_NODES; i++)
00469         data[i] = malloc(sizeof(double)*DATA_PER_NODE);
00470     
00471     memset( pathPlusFileName, 0, sizeof(pathPlusFileName) );
00472     sprintf( pathPlusFileName, "%s/%s", argv[2], "mergedOutput.txt" );
00473     inputFile = fopen (pathPlusFileName, "r+");
00474     if( inputFile == NULL ){
00475         printf( "mergedOutput.txt does not exist in %s/..\n", argv[2] );
00476         exit(0);
00477     }
00478 
00479     for(i=0; i<LOAD_NODES; i++){
00480         memset(buffer, 0, sizeof(buffer));
00481         count = 0;
00482         while(fgets(buffer, 1024, inputFile) != NULL){
00483             if(strlen(buffer) == 1){
00484                 //printf("successfully processed the time evolution of a particular node\n");
00485                 break;
00486             }
00487             ptr = strtok(buffer, "\t");
00488             ptr = strtok(NULL, "\t");
00489             ptr = strtok(NULL, "\t");
00490             data[i][count] = atof(ptr);
00491             //printf ("data[%d] = %lf\n", count, data[i][count]);
00492             memset (buffer, 0, sizeof(buffer));
00493             count+=1;
00494         }
00495     }
00496     
00497     
00498     createGLWindow();
00499     while(!done){
00500         printf ("plot from nodeID - ");
00501         memset(buffer, 0, sizeof(buffer));
00502         fgets(buffer, 1024, stdin);
00503         from = atoi(buffer);
00504         
00505         printf ("plot to nodeID - ");
00506         memset(buffer, 0, sizeof(buffer));
00507         fgets(buffer, 1024, stdin);
00508         to = atoi(buffer);
00509 
00510         if(from < 0 || to < 0){
00511             done = 1;
00512             break;
00513         }
00514         
00515         while(!windowEvents()){
00516             dumpNodes((double**)data, from, to, DATA_PER_NODE);
00517         }
00518     }
00519     
00520     fclose(inputFile);
00521     for(i=0; i<LOAD_NODES; i++)
00522         free(data[i]);
00523     free(data);
00524 
00525     MPI_Finalize();
00526     StGermain_Finalise();
00527     
00528     return 1;
00529 }
00530