MDSplus / mdsplus

The MDSplus data management system
https://mdsplus.org/
Other
74 stars 44 forks source link

Can not store array of nids in a numeric node #2575

Open joshStillerman opened 1 year ago

joshStillerman commented 1 year ago

Affiliation MIT Plasma Fusion Center

Version(s) Affected

ALL ?

Platform Linux / Ubuntu

Describe the bug Given a numeric node, can not put array of nids into a numeric node using python. This works fine from TCL.

Really need to be able to make a TreeNodeArray from an array of nodes. The closest I have come to it is to make something that thinks it is a TreeNodeArray but its elements are the integer NIDs of nodes.

To Reproduce

$ python3
Python 3.8.10 (default, Mar 13 2023, 10:26:41) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from MDSplus import Tree
>>> t = Tree('testing', -1, 'new')
>>> t.addNode('targ', 'NUMERIC')
TARG
>>> t.addNode('one', 'NUMERIC')
ONE
>>> t.TARG.record = [t.ONE]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/mdsplus/python/MDSplus/tree.py", line 1639, in __setattr__
    super(TreeNode, self).__setattr__(name, value)
  File "/usr/local/mdsplus/python/MDSplus/tree.py", line 1535, in record
    self.putData(value)
  File "/usr/local/mdsplus/python/MDSplus/tree.py", line 2687, in putData
    _exc.checkStatus(
  File "/usr/local/mdsplus/python/MDSplus/mdsExceptions.py", line 94, in checkStatus
    raise exception
MDSplus.mdsExceptions.TreeINVDTPUSG: %TREE-E-INVDTPUSG, Attempt to store datatype which conflicts with the designated usage of this node
>>> t.write()
>>> 
jas@sdn-1:~/data_contracts$ mdstcl
TCL> set tree testing
TCL> dir

\TESTING::TOP

 :ONE          :TARG        

Total of 2 nodes.
TCL> put targ "[ONE]"
TCL> dir /full targ

\TESTING::TOP

 :TARG        
      Status: on,parent is on, usage numeric
      compress on put
      contains node references (node ids only)
      Data inserted: 17-MAY-2023 14:56:12.32    Owner: uid=1004(jas)
      Dtype: DTYPE_FUNCTION        Class: CLASS_R             Length: 54 bytes

Total of 1 node.
TCL> deco targ
[ONE]
TCL> 

Expected behavior Expect to be able to write the same data with python that I can write with other tools

Screenshots If applicable, add screenshots to help explain your problem.

Additional context Add any other context about the problem here.

joshStillerman commented 1 year ago

Turns out it does not like records which are Python Lists.

Given a tree t and a numeric node NUM the following happens:

>>> t.NUM.record = 1
>>> t.NUM.record = [1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/mdsplus/python/MDSplus/tree.py", line 1639, in __setattr__
    super(TreeNode, self).__setattr__(name, value)
  File "/usr/local/mdsplus/python/MDSplus/tree.py", line 1535, in record
    self.putData(value)
  File "/usr/local/mdsplus/python/MDSplus/tree.py", line 2687, in putData
    _exc.checkStatus(
  File "/usr/local/mdsplus/python/MDSplus/mdsExceptions.py", line 94, in checkStatus
    raise exception
MDSplus.mdsExceptions.TreeINVDTPUSG: %TREE-E-INVDTPUSG, Attempt to store datatype which conflicts with the designated usage of this node
>>> t.NUM.record = MDSplus.Array([1])

I wonder if we check if the argument is a list and if so ask MDSplus to make an array of it and failing that ask MDSplus to make an APD of it ?

Then we could have the behavior:

>>> t.NUM.record = MDSplus.Apd([1, 'aa'])
>>> t.NUM.data()
array([1, 'aa'], dtype=object)
>>> t.NUM.record = MDSplus.Array([1])
>>> t.NUM.data()
array([1])
>>> 
zack-vii commented 1 year ago

The idea was to map python list to List and python dict to Dict.

As you can see from the datatype you are not storing a NIDArray but rather a VECTOR function with one argument (the nid ONE). In python you achieve the same with t.TARG.record = MDSplus.VECTOR(t.ONE).

You will find that t.TARG.record = MDSplus.Array(t.ONE) will fail as ONE is resolved first and has no data.