@@ -1577,6 +1577,142 @@ def SetStatusLine(text):
15771577 def OnShowISODISTORT (event ):
15781578 ShowIsoDistortCalc (G2frame )
15791579
1580+ def ExportConstraints (event ):
1581+ import datetime
1582+ G2frame = wx .GetApp ().GetTopWindow ()
1583+ sub = G2gd .GetGPXtreeItemId (G2frame ,G2frame .root ,'Constraints' )
1584+ Constraints = G2frame .GPXtree .GetItemPyData (sub )
1585+ text = f'# Constraints from { G2frame .GSASprojectfile } on '
1586+ text += datetime .datetime .strftime (datetime .datetime .now (),
1587+ "%Y-%m-%dT%H:%M\n " )
1588+ for key in 'Hist' , 'HAP' , 'Phase' :
1589+ for c in Constraints [key ]:
1590+ s = ''
1591+ for i0 ,i1 in c [:- 3 ]:
1592+ if c [- 1 ] == 'e' and s :
1593+ s += ' = '
1594+ elif c [- 1 ] == 'h' and s : # unexpected, should be 1 hold per constraint
1595+ s += ' = '
1596+ elif s :
1597+ s += ' + '
1598+ if c [- 1 ] == 'h' :
1599+ s += f'{ i1 } '
1600+ else :
1601+ s += f'{ i0 } * { i1 } '
1602+ if c [- 1 ] == 'c' :
1603+ s = f'Equation & { s } = { c [- 3 ]} '
1604+ elif c [- 1 ] == 'e' :
1605+ s = f'Equivalence & { s } '
1606+ elif c [- 1 ] == 'h' :
1607+ s = f'Hold & { s } '
1608+ elif c [- 1 ] == 'f' :
1609+ if c [- 3 ]: # prefix by var name, if present
1610+ s = f'{ c [- 3 ]} & { s } '
1611+ if c [- 2 ]: # vary flag
1612+ s = s + ' & varied'
1613+ s = f'NewVar & { s } '
1614+ else : # unexpected!
1615+ print ('Unknown constraint:' ,c )
1616+ continue
1617+ text += s + '\n '
1618+
1619+ f = G2G .askSaveFile (G2frame ,'Constraints' ,'.constr' ,'text constraints file' )
1620+ with open (f ,'w' ) as fp :
1621+ fp .write (text )
1622+ print (f'Constraints written to file { fp .name } ' )
1623+
1624+ def var2key (varObj ):
1625+ if varObj .phase and varObj .histogram :
1626+ return 'HAP'
1627+ elif varObj .phase :
1628+ return 'Phase'
1629+ elif varObj .histogram :
1630+ return 'Hist'
1631+ else :
1632+ return 'Global'
1633+
1634+ def ImportConstraints (event ):
1635+ G2frame = wx .GetApp ().GetTopWindow ()
1636+ sub = G2gd .GetGPXtreeItemId (G2frame ,G2frame .root ,'Constraints' )
1637+ Constraints = G2frame .GPXtree .GetItemPyData (sub )
1638+ dlg = wx .FileDialog (G2frame , 'Select a text file with constraints to read' ,
1639+ style = wx .FD_DEFAULT_STYLE | wx .FD_FILE_MUST_EXIST ,
1640+ wildcard = "constraints|*.constr" )
1641+ try :
1642+ res = dlg .ShowModal ()
1643+ if res != wx .ID_OK : return
1644+ f = dlg .GetPath ()
1645+ finally :
1646+ dlg .Destroy ()
1647+ if not os .path .exists (f ):
1648+ print (f'Strange, { f } not found' )
1649+ return
1650+ txt = open (f ,'r' ).readlines ()
1651+ for i ,line in enumerate (txt ):
1652+ if line .strip ().startswith ('#' ): continue
1653+ spLine = line .split ('&' )
1654+ tag = spLine [0 ].strip ()
1655+ if tag == 'Equation' :
1656+ val = spLine [1 ].split ('=' )[1 ].strip ()
1657+ cons = []
1658+ for e in spLine [1 ].split ('=' )[0 ].split ('+' ):
1659+ try :
1660+ m ,var = e .split ('*' )
1661+ varObj = G2obj .G2VarObj (var .strip ())
1662+ cons += [[float (m ),varObj ]]
1663+ except :
1664+ print ('skipping {line}' )
1665+ continue
1666+ # TODO: could do a consistency check to make sure that all
1667+ # vars are of same type. For now only the last one matters.
1668+ key = var2key (varObj )
1669+ Constraints [key ].append (cons + [val ,None ,'c' ])
1670+ elif tag == 'Hold' :
1671+ cons = []
1672+ for e in spLine [1 ].split ('=' ): # should only be one
1673+ varObj = G2obj .G2VarObj (e .strip ())
1674+ cons += [[0. ,varObj ]]
1675+ key = var2key (varObj )
1676+ Constraints [key ].append (cons + [None ,None ,'h' ])
1677+ elif tag == 'Equivalence' :
1678+ cons = []
1679+ for e in spLine [1 ].split ('=' ):
1680+ try :
1681+ m ,var = e .split ('*' )
1682+ varObj = G2obj .G2VarObj (var .strip ())
1683+ cons += [[float (m ),varObj ]]
1684+ except :
1685+ print ('skipping {line}' )
1686+ continue
1687+ # TODO: could do a consistency check to make sure that all
1688+ # vars are of same type. For now only the last one matters.
1689+ key = var2key (varObj )
1690+ Constraints [key ].append (cons + [None ,None ,'e' ])
1691+ elif tag == 'NewVar' :
1692+ cons = []
1693+ name = None
1694+ vary = False
1695+ if len (spLine ) >= 3 :
1696+ name = spLine [1 ].strip ()
1697+ if len (spLine ) >= 4 :
1698+ vary = True
1699+ for e in spLine [1 ].split ('+' ):
1700+ try :
1701+ m ,var = e .split ('*' )
1702+ varObj = G2obj .G2VarObj (var .strip ())
1703+ cons += [[float (m ),varObj ]]
1704+ except :
1705+ print ('skipping {line}' )
1706+ continue
1707+ # TODO: could do a consistency check to make sure that all
1708+ # vars are of same type. For now only the last one matters.
1709+ key = var2key (varObj )
1710+ Constraints [key ].append (cons + [name ,vary ,'f' ])
1711+ else :
1712+ print (f'line #{ i + 1 } ({ line } ) not recognized' )
1713+ continue
1714+ OnPageChanged (None )
1715+
15801716 #### UpdateConstraints execution starts here ##############################
15811717 G2gd .SetDataMenuBar (G2frame ,G2frame .dataWindow .ConstraintMenu )
15821718 if Clear :
@@ -1723,6 +1859,8 @@ def OnShowISODISTORT(event):
17231859 G2frame .Bind (wx .EVT_MENU , OnAddAtomEquiv , id = G2G .wxID_EQUIVALANCEATOMS )
17241860# G2frame.Bind(wx.EVT_MENU, OnAddRiding, id=G2G.wxID_ADDRIDING)
17251861 G2frame .Bind (wx .EVT_MENU , OnShowISODISTORT , id = G2G .wxID_SHOWISO )
1862+ G2frame .Bind (wx .EVT_MENU , ExportConstraints , id = G2G .wxID_CONSTREXPORT )
1863+ G2frame .Bind (wx .EVT_MENU , ImportConstraints , id = G2G .wxID_CONSTRIMPORT )
17261864 # tab commands
17271865 for id in (G2G .wxID_CONSPHASE ,
17281866 G2G .wxID_CONSHAP ,
0 commit comments