-
Notifications
You must be signed in to change notification settings - Fork 23
Description
Hello, from what I understand, we should get a unique SFILES for a given flowsheet. However, I've come across some structures which appear to have more than one unique canonical representation.
This is what I did:
- I started with a networkX graph.
- I create a Flowsheet class to generate a SFILES (
create_from_nx()thenconvert_to_sfiles()). I obtain the following SFILES:"(expander)<1(comp)(expander)(splt)[(cond)(comp)(heat)(mix)1<2](comp)2". - I create another Flowsheet class instance, this time initializing it with the SFILES I've just mentioned (
f2 = Flowsheet(sfiles_in=...)). - I use the graph generated by the Flowsheet class (
stateattribute), to instantiate another Flowsheet class (like in step 2.). I get a different SFILES:"(cond)<1(comp)(heat)(mix)<2(expander)(comp)(expander)(splt)1(comp)2". - If I repeat steps 3 and 4, I alternate between the two SFILES strings mentioned.
Here's an example code I've run with the latest version of the SFILES 2 library:
from Flowsheet_Class.flowsheet import Flowsheet
f = Flowsheet(sfiles_in="(expander)<1(comp)(expander)(splt)[(cond)(comp)(heat)(mix)1<2](comp)2")
g = Flowsheet(); g.create_from_nx(f.state); g.convert_to_sfiles()
print(g.sfiles) # '(cond)<1(comp)(heat)(mix)<2(expander)(comp)(expander)(splt)1(comp)2'
f = Flowsheet(sfiles_in=g.sfiles)
g.create_from_nx(f.state); g.convert_to_sfiles()
print(g.sfiles) # '(expander)<1(comp)(expander)(splt)[(cond)(comp)(heat)(mix)1<2](comp)2'
f = Flowsheet(sfiles_in=g.sfiles)
g.create_from_nx(f.state); g.convert_to_sfiles()
print(g.sfiles) # '(cond)<1(comp)(heat)(mix)<2(expander)(comp)(expander)(splt)1(comp)2'
# And so on...
I believe this is due to the fact that:
- SFILES 2.0 tie-break rule number 4 depends on graph node numbering.
- When the networkX graph is created from a SFILES, the numbering may depend on how the SFILES is defined (?). Maybe the fact that the process is a cycle has an important influence in this problem.
Indeed, when comparing creating f = Flowsheet(sfiles_in=g.sfiles), it can be seen that the resulting f.state is different from g.state (comp-1 becomes comp-2 and vice-versa).
If it is of use, I've come across this same issue with ~500 other cyclic SFILES (with an older version of the library, not sure if still applicable), which I can share. Here are a few other examples (some may cycle between 3 SFILES):
(heat)<1(expander)(heat)(splt)[(cond)(comp)(heat)(mix)1<2](expander)2
(heat)<1(expander)(heat)(splt)[(cond)(comp)(cond)(mix)1<2](comp)2
(hex){1}<1(cond)(comp)(splt)[(hex){2}(heat)(expander)(cond)(expander)(mix)<2(comp)(hex){2}1](hex){1}2
(comp)<1(heat)(mix)<2(expander)(cond)(splt)1(comp)2
(cond)<1(comp)(heat)(mix)<2(heat)(cond)(expander)(splt)1(cond)2
(comp)<1(expander)(cond)(splt)[(comp)(cond)(heat)(mix)1<2](expander)2
(comp)<1(heat)(expander)(splt)[(cond)(heat)(cond)(mix)1<2](comp)2
(comp)<1(heat)(expander)(splt)[(cond)(expander)(heat)(mix)1<2](cond)2
(heat)<1(comp)(heat)(mix)<2(expander)(comp)(cond)(splt)1(cond)2
(heat)<1(comp)(expander)(mix)<2(cond)(expander)(comp)(splt)1(cond)2
(heat)<1(cond)(mix)<2(comp)(mix)<3(heat)(expander)(splt)1(cond)(splt)[(comp)2](comp)3
(cond)<1(expander)(cond)(splt)[(heat)(comp)(heat)(mix)1<2](expander)2
(cond)<1(heat)(expander)(splt)[(cond)(comp)(heat)(mix)1<2](comp)2
(comp)<1(heat)(mix)<2(expander)(cond)(splt)1(cond)2
(heat)<1(expander)(hex){1}(splt)[(cond)(comp)(hex){1}(mix)1<2](heat)2
(expander)<1(heat)(cond)(splt)[(comp)(expander)(heat)(mix)1<2](expander)2
(expander)<1(hex){1}(cond)(comp)(mix)<3(expander)(heat)(mix)<2(hex){2}(expander)(splt)[(cond)(hex){3}(expander)(comp)(hex){2}(heat)(splt)[(hex){3}(cond)1](hex){1}(heat)2](comp)(expander)3
(comp)<1(heat)(expander)(mix)<2(expander)(cond)(comp)(splt)1(cond)2
PS: I'm using python version 3.9.21, in a clean environment with just SFILES2 installed.