iconPlot 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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