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

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

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


Revision 1.9 - (hide annotations) (download)
Fri Aug 3 19:14:34 2007 UTC (17 years, 11 months ago) by marissa
Branch: MAIN
Changes since 1.8: +276 -238 lines
File MIME type: text/plain
final bash and c versions

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

  ViewVC Help
Powered by ViewVC 1.1.22