/[MITgcm]/MITgcm_contrib/darwinview/src/darwin.bash
ViewVC logotype

Annotation of /MITgcm_contrib/darwinview/src/darwin.bash

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (hide annotations) (download)
Wed Aug 1 18:04:31 2007 UTC (17 years, 11 months ago) by marissa
Branch: MAIN
Changes since 1.3: +576 -112 lines
more changes! hooray!

1 marissa 1.4 #include <GL/glut.h>
2     #include <stdlib.h>
3     #include <stdio.h>
4     #include <string.h>
5     #include <math.h>
6     #define WINDOW "image"
7     #define UP 101
8     #define DOWN 103
9     #define RIGHT 102
10     #define LEFT 100
11     #define MAX 700
12     #define SCALE .06
13    
14     int NX, NY, NZ;
15    
16     void do_byteswap_f32( float arr[], int nel ), global(), local( int, int, int );
17     void readnames( char[] ), readarray( float[], char[], int ), readjet(), readxz( float[], char[] );
18     void readyz( float[], char[] ), readdepths( char[] );
19     void TimerFunction( int ), stroke( char[], int, int );
20    
21     float data[MAX][MAX*MAX], mxval, mnval, jet[64][3];
22     float globalmx=0, globalmn=100;
23     int win[MAX], ilev=1, howmany, sets, count=0, glo=0, usr=0, anim=0, endian=0;
24     int xmax, ymax, yoffset=0, xoffset=0, yz=0, logscale=0, xz=0, nonegs=1;
25     int depths[MAX], scaledepth=0, totaldepth=0, scalecount=0;
26     char initfns[MAX][MAX], fns[MAX][MAX][MAX];
27    
28     void menu( int value ){ // called when menu is opened on right click
29    
30     switch( value ){
31     case 1: usr=glo=0; // unset glo & usr, sets local max/min
32     break;
33     case 2: glo=1; // enables global max/min
34     usr=0; // unsets usr
35     mxval=globalmx; // sets max to globalmx
36     mnval=globalmn; // sets min to globalmn
37     break;
38     case 3: usr=1; // switch to user-set max/min
39     glo=0; // unset glo
40     printf( "Max=" ); scanf( "%f", &mxval ); // prompt user for new max
41     printf( "Min=" ); scanf( "%f", &mnval ); // prompt user for new min
42     break;
43     case 4: logscale=( logscale+1 )%2; // switch log scale on/off
44     break;
45     case 5: nonegs=( nonegs+1 )%2; // switch allowance of negatives on/off
46     break;
47     case 6: endian=( endian+1 )%2; // switch between big/little endian
48     break;
49     }
50     glutPostRedisplay();
51     }
52    
53     void display(){ // called on glutPostRedisplay
54     int i, j, h, ioff, q;
55     float r, g, b, k, y;
56     double num, logmx, logmn;
57     char str[MAX];
58    
59    
60     for( q=0; q<sets; q++ ){ // runs display func for each subwindow
61     glutSetWindow( win[q] ); // sets which subwindow to display to
62     glClear( GL_COLOR_BUFFER_BIT ); // background to black
63    
64     if( xz ) { xmax=NX; ymax=NZ; }
65     else{
66     if( yz ){ xmax=NY; ymax=NZ; }
67     else { xmax=NX; ymax=NY; }
68     }
69    
70     if( glo || usr ){ // if global or user-set max/min
71     if( xz )
72     readxz( data[q], fns[q][count] );
73     else{
74     if( yz )
75     readyz( data[q], fns[q][count] );
76     else
77     readarray( data[q], fns[q][count], ilev ); // read new array w/o calculating local max/min
78     }
79     }
80     else // if local max/min is set
81     local( q, count, ilev ); // read new array and calculate local max/min
82    
83     if( logscale ){
84     if( usr ){
85     logmx=(double)mxval;
86     logmn=(double)mnval;
87     }
88     else{
89     logmx=log10( mxval );
90     logmn=log10( mnval );
91     }
92     }
93    
94     if( scaledepth && xz || scaledepth && yz ) ymax=totaldepth;
95     ioff=0; h=0; // ioff will count both i&j b/c data is 1D
96     for( j=0; j<ymax; j++ ){ // cycles through y values
97     for( i=0; i<xmax; i++ ){ // cycles through x values
98     r=g=b=0; // set color values to black
99     if( data[q][ioff]==0 ); // if data=0, values stay black
100     else{
101     if( logscale ){
102     num=(double)data[q][ioff];
103     num=log10( num );
104     if( num<logmn ) num=0;
105     else{
106     if( num>logmx ) num=63;
107     else
108     num=63*( num-logmn )/( logmx-logmn );
109     }
110     }
111     else{
112     if( data[q][ioff]<mnval ) num=0; // if data is less than min, =min
113     else{
114     if( data[q][ioff]>mxval ) num=63; // if data is more than max, =max
115     else
116     num=63*( data[q][ioff]-mnval )/( mxval-mnval ); // scale num from 0-63 (not defined for 64)
117     }
118     }
119     r=jet[(int)num][0]; // set red val
120     g=jet[(int)num][1]; // set green val
121     b=jet[(int)num][2]; // set blue val
122     }
123    
124     glColor3f( r, g, b ); // put r, g, b into effect
125     if( scaledepth && xz || scaledepth && yz )
126     glRectf( i, j, i+1, j+depths[h] );
127     else
128     glRectf( i, j, i+1, j+1 ); // draws a square for data value
129     ioff++;
130     }
131     if( scaledepth && xz || scaledepth && yz ){
132     j+=depths[h]-1;
133     h++;
134     }
135     }
136    
137     glColor3f( 1, 1, 1 ); // set color to white
138     glRectf( xmax, 0, xmax+1, ymax+1 ); // draws a border
139     glRectf( 0, ymax, xmax, ymax+1 ); // draws a border
140     for( i=0; i<64; i++ ){ // draws color bar
141     glColor3f( jet[i][0], jet[i][1], jet[i][2]); // sets color
142     k=(float)i; // turns i into a float
143     y=(float)ymax/64; // sets height of rectangles
144     glRectf( xmax+10, y*k, xmax+20, (k+1)*y ); // draws rectangle
145     }
146     glColor3f( 1, 1, 1 ); // color to white
147    
148     if( logscale )
149     sprintf( str, "%.2f", logmx );
150     else
151     sprintf( str, "%.1e", mxval ); // labels color bar with max val
152     stroke( str, xmax+2, ymax-1 );
153    
154     if( logscale )
155     sprintf( str, "%.2f", logmn );
156     else
157     sprintf( str, "%.1e", mnval ); // labels color bar with min val
158     stroke( str, xmax+2, 1 );
159    
160     if( xz )
161     sprintf( str, "N-S slice %d", yoffset+1);
162     else{
163     if( yz )
164     sprintf( str, "E-W slice %d", xoffset+1);
165     else
166     sprintf( str, "Level %d", ilev ); // labels current level
167     }
168     stroke( str, 1, ymax+5 );
169    
170     sprintf( str, "Time %d", count+1 ); // labels current time
171     stroke( str, xmax/2, ymax+5 );
172    
173     if( glo ) // labels how max/min have been set
174     sprintf( str, "Global" ); // if glo is set, display Global
175     if( usr )
176     sprintf( str, "User-set" ); // if usr is set, display User-set
177     if( !usr && !glo )
178     sprintf( str, "Local" ); // else display Local
179     stroke( str, xmax+8, ymax+8 );
180    
181     if( anim ){ // tell user if autoplay is on
182     sprintf( str, "Autoplay" );
183     stroke( str, xmax-35, ymax+8 );
184     }
185    
186     if( logscale ){
187     sprintf( str, "Log Scale" ); // tell user if log scale is on
188     stroke( str, xmax-25, ymax+15);
189     }
190    
191     stroke( fns[q][count], 1, ymax+15 ); // labels current file
192    
193     glutSwapBuffers(); // double buffering set to animate smoothly
194     glFlush();
195     }
196     }
197 marissa 1.1
198 marissa 1.4 void stroke( char str[], int x, int y ){ // called to display text onscreen
199     int i;
200 marissa 1.1
201 marissa 1.4 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
202     glEnable( GL_BLEND );
203     glEnable( GL_LINE_SMOOTH );
204     glMatrixMode( GL_MODELVIEW );
205 marissa 1.1
206 marissa 1.4 glPushMatrix();
207    
208     glScalef( SCALE, SCALE, SCALE );
209     glTranslatef( (1/SCALE)*x, (1/SCALE)*y, 0 );
210    
211     for( i=0; i<strlen( str ); i++) // display each character of str
212     glutStrokeCharacter( GLUT_STROKE_ROMAN, str[i] );
213    
214     glPopMatrix();
215     }
216    
217     void key( unsigned char key, int x, int y ){ // called on key press
218     int i, tmp;
219    
220     switch(key){
221     case 'q': exit(0); // quits on 'q'
222     break;
223     case 'r': count=0; // resets back to first time
224     ilev=1; // and first level
225     break;
226     case 'a': anim=(anim+1)%2; // turns anim on/off
227     break;
228     case 'x': xz=(xz+1)%2;
229     yz=0;
230     break;
231     case 'y': yz=(yz+1)%2;
232     xz=0;
233     break;
234     case 'z': if( xz || yz ){
235     scaledepth=( scaledepth+1 )%2;
236     scalecount++;
237     if( scalecount==1 )
238     readdepths( ".darwinview/depths" );
239     }
240     break;
241     }
242     glutPostRedisplay();
243     }
244    
245     void TimerFunction( int value ){ // called when anim is set and arrow key is pressed
246     int i;
247    
248     switch(value){ // increments in the correct direction
249     case DOWN : if( xz && yoffset>0 )
250     yoffset--;
251     else{
252     if( yz && xoffset<NX-1 )
253     xoffset++;
254     else
255     if( ilev<NZ && !xz && !yz )
256     ilev++; // if down arrow pressed, move down a level
257     }
258     break;
259     case UP : if( xz && yoffset<NY-1 )
260     yoffset++;
261     else{
262     if( yz && xoffset>0 )
263     xoffset--;
264     else
265     if( ilev>1 && !xz && !yz )
266     ilev--; // if up arrow is pressed, move up a level
267     }
268     break;
269     case LEFT : if( count>0 )
270     count--; // if left arrow is pressed, move back one time step
271     break;
272     case RIGHT: if( count<howmany-1 )
273     count++; // if right arrow is pressed, moves forward one time step
274     break;
275     }
276    
277     glutPostRedisplay();
278    
279     if ( anim )
280     switch( value ){
281     case DOWN : if( xz && yoffset==0 )
282     yoffset=NY-1;
283     else{
284     if( yz && xoffset==NX-1 )
285     xoffset=0;
286     else
287     if( ilev==NZ && !xz && !yz )
288     ilev=1; // if end reached, restart
289     }
290     glutTimerFunc( 100, TimerFunction, value ); // recalls itself
291     break;
292     case UP : if( xz && yoffset==NY-1 )
293     yoffset=0;
294     else{
295     if( yz && xoffset==0 )
296     xoffset=NX-1;
297     else
298     if( ilev==1 )
299     ilev=NZ; // if end reached, restart
300     }
301     glutTimerFunc( 100, TimerFunction, value ); // recalls itself
302     break;
303     case LEFT : if( count==0 ) count=howmany-1; // if end reached, restart
304     glutTimerFunc( 100, TimerFunction, value ); // recalls itself
305     break;
306     case RIGHT: if( count==howmany-1 ) count=0; // if end reached, restart
307     glutTimerFunc( 100, TimerFunction, value ); // recalls itself
308     break;
309     }
310     }
311    
312     void specialkey( int key, int x, int y ){
313     int i;
314    
315     if( anim ) // if animation is set, call the timer function
316     glutTimerFunc( 100, TimerFunction, key); // to scroll automatically
317    
318     switch(key){
319     case DOWN : if( xz && yoffset>0 )
320     yoffset--;
321     else{
322     if( yz && xoffset<NY-1 )
323     xoffset++;
324     else
325     if( ilev<NZ && !xz && !yz ) // if you haven't reached the bottom
326     ilev++; // keep going down
327     }
328     break;
329     case UP : if( xz && yoffset<NY-1 )
330     yoffset++;
331     else{
332     if( yz && xoffset>0 )
333     xoffset--;
334     else
335     if( ilev>1 ) // if you haven't reached the top
336     ilev--; // keep going up
337     }
338     break;
339     case RIGHT : if( count<howmany-1 ) // if you haven't reached the last file
340     count++; // keep going right
341     break;
342     case LEFT : if( count>0 ) // if you haven't reached the first file
343     count--; // keep going left
344     break;
345     }
346     glutPostRedisplay();
347     }
348    
349     void global(){ // calculates the max/min for the total data set
350     FILE* fp;
351     int h, i, j;
352     for( h=0; h<sets; h++) // cycles through each window
353     for( i=0; i<howmany; i++ ) // cycles through each time
354     for( j=0; j<NZ; j++ ){ // cycles through each level for each file
355     local( h, i, j ); // calculates local max/min for specific data set
356     if( mxval > globalmx ) globalmx = mxval; // sets highest value to globalmx
357     if( mnval < globalmn ) globalmn = mnval; // sets lowest value to globalmn
358     }
359     }
360    
361     void local( int i, int time, int lev ){ // calculates local max/min
362     int j;
363    
364     mxval=0;
365     mnval=100;
366     if( xz )
367     readxz( data[i], fns[i][time]);
368     else{
369     if( yz )
370     readyz( data[i], fns[i][time]);
371     else
372     readarray( data[i], fns[i][time], lev ); // read new array of data
373     }
374     for( j=0; j<xmax*ymax; j++ ){
375     if( data[i][j] > mxval )
376     mxval=data[i][j]; // set largest val to mxval
377     if( data[i][j] < mnval && data[i][j]!=0 )
378     mnval=data[i][j]; // set smallest positive val to mnval
379     }
380     }
381    
382     void readnames( char filename[] ){ // reads in list of filenames
383     FILE* fp;
384     int i=0, j=0;
385    
386     fp=fopen( filename, "r" ); // opens list of filenames
387     while( !feof(fp) ){ // reads until the end of the file
388     fscanf( fp, "%s", initfns[i] ); // places filename into an array of strings
389     i++; // counts how many filenames there are
390     }
391     fclose( fp ); // close file
392     sets=i-1; // saves number of initial filenames
393    
394     for(i=0; i<sets; i++){ // goes through each read-in filename
395     fp=fopen( initfns[i], "r" ); // opens each filename
396     j=0;
397     while( !feof(fp) ){ // reads in filenames from each filename
398     fscanf( fp, "%s", fns[i][j]);
399     j++;
400     }
401     fclose(fp); // close file
402     }
403     howmany=j-1; // saves number of data filenames
404     }
405    
406     void readdepths( char filename[] ){
407     int i;
408     FILE* fp;
409    
410     fp=fopen( filename, "r" );
411    
412     for( i=NZ-1; i>=0; i-- ){
413     fscanf( fp, "%d ", &depths[i] );
414     totaldepth+=depths[i];
415     }
416    
417     fclose( fp );
418     }
419    
420     void readjet(){ //reads in color scale values
421     FILE* fp;
422     int i, j;
423 marissa 1.3
424 marissa 1.4 fp=fopen( ".darwinview/jet.h", "r" ); // opens file containing values
425     for( i=0; i<64; i++ ) // reads in 64 sets of r, g, b values
426     for( j=0; j<3; j++ )
427     fscanf( fp, "%f", &jet[i][j] );
428     fclose( fp ); // closes file
429     }
430    
431     void readxz( float arr[], char filename[] ){
432     int i, j;
433     float tmp[MAX][MAX], tmp2[MAX*MAX];
434     FILE* fp;
435    
436     fp=fopen( filename, "rb" );
437     for( i=0; i<NZ; i++){
438     fseek( fp, (NX*yoffset*4)+(i*NX*NY*4), SEEK_SET );
439     fread( &arr[NX*i], sizeof( arr[0] ), NX, fp ); // reads in data to fill one level
440     }
441     fclose( fp );
442    
443     for( i=0; i<NZ; i++ )
444     for( j=0; j<NX; j++)
445     tmp[i][j]=arr[i*NX+j];
446    
447     for( i=0; i<NZ; i++ )
448     for( j=0; j<NX; j++)
449     tmp2[i*NX+j]=tmp[NZ-i-1][j];
450    
451     for( i=0; i<NX*NZ; i++)
452     arr[i]=tmp2[i];
453     }
454    
455     void readyz( float arr[], char filename[] ){
456     int i, j;
457     float tmp[MAX][MAX], tmp2[MAX*MAX];
458     FILE* fp;
459    
460     fp=fopen( filename, "rb" );
461     for( i=0; i<NY*NZ; i++ ){
462     fseek( fp, (xoffset*4)+(i*NX*4), SEEK_SET );
463     fread( &arr[i], sizeof( arr[0] ), 1, fp );
464     }
465     fclose(fp);
466    
467     for( i=0; i<NZ; i++ )
468     for( j=0; j<NY; j++)
469     tmp[i][j]=arr[i*NY+j];
470    
471     for( i=0; i<NZ; i++ )
472     for( j=0; j<NY; j++)
473     tmp2[i*NY+j]=tmp[NZ-i-1][j];
474    
475     for( i=0; i<NY*NZ; i++)
476     arr[i]=tmp2[i];
477     }
478    
479     void readarray( float arr[], char filename[], int il ){ // reads new data
480     FILE* fp;
481     int i;
482    
483     fp=fopen( filename, "rb" ); // opens the file containing data
484     fseek( fp, (il-1)*NX*NY*4, SEEK_SET ); // seeks to the correct place using ilev
485     fread( arr, sizeof( arr[0] ), NX*NY, fp ); // reads in data to fill one level
486     fclose( fp ); // close file
487    
488     if( nonegs )
489     for( i=0; i<NX*NY; i++ )
490     if( arr[i] < 0 )
491     arr[i] = pow(10, -20); // sets negative values to 10^-20
492    
493     if( endian )
494     do_byteswap_f32( arr, NX*NY ); // switches endian
495     }
496    
497     void do_byteswap_f32( float arr[], int nel ){ // switches endian
498    
499     int i;
500     char src[4], trg[4];
501    
502     for( i=0; i<nel; i++ ){
503     memcpy( src, &(arr[i]), 4 );
504     trg[0]=src[3];
505     trg[1]=src[2];
506     trg[2]=src[1];
507     trg[3]=src[0];
508     memcpy( &(arr[i]), trg, 4 );
509     }
510     }
511    
512     void black( ){
513     glClear( GL_COLOR_BUFFER_BIT );
514     glutSwapBuffers();
515     glFlush();
516     }
517    
518    
519     int main( int argc, char *argv[] ){
520     int i, setsx, setsy, tmpx, tmpy, winx, winy, parent;
521     char str[MAX], filename[MAX];
522     FILE* fp;
523    
524     if( strcmp(argv[1], "binary") == 0 )
525     fp=fopen( ".darwinview/binconfig", "r" );
526     else
527     if( strcmp(argv[1],"netcdf") == 0 )
528     fp=fopen( ".darwinview/ncconfig", "r" );
529    
530     fscanf( fp, "%dx%d ", &winx, &winy );
531     winy-=60; winx-=20; // adjusts resolution so edges won't get cut off
532     fscanf( fp, "%d %d %d ", &NX, &NY, &NZ );
533     fscanf( fp, "%dx%d ", &setsx, &setsy ); // prompts user for dimensions of subwindows
534     fscanf( fp, "%s", filename );
535    
536     fclose( fp );
537    
538     xmax=NX; ymax=NY;
539    
540     readjet(); // stores color values
541     readnames( filename ); // gets list of filenames to read from
542     global(); // calculates max and min for all data
543    
544     glutInit( &argc, argv );
545     glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE ); // sets rgb mode and double buffering
546     glutInitWindowSize( winx, winy ); // parent window will cover screen
547     glutInitWindowPosition( 10, 10 ); // location of parent window
548     parent=glutCreateWindow( WINDOW ); // creates parent window
549    
550     glClearColor( 0, 0, 0, 0 ); // sets clear color to black
551     gluOrtho2D( 0, winx , winy, 0 ); // sets(0,0) as top left corner
552     glutDisplayFunc( display );
553     glutKeyboardFunc( key ); // called on key press
554     glutSpecialFunc( specialkey ); // called on special key press (arrow keys)
555 marissa 1.3
556    
557 marissa 1.4 for( i=0; i<setsx*setsy; i++ ){
558     tmpx = (i%setsx)*(winx/setsx); // x coordinate of top left corner of subwindow
559     tmpy = (i/setsx)*(winy/setsy); // y coordinate of top left corner of subwindow
560    
561     win[i]=glutCreateSubWindow( parent, tmpx, tmpy, winx/setsx, winy/setsy ); // creates subwindow
562     gluOrtho2D( 0, NX+35, 0, NY+25 ); // sets how data is mapped to subwindow
563     glutKeyboardFunc( key ); // called on key press
564     glutSpecialFunc( specialkey ); // called on special key press (arrow keys)
565     if( i >= sets ) //
566     glutDisplayFunc( black );
567     else
568     glutDisplayFunc( display ); // sets display func for subwindow
569    
570 marissa 1.1
571 marissa 1.4 glutCreateMenu( menu ); // adds a menu
572     glutAddMenuEntry( "Local Color Scale", 1 ); // adds a menu entry
573     glutAddMenuEntry( "Global Color Scale", 2 ); // adds a menu entry
574     glutAddMenuEntry( "User-Set Color Scale", 3 ); // adds a menu entry
575     glutAddMenuEntry( "Log Scale (on/off)", 4 ); // adds a menu entry
576     glutAddMenuEntry( "Allow Negatives (on/off)", 5 ); // adds a menu entry
577     glutAddMenuEntry( "Switch Endian (big/little) ", 6); // adds a menu entry
578     glutAttachMenu( GLUT_RIGHT_BUTTON ); // menu called on right click
579     }
580    
581     glutMainLoop(); // begin processing events
582     return 0;
583     }
584 marissa 1.1

  ViewVC Help
Powered by ViewVC 1.1.22