iconPlot 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,1687 @@
1
+ ;---------------------------------------------------------------
2
+ ; ICON PLOT LIB
3
+ ; This library aimes to provide an abstract way to access and plot ICON data
4
+ ; fields from NetCDF files. It should obay some general requirements:
5
+ ; * Don-Repeat-Yourself-principle: Every method has one responsebility, which no
6
+ ; other method has. Or in other words: Don't just CopyAndPaste.
7
+ ; * Use as much information from the input files as possible. If something is
8
+ ; missing, create a better file or let the user input this peace of
9
+ ; information. Examples are coordinates of data variabels and bounds of them.
10
+ ; There are attributes for this.
11
+ ; * naming conventions:
12
+ ; # check* methods are procedure which can exit the whole program
13
+ ; # get* methods are functions with return, what they descibe with their
14
+ ; name. This is similar to NCL itself, e.g. getfilevardims()
15
+ ; # set* methods are procedures
16
+ ;---------------------------------------------------------------
17
+ ; Authors : Ralf Mueller (ralf.mueller@zmaw.de)
18
+ ; Stephan Lorenz (stephan.lorenz@zmaw.de)
19
+ ;-------------------------------------------------------------------------------
20
+ ; some global defaults
21
+ DEFAULTLON = "clon"
22
+ DEFAULTLAT = "clat"
23
+ RAD2DEG = 45./atan(1.)
24
+ ABORTMSG = "Abort Script."
25
+ NUMLEVS = 10
26
+ CDO = "cdo"
27
+ ;-------------------------------------------------------------------------------
28
+ procedure setCDO(path)
29
+ begin
30
+ CDO=path
31
+ end
32
+ ;-------------------------------------------------------------------------------
33
+ ; signum function
34
+ undef("sign")
35
+ function sign(val)
36
+ begin
37
+ if (val.eq.0) then
38
+ return(1)
39
+ else
40
+ return(val/abs(val))
41
+ end if
42
+ end
43
+ ;-------------------------------------------------------------------------------
44
+ ; Is the 'time' variable a dimesions in the input dimensions array?
45
+ undef("has_time")
46
+ function has_time(dims)
47
+ begin
48
+ if (any(dims.eq."time")) then
49
+ return(True)
50
+ else
51
+ return(False)
52
+ end if
53
+ end
54
+ ;-------------------------------------------------------------------------------
55
+ ; Has the input variable the dimension 'time'?
56
+ undef("var_has_time")
57
+ function var_has_time(varname,filehandle)
58
+ begin
59
+ dims = getfilevardims(filehandle,varname)
60
+ if ( any(dims.eq."time") ) then
61
+ return(True)
62
+ else
63
+ return(False)
64
+ end if
65
+ end
66
+ ;-------------------------------------------------------------------------------
67
+ ; has a file a certain variable
68
+ undef("has_var")
69
+ function has_var(filehandle,varname)
70
+ begin
71
+ vNames = getfilevarnames(filehandle)
72
+ n = dimsizes (vNames)
73
+ do i=0,n-1 ; loop thru each variable
74
+ if (vNames(i).eq.varname) return True end if
75
+ end do
76
+ return False
77
+ end
78
+ ;---------------------------------------------------------------
79
+ ; get vertical dimension
80
+ undef("getVertDim")
81
+ function getVertDim(filehandle,var)
82
+ begin
83
+ dimNames = getvardims(var)
84
+ matches = (/"lev","depth","height","z"/)
85
+ do i=0,dimsizes(matches)-1
86
+ retval = str_match(dimNames,matches(i))
87
+ if (.not.ismissing(retval)) return retval end if
88
+ end do
89
+ return(str_match(dimNames,matches(0)))
90
+ end
91
+ ;---------------------------------------------------------------
92
+ ; procedure warper for array_append_record
93
+ undef("array_append_record_proc")
94
+ procedure array_append_record_proc(array,addition)
95
+ begin
96
+ arrayCopy = array_append_record(array,addition,0)
97
+
98
+ array = arrayCopy
99
+ end
100
+ ;-------------------------------------------------------------------------------
101
+ ; Read a horizontal field of the variable 'varname' from the given filehandle.
102
+ ; If it is time dependend or has a vertival axis, use the given values for
103
+ ; timstep and levelindex for selecting the field.
104
+ ;
105
+ ; Currently this limited to 3 dimensions, so that 4D tracer variables are ignored
106
+ undef("selIconField")
107
+ function selIconField(varname,filehandle,timestep,levelindex)
108
+ begin
109
+ dims = getfilevardims(filehandle,varname)
110
+ noOfDims = dimsizes(dims)
111
+ noOfDims = noOfDims(0)
112
+ usableVar = False
113
+ if ( has_time(dims) ) then
114
+ if (noOfDims .eq. 3) then ; dims: (time,lev,cell)
115
+ var = filehandle->$varname$(timestep,levelindex,:)
116
+ usableVar = True
117
+ end if
118
+ if (noOfDims .eq. 2) then ; dims: (time,cell)
119
+ var = filehandle->$varname$(timestep,:)
120
+ usableVar = True
121
+ end if
122
+ if (noOfDims .eq. 1) then ; dims: (time)
123
+ var = filehandle->$varname$(:)
124
+ usableVar = True
125
+ end if
126
+ else
127
+ ; TODO: support for 4D tracer fields
128
+ ; if (noOfDims .eq. 3) then ; dims: (lev,cell,tracerID)
129
+ ; var = filehandle->$varname$(levIndex,:,tracer)
130
+ ; usableVar = True
131
+ ; end if
132
+ if (noOfDims .eq. 2) then ; dims: (lev,cell)
133
+ var = filehandle->$varname$(levelindex,:)
134
+ usableVar = True
135
+ end if
136
+ if (noOfDims .eq. 1) then ; dims: (cell)
137
+ var = filehandle->$varname$(:)
138
+ usableVar = True
139
+ end if
140
+ end if
141
+ if (.not. usableVar) then
142
+ print("Warning! Could not read " + varname + " from input file")
143
+ exit
144
+ end if
145
+ return var
146
+ end
147
+ ;-------------------------------------------------------------------------------
148
+ ; get full 3d ICON variable
149
+ undef("selIconVar")
150
+ function selIconVar(varname,filehandle,timestep)
151
+ begin
152
+ dims = getfilevardims(filehandle,varname)
153
+ noOfDims = dimsizes(dims)
154
+ noOfDims = noOfDims(0)
155
+ usableVar = False
156
+ if ( has_time(dims) ) then
157
+ if (noOfDims .eq. 3) then ; dims: (time,lev,cells)
158
+ var = filehandle->$varname$(timestep,:,:)
159
+ usableVar = True
160
+ end if
161
+ if (noOfDims .eq. 2) then ; dims: (time,cells)
162
+ var = filehandle->$varname$(timestep,:)
163
+ usableVar = True
164
+ end if
165
+ if (noOfDims .eq. 1) then ; dims: (cells)
166
+ var = filehandle->$varname$(:)
167
+ usableVar = True
168
+ end if
169
+ else
170
+ if (noOfDims .eq. 2) then ; dims: (lev,cells)
171
+ var = filehandle->$varname$(:,:)
172
+ usableVar = True
173
+ end if
174
+ if (noOfDims .eq. 1) then ; dims: (cells)
175
+ var = filehandle->$varname$(:)
176
+ usableVar = True
177
+ end if
178
+ end if
179
+ if (.not. usableVar) then
180
+ print("Warning! Could not read " + varname + " from input file")
181
+ exit
182
+ end if
183
+ return var
184
+ end
185
+ ;-------------------------------------------------------------------------------
186
+ ; see selIconField(), but for fields on a regular lonlat grid
187
+ undef("selRegularField")
188
+ function selRegularField(varname,filehandle,timestep,levelindex)
189
+ begin
190
+ dims = getfilevardims(filehandle,varname)
191
+ noOfDims = dimsizes(dims)
192
+ noOfDims = noOfDims(0)
193
+ usableVar = False
194
+ if ( has_time(dims) ) then
195
+ if (noOfDims .eq. 4) then ; dims: (time,lev,x,y)
196
+ var = filehandle->$varname$(timestep,levelindex,:,:)
197
+ usableVar = True
198
+ end if
199
+ if (noOfDims .eq. 3) then ; dims: (time,x,y)
200
+ var = filehandle->$varname$(timestep,:,:)
201
+ usableVar = True
202
+ end if
203
+ if (noOfDims .eq. 2) then ; dims: (x,y)
204
+ var = filehandle->$varname$(:,:)
205
+ usableVar = True
206
+ end if
207
+ if (noOfDims .eq. 1) then ; dims: (time)
208
+ var = filehandle->$varname$(:)
209
+ usableVar = True
210
+ end if
211
+ else
212
+ if (noOfDims .eq. 3) then ; dims: (lev,x,y)
213
+ var = filehandle->$varname$(levelindex,:,:)
214
+ usableVar = True
215
+ end if
216
+ if (noOfDims .eq. 2) then ; dims: (x,y)
217
+ var = filehandle->$varname$(:,:)
218
+ usableVar = True
219
+ end if
220
+ if (noOfDims .eq. 1) then ; dims: (x)
221
+ var = filehandle->$varname$(:)
222
+ usableVar = True
223
+ end if
224
+ end if
225
+ if (.not. usableVar) then
226
+ print("Warning! Could not read " + varname + " from input file")
227
+ exit
228
+ end if
229
+ return var
230
+ end
231
+ ;-------------------------------------------------------------------------------
232
+ ; see selRegularField(), but for 3d regular variable
233
+ undef("selRegularVar")
234
+ function selRegularVar(varname,filehandle,timestep)
235
+ begin
236
+ dims = getfilevardims(filehandle,varname)
237
+ noOfDims = dimsizes(dims)
238
+ noOfDims = noOfDims(0)
239
+ usableVar = False
240
+ if ( has_time(dims) ) then
241
+ if (noOfDims .eq. 4) then ; dims: (time,lev,x,y)
242
+ var = filehandle->$varname$(timestep,:,:,:)
243
+ usableVar = True
244
+ end if
245
+ if (noOfDims .eq. 3) then ; dims: (time,x,y)
246
+ var = filehandle->$varname$(timestep,:,:)
247
+ usableVar = True
248
+ end if
249
+ if (noOfDims .eq. 2) then ; dims: (x,y)
250
+ var = filehandle->$varname$(:,:)
251
+ usableVar = True
252
+ end if
253
+ if (noOfDims .eq. 1) then ; dims: (time)
254
+ var = filehandle->$varname$(:)
255
+ usableVar = False
256
+ end if
257
+ else
258
+ if (noOfDims .eq. 3) then ; dims: (lev,x,y)
259
+ var = filehandle->$varname$(:,:,:)
260
+ usableVar = True
261
+ end if
262
+ if (noOfDims .eq. 2) then ; dims: (x,y)
263
+ var = filehandle->$varname$(:,:)
264
+ usableVar = True
265
+ end if
266
+ if (noOfDims .eq. 1) then ; dims: (x)
267
+ var = filehandle->$varname$(:)
268
+ usableVar = True
269
+ end if
270
+ end if
271
+ if (.not. usableVar) then
272
+ print("Warning! Could not read " + varname + " from input file")
273
+ exit
274
+ end if
275
+ return var
276
+ end
277
+ ;-------------------------------------------------------------------------------
278
+ ; abstract Field selection
279
+ undef("selField")
280
+ function selField(varname,filehandle,timestep,levelindex,horizontalgridtype)
281
+ begin
282
+ if ( horizontalgridtype .eq. "unstructured") then
283
+ var = selIconField(varname,filehandle,timestep,levelindex)
284
+ else
285
+ var = selRegularField(varname,filehandle,timestep,levelindex)
286
+ end if
287
+ return var
288
+ end
289
+ ;-------------------------------------------------------------------------------
290
+ ; scale the given variable with the given factor, if it is NOT 1
291
+ undef("scaleVar")
292
+ procedure scaleVar(var,scalefactor)
293
+ local scalefactor
294
+ begin
295
+ if (scalefactor .ne. 1) then
296
+ var = var*scalefactor
297
+ end if
298
+ end
299
+ ;-------------------------------------------------------------------------------
300
+ ; Return the grid type of a given ICON variable (cell, vertex, or edge).
301
+ ; This is based on the naming of the coordinates.
302
+ undef("getGridType")
303
+ function getGridType(variable)
304
+ begin
305
+ str = variable@coordinates
306
+ gtype = stringtocharacter(str)
307
+ if (gtype(0) .eq. "c") then
308
+ str = "cell"
309
+ end if
310
+ if (gtype(0) .eq. "e") then
311
+ str = "edge"
312
+ end if
313
+ if (gtype(0) .eq. "v") then
314
+ str = "vertex"
315
+ end if
316
+ return str
317
+ end
318
+ ;-------------------------------------------------------------------------------
319
+ ; Return the size of coordinates
320
+ undef("getCoordSizes")
321
+ function getCoordSizes(variable,filehandle)
322
+ begin
323
+ lonlat = str_split(variable@coordinates," ")
324
+ lon = lonlat(0)
325
+ lat = lonlat(1)
326
+ lonSize = dimsizes(filehandle->$lon$)
327
+ latSize = dimsizes(filehandle->$lat$)
328
+
329
+ return (/lonSize,latSize/)
330
+ end
331
+ ;-------------------------------------------------------------------------------
332
+ ; Return the coordinates of a given variable in radians
333
+ undef("getCoordinates")
334
+ function getCoordinates(variable,filehandle)
335
+ begin
336
+ lonlat = str_split(variable@coordinates," ")
337
+ lon = lonlat(0)
338
+ lat = lonlat(1)
339
+ x = filehandle->$lon$
340
+ y = filehandle->$lat$
341
+
342
+ return (/x,y/)
343
+ end
344
+ ;-------------------------------------------------------------------------------
345
+ ; Return the coordinates of a given variable in degrees
346
+ undef("getLonLats")
347
+ procedure getLonLats(variable,filehandle,x,y)
348
+ begin
349
+ lonlat = str_split(variable@coordinates," ")
350
+ lon = lonlat(0)
351
+ lat = lonlat(1)
352
+ x = filehandle->$lon$
353
+ y = filehandle->$lat$
354
+ x = x * RAD2DEG
355
+ y = y * RAD2DEG
356
+ end
357
+ ;-------------------------------------------------------------------------------
358
+ ; get variable from a certain file
359
+ undef("getVarFromFile")
360
+ function getVarFromFile(varname,filename)
361
+ begin
362
+ f = addfile(filename+".nc","r")
363
+ var = f->$varname$
364
+ return var
365
+ end
366
+ ;-------------------------------------------------------------------------------
367
+ ; read a coordinates variable from icon file and return its lonlat representation
368
+ undef("getCoordinateFromFile")
369
+ function getCoordinateFromFile(varname,filename)
370
+ begin
371
+ var = getVarFromFile(varname,filename)
372
+ return var*RAD2DEG
373
+ end
374
+ ;-------------------------------------------------------------------------------
375
+ ; Create an ascending array of numbers with a 'halflog' interval, i.e. for
376
+ ; every decade the numbers 1, 2 and 5 are present.
377
+ ; Examples:
378
+ ; (/1,2,5,10,20,50,100,200,500/) or
379
+ ; (/-1,-5e-1,-2e-1,-1e-1,-5e-2,-2e-2,-1e-2,0,1e-2,2e-2,5e-2,1e-1,2e-1,5e-1,1/)
380
+ ; scaleLimit determines the numer of decades on the positive or negtive axis of the output array
381
+ undef("createLevels")
382
+ function createLevels(minVar, maxVar, scaleLimit)
383
+ begin
384
+ delimiter = "|"
385
+ tics4positive = (/1, 2, 5/)
386
+ tics4negative = (/5, 2, 1/)
387
+
388
+ signMin = sign(minVar)
389
+ signMax = sign(maxVar)
390
+ if (minVar.eq.0) then
391
+ logfirst = 0.0
392
+ first = 0.0
393
+ else
394
+ logfirst = ceil(log10(abs(minVar)))
395
+ first = signMin*10^logfirst
396
+ end if
397
+ if (maxVar.eq.0) then
398
+ loglast = 0.0
399
+ last = 0.0
400
+ else
401
+ loglast = ceil(log10(abs(maxVar)))
402
+ last = signMax*10^loglast
403
+ end if
404
+
405
+
406
+ retval = (/first, last, logfirst, loglast, signMin, signMax, logfirst*signMin - loglast*signMax/)
407
+
408
+ myScale = logfirst
409
+ levels = ""
410
+ ;levels = new(1,float)
411
+ if (first .eq. 0) then
412
+ levels = str_concat((/levels,delimiter,"0"/))
413
+ ;array_append_record_proc(levels,0.0)
414
+ print(levels)
415
+ end if
416
+ current = first
417
+ if (current .lt. 0) then
418
+ tics = tics4negative
419
+ do scaleChange=1,scaleLimit
420
+ do ticIndex=0,2
421
+ current = - tics(ticIndex)*10^(logfirst-scaleChange)
422
+ levels = str_concat((/levels,delimiter,flt2string(doubletofloat(current))/))
423
+ ;array_append_record_proc(levels,doubletofloat(current))
424
+ end do
425
+ end do
426
+ end if
427
+ if (first.lt.0 .and. last.gt.0) then
428
+ levels = str_concat((/levels,delimiter,"0"/))
429
+ ;array_append_record_proc(levels,0.0)
430
+ end if
431
+ if (last .gt. 0) then
432
+ tics = tics4positive
433
+ if (first.lt.0) then
434
+ startScale = min((/logfirst, loglast/)) - scaleLimit
435
+ else
436
+ startScale = min((/logfirst, loglast/))
437
+ end if
438
+ j = 0
439
+ do while (current.lt.(last/10))
440
+ myScale = startScale + j
441
+ do ticIndex=0,2
442
+ current = tics(ticIndex)*10^(myScale)
443
+ levels = str_concat((/levels,delimiter,flt2string(doubletofloat(current))/))
444
+ ;array_append_record_proc(levels,current)
445
+ end do
446
+ j = j + 1
447
+ end do
448
+ levels = str_concat((/levels,delimiter,flt2string(doubletofloat(last))/))
449
+ ;array_append_record_proc(levels,last)
450
+ end if
451
+ return(str_split(levels,"|"))
452
+ ;print(levels)
453
+ ;return(levels)
454
+ end
455
+ ;---------------------------------------------------------------
456
+ ; Print all variable names of a given file
457
+ undef("printVarNames")
458
+ procedure printVarNames(filehandle)
459
+ begin
460
+ filevarnames = getfilevarnames(filehandle)
461
+ print("# === variable names in file: "+filevarnames)
462
+ end
463
+ ;---------------------------------------------------------------
464
+ ; Print information about dimensions and attributes of a given varaiable
465
+ procedure printVar(varname, filehandle)
466
+ begin
467
+ dims = getfilevardims(filehandle,varname)
468
+ sizes = filevardimsizes(filehandle,varname)
469
+ var = filehandle->$varname$
470
+ ; Print info about variable, its dimensions and attributes
471
+ print(dimsizes(sizes) + " Dimensions:")
472
+ if(.not.any(ismissing(dims))) then
473
+ do j = 0, dimsizes(dims) -1
474
+ print( j + ") " + dims(j) + ": " + sizes(j))
475
+ end do
476
+ end if
477
+ atts = getfilevaratts(filehandle,varname)
478
+ if(.not.any(ismissing(atts))) then
479
+ do k = 0, dimsizes(atts) -1
480
+ print(atts(k) + ": " +filehandle->$varname$@$atts(k)$)
481
+ if (atts(k) .eq. "coordinates") then
482
+ coordinates = var@$atts(k)$
483
+ else
484
+ coordinates = DEFAULTLON + " " + DEFAULTLAT
485
+ end if
486
+ end do
487
+ end if
488
+ end
489
+ ;---------------------------------------------------------------
490
+ ; Check, if a given variable name is present in a file
491
+ undef("checkVarname")
492
+ procedure checkVarname(varname, filehandle)
493
+ begin
494
+ filevarnames = getfilevarnames(filehandle)
495
+ if (.not. any(filevarnames.eq.varname)) then
496
+ print("Could not find variable "+varname+"!")
497
+ exit
498
+ end if
499
+ return True
500
+ end
501
+ ;---------------------------------------------------------------
502
+ ; Check, if the dimensions of to variables are equal
503
+ undef("checkDimsOfVars")
504
+ procedure checkDimsOfVars(varname0,varname1,filehandle)
505
+ begin
506
+ print(getfilevardims(filehandle,varname0))
507
+ print(getfilevardims(filehandle,varname1))
508
+ if (str_join(getfilevardims(filehandle,varname0),"") .ne. str_join(getfilevardims(filehandle,varname1),"")) then
509
+ print("Variables '"+varname0+"' and '"+varname1+"' must have the same dimensions!")
510
+ print("ABORT!")
511
+ exit
512
+ end if
513
+ end
514
+ ;---------------------------------------------------------------
515
+ ; Read a variable from the given or an optional file
516
+ undef("getMaskVar")
517
+ function getMaskVar(maskvarname,filehandle,hasOtherMaskfile,maskfilename,timestep,levelindex,plotmode,horizontalgridtype)
518
+ begin
519
+ if (hasOtherMaskfile) then
520
+ mfilehandle = addfile( maskfilename+".nc","r" )
521
+ else
522
+ mfilehandle = filehandle
523
+ end if
524
+ checkVarname(maskvarname, mfilehandle)
525
+ if (plotmode.eq."scalar" .or. plotmode.eq."overlay") then
526
+ if (horizontalgridtype.eq."unstructured") then
527
+ maskvar = selIconField(maskvarname,mfilehandle,timestep,levelindex)
528
+ else
529
+ maskvar = selRegularField(maskvarname,mfilehandle,timestep,levelindex)
530
+ end if
531
+ else
532
+ if (plotmode.eq."vector") then
533
+ maskvar = selRegularField(maskvarname,mfilehandle,timestep,levelindex)
534
+ else ; section
535
+ maskvar = selRegularVar(maskvarname,mfilehandle,timestep)
536
+ end if
537
+ end if
538
+
539
+ return maskvar
540
+ end
541
+ ;---------------------------------------------------------------
542
+ ; Read the dimensions of a variables from the given ot an optional file
543
+ ;
544
+ ; GLOBALS: maskFile
545
+ undef("getMaskDim")
546
+ function getMaskDim(maskvarname,filehandle,hasOtherMaskfile)
547
+ begin
548
+ if (hasOtherMaskfile) then
549
+ filehandle = addfile( maskFile+".nc","r" )
550
+ end if
551
+ checkVarname(maskvarname, filehandle)
552
+ maskdims = getfilevardims(filehandle,maskvarname)
553
+
554
+ return maskdims
555
+ end
556
+ ;---------------------------------------------------------------
557
+ ; set new filename bases on the input filename and intput type
558
+ undef("setNewFilename")
559
+ function setNewFilename(filename,tag,itype,atmlev)
560
+ begin
561
+ atmtag = ""
562
+ if (itype .eq. "atm") atmtag = "atmlev"+str_capital(atmlev)+"_" end if
563
+ newFilename = tag+"_"+atmtag+systemfunc("basename "+filename)
564
+ return newFilename
565
+ end
566
+ ;---------------------------------------------------------------
567
+ ; set filename for the automatically remapped file
568
+ undef("setRemapFilename")
569
+ function setRemapFilename(filename,itype,atmlev)
570
+ begin
571
+ return setNewFilename(filename,"remapnn",itype,atmlev)
572
+ end
573
+ undef("setZonmeanFilename")
574
+ function setZonmeanFilename(filename,itype,atmlev)
575
+ begin
576
+ return setNewFilename(filename,"zonmean",itype,atmlev)
577
+ end
578
+ ;---------------------------------------------------------------
579
+ ; Check, if two files have the same number of timestemps. Exit otherwise
580
+ undef("checkRemappedFile")
581
+ function checkRemappedFile(infilename,remapfilename,varname,itype,atmlev,atmplevs,atmhlevs)
582
+ begin
583
+ retval = True
584
+
585
+ if (.not. isfilepresent(remapfilename)) return False end if
586
+
587
+ orgFile = addfile (infilename+".nc" , "r")
588
+ orgTime = getfilevardimsizes(orgFile,"time")
589
+
590
+ if (.not. has_var(orgFile,varname)) then
591
+ print("Cannot find varname:"+varname)
592
+ exit
593
+ end if
594
+
595
+ orgvertdimname = getVertDim(orgFile,orgFile->$varname$)
596
+ if (.not. ismissing(orgvertdimname) ) then
597
+ orgvertdim = orgFile->$orgvertdimname$
598
+ end if
599
+
600
+ remapFile = addfile(remapfilename+".nc","r")
601
+ remapTime = getfilevardimsizes(remapFile,"time")
602
+ ; test if the given variable can be found
603
+ if (.not. has_var(remapFile,varname)) then
604
+ print("Cannot find "+varname+" in remapped files:"+remapfilename)
605
+ retval = False
606
+ return retval
607
+ else
608
+ remappedvertdimname = getVertDim(remapFile,remapFile->$varname$)
609
+ if (.not. ismissing(remappedvertdimname)) then
610
+ remappedvertdim = remapFile->$remappedvertdimname$
611
+ end if
612
+ end if
613
+
614
+
615
+ if ( orgTime .eq. remapTime ) then
616
+ print("#=====================================================================================")
617
+ print("Remapped File '"+remapfilename+"' seems to have right time axes.")
618
+ else
619
+ print("#=====================================================================================")
620
+ print("Remapped File '"+remapfilename+"' seems to be wrong: Has different number of timesteps")
621
+ print("Original file has "+orgTime(0)+" timesteps")
622
+ print("Remapped File has "+remapTime(0)+" timesteps")
623
+ retval = False
624
+ end if
625
+
626
+ if (itype .eq. "atm") then
627
+ if (atmlev .eq. "p" .and. (str_join(atmplevs,",") .ne. str_join(remappedvertdim,",")) .and. (.not. ismissing(remappedvertdimname)))
628
+ print("Vertical pressure levels differ")
629
+ retval = False
630
+ else
631
+ print("Vertical pressure levels ok.")
632
+ end if
633
+ if (atmlev .eq. "h" .and. (str_join(atmhlevs,",") .ne. str_join(remappedvertdim,",")) .and. (.not. ismissing(remappedvertdimname)))
634
+ print("Vertical height levels differ")
635
+ retval = False
636
+ else
637
+ print("Vertical height levels ok.")
638
+ end if
639
+ end if
640
+ if (itype .eq. "oce") then
641
+ if ((.not. ismissing(orgvertdimname)) .and. (str_join(orgvertdim,",") .ne. str_join(remappedvertdim,",")) .and. (.not. ismissing(remappedvertdimname)))
642
+ print("Vertical depth levels differ")
643
+ retval = False
644
+ else
645
+ print("Vertical depth levels ok")
646
+ end if
647
+ end if
648
+
649
+ return retval
650
+ end
651
+ ;---------------------------------------------------------------
652
+ ; Perform a remapping (wich CDO) to a regular grid with a given resolution and return the
653
+ ; filename of the remapped file. If the file is already present, the name is returned only
654
+ undef("remapForVecPlot")
655
+ procedure remapForVecPlot(iFile,remapFilename,resolution,useMask,plotMode,debug,addvars)
656
+ begin
657
+ if (plotMode.eq."section") then vecVars=(/varName/) end if
658
+ print("#=====================================================================================")
659
+ print("Looking for remapped file: "+remapFilename)
660
+ print("Use CDO to perform remapping: Create intermediate file: "+remapFilename)
661
+ print("Remove this intermediate file, if it was NOT automatically created from your inpur file "+iFile+"!")
662
+ variables = str_join(vecVars,",")
663
+ if ( addvars(0) .ne. "")
664
+ variables = str_concat((/variables,",",str_join(addvars,",")/))
665
+ print(str_join(addvars,","))
666
+ print("variables:"+variables)
667
+ end if
668
+ if ( useMask ) then
669
+ variables=variables +","+maskName
670
+ end if
671
+ if (plotMode.eq."overlay") variables = variables+","+varName end if
672
+
673
+ cmd = CDO+" -P 8 -remapnn,"+resolution+" -selname,"+variables+" "+iFile+" "+remapFilename
674
+ if debug then
675
+ print(cmd)
676
+ end if
677
+ system(cmd)
678
+ end
679
+ ;---------------------------------------------------------------
680
+ ; perform zonal mean for hoffmueller plot
681
+ undef("zonmean4HoffmuellerPlot")
682
+ procedure zonmean4HoffmuellerPlot(filename,varname,zonmeanfilename)
683
+ begin
684
+ cmd = CDO+" zonmean -selname,"+varname+" "+filename+" "+zonmeanfilename
685
+ if debug then
686
+ print(cmd)
687
+ end if
688
+ system(cmd)
689
+ end
690
+ ;---------------------------------------------------------------
691
+ ; Return the bounds of the coordinates of agiven variable
692
+ undef("getBoundsOfCoordinates")
693
+ function getBoundsOfCoordinates(variable,filehandle)
694
+ begin
695
+ lonlat = str_split(variable@coordinates," ")
696
+ lon = lonlat(0)
697
+ lat = lonlat(1)
698
+
699
+
700
+ boundslonName = filehandle->$lon$@bounds
701
+ boundslatName = filehandle->$lat$@bounds
702
+ boundslon = filehandle->$boundslonName$ * RAD2DEG
703
+ boundslat = filehandle->$boundslatName$ * RAD2DEG
704
+
705
+ return (/boundslon, boundslat/)
706
+ end
707
+ ;---------------------------------------------------------------
708
+ ; Return the bounds of the coordinates of agiven variable
709
+ undef("getBoundsFromFile")
710
+ function getBoundsFromFile(lonname,latname,filename)
711
+ begin
712
+ f = addfile(filename+".nc","r")
713
+ boundslonName = f->$lonname$@bounds
714
+ boundslatName = f->$latname$@bounds
715
+ boundslon = f->$boundslonName$ * RAD2DEG
716
+ boundslat = f->$boundslatName$ * RAD2DEG
717
+
718
+ return (/boundslon, boundslat/)
719
+ end
720
+ ;---------------------------------------------------------------
721
+ ; (Re)Set end of bounds. Required by the implementation of the grid plot
722
+ undef("setBoundsEnds")
723
+ procedure setBoundsEnds(blon,blat,lonmin,lonmax,latmin,latmax)
724
+ begin
725
+ latmax=max(blat)
726
+ latmin=min(blat)
727
+ lonmax=max(blon)
728
+ lonmin=min(blon)
729
+
730
+ if ( lonmin.lt.0 ) then
731
+ ; longitudes are given in the range [-180,180]
732
+ lonmin = -180.
733
+ lonmax = 180.
734
+ else
735
+ ; longitudes are given in the range [0,360]
736
+ lonmin = 0.
737
+ lonmax = 360.
738
+ end if
739
+ end
740
+ ;---------------------------------------------------------------
741
+ ; Bounds check for the grid plot
742
+ undef("checkLongitude")
743
+ procedure checkLongitude(x,boundslon,lonmin,lonmax,debug)
744
+ begin
745
+ dlon = 80.
746
+ ncell_tot = dimsizes(x) ; total # of cells
747
+ nfix = 0 ; count the # of problematic cells
748
+
749
+ do icell = 0, ncell_tot-1
750
+ if ( any(boundslon(icell,:).le.(lonmin+dlon)) .and. \
751
+ any(boundslon(icell,:).gt.(lonmax-dlon)) ) then
752
+
753
+ bl1=boundslon(icell,0)
754
+ bl2=boundslon(icell,1)
755
+ bl3=boundslon(icell,2)
756
+
757
+ boundslon(icell,:) = where(boundslon(icell,:).gt.(lonmax-dlon), \;
758
+ boundslon(icell,:)-360., \; where true
759
+ boundslon(icell,:) ) ; where false
760
+
761
+ bn1=boundslon(icell,0)
762
+ bn2=boundslon(icell,1)
763
+ bn3=boundslon(icell,2)
764
+
765
+ if (debug) then
766
+ print("cell="+icell+" lon="+bl1+", "+bl2+", "+bl3+" changed into " \
767
+ +" lon="+bn1+", "+bn2+", "+bn3)
768
+ end if
769
+
770
+ nfix = nfix +1
771
+ end if
772
+ end do
773
+ print("Longitude(s) of "+nfix+" cells corrected to avoid plotting problem.")
774
+ end
775
+ ;---------------------------------------------------------------
776
+ ; Set the Vertical Selection mode of the given NCL resource
777
+ undef("setLevels")
778
+ procedure setLevels(selmode,resource,minvar,maxvar,scalelimit,numlevs,debug)
779
+ begin
780
+ if (selmode .eq. "manual") then
781
+ resource@cnLevelSelectionMode = "ManualLevels"
782
+ resource@cnMinLevelValF = minvar
783
+ resource@cnMaxLevelValF = maxvar
784
+ ; diffLog10 = log10(abs(maxVar-minVar))
785
+ ;; if (diffLog10 .lt. 0) then
786
+ ; resource@cnLevelSpacingF = 10^(floor(diffLog10))/numLevs
787
+ ;; else
788
+ ;; resource@cnLevelSpacingF = 10^(floor(diffLog10))/numLevs
789
+ ;; end if
790
+ diffspacing = abs(maxvar-minvar)/(int2flt(numlevs))
791
+ resource@cnLevelSpacingF = diffspacing
792
+ end if
793
+
794
+ if (selmode .eq. "halflog") then
795
+ resource@cnLevelSelectionMode = "ExplicitLevels"
796
+ plotLevels = createLevels(minvar,maxvar,scalelimit)
797
+ if (debug) print("plotlevels = "+plotLevels) end if
798
+ resource@cnLevels = plotLevels
799
+ end if
800
+ if (debug) then
801
+ print("Manual Plotlevel setting......")
802
+ print(" selMode : " + selmode)
803
+ print(" minVal : " + minvar)
804
+ print(" maxVal : " + maxvar)
805
+ print(" numLevs: " + numlevs)
806
+ print(" scalelimit: " + scalelimit)
807
+ print(" plotLevels: " + resource@cnLevels)
808
+ end if
809
+ end
810
+ ;---------------------------------------------------------------
811
+ ; Create a default NCL resource
812
+ undef("setDefaultResource")
813
+ procedure setDefaultResource(resource,verticallabelbar)
814
+ begin
815
+ resource@gsnMaximize = False
816
+ ; resource@gsnPaperOrientation = "landscape" ; turns plot on paper
817
+ ; resource@wkPaperSize = "A4"
818
+ resource@gsnFrame = False
819
+ resource@gsnSpreadColors = True
820
+
821
+ resource@cnFillOn = True ; writes labelbar, no contour labels
822
+ resource@cnLinesOn = False
823
+ resource@cnInfoLabelOn = False
824
+
825
+ FontHeight0 = 0.012
826
+ FontHeight1 = 0.015
827
+ FontHeight2 = 0.017
828
+ FontHeight3 = 0.020
829
+
830
+ resource@tiXAxisFontHeightF = FontHeight0
831
+ resource@tiYAxisFontHeightF = FontHeight0
832
+ resource@tmXBLabelFontHeightF = FontHeight0
833
+ resource@tmYLLabelFontHeightF = FontHeight0
834
+ resource@tmXBLabelJust = "CenterCenter"
835
+ resource@gsnStringFontHeightF = FontHeight0
836
+
837
+ resource@mpFillOn = True
838
+ resource@cnFillOn = True
839
+
840
+ resource@lbLabelBarOn = True
841
+ if (verticallabelbar .eq. True) then
842
+ resource@lbOrientation = "vertical"
843
+ else
844
+ resource@pmLabelBarHeightF = 0.12
845
+ resource@pmLabelBarWidthF = 0.80
846
+ resource@pmLabelBarOrthogonalPosF = 0.15
847
+ end if
848
+ resource@lbLabelAutoStride = True
849
+ resource@lbLabelFontHeightF = FontHeight1 ; color bar labels
850
+
851
+ resource@cnFillMode = "RasterFill"
852
+ ;resource@cnFillMode = "CellFill"
853
+ resource@cnRasterSmoothingOn = True
854
+ resource@mpGreatCircleLinesOn = True
855
+ resource@stMinArrowSpacingF = 0.001
856
+ end
857
+ ;---------------------------------------------------------------
858
+ undef("setDefaultSectionResource")
859
+ function setDefaultSectionResource(points,secpoints,seclc,secrc)
860
+ begin
861
+ resource = True; plot mods desired
862
+ resource@gsnFrame = False; don't turn page yet
863
+ resource@gsnDraw = False; don't draw yet
864
+ resource@tmXBMode = "Explicit"; explicitly label x-axis
865
+ resource@tmXBValues = (/points(0),points(secpoints-1)/); points to label values
866
+ resource@tmXBLabels = (/ seclc(1) +"N, "+ seclc(0)+"E" , secrc(1)+"N, "+secrc(0)+"E" /)
867
+
868
+ resource@cnFillOn = True; turn on color
869
+ resource@lbLabelAutoStride = True; nice label bar label stride
870
+ resource@gsnSpreadColors = True; use full range of colormap
871
+ resource@cnLinesOn = False; turn off countour lines
872
+ resource@lbOrientation = "vertical"; vertical label bar
873
+ resource@pmLabelBarOrthogonalPosF = -0.05; move label bar closer to plot
874
+ resource@lbTitlePosition = "Bottom"
875
+ ; resource@gsnYAxisIrregular2Log = True
876
+
877
+ delete(resource@cnMissingValFillPattern); no longer filling missing value areas
878
+ delete(resource@cnMissingValFillColor); no longer filling missing value areas
879
+ resource@cnMissingValFillColor = "gray30"
880
+ resource@cnMissingValPerimOn = True
881
+
882
+ resource@cnMissingValFillPattern = -1; set the missing value fill pattern to 5
883
+ resource@cnMissingValFillScaleF = 0.9; increase the density of the fill pattern (default = 1.0)
884
+ ; resource@cnMissingValPerimOn = True; already turned on above
885
+ resource@cnMissingValPerimColor = "black"; change the missing value perimeter to black
886
+ resource@cnMissingValPerimDashPattern = 1; set the dash pattern of the missing value perimeter to 1
887
+ resource@cnMissingValPerimThicknessF = 3.0; increase the thickness of the missing value perimeter 3X
888
+ ;resource@gsnYAxisIrregular2Log = True
889
+ return resource
890
+ end
891
+ undef("setDefaultOverlayResource")
892
+ procedure setDefaultOverlayResource(resource)
893
+ begin
894
+ resource@gsnDraw = False
895
+ resource@gsnFrame = False
896
+ resource@vcVectorDrawOrder = "Postdraw"
897
+ resource@vcFillArrowWidthF = 12.0
898
+ resource@lbOrientation = "Vertical"
899
+ resource@lbTitleString = "C"
900
+ resource@lbTitlePosition = "Left"
901
+ resource@cnInfoLabelOn = False
902
+ resource@lbTitleFontHeightF = 0.02
903
+ resource@lbLabelFontHeightF = 0.015
904
+ resource@lbLeftMarginF = 0.01
905
+ resource@lbLabelBarOn = False; switch of the vector label bar, because the speed is show as vector lenghts
906
+ end
907
+ ;---------------------------------------------------------------
908
+ undef("shift4SecMap")
909
+ procedure shift4SecMap(resource)
910
+ begin
911
+ resource@vpWidthF = 0.6; set width of plot
912
+ resource@vpHeightF = 0.4; set height of plot
913
+
914
+ resource@vpXF = 0.2
915
+ resource@vpYF = 0.9
916
+ end
917
+ ;---------------------------------------------------------------
918
+ ; Compute the left shift for string with font hight 0.01, which should be
919
+ ; displayed in the lower left corner of the plot with gsn_test_ndc()
920
+ undef("getLshiftForNDCString")
921
+ function getLshiftForNDCString(mystring)
922
+ begin
923
+ lshift = (strlen(mystring)/2 - 1)/100.0
924
+ if (strlen(mystring) .gt. 4)
925
+ lshift = lshift - lshift/5 + 0.1/strlen(mystring)
926
+ else
927
+ lshift = lshift + 0.01
928
+ end if
929
+
930
+ return lshift
931
+ end
932
+ ;---------------------------------------------------------------
933
+ ; Display a small string in the lower left corner of the plot
934
+ undef("setBaseString")
935
+ procedure setBaseString(workstation,plot,resource,basestring)
936
+ begin
937
+ resource@txFontHeightF = 0.01 ; if this is changed, please adjust the implementation of getLshiftForNDCString()
938
+ gsn_text_ndc(workstation,basestring,getLshiftForNDCString(basestring),.01,resource)
939
+ end
940
+ ;---------------------------------------------------------------
941
+ ; see setBaseString, but use an optional global argument
942
+ ;
943
+ ; GLOBALS: bStrg
944
+ undef("setAutomaticBaseString")
945
+ procedure setAutomaticBaseString(workstation,plotmode)
946
+ begin
947
+ if(isvar("bStrg")) then
948
+ BaseString = bStrg
949
+ else
950
+ BaseString = "Prgr icon_plot.ncl: " + systemfunc("date") + ","+getenv("USER")
951
+ end if
952
+ res = True
953
+ res@txFontHeightF = 0.011
954
+ if (plotmode.eq."section") res@txPosYF = 0.01 end if
955
+ gsn_text_ndc(workstation,BaseString,getLshiftForNDCString(BaseString),.12,res)
956
+ end
957
+ ;---------------------------------------------------------------
958
+ ; Set the Captions of a plot (left,right,center,title)
959
+ undef("setPlotCaptions")
960
+ procedure setPlotCaptions(resource,leftstring,rightstring,centerstring,titlestring)
961
+ begin
962
+ resource@gsnLeftString = leftstring
963
+ resource@gsnRightString = rightstring
964
+ resource@gsnCenterString = centerstring
965
+ resource@tiMainString = titlestring
966
+ end
967
+ ;---------------------------------------------------------------
968
+ ; Set the capitons of a plot automatically
969
+ ;
970
+ ; GLOBALS: lStrg, rStrg, tStrg
971
+ undef("setAutomaticPlotCaptions")
972
+ procedure setAutomaticPlotCaptions(resource,plotmode,varname,filehandle,filename,timestep,levelindex,itype,atmlev,k2c)
973
+ local varname
974
+ begin
975
+ ; titles
976
+ if (plotmode.eq."vector") then
977
+ varname = vecVars(0)
978
+ left_str = "velocity"
979
+ else
980
+ left_str = varname
981
+ end if
982
+ if(.not. isvar("lStrg")) then
983
+ hastime = var_has_time(varname, filehandle)
984
+ if (hastime) then
985
+ timeval = filehandle->time(timestep)
986
+ dayfrag = timeval - floor(timeval)
987
+ day = doubletointeger(floor(timeval))
988
+ hour = doubletointeger(floor(86400*dayfrag/3600))
989
+ minute = doubletointeger(floor((86400*dayfrag - hour*3600)/60))
990
+ second = doubletointeger(86400*dayfrag - hour*3600 - minute*60)
991
+ timeStr = str_join((/day,hour,minute,second/),"|")
992
+ left_str = left_str + " (ts:"+timestep+"["+timeStr+"] "
993
+ else
994
+ left_str = "("
995
+ end if
996
+ if (plotmode .ne. "section")
997
+ if ( .not.ismissing(getVertDim(filehandle,filehandle->$varname$)) ) then
998
+ vertdimname = getVertDim(filehandle,filehandle->$varname$)
999
+ vertdim = filehandle->$vertdimname$
1000
+ vertval = vertdim(levelindex)
1001
+ left_str = left_str + "lev:"+vertval
1002
+ if (atmlev .ne. "m")
1003
+ left_str = left_str+vertdim@units+")"
1004
+ else
1005
+ left_str = left_str +")"
1006
+ end if
1007
+ end if
1008
+ end if
1009
+ else
1010
+ left_str = lStrg
1011
+ end if
1012
+
1013
+ if(.not. isvar("rStrg")) then
1014
+ rStrg = (/filename/)
1015
+ end if
1016
+ rightstring = str_join(rStrg," ")
1017
+
1018
+ if(.not. isvar("tStrg")) then
1019
+ tStrg = "ICON"
1020
+ end if
1021
+ titlestring = str_join(tStrg," ")
1022
+ centerstring = ""
1023
+
1024
+ resource@gsnLeftString = left_str
1025
+ resource@gsnRightString = rightstring
1026
+ resource@gsnCenterString = centerstring
1027
+ resource@tiMainString = titlestring
1028
+ v = filehandle->$varname$
1029
+ if ( isatt(v,"units") ) then
1030
+ resource@lbTitleString = "["+v@units+"]"
1031
+ else
1032
+ resource@lbTitleString = ""
1033
+ end if
1034
+ if (itype .eq. "atm" .and. varname .eq. "T" .and. k2c) resource@lbTitleString = "C" end if
1035
+
1036
+ resource@lbTitlePosition = "Bottom"
1037
+ resource@cnInfoLabelOn = False
1038
+ resource@lbTitleFontHeightF = 0.02
1039
+ resource@lbLabelFontHeightF = 0.015
1040
+ resource@lbLeftMarginF = 0.01
1041
+ end
1042
+ ;---------------------------------------------------------------
1043
+ ; vertical axes label for section plot
1044
+ undef("setSectionVertLabel")
1045
+ procedure setSectionVertLabel(resource,itype,atmlev)
1046
+ begin
1047
+ resource@lbTitleString = "[C]"
1048
+ label = ""
1049
+ reversYAxis = True
1050
+ if (itype .eq. "atm") then
1051
+ label = "Index"
1052
+ if (atmlev .eq. "p") label = "Pressure (Pa)" end if
1053
+ if (atmlev .eq. "h")
1054
+ label = "Height (m)"
1055
+ reversYAxis = False
1056
+ end if
1057
+ else
1058
+ label = "depth below sea (m)"
1059
+ end if
1060
+ resource@tiYAxisString = label
1061
+ resource@trYReverse = reversYAxis
1062
+ end
1063
+ ;---------------------------------------------------------------
1064
+ ; Determine the type of the map
1065
+ undef("setMapType")
1066
+ procedure setMapType(resource,maptype,centerlon,centerlat,satdist)
1067
+ begin
1068
+ if (maptype .eq. "ortho") then
1069
+ resource@mpProjection = "Orthographic"
1070
+ resource@mpPerimOn = False; turn off box around plot
1071
+ resource@mpGridAndLimbOn = True; draw grid lines and limb line
1072
+ resource@mpGridLineDashPattern = 2; choose pattern used to draw the grid
1073
+ resource@mpCenterLonF = centerlon
1074
+ resource@mpCenterLatF = centerlat
1075
+ resource@vcRefLengthF = 0.01
1076
+ resource@vcRefAnnoArrowLineColor = "black"; change ref vector color
1077
+ resource@vcRefAnnoArrowUseVecColor = False; do not use vec color for ref
1078
+ resource@vcRefAnnoOn = False; turns off ref vector annotation
1079
+ resource@vcGlyphStyle = "CurlyVector"; turn on curly vectors
1080
+ resource@vcMonoLineArrowColor = True; multiple colors desired
1081
+ resource@vcVectorDrawOrder = "PostDraw"; draw vectors last
1082
+
1083
+
1084
+ resource@mpGridAndLimbOn = True ; turn on lat/lon grid lines
1085
+ resource@mpGridMaskMode = "MaskNotOcean" ; don't draw over land or
1086
+ ; inland water bodies
1087
+
1088
+ ; resource@mpLandFillColor = "tan"
1089
+ ; resource@mpOceanFillColor = "LightBlue"
1090
+ ; resource@mpInlandWaterFillColor = "LightBlue"
1091
+ end if
1092
+
1093
+ if (maptype .eq. "lonlat")
1094
+ resource@mpProjection = "CylindricalEquidistant"
1095
+ resource@mpLimitMode = "LatLon"
1096
+ end if
1097
+
1098
+ if (maptype .eq. "NHps")
1099
+ resource@mpProjection = "Stereographic"
1100
+ resource@mpRelativeCenterLon = True
1101
+ resource@mpCenterLonF = 0
1102
+ resource@mpRelativeCenterLat = True
1103
+ resource@mpCenterLatF = 90.
1104
+ resource@mpLimitMode = "Corners"
1105
+ end if
1106
+
1107
+ if (maptype .eq. "SHps")
1108
+ resource@mpProjection = "Stereographic"
1109
+ resource@mpRelativeCenterLon = True
1110
+ resource@mpCenterLonF = 0
1111
+ resource@mpRelativeCenterLat = True
1112
+ resource@mpCenterLatF = -90.
1113
+ resource@mpLimitMode = "Corners"
1114
+ end if
1115
+ if (maptype .eq. "sat")
1116
+ resource@mpProjection = "Satellite"
1117
+ resource@mpMinLatF = resource@mpMinLatF + 10.
1118
+ resource@mpMaxLatF = resource@mpMaxLatF - 10.
1119
+ resource@mpMinLonF = resource@mpMinLonF + 10.
1120
+ resource@mpMaxLonF = resource@mpMaxLonF - 10.
1121
+ resource@mpCenterLonF = centerlon
1122
+ resource@mpCenterLatF = centerlat
1123
+ resource@mpSatelliteDistF = satdist
1124
+ end if
1125
+ if (maptype .eq. "lambert")
1126
+ resource@mpProjection = "LambertConformal"
1127
+ resource@mpProjection = "Hammer"
1128
+ resource@mpProjection = "Mollweide"
1129
+ resource@mpProjection = "Robinson"
1130
+ resource@mpProjection = "WinkelTripel"
1131
+ resource@mpProjection = "Gnomonic"
1132
+ resource@mpProjection = "Aitoff"
1133
+ ; resource@gsnMaskLambertConformal = True
1134
+ end if
1135
+ end
1136
+ ;---------------------------------------------------------------
1137
+ ; Determine the corners of the map to plot
1138
+ ; mapllc = map-lower-left-corner
1139
+ ; mapurl = map-upper-right-corner
1140
+ ; format: (/lon,lat/)
1141
+ undef("selMapCut")
1142
+ procedure selMapCut(resource,mapllc,mapurc)
1143
+ begin
1144
+ ; bounds of plotting area (not used for Orthographic)
1145
+ resource@mpMinLatF = mapllc(1)
1146
+ resource@mpMaxLatF = mapurc(1)
1147
+ resource@mpMinLonF = mapllc(0)
1148
+ resource@mpMaxLonF = mapurc(0)
1149
+
1150
+ ; center of view (for Orthographic and Sattelite only)
1151
+ ; resource@mpCenterLonF = (resource@mpMaxLonF+resource@mpMinLonF)/2.0
1152
+ ; resource@mpCenterLatF = (resource@mpMaxLatF+resource@mpMinLatF)/2.0
1153
+
1154
+ ; bounds of plotting area for stereographic plots
1155
+ resource@mpLeftCornerLonF = mapllc(0)
1156
+ resource@mpLeftCornerLatF = mapllc(1)
1157
+ resource@mpRightCornerLonF = mapurc(0)
1158
+ resource@mpRightCornerLatF = mapurc(1)
1159
+ end
1160
+ ;---------------------------------------------------------------
1161
+ ; Set the visibility of the map
1162
+ undef("setMapVisibility")
1163
+ procedure setMapVisibility(resource,mapline)
1164
+ begin
1165
+ if (mapline) then
1166
+ resource@mpGeophysicalLineColor = "foreground"
1167
+ else
1168
+ resource@mpGeophysicalLineColor = "transparent"
1169
+ end if
1170
+ end
1171
+ ;---------------------------------------------------------------
1172
+ ; exit if minvar is larger than maxvar
1173
+ undef("checkMinMaxVar")
1174
+ procedure checkMinMaxVar(minvar,maxvar)
1175
+ begin
1176
+ if ( minvar .gt. maxvar ) then
1177
+ print("minVar has to be larger than maxVar")
1178
+ exit
1179
+ end if
1180
+ end
1181
+ ;---------------------------------------------------------------
1182
+ ; set the color of masked locations
1183
+ undef("setMaskColor")
1184
+ procedure setMaskColor(wks,resource)
1185
+ begin
1186
+ newcolor = NhlNewColor(wks,0.85,0.85,0.85) ; add gray to colormap
1187
+ ;resource@gsnSpreadColorStart = 1
1188
+ resource@gsnSpreadColorEnd = 19 ; last color number not known?
1189
+ resource@cnMissingValFillColor = 20 ; last color is used for missing values
1190
+ end
1191
+ ;---------------------------------------------------------------
1192
+ ; set the coordinates for an ICON data field
1193
+ undef("setCoordinates")
1194
+ procedure setCoordinates(resource,lons,lats)
1195
+ begin
1196
+ resource@sfXArray = lons
1197
+ resource@sfYArray = lats
1198
+ end
1199
+ ;---------------------------------------------------------------
1200
+ ; set the coordinates bounds for an ICON data field
1201
+ undef("setBounds")
1202
+ procedure setBounds(resource,filehandle,x,y,debug)
1203
+ begin
1204
+ ; add the bounds to the resource if bounds are present
1205
+ if (isatt(x,"bounds")) then
1206
+ xbounds = filehandle->$x@bounds$
1207
+ if (debug) print(""+x@bounds) end if
1208
+ resource@sfXCellBounds = xbounds
1209
+ end if
1210
+ if (isatt(y,"bounds")) then
1211
+ ybounds = filehandle->$y@bounds$
1212
+ if (debug) print(""+y@bounds) end if
1213
+ resource@sfYCellBounds = ybounds
1214
+ end if
1215
+ end
1216
+ ;---------------------------------------------------------------
1217
+ ; Print out some information about the used map
1218
+ undef("showMapInfo")
1219
+ procedure showMapInfo(resource,maptype,mapline)
1220
+ begin
1221
+ print("mapType: "+maptype)
1222
+ print("mapLine: "+mapline)
1223
+ print("CentLon/Lat="+resource@mpCenterLonF+"; "+resource@mpCenterLatF)
1224
+ print("Min/MaxLatF="+resource@mpMinLatF+"; "+resource@mpMaxLatF)
1225
+ print("Min/MaxLonF="+resource@mpMinLonF+"; "+resource@mpMaxLonF)
1226
+ end
1227
+ ;---------------------------------------------------------------
1228
+ ; preprocessing for atmosphere data, i.e. put variables on height
1229
+ ; or pressure levels:
1230
+ ; use ml2pl/ml2hl for vertical interpolation
1231
+ undef("preProc4Atm")
1232
+ function preProc4Atm(filename,atmlev,atmplevs,atmhlevs,debug)
1233
+ begin
1234
+ atmfilename = "atmPreProc_"+systemfunc("basename "+filename)
1235
+ if (atmlev .eq. "p") then
1236
+ operator = "ml2plx"
1237
+ levels = str_join(atmplevs,",")
1238
+ else
1239
+ operator = "ml2hlx"
1240
+ levels = str_join(atmhlevs,",")
1241
+ end if
1242
+
1243
+ cmd = CDO+" "+ operator +","+levels+" -selgrid,1 "+ filename +" "+ atmfilename
1244
+ if debug then
1245
+ print(cmd)
1246
+ end if
1247
+ system(cmd)
1248
+
1249
+ return atmfilename
1250
+ end
1251
+ ;---------------------------------------------------------------
1252
+ ; determine the leveltype: hybrid or non-hybrid
1253
+ undef("getVertDimType")
1254
+ function getVertDimType(dim)
1255
+ begin
1256
+ dtype = str_match(dim@long_name,"hybrid")
1257
+ if (ismissing(dtype)) then
1258
+ return "non-hybrid"
1259
+ else
1260
+ return "hybrid"
1261
+ end if
1262
+ end
1263
+ ;---------------------------------------------------------------
1264
+ ; determine the input type: oce OR atm
1265
+ ; variables on hybrid layers are belong to atm input, everything
1266
+ ; else is oce
1267
+ undef("getVarLevelType")
1268
+ function getVarLevelType(filename,varname)
1269
+ begin
1270
+ f = addfile(filename+".nc","r")
1271
+ vertdim = getVertDim(f,f->$varname$)
1272
+ if (ismissing(vertdim)) then
1273
+ delete(f)
1274
+ delete(vertdim)
1275
+ return "none"
1276
+ else
1277
+ retval = getVertDimType(f->$vertdim$)
1278
+ delete(f)
1279
+ delete(vertdim)
1280
+
1281
+ return retval
1282
+ end if
1283
+ end
1284
+ ;---------------------------------------------------------------
1285
+ ; determine the horizontal grid type (unstructured or lonlat)
1286
+ undef("getHorizGridType")
1287
+ function getHorizGridType(filename,varname,isIcon)
1288
+ begin
1289
+ if (isIcon) then
1290
+ print("DEBUG:"+isIcon)
1291
+ gridtype = "unstructured"
1292
+ else
1293
+ print("CDO:"+CDO)
1294
+ print("Call cdo griddes for determine the horizontal gridtype")
1295
+ gridtype = systemfunc(CDO+" -griddes -selname,"+varname+" -seltimestep,1 "+filename+" | grep gridtype | cut -d ' ' -f 4")
1296
+ end if
1297
+ print("Found horizontal grid of type: "+gridtype)
1298
+ return gridtype
1299
+ end
1300
+ ;---------------------------------------------------------------
1301
+ ; setting for vertical cross sections based on remapped icon data
1302
+ undef("setSection")
1303
+ function setSection(secLC,secRC,npoints,var)
1304
+ begin
1305
+ leftlat = secLC(1)
1306
+ rightlat = secRC(1)
1307
+
1308
+ leftlon = secLC(0)
1309
+ rightlon = secRC(0)
1310
+
1311
+ dist = gc_latlon(leftlat,leftlon,rightlat,rightlon,npoints,2)
1312
+ trans = linint2_points(var&lon,var&lat,var,True,dist@gclon,dist@gclat,2)
1313
+
1314
+ return trans
1315
+ end
1316
+ ;---------------------------------------------------------------
1317
+ ; setting for vertical cross sections based on remapped icon data
1318
+ undef("setSectionFromHybridPress")
1319
+ function setSectionFromHybridPress(secLC,secRC,npoints,var,filehandle,timestep)
1320
+ begin
1321
+ leftlat = secLC(1)
1322
+ rightlat = secRC(1)
1323
+
1324
+ leftlon = secLC(0)
1325
+ rightlon = secRC(0)
1326
+
1327
+ ;config
1328
+ pressName = "PS"
1329
+ geopotName = "PHIS"
1330
+ hybCords = (/"hyam","hybm","hyai","hybi"/)
1331
+ hyamName = hybCords(0)
1332
+ hybmName = hybCords(1)
1333
+ hyaiName = hybCords(2)
1334
+ hybiName = hybCords(3)
1335
+
1336
+ nlevels = 47
1337
+ p00 = 1.e3; reference pressure in hPa
1338
+
1339
+
1340
+
1341
+ phis = filehandle->$pressName$(0,:,:) ; dims: (time,lon,lat)
1342
+
1343
+ psfc = filehandle->$pressName$(timestep,:,:) ; surface pressure, dims: (time,lon.lat)
1344
+ psfc = psfc*1.e-2 ; convert to hPa
1345
+ hyam = filehandle->$hyamName$*1.e-2 ; convert to hPa
1346
+ hybm = filehandle->$hybmName$
1347
+ hyai = filehandle->$hyaiName$*1.e-2 ; convert to hPa
1348
+ hybi = filehandle->$hybiName$
1349
+ klevi = dimsizes(hyai) ;
1350
+ klevm = dimsizes(hyam) ;
1351
+
1352
+ ; compute 3d pressure
1353
+ dims = dimsizes(psfc)
1354
+ print("dims:"+str_join((/nlevels, dims(0), dims(1)/),"|"))
1355
+ pres3d = new ((/nlevels, dims(0), dims(1)/),double)
1356
+ pres3di = new ((/nlevels+1,dims(0), dims(1)/),double)
1357
+ theta3d = new ((/nlevels, dims(0), dims(1)/),double)
1358
+ do k = 0, nlevels-1
1359
+ pres3d(k,:,:) = psfc(:,:)*hybm(k) + hyam(k)
1360
+ end do
1361
+ do k = 0, nlevels
1362
+ pres3di(k,:,:) = psfc(:,:)*hybi(k) + hyai(k)
1363
+ end do
1364
+
1365
+ if (False) then ; potential temperature
1366
+ var = var*(p00/pres3d)^(2./7.)
1367
+ end if
1368
+
1369
+ ; plot pressure levels
1370
+ plevs = (ispan(100,1000,25))*1.0
1371
+
1372
+ var_at_p = new ((/dimsizes(plevs),dimsizes(var&lat),dimsizes(var&lon)/),double)
1373
+ copy_VarMeta( theta3d, var_at_p)
1374
+ var_at_p@lon = var&lon
1375
+ var_at_p@lat = var&lat
1376
+ var_at_p@units = var@units
1377
+ var_at_p@long_name = var@long_name
1378
+
1379
+ extrapolate = True ; switch for doing extrapolation below the ground:
1380
+ intmethod = 1 ; 1: method for temperature, -1: method for geopotential, 0: other vars
1381
+ tlow = var(nlevels-1,:,:) ; temperature at lowest model level
1382
+ ; (use ground temperature if available)
1383
+
1384
+ var_at_p = vinth2p_ecmwf(var,hyam,hybm,plevs,pres3di(nlevels,:,:)*100.,\
1385
+ intmethod,1.,1,extrapolate,1,tlow,phis)
1386
+
1387
+ dist = gc_latlon(leftlat,leftlon,rightlat,rightlon,npoints,2)
1388
+ trans = linint2_points_Wrap(var_at_p&lon,var_at_p&lat,var_at_p,True,dist@gclon,dist@gclat,2)
1389
+
1390
+ return trans
1391
+ end
1392
+ ;---------------------------------------------------------------
1393
+ ; setting for vertical cross sections based on pure icon input
1394
+ undef("setSectionFromHybridPressICON")
1395
+ function setSectionFromHybridPressICON(secLC,secRC,npoints,var,filehandle,timestep)
1396
+ begin
1397
+ leftlat = secLC(1)
1398
+ rightlat = secRC(1)
1399
+
1400
+ leftlon = secLC(0)
1401
+ rightlon = secRC(0)
1402
+
1403
+ ;config
1404
+ pressName = "PS"
1405
+ geopotName = "PHIS"
1406
+ hybCords = (/"hyam","hybm","hyai","hybi"/)
1407
+ hyamName = hybCords(0)
1408
+ hybmName = hybCords(1)
1409
+ hyaiName = hybCords(2)
1410
+ hybiName = hybCords(3)
1411
+
1412
+ nlevels = 47
1413
+ plevels = 20
1414
+ p00 = 1.e3; reference pressure in hPa
1415
+ rad2deg = 45./atan(1.) ; radians to degrees
1416
+
1417
+ u3d = var
1418
+ phis = filehandle->$pressName$(0,:); dims: (time,cell)
1419
+ psfc = filehandle->$pressName$(timestep,:); surface pressure, dims: (time,lon.lat)
1420
+ psfc = psfc*1.e-2; convert to hPa
1421
+ hyam = filehandle->$hyamName$*1.e-2; convert to hPa
1422
+ hybm = filehandle->$hybmName$
1423
+ hyai = filehandle->$hyaiName$*1.e-2; convert to hPa
1424
+ hybi = filehandle->$hybiName$
1425
+ klevi = dimsizes(hyai);
1426
+ klevm = dimsizes(hyam);
1427
+
1428
+ ; compute 3d pressure
1429
+ dims = dimsizes(psfc)
1430
+ print("dims:"+str_join((/nlevels, dims/),"|"))
1431
+ pres3d = new ((/nlevels, dims/),double)
1432
+ pres3di = new ((/nlevels+1,dims/),double)
1433
+ theta3d = new ((/nlevels, dims/),double)
1434
+ do k = 0, nlevels-1
1435
+ pres3d(k,:) = psfc(:)*hybm(k) + hyam(k)
1436
+ end do
1437
+ do k = 0, nlevels
1438
+ pres3di(k,:) = psfc(:)*hybi(k) + hyai(k)
1439
+ end do
1440
+
1441
+ theta3d = var
1442
+ theta3d@units="K"
1443
+ theta3d@long_name="Temperature"
1444
+
1445
+ ; if (False) then ; potential temperature
1446
+ ; var = var*(p00/pres3d)^(2./7.)
1447
+ ; end if
1448
+
1449
+ x = filehandle->clon *rad2deg; cell center, lon
1450
+ y = filehandle->clat *rad2deg; cell center, lat
1451
+
1452
+ ylat = fspan(-90,90,91)
1453
+ ylat@units = "degrees_north"
1454
+ xlon = fspan(-180,180,181)
1455
+ xlon@units = "degrees_east"
1456
+ ylat!0 = "ylat"
1457
+ xlon!0 = "xlon"
1458
+
1459
+ u3dll = triple2grid(x,y,u3d,xlon,ylat,False)
1460
+ pres3dll = triple2grid(x,y,pres3d,xlon,ylat,False)
1461
+ pres3dill = triple2grid(x,y,pres3di,xlon,ylat,False)
1462
+ theta3dll = triple2grid(x,y,theta3d,xlon,ylat,False)
1463
+ phisll = triple2grid(x,y,phis,xlon,ylat,False)
1464
+
1465
+ u3dll!1 = "ylat"
1466
+ u3dll!2 = "xlon"
1467
+ u3dll&ylat = ylat
1468
+ u3dll&xlon = xlon
1469
+
1470
+ phisll!0 = "ylat"
1471
+ phisll!1 = "xlon"
1472
+ phisll&ylat = ylat
1473
+ phisll&xlon = xlon
1474
+
1475
+ copy_VarMeta( u3dll, pres3dill)
1476
+ copy_VarMeta( u3dll, pres3dll)
1477
+ copy_VarMeta( u3dll, theta3dll)
1478
+
1479
+ ; now we try to interpolate from model levels to pressure levels
1480
+ plevs = (ispan(100,1000,25))*1.0
1481
+
1482
+ var_at_p = new ((/dimsizes(plevs),dimsizes(ylat),dimsizes(xlon)/),double)
1483
+ copy_VarMeta(u3dll, var_at_p)
1484
+ ; var_at_p@ylat =ylat
1485
+ ; var_at_p@xlon =xlon
1486
+ var_at_p@units = theta3d@units
1487
+ var_at_p@long_name = theta3d@long_name
1488
+
1489
+ extrapolate = True ; switch for doing extrapolation below the ground:
1490
+ intmethod = 1 ; 1: method for temperature, -1: method for geopotential, 0: other vars
1491
+ tlow = theta3dll(nlevels-1,:,:) ; temperature at lowest model level
1492
+ ; (use ground temperature if available)
1493
+
1494
+ var_at_p = vinth2p_ecmwf(theta3dll, hyam, hybm, plevs, pres3dill(nlevels,:,:)*100.,\
1495
+ intmethod,1.,1,extrapolate,1,tlow,phisll)
1496
+ print(min(var_at_p))
1497
+
1498
+ dist = gc_latlon(leftlat,leftlon,rightlat,rightlon,npoints,2)
1499
+ trans = linint2_points_Wrap(xlon,ylat,var_at_p,True,dist@gclon,dist@gclat,2)
1500
+
1501
+ return trans
1502
+ end
1503
+ ;---------------------------------------------------------------
1504
+ ; Create flags array the the grid plot
1505
+ undef("getFlags")
1506
+ function getFlags(var,boundslon,boundslat,resource)
1507
+ begin
1508
+ flags = new(dimsizes(var),logical,"No_FillValue")
1509
+ do i = 0,dimsizes(var) - 1
1510
+ flags(i) = where(all(boundslon(i,:) .gt. resource@mpMaxLonF) .or. \
1511
+ all(boundslon(i,:) .lt. resource@mpMinLonF) .or. \
1512
+ all(boundslat(i,:) .gt. resource@mpMaxLatF) .or. \
1513
+ all(boundslat(i,:) .lt. resource@mpMinLatF), \
1514
+ False, True)
1515
+ end do
1516
+ return flags
1517
+ end
1518
+ ;---------------------------------------------------------------
1519
+ ; Set the default vector plot resource
1520
+ undef("setDefaultVectorPlot")
1521
+ procedure setDefaultVectorPlot(resource, refmagnitude, reflength, style, mindistance)
1522
+ begin
1523
+ resource@vcRefMagnitudeF = refmagnitude ; make vectors larger
1524
+ resource@vcRefLengthF = reflength ; reference vector length
1525
+ resource@vcGlyphStyle = style ; turn on curly vectors
1526
+ resource@vcMinDistanceF = mindistance ; thin out vectors
1527
+ end
1528
+ ;---------------------------------------------------------------
1529
+ ; Return the Colors of a given plot
1530
+ undef("getColorsFromPlot")
1531
+ function getColorsFromPlot(plot)
1532
+ begin
1533
+ getvalues plot@contour
1534
+ "cnFillColors" : colors
1535
+ end getvalues
1536
+ return colors
1537
+ end
1538
+ ;---------------------------------------------------------------
1539
+ ; Return the levels of a given plot
1540
+ undef("getLevelsFromPlot")
1541
+ function getLevelsFromPlot(plot)
1542
+ begin
1543
+ getvalues plot@contour
1544
+ "cnLevels" : levels
1545
+ end getvalues
1546
+ return levels
1547
+ end
1548
+ ;---------------------------------------------------------------
1549
+ ; Print out some information about the grid plot
1550
+ undef("printGridPlotInfo")
1551
+ procedure printGridPlotInfo(colors,levels,flags)
1552
+ begin
1553
+ print(colors)
1554
+ print(levels)
1555
+ print ("Outside the plot area: " + dimsizes(ind(flags .eq. False)) + \
1556
+ " triangles - not plotted")
1557
+ end
1558
+ ;---------------------------------------------------------------
1559
+ ; Create a resource for the grid plot
1560
+ undef("setupGridResource")
1561
+ function setupGridResource(var,levels,colors,boundslon,boundslat,wks,plot,debug)
1562
+ begin
1563
+ pres = True
1564
+ pres@gsEdgesOn = True ; Turn on edges
1565
+ pres@gsFillIndex = 0 ; Solid fill, the default
1566
+
1567
+ ; First draw the triangles associated with the lowest level.
1568
+ i = 0
1569
+ vlow = ind(var .lt. levels(i))
1570
+ ; if no index vlow is found with values less than levels(0), vlow is missing value:
1571
+ if (.not. ismissing(vlow(0))) then
1572
+ do j = 0, dimsizes(vlow)-1
1573
+ pres@gsFillColor = colors(i) ; first color
1574
+ gsn_polygon(wks,plot,boundslon(vlow(j),:),boundslat(vlow(j),:),pres)
1575
+ end do
1576
+ end if
1577
+ if (debug) then
1578
+ print("i=" + i + ", Values smaller than "+levels(i)+": " + dimsizes(vlow) + \
1579
+ " triangles considered, color= " + colors(i))
1580
+ end if
1581
+ delete(vlow)
1582
+
1583
+ ; Now draw the triangles between the lowest and highest levels.
1584
+ do i = 0, dimsizes(levels) -2
1585
+ vind = ind(var .ge. levels(i) .and. var .lt. levels(i+1))
1586
+ ; if no index is found, vind is missing value:
1587
+ if (.not. ismissing(vind(0))) then
1588
+ do j = 0, dimsizes(vind)-1
1589
+ pres@gsFillColor = colors(i+1)
1590
+ gsn_polygon( wks,plot, boundslon(vind(j),:),boundslat(vind(j),:),pres)
1591
+ end do
1592
+ end if
1593
+ if (debug) then
1594
+ print ("i=" + i + ", Values between " + levels(i) + " and " + levels(i+1) +": "\
1595
+ +dimsizes(vind) + " triangles considered, color= " + colors(i+1))
1596
+ end if
1597
+ delete(vind)
1598
+ end do
1599
+
1600
+ ; Finally draw the triangles associated with the highest level.
1601
+ i = dimsizes(levels) -1
1602
+ vhig = ind(var .ge. levels(i) )
1603
+
1604
+ ; if no index vhig is found with values larger levels(max-1), vhig is missing value:
1605
+ if (.not. ismissing(vhig(0))) then
1606
+ do j = 0, dimsizes(vhig) -1
1607
+ pres@gsFillColor = colors(i+1)
1608
+ gsn_polygon( wks,plot, boundslon(vhig(j),:),boundslat(vhig(j),:),pres)
1609
+ end do
1610
+ end if
1611
+ if (debug) then
1612
+ print ("i=" + i + ", Values larger than "+levels(i) +": " \
1613
+ + dimsizes(vhig) + " triangles considered, color= " + colors(i+1))
1614
+ end if
1615
+ delete(vhig)
1616
+
1617
+ return pres
1618
+ end
1619
+ ;---------------------------------------------------------------
1620
+ ; Plot the ICON grid of a variable to the plot.
1621
+ undef("plotGrid")
1622
+ procedure plotGrid(workstation,plot,variable,x,bounds,filehandle,resource,debug)
1623
+ begin
1624
+ boundslon = bounds(0,:,:)
1625
+ boundslat = bounds(1,:,:)
1626
+
1627
+ latmax=flt2dble(0.0)
1628
+ latmin=flt2dble(0.0)
1629
+ lonmax=flt2dble(0.0)
1630
+ lonmin=flt2dble(0.0)
1631
+ setBoundsEnds(boundslon,boundslat,lonmin,lonmax,latmin,latmax)
1632
+ checkLongitude(x,boundslon,lonmin,lonmax,debug)
1633
+
1634
+ flags = getFlags(variable,boundslon,boundslat,resource)
1635
+
1636
+ colors = getColorsFromPlot(plot)
1637
+ levels = getLevelsFromPlot(plot)
1638
+
1639
+ if (debug) printGridPlotInfo(colors,levels,flags) end if
1640
+
1641
+ pres = setupGridResource(variable,levels,colors,boundslon,boundslat,workstation,plot,debug)
1642
+ end
1643
+ ;---------------------------------------------------------------
1644
+ ; read in mask variable
1645
+ undef("readMaskVar")
1646
+ function readMaskVar()
1647
+ begin
1648
+ end
1649
+ ;---------------------------------------------------------------
1650
+ ; plot vector/streamlines to resource
1651
+ undef("plotVecOrStream")
1652
+ function plotVecOrStream(useScalar,useStreamlines,uvar,vvar,scalarvar,resource,workstation,showMap)
1653
+ begin
1654
+ if (useScalar) then
1655
+ if (useStreamlines) then
1656
+ if (showMap)
1657
+ vc = gsn_csm_streamline_contour_map(workstation,uvar,vvar,scalarvar,resource)
1658
+ else
1659
+ vc = gsn_streamline_scalar(workstation,uvar,vvar,scalarvar,resource)
1660
+ end if
1661
+ else
1662
+ if (showMap)
1663
+ vc = gsn_csm_vector_scalar_map(workstation,uvar,vvar,scalarvar,resource)
1664
+ else
1665
+ vc = gsn_csm_vector_scalar(workstation,uvar,vvar,scalarvar,resource)
1666
+ end if
1667
+ end if
1668
+ else
1669
+ if (showMap)
1670
+ if (useStreamlines) then
1671
+ vc = gsn_csm_streamline_map(workstation,uvar,vvar,resource)
1672
+ else
1673
+ vc = gsn_csm_vector_map(workstation,uvar,vvar,resource)
1674
+ end if
1675
+ else
1676
+ if (useStreamlines) then
1677
+ vc = gsn_csm_streamline(workstation,uvar,vvar,resource)
1678
+ else
1679
+ vc = gsn_csm_vector(workstation,uvar,vvar,resource)
1680
+ end if
1681
+ end if
1682
+ end if
1683
+ return vc
1684
+ end
1685
+
1686
+ ;
1687
+ ; vim:list