--- MITgcm_contrib/darwinview/src/darwin.c 2007/08/03 14:37:15 1.8 +++ MITgcm_contrib/darwinview/src/darwin.c 2007/08/03 19:14:34 1.9 @@ -1,3 +1,24 @@ +/* + * darwinView + * Written by Marissa Weichman June-July 2007 + * Contact: mweichman@gmail.com + * + * See the darwinView Guide for instructions on using this program. + * + * The program begins running at main(), at the bottom of this file. The function + * readjet() reads in the rgb for the color scale, while readnames() fills the array + * fns[][][] with the appropriate filenames to read data from. The functions that + * do the reading in are readxy(), readxz() and readyz() depending upon which plane + * is being viewed (xy, xz and yz, respectively). The functions global() and local() + * calculate the global and local maximum and minimum of the data sets. The key() + * and specialkey() functions handle keyboard input from the user. Everytime a key + * push changes any information, the display() function is called, which redisplays + * the plots with the new values. Finally, TimerFunction() is called when the + * autoplay feature is set, and an arrow key is pushed. TimerFunction() calls itself + * recursively, and redisplays every 10th of a second as it scrolls through time, + * depth levels, etc. + */ + #include #include #include @@ -14,18 +35,17 @@ int NX, NY, NZ; void do_byteswap_f32( float arr[], int nel ), global(), local( int, int, int ); -void readnames( char[] ), readarray( float[], char[], int ), readjet(), readxz( float[], char[] ); -void readyz( float[], char[] ), readdepths( char[] ); void TimerFunction( int ), stroke( char[], int, int ); +void readxy( float[], char[], int), readxz( float[], char[] ), readyz( float[], char[] ); +void readnames( char[] ), readjet(), readdepths( char[] ); -float data[MAX][MAX*MAX], mxval, mnval, jet[64][3]; -float globalmx=0, globalmn=100; -int win[MAX], ilev=1, howmany, sets, count=0, glo=0, usr=0, anim=0, endian=0; -int xmax, ymax, yoffset=0, xoffset=0, yz=0, logscale=0, xz=0, nonegs=1; -int depths[MAX], scaledepth=0, totaldepth=0, scalecount=0; +float data[MAX][MAX*MAX], mxval, mnval, jet[64][3], globalmx=0, globalmn=100; +int glo=0, usr=0, anim=0, endian=0, logscale=0, xz=0, yz=0, nonegs=1, scaledepth=0; +int win[MAX], depths[MAX], ilev=1, howmany, sets, count=0, xmax, ymax, yoffset=0, xoffset=0; +int totaldepth=0, scalecount=0; char initfns[MAX][MAX], fns[MAX][MAX][MAX]; -void menu( int value ){ // called when menu is opened on right click +void menu( int value ){ // called when menu is opened on right click switch( value ){ case 1: usr=glo=0; // unset glo & usr, sets local max/min @@ -37,184 +57,191 @@ break; case 3: usr=1; // switch to user-set max/min glo=0; // unset glo - printf( "Max=" ); scanf( "%f", &mxval ); // prompt user for new max - printf( "Min=" ); scanf( "%f", &mnval ); // prompt user for new min + printf( "Max = " ); scanf( "%f", &mxval ); // prompt user for new max + printf( "Min = " ); scanf( "%f", &mnval ); // prompt user for new min break; - case 4: logscale=( logscale+1 )%2; // switch log scale on/off + case 4: logscale=( logscale+1 )%2; // toggle log scale break; - case 5: nonegs=( nonegs+1 )%2; // switch allowance of negatives on/off + case 5: nonegs=( nonegs+1 )%2; // toggle allowance of negatives break; - case 6: endian=( endian+1 )%2; // switch between big/little endian + case 6: endian=( endian+1 )%2; // toggle big/little endian break; } - glutPostRedisplay(); + glutPostRedisplay(); // redisplay with new values } -void display(){ // called on glutPostRedisplay +void display(){ // called on glutPostRedisplay int i, h, ioff, q; float r, g, b, k, y, j, tmp; double num, logmx, logmn; char str[MAX]; - for( q=0; qlogmx ) num=63; + if( num>logmx ) num=63; // set data more than max to max else - num=63*( num-logmn )/( logmx-logmn ); + num=63*( num-logmn )/( logmx-logmn ); // scale all others } } - else{ - if( data[q][ioff]mxval ) num=63; // if data is more than max, =max + if( data[q][ioff]>mxval ) num=63; // set data more than max to max else - num=63*( data[q][ioff]-mnval )/( mxval-mnval ); // scale num from 0-63 (not defined for 64) + num=63*( data[q][ioff]-mnval )/( mxval-mnval ); // scale all others } } - r=jet[(int)num][0]; // set red val - g=jet[(int)num][1]; // set green val - b=jet[(int)num][2]; // set blue val + r=jet[(int)num][0]; // set red value + g=jet[(int)num][1]; // set green value + b=jet[(int)num][2]; // set blue value } - glColor3f( r, g, b ); // put r, g, b into effect - if( scaledepth && xz || scaledepth && yz ) - glRectf( i, j, i+1, j+(depths[h]*tmp) ); - else - glRectf( i, j, i+1, j+1 ); // draws a square for data value + glColor3f( r, g, b ); // put r, g, b into effect + if( scaledepth && xz || scaledepth && yz ) // if scaledepth is set + glRectf( i, j, i+1, j+(depths[h]*tmp) ); // draw box appropriate to width of level + else // otherwise + glRectf( i, j, i+1, j+1 ); // draw a square ioff++; - } - if( scaledepth && xz || scaledepth && yz ){ - j+=(depths[h]*tmp); - h++; + } // leave x loop + if( scaledepth && xz || scaledepth && yz ){ // if scaledepth is set + j+=(depths[h]*tmp); // scale j by width of current depth level + h++; // increment h (counts through depth levels) } - else j++; - } + else j++; // otherwise, increment j by 1 + } // leave y loop - glColor3f( 1, 1, 1 ); // set color to white - glRectf( xmax, 0, xmax+1, ymax+1 ); // draws a border - glRectf( 0, ymax, xmax, ymax+1 ); // draws a border - for( i=0; i<64; i++ ){ // draws color bar - glColor3f( jet[i][0], jet[i][1], jet[i][2]); // sets color - k=(float)i; // turns i into a float - y=(float)ymax/64; // sets height of rectangles - glRectf( xmax+10, y*k, xmax+20, (k+1)*y ); // draws rectangle + glColor3f( 1, 1, 1 ); // set color to white + glRectf( xmax, 0, xmax+1, ymax+1 ); // draw a border right of plot + glRectf( 0, ymax, xmax, ymax+1 ); // draw a border on top of plot + + for( i=0; i<64; i++ ){ // draw color bar + glColor3f( jet[i][0], jet[i][1], jet[i][2]); // sets color + k=(float)i; // turns i into a float + y=(float)ymax/64; // scales rectangles to fit in ymax + glRectf( xmax+10, y*k, xmax+20, (k+1)*y ); // draws rectangle } - glColor3f( 1, 1, 1 ); // color to white - if( logscale ) + glColor3f( 1, 1, 1 ); // color to white + + if( logscale ) sprintf( str, "%.2f", logmx ); else - sprintf( str, "%.1e", mxval ); // labels color bar with max val + sprintf( str, "%.1e", mxval ); // labels color bar with max val stroke( str, xmax+2, ymax-1 ); if( logscale ) sprintf( str, "%.2f", logmn ); else - sprintf( str, "%.1e", mnval ); // labels color bar with min val + sprintf( str, "%.1e", mnval ); // labels color bar with min val stroke( str, xmax+2, 1 ); - if( xz ) - sprintf( str, "N-S slice %d", yoffset+1); + if( xz ) // in xz view + sprintf( str, "N-S slice %d", yoffset+1); // labels NS slice else{ - if( yz ) - sprintf( str, "E-W slice %d", xoffset+1); - else - sprintf( str, "Level %d", ilev ); // labels current level + if( yz ) // in yz view + sprintf( str, "E-W slice %d", xoffset+1); // labels EW slice + else // in xy view + sprintf( str, "Level %d", ilev ); // labels current level } stroke( str, 1, ymax+5 ); - sprintf( str, "Time %d", count+1 ); // labels current time + sprintf( str, "Time %d", count+1 ); // labels current time step stroke( str, xmax/2, ymax+5 ); - if( glo ) // labels how max/min have been set - sprintf( str, "Global" ); // if glo is set, display Global + if( glo ) // labels how max/min have been set + sprintf( str, "Global" ); // if glo is set, display Global if( usr ) - sprintf( str, "User-set" ); // if usr is set, display User-set + sprintf( str, "User-set" ); // if usr is set, display User-set if( !usr && !glo ) - sprintf( str, "Local" ); // else display Local + sprintf( str, "Local" ); // else display Local stroke( str, xmax+8, ymax+8 ); - if( anim ){ // tell user if autoplay is on + if( anim ){ // tell user if autoplay is on sprintf( str, "Autoplay" ); stroke( str, xmax-35, ymax+8 ); } if( logscale ){ - sprintf( str, "Log Scale" ); // tell user if log scale is on + sprintf( str, "Log Scale" ); // tell user if log scale is on stroke( str, xmax-25, ymax+15); } - stroke( fns[q][count], 1, ymax+15 ); // labels current file + stroke( fns[q][count], 1, ymax+15 ); // labels current file - glutSwapBuffers(); // double buffering set to animate smoothly + glutSwapBuffers(); // double buffering set to animate smoothly glFlush(); } } -void stroke( char str[], int x, int y ){ // called to display text onscreen +void stroke( char str[], int x, int y ){ // called to display text onscreen int i; - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); - glEnable( GL_BLEND ); - glEnable( GL_LINE_SMOOTH ); - glMatrixMode( GL_MODELVIEW ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // sets blending mode + glEnable( GL_BLEND ); // enables blending + glEnable( GL_LINE_SMOOTH ); // enables smooth lines + glMatrixMode( GL_MODELVIEW ); // sets matrix mode - glPushMatrix(); + glPushMatrix(); // push matrix - glScalef( SCALE, SCALE, SCALE ); - glTranslatef( (1/SCALE)*x, (1/SCALE)*y, 0 ); + glScalef( SCALE, SCALE, SCALE ); // scales stroked text + glTranslatef( (1/SCALE)*x, (1/SCALE)*y, 0 ); // determines location of text - for( i=0; i0 ) - yoffset--; + case DOWN : if( xz && yoffset>0 ) // if down arrow key is pressed + yoffset--; // in xz view, move south else{ if( yz && xoffset0 ) - xoffset--; + xoffset--; // in yz view, move west else if( ilev>1 && !xz && !yz ) - ilev--; // if up arrow is pressed, move up a level + ilev--; // in xy view, move up a depth level } break; case LEFT : if( count>0 ) count--; // if left arrow is pressed, move back one time step break; case RIGHT: if( count0 ) - yoffset--; + case DOWN : if( xz && yoffset>0 ) // if you haven't reached the bottom in xz view + yoffset--; // go down one NS slice else{ - if( yz && xoffset0 ) - xoffset--; + if( yz && xoffset>0 ) // if you haven't reached the edge in yz view + xoffset--; // go west one EW slice else - if( ilev>1 ) // if you haven't reached the top - ilev--; // keep going up + if( ilev>1 && !xz && !yz ) // if you haven't reached the top in xy view + ilev--; // go up one level } break; - case RIGHT : if( count0 ) // if you haven't reached the first file - count--; // keep going left + case LEFT : if( count>0 ) // if you haven't reached the first time step + count--; // go back one time step break; } - glutPostRedisplay(); + glutPostRedisplay(); // redisplay with new values } void global(){ // calculates the max/min for the total data set @@ -359,7 +386,7 @@ int h, i, j; for( h=0; h globalmx ) globalmx = mxval; // sets highest value to globalmx if( mnval < globalmn ) globalmn = mnval; // sets lowest value to globalmn @@ -369,21 +396,21 @@ void local( int i, int time, int lev ){ // calculates local max/min int j; - mxval=0; + mxval=0; mnval=100; if( xz ) - readxz( data[i], fns[i][time]); + readxz( data[i], fns[i][time]); // if xz view, reads new array of xz vals else{ if( yz ) - readyz( data[i], fns[i][time]); + readyz( data[i], fns[i][time]); // if yz view, reads new array of yz vals else - readarray( data[i], fns[i][time], lev ); // read new array of data + readxy( data[i], fns[i][time], lev ); // if xy view, reads new array of xy vals } - for( j=0; j mxval ) mxval=data[i][j]; // set largest val to mxval if( data[i][j] < mnval && data[i][j]!=0 ) - mnval=data[i][j]; // set smallest positive val to mnval + mnval=data[i][j]; // set smallest nonzero val to mnval } } @@ -397,9 +424,9 @@ i++; // counts how many filenames there are } fclose( fp ); // close file - sets=i-1; // saves number of initial filenames + sets=i-1; // saves number of initial filenames - for(i=0; i=0; i-- ){ + for( i=NZ-1; i>=0; i-- ){ // read in data backwards, starting at the lowest depth fscanf( fp, "%d ", &depths[i] ); - totaldepth+=depths[i]; + totaldepth+=depths[i]; // calculate total depth } - fclose( fp ); + fclose( fp ); // close file } -void readjet(){ //reads in color scale values +void readjet(){ // read in color scale values FILE* fp; int i, j; - fp=fopen( "jet.dat", "r" ); // opens file containing values - for( i=0; i<64; i++ ) // reads in 64 sets of r, g, b values + fp=fopen( "jet.dat", "r" ); // open file containing values + for( i=0; i<64; i++ ) // read in 64 sets of rgb values for( j=0; j<3; j++ ) fscanf( fp, "%f", &jet[i][j] ); - fclose( fp ); // closes file + fclose( fp ); // close file } -void readxz( float arr[], char filename[] ){ +void readxz( float arr[], char filename[] ){ // reads in xz values int i, j; - float tmp[MAX][MAX], tmp2[MAX*MAX]; + float tmp[MAX][MAX]; FILE* fp; - fp=fopen( filename, "rb" ); - for( i=0; i= sets ) // - glutDisplayFunc( black ); - else - glutDisplayFunc( display ); // sets display func for subwindow + if( i >= sets ) // if there are more subwindows than data sets + glutDisplayFunc( black ); // color those windows black + else // otherwise + glutDisplayFunc( display ); // sets display func for subwindow glutCreateMenu( menu ); // adds a menu