[ncl-talk] Using WRAPIT with string variables

Dennis Shea shea at ucar.edu
Fri Aug 4 14:16:36 MDT 2017


Yikes!   Right now, I don't have the time to look at this in detail.

NCL and fortran (f77 here) can pass *one* string back and forth but *not*
arrays of strings. Passing arrays of strings between NCL (written in C)
<==>fortran (f77) is not possible. There is not standard for this. This
issue has been noted:  https://www.ncl.ucar.edu/Suppo
rt/talk_archives/2009/0816.html

This has nothing to do with NCL per se. Historically, passing arrays of
strings between fortran and C has been problematical. f95+ has features
that facilitate this. However, NCL's WRAPIT was created well before this
capability was made available.

Your script  passes two* arrays *of type string from a subroutine which
reads the 'character' variables to an NCL script which has pre-allocated
string arrays to capture the character/string values read in fortran.

====
external READ_DATA "./read_sta_data.so"
[SNIP]
       station             = new((/40/),"string")     ; <==== pre-allocated
array of string
       weather_type  = new((/30/),"string")
       READ_DATA::read_sta_data( \
       year, \
       month, \
[SNIP]
       wet_bulb_temp,\
       weather_type, \             ; <==== array of strings
       station, \                        ;               "             "
       n_files)
====

I am not knowledgeable about the reasons why arrays of strings cause
problems. (Nominally) Fortran passes by address while C passes by value
(N'est ce pas?). Perhaps this is one issue issue.

I have a attached a simple example that illustrates what happens when
arrays are passed back and forth betwee NCL and fortran.

===
I note that you have commented the following NCL lines.

; asc_file = "weather_type_old.csv"
; asc_file = "weather_type.csv"
; lines = asciiread(asc_file,-1,"string")
; print(lines)
; delim = ","
; station    = str_get_field(lines,1,delim)
; weather_type    = str_get_field(lines,2,delim)
  print("station = " + station)
  print("weather_type = " + weather_type)

I think you will have to read the string values in NCL directly.

Actually, I would read the whole data set in NCL ... no fortran.

==> Example script

%> WRAPIT str.f

ignore warnings

%> ncl str.ncl

============
%> ncl str.ncl

(0)    NCL: stri=Foo
(0)    NCL: stro=missing
 fortran: strin=Foo
 fortran: strout=FooFoo
(0)    after fortran: stro=FooFoo
(0)
(0)    =========Multiple Strings =================
(0)
(0)    NCL: STRI=Foo1 : STRO=missing
(1)    NCL: STRI=Foo2 : STRO=missing
(2)    NCL: STRI=Foo3 : STRO=missing
(0)
 fortran: nin=           3   nout=           3

 fortran: n=           1  strin(n)=Foo1                 <=== only string
that is 'correct'
 fortran: n=           2  strin(n)=@                      <=== not paseed
correctly
 fortran: n=           3  strin(n)=

 fortran: n=           1  strin(n)=Foo1 strout(n)=Foo1Foo
 fortran: n=           2  strin(n)=@      strout(n)=@
 fortran: n=           3  strin(n)=          strout(n)=
(0)
(0)    after fortran: STRI=Foo1 : STRO=Foo1Foo
(1)    after fortran: STRI=Foo2 : STRO=missing
(2)    after fortran: STRI=Foo3 : STRO=missing


D

On Thu, Aug 3, 2017 at 11:30 PM, Barry Lynn <barry.h.lynn at gmail.com> wrote:

>>  eilat.txt
> <https://drive.google.com/file/d/0B3E3GjUeKpBdWnhCNDhyV1JfalE/view?usp=drive_web>
> ​​
>  get_ij.f
> <https://drive.google.com/file/d/0B3E3GjUeKpBdY2FjVWMyLTRlSTg/view?usp=drive_web>
> ​​
>  get_ij_land.f
> <https://drive.google.com/file/d/0B3E3GjUeKpBdaWxiSGFOdzF5RVU/view?usp=drive_web>
> ​​
>  jerusalem.txt
> <https://drive.google.com/file/d/0B3E3GjUeKpBdZXBXNnl6QU5DQWM/view?usp=drive_web>
> ​​
>  katzrin.txt
> <https://drive.google.com/file/d/0B3E3GjUeKpBdeDIyUWZ2c05Yd28/view?usp=drive_web>
> ​​
>  map_sta_data.ncl
> <https://drive.google.com/file/d/0B3E3GjUeKpBdQURiNTR5UHlsckk/view?usp=drive_web>
> ​​
>  read_sta_data.f
> <https://drive.google.com/file/d/0B3E3GjUeKpBdSXkxcjdTR2d0U2s/view?usp=drive_web>
> ​​
>  shlomi.txt
> <https://drive.google.com/file/d/0B3E3GjUeKpBdSGhoMVd3aW9hejA/view?usp=drive_web>
> ​​
>  tel_aviv.txt
> <https://drive.google.com/file/d/0B3E3GjUeKpBdZ2RpY01RWjZnTkE/view?usp=drive_web>
> ​​
>  wrfinput_d02
> <https://drive.google.com/file/d/0B3E3GjUeKpBdNmhpUHo4R2lCNTQ/view?usp=drive_web>
> ​Hi Dennis:
>
> Thank you for looking at this.
>
> I am running into some problems.
>
> 1) I can define my variables within the *.f program as you indicated, but
> each of them must have n_files elements.  WRAPIT read_sta_data.f compiles.
>
> 2) If I don't try to return to my ncl program, then I can write all array
> element of  these variables to a csv file, but they are truncated to seven
> elements.  Both the name and weather type no longer write out more than
> seven elements.
>
> 3) If I try to return to the NCL program (remove the "stop" at the end of
> the *.f program), I get a memory error.
>
> 4) I am not sure the cause of 2 (when I had defined the station and
> weather_type variables as *40, I had no problem writing complete variable
> to the weather_type.csv file (which I shouldn't need any more, since we're
> suppose to pass the variables back).
>
> 5) Regarding the memory error, I am probably not defining string correctly
> for an array.
>
> Here is part of the memory error.  Programs, files attached.
>
> *** Error in `ncl': double free or corruption (out): 0x000000000c8637a0 ***
>
> ======= Backtrace: =========
>
> /usr/lib64/libc.so.6(+0x7d1fd)[0x2ba528ed61fd]
>
> ./read_sta_data.so(read_sta_data_+0x4fb3)[0x2ba52b48e60c]
>
> ./read_sta_data.so(read_sta_data_W+0xb3c)[0x2ba52b488d04]
>
> ncl(CallINTRINSIC_PROC_CALL+0x43)[0x8a282f]
>
> ncl(_NclExecute+0x419)[0x8aa685]
>
> ncl(yyparse+0x82c)[0x772f2e]
>
> ncl(NclDriver+0xc19)[0x76eec7]
>
> ncl(main+0x9)[0x76b4bd]
>
> /usr/lib64/libc.so.6(__libc_start_main+0xf5)[0x2ba528e7aaf5]
>
> ncl[0x76b3f9]
>
> Thanks.
>
> On Wed, Aug 2, 2017 at 5:27 PM, Dennis Shea <shea at ucar.edu> wrote:
>
>> You can pass strings to and from fortran subroutines.
>>
>> ============= test fortran subroutine: str.f
>> C NCLFORTSTART
>>       subroutine teststr(strin,strout)
>>       implicit none
>>       character*(*) strin, strout
>> C NCLEND
>>
>>       print *,"fortran: strin=",strin
>>
>>       strout = strin // strin         ! create return string
>>
>>       print *, "fortran: strout=", strout
>>
>>       return
>>       end
>> =========================Create str.so
>> %> WRAPIT str.f
>>
>> There will be some warning messages
>>
>> ============== NCL script: str.ncl
>> external STRING "./str.so"
>>
>>   stri = "Foo"                          ; input
>>   stro = new( 1, "string")        ; reserve space for return string
>>
>>   STRING::teststr(stri, stro)
>>
>>   print("after fortran: stro="+stro)
>>
>> =============
>> %> ncl str.ncl
>>
>> =============output
>>
>>  fortran: strin=Foo
>>  fortran: strout=FooFoo
>> (0)    after fortran: stro=FooFoo
>>
>>
>>
>> On Wed, Aug 2, 2017 at 6:13 AM, Barry Lynn <barry.h.lynn at gmail.com>
>> wrote:
>>
>>> Hi:
>>>
>>> As you may have read before, you can't pass string variables through the
>>> subroutine call using WRAPIT.  Perhaps you could pass a single character,
>>> but I am not sure.
>>>
>>> There is a simple way around this.
>>>
>>> One can produce a csv file through a simple write statement in the *.f
>>> program.  Then, open the file in ncl.
>>>
>>> A one line output (here).
>>>
>>>  Tel Aviv University           ,  Mostly Sunny       ,
>>>
>>> Then, you can read it in the ncl program this way.
>>>
>>>   asc_file = "weather_type.csv"
>>>
>>>   lines = asciiread(asc_file,-1,"string")
>>>
>>>   print(lines)
>>>
>>>   delim = ","
>>>
>>>   station    = str_get_field(lines,1,delim)
>>>
>>>   weather_type    = str_get_field(lines,2,delim)
>>>
>>>   print("station = " + station)
>>>
>>>   print("weather_type = " + weather_type)
>>>
>>>
>>> Just in case you want to read in a real value, you can do the following.
>>>
>>> Latitude = tofloat(str_get_field(lines,2,delim))
>>>
>>> )
>>>
>>>
>>>
>>> --
>>> Barry H. Lynn, Ph.D
>>> Senior Lecturer,
>>> The Institute of the Earth Science,
>>> The Hebrew University of Jerusalem,
>>> Givat Ram, Jerusalem 91904, Israel
>>> Tel: 972 547 231 170
>>> Fax: (972)-25662581
>>>
>>> C.E.O, Weather It Is, LTD
>>> Weather and Climate Focus
>>> http://weather-it-is.com
>>> Jerusalem, Israel
>>> Local: 02 930 9525
>>> Cell: 054 7 231 170
>>> Int-IS: x972 2 930 9525
>>> US 914 432 3108 <(914)%20432-3108>
>>>
>>> _______________________________________________
>>> ncl-talk mailing list
>>> ncl-talk at ucar.edu
>>> List instructions, subscriber options, unsubscribe:
>>> http://mailman.ucar.edu/mailman/listinfo/ncl-talk
>>>
>>>
>>
>
>
> --
> Barry H. Lynn, Ph.D
> Senior Lecturer,
> The Institute of the Earth Science,
> The Hebrew University of Jerusalem,
> Givat Ram, Jerusalem 91904, Israel
> Tel: 972 547 231 170
> Fax: (972)-25662581
>
> C.E.O, Weather It Is, LTD
> Weather and Climate Focus
> http://weather-it-is.com
> Jerusalem, Israel
> Local: 02 930 9525
> Cell: 054 7 231 170
> Int-IS: x972 2 930 9525
> US 914 432 3108 <(914)%20432-3108>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mailman.ucar.edu/pipermail/ncl-talk/attachments/20170804/92d2d128/attachment.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: str.ncl
Type: application/octet-stream
Size: 696 bytes
Desc: not available
Url : http://mailman.ucar.edu/pipermail/ncl-talk/attachments/20170804/92d2d128/attachment.obj 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: str.f
Type: application/octet-stream
Size: 919 bytes
Desc: not available
Url : http://mailman.ucar.edu/pipermail/ncl-talk/attachments/20170804/92d2d128/attachment-0001.obj 


More information about the ncl-talk mailing list