[ncl-talk] Function return

Prashanth Bhalachandran prashanth.bhalachandran at gmail.com
Sat Oct 14 14:36:45 MDT 2017


Alan, 
I give the filename and time as an input argument. The code now works where I define every other array except for the wnout array (the return from the function). The whole code is pasted here. The filename and time actually come from my shell script. But for debugging, I am giving it as an input argument. You were right in that wnout array does not need any prior definition. But the rest of them do, it seems. 

ncl 'filename = "20141009.nc"' 'time=24' varcalc.ncl
 Copyright (C) 1995-2017 - All Rights Reserved
 University Corporation for Atmospheric Research
 NCAR Command Language Version 6.4.0
 The use of this software is governed by a License Agreement.
 See http://www.ncl.ucar.edu/ for more details.

Variable: wnout
Type: list <fifo>
Total items: 2


;;;;;;;;;;;;;;;;;;;;;;;;  varcalc.ncl ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;  

 load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"
 load "/scratch/lustreD/s/sbhalach/DATA/func_center.ncl"
 load "/scratch/lustreD/s/sbhalach/DATA/func_rtheta.ncl"

 a = addfile(filename,"r")
 u10 = a->u10
 v10 = a->v10
 slp = a->slp

;;;;;;;;;;;;;;;;; Constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 R         = 6371 
 d2r       = atan(1.0)/45; Equivalent of pi/180 - 0.01745329
 r2d       = 1.0/d2r
 toknots   = 1.94384
 pi        = 3.14159

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  latvals   = new((/801/),float,1e+30)
  lonvals   = new((/810/),float,1e+30)
  speed     = new((/801,810/),float,1e+30)  
  var01     = new((/251,73/),float,1e+30)
  var0      = new((/251/),float,1e+30)


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 slpsub       = slp(time,0,:,:) ; X is now a 2D array
 speed(:,:)   = wind_speed(u10(time,0,:,:),v10(time,0,:,:)) * toknots
 latvals(:)   = u10&lat(0:800)
 lonvals(:)   = u10&lon(0:809)

 coord        = center_find(speed(:,:),slpsub) 
 lat1         = coord[0]
 lon1         = coord[1]

 wnout        = wn01(latvals,lonvals,lat1,lon1,speed)   
 var0         = wnout[0] 
 var1         = wnout[1]  
 
;;;;;;;;;;;;;;;;;;;;; FUNCTION (func_rtheta.ncl) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"
load "/scratch/lustreD/s/sbhalach/DATA/func_center.ncl"


undef("wn01")

 function wn01(latvals:float,lonvals:float,lat1:float,lon1:float,var:float)
 local R,d2r,r2d,toknots,pi,delr,Xi,Yi,xo,yo,nearxo,nearyo,ovar,var01,var0,c1,b1,orad,otha,arr,a1,a2,a3,a4,a5,a6,a7,a8,a9,r,weights 

 begin 

 R         = 6371 
 d2r       = atan(1.0)/45; Equivalent of pi/180 or 0.01745329
 r2d       = 1.0/d2r
 toknots   = 1.94384
 pi        = 3.14159 
 delr      = 12

 Xi        = new((/810/),float,1e+30)
 Yi        = new((/801/),float,1e+30)
 ovar      = new((/251,73/),float,1e+30)  
 var01     = new((/251,73/),float,1e+30)
 var0      = new((/251/),float,1e+30)
 c1        = new((/251/),float,1e+30)
 b1        = new((/251/),float,1e+30)
 orad      = ispan(0,1000,delr)
 otha      = fspan(0,6.283185,73)
 arr       = new((/3,3/),float,1e+30)  

 Xi(:) = R *cos(lat1*d2r)*(lonvals(:)-lon1) * d2r
 Yi(:) = R *(latvals(:)-lat1) * d2r
 
 do radius=0,250,1 
  do theta=0,72,1   

    xo  = (radius*delr)*cos((theta*5)*d2r)   ; reference points 
    yo  = (radius*delr)*sin((theta*5)*d2r)   ; reference points
  
    nearxo = ind_nearest_coord (xo, Xi(:), 0)  ;Find the index of the bounds
    nearyo = ind_nearest_coord (yo, Yi(:), 0) 

    if(nearxo .eq. 0 .or. nearxo .eq. 809 .or. nearyo .eq. 0 .or. nearyo .eq. 800) then
    ovar(radius,theta) = var(nearyo,nearxo)

  else
   a1 = var(nearyo+1,nearxo+1)
   a2 = var(nearyo+1,nearxo)
   a3 = var(nearyo-1,nearxo-1)
   a4 = var(nearyo,nearxo+1)
   a5 = var(nearyo,nearxo)
   a6 = var(nearyo,nearxo-1)
   a7 = var(nearyo-1,nearxo+1)
   a8 = var(nearyo-1,nearxo)
   a9 = var(nearyo-1,nearxo-1)

   arr = (/ (/a1,a2,a3/), (/a4,a5,a6/), (/a7,a8,a9/)/)   ; Written as nD arrays for visual clarity of neighbors

   weights = (/ (/0.0625,0.0625,0.0625/), (/0.0625,0.5,0.0625/), (/0.0625,0.0625,0.0625/)/) 
   ovar(radius,theta) =  dim_avg_wgt(ndtooned(arr),ndtooned(weights),1)  

;  Give 50% weight to the nearest location and distribute the other 50% equally amongst the neighbours  
   end if

  end do ; Loop over every radius and theta 
 end do    ; End of r-theta loop

  do r=0,250,1 
     var0(r)    =  1/(2*pi)*simpeq(ovar(r,:),5.0*d2r) 
     c1(r)      =  1/(2*pi)*simpeq(ovar(r,:)*cos(otha),5.0*d2r)
     b1(r)      =  1/(2*pi)*simpeq(ovar(r,:)*sin(otha),5.0*d2r)
     var01(r,:) =  var0(r) + (c1(r)*cos(otha)) + (b1(r)*sin(otha))
  end do    


 return([/var0,var01/])
 end 





> On Oct 14, 2017, at 1:27 PM, Alan Brammer <abrammer at albany.edu> wrote:
> 
> Would probably be best to attach varcalc.ncl so we can see the whole script. 
> 
>  The edited code I sent back to you should not create those errors if you have defined time somewhere.  Otherwise there will have been an initial error saying that time was not defined, which then cascades down the code.  Previously, the code will have continued but with the empty arrays but doing effectively nothing. 
> 
> Always start with the first error. 
> 
> 
> 
> On Sat, Oct 14, 2017 at 4:13 PM, Prashanth Bhalachandran <prashanth.bhalachandran at gmail.com <mailto:prashanth.bhalachandran at gmail.com>> wrote:
> Dear Alan, 
> Unfortunately, I get a series of fatal errors if I don’t define them apriori. 
> 
> fatal:Undefined identifier: (speed) is undefined, can't continue
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 32 in file varcalc.ncl
> 
> fatal:Undefined identifier: (latvals) is undefined, can't continue
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 33 in file varcalc.ncl
> 
> fatal:Undefined identifier: (lonvals) is undefined, can't continue
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 34 in file varcalc.ncl
> 
> fatal:Undefined identifier: (speed) is undefined, can't continue
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 36 in file varcalc.ncl
> 
> fatal:Undefined identifier: (coord) is undefined, can't continue
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 37 in file varcalc.ncl
> 
> fatal:Undefined identifier: (coord) is undefined, can't continue
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 38 in file varcalc.ncl
> 
> fatal:Variable (latvals) is undefined
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 42 in file varcalc.ncl
> 
> fatal:Undefined identifier: (wnout) is undefined, can't continue
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 43 in file varcalc.ncl
> 
> fatal:Undefined identifier: (wnout) is undefined, can't continue
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 44 in file varcalc.ncl
> 
> fatal:Variable (var0) is undefined
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 45 in file varcalc.ncl
> 
> fatal:Variable (var1) is undefined
> fatal:["Execute.c":8640]:Execute: Error occurred at or near line 46 in file varcalc.ncl
> 
> 
>> On Oct 14, 2017, at 12:44 PM, Alan Brammer <abrammer at albany.edu <mailto:abrammer at albany.edu>> wrote:
>> 
>> > I don’t know what my dimensions of wnout will be. Will it be a 251x251x73 array? 
>> 
>> It will​ be a list, there won't be array dimensions.  You do not need to define wnout before hand. 
>> likewise, you do not need to define ​var0 or var1 before hand.  
>> 
>> e.g.
>> 
>> 
>>  a = addfile(filename,"r")
>>  u10 = a->u10
>>  v10 = a->v10
>>  slp = a->slp
>> 
>> ;;;;;;;;;;;;;;;;; Constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> 
>>  R         = 6371 
>>  d2r       = atan(1.0)/45; Equivalent of pi/180 - 0.01745329
>>  r2d       = 1.0/d2r
>>  toknots   = 1.94384
>>  pi        = 3.14159
>> 
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> 
>> ;; this section wasn't really needed
>> 
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> 
>>  slpsub    = slp(time,0,:,:) ; X is now a 2D array
>>  speed     = wind_speed(u10(time,0,:,:),v10(time,0,:,:)) * toknots
>>  latvals   = u10&lat(0:800)
>>  lonvals   = u10&lon(0:809)
>> 
>>  coord        = center_find(speed(:,:),slpsub) 
>>  lat1         = coord[0]
>>  lon1         = coord[1]
>> 
>> ;;;;;;;;;;;;;; Find all variables here and store into allvars ;;;;;;;
>> 
>>  wnout        = wn01(latvals,lonvals,lat1,lon1,speed)   
>>  var0         = wnout[0] 
>>  var1         = wnout[1]  
>> 
>> printVarSummary(var0)
>> printVarSummary(var1)
>> 
>> ;;;;;;;;;;;;;;;;;;;;;; Write to a netcdf file ;;;;;;;;;;;;;;;;;;
>> 
>> ;;;;   I do not think the lines that were here will work. 
>> 
>> On Sat, Oct 14, 2017 at 10:26 AM, Prashanth Bhalachandran <prashanth.bhalachandran at gmail.com <mailto:prashanth.bhalachandran at gmail.com>> wrote:
>> Dear Marston, 
>> Thank you for your response. I will ensure that the missing values are the default ones from NCL. I hope my attaching the code will give you a little more context. 
>> 
>> My concern is this : If I am returning two arrays var0  and var01 (please see the red highlighted portions for array dimensions), how will I receive it in the main wrapper script? 
>> 
>> That is, if my var0 dimension is : (/251/) and my var01 dimension is (/251,73/), and I return the variable from the function using return([/var0,var01/]), when I collect it in the wrapper script using  
>> wnout        = wn01(latvals,lonvals,lat1,lon1,speed), 
>> 
>> I don’t know what my dimensions of wnout will be. Will it be a 251x251x73 array? I do know that I want to extract it as: 
>>  var0         = wnout[0] 
>>  var1         = wnout[1]    
>>  
>> 
>> CODE 
>> 
>>  load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"
>>  load "/scratch/lustreD/s/sbhalach/DATA/func_center.ncl"
>>  load "/scratch/lustreD/s/sbhalach/DATA/func_rtheta.ncl"
>> 
>>  a = addfile(filename,"r")
>>  u10 = a->u10
>>  v10 = a->v10
>>  slp = a->slp
>> 
>> ;;;;;;;;;;;;;;;;; Constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> 
>>  R         = 6371 
>>  d2r       = atan(1.0)/45; Equivalent of pi/180 - 0.01745329
>>  r2d       = 1.0/d2r
>>  toknots   = 1.94384
>>  pi        = 3.14159
>> 
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> 
>>  latvals   = new((/801/),float,1e+30)
>>  lonvals   = new((/810/),float,1e+30)
>>  speed     = new((/801,810/),float,1e+30)  
>>  var01     = new((/251,73/),float,1e+30)
>>  var0      = new((/251/),float,1e+30)
>>  
>> 
>> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
>> 
>>  slpsub       = slp(time,0,:,:) ; X is now a 2D array
>>  speed(:,:)   = wind_speed(u10(time,0,:,:),v10(time,0,:,:)) * toknots
>>  latvals(:)   = u10&lat(0:800)
>>  lonvals(:)   = u10&lon(0:809)
>> 
>>  coord        = center_find(speed(:,:),slpsub) 
>>  lat1         = coord[0]
>>  lon1         = coord[1]
>> 
>> ;;;;;;;;;;;;;; Find all variables here and store into allvars ;;;;;;;
>> 
>>  wnout        = wn01(latvals,lonvals,lat1,lon1,speed)   
>>  var0         = wnout[0] 
>>  var1         = wnout[1]  
>> 
>> ;;;;;;;;;;;;;;;;;;;;;; Write to a netcdf file ;;;;;;;;;;;;;;;;;;
>> 
>>  system("rm -f $f1_$f2.nc <http://f2.nc/>")
>>  ncdf = addfile("$f1_$f2.nc <http://f2.nc/>","c")
>>  ncdf->allvars = allvars
>>  ncdf->yymmdd  = $f1
>>  ncdf->time    = $f2
>>  
>> -------------------------------------------------------------------
>> 
>> FUNCTION 
>> 
>> load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"
>> load "/scratch/lustreD/s/sbhalach/DATA/func_center.ncl"
>> 
>> 
>> undef("wn01")
>> 
>>  function wn01(latvals:float,lonvals:float,lat1:float,lon1:float,var:float)
>>  local R,d2r,r2d,toknots,pi,delr,Xi,Yi,xo,yo,nearxo,nearyo,ovar,var01,var0,c1,b1,orad,otha,arr,a1,a2,a3,a4,a5,a6,a7,a8,a9,r,weights 
>> 
>>  begin 
>> 
>>  R         = 6371 
>>  d2r       = atan(1.0)/45; Equivalent of pi/180 or 0.01745329
>>  r2d       = 1.0/d2r
>>  toknots   = 1.94384
>>  pi        = 3.14159 
>>  delr      = 12
>> 
>>  Xi        = new((/810/),float,1e+30)
>>  Yi        = new((/801/),float,1e+30)
>>  ovar      = new((/251,73/),float,1e+30)  
>>  var01     = new((/251,73/),float,1e+30)
>>  var0      = new((/251/),float,1e+30)
>>  c1        = new((/251/),float,1e+30)
>>  b1        = new((/251/),float,1e+30)
>>  orad      = ispan(0,1000,delr)
>>  otha      = fspan(0,6.283185,73)
>>  arr       = new((/3,3/),float,1e+30)  
>> 
>>  Xi(:) = R *cos(lat1*d2r)*(lonvals(:)-lon1) * d2r
>>  Yi(:) = R *(latvals(:)-lat1) * d2r
>>  
>>  do radius=0,250,1 
>>   do theta=0,72,1   
>> 
>>     xo  = (radius*delr)*cos((theta*5)*d2r)   ; reference points 
>>     yo  = (radius*delr)*sin((theta*5)*d2r)   ; reference points
>>   
>>     nearxo = ind_nearest_coord (xo, Xi(:), 0)  ;Find the index of the bounds
>>     nearyo = ind_nearest_coord (yo, Yi(:), 0) 
>> 
>>     if(nearxo .eq. 0 .or. nearxo .eq. 809 .or. nearyo .eq. 0 .or. nearyo .eq. 800) then
>>     ovar(radius,theta) = var(nearyo,nearxo)
>> 
>>   else
>>    a1 = var(nearyo+1,nearxo+1)
>>    a2 = var(nearyo+1,nearxo)
>>    a3 = var(nearyo-1,nearxo-1)
>>    a4 = var(nearyo,nearxo+1)
>>    a5 = var(nearyo,nearxo)
>>    a6 = var(nearyo,nearxo-1)
>>    a7 = var(nearyo-1,nearxo+1)
>>    a8 = var(nearyo-1,nearxo)
>>    a9 = var(nearyo-1,nearxo-1)
>> 
>>    arr = (/ (/a1,a2,a3/), (/a4,a5,a6/), (/a7,a8,a9/)/)   ; Written as nD arrays for visual clarity of neighbors
>> 
>>    weights = (/ (/0.0625,0.0625,0.0625/), (/0.0625,0.5,0.0625/), (/0.0625,0.0625,0.0625/)/) 
>>    ovar(radius,theta) =  dim_avg_wgt(ndtooned(arr),ndtooned(weights),1)  
>> 
>> ;  Give 50% weight to the nearest location and distribute the other 50% equally amongst the neighbours  
>>    end if
>> 
>>   end do ; Loop over every radius and theta 
>>  end do    ; End of r-theta loop
>> 
>>   do r=0,250,1 
>>      var0(r)    =  1/(2*pi)*simpeq(ovar(r,:),5.0*d2r)                    ; Dimension (/251/)
>>      c1(r)      =  1/(2*pi)*simpeq(ovar(r,:)*cos(otha),5.0*d2r)
>>      b1(r)      =  1/(2*pi)*simpeq(ovar(r,:)*sin(otha),5.0*d2r)
>>      var01(r,:) =  var0(r) + (c1(r)*cos(otha)) + (b1(r)*sin(otha))	 ; Dimension (/251,73/)
>>   end do    
>>  return([/var0,var01/])
>> 
>>  end 
>> 
>> 
>> 
>>> On Oct 14, 2017, at 12:42 AM, Marston Johnston <shejo284 at gmail.com <mailto:shejo284 at gmail.com>> wrote:
>>> 
>>> There is an error in your code:        var0 = new((/251/),float,1e+30
>>> As a preference, I always find it best to use the default FillValues when creating arrays. Read up on missing values/fillvalues on the NCL wedpage.
>>>  
>>> There is nothing wrong with returning a list from a function, even if the dimensions are different. Why would the dimensions matter?
>>> This doesn’t seem to be your problem. You have not provided enough information about your code and variable information (printVarSumary) to give a definite answer.
>>> It seems you need to do some more debugging of your code yourself.
>>>  
>>> When defining functions, it is good practice to set the define the intrinsic variables as “local” as well as using the “undef” function. 
>>> Using the same name for the variables inside and outside the function, if you are indeed using a function that is properly designed, can mask a bug in your code. 
>>>  
>>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>> Marston S. Ward, PhD
>>> Department of Earth Sciences
>>> University of Gothenburg, Sweden
>>> Email: marston.johnston at gu.se <mailto:marston.johnston at gu.se>
>>> SkypeID: marston.johnston 
>>> Phone: +46-31-7864901 <tel:+46%2031%20786%2049%2001> 
>>> Only the fruitful thing is true!
>>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>>>  
>>>  
>>> From: ncl-talk <ncl-talk-bounces at ucar.edu <mailto:ncl-talk-bounces at ucar.edu>> on behalf of Prashanth Bhalachandran <prashanth.bhalachandran at gmail.com <mailto:prashanth.bhalachandran at gmail.com>>
>>> Date: Saturday, 14 October 2017 at 03:57
>>> To: <ncl-talk at ucar.edu <mailto:ncl-talk at ucar.edu>>
>>> Subject: Re: [ncl-talk] Function return
>>>  
>>> Hello, 
>>> I have a quick question regarding returning of arrays from functions. 
>>>  
>>> In my code, I have two arrays var0 and var01 that I want to return from my function. Their dimensionalities are as follows: 
>>> 
>>> 
>>> var0      = new((/251/),float,1e+30
>>> var01     = new((/251,73/),float,1e+30)
>>>      
>>>  
>>> At present, I am trying to return this using the command : 
>>>  
>>> return([/var0,var01/]) ; Note that the dimensions of var0 and var1 are different. 
>>> 
>>> 
>>> As a result, in my wrapper script, when I receive the variables, it is becoming a confusing task. 
>>> 
>>> 
>>>  wnout        = wn01(latvals,lonvals,lat1,lon1,speed)   
>>>  var0         = wnout[0] 
>>>  var1         = wnout[1]  
>>> 
>>> 
>>>  The above return procedure is giving out an error since I don’t know how to define the dimensions of wnout. Is there any better way to return two arrays of varying dimensions in NCL? 
>>> 
>>> 
>>> Thank you, 
>>> Prashanth  
>>> _______________________________________________ ncl-talk mailing list ncl-talk at ucar.edu <mailto:ncl-talk at ucar.edu> List instructions, subscriber options, unsubscribe: http://mailman.ucar.edu/mailman/listinfo/ncl-talk <http://mailman.ucar.edu/mailman/listinfo/ncl-talk>
>> 
>> _______________________________________________
>> ncl-talk mailing list
>> ncl-talk at ucar.edu <mailto:ncl-talk at ucar.edu>
>> List instructions, subscriber options, unsubscribe:
>> http://mailman.ucar.edu/mailman/listinfo/ncl-talk <http://mailman.ucar.edu/mailman/listinfo/ncl-talk>
>> 
>> 
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.ucar.edu/pipermail/ncl-talk/attachments/20171014/54eab695/attachment-0001.html>


More information about the ncl-talk mailing list