From 26a1e4522dd18372690a7913f0c2df4a688a3245 Mon Sep 17 00:00:00 2001
From: Timothe Jost <timothe.jost@wanadoo.fr>
Date: Tue, 10 Oct 2023 01:39:02 +0200
Subject: [PATCH] almost working base feature set

---
 .coverage                                     |  Bin 53248 -> 53248 bytes
 pypelines.egg-info/PKG-INFO                   |   18 +
 pypelines.egg-info/SOURCES.txt                |   19 +
 pypelines.egg-info/dependency_links.txt       |    1 +
 pypelines.egg-info/top_level.txt              |    2 +
 pypelines/__init__.py                         |    1 +
 .../__pycache__/__init__.cpython-311.pyc      |  Bin 332 -> 358 bytes
 pypelines/__pycache__/__init__.cpython-39.pyc |  Bin 0 -> 273 bytes
 pypelines/__pycache__/disk.cpython-311.pyc    |  Bin 0 -> 14332 bytes
 .../__pycache__/examples.cpython-311.pyc      |  Bin 1512 -> 1575 bytes
 pypelines/__pycache__/loggs.cpython-39.pyc    |  Bin 0 -> 2328 bytes
 .../__pycache__/multisession.cpython-39.pyc   |  Bin 0 -> 482 bytes
 pypelines/__pycache__/pipe.cpython-311.pyc    |  Bin 6924 -> 5753 bytes
 pypelines/__pycache__/pipe.cpython-39.pyc     |  Bin 0 -> 4904 bytes
 .../__pycache__/pipeline.cpython-311.pyc      |  Bin 3274 -> 4843 bytes
 pypelines/__pycache__/sessions.cpython-39.pyc |  Bin 0 -> 3653 bytes
 pypelines/__pycache__/step.cpython-311.pyc    |  Bin 9923 -> 10915 bytes
 pypelines/__pycache__/step.cpython-39.pyc     |  Bin 0 -> 6030 bytes
 pypelines/disk.py                             |  156 ++-
 pypelines/examples.py                         |    2 +-
 pypelines/feature_test.ipynb                  | 1000 +++++++++++++++++
 pypelines/pipe.py                             |   54 +-
 pypelines/pipeline.py                         |   62 +-
 pypelines/step.py                             |  107 +-
 scripts/self_install_local_editmode.cmd       |    4 +
 setup.py                                      |    8 +-
 tests/__pycache__/tests.cpython-311.pyc       |  Bin 2021 -> 2021 bytes
 27 files changed, 1331 insertions(+), 103 deletions(-)
 create mode 100644 pypelines.egg-info/PKG-INFO
 create mode 100644 pypelines.egg-info/SOURCES.txt
 create mode 100644 pypelines.egg-info/dependency_links.txt
 create mode 100644 pypelines.egg-info/top_level.txt
 create mode 100644 pypelines/__pycache__/__init__.cpython-39.pyc
 create mode 100644 pypelines/__pycache__/disk.cpython-311.pyc
 create mode 100644 pypelines/__pycache__/loggs.cpython-39.pyc
 create mode 100644 pypelines/__pycache__/multisession.cpython-39.pyc
 create mode 100644 pypelines/__pycache__/pipe.cpython-39.pyc
 create mode 100644 pypelines/__pycache__/sessions.cpython-39.pyc
 create mode 100644 pypelines/__pycache__/step.cpython-39.pyc
 create mode 100644 pypelines/feature_test.ipynb
 create mode 100644 scripts/self_install_local_editmode.cmd

diff --git a/.coverage b/.coverage
index 7f4cc21f0600cbe15bb35deaaf856e3f4f26e781..437d2d4b5c9f6b39ff6542e53809bbf383d04dae 100644
GIT binary patch
delta 233
zcmZozz}&Ead4e<}_e2?IR&EBpv{xHb7T8O1^TaXmujY^9=j7YY7stoRyM;HNmy2gT
zPuylf0S6v7e{L3rM&-#H{ax5oGK;hI3Mx0R_X%a@;O2>E;9tWNznLo_n1?lhrBRs?
zq=*Bmh<o#fm@s9r7zX~I{15pL@o(i{%RimJl|PR^g+B&lGXLb%eoY|(b{0lXC3X#6
zaR&wlAYxFMJgZ;ZT$ULqY{MKUSo`&U>dD*x94cBFfs!DQ#lXNK#srksW6E2~VjvLr
UUbWdT!ihmZD1>qI&wh3X0L9Eby8r+H

delta 185
zcmZozz}&Ead4e<}*F+g-RxSp;yd4`;7T8O0@vLXyU(FxI&&ju)FOH9scMESkFHmr^
zpul9F&Fg(anc28_HZbt7*~}9V%rkL8@a7FMVaj5u4E#U&AMqdM-@(6ue-?iqe>s0H
ze=1OuC;#M_eoY=Ob{0lXF?NlqQ4EZer}t}{NHYTkESTe-ye^Oaw9Wp3I2!{5Tw!3~
h5M=^N>M-S{ZrQc%&}&w^#Jkf16g@>Z|LkXX001`ZHYWf8

diff --git a/pypelines.egg-info/PKG-INFO b/pypelines.egg-info/PKG-INFO
new file mode 100644
index 0000000..b27b9d9
--- /dev/null
+++ b/pypelines.egg-info/PKG-INFO
@@ -0,0 +1,18 @@
+Metadata-Version: 2.1
+Name: pypelines
+Version: 0.0.1
+Summary: Framework to organize processing code outputs to/from disk, processing chaining and versionning with a common easy to use api
+Home-page: https://gitlab.pasteur.fr/haisslab/data-management/pypelines
+Author: Timothé Jost-MOUSSEAU
+Author-email: timothe.jost-mousseau@pasteur.com
+License: MIT
+Classifier: Development Status :: 3 - Alpha
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Classifier: Programming Language :: Python :: 3.11
diff --git a/pypelines.egg-info/SOURCES.txt b/pypelines.egg-info/SOURCES.txt
new file mode 100644
index 0000000..d9bcaf8
--- /dev/null
+++ b/pypelines.egg-info/SOURCES.txt
@@ -0,0 +1,19 @@
+README.md
+setup.py
+pypelines/__init__.py
+pypelines/disk.py
+pypelines/examples.py
+pypelines/loggs.py
+pypelines/multisession.py
+pypelines/pickle_backend.py
+pypelines/pipe.py
+pypelines/pipeline.py
+pypelines/sessions.py
+pypelines/step.py
+pypelines/versions.py
+pypelines.egg-info/PKG-INFO
+pypelines.egg-info/SOURCES.txt
+pypelines.egg-info/dependency_links.txt
+pypelines.egg-info/top_level.txt
+tests/__init__.py
+tests/tests.py
\ No newline at end of file
diff --git a/pypelines.egg-info/dependency_links.txt b/pypelines.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/pypelines.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/pypelines.egg-info/top_level.txt b/pypelines.egg-info/top_level.txt
new file mode 100644
index 0000000..35c4292
--- /dev/null
+++ b/pypelines.egg-info/top_level.txt
@@ -0,0 +1,2 @@
+pypelines
+tests
diff --git a/pypelines/__init__.py b/pypelines/__init__.py
index 38f5db9..159c556 100644
--- a/pypelines/__init__.py
+++ b/pypelines/__init__.py
@@ -3,4 +3,5 @@ __version__ = "0.0.1"
 from .pipe import *
 from .pipeline import *
 from .step import *
+from .disk import *
 from .versions import *
\ No newline at end of file
diff --git a/pypelines/__pycache__/__init__.cpython-311.pyc b/pypelines/__pycache__/__init__.cpython-311.pyc
index 8550abbac6f7ee0b29e5f4d402f453d9c6cdd4e9..1f1e7f14aae5ebd0f29edc5dda4fc2fad498dceb 100644
GIT binary patch
delta 141
zcmX@Z^o)sjIWI340}zzmQ%>!e$ScWcG*MlPl`(}WhjpT#G$Y%@EEP|dl+5DnTO4Jn
zMa7x<dBrOkK7(}p@=vykDJ=#H#*}2`7nkJbm&T;zCzs}?=9Lu36jYXE<mbi2#}_0f
lXD6no7RSfO6imFR$;AuQ$_T{8K9gA(jVEg}%Cc|+xd1(9D<=Q|

delta 157
zcmaFHbcTs{IWI340}%8akxMO}$ScXHHBntlk~x?`lckE)K+izW@FgQqT9fe>qn4j0
z>%<}zXO6PeqT<Z_yyBG%pFvuG`8!+1gcbt@V@k5}i%W9zOJiK}lS^|`^Gb?i0xC-~
y^7CTi;|mg#vlG)(i{s;C0w&(q<l+Hp1sPrJFj<Jvc(N`d7xx7QaUd!JIS2r@-z?n#

diff --git a/pypelines/__pycache__/__init__.cpython-39.pyc b/pypelines/__pycache__/__init__.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..69ca6721c475b449b82b457a2b80142213b0c785
GIT binary patch
literal 273
zcmYe~<>g`kf}SICsl`D0F^Gc<n1CDyATHJb5-AK(3@MB$OgW4p5Sj@}Gec<>Ak7@i
zpvh9jYM^JJXZVs4s7sUa7NeG*ChINk`1rEaqT<Z_y!iNAECrbbsZkstGAA=H^%hHU
zNoqk92UJ1vN`@jfpk6TX%iq~5CbSr+HKrshzqlkfzcj`rKe;qFHLs*NCZMt;BR?-D
zKE5C^IXf{uwKzT=C<ZaLIHmy3ijU9C%PfhH*DI*J#bJ}1pHiBWY6o&(F$a)fVd7u}
FK>)^zNu>Y)

literal 0
HcmV?d00001

diff --git a/pypelines/__pycache__/disk.cpython-311.pyc b/pypelines/__pycache__/disk.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9d3d69007e0312dc2a3c23b785b3a48f5da7a0c1
GIT binary patch
literal 14332
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

literal 0
HcmV?d00001

diff --git a/pypelines/__pycache__/examples.cpython-311.pyc b/pypelines/__pycache__/examples.cpython-311.pyc
index 780df463f25f93e2172633060d028bf9f416db06..ef924db813456c744487c5d682737f73a58a5cda 100644
GIT binary patch
delta 569
zcmaFCy_|=4IWI340}#x<qntW%BCjOlq>1XD8Yyhc7#SE=12F_dv8S?Ualm*?4DJjm
z>@5r_922K0vT_D9XmU;5GsiI5DyFnJwWv6zBrCtTBsae_CM7?)G&eP`q&TLavLquv
zFD5>|ATc>RF+H_7K0c;kawnr#{Vn#?ip1Q4oYZ8P@gSNR%K4lEWK3sBWr$)-VTfX4
zVn}69VO+z6>bexp6qXjoWk8jyq1qT2qFBIcS=XTX1mtdHm8w9ctSKBIKiuMWg}5Xj
zvmo^rqoF3_E%q{?e=_s)CdV<Qv55i=FA|%4iYaRHD<<j5D$Ew@Afa2FiACvPZyFVG
z1NoXPMdBcp5+DMsM+T@ze)1w_J4WHj51FOdBtbH=lNnir>jgke5CPIzTnZ!_;P3+*
z1DilY)C}bdta2Aw<*u;GePCi_4P*SkfFM6IGqA}cWFR^&NSj??HNVJeeudQ>q{RuW
z#fcH5*aAh2A0}1A19r&d*(@=P0+WBR$Z{zI1wip%e0Z`vYd*&U%ZtLgSA=yZPhkxK
E0DUBbegFUf

delta 560
zcmZ3^^MadqIWI340}y=vE1z08kyny&!bEjXwPiq&)gWOoh+<D=&*Fgbm>Ap{QrKD;
zQrIWXP-Nu@X3*rExNnZ3vsFxJacWU<Oi5OLaY=4|X^cyLa%paAUP*CGKxIireqKy`
zd_iJzc4B&JaeRDCz~pX5ugUiq#p;uQCQoNbWr$)-VTfX4Vn}61wLXO{g{g%RRV<1H
zq%M^uopBBGGDe_dffxc(SXvm+)Uu|q0$s^|i`%s#F}ENmH6XJf^%j$naWV@?%j9OJ
z7&ajwqeyu2PG<SZEX>xEqnIt!K|;4U6N}Qpo-iun2J$soibOyvML`5uk0ek}Y`p+T
zj;#n3Mn#+;0u-i2tRO-RL`Z=MkO4(JAc7Y}@WTj@cyS((Xn?~HYz%Ay4N;9TEioUM
z7+J#@KQJK3kIW2gLU0L?O67*A8NM^@FR*G~WYxaHstwZP1lHrk2vV&B6q~%CMS_uk
w@(q?44Y19quKC4blbfGXnv-f*qyTgYC^U-?PL5&CXS*n@az$8W@@3W#0M7n;IsgCw

diff --git a/pypelines/__pycache__/loggs.cpython-39.pyc b/pypelines/__pycache__/loggs.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..71d21045c45bb50646ed6e45be18ef5804f22d25
GIT binary patch
literal 2328
zcmZ`)O^+Kj7`A67Gm~sKl<h(R6^K-X$Yp6cqN=LYs$5D`(M5<T$Qs7pY|=?)YkRwG
zl%7(lJ;4vCkhX}+{uwUZe1!{tp(mc#GwFU6C;lA!o%em-=ka9g>n(=z&tIRYKO2nw
zO_P%)!sI5ZxratF$qP21J}CG!7zCVs!(=F<XG}(lO~Pe3h_KR-F;?PbFlb<w$P}|w
zHSjc+P1$<J28rbNS#RxMSY`bq?ivR=+cP;$PnH0ao2aIXMzH~xY!FC32xTBcn2BU0
z8|d*um`mLHt#W47V|!;@Sf%IRwz??WyJOSEKkM%J<?g}mIN$A#XA_lM)6J_R`&ogd
zol;LTJ1%D!+p=qSRktWdTi#Ai-mD6Zsop|0gyDiOm;f~Q*%9yexLd33im4eL1uinG
z*wHaI9x>fS_xkRwuZQ0orOnVzN@J(x{_u90?@!gtn&G`CcDI}jh1kpT2iZs&A+WZm
zit$XD;oh4OoEw>~y(caeVmupLA;`Azp7Qzor{LIHZ8;Z6h%-Kr4=`A;344i5FZhJN
zWWR+AF1QQ;Z`gm$yW73MN8v)mg>i}#F4ih9we)dS4I$#<3hy??hKR)YCZBJf_Nm&^
z@5L0sESoAJTuX>)DfbH+w}p6!)YMNBA!L~gq1Rwdze5ehd!nHiYkC>j%nae3@+eG0
zzm{Wqst`^$QO##)j`<}6a4M{b4UTy_gJTImNL}l0IjUng2jm+@T!6ir5yT7d7H5P0
zofUc)s<_2LW<(~Xk~+bOvvE+A@1oY|#e9D8_~pmx<k+$*<N<~5)47d-WrzF~k}3iu
zHkgFB*-w|BavLqUL|T_2RvQljy}><qA8tsjh}b5yz9ipMI(OJao4(@Ju3pryNWivx
zEte1p$Fq@Zj+BLeBc<J%E=w!u0VYWmtZ@l8WY%hbSicAFd|F&*rIl)<YXXuxUaK|3
z&ZgSat0@GuqO=fX$#l>#-r{Y(!P6i{Ki@osR=qj*RHV%)G(N|Ey@_D?ApsVyLe>Oo
zFRGmW5M$TYYFa*0m7n@@_1McHRgZIFp;4F6=uuX<*f0HjCc(sc^_W!qDUSbNma83*
zh$dEPB81+c#*5$+8eO60ZA#e013FbJA&t_OrnPfQAP}e+3S^~(=WNHb<XJihp98Bw
zMAv{<z<p&5uE|phARDV{$S=t)R50O7eu+H|Y_Md9;UZW;3O&pNbEOx#&{*vnSuxIx
zYnc5#rG0F@u)1CnQ@yOZKDk5U^CC026RViL<_Qc^agAc9(n{^-8?E#jZv)Y-*A{bC
z6f3J9&K@jkZ=Y;mA^W7Tlxv#jXO*|2lc9^$vKMU0k1<^Gr?^!8MSAKWK}Njs92jD-
z2o3?A3|<BLqZa^hjFmt5FF0x;$R+>va}LuBHiEg|`FCvf{0DrIB+?YIWyo>iTw|tx
zm2v<35v{+3!v3H$D@6?{Nfeio3!zLO5-|S)F1RSuBje%+2h`&O9qsJT@?*GNLLY1-
ziU2a?Jqy~r1NqHA_Ntdtg)f-gx?YrdR+t-G^?pt8LDg5$>1)(@oWG=zS9Sa3adO2|
zm+_c)8u}~Dd#S#J&Nay+Tb6~<grJLSB~lJN$9+8h$lIjh((Bbn<_3A>KjA5F2ODdh
Iix(RI0bx<>-T(jq

literal 0
HcmV?d00001

diff --git a/pypelines/__pycache__/multisession.cpython-39.pyc b/pypelines/__pycache__/multisession.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ce3a379a62fbf55dfac022cb10bfa5131a4e3450
GIT binary patch
literal 482
zcmZ`$y-LJD5Z>LyBOG2M7ItEpCJ!JYrzco>2&YX549o7S(IgvplHzQ=m+>ilkF-95
zot3jWqOow`o4=ipnU9sT*_4sJCx_;S;)gHB7Em!K;2yb4rkUm&!mCJ`7AqD9iu!*{
zP&FsuJ~_iuu30KH*J8ucKnKJLyMuFy=Bh2491UV_t23o2u}*pRU_R%B1pz~Hnh~2X
z-&icV5KVE{O={^()i^)eyRX&aIJ-sTFl!zyHl=N|3#;0arZBr+HxIVT0BWh8<h?-v
z>eZ&mD}!16la-^>l6u`m0C|-+06YGa{zm?C^q+`im|l`pqE@mr0NoUzw7M;Pz6<c&
s%3}NCCd2i=I-K9+yn6ow{mMx6^)lvt9L@IXJ)w(Ewku9O>yyB~0lRZ?N&o-=

literal 0
HcmV?d00001

diff --git a/pypelines/__pycache__/pipe.cpython-311.pyc b/pypelines/__pycache__/pipe.cpython-311.pyc
index 245faedfbd79e61c050d0ce15c0ff7af4844816c..a3cac95ede6de457e2ca62a66c6cc597ff4404a2 100644
GIT binary patch
delta 2738
zcmai0OKcm*8J>Oc{S--4lvG(uOMWoX1CHAu7W_&oJCW4NF6zYbLcyBhj%-T1Bs;ro
zVU-4j!Uwrf02|Y!2AZNq4^9pDP{4<rb58&&5Kv)JqbZ64MSG#)9NL`v|GQdB3KDdr
z{V?<W^FQ~WS#G@i-|?d#B@$5rgWVaUN<Sfg$Av%SoyqgN_l~}>LUh>(njtkL5Ivv=
zjj$O}Bknw8MAay8VIyY7)wr2Z6J}CPnkhA9rq#4SXqp9eqDPEAGoxk%B9hmM9=%QU
z*h7(!$MASV&FY~alT!R%=aqCxaN?J$l@)_te0P~vY#tWMd@elHrm`BKK{Z6fYDCZJ
z!P_!8muYNC)I%_j>*3o(P3RFC16E#=!I7*c^#gjGrgoUb?SPuzVUkqVWj(MI)KkFr
z?XsYm1}3BT(Ja``fR!A~-^N8276<eI#F}@)uazx&soJ0yoK&OCXwB9durjJO%94<m
z6J*qGvf4tWmnX0xcqDk9cL0A)TI2!$M9T4n$Pe39SZP6!xx-HRGeVZb{=7wOw7oNy
zBmV4<!v2cRkav_t@Ow+VCD{l3U4*nGUDTzA;QKK~;SLsUNiDKm?741<r$De#w4pKl
z0ULt+)mY)J6_;Tn_JA)U&=(*M`0L*gJ&4<TYw@@8LjgR(<BeYk-(-4b#ce!x1e6p0
z)~`7V{Xa*%7|q6dt{)_!x`z{|{Zc@=Q~X|Zv@Ny7hv4n8-|FO+<QAc)>D9n4`f)(%
zNK0&et#ks}II}O>sy(__W48zoGP^t>{4*)fXJe_0;oU0kM9^!N<*cu<H)nh^u-=VR
z+S4*c{wy{sNc>4`bm&{PZQOOT9a(^r7HKf5S1V<kI-#niSvGB4U>L#bxvTZ2V%?}W
z4P9aMdKE-WDcg!c%a*OwYgEC_O2sH!mh!WzeM32igh}libzP~}l-0Z^oKzHx8cUNX
zwUpD!>iqZ1wOXCO62A~)cp6GM{$6~%?L;)qwWeuKSkr1{lfo>5N6K9|0oMY=S+g2&
zFF4Wb)HbR4E@hSzu3DaFCj@NSwwWUtwB|(LDjQ9Dp0PS}Vpg?w-JougPM~U2({iF{
z({<anoRGDnDjSfl6Z|RaT225%uu8HcV;-yzLUtmq9>xePCWd{a!1!vuGQHTeAf`oo
zxo+8Jy}78@D@_xw2Wzo$6RJ~N)U-yqvQoZIElmT?y)$@G%8g;-)mqiowADWUcA504
zDR5yGMZTPvXm^7oUs#tnqECy*wu&eIbosN;)*Ekkit1)j-72bGB1R@$*o+UaU%f9s
zP37;}_pkmTu$h|NN=<f&keJv$Hhx$BRrLPJ&Gg~_{3DiJw>MVroZUEk|3{z44t8P(
zpJu+(CFJ0&*tw=}U8{L>507<j-ue=nM3@ox($5IV&WRuZ1U@k*@{baSDwoC1N_}hP
zCT_j#D!6!FoW;H8#f!Tf$kE7~u8}ugBY+vAjD5KJ=aH$;N2WGMj&F?|?-D8Uq6>E}
zuFu}J`O)Nz5aLGiL}Ytl_`|{VnT<LAyX36+obZ1o4G>*P9W4w(1=$clNnkHvHSt1H
z*aZI|r3hE}$Eg#-6#sYXO6ZZWP!d^z&!>ljxRJfcYw00jg8wo-E~xxt_()AX`CIz;
zV#bwDqb)o&3L1MqJKd)tgJ*Qj{bN)7i|kb9Wgr+H;F9F}XJ>gamj$!m%N^=BQ3cP#
z8u=oXUAGy&Z#K?rxv}Y8#lVgt$ee`UG#gac>h5=vjpP1T0W7?Uu^BO%Pjh4a3`x)Q
zb~v^!xuz>J?`DVip#y(8?1m)oTHa&I?`yC$nm>|jq9y$3tdVY*MB-?RzmuOl*o*Ly
z=-GJ#clK)XC_k3@IWW)t1pC)hp!wJQSbtBG&Fxbe?4NA6fnh&Dz+#kS_wczNSBBRq
z++ges3i1qJtrOKWv#vMcjB8F@(|*z{8{Rd-@KR>@!DELJ@Xa_;y=tv^R}RB8Ssq~$
zMUrJR_FV$**-0c%BVbk8YY68NUPr)Euz7?91T3WY-X?IC_5qz*Gtg~bJ0NzWBwJXU
z-|ib&o7?Ui1{gTrk@H>oNZ@3bco6lcmxL#$3JIa#Z3(nm%6ad|O{t%o1BJGX>3Eq%
zmYTJSU9TG!!ygW87{CeIHydyPdLc)Vjv>Sm@N3Ho2>9c|i+g`AUxiP3r9H#0z!p3>
v);|Hdk{}4%WT?Z#gD+*a$w+7aKc61FcJ8G`K`3;|H{&yx|MFX;ZZ-c0`ZZ~b

literal 6924
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
Jhf!R7{|3tCVIKeh

diff --git a/pypelines/__pycache__/pipe.cpython-39.pyc b/pypelines/__pycache__/pipe.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6854d1333d1bfd533b072933e189ad98a6510225
GIT binary patch
literal 4904
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

literal 0
HcmV?d00001

diff --git a/pypelines/__pycache__/pipeline.cpython-311.pyc b/pypelines/__pycache__/pipeline.cpython-311.pyc
index caf0bc1b20115b3044272f07dc526daaa7680c37..2806549c7dc65213fac3561356c08fbaa13ef1aa 100644
GIT binary patch
literal 4843
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
aE+*{ury*YFIFMw2`Za6+_65Ccr~e1}SanYT

delta 1270
zcmZ`%&2Jk;6rb4-d)K>mo%lOWS|@4RI3<w^qz66{sUM<HWI`%97$eJgC#{QPo0)Z_
zNNcd52OlbtGDx`q@}cU7$^nW0BE2}3C9Fk4zJP>!aRm}m;lSICokIz4cYpKty{F&%
z&6{~Lx0eXq^ZR`WEVy@^e68FLJX&9Yzg<L778@ullu%YQFp&&_NE?zN-juSk;WOl$
zIO{Py#JeFFUWh4%W~dNT4e2UM>$ZNrz{pyuM#`lM;p@Tzp5zT7p<rZTD8T%C;k!2<
zptN91jFdO14o#T=kV-v!=fW$w_ZXopXWpnXbF*5{U91-Co1|j0+}gHzy;{lT^R+_p
z<H9w<^7-5v{~e#;TjE06rI`SlCK`B<8fy7=Ufx&YT_xU8;{9WZj*|ETvM9sP;^=A^
zyj>7vp}Z4x%|KVt1Dr`?TiF5$rD}zx1sa4LjRFic(lPM4SD226oS+||iF)x=OS<K6
z!9znoJ`&GhuPxVL28{nLox*WGBQM}F{?t2zqx^IE8~(GBJSD)UL4(i~uAzotiS8<z
z7#N3UVN>A0c&0e>NBE8!)EgKii(7~uH@$pCeH}~uwkO2DRKr-~chouT=X>hp1n|ig
zzTqA5TtpvUX?QHuR-E!P$nsdw&ywy+2t9=Fz;d9cAwV5uw=j)ZLffT}LH%7&_3%&`
z9Ho4aJAFj%*4q|z&mVTT#J1|n-1a?w%V+yatW;rUp;9Ea$V^ISp}iegC&juu^h=ah
zsqHD$YNTS=VwqHI-}{Afog5?-N<OKVC`{JUrh;Dgd~9XJ$nR+BbCKa+sbCT#KdQI2
zq37NvM_uZ`+!Lis{E2q@LJGp{BiJaMsg~$y)4iz^txR7VZ>{#C@zxu^YLT7m-?Dve
zwyVt!5LTCZvE;7xmDRqyA6x9k7F(D3s=gcTrDi(HR6jY}O};Qdl6uYs{+oV2)zhbc
z(&r!R^Y@ec`f^ua?znG%@@z}#Dv2In@K1!DyG0`aX)%+bCmqMf{|e51HVLjRncFo&
z$DNv(1M?0zW28$C9CN^BaPBJAMxcPhz5r+*K7BpVyflzxdE$O}fMEIIq`N#10W43$
zcI7KB4#A_ydE71zkh30v;iNo2K>q_Y#Qzyvd~wDRr;ZdpC;gf7+Gf?Lm&po!6-u1@
a$3EpBjK9155(eh~!c!;q=Mf2a9RC81(mp2u

diff --git a/pypelines/__pycache__/sessions.cpython-39.pyc b/pypelines/__pycache__/sessions.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e01a1dd7786579b2b8a3485917135332a301afc6
GIT binary patch
literal 3653
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

literal 0
HcmV?d00001

diff --git a/pypelines/__pycache__/step.cpython-311.pyc b/pypelines/__pycache__/step.cpython-311.pyc
index c4d11c73dbea1bb430c7db0000641c7f854d66ed..a680037efa3756d6b9283d1ab533f63362d9b6cf 100644
GIT binary patch
delta 4791
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
NqL5#|ORw13e*v@)B^v+$

delta 3857
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
HHP!zKTaaET

diff --git a/pypelines/__pycache__/step.cpython-39.pyc b/pypelines/__pycache__/step.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0cf6a81245bc75eb2101f88dc1094dba39276444
GIT binary patch
literal 6030
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

literal 0
HcmV?d00001

diff --git a/pypelines/disk.py b/pypelines/disk.py
index cfd1cfb..c22822d 100644
--- a/pypelines/disk.py
+++ b/pypelines/disk.py
@@ -1,5 +1,6 @@
-import os
+import os, re
 from . sessions import Session
+import pickle
 
 from typing import Callable, Type, Iterable, Protocol, TYPE_CHECKING
 
@@ -16,9 +17,8 @@ class BaseDiskObject :
     disk_version = None
     disk_step = None
 
-    def __init__(self, session : Session, step : BaseStep, extra = "") -> None :
+    def __init__(self, session : Session, step : "BaseStep", extra = "") -> None :
 
-        self.step = None
         self.session = session
         self.step = step
         self.extra = extra
@@ -29,7 +29,7 @@ class BaseDiskObject :
         """sets self.disk_version and self.disk_step"""
         ...
 
-    def save(self, object):
+    def save(self, data : OutputData) -> None:
         ...
 
     def load(self) -> OutputData:
@@ -42,7 +42,6 @@ class BaseDiskObject :
     def version_exist(self, session : Session):
         """returns True if the file found had a stamp for that step corresponding to the current version. False otherwise""" 
         return self.step.version == self.disk_version
-    
 
 class PickleObject(BaseDiskObject) :
 
@@ -50,35 +49,88 @@ class PickleObject(BaseDiskObject) :
     file_prefix = "preproc_data"
     extension = "pickle"
     current_suffixes = ""
+    remove = True
+    current_disk_file = None
 
-    def make_file_prefix_path(self):
-        prefix_path = self.file_prefix + "." + self.step.pipe_name
-        rigid_pattern = self.file_prefix
+    def parse_extra(self,extra):
+        extra = extra.strip(".").replace(".",r"\.")
+        return r"\." + extra if extra else ""
 
-        pattern = ""
+    def make_file_name_pattern(self):
 
-        if self.step.pipe.single_step :
-            pass
+        steps_patterns = []
 
-        if self.step.use_version :
-            pass
+        for key in sorted(self.step.pipe.steps.keys()):
 
+            step = self.step.pipe.steps[key]
+            steps_patterns.append( fr"(?:{step.step_name})" )
 
-        flexible_pattern = self.f
+        steps_patterns = "|".join(steps_patterns)
 
-    def check_disk(self):
-        search_path = os.path.join(self.session.path, self.collection)
+        version_pattern = fr"(?:\.(?P<version>[^\.]*))?"
+        step_pattern = fr"(?:\.(?P<step_name>{steps_patterns}){version_pattern})?"
         
+        extra = self.parse_extra(self.extra)
+                
+        pattern = self.file_prefix + r"\." + self.step.pipe_name + step_pattern + extra + r"\." + self.extension
+        print(pattern)
+        return pattern
+    
+    def get_file_name(self):
 
-    def save(self, object):
-        ...
+        extra = self.parse_extra(self.extra)
+        version_string = "." + self.step.version if self.step.use_version else ""
+        filename = self.file_prefix + "." + self.step.pipe_name + "." + self.step.step_name + version_string + extra + "." + self.extension
+        return filename
 
-    def load(self) -> OutputData:
-        ...
+    def check_disk(self):
+        search_path = os.path.join(self.session.path, os.path.sep.join(self.collection))
+        print(search_path)
+        matching_files = files(search_path, re_pattern = self.make_file_name_pattern(), relative = True, levels = 0)
+        print(matching_files)
+        if len(matching_files):
+            keys = ["step_name","version"]
+            expected_values = {"step_name" : self.step.step_name, "version" : self.step.version if self.step.use_version else None}
+            pattern = re.compile(self.make_file_name_pattern())
+            match_datas = []
+            for index, file in enumerate(matching_files) :
+                match = pattern.search(file)
+                match_data = {}
+                for key in keys :
+                    match_data[key] = match.group(key)
+                    #TODO : catch here with KeyError and return an error that is more explicit, saying key is not present in the pattern
+                if expected_values == match_data :
+                    self.current_disk_file = os.path.join(search_path, matching_files[index])
+                    return True
+                match_datas.append(match_data)
+            else :            
+                if len(match_datas) == 1:
+                    print(f"A single partial match was found. Please make sure it is consistant with expected behaviour. Expected : {expected_values} , Found : {match_datas[0]}") 
+                    self.current_disk_file = os.path.join(search_path, matching_files[0])
+                    return True
+                print(f"More than one partial match were found. Cannot auto select. Expected : {expected_values} , Found : {match_datas}")   
+                return False
+        return False
+    
+    def get_full_path(self):
+        full_path = os.path.join(self.session.path, os.path.sep.join(self.collection), self.get_file_name() )
+        return full_path
+
+    def save(self, data : OutputData):
+        new_full_path = self.get_full_path()
+        with open(new_full_path, "wb") as f :
+            pickle.dump(data, f)
+        if self.current_disk_file is not None and self.current_disk_file != new_full_path and self.remove :
+            os.remove(self.current_disk_file)
+        self.current_disk_file = new_full_path
 
+    def load(self) -> OutputData:
+        if self.current_disk_file is None :
+            raise IOError("Could not find a file to load. Either no file was found on disk, or you forgot to run 'check_disk()'")
+        with open(self.current_disk_file, "rb") as f :
+            return pickle.load(f)
 
 import natsort
-from . import extract
 
 def files(input_path, re_pattern = None, relative = False,levels = -1, get = "files", parts = "all", sort = True):
     """
@@ -103,11 +155,11 @@ def files(input_path, re_pattern = None, relative = False,levels = -1, get = "fi
         for subdir in os.listdir(_input_path):
             fullpath = os.path.join(_input_path,subdir)
             if os.path.isfile(fullpath): 
-                if (get == "all" or get == "files") and (re_pattern is None or extract.qregexp(re_pattern,fullpath)):
+                if (get == "all" or get == "files") and (re_pattern is None or qregexp(re_pattern,fullpath)):
                     output_list.append(os.path.normpath(fullpath))
                     
             else :
-                if (get == "all" or get == "dirs" or get == "folders") and (re_pattern is None or extract.qregexp(re_pattern,fullpath)):
+                if (get == "all" or get == "dirs" or get == "folders") and (re_pattern is None or qregexp(re_pattern,fullpath)):
                     output_list.append(os.path.normpath(fullpath))
                 if current_level < levels:
                     current_level += 1 
@@ -129,4 +181,62 @@ def files(input_path, re_pattern = None, relative = False,levels = -1, get = "fi
         
 
     
+def qregexp(regex, input_line, groupidx=None, matchid=None , case=False):
+    """
+    Simplified implementation for matching regular expressions. Utility for python's built_in module re .
+
+    Tip:
+        Design your patterns easily at [Regex101](https://regex101.com/)
+
+    Args:
+        input_line (str): Source on wich the pattern will be searched.
+        regex (str): Regex pattern to match on the source.
+        **kwargs (optional):
+            - groupidx : (``int``)
+                group index in case there is groups. Defaults to None (first group returned)
+            - matchid : (``int``)
+                match index in case there is multiple matchs. Defaults to None (first match returned)
+            - case : (``bool``)
+                `False` / `True` : case sensitive regexp matching (default ``False``)
+
+    Returns:
+        Bool , str: False or string containing matched content.
+
+    Warning:
+        This function returns only one group/match.
+
+    """
+
+    if case :
+        matches = re.finditer(regex, input_line, re.MULTILINE|re.IGNORECASE)
+    else :
+        matches = re.finditer(regex, input_line, re.MULTILINE)
+
+    if matchid is not None :
+        matchid = matchid +1
+
+    for matchnum, match in enumerate(matches,  start = 1):
+
+        if matchid is not None :
+            if matchnum == matchid :
+                if groupidx is not None :
+                    for groupx, groupcontent in enumerate(match.groups()):
+                        if groupx == groupidx :
+                            return groupcontent
+                    return False
+
+                else :
+                    MATCH = match.group()
+                    return MATCH
+
+        else :
+            if groupidx is not None :
+                for groupx, groupcontent in enumerate(match.groups()):
+                    if groupx == groupidx :
+                        return groupcontent
+                return False
+            else :
+                MATCH = match.group()
+                return MATCH
+    return False
         
\ No newline at end of file
diff --git a/pypelines/examples.py b/pypelines/examples.py
index bc46c65..763bb8b 100644
--- a/pypelines/examples.py
+++ b/pypelines/examples.py
@@ -6,7 +6,7 @@ from .step import stepmethod
 class ExamplePipeline(BasePipeline):
     ...
 
-example_pipeline = ExamplePipeline()
+example_pipeline = ExamplePipeline("example")
 
 @example_pipeline.register_pipe
 class ExamplePipe(PicklePipe):
diff --git a/pypelines/feature_test.ipynb b/pypelines/feature_test.ipynb
new file mode 100644
index 0000000..f8fdc7a
--- /dev/null
+++ b/pypelines/feature_test.ipynb
@@ -0,0 +1,1000 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from pypelines import BasePipeline, BaseStep, BasePipe, PickleObject, Session, stepmethod\n",
+    "from pypelines.examples import example_pipeline"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'compress_videos': <compress_videos.step StepObject>,\n",
+       " 'suite2p': <BasePipe.suite2p PipeObject>,\n",
+       " 'trials_roi_df': <trials_roi_df.aggregate StepObject>,\n",
+       " 'trials_df': <trials_df.initial StepObject>,\n",
+       " 'rois_df': <BasePipe.rois_df PipeObject>,\n",
+       " 'figures': <BasePipe.figures PipeObject>}"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pline = BasePipeline(\"preproc_data\")\n",
+    "\n",
+    "\n",
+    "@pline.register_pipe \n",
+    "class compress_videos(BasePipe) :\n",
+    "    \n",
+    "    single_step = True\n",
+    "        \n",
+    "    @stepmethod(requires = [\"rois_df.step1\",\"trials_roi_df.aggregate\"])\n",
+    "    def step(self):\n",
+    "        \"\"\"zaea\n",
+    "        \"\"\"\n",
+    "        #comment here comment there\n",
+    "\n",
+    "        monfion = \"est fat\"\n",
+    "        \n",
+    "        return  \"blabla\" \n",
+    "\n",
+    "@pline.register_pipe\n",
+    "class suite2p(BasePipe) :\n",
+    "\n",
+    "    @stepmethod(requires = [\"compress_videos.step\"])\n",
+    "    def do_this(self,*args,**kwargs):\n",
+    "        print(self)\n",
+    "        print(args)\n",
+    "        print(kwargs)\n",
+    "    \n",
+    "    @stepmethod(requires = [\"suite2p.do_this\"])\n",
+    "    def step2(self,):\n",
+    "        return \"something\"\n",
+    "\n",
+    "@pline.register_pipe \n",
+    "class trials_roi_df(BasePipe) :\n",
+    "    \n",
+    "    single_step = True\n",
+    "        \n",
+    "    @stepmethod()\n",
+    "    def aggregate(self):\n",
+    "        \"\"\"zaea\n",
+    "        \"\"\"\n",
+    "        #comment here comment there\n",
+    "\n",
+    "        monfion = \"est fat\"\n",
+    "        \n",
+    "        return  \"blabla\" \n",
+    "\n",
+    "@pline.register_pipe# this wrapper is called after the internal wrappers, so we will be able to finish utility things with it. # this step instanciates a registered class into the Pipeline, then returns the uninstanciated class in case they must be used by other pipelines.\n",
+    "class trials_df(BasePipe):\n",
+    "\n",
+    "    single_step = True\n",
+    "    use_versions = True # by default, if more than one worker is registered, this is set to true, except is explicitly set to false like this.\n",
+    "\n",
+    "    \"\"\"arguments that the Pipe will use : \n",
+    "\n",
+    "    - extra = info related to anything the user may want. It can be a simple string, a dict with keys related to folder location, or anything else that may help the user find the location of the file.\n",
+    "    - session = info related to the base location of the files. In pandas series format. It must contain a path attribute/item, and an alias item. subject etc are somewhat optionnal for my case i would say. \n",
+    "        I will have to see if i can extend acessors externally (plugin methodo ?) to suit my purposes.\n",
+    "    - version = a version must be a string (a hash, whatever length, but a string) that allows to look up in a versions.json file to match what was the associated worker step, and it's relation in the hierarchy of steps.\n",
+    "    \"\"\"\n",
+    "\n",
+    "    @stepmethod()\n",
+    "    def initial(self):\n",
+    "        print(self) #this is a pipe instance, not a step, we will need to see if this is a good idea or not\n",
+    "\n",
+    "@pline.register_pipe\n",
+    "class rois_df(BasePipe) :\n",
+    "\n",
+    "    @stepmethod(requires = [\"trials_df.initial\"], version = \"1\")\n",
+    "    def step1(self):\n",
+    "        pass\n",
+    "\n",
+    "    @stepmethod(requires = [\"suite2p.step2\"], version = \"5\")\n",
+    "    def step2(self):\n",
+    "        return \"something\"\n",
+    "    \n",
+    "@pline.register_pipe\n",
+    "class figures(BasePipe) :\n",
+    "\n",
+    "    @stepmethod(requires = [\"compress_videos.step\"])\n",
+    "    def step1(self):\n",
+    "        pass\n",
+    "\n",
+    "    @stepmethod(requires = [\"figures.step1\"])\n",
+    "    def step2(self):\n",
+    "        pass\n",
+    "\n",
+    "\n",
+    "pline.pipes"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "C:\\test\\wm32\\2023-08-25\\001\\preprocessing_saves\n",
+      "preproc_data\\.suite2p(?:\\.(?P<step_name>(?:do_this)|(?:step2))(?:\\.(?P<version>[^\\.]*))?)?\\.pickle\n",
+      "['preproc_data.suite2p.do_this.pickle']\n",
+      "preproc_data\\.suite2p(?:\\.(?P<step_name>(?:do_this)|(?:step2))(?:\\.(?P<version>[^\\.]*))?)?\\.pickle\n",
+      "A single partial match was found. Please make sure it is consistant with expected behaviour. Expected : {'step_name': 'do_this', 'version': ''} , Found : {'step_name': 'do_this', 'version': None}\n"
+     ]
+    }
+   ],
+   "source": [
+    "session = Session(subject=\"wm32\",date=\"2023-08-25\",number=1,path=r\"C:\\test\", auto_path = True)\n",
+    "disk = PickleObject(session, pline.suite2p.do_this, extra = \"\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "preproc_data\\.suite2p(?:\\.(?P<step_name>(?:do_this)|(?:step2))(?:\\.(?P<version>[^\\.]*))?)?\\.pickle\n",
+      "preproc_data\\.suite2p(?:\\.(?P<step_name>(?:do_this)|(?:step2))(?:\\.(?P<version>[^\\.]*))?)?\\.pickle\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(disk.make_file_name_pattern())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "C:\\test\\wm32\\2023-08-25\\001\\preprocessing_saves\n",
+      "preproc_data\\.suite2p(?:\\.(?P<step_name>(?:do_this)|(?:step2))(?:\\.(?P<version>[^\\.]*))?)?\\.pickle\n",
+      "['preproc_data.suite2p.do_this.pickle', 'preproc_data.suite2p.pickle']\n",
+      "preproc_data\\.suite2p(?:\\.(?P<step_name>(?:do_this)|(?:step2))(?:\\.(?P<version>[^\\.]*))?)?\\.pickle\n",
+      "More than one partial match were found. Cannot auto select. Expected : {'step_name': 'do_this', 'version': ''} , Found : [{'step_name': 'do_this', 'version': None}, {'step_name': None, 'version': None}]\n",
+      "False\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(disk.check_disk())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "None\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(disk.save(\"caca\"))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 23,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "None\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(disk.save(\"caca\"))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "None\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(disk.save(\"caca\"))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "None\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(disk.save(\"caca\"))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "caca\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(disk.load())"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[('a', <dict_keyiterator object at 0x00000188E1C2BA60>, deque([0, 1]), deque([-1, -1]))]\n",
+      "['b', 'c']\n",
+      "<dict_keyiterator object at 0x00000188E1C2BA60>\n",
+      "b\n",
+      "c\n",
+      "<dict_keyiterator object at 0x00000188E1C2A020>\n",
+      "c\n",
+      "d\n",
+      "h\n",
+      "<dict_keyiterator object at 0x00000188E2DCF0B0>\n",
+      "h\n",
+      "<dict_keyiterator object at 0x00000188E308EC00>\n",
+      "<dict_keyiterator object at 0x00000188E308EB10>\n",
+      "[('e', <dict_keyiterator object at 0x00000188E2DCF0B0>, deque([0]), deque([-1]))]\n",
+      "['f']\n",
+      "<dict_keyiterator object at 0x00000188E2DCF0B0>\n",
+      "f\n",
+      "<dict_keyiterator object at 0x00000188E1C2BA60>\n",
+      "c\n",
+      "g\n",
+      "<dict_keyiterator object at 0x00000188E1C2A020>\n",
+      "h\n",
+      "<dict_keyiterator object at 0x00000188E308EB10>\n",
+      "h\n",
+      "<dict_keyiterator object at 0x00000188E1C2BA60>\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAApQAAAHzCAYAAACe1o1DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAArxUlEQVR4nO3dfZRddX0v/s85M3mYySNJDBHMQEIeKmkEwVxSbAgRDFVrKiJCJYahoF7Xz3v9qdQfDSrqbVn1gVr5+Vu9YuMKhmigl8RL23sVolFDhBRQJDe2eQIyaSQZMoEwmUkmmTnn90dImod5PmfmnLP367VW1mLO3vu7vyd/TN7s9/7uncnn8/kAAIB+ypZ6AgAAVDaBEgCAggiUAAAURKAEAKAgAiUAAAURKAEAKIhACQBAQQRKAAAKIlACAFAQgRIAgIIIlAAAFESgBACgIAIlAAAFESgBACiIQAkAQEEESgAACiJQAgBQEIESAICCCJQAABREoAQAoCACJQAABREoAQAoiEAJAEBBBEoAAAoiUAIAUBCBEgCAggiUAAAURKAEAKAgAiUAAAURKAEAKIhACQBAQQRKAAAKIlACAFAQgRIAgIIIlAAAFESgBACgIAIlAAAFqS71BAAAKk1LW3u82NQSR9pzMbQ6G+ePHxEjhqU3VqX3mwMA9MG2vc2xcmNDrNvSGA37WyN/0rZMRNSNq40FMyfGTZfVxfSzR5VqmiWRyefz+Z53AwBIp137W2Ppmk2xfvu+qMpmoiPXdXQ6vn3etAlx97WzY/K42kGcaekIlAAAXVj1VEPc9cjmaM/luw2Sp6vKZqI6m4kvLZoVN86pG8AZlgeBEgCgE99aty2+/ujWgse5feGM+MSC6UWYUfmyyhsA4DSrnmooSpiMiPj6o1vjwacaijJWuRIoAQBOsmt/a9z1yOaijvmFRzbHrv2tRR2znAiUAAAnWbpmU7T34X7J3mjP5WPpmk1FHbOcCJQAAK/btrc51m/f16cFOL3RkcvH+u37Yntjc1HHLReeQwkA8LqVGxt6fDRQRER787549RcPxKEdT0eu7WAMOeucGD3nfTHyooVdHlOVzcQDTzbEFxfNKva0S06gBAB43botjT2GyY6WV2LP926PyGRi1KXviaraMXFoxzPR9L/vjdyRQzF6zp90flwuH+u2NsYXQ6AEAEikg23t0dCLhTOv/nxFRD4Xb/yzb0VVzeiIiBj11nfHy//zq/Hq49+PkRf/UWSHDOv02Iam1mhpa0/caxrdQwkAEBE7m1qipzsn8/l8tG7ZEDXT/lNEPh8drQdO/KmZcknk21riyN4dXR8fES82tRR13uUgWfEYAKCfjrTnetwn13ogcm0tcfDZH8XBZ3/U+T4trxZ8nkojUAIARMTQ6l4Ut6+/YHDErAUxYvZVnY/zhvMLP0+FESgBACLi/PEjIhPRbe2drR0dmaE1kc/noub8i/t8jszr50ma5EVkAIA+yufz8ezTG2N4x8Fu98tkq6J25tujdcuGOPLyi2ds72g90O3xdeNrE7cgJ8IVSgAgxRoaGmLFihWxfPny2L59e5x37e2RmTk/8pHp8pizrrw5Du98LvZ87zMx8qJrYsiEusgdao4je3fE4Refjcn/96pOj6vKZmLBjIkD9VVKKpPP54v7KHgAgDLW2toaa9asieXLl8dPfvKTqKmpiQ984ANRX18f57z5krjmm4/3OEZHy6txYMMPonX7v0THwVeiqmZUDJlQF7VvnhejLv6jLo9b+6krYtrEUcX8OmVBoAQAEi+fz8cvf/nLWL58eTz44IPR3NwcV1xxRdTX18cHPvCBGDXqP0Leh5dtjF8+31TU1y9WZTNx+dTxseLWy4o2ZjkRKAGAxDqj0j7vvLj55ptjyZIlccEFF3R6zK79rXH1N34ebUV8vM+w6mys/dT8mDyutmhjlhOBEgBIlO4q7fnz50c22/Oa5FVPNcQdqzcVbU5fef/suGFOXdHGKzcW5QAAFa+rSnvZsmVnVNq9ceOcuth3sC2+/ujWguf25wtnJjpMRrhCCQBUsP5U2n2x6qmGuOuRzdGey/fpnsqqbCaqs5n48qJZiQ+TEQIlAFBhilFp98Wu/a2xdM2mWL99X1RlM90Gy+Pb502bEHdfOzux90yeTqAEAMpeX1ZpD5Rte5tj5caGWLe1MRqaWk95o04mjj20fMGMibF4bl0iHw3UHYESAChbA11p91dLW3u82NQSR9pzMbQ6G+ePH5HIN+D0lkAJAJSVwa60KZxACQCUXDlU2vSfQAkAlEy5Vtr0jUAJAAwqlXbyCJQAwIBTaSebQAkADBiVdjoIlABAUam000egBAAKptJON4ESAOg3lTYRAiUA0EcqbU4nUAIAPVJp0x2BEgDokkqb3hAoAYBTqLTpK4ESAFBpUxCBEgBSTKVNMQiUAJAyKm2KTaAEgBRQaTOQBEoASDCVNoNBoASAhFFpM9gESgBIAJU2pSRQAkAFU2lTDgRKAKgwKm3KjUAJABVApU05EygBoIyptKkEAiUAlBmVNpVGoASAMqDSppIJlABQQiptkkCgBIBBptImaQRKABgEKm2STKAEgAGk0iYNBEoAKDKVNmkjUAJAEai0STOBEgAKoNIGgRIA+kylDacSKAGgF1Ta0DWBEgC6odKGngmUAHAalTb0jUAJAKHShkIIlACkmkobCidQApA6Km0oLoESgFRQacPAESgBSDSVNgw8gRKAxFFpw+ASKAFIBJU2lI5ACUBFU2lD6QmUAFQclTaUF4ESgIqg0obyJVACUNZU2lD+BEoAyo5KGyqLQAlAWVBpQ+USKAEoKZU2VD6BEoBBp9KGZBEoARgUKm1ILoESgAGl0obkEygBKDqVNqSLQAlAUai0Ib0ESgAKotIGBEoA+kylDZxMoASgV1TaQFcESgC6pdIGeiJQAnAGlTbQFwIlABGh0gb6T6AESDmVNlAogRIghVTaQDEJlAApodIGBopACZBwKm1goAmUAAmk0gYGk0AJkBAqbaBUBEqACtdZpV1fXx9LliyJqVOnlnp6QAoIlAAVqKtK+5ZbbokrrrhCpQ0MKoESoEKotIFyJVAClDmVNlDuUh8oW9ra48WmljjSnouh1dk4f/yIGDGsutTTAlJOpQ1UklQGym17m2PlxoZYt6UxGva3xsl/AZmIqBtXGwtmToybLquL6WerkIDBodIGKlWqAuWu/a2xdM2mWL99X1RlM9GR6/qrH98+b9qEuPva2TF5XO0gzhRIE5U2UOlSEyhXPdUQdz2yOdpz+W6D5OmqspmozmbiS4tmxY1z6gZwhkCaqLSBJElFoPzWum3x9Ue3FjzO7QtnxCcWTC/CjIA0UmkDSZX4QLnqqYa4Y/Wmoo33lffPjhtcqQT6QKUNJF2iA+Wu/a1x9Td+Hm3tuaKNOaw6G2s/Nd89lUC3VNpAmiT6N9rSNZuivQ/3S/ZGey4fS9cU74onkBz5fD42bNgQH/nIR2LSpEmxePHiOHLkSCxbtiz27NkT999/f1x55ZXCJJA4iX3g4ra9zbF++76ij9uRy8f67ftie2NzTJvofieg80r705/+tEobSI3EBsqVGxu6fDRQ+4HGOPDk/4jDO38THa+9HJnqYTH8vLfEWQv+LKrHnt3j2FXZTDzwZEN8cdGsgZg6UAG6qrS/853vqLSB1Ensb7x1Wxq7fDxQ20tbo233v8aIN18RZ1390Rj51nfF4Z2/iT3f/4vIHT3c49gduXys29pY7CkDZU6lDdC5RF6hPNjWHg37W7vcXnPBnBjxe394yme10/5T7Flxe7Ru+WWM/P139HiOhqbWaGlr95pGSAGVNkD3EpmGdja1RHdLcbJDhp3473xHe+SOtEb1WW+M7LARcWTPjoheBMp8RLzY1BKzzhlT+ISBsqPSBui9RAbKIz08Jih3tC1ee+If4uCmtdHR3BRxUvzMtbUU7TxAZenqweN///d/H9dff70HjwN0IZGBcmh191cOXnns23Fw09oY9bZFMezc34vssBERmUzs+59fjejDYzl7Og9QGVTaAIVJZKA8f/yIyER0WXu3bNkQI37/HTHuqttOfJZvPxK5wwd7fY7M6+cBKpNKG6B4EhkoRwyrjrpxtbGzi4U5mcyZ/1C89sw/RuR7X2HXja+1IAcqTFeV9rJly7xLG6AAiU1EC2ZOjBUbd3b66KCaaXOi5f/8NLLDamPIhLpo2/1vcfjFZyNbM7pXY1dlM7FgxsRiTxkYICptgIGV2EB502V1sfyJFzvdNu7qj0ZkstGy+WeR7zgaw859c5x941/G3ge/0KuxO3L5WDy3roizBYpNpQ0weDL5fB9WoVSYDy/bGL98vqnLB5z3R1U2E5dPHR8rbr2saGMCxdFVpV1fX6/SBhhAiQ6Uu/a3xtXf+Hm0FfHxPsOqs7H2U/Nj8rjaoo0JFKazSru+vl6lDTBIEh0oIyJWPdUQd6zeVLTxvvL+2XHDHHU3lFpXlfYtt9yi0gYYZIm9h/K4G+fUxb6DbfH1R7cWPNafL5wpTEIJWaUNUJ4Sf4XyuFVPNcRdj2yO9ly+T/dUVmUzUZ3NxJcXzRImoURU2gDlLTWBMuLYPZVL12yK9dv3RVU2022wPL593rQJcfe1s90zCYNMpQ1QOVIVKI/btrc5Vm5siHVbG2Nn06kPP8/EsYeWL5gxMRbPrYtpE1VoMFis0gaoTKkMlCdb/Y//HDfe9l/i//mLO+PGD34gzh8/whtwYJCptAEqW+qT0/CqTBxtfCHOGXYkZp0zptTTgdTw4HGA5Eh9oAQGj1XaAMkkUAIDzru0AZJNoAQGhEobID0ESqBoVNoA6SRQAgVTaQOkm0AJ9ItKG4DjBEqg11TaAHRGoAR6pNIGoDsCJdAplTYAvSVQAieotAHoD4ES6LTS/tSnPhVLliyJCy64oNTTA6DMCZSQUl1V2vfdd1/Mnz9fpQ1ArwmUkCIqbQAGgkAJKaDSBmAgCZSQUCptAAaLQAkJotIGoBQESkgAlTYApSRQQoVSaQNQLgRKqCAqbQDKkUAJFUClDUA5EyihTKm0AagUAiWUEZU2AJVIoIQyoNIGoJIJlFAiKm0AkkKghEGk0gYgiQRKGAQqbQCSTKCEAaLSBiAtBEooIpU2AGkkUEIRqLQBSDOBEvpJpQ0AxwiU0AcqbQA4k0AJvaDSBoCuCZTQBZU2APSOQAknUWkDQN8JlBAqbQAohEBJaqm0AaA4BEpSRaUNAMUnUJIKKm0AGDgCJYml0gaAwSFQkigqbQAYfAIliaDSBoDSESipWCptACgPAiUVRaUNAOVHoKQiqLQBoHwJlJQtlTYAVAaBkrKi0gaAyiNQUhZU2gBQuQRKSkalDQDJIFAyqFTaAJA8AiWDQqUNAMklUDJgVNoAkA4CJUWl0gaA9BEoKQqVNgCkl0BJv6m0AYAIgZI+UmkDAKcTKOkVlTYA0BWBki6ptAGA3hAoOYVKGwDoK4GSiFBpAwD9J1CmmEobACgGgTJlVNoAQLEJlCmh0gYABopAmWAqbQBgMAiUCaPSBgAGWyafz+dLPYlSuPXWW+MXv/hFtLS0xEsvvRRveMMbYsyYMfGWt7wlHn744VJPr886q7RvvvlmlTYAMOBSe4WysbExtm/ffuLnl19+OV5++eUYP358CWfVNyptAKAcpPYK5dNPPx1z5sw54/Mf//jHsXDhwhLMqHe6qrTr6+tV2gBASaQ2UEZEvOc974kf/ehHkcvlIpPJxNve9rbYuHFjZDKZUk/tDCptAKBcpTpQnn6VstyuTnZVadfX16u0AYCykepAGRExZ86cePrpp+O8886LF154oeRXJ1XaAEClSe2inOM+9rGPxdNPPx2LFy8uaZj04HEAoFKlPlBeeMncqPm9P4yaWe+IR36zO+ZOGR8TRw8flHNbpQ0AJEEqK++1v90T9zy2NbY1Hoz23JlfvzqbiekTR8Zn3jkjrr5wUlHPrdIGAJImVYFy4/NN8bEHnolXDx3t9TFja4bEtxdfGpdNLez5lFZpAwBJlZpA+emHno3Vv97d7+Pf/9Zz428+eHGn21avXh2f/OQnY926dTFt2rQTn1ulDQCkQSoSzeJlTxYUJiMiVv96dyxe9uQZn69duzZuuOGG+Pd///f47ne/G/l8PjZs2BAf+chHYtKkSbF48eI4cuRILFu2LPbs2RP3339/LFiwQJgEABIj8Vcou7oy+er6lXFgww/iTf91ZbQf2BuvrL0vjjS+EPmjbfHGW+6NoWdP7XS86y45N+65/uKIiNi4cWNceeWV0dbWFvl8PkaMGBGTJk2KHTt2qLQBgNRI9Crvjc839XhlMt/RHi+v+evIVA+Ns676SGSqh0XVmIld7v/wr3bHBy+dHCMP7YmFCxeeCJMRES0tLTFlypT4zne+o9IGAFIj0YHyYw880+M+7Qcao+O1xhj3rv8Soy66plfj3nb/xtj+1evi8OHDp3xeVVUVEyZMiAULFvRrvgAAlSixl9DW/nZPr1Zz5w4diIiI7LARvR67+Ug+sm96yxmfd3R0xOrVq6Otra33EwUAqHCJvUJ5z2Nbe7Xfyw//ZURE7PvhX8e+iKgaOT7O/c/fiUz10G6Pm/eJr8Wqm98Su3fvPuVPJpOJoUO7PxYAIEkSGyi3NR7s1X7Z2jGRaz0Qwyb/fkSuI9p2/2s0/e//Nya89zPdHre98WCMHTs2xo4dG7NmzSrGlAEAKlIiK++9rx3u9A04nakee05ERIy69I9j0oe/FiMveU+0bF4XRxpf6Pa49lw+Gl873O0+AABpkMhAufGFpl7vWztz7ik/j770jyMi4tCOp3s89sk+nAcAIKkSGSgPHeno9b5VI099pWL12DdGZLLRfmBvUc8DAJBUiQyUNUOr+n9wJjM45wEASIhEBsq5U8b3vNPrOg6eWlu3v/K7iHwuqsecXdTzAAAkVSID5cTRw6M627srja1bTn0/92vP/FNERNRMvbTb46qzmZg4enj/JggAkCCJDJQREdMnjuzVfh0t+yMi4vDzv4p9/3hPHPzVP0fthfO7fJd3REQ+n4/2pl1x1113xY4dO4oyXwCASpXYQPmZd87o1X5j3/6hiIg4+NufxaEdT8WoS/44Jrz7k90ek8lk4uKqXfGNb3wjpk2bFldccUV897vfjebm5oLnDQBQaTL5fL53D2ysQBd/+dFevX6xr8bWDIlnv7AwWltb44c//GEsX7481q5dGzU1NXHdddfFLbfcEvPnz49sNrF5HQDghEQHyo3PN8UN33my5x376MGPzI3Lpp66IGfXrl2xYsWKWL58eWzbti3OO++8uPnmm2PJkiVxwQUXFH0OAADlItGBMiLi0w89G6t/vbto4113yblxz/UXd7k9n8/HE088EcuXL49Vq1ZFc3NzzJs3L+rr6+P666+PUaNGFW0uAADlIPGBMiJi8bIn4/Hthb/VZt60CbHi1st6vb9KHABIg1QEyojCr1T2dGWyJypxACCpUhMoI47dU/mxB57p00KdsTVD4tuLLz3jnsn+UokDAEmTqkB53Nrf7ol7Htsa2xoPRntH7ozXLVZnMzF94si4feHMuOrNPb8xp79U4gBAEqQyUJ7stk98Or7/k6di1kWXxOf/4rMxd8r4krwBRyUOAFSq1F8CGx5H4tC/PR5j9m2ORRedW7LXKU6ePDmWLl0aW7ZsiQ0bNsTChQs9OB0AqAipD5TlJpPJxOWXXx733Xdf7NmzJ1auXBnDhw+P2267LSZNmhRLliyJdevWRS6XK/VUAQAiQqAsa7W1tfGhD30oHn300di5c2fceeed8eSTT8Y73vGOmDp1qneJAwBlQaCsECpxAKBcCZQVRiUOAJQbgbKCqcQBgHIgUCaEShwAKBWBMmFU4gDAYBMoE0wlDgAMBoEyJVTiAMBAEShTRiUOABSbQJliKnEAoBgESiJCJQ4A9J9AySlU4gBAXwmUdEklDgD0hkBJr6jEAYCuCJT0iUocADidQEm/qcQBgAiBkiJRiQNAegmUFJVKHADSR6BkwKjEASAdBEoGhUocAJJLoGRQqcQBIHkESkpGJQ4AySBQUhZU4gBQuQRKyopKHAAqj0BJ2VKJA0BlECipCCpxAChfAiUVRSUOAOVHoKRiqcQBoDwIlCSCShwASkegJFFU4gAw+ARKEkslDgCDQ6AkFVTiADBwBEpSpTeV+E9/+lOVOAD0gUBJanVViV911VUxZcqU+MIXvqASB4BeECghTq3EH3/88bjmmmvib//2b1XiANALAiWcJJPJxNvf/naVOAD0gUAJXVCJA0DvCJTQC6evEleJA8B/ECihD6wSB4AzCZTQTypxADhGoIQiUIkDkGYCJRSRShyANBIoYYCoxAFIC4ESBoFKHIAkEyhhEKnEAUgigRJKRCUOQFIIlFAGVOIAVDKBEsqIShyASiRQQplSiQNQKQRKqAAqcQDKmUAJFUQlDkA5EiihQqnEASgXAiUkgEocgFISKCFBVOIAlIJACQmlEgdgsAiUkAIqcQAGkkAJKaISB2AgCJSQUipxAIpFoARU4gAURKAETlCJA9AfAiXQKZU4AL0lUAI9UokD0B2BEug1lTgAncnk8/l8qSdRChMnToz9+/dHLpeL438FVVVVMXLkyHj11VdLOzmoMLt27YoVK1bE8uXLY9u2bVFXVxc333xz3HzzzXHBBReUenoADLDUBspMJtPltpT+lUDB8vl8PPHEE7F8+fJ48MEH47XXXot58+ZFfX19XH/99TFq1KhSTxGAAZDaynv+/Pmdfn7hhRcO8kwgOU6uxF966SWVOEBKpPYKZXt7ewwZMuSMz1955ZUYO3bs4E8IEkwlDpBsqQ2UERFXXnll/PznPz/x84UXXhibN28u4Ywg2VTiAMmU6kB5+lVKVydh8LS2tsYPf/jDWL58eaxduzZqamriuuuui/r6+rjyyisjm03tHTkAFSfVgTIiYurUqfHCCy/E6NGj48CBA6WeDqSSShygsqU+UP7yV/8nrr7p43HnF74Usy+cGXOnjI+Jo4eXelqQSuVWibe0tceLTS1xpD0XQ6uzcf74ETFiWPWgzgGgEqQyUK797Z6457Gtsa3xYLTnzvz61dlMTJ84Mj7zzhlx9YWTSjBDoFSV+La9zbFyY0Os29IYDftb4+TfEJmIqBtXGwtmToybLquL6We75xMgImWBcuPzTfGxB56JVw8d7fUxY2uGxLcXXxqXTR0/gDMDujMYlfiu/a2xdM2mWL99X1RlM9HRyf9sHnd8+7xpE+Lua2fH5HG1RZkDQKVKTaD89EPPxupf7+738e9/67nxNx+8uHgTAvqsr5X43/3d38XmzZvjm9/8ZlRVVXU57qqnGuKuRzZHey7fbZA8XVU2E9XZTHxp0ay4cU5dv78XQKVLRaBcvOzJeHx7U8Hj/OG08fHArXOLMCOgUD1V4h0dHXH22WfHK6+8Erfddlvcd999nb4h61vrtsXXH91a8HxuXzgjPrFgesHjAFSixAfKvl6ZfHX9yjiw4Qdx3h3/1On26y45N+65/uIizQ4ohs4q8blz58ZDDz10Yp/Pfvaz8ZWvfOWU41Y91RB3rN5UtHl85f2z4wZXKoEUSvSD3jY+31RQzd2Zh3+1OzY+X/jVTqB4Jk+eHEuXLo0tW7bEhg0b4pprronVq1efss9Xv/rVUwLlrv2tcdcjxX2RwRce2Ry79rcWdUyASpDoQPmxB56pqHGBwhx/l/hf/dVfRWflyx133BF33nlnREQsXbOp06c8FKI9l4+la4p3xROgUiQ2UK797Z4+rebui1cPHY2f/OveARkbKNyDDz4YHR0dUVVVFdXVpz438p577olte5tj/fZ9fVqA0xsduXys374vtjc2F3VcgHKX2Cf03vNYzzfZH961OfY/9t/j6Ms7T3yWGVoTERH5jqORqRrS1aHx9Ue3xFVvPrvwiQJFN2PGjHj3u98d55xzTpx77rkn/pxzzjkxZcqU+MbPG3p8NFBExOGdz8Ur674bR17eGdWjxsfoy66LjoP7u73PuiqbiQeebIgvLpo1EF8NoCwlNlBuazzY7fYjjS9G44Ofj3xHe0QmE0MnTY+j+3ZGpmpI5CMif7St20DZ0/hA6SxcuDAWLlzY5fZ1W37VY5g8smdH7H3orqgaOS7GzrspIpeLAxt+ENnaMd0e15HLx7qtjfHFECiB9EhkoNz72uEe7416df0Dx8JkPh+TltwTw944PY7u2xW/W/Z/RUREZtiIbo9vz+Wj8bXDXtMIFeZgW3s09GLhzKuPr4xMNhuTFn81qkcde7FB7Zv/MH73nY/3eGxDU2u0tLV7TSOQGom8h3LjC92vws7nOuLwC7+KyGSiZvplMeyNx54dN2TC5KiZeklERKfPqzvdkz2cByg/O5taoqc7J/O5jjj84m+iZvrcE2EyImLIWedEzdRLezxHPiJebGopbKIAFSSRgfLQkY5ut+daX4t8+5GIXEcMecN5p2yrHndu0c4DlJ8j7bke9+loPRD59rYYctY5Z2yrPuuNRTsPQFIkMlDWDO36FWuVeB6geIZWD86vvcE6D0A5SORvvLlTxne7PVs7OjLVQyOyVaes8I6IaN/f+weh93QeoPycP35E9HRDS1XtmMhUD42jr/zujG3tr7zU4zkyr58HIC0SGSgnjh4e1dmu/8nIZKti+JRLIvL5OLRtY7S9tC0iIo7u2xWHnv9VRESnD0U+WXU2Y0EOVKCaIdk4e0T37UImWxXDz7soDm17Mtqb/+Ne6aOv/C4OPd/ziw3qxtdakAOkSmJ/402fODL+dU/XDxceO++mY/8w5Dpiz4rbX39sUENka0ZHrvXVyLe1RGb4yG7HByrH9u3b4/7774/vfe970Tzjj2Ls2xZFd3c5jpl3Uxxa8evY88BnY9Rb3xWRz0XzM/8UQyacF0cbn+/yuKpsJhbMmFj8LwBQxhJ5hTIi4jPvnNHt9qETp8TZN/y3GDJhckQ+F0de2hr5o4cj33Hs7TqZIcO6Pf72hTOLNldgYDQ3N8eyZcti3rx5MX369Lj33nvjmmuuib/7zE3dhsmIiGGTpsXE678UVcNHxqvrH4iDv3ksxsxbHDXnX3TslpkudOTysXhuXXG/CECZS+wVyqsvnBRja4Z0+/rF4XW/H+fc+v/1eeyxNUO8JQfKVC6Xi5/97GexfPnyePjhh+PQoUPxzne+M77//e/H+973vqipOfY2rH/avTF++XxTtw84rzn/oqi55ZunfNb48F9G1ajO75+uymbi8qnjY9rEUcX7QgAVILFXKCMivr245+fFldO4QP9t3749Pv/5z8eUKVPiqquuio0bN8bnPve52LlzZ/z4xz+OP/3TPz0RJiMi7r52drf3WkdE5I62nfLz0f2749COp2N43exO96/OZuLuazvfBpBkib1CGRFx2dTx8f63nhurf937lds9ue6Sc+OyqVZ3Qzlobm6Ohx56KJYvXx6PP/54jB49Om688caor6+PuXPndvuCgsnjauNLi2bFHas3dbnP7/77bTFi9lVRPXZStL/2chz81f+KTFV1jL7suk73//KiWTF5XG3B3wug0iQ6UEZE/M0HL47G5sPx+PbC32ozb9qEuOf6iwufFNBvva20e+PGOXWx72BbfP3RrZ1uHz710mj57S+io+WVyFQPiWHn/F6Mnb8khnTyAoQ/Xzgzbpjj3kkgnTL5np6PkxCffujZgq5UXnfJucIklNDJq7QbGhpixowZUV9fH4sXL47JkycXNPaqpxrirkc2R3su3+09laerymaiOpuJLy+aJUwCqZaaQBkRsfH5pvjYA890u1DndGNrhsS3F1+q5oYSKKTS7qtd+1tj6ZpNsX77vqjKZroNlse3z5s2Ie6+draaG0i9VAXK49b+dk/c89jW2NZ4MNo7+UejOpuJ6RNHxu0LZ1rNDYOsq0q7vr6+z5V2f2zb2xwrNzbEuq2N0dDUGif/hsjEsYeWL5gxMRbPrbOaG+B1qQyUJ/vBD/85bv2Lv44lf/aRePfCq2LulPHegAMlMJCVdn+1tLXHi00tcaQ9F0Ors3H++BHegAPQidT/ZhwzNBOH/u3xuGjkh2LRRWfeaA8MnMGstPtjxLDqmHXOmJLOAaASpD5QAoOrmKu0ASgPAiUwKDqrtD/3uc+VtNIGoDgESmDAlHulDUBxCJRAUam0AdJHoASKQqUNkF4CJdBvKm0AIgRKoI9U2gCcTqAEekWlDUBXBEqgSyptAHpDoAROodIGoK8ESiAiVNoA9J9ACSmm0gagGARKSBmVNgDFJlBCSqi0ARgoAiUkmEobgMEgUELCqLQBGGwCJSSEShuAUhEooYKptAEoBwIlVBiVNgDlRqCECqHSBqBcCZRQxlTaAFQCgRLKjEobgEojUEKZUGkDUKkESighlTYASSBQwiBTaQOQNAIlDBKVNgBJJVDCAFJpA5AGAiUUmUobgLQRKKFIVNoApJVACQVQaQOAQAl9ptIGgFMJlNBLKm0A6JxACd1QaQNAzwRKOI1KGwD6RqCE16m0AaB/BEpSrbNK+4Ybboj6+vr4gz/4A5U2APSCQEnqqLQBoLgESlJDpQ0AA0OgJNGs0gaAgSdQkjgqbQAYXAIliaHSBoDSECipaCptACg9gZKKo9IGgPIiUFIxduzYEffff3/cf//9Km0AKCMCJWWtubk5/uEf/iGWL18e69evV2kDQBkSKCk7Km0AqCwCJWXj9Ep7+vTpceedd8aHP/xhlTYAlDGBkpLqrNL2Lm0AqCwCJYNOpQ0AySJQMmhU2gCQTAIlA0qlDQDJJ1BSdCptAEgXgZKiUWkDQDoJlBREpQ0ACJT0WWeV9tVXXx0rV66M973vfVFbW1vqKQIAg0igpNdU2gBAZwRKuqXSBgB6IlByBpU2ANAXAiUnqLQBgP4QKFNOpQ0AFEqgTCGVNgBQTAJliqi0AYCBIFAmnEobABhoAmUCqbQBgMGUyefz+VJPohSWLl0a//Iv/xL79u2L3/zmNzFz5sx405veFBdeeGHce++9pZ5ev3RWadfX16u0AYABldpAWVNTE4cPHz7j86qqqmhvby/BjPpHpQ0AlFq21BMolZtuuqnTz9/znvcM8kz6LpfLxU9/+tNYsmRJTJo0KW677bYYPnx4rFy5Ml566aW477774vLLLxcmAYBBkdorlIcPH46RI0dGR0fHic8ymUw0NjbGhAkTSjizrqm0AYBylNpFOcOHD4/6+vpYtmzZic/e+973ll2YVGkDAOUutVcoI45dpRwxYkTkcrmIiHj55ZfLIlB2tUq7vr7eKm0AoOykOlBGRLzrXe+KH/3oR3HRRRfFs88+W9K5qLQBgEqU+kDZ9NrBWPj+m+Jv7/1WjBs7Os4fPyJGDBu8OwFU2gBApUtloNy2tzlWbmyIdVsao2F/a5z8F5CJiLpxtbFg5sS46bK6mH72qKKfX6UNACRJqgLlrv2tsXTNpli/fV9UZTPRkev6qx/fPm/ahLj72tkxeVzhIU+lDQAkUWoC5aqnGuKuRzZHey7fbZA8XVU2E9XZTHxp0ay4cU5dp/vs3r077r333vj85z8fI0eOPGWbShsASLpUPDboW+u2xdcf3dqvYzteD6B3rN4U+w62xScWTD9l+759+2LBggWxbdu2uOCCC+KjH/2od2kDAKmS+CuUq55qiDtWbzrj81fXr4wDG34Qb/qvK6Oqdkyvx/vK+2fHDa9fqWxubo758+fHc889F7lcLmbPnh1/8id/otIGAFIl0Vcod+1vjbse2VzUMb/wyOa4/IIJ8YbabLz3ve+N55577sTbdp577rnYsWNHfOhDH1JpAwCpkehAuXTNpmjvw/2SvdGey8cdq5+LF7776XjiiSdO2ZbNZuPjH/94fO1rXyvqOQEAylm21BMYKNv2Nsf67fv6tACnNzpy+diwoyme2rorIo6FyKqqqog49jigFStWnPJ+cACApEvsFcqVGxt6fDRQRESurSVe+el3o3XbkxGRj9oZl8e4hf85skOGd3lMVSZi0ae+FlePeyV+97vfxe7du2PXrl2xc+fOqK6ujo6OjhMhEwAg6RIbKNdtaezV1cl9P/xKVI85O86af3Mc2bs9Dv7m0aiqHRNnLbily2M68hH7hp0dH//4jcWcMgBARUpkoDzY1h4N+1t7te+Qs6fGhHd/8sTPHYea4+Bzj3UbKCMiGppao6WtfVBf0wgAUI4SeQ/lzqaW6O2dk6Pe+q5Tfh7+plmRO/Ra5Nq6D6T5iHixqaV/EwQASJBEBsoj7ble71s9+g2n/JwdfuxNN7nDB4t6HgCApEpkoBxa3Yevleli3148771P5wEASKhEJqLzx4+IgX6ceOb18wAApF0iA+WIYdVRN25g35ddN77WghwAgEhooIyIWDBzYlRlB+Y6ZVU2EwtmTByQsQEAKk1iA+VNl9UV/S05x3Xk8rF4bt2AjA0AUGky+XwvVp9UqA8v2xi/fL6pqMGyKpuJy6eOjxW3Xla0MQEAKllir1BGRNx97eyoLnLtXZ3NxN3Xzi7qmAAAlSzRgXLyuNr40qJZRR3zy4tmxeQBXvADAFBJEh0oIyJunFMXty+cUZSx/nzhzLhhjnsnAQBOluh7KE+26qmGuOuRzdGey/fpnsqqbCaqs5n48qJZwiQAQCdSEygjInbtb42lazbF+u37oiqb6TZYHt8+b9qEuPva2WpuAIAupCpQHrdtb3Os3NgQ67Y2RkNTa5z8F5CJYw8tXzBjYiyeWxfTJo4q1TQBACpCKgPlyVra2uPFppY40p6LodXZOH/8CG/AAQDog9QHSgAACpP4Vd4AAAwsgRIAgIIIlAAAFESgBACgIAIlAAAFESgBACiIQAkAQEEESgAACiJQAgBQEIESAICCCJQAABREoAQAoCACJQAABREoAQAoiEAJAEBBBEoAAAoiUAIAUBCBEgCAggiUAAAURKAEAKAgAiUAAAURKAEAKIhACQBAQQRKAAAKIlACAFAQgRIAgIIIlAAAFESgBACgIAIlAAAFESgBACiIQAkAQEEESgAACiJQAgBQEIESAICCCJQAABREoAQAoCACJQAABfn/AcyT2IWRQrhtAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "import networkx as nx\n",
+    "from collections import deque\n",
+    "\n",
+    "def tree_layout(G):\n",
+    "\n",
+    "    roots = [node for node in G.nodes if G.in_degree(node) == 0]\n",
+    "    if not roots:\n",
+    "        print(\"Error: graph has no roots!\")\n",
+    "        return None\n",
+    "\n",
+    "    pos = {}\n",
+    "    base_x = 0\n",
+    "    next_x = 0\n",
+    "    for root in roots:\n",
+    "        qx = deque([next_x + xt for xt in range(0, G.out_degree(root))])\n",
+    "        qy = deque([0 - 1]*G.out_degree(root))\n",
+    "        next_x = base_x\n",
+    "\n",
+    "        visited = {root}\n",
+    "        deque_content = [(root, iter(G[root]), qx, qy)]\n",
+    "        print(deque_content)\n",
+    "        print(list(iter(G[root])))\n",
+    "        queue = deque(deque_content)\n",
+    "\n",
+    "        while queue:\n",
+    "            parent, children, qx, qy = queue.popleft()\n",
+    "            print(children)\n",
+    "            for child in children:\n",
+    "                print(child)\n",
+    "                #child = next(children)\n",
+    "                if child not in visited:\n",
+    "                    x = qx.popleft()\n",
+    "                    y = qy.popleft()\n",
+    "                    pos[child] = (x, y)\n",
+    "                    visited.add(child)\n",
+    "                    qx_child = deque([x+ xt for xt in range(0, G.out_degree(child))])\n",
+    "                    qy_child = deque([y - 1]*G.out_degree(child))\n",
+    "                    queue.append((child, iter(G[child]), qx_child, qy_child))\n",
+    "            #except StopIteration:\n",
+    "            \n",
+    "\n",
+    "        pos[root] = (base_x, max([val[1] for val in pos.values()])+1) # place the root\n",
+    "        base_x = base_x + max([val[0] for val in pos.values()]) + 1\n",
+    "\n",
+    "    return pos\n",
+    "\n",
+    "# Use the function like this:\n",
+    "G = nx.DiGraph()\n",
+    "G.add_edge('a', 'b')\n",
+    "G.add_edge('a', 'c')\n",
+    "G.add_edge('b', 'c')\n",
+    "G.add_edge('b', 'd')\n",
+    "G.add_edge('b', 'h')\n",
+    "G.add_edge('f', 'c')\n",
+    "G.add_edge('c', 'h')\n",
+    "G.add_edge('e', 'f')\n",
+    "G.add_edge('f', 'g')\n",
+    "G.add_edge('g', 'h')\n",
+    "pos = tree_layout(G)\n",
+    "nx.draw(G, pos, with_labels=True)\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "NodeView(('prefetch.step', 'rois_df.step1', 'blabliblou.herewego', 'suite2p.do_this', 'suite2p.step2', 'trials_df.initial', 'rois_df.step2', 'side_step.step1', 'side_step.step2'))"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "[('blabliblou.herewego', <dict_keyiterator object at 0x0000017FC214FAB0>, deque([0]), deque([-1]))]\n",
+      "['prefetch.step']\n",
+      "<dict_keyiterator object at 0x0000017FC214FAB0>\n",
+      "prefetch.step\n",
+      "<dict_keyiterator object at 0x0000017FC1FD02C0>\n",
+      "suite2p.do_this\n",
+      "side_step.step1\n",
+      "<dict_keyiterator object at 0x0000017FBFEF7AB0>\n",
+      "suite2p.step2\n",
+      "<dict_keyiterator object at 0x0000017FBFEF5F30>\n",
+      "side_step.step2\n",
+      "<dict_keyiterator object at 0x0000017FC1FD02C0>\n",
+      "rois_df.step2\n",
+      "<dict_keyiterator object at 0x0000017FBFEF7AB0>\n",
+      "<dict_keyiterator object at 0x0000017FBFEF5F30>\n",
+      "[('trials_df.initial', <dict_keyiterator object at 0x0000017FBFEF7AB0>, deque([0]), deque([-1]))]\n",
+      "['rois_df.step1']\n",
+      "<dict_keyiterator object at 0x0000017FBFEF7AB0>\n",
+      "rois_df.step1\n",
+      "<dict_keyiterator object at 0x0000017FBFEF5F30>\n",
+      "prefetch.step\n",
+      "<dict_keyiterator object at 0x0000017FC214FAB0>\n",
+      "suite2p.do_this\n",
+      "side_step.step1\n",
+      "<dict_keyiterator object at 0x0000017FBFEF5F30>\n",
+      "suite2p.step2\n",
+      "<dict_keyiterator object at 0x0000017FBFF489A0>\n",
+      "side_step.step2\n",
+      "<dict_keyiterator object at 0x0000017FC214FAB0>\n",
+      "rois_df.step2\n",
+      "<dict_keyiterator object at 0x0000017FBFEF5F30>\n",
+      "<dict_keyiterator object at 0x0000017FBFF489A0>\n"
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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WzMNI6Jao0KXvDMzMzFt2jS4u7tDoVDA0dERPXv2xJkzZwAA7u7uekccunbtqtNZPX4P1ahRo7B69WoAhWGz6KeIRqNBeHg4vL29YWpqCicnJ0yYMAH379/XljExMdGGSQCIOJkAuUyCefMXAAAFKYnadXnxFxC/uD+yrxzG/d83IHHlcCQsewXJ2xZA9eBemedBKsjF8LFvl3geunbtir179yI+Pl57LI/eW5afn4958+bBy8sLCoUCrq6ueP/995Gfn6+7H0nC5MmTERERgRYtWsDU1BS+vr44fPiwTrlOnToVe8tPs2bN4O3tjStXrpR5PETlUdb3X989lOnp6Rg1ahSsrKxgbW2NkJCQEi+jXr16FcHBwbC1tYWpqSnat2+P3bt3V7idv/zyCzp37gxra2tYWFigRYsWmDt3LgDg0KFD6NChAwAgdV844hf3R/zi/si6EKndPv/2NSRt/hgJK4YgYekruBsxG3l//6l7XNERiF/cHwWpibi3azESlr+KxPDXkPbLfyBpCrDpROn3UsbExOCVV16Bs7MzTE1N0bhxYwwbNgwZGRkACr/72dnZ2LBhg7YPebRvvXXrFt588004OTlBoVDA29sb33zzjc4+Dh06BEmSsHnzZsydOxfOzs5QKpUICgpCYmKiTtnHwyQADB48GADYhxBRuVRohHLixInYtm0bJk+ejFatWiE1NRVHjhzBlStX0K5du0o3YsKECbh9+zZ++eUXbNy4Ue/69evXY/To0Zg6dSpu3ryJVatW4ezZszh69KjekZGoa8lQawTU2YWhU27eoFiZjGNbAABWfsFQ56Qj84/dSPrxQ7iM/hdkxiVftkv+eRXirx3Du+9M0XsePvjgA2RkZODvv//GihUrABRevgIKw3FQUBCOHDmC8ePHo2XLlrh48SJWrFiB69evF7tn6vfff8fmzZsxdepUKBQKrFmzBr1798apU6dKvZQthEBSUhK8vb1LLENUERX9/gshMHDgQBw5cgQTJ05Ey5YtsXPnToSEhBQre/nyZfj7+6NRo0aYPXs2lEoltmzZgkGDBmH79u3acFOWy5cvo3///mjTpg0WLFgAhUKB2NhYHD16FADQsmVLLFiwAB9//DEsnu0NRePC74eicUsAQG7ceSRvnQeFsxes/V8DJBmyLvyCpB/mwvmNJVA0bKGzv3u7lsDIyhE2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V1vzsgsSUZW6e/duqT/67s0sDfsHIqKqU+cnGRvWwQ0pWflYevC6wXXN7NUCQzu4VUGriKiiXFxcSl0fEhKC9evXV6hO9g9ERFWjTt9D+agfTydg3u7LUGlEhe6ZksskGMkkLAjy5n8WRDUoMjKy1PUNGzas9Pyr7B+IiAxTbwIlACSm5WDuzouIjk2BXCaV+h9H0fouXvYIG+zDy1hEdRz7ByKiyqtXgbJITFImIk4mIOp6MuJTc3TWSQDc7MzRrbkjhnd0g5ejZc00kohqxKP9Q0JqDh7tINk/EBHpVy8D5aPOXvwTfj3648uvv0X7ds/C3U6pfcMFEdVv2fkqxKVm46FKAxMjGfsHIqIS1Pue0cxYhoLkm/CyMYJ3Q6uyNyCiekOpYL9ARFQedXraICIiIiKqfgyURERERGQQBkoiIiIiMggDJREREREZhIGSiIiIiAzCQElEREREBmGgJCIiIiKDMFASERERkUEYKImIiIjIIAyURERERGQQBkoiIiIiMggDJREREREZhIGSiIiIiAzCQElEREREBmGgJCIiIiKDMFASERERkUEYKImIiIjIIAyURERERGQQBkoiIiIiMggDJREREREZhIGSiIiIiAzCQElEREREBmGgJCIiIiKDMFASERERkUEYKImIiIjIIAyURERERGQQBkoiIiIiMggDJREREREZhIGSiIiIiAzCQElEREREBmGgJCIiIiKDGNV0A2rK7t27cfHiRdy7dw8AsGHDBhw6dAheXl4YOnRoDbeOiIiIqPaQhBCiphtRE5599lmcP38eRkZGUKlUkMvlUKvVaNy4MRITE2u6eURERES1Rr295D1t2jQAgEqlAgCo1WpIkqRdTkRERETlU29HKFUqFby8vJCQkICiU2Bra4uEhAQolcoabh0RERFR7VFvRyiNjIwQGhqqDZOSJGHu3LkMk0REREQVVG9HKIHCUcomTZrg9u3baNCgAW7fvs1ASURERFRB9XaEEigcpZw6dSoAICQkhGGSiIiIqBLq9QglAGRk52Hmgs8wZtwEWJibwt1OCaWi3s6mRERERFRh9TJQxiRlIuJkAqKuJSMhLQePngAJgJutObq1cMQbfm5o5mRZU80kIiIiqhXqVaBMTMvB3J0XER2bArlMglpT8qEXre/iZY+wwT5wtTV/gi0lIiIiqj3qTaD88XQC5u2+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",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from networkx import draw\n",
+    "g = pline.get_graph()[1]\n",
+    "display(g.nodes)\n",
+    "pos = tree_layout(g)\n",
+    "draw(g, pos= pos, with_labels = True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "NodeView(('prefetch.step', 'other_steps.step1', 'suite2p.do_this', 'suite2p.step2', 'demoPipeClass.initial', 'other_steps.step2', 'side_step.step1', 'side_step.step2'))"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAApQAAAHzCAYAAACe1o1DAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAACSCUlEQVR4nOzdZ1RUVxsF4D0z9A4KAkpRUSJFE40dYxdbiIWA0ShYY9RYYokajWIUe0kssXeNYC+xoth7NNaoqEGsICBIUWBmzvfDj4kTijQdYPazFivOre+9BNyee+45EiGEABERERFRAUk1XQARERERlWwMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCgMlERERERUKAyURERERFQoDJREREREVCg6mi6AiIiI6ENLSZMjMi4F6XIl9HSkcC5jDGN9xqKC4p0jIiIirRARnYQN56IQfjsGUfGpEG+tkwBwtDJCU1cbdKvriCrlTDVVZokkEUKId29GREREVDI9jE/F2O3XcOJuLGRSCRTKnKNP5vpGLmUR3NETDlZGH7DSkouBkoiIiEqtTReiMGHXDciVItcg+V8yqQQ6UgmCfNzRpbbje6ywdGCgJCIiolJpQXgEZh28U+jjjGhVFYOaVimCikovvuVNREREuQoMDISzs/M7t4uMjIREIsHq1avfe03vsulCVJGESQCYdfAOQi5EFcmxSisGSiIiIioVnjx5gokTJ2L/sTOYsOtGkR77p1038DA+tUiOFRwcjB07dhTJsd5l27Zt8Pf3R6VKlWBkZARXV1cMHz4cCQkJRXoePvImIiKiXGVkZECpVEJfXz/X7SIjI1GxYkWsWrUKgYGBH6a4t1y8eBG1a9dG/Z7jEG1XP199Jt9F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n4a3tzeDpBZgoCQiIqICEUJg9+7dqFOnDtq3bw99fX0cOnQIJ0+eRKtWrRgktQgDJREREeWLEAK7du3Cp59+Ch8fHxgZGeHw4cM4fvw4WrRowSCphRgoiYiIKE+EENixYwdq1aqFL774AqampggPD8exY8fQrFkzBkktxkBJREREuVIqldi2bRs++eQTdOzYERYWFjh69KhqthsiBkoiIiLKllKpxNatW/HJJ5+gc+fOKFu2LI4fP66a7YYoEwMlERERqVEqldi8eTNq1KgBX19f2NjY4MSJEwgLC0OjRo00XR4VQwyUREREBABQKBQICQlB9erV4efnB3t7e5w6dQqHDh2Cl5eXpsujYoyBkoiISMspFAr8/vvv8PT0RJcuXeDg4IDTp0+rZrshehcGSiIiIi2lUCiwceNGeHh4oGvXrqhYsSLOnj2rmu2GKK8YKImIiLSMXC7H+vXr4e7ujm7duqFy5co4d+6carYbovxioCQiItIScrkca9euhZubG7p3746qVaviwoUL2LNnD+rUqaPp8qgEY6AkIiIq5eRyOVavXo1q1aohICAAbm5u+PPPP1Wz3RAVFgMlERFRKZWRkYFVq1bB1dUVPXv2hIeHBy5duoQdO3agZs2ami6PShEdTRdARERERSsjIwNr167FlClT8M8//6BTp07Ytm0batSooenSqJRioCQiIiol0tPTsWbNGgQHByMyMhK+vr7YsWMHqlevrunSqJRjoCQiIirh0tPTsWrVKkydOhVRUVH48ssvsXv3bnh4eGi6NNISDJREREQlVFpaGlatWoXg4GA8evQIfn5++OOPP+Du7q7p0kjL8KUcIiKiEiYtLQ2LFi2Ci4sLBgwYAC8vL1y/fh2bNm1imCSNYKAkIiIqIV6/fo0FCxagcuXK+O6779C4cWPcvHkTGzduhJubm6bLIy3GQElERFTMvX79GvPnz0flypUxZMgQNGvWDDdv3sT69evx0Ucfabo8IvahJCIiKq5evXqFpUuXYvr06YiJiUG3bt3w448/omrVqpoujUgNAyUREVExk5qaiiVLlmDGjBl4/vw5unfvjh9//BEuLi6aLo0oWwyURERExURKSgoWL16MmTNnIjY2FgEBARg7diwqV66s6dKIcsVASUREpGEpKSn47bffMHPmTMTHxyMwMBBjx45FxYoVNV0aUZ4wUBIR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",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from networkx import draw\n",
+    "g = pline.get_graph()[1]\n",
+    "display(g.nodes)\n",
+    "#pos = tree_layout(g)\n",
+    "draw(g,  with_labels = True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "NodeView(('prefetch.step', 'other_steps.step1', 'suite2p.do_this', 'suite2p.step2', 'demoPipeClass.initial', 'other_steps.step2', 'side_step.step1', 'side_step.step2'))"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "ename": "NetworkXError",
+     "evalue": "Node 'other_steps.step1' has no position.",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n",
+      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;49;00m v \u001b[39min\u001b[39;49;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "\u001b[1;31mKeyError\u001b[0m: 'other_steps.step1'\n",
+      "\n",
+      "The above exception was the direct cause of the following exception:\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m                             Traceback (most recent call last)\n",
+      "\u001b[1;32mc:\\Users\\tjostmou\\Documents\\Python\\__packages__\\Pypelines\\pypelines\\feature_test.ipynb Cell 6\u001b[0m line \u001b[0;36m5\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=2'>3</a>\u001b[0m display(g\u001b[39m.\u001b[39mnodes)\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m pos \u001b[39m=\u001b[39m tree_layout(g)\n",
+      "\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=4'>5</a>\u001b[0m draw(g, pos\u001b[39m=\u001b[39;49m pos, with_labels \u001b[39m=\u001b[39;49m \u001b[39mTrue\u001b[39;49;00m)\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:121\u001b[0m, in \u001b[0;36mdraw\u001b[1;34m(G, pos, ax, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    118\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m kwds:\n",
+      "\u001b[0;32m    119\u001b[0m     kwds[\u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mlabels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39min\u001b[39;00m kwds\n",
+      "\u001b[1;32m--> 121\u001b[0m draw_networkx(G, pos\u001b[39m=\u001b[39;49mpos, ax\u001b[39m=\u001b[39;49max, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwds)\n",
+      "\u001b[0;32m    122\u001b[0m ax\u001b[39m.\u001b[39mset_axis_off()\n",
+      "\u001b[0;32m    123\u001b[0m plt\u001b[39m.\u001b[39mdraw_if_interactive()\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:303\u001b[0m, in \u001b[0;36mdraw_networkx\u001b[1;34m(G, pos, arrows, with_labels, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    300\u001b[0m \u001b[39mif\u001b[39;00m pos \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n",
+      "\u001b[0;32m    301\u001b[0m     pos \u001b[39m=\u001b[39m nx\u001b[39m.\u001b[39mdrawing\u001b[39m.\u001b[39mspring_layout(G)  \u001b[39m# default to spring layout\u001b[39;00m\n",
+      "\u001b[1;32m--> 303\u001b[0m draw_networkx_nodes(G, pos, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mnode_kwds)\n",
+      "\u001b[0;32m    304\u001b[0m draw_networkx_edges(G, pos, arrows\u001b[39m=\u001b[39marrows, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39medge_kwds)\n",
+      "\u001b[0;32m    305\u001b[0m \u001b[39mif\u001b[39;00m with_labels:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:427\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\u001b[1;32m--> 427\u001b[0m     \u001b[39mraise\u001b[39;00m nx\u001b[39m.\u001b[39mNetworkXError(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mNode \u001b[39m\u001b[39m{\u001b[39;00merr\u001b[39m}\u001b[39;00m\u001b[39m has no position.\u001b[39m\u001b[39m\"\u001b[39m) \u001b[39mfrom\u001b[39;00m \u001b[39merr\u001b[39;00m\n",
+      "\u001b[0;32m    429\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(alpha, Iterable):\n",
+      "\u001b[0;32m    430\u001b[0m     node_color \u001b[39m=\u001b[39m apply_alpha(node_color, alpha, nodelist, cmap, vmin, vmax)\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m: Node 'other_steps.step1' has no position."
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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fjruvffeuOeee+Iv/uIv4vnnn4/LLrvshK9ZKpWitbX1qF9/4IPP+efm/HNz/rk5/9xG4/zLfo4vAACciUbu28IAAHAaE74AAKQgfAEASEH4AgCQwmkTvmvWrIlp06ZFdXV1NDQ0xNatW487/3vf+15ceumlUV1dHZdffnls2rRpjHbKaCjn/NetWxfXXnttjB8/PsaPHx9NTU3v+88Lp7dyf///3vr162PcuHExd+7c0d0go6rc83/nnXdi8eLFMXny5CiVSnHJJZf4d8AZrNzzX716dXz0ox+Nc845J+rr62PJkiXx29/+dox2y0j58Y9/HHPmzIkpU6bEuHHj4vnnn3/fNVu2bIlPfvKTUSqV4iMf+Ug89dRT5V+4OA2sX7++qKqqKp588sniv/7rv4rbbrutOP/884vu7u6jzv/JT35SVFZWFg8++GDx6quvFvfee29x9tlnF6+88soY75yRUO7533zzzcWaNWuKHTt2FDt37iz+7u/+rqitrS3++7//e4x3zkgo9/x/78033yymTp1aXHvttcVf//Vfj81mGXHlnv+hQ4eKWbNmFTfccEPx0ksvFW+++WaxZcuWorOzc4x3zkgo9/y/853vFKVSqfjOd75TvPnmm8ULL7xQTJ48uViyZMkY75yTtWnTpmL58uXFs88+W0RE8dxzzx13/u7du4tzzz23aGlpKV599dXiG9/4RlFZWVls3ry5rOueFuE7e/bsYvHixYO/7u/vL6ZMmVK0tbUddf7nPve54sYbbxwy1tDQUPz93//9qO6T0VHu+f+xw4cPF+edd17x7W9/e7S2yCgazvkfPny4uPrqq4tvfetbxcKFC4XvGazc8//mN79ZXHTRRUVfX99YbZFRVO75L168uPj0pz89ZKylpaW45pprRnWfjK4TCd8vf/nLxSc+8YkhY/PmzSuam5vLutYp/6pDX19fbNu2LZqamgbHKioqoqmpKTo6Oo66pqOjY8j8iIjm5uZjzuf0NZzz/2PvvvtuvPfee3HBBReM1jYZJcM9/69+9asxceLEuOWWW8Zim4yS4Zz/97///WhsbIzFixdHXV1dXHbZZbFy5cro7+8fq20zQoZz/ldffXVs27Zt8OsQu3fvjk2bNsUNN9wwJnvm1Bmp9iv7T24bafv374/+/v7BP/nt9+rq6mLXrl1HXdPV1XXU+V1dXaO2T0bHcM7/j919990xZcqUI35DcPobzvm/9NJL8cQTT0RnZ+cY7JDRNJzz3717d/zHf/xHfP7zn49NmzbFG2+8EV/84hfjvffei9bW1rHYNiNkOOd/8803x/79++NTn/pUFEURhw8fjjvuuCPuueeesdgyp9Cx2q+3tzd+85vfxDnnnHNC73PK7/jCyVi1alWsX78+nnvuuaiurj7V22GUHThwIObPnx/r1q2LCRMmnOrtcAoMDAzExIkT4/HHH4+ZM2fGvHnzYvny5bF27dpTvTXGwJYtW2LlypXx2GOPxfbt2+PZZ5+NjRs3xgMPPHCqt8YZ4pTf8Z0wYUJUVlZGd3f3kPHu7u6YNGnSUddMmjSprPmcvoZz/r/30EMPxapVq+KHP/xhXHHFFaO5TUZJuef/85//PN56662YM2fO4NjAwEBERJx11lnx2muvxcUXXzy6m2bEDOf3/+TJk+Pss8+OysrKwbGPfexj0dXVFX19fVFVVTWqe2bkDOf877vvvpg/f37ceuutERFx+eWXx8GDB+P222+P5cuXR0WF+3kfVMdqv5qamhO+2xtxGtzxraqqipkzZ0Z7e/vg2MDAQLS3t0djY+NR1zQ2Ng6ZHxHx4osvHnM+p6/hnH9ExIMPPhgPPPBAbN68OWbNmjUWW2UUlHv+l156abzyyivR2dk5+PrsZz8b119/fXR2dkZ9ff1Ybp+TNJzf/9dcc0288cYbg//BExHx+uuvx+TJk0XvGWY45//uu+8eEbe//4+g3/2MFB9UI9Z+5f3c3ehYv359USqViqeeeqp49dVXi9tvv704//zzi66urqIoimL+/PnF0qVLB+f/5Cc/Kc4666zioYceKnbu3Fm0trZ6nNkZrNzzX7VqVVFVVVU888wzxa9+9avB14EDB07VR+AklHv+f8xTHc5s5Z7/nj17ivPOO6/4h3/4h+K1114rfvCDHxQTJ04svva1r52qj8BJKPf8W1tbi/POO6/4t3/7t2L37t3Fv//7vxcXX3xx8bnPfe5UfQSG6cCBA8WOHTuKHTt2FBFRPPLII8WOHTuKX/ziF0VRFMXSpUuL+fPnD87//ePM/umf/qnYuXNnsWbNmjP3cWZFURTf+MY3igsvvLCoqqoqZs+eXfznf/7n4F+77rrrioULFw6Z/93vfre45JJLiqqqquITn/hEsXHjxjHeMSOpnPP/8Ic/XETEEa/W1tax3zgjotzf//8/4XvmK/f8X3755aKhoaEolUrFRRddVHz9618vDh8+PMa7ZqSUc/7vvfde8ZWvfKW4+OKLi+rq6qK+vr744he/WPzv//7v2G+ck/KjH/3oqP8u//15L1y4sLjuuuuOWDNjxoyiqqqquOiii4p//dd/Lfu644rC/xsAAOCD75R/xxcAAMaC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBT+HzgRrWHQVr4zAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from networkx import draw\n",
+    "g = pline.get_graph()[1]\n",
+    "display(g.nodes)\n",
+    "pos = tree_layout(g)\n",
+    "draw(g, pos= pos, with_labels = True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "NodeView(('prefetch.step', 'other_steps.step1', 'suite2p.do_this', 'suite2p.step2', 'demoPipeClass.initial', 'other_steps.step2', 'side_step.step1', 'side_step.step2'))"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "ename": "NetworkXError",
+     "evalue": "Node 'other_steps.step1' has no position.",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n",
+      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;49;00m v \u001b[39min\u001b[39;49;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "\u001b[1;31mKeyError\u001b[0m: 'other_steps.step1'\n",
+      "\n",
+      "The above exception was the direct cause of the following exception:\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m                             Traceback (most recent call last)\n",
+      "\u001b[1;32mc:\\Users\\tjostmou\\Documents\\Python\\__packages__\\Pypelines\\pypelines\\feature_test.ipynb Cell 6\u001b[0m line \u001b[0;36m5\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=2'>3</a>\u001b[0m display(g\u001b[39m.\u001b[39mnodes)\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m pos \u001b[39m=\u001b[39m tree_layout(g)\n",
+      "\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=4'>5</a>\u001b[0m draw(g, pos\u001b[39m=\u001b[39;49m pos, with_labels \u001b[39m=\u001b[39;49m \u001b[39mTrue\u001b[39;49;00m)\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:121\u001b[0m, in \u001b[0;36mdraw\u001b[1;34m(G, pos, ax, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    118\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m kwds:\n",
+      "\u001b[0;32m    119\u001b[0m     kwds[\u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mlabels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39min\u001b[39;00m kwds\n",
+      "\u001b[1;32m--> 121\u001b[0m draw_networkx(G, pos\u001b[39m=\u001b[39;49mpos, ax\u001b[39m=\u001b[39;49max, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwds)\n",
+      "\u001b[0;32m    122\u001b[0m ax\u001b[39m.\u001b[39mset_axis_off()\n",
+      "\u001b[0;32m    123\u001b[0m plt\u001b[39m.\u001b[39mdraw_if_interactive()\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:303\u001b[0m, in \u001b[0;36mdraw_networkx\u001b[1;34m(G, pos, arrows, with_labels, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    300\u001b[0m \u001b[39mif\u001b[39;00m pos \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n",
+      "\u001b[0;32m    301\u001b[0m     pos \u001b[39m=\u001b[39m nx\u001b[39m.\u001b[39mdrawing\u001b[39m.\u001b[39mspring_layout(G)  \u001b[39m# default to spring layout\u001b[39;00m\n",
+      "\u001b[1;32m--> 303\u001b[0m draw_networkx_nodes(G, pos, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mnode_kwds)\n",
+      "\u001b[0;32m    304\u001b[0m draw_networkx_edges(G, pos, arrows\u001b[39m=\u001b[39marrows, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39medge_kwds)\n",
+      "\u001b[0;32m    305\u001b[0m \u001b[39mif\u001b[39;00m with_labels:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:427\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\u001b[1;32m--> 427\u001b[0m     \u001b[39mraise\u001b[39;00m nx\u001b[39m.\u001b[39mNetworkXError(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mNode \u001b[39m\u001b[39m{\u001b[39;00merr\u001b[39m}\u001b[39;00m\u001b[39m has no position.\u001b[39m\u001b[39m\"\u001b[39m) \u001b[39mfrom\u001b[39;00m \u001b[39merr\u001b[39;00m\n",
+      "\u001b[0;32m    429\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(alpha, Iterable):\n",
+      "\u001b[0;32m    430\u001b[0m     node_color \u001b[39m=\u001b[39m apply_alpha(node_color, alpha, nodelist, cmap, vmin, vmax)\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m: Node 'other_steps.step1' has no position."
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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fjruvffeuOeee+Iv/uIv4vnnn4/LLrvshK9ZKpWitbX1qF9/4IPP+efm/HNz/rk5/9xG4/zLfo4vAACciUbu28IAAHAaE74AAKQgfAEASEH4AgCQwmkTvmvWrIlp06ZFdXV1NDQ0xNatW487/3vf+15ceumlUV1dHZdffnls2rRpjHbKaCjn/NetWxfXXnttjB8/PsaPHx9NTU3v+88Lp7dyf///3vr162PcuHExd+7c0d0go6rc83/nnXdi8eLFMXny5CiVSnHJJZf4d8AZrNzzX716dXz0ox+Nc845J+rr62PJkiXx29/+dox2y0j58Y9/HHPmzIkpU6bEuHHj4vnnn3/fNVu2bIlPfvKTUSqV4iMf+Ug89dRT5V+4OA2sX7++qKqqKp588sniv/7rv4rbbrutOP/884vu7u6jzv/JT35SVFZWFg8++GDx6quvFvfee29x9tlnF6+88soY75yRUO7533zzzcWaNWuKHTt2FDt37iz+7u/+rqitrS3++7//e4x3zkgo9/x/78033yymTp1aXHvttcVf//Vfj81mGXHlnv+hQ4eKWbNmFTfccEPx0ksvFW+++WaxZcuWorOzc4x3zkgo9/y/853vFKVSqfjOd75TvPnmm8ULL7xQTJ48uViyZMkY75yTtWnTpmL58uXFs88+W0RE8dxzzx13/u7du4tzzz23aGlpKV599dXiG9/4RlFZWVls3ry5rOueFuE7e/bsYvHixYO/7u/vL6ZMmVK0tbUddf7nPve54sYbbxwy1tDQUPz93//9qO6T0VHu+f+xw4cPF+edd17x7W9/e7S2yCgazvkfPny4uPrqq4tvfetbxcKFC4XvGazc8//mN79ZXHTRRUVfX99YbZFRVO75L168uPj0pz89ZKylpaW45pprRnWfjK4TCd8vf/nLxSc+8YkhY/PmzSuam5vLutYp/6pDX19fbNu2LZqamgbHKioqoqmpKTo6Oo66pqOjY8j8iIjm5uZjzuf0NZzz/2PvvvtuvPfee3HBBReM1jYZJcM9/69+9asxceLEuOWWW8Zim4yS4Zz/97///WhsbIzFixdHXV1dXHbZZbFy5cro7+8fq20zQoZz/ldffXVs27Zt8OsQu3fvjk2bNsUNN9wwJnvm1Bmp9iv7T24bafv374/+/v7BP/nt9+rq6mLXrl1HXdPV1XXU+V1dXaO2T0bHcM7/j919990xZcqUI35DcPobzvm/9NJL8cQTT0RnZ+cY7JDRNJzz3717d/zHf/xHfP7zn49NmzbFG2+8EV/84hfjvffei9bW1rHYNiNkOOd/8803x/79++NTn/pUFEURhw8fjjvuuCPuueeesdgyp9Cx2q+3tzd+85vfxDnnnHNC73PK7/jCyVi1alWsX78+nnvuuaiurj7V22GUHThwIObPnx/r1q2LCRMmnOrtcAoMDAzExIkT4/HHH4+ZM2fGvHnzYvny5bF27dpTvTXGwJYtW2LlypXx2GOPxfbt2+PZZ5+NjRs3xgMPPHCqt8YZ4pTf8Z0wYUJUVlZGd3f3kPHu7u6YNGnSUddMmjSprPmcvoZz/r/30EMPxapVq+KHP/xhXHHFFaO5TUZJuef/85//PN56662YM2fO4NjAwEBERJx11lnx2muvxcUXXzy6m2bEDOf3/+TJk+Pss8+OysrKwbGPfexj0dXVFX19fVFVVTWqe2bkDOf877vvvpg/f37ceuutERFx+eWXx8GDB+P222+P5cuXR0WF+3kfVMdqv5qamhO+2xtxGtzxraqqipkzZ0Z7e/vg2MDAQLS3t0djY+NR1zQ2Ng6ZHxHx4osvHnM+p6/hnH9ExIMPPhgPPPBAbN68OWbNmjUWW2UUlHv+l156abzyyivR2dk5+PrsZz8b119/fXR2dkZ9ff1Ybp+TNJzf/9dcc0288cYbg//BExHx+uuvx+TJk0XvGWY45//uu+8eEbe//4+g3/2MFB9UI9Z+5f3c3ehYv359USqViqeeeqp49dVXi9tvv704//zzi66urqIoimL+/PnF0qVLB+f/5Cc/Kc4666zioYceKnbu3Fm0trZ6nNkZrNzzX7VqVVFVVVU888wzxa9+9avB14EDB07VR+AklHv+f8xTHc5s5Z7/nj17ivPOO6/4h3/4h+K1114rfvCDHxQTJ04svva1r52qj8BJKPf8W1tbi/POO6/4t3/7t2L37t3Fv//7vxcXX3xx8bnPfe5UfQSG6cCBA8WOHTuKHTt2FBFRPPLII8WOHTuKX/ziF0VRFMXSpUuL+fPnD87//ePM/umf/qnYuXNnsWbNmjP3cWZFURTf+MY3igsvvLCoqqoqZs+eXfznf/7n4F+77rrrioULFw6Z/93vfre45JJLiqqqquITn/hEsXHjxjHeMSOpnPP/8Ic/XETEEa/W1tax3zgjotzf//8/4XvmK/f8X3755aKhoaEolUrFRRddVHz9618vDh8+PMa7ZqSUc/7vvfde8ZWvfKW4+OKLi+rq6qK+vr744he/WPzv//7v2G+ck/KjH/3oqP8u//15L1y4sLjuuuuOWDNjxoyiqqqquOiii4p//dd/Lfu644rC/xsAAOCD75R/xxcAAMaC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBT+HzgRrWHQVr4zAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from networkx import draw\n",
+    "g = pline.get_graph()[1]\n",
+    "display(g.nodes)\n",
+    "pos = tree_layout(g)\n",
+    "draw(g, pos= pos, with_labels = True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "NodeView(('prefetch.step', 'other_steps.step1', 'suite2p.do_this', 'suite2p.step2', 'demoPipeClass.initial', 'other_steps.step2', 'side_step.step1', 'side_step.step2'))"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "ename": "NetworkXError",
+     "evalue": "Node 'other_steps.step1' has no position.",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n",
+      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;49;00m v \u001b[39min\u001b[39;49;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "\u001b[1;31mKeyError\u001b[0m: 'other_steps.step1'\n",
+      "\n",
+      "The above exception was the direct cause of the following exception:\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m                             Traceback (most recent call last)\n",
+      "\u001b[1;32mc:\\Users\\tjostmou\\Documents\\Python\\__packages__\\Pypelines\\pypelines\\feature_test.ipynb Cell 6\u001b[0m line \u001b[0;36m5\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=2'>3</a>\u001b[0m display(g\u001b[39m.\u001b[39mnodes)\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m pos \u001b[39m=\u001b[39m tree_layout(g)\n",
+      "\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=4'>5</a>\u001b[0m draw(g, pos\u001b[39m=\u001b[39;49m pos, with_labels \u001b[39m=\u001b[39;49m \u001b[39mTrue\u001b[39;49;00m)\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:121\u001b[0m, in \u001b[0;36mdraw\u001b[1;34m(G, pos, ax, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    118\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m kwds:\n",
+      "\u001b[0;32m    119\u001b[0m     kwds[\u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mlabels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39min\u001b[39;00m kwds\n",
+      "\u001b[1;32m--> 121\u001b[0m draw_networkx(G, pos\u001b[39m=\u001b[39;49mpos, ax\u001b[39m=\u001b[39;49max, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwds)\n",
+      "\u001b[0;32m    122\u001b[0m ax\u001b[39m.\u001b[39mset_axis_off()\n",
+      "\u001b[0;32m    123\u001b[0m plt\u001b[39m.\u001b[39mdraw_if_interactive()\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:303\u001b[0m, in \u001b[0;36mdraw_networkx\u001b[1;34m(G, pos, arrows, with_labels, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    300\u001b[0m \u001b[39mif\u001b[39;00m pos \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n",
+      "\u001b[0;32m    301\u001b[0m     pos \u001b[39m=\u001b[39m nx\u001b[39m.\u001b[39mdrawing\u001b[39m.\u001b[39mspring_layout(G)  \u001b[39m# default to spring layout\u001b[39;00m\n",
+      "\u001b[1;32m--> 303\u001b[0m draw_networkx_nodes(G, pos, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mnode_kwds)\n",
+      "\u001b[0;32m    304\u001b[0m draw_networkx_edges(G, pos, arrows\u001b[39m=\u001b[39marrows, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39medge_kwds)\n",
+      "\u001b[0;32m    305\u001b[0m \u001b[39mif\u001b[39;00m with_labels:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:427\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\u001b[1;32m--> 427\u001b[0m     \u001b[39mraise\u001b[39;00m nx\u001b[39m.\u001b[39mNetworkXError(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mNode \u001b[39m\u001b[39m{\u001b[39;00merr\u001b[39m}\u001b[39;00m\u001b[39m has no position.\u001b[39m\u001b[39m\"\u001b[39m) \u001b[39mfrom\u001b[39;00m \u001b[39merr\u001b[39;00m\n",
+      "\u001b[0;32m    429\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(alpha, Iterable):\n",
+      "\u001b[0;32m    430\u001b[0m     node_color \u001b[39m=\u001b[39m apply_alpha(node_color, alpha, nodelist, cmap, vmin, vmax)\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m: Node 'other_steps.step1' has no position."
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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fjruvffeuOeee+Iv/uIv4vnnn4/LLrvshK9ZKpWitbX1qF9/4IPP+efm/HNz/rk5/9xG4/zLfo4vAACciUbu28IAAHAaE74AAKQgfAEASEH4AgCQwmkTvmvWrIlp06ZFdXV1NDQ0xNatW487/3vf+15ceumlUV1dHZdffnls2rRpjHbKaCjn/NetWxfXXnttjB8/PsaPHx9NTU3v+88Lp7dyf///3vr162PcuHExd+7c0d0go6rc83/nnXdi8eLFMXny5CiVSnHJJZf4d8AZrNzzX716dXz0ox+Nc845J+rr62PJkiXx29/+dox2y0j58Y9/HHPmzIkpU6bEuHHj4vnnn3/fNVu2bIlPfvKTUSqV4iMf+Ug89dRT5V+4OA2sX7++qKqqKp588sniv/7rv4rbbrutOP/884vu7u6jzv/JT35SVFZWFg8++GDx6quvFvfee29x9tlnF6+88soY75yRUO7533zzzcWaNWuKHTt2FDt37iz+7u/+rqitrS3++7//e4x3zkgo9/x/78033yymTp1aXHvttcVf//Vfj81mGXHlnv+hQ4eKWbNmFTfccEPx0ksvFW+++WaxZcuWorOzc4x3zkgo9/y/853vFKVSqfjOd75TvPnmm8ULL7xQTJ48uViyZMkY75yTtWnTpmL58uXFs88+W0RE8dxzzx13/u7du4tzzz23aGlpKV599dXiG9/4RlFZWVls3ry5rOueFuE7e/bsYvHixYO/7u/vL6ZMmVK0tbUddf7nPve54sYbbxwy1tDQUPz93//9qO6T0VHu+f+xw4cPF+edd17x7W9/e7S2yCgazvkfPny4uPrqq4tvfetbxcKFC4XvGazc8//mN79ZXHTRRUVfX99YbZFRVO75L168uPj0pz89ZKylpaW45pprRnWfjK4TCd8vf/nLxSc+8YkhY/PmzSuam5vLutYp/6pDX19fbNu2LZqamgbHKioqoqmpKTo6Oo66pqOjY8j8iIjm5uZjzuf0NZzz/2PvvvtuvPfee3HBBReM1jYZJcM9/69+9asxceLEuOWWW8Zim4yS4Zz/97///WhsbIzFixdHXV1dXHbZZbFy5cro7+8fq20zQoZz/ldffXVs27Zt8OsQu3fvjk2bNsUNN9wwJnvm1Bmp9iv7T24bafv374/+/v7BP/nt9+rq6mLXrl1HXdPV1XXU+V1dXaO2T0bHcM7/j919990xZcqUI35DcPobzvm/9NJL8cQTT0RnZ+cY7JDRNJzz3717d/zHf/xHfP7zn49NmzbFG2+8EV/84hfjvffei9bW1rHYNiNkOOd/8803x/79++NTn/pUFEURhw8fjjvuuCPuueeesdgyp9Cx2q+3tzd+85vfxDnnnHNC73PK7/jCyVi1alWsX78+nnvuuaiurj7V22GUHThwIObPnx/r1q2LCRMmnOrtcAoMDAzExIkT4/HHH4+ZM2fGvHnzYvny5bF27dpTvTXGwJYtW2LlypXx2GOPxfbt2+PZZ5+NjRs3xgMPPHCqt8YZ4pTf8Z0wYUJUVlZGd3f3kPHu7u6YNGnSUddMmjSprPmcvoZz/r/30EMPxapVq+KHP/xhXHHFFaO5TUZJuef/85//PN56662YM2fO4NjAwEBERJx11lnx2muvxcUXXzy6m2bEDOf3/+TJk+Pss8+OysrKwbGPfexj0dXVFX19fVFVVTWqe2bkDOf877vvvpg/f37ceuutERFx+eWXx8GDB+P222+P5cuXR0WF+3kfVMdqv5qamhO+2xtxGtzxraqqipkzZ0Z7e/vg2MDAQLS3t0djY+NR1zQ2Ng6ZHxHx4osvHnM+p6/hnH9ExIMPPhgPPPBAbN68OWbNmjUWW2UUlHv+l156abzyyivR2dk5+PrsZz8b119/fXR2dkZ9ff1Ybp+TNJzf/9dcc0288cYbg//BExHx+uuvx+TJk0XvGWY45//uu+8eEbe//4+g3/2MFB9UI9Z+5f3c3ehYv359USqViqeeeqp49dVXi9tvv704//zzi66urqIoimL+/PnF0qVLB+f/5Cc/Kc4666zioYceKnbu3Fm0trZ6nNkZrNzzX7VqVVFVVVU888wzxa9+9avB14EDB07VR+AklHv+f8xTHc5s5Z7/nj17ivPOO6/4h3/4h+K1114rfvCDHxQTJ04svva1r52qj8BJKPf8W1tbi/POO6/4t3/7t2L37t3Fv//7vxcXX3xx8bnPfe5UfQSG6cCBA8WOHTuKHTt2FBFRPPLII8WOHTuKX/ziF0VRFMXSpUuL+fPnD87//ePM/umf/qnYuXNnsWbNmjP3cWZFURTf+MY3igsvvLCoqqoqZs+eXfznf/7n4F+77rrrioULFw6Z/93vfre45JJLiqqqquITn/hEsXHjxjHeMSOpnPP/8Ic/XETEEa/W1tax3zgjotzf//8/4XvmK/f8X3755aKhoaEolUrFRRddVHz9618vDh8+PMa7ZqSUc/7vvfde8ZWvfKW4+OKLi+rq6qK+vr744he/WPzv//7v2G+ck/KjH/3oqP8u//15L1y4sLjuuuuOWDNjxoyiqqqquOiii4p//dd/Lfu644rC/xsAAOCD75R/xxcAAMaC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBT+HzgRrWHQVr4zAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from networkx import draw\n",
+    "g = pline.get_graph()[1]\n",
+    "display(g.nodes)\n",
+    "pos = tree_layout(g)\n",
+    "draw(g, pos= pos, with_labels = True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "NodeView(('prefetch.step', 'other_steps.step1', 'suite2p.do_this', 'suite2p.step2', 'demoPipeClass.initial', 'other_steps.step2', 'side_step.step1', 'side_step.step2'))"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "ename": "NetworkXError",
+     "evalue": "Node 'other_steps.step1' has no position.",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n",
+      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;49;00m v \u001b[39min\u001b[39;49;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "\u001b[1;31mKeyError\u001b[0m: 'other_steps.step1'\n",
+      "\n",
+      "The above exception was the direct cause of the following exception:\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m                             Traceback (most recent call last)\n",
+      "\u001b[1;32mc:\\Users\\tjostmou\\Documents\\Python\\__packages__\\Pypelines\\pypelines\\feature_test.ipynb Cell 6\u001b[0m line \u001b[0;36m5\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=2'>3</a>\u001b[0m display(g\u001b[39m.\u001b[39mnodes)\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m pos \u001b[39m=\u001b[39m tree_layout(g)\n",
+      "\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=4'>5</a>\u001b[0m draw(g, pos\u001b[39m=\u001b[39;49m pos, with_labels \u001b[39m=\u001b[39;49m \u001b[39mTrue\u001b[39;49;00m)\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:121\u001b[0m, in \u001b[0;36mdraw\u001b[1;34m(G, pos, ax, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    118\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m kwds:\n",
+      "\u001b[0;32m    119\u001b[0m     kwds[\u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mlabels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39min\u001b[39;00m kwds\n",
+      "\u001b[1;32m--> 121\u001b[0m draw_networkx(G, pos\u001b[39m=\u001b[39;49mpos, ax\u001b[39m=\u001b[39;49max, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwds)\n",
+      "\u001b[0;32m    122\u001b[0m ax\u001b[39m.\u001b[39mset_axis_off()\n",
+      "\u001b[0;32m    123\u001b[0m plt\u001b[39m.\u001b[39mdraw_if_interactive()\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:303\u001b[0m, in \u001b[0;36mdraw_networkx\u001b[1;34m(G, pos, arrows, with_labels, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    300\u001b[0m \u001b[39mif\u001b[39;00m pos \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n",
+      "\u001b[0;32m    301\u001b[0m     pos \u001b[39m=\u001b[39m nx\u001b[39m.\u001b[39mdrawing\u001b[39m.\u001b[39mspring_layout(G)  \u001b[39m# default to spring layout\u001b[39;00m\n",
+      "\u001b[1;32m--> 303\u001b[0m draw_networkx_nodes(G, pos, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mnode_kwds)\n",
+      "\u001b[0;32m    304\u001b[0m draw_networkx_edges(G, pos, arrows\u001b[39m=\u001b[39marrows, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39medge_kwds)\n",
+      "\u001b[0;32m    305\u001b[0m \u001b[39mif\u001b[39;00m with_labels:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:427\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\u001b[1;32m--> 427\u001b[0m     \u001b[39mraise\u001b[39;00m nx\u001b[39m.\u001b[39mNetworkXError(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mNode \u001b[39m\u001b[39m{\u001b[39;00merr\u001b[39m}\u001b[39;00m\u001b[39m has no position.\u001b[39m\u001b[39m\"\u001b[39m) \u001b[39mfrom\u001b[39;00m \u001b[39merr\u001b[39;00m\n",
+      "\u001b[0;32m    429\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(alpha, Iterable):\n",
+      "\u001b[0;32m    430\u001b[0m     node_color \u001b[39m=\u001b[39m apply_alpha(node_color, alpha, nodelist, cmap, vmin, vmax)\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m: Node 'other_steps.step1' has no position."
+     ]
+    },
+    {
+     "data": {
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAr4AAAIRCAYAAACszb5OAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAf+0lEQVR4nO3df2zV9b348Ret9lQzW/FyKT9uHVd3ndtUcCC91Rnj0rsmGnb542ZcXYBL/HHduMbR3DtBlM65Ua5XDcnEEZle98e8sBk1yyB4Xe/I4uwNGdDEXUHj0MFd1gp315aLG5X28/1jWfft+CGntAV8PR7J+YO37/f5vI9viU8/nn4YVxRFEQAA8AFXcao3AAAAY0H4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJBC2eH74x//OObMmRNTpkyJcePGxfPPP/++a7Zs2RKf/OQno1QqxUc+8pF46qmnhrFVAAAYvrLD9+DBgzF9+vRYs2bNCc1/880348Ybb4zrr78+Ojs740tf+lLceuut8cILL5S9WQAAGK5xRVEUw148blw899xzMXfu3GPOufvuu2Pjxo3xs5/9bHDsb//2b+Odd96JzZs3D/fSAABQlrNG+wIdHR3R1NQ0ZKy5uTm+9KUvHXPNoUOH4tChQ4O/HhgYiF//+tfxJ3/yJzFu3LjR2ioAAKeJoijiwIEDMWXKlKioGJkfSxv18O3q6oq6urohY3V1ddHb2xu/+c1v4pxzzjliTVtbW9x///2jvTUAAE5ze/fujT/7sz8bkfca9fAdjmXLlkVLS8vgr3t6euLCCy+MvXv3Rk1NzSncGQAAY6G3tzfq6+vjvPPOG7H3HPXwnTRpUnR3dw8Z6+7ujpqamqPe7Y2IKJVKUSqVjhivqakRvgAAiYzk11xH/Tm+jY2N0d7ePmTsxRdfjMbGxtG+NAAADCo7fP/v//4vOjs7o7OzMyJ+97iyzs7O2LNnT0T87msKCxYsGJx/xx13xO7du+PLX/5y7Nq1Kx577LH47ne/G0uWLBmZTwAAACeg7PD96U9/GldeeWVceeWVERHR0tISV155ZaxYsSIiIn71q18NRnBExJ//+Z/Hxo0b48UXX4zp06fHww8/HN/61reiubl5hD4CAAC8v5N6ju9Y6e3tjdra2ujp6fEdXwCABEaj/0b9O74AAHA6EL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIIVhhe+aNWti2rRpUV1dHQ0NDbF169bjzl+9enV89KMfjXPOOSfq6+tjyZIl8dvf/nZYGwYAgOEoO3w3bNgQLS0t0draGtu3b4/p06dHc3NzvP3220ed//TTT8fSpUujtbU1du7cGU888URs2LAh7rnnnpPePAAAnKiyw/eRRx6J2267LRYtWhQf//jHY+3atXHuuefGk08+edT5L7/8clxzzTVx8803x7Rp0+Izn/lM3HTTTe97lxgAAEZSWeHb19cX27Zti6ampj+8QUVFNDU1RUdHx1HXXH311bFt27bB0N29e3ds2rQpbrjhhmNe59ChQ9Hb2zvkBQAAJ+Oscibv378/+vv7o66ubsh4XV1d7Nq166hrbr755ti/f3986lOfiqIo4vDhw3HHHXcc96sObW1tcf/995ezNQAAOK5Rf6rDli1bYuXKlfHYY4/F9u3b49lnn42NGzfGAw88cMw1y5Yti56ensHX3r17R3ubAAB8wJV1x3fChAlRWVkZ3d3dQ8a7u7tj0qRJR11z3333xfz58+PWW2+NiIjLL788Dh48GLfffnssX748KiqObO9SqRSlUqmcrQEAwHGVdce3qqoqZs6cGe3t7YNjAwMD0d7eHo2NjUdd8+677x4Rt5WVlRERURRFufsFAIBhKeuOb0RES0tLLFy4MGbNmhWzZ8+O1atXx8GDB2PRokUREbFgwYKYOnVqtLW1RUTEnDlz4pFHHokrr7wyGhoa4o033oj77rsv5syZMxjAAAAw2soO33nz5sW+fftixYoV0dXVFTNmzIjNmzcP/sDbnj17htzhvffee2PcuHFx7733xi9/+cv40z/905gzZ058/etfH7lPAQAA72NccQZ836C3tzdqa2ujp6cnampqTvV2AAAYZaPRf6P+VAcAADgdCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkMKwwnfNmjUxbdq0qK6ujoaGhti6detx57/zzjuxePHimDx5cpRKpbjkkkti06ZNw9owAAAMx1nlLtiwYUO0tLTE2rVro6GhIVavXh3Nzc3x2muvxcSJE4+Y39fXF3/1V38VEydOjGeeeSamTp0av/jFL+L8888fif0DAMAJGVcURVHOgoaGhrjqqqvi0UcfjYiIgYGBqK+vjzvvvDOWLl16xPy1a9fGv/zLv8SuXbvi7LPPHtYme3t7o7a2Nnp6eqKmpmZY7wEAwJljNPqvrK869PX1xbZt26KpqekPb1BREU1NTdHR0XHUNd///vejsbExFi9eHHV1dXHZZZfFypUro7+//5jXOXToUPT29g55AQDAySgrfPfv3x/9/f1RV1c3ZLyuri66urqOumb37t3xzDPPRH9/f2zatCnuu+++ePjhh+NrX/vaMa/T1tYWtbW1g6/6+vpytgkAAEcY9ac6DAwMxMSJE+Pxxx+PmTNnxrx582L58uWxdu3aY65ZtmxZ9PT0DL727t072tsEAOADrqwfbpswYUJUVlZGd3f3kPHu7u6YNGnSUddMnjw5zj777KisrBwc+9jHPhZdXV3R19cXVVVVR6wplUpRKpXK2RoAABxXWXd8q6qqYubMmdHe3j44NjAwEO3t7dHY2HjUNddcc0288cYbMTAwMDj2+uuvx+TJk48avQAAMBrK/qpDS0tLrFu3Lr797W/Hzp074wtf+EIcPHgwFi1aFBERCxYsiGXLlg3O/8IXvhC//vWv46677orXX389Nm7cGCtXrozFixeP3KcAAID3UfZzfOfNmxf79u2LFStWRFdXV8yYMSM2b948+ANve/bsiYqKP/R0fX19vPDCC7FkyZK44oorYurUqXHXXXfF3XffPXKfAgAA3kfZz/E9FTzHFwAgl1P+HF8AADhTCV8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkMKwwnfNmjUxbdq0qK6ujoaGhti6desJrVu/fn2MGzcu5s6dO5zLAgDAsJUdvhs2bIiWlpZobW2N7du3x/Tp06O5uTnefvvt465766234h//8R/j2muvHfZmAQBguMoO30ceeSRuu+22WLRoUXz84x+PtWvXxrnnnhtPPvnkMdf09/fH5z//+bj//vvjoosuOqkNAwDAcJQVvn19fbFt27Zoamr6wxtUVERTU1N0dHQcc91Xv/rVmDhxYtxyyy0ndJ1Dhw5Fb2/vkBcAAJyMssJ3//790d/fH3V1dUPG6+rqoqur66hrXnrppXjiiSdi3bp1J3ydtra2qK2tHXzV19eXs00AADjCqD7V4cCBAzF//vxYt25dTJgw4YTXLVu2LHp6egZfe/fuHcVdAgCQwVnlTJ4wYUJUVlZGd3f3kPHu7u6YNGnSEfN//vOfx1tvvRVz5swZHBsYGPjdhc86K1577bW4+OKLj1hXKpWiVCqVszUAADiusu74VlVVxcyZM6O9vX1wbGBgINrb26OxsfGI+Zdeemm88sor0dnZOfj67Gc/G9dff310dnb6CgMAAGOmrDu+EREtLS2xcOHCmDVrVsyePTtWr14dBw8ejEWLFkVExIIFC2Lq1KnR1tYW1dXVcdlllw1Zf/7550dEHDEOAACjqezwnTdvXuzbty9WrFgRXV1dMWPGjNi8efPgD7zt2bMnKir8gXAAAJxexhVFUZzqTbyf3t7eqK2tjZ6enqipqTnV2wEAYJSNRv+5NQsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkMKzwXbNmTUybNi2qq6ujoaEhtm7desy569ati2uvvTbGjx8f48ePj6ampuPOBwCA0VB2+G7YsCFaWlqitbU1tm/fHtOnT4/m5uZ4++23jzp/y5YtcdNNN8WPfvSj6OjoiPr6+vjMZz4Tv/zlL0968wAAcKLGFUVRlLOgoaEhrrrqqnj00UcjImJgYCDq6+vjzjvvjKVLl77v+v7+/hg/fnw8+uijsWDBghO6Zm9vb9TW1kZPT0/U1NSUs10AAM5Ao9F/Zd3x7evri23btkVTU9Mf3qCiIpqamqKjo+OE3uPdd9+N9957Ly644IJjzjl06FD09vYOeQEAwMkoK3z3798f/f39UVdXN2S8rq4uurq6Tug97r777pgyZcqQeP5jbW1tUVtbO/iqr68vZ5sAAHCEMX2qw6pVq2L9+vXx3HPPRXV19THnLVu2LHp6egZfe/fuHcNdAgDwQXRWOZMnTJgQlZWV0d3dPWS8u7s7Jk2adNy1Dz30UKxatSp++MMfxhVXXHHcuaVSKUqlUjlbAwCA4yrrjm9VVVXMnDkz2tvbB8cGBgaivb09Ghsbj7nuwQcfjAceeCA2b94cs2bNGv5uAQBgmMq64xsR0dLSEgsXLoxZs2bF7NmzY/Xq1XHw4MFYtGhRREQsWLAgpk6dGm1tbRER8c///M+xYsWKePrpp2PatGmD3wX+0Ic+FB/60IdG8KMAAMCxlR2+8+bNi3379sWKFSuiq6srZsyYEZs3bx78gbc9e/ZERcUfbiR/85vfjL6+vvibv/mbIe/T2toaX/nKV05u9wAAcILKfo7vqeA5vgAAuZzy5/gCAMCZSvgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSELwAAKQhfAABSEL4AAKQgfAEASEH4AgCQgvAFACAF4QsAQArCFwCAFIQvAAApCF8AAFIQvgAApCB8AQBIQfgCAJCC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBSGFb5r1qyJadOmRXV1dTQ0NMTWrVuPO/973/teXHrppVFdXR2XX355bNq0aVibBQCA4So7fDds2BAtLS3R2toa27dvj+nTp0dzc3O8/fbbR53/8ssvx0033RS33HJL7NixI+bOnRtz586Nn/3sZye9eQAAOFHjiqIoylnQ0NAQV111VTz66KMRETEwMBD19fVx5513xtKlS4+YP2/evDh48GD84Ac/GBz7y7/8y5gxY0asXbv2hK7Z29sbtbW10dPTEzU1NeVsFwCAM9Bo9N9Z5Uzu6+uLbdu2xbJlywbHKioqoqmpKTo6Oo66pqOjI1paWoaMNTc3x/PPP3/M6xw6dCgOHTo0+Ouenp6I+N3fAAAAPvh+331l3qM9rrLCd//+/dHf3x91dXVDxuvq6mLXrl1HXdPV1XXU+V1dXce8TltbW9x///1HjNfX15ezXQAAznD/8z//E7W1tSPyXmWF71hZtmzZkLvE77zzTnz4wx+OPXv2jNgH58zR29sb9fX1sXfvXl91Scj55+b8c3P+ufX09MSFF14YF1xwwYi9Z1nhO2HChKisrIzu7u4h493d3TFp0qSjrpk0aVJZ8yMiSqVSlEqlI8Zra2v9g59YTU2N80/M+efm/HNz/rlVVIzc03fLeqeqqqqYOXNmtLe3D44NDAxEe3t7NDY2HnVNY2PjkPkRES+++OIx5wMAwGgo+6sOLS0tsXDhwpg1a1bMnj07Vq9eHQcPHoxFixZFRMSCBQti6tSp0dbWFhERd911V1x33XXx8MMPx4033hjr16+Pn/70p/H444+P7CcBAIDjKDt8582bF/v27YsVK1ZEV1dXzJgxIzZv3jz4A2x79uwZckv66quvjqeffjruvffeuOeee+Iv/uIv4vnnn4/LLrvshK9ZKpWitbX1qF9/4IPP+efm/HNz/rk5/9xG4/zLfo4vAACciUbu28IAAHAaE74AAKQgfAEASEH4AgCQwmkTvmvWrIlp06ZFdXV1NDQ0xNatW487/3vf+15ceumlUV1dHZdffnls2rRpjHbKaCjn/NetWxfXXnttjB8/PsaPHx9NTU3v+88Lp7dyf///3vr162PcuHExd+7c0d0go6rc83/nnXdi8eLFMXny5CiVSnHJJZf4d8AZrNzzX716dXz0ox+Nc845J+rr62PJkiXx29/+dox2y0j58Y9/HHPmzIkpU6bEuHHj4vnnn3/fNVu2bIlPfvKTUSqV4iMf+Ug89dRT5V+4OA2sX7++qKqqKp588sniv/7rv4rbbrutOP/884vu7u6jzv/JT35SVFZWFg8++GDx6quvFvfee29x9tlnF6+88soY75yRUO7533zzzcWaNWuKHTt2FDt37iz+7u/+rqitrS3++7//e4x3zkgo9/x/78033yymTp1aXHvttcVf//Vfj81mGXHlnv+hQ4eKWbNmFTfccEPx0ksvFW+++WaxZcuWorOzc4x3zkgo9/y/853vFKVSqfjOd75TvPnmm8ULL7xQTJ48uViyZMkY75yTtWnTpmL58uXFs88+W0RE8dxzzx13/u7du4tzzz23aGlpKV599dXiG9/4RlFZWVls3ry5rOueFuE7e/bsYvHixYO/7u/vL6ZMmVK0tbUddf7nPve54sYbbxwy1tDQUPz93//9qO6T0VHu+f+xw4cPF+edd17x7W9/e7S2yCgazvkfPny4uPrqq4tvfetbxcKFC4XvGazc8//mN79ZXHTRRUVfX99YbZFRVO75L168uPj0pz89ZKylpaW45pprRnWfjK4TCd8vf/nLxSc+8YkhY/PmzSuam5vLutYp/6pDX19fbNu2LZqamgbHKioqoqmpKTo6Oo66pqOjY8j8iIjm5uZjzuf0NZzz/2PvvvtuvPfee3HBBReM1jYZJcM9/69+9asxceLEuOWWW8Zim4yS4Zz/97///WhsbIzFixdHXV1dXHbZZbFy5cro7+8fq20zQoZz/ldffXVs27Zt8OsQu3fvjk2bNsUNN9wwJnvm1Bmp9iv7T24bafv374/+/v7BP/nt9+rq6mLXrl1HXdPV1XXU+V1dXaO2T0bHcM7/j919990xZcqUI35DcPobzvm/9NJL8cQTT0RnZ+cY7JDRNJzz3717d/zHf/xHfP7zn49NmzbFG2+8EV/84hfjvffei9bW1rHYNiNkOOd/8803x/79++NTn/pUFEURhw8fjjvuuCPuueeesdgyp9Cx2q+3tzd+85vfxDnnnHNC73PK7/jCyVi1alWsX78+nnvuuaiurj7V22GUHThwIObPnx/r1q2LCRMmnOrtcAoMDAzExIkT4/HHH4+ZM2fGvHnzYvny5bF27dpTvTXGwJYtW2LlypXx2GOPxfbt2+PZZ5+NjRs3xgMPPHCqt8YZ4pTf8Z0wYUJUVlZGd3f3kPHu7u6YNGnSUddMmjSprPmcvoZz/r/30EMPxapVq+KHP/xhXHHFFaO5TUZJuef/85//PN56662YM2fO4NjAwEBERJx11lnx2muvxcUXXzy6m2bEDOf3/+TJk+Pss8+OysrKwbGPfexj0dXVFX19fVFVVTWqe2bkDOf877vvvpg/f37ceuutERFx+eWXx8GDB+P222+P5cuXR0WF+3kfVMdqv5qamhO+2xtxGtzxraqqipkzZ0Z7e/vg2MDAQLS3t0djY+NR1zQ2Ng6ZHxHx4osvHnM+p6/hnH9ExIMPPhgPPPBAbN68OWbNmjUWW2UUlHv+l156abzyyivR2dk5+PrsZz8b119/fXR2dkZ9ff1Ybp+TNJzf/9dcc0288cYbg//BExHx+uuvx+TJk0XvGWY45//uu+8eEbe//4+g3/2MFB9UI9Z+5f3c3ehYv359USqViqeeeqp49dVXi9tvv704//zzi66urqIoimL+/PnF0qVLB+f/5Cc/Kc4666zioYceKnbu3Fm0trZ6nNkZrNzzX7VqVVFVVVU888wzxa9+9avB14EDB07VR+AklHv+f8xTHc5s5Z7/nj17ivPOO6/4h3/4h+K1114rfvCDHxQTJ04svva1r52qj8BJKPf8W1tbi/POO6/4t3/7t2L37t3Fv//7vxcXX3xx8bnPfe5UfQSG6cCBA8WOHTuKHTt2FBFRPPLII8WOHTuKX/ziF0VRFMXSpUuL+fPnD87//ePM/umf/qnYuXNnsWbNmjP3cWZFURTf+MY3igsvvLCoqqoqZs+eXfznf/7n4F+77rrrioULFw6Z/93vfre45JJLiqqqquITn/hEsXHjxjHeMSOpnPP/8Ic/XETEEa/W1tax3zgjotzf//8/4XvmK/f8X3755aKhoaEolUrFRRddVHz9618vDh8+PMa7ZqSUc/7vvfde8ZWvfKW4+OKLi+rq6qK+vr744he/WPzv//7v2G+ck/KjH/3oqP8u//15L1y4sLjuuuuOWDNjxoyiqqqquOiii4p//dd/Lfu644rC/xsAAOCD75R/xxcAAMaC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBT+HzgRrWHQVr4zAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from networkx import draw\n",
+    "g = pline.get_graph()[1]\n",
+    "display(g.nodes)\n",
+    "pos = tree_layout(g)\n",
+    "draw(g, pos= pos, with_labels = True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "NodeView(('prefetch.step', 'other_steps.step1', 'suite2p.do_this', 'suite2p.step2', 'demoPipeClass.initial', 'other_steps.step2', 'side_step.step1', 'side_step.step2'))"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "ename": "NetworkXError",
+     "evalue": "Node 'other_steps.step1' has no position.",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n",
+      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;49;00m v \u001b[39min\u001b[39;49;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n",
+      "\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n",
+      "\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\n",
+      "\u001b[1;31mKeyError\u001b[0m: 'other_steps.step1'\n",
+      "\n",
+      "The above exception was the direct cause of the following exception:\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m                             Traceback (most recent call last)\n",
+      "\u001b[1;32mc:\\Users\\tjostmou\\Documents\\Python\\__packages__\\Pypelines\\pypelines\\feature_test.ipynb Cell 6\u001b[0m line \u001b[0;36m5\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=2'>3</a>\u001b[0m display(g\u001b[39m.\u001b[39mnodes)\n",
+      "\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m pos \u001b[39m=\u001b[39m tree_layout(g)\n",
+      "\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=4'>5</a>\u001b[0m draw(g, pos\u001b[39m=\u001b[39;49m pos, with_labels \u001b[39m=\u001b[39;49m \u001b[39mTrue\u001b[39;49;00m)\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:121\u001b[0m, in \u001b[0;36mdraw\u001b[1;34m(G, pos, ax, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    118\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m kwds:\n",
+      "\u001b[0;32m    119\u001b[0m     kwds[\u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mlabels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39min\u001b[39;00m kwds\n",
+      "\u001b[1;32m--> 121\u001b[0m draw_networkx(G, pos\u001b[39m=\u001b[39;49mpos, ax\u001b[39m=\u001b[39;49max, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwds)\n",
+      "\u001b[0;32m    122\u001b[0m ax\u001b[39m.\u001b[39mset_axis_off()\n",
+      "\u001b[0;32m    123\u001b[0m plt\u001b[39m.\u001b[39mdraw_if_interactive()\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:303\u001b[0m, in \u001b[0;36mdraw_networkx\u001b[1;34m(G, pos, arrows, with_labels, **kwds)\u001b[0m\n",
+      "\u001b[0;32m    300\u001b[0m \u001b[39mif\u001b[39;00m pos \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n",
+      "\u001b[0;32m    301\u001b[0m     pos \u001b[39m=\u001b[39m nx\u001b[39m.\u001b[39mdrawing\u001b[39m.\u001b[39mspring_layout(G)  \u001b[39m# default to spring layout\u001b[39;00m\n",
+      "\u001b[1;32m--> 303\u001b[0m draw_networkx_nodes(G, pos, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mnode_kwds)\n",
+      "\u001b[0;32m    304\u001b[0m draw_networkx_edges(G, pos, arrows\u001b[39m=\u001b[39marrows, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39medge_kwds)\n",
+      "\u001b[0;32m    305\u001b[0m \u001b[39mif\u001b[39;00m with_labels:\n",
+      "\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:427\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n",
+      "\u001b[0;32m    425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n",
+      "\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\u001b[1;32m--> 427\u001b[0m     \u001b[39mraise\u001b[39;00m nx\u001b[39m.\u001b[39mNetworkXError(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mNode \u001b[39m\u001b[39m{\u001b[39;00merr\u001b[39m}\u001b[39;00m\u001b[39m has no position.\u001b[39m\u001b[39m\"\u001b[39m) \u001b[39mfrom\u001b[39;00m \u001b[39merr\u001b[39;00m\n",
+      "\u001b[0;32m    429\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(alpha, Iterable):\n",
+      "\u001b[0;32m    430\u001b[0m     node_color \u001b[39m=\u001b[39m apply_alpha(node_color, alpha, nodelist, cmap, vmin, vmax)\n",
+      "\n",
+      "\u001b[1;31mNetworkXError\u001b[0m: Node 'other_steps.step1' has no position."
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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fjruvffeuOeee+Iv/uIv4vnnn4/LLrvshK9ZKpWitbX1qF9/4IPP+efm/HNz/rk5/9xG4/zLfo4vAACciUbu28IAAHAaE74AAKQgfAEASEH4AgCQwmkTvmvWrIlp06ZFdXV1NDQ0xNatW487/3vf+15ceumlUV1dHZdffnls2rRpjHbKaCjn/NetWxfXXnttjB8/PsaPHx9NTU3v+88Lp7dyf///3vr162PcuHExd+7c0d0go6rc83/nnXdi8eLFMXny5CiVSnHJJZf4d8AZrNzzX716dXz0ox+Nc845J+rr62PJkiXx29/+dox2y0j58Y9/HHPmzIkpU6bEuHHj4vnnn3/fNVu2bIlPfvKTUSqV4iMf+Ug89dRT5V+4OA2sX7++qKqqKp588sniv/7rv4rbbrutOP/884vu7u6jzv/JT35SVFZWFg8++GDx6quvFvfee29x9tlnF6+88soY75yRUO7533zzzcWaNWuKHTt2FDt37iz+7u/+rqitrS3++7//e4x3zkgo9/x/78033yymTp1aXHvttcVf//Vfj81mGXHlnv+hQ4eKWbNmFTfccEPx0ksvFW+++WaxZcuWorOzc4x3zkgo9/y/853vFKVSqfjOd75TvPnmm8ULL7xQTJ48uViyZMkY75yTtWnTpmL58uXFs88+W0RE8dxzzx13/u7du4tzzz23aGlpKV599dXiG9/4RlFZWVls3ry5rOueFuE7e/bsYvHixYO/7u/vL6ZMmVK0tbUddf7nPve54sYbbxwy1tDQUPz93//9qO6T0VHu+f+xw4cPF+edd17x7W9/e7S2yCgazvkfPny4uPrqq4tvfetbxcKFC4XvGazc8//mN79ZXHTRRUVfX99YbZFRVO75L168uPj0pz89ZKylpaW45pprRnWfjK4TCd8vf/nLxSc+8YkhY/PmzSuam5vLutYp/6pDX19fbNu2LZqamgbHKioqoqmpKTo6Oo66pqOjY8j8iIjm5uZjzuf0NZzz/2PvvvtuvPfee3HBBReM1jYZJcM9/69+9asxceLEuOWWW8Zim4yS4Zz/97///WhsbIzFixdHXV1dXHbZZbFy5cro7+8fq20zQoZz/ldffXVs27Zt8OsQu3fvjk2bNsUNN9wwJnvm1Bmp9iv7T24bafv374/+/v7BP/nt9+rq6mLXrl1HXdPV1XXU+V1dXaO2T0bHcM7/j919990xZcqUI35DcPobzvm/9NJL8cQTT0RnZ+cY7JDRNJzz3717d/zHf/xHfP7zn49NmzbFG2+8EV/84hfjvffei9bW1rHYNiNkOOd/8803x/79++NTn/pUFEURhw8fjjvuuCPuueeesdgyp9Cx2q+3tzd+85vfxDnnnHNC73PK7/jCyVi1alWsX78+nnvuuaiurj7V22GUHThwIObPnx/r1q2LCRMmnOrtcAoMDAzExIkT4/HHH4+ZM2fGvHnzYvny5bF27dpTvTXGwJYtW2LlypXx2GOPxfbt2+PZZ5+NjRs3xgMPPHCqt8YZ4pTf8Z0wYUJUVlZGd3f3kPHu7u6YNGnSUddMmjSprPmcvoZz/r/30EMPxapVq+KHP/xhXHHFFaO5TUZJuef/85//PN56662YM2fO4NjAwEBERJx11lnx2muvxcUXXzy6m2bEDOf3/+TJk+Pss8+OysrKwbGPfexj0dXVFX19fVFVVTWqe2bkDOf877vvvpg/f37ceuutERFx+eWXx8GDB+P222+P5cuXR0WF+3kfVMdqv5qamhO+2xtxGtzxraqqipkzZ0Z7e/vg2MDAQLS3t0djY+NR1zQ2Ng6ZHxHx4osvHnM+p6/hnH9ExIMPPhgPPPBAbN68OWbNmjUWW2UUlHv+l156abzyyivR2dk5+PrsZz8b119/fXR2dkZ9ff1Ybp+TNJzf/9dcc0288cYbg//BExHx+uuvx+TJk0XvGWY45//uu+8eEbe//4+g3/2MFB9UI9Z+5f3c3ehYv359USqViqeeeqp49dVXi9tvv704//zzi66urqIoimL+/PnF0qVLB+f/5Cc/Kc4666zioYceKnbu3Fm0trZ6nNkZrNzzX7VqVVFVVVU888wzxa9+9avB14EDB07VR+AklHv+f8xTHc5s5Z7/nj17ivPOO6/4h3/4h+K1114rfvCDHxQTJ04svva1r52qj8BJKPf8W1tbi/POO6/4t3/7t2L37t3Fv//7vxcXX3xx8bnPfe5UfQSG6cCBA8WOHTuKHTt2FBFRPPLII8WOHTuKX/ziF0VRFMXSpUuL+fPnD87//ePM/umf/qnYuXNnsWbNmjP3cWZFURTf+MY3igsvvLCoqqoqZs+eXfznf/7n4F+77rrrioULFw6Z/93vfre45JJLiqqqquITn/hEsXHjxjHeMSOpnPP/8Ic/XETEEa/W1tax3zgjotzf//8/4XvmK/f8X3755aKhoaEolUrFRRddVHz9618vDh8+PMa7ZqSUc/7vvfde8ZWvfKW4+OKLi+rq6qK+vr744he/WPzv//7v2G+ck/KjH/3oqP8u//15L1y4sLjuuuuOWDNjxoyiqqqquOiii4p//dd/Lfu644rC/xsAAOCD75R/xxcAAMaC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBT+HzgRrWHQVr4zAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from networkx import draw\n",
+    "g = pline.get_graph()[1]\n",
+    "display(g.nodes)\n",
+    "pos = tree_layout(g)\n",
+    "draw(g, pos= pos, with_labels = True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "NodeView(('prefetch.step', 'other_steps.step1', 'suite2p.do_this', 'suite2p.step2', 'demoPipeClass.initial', 'other_steps.step2', 'side_step.step1', 'side_step.step2'))"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "ename": "NetworkXError",
+     "evalue": "Node 'other_steps.step1' has no position.",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[1;31mKeyError\u001b[0m                                  Traceback (most recent call last)",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;49;00m v \u001b[39min\u001b[39;49;00m nodelist])\n\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:425\u001b[0m, in \u001b[0;36m<listcomp>\u001b[1;34m(.0)\u001b[0m\n\u001b[0;32m    424\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m--> 425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n",
+      "\u001b[1;31mKeyError\u001b[0m: 'other_steps.step1'",
+      "\nThe above exception was the direct cause of the following exception:\n",
+      "\u001b[1;31mNetworkXError\u001b[0m                             Traceback (most recent call last)",
+      "\u001b[1;32mc:\\Users\\tjostmou\\Documents\\Python\\__packages__\\Pypelines\\pypelines\\feature_test.ipynb Cell 6\u001b[0m line \u001b[0;36m5\n\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=2'>3</a>\u001b[0m display(g\u001b[39m.\u001b[39mnodes)\n\u001b[0;32m      <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=3'>4</a>\u001b[0m pos \u001b[39m=\u001b[39m tree_layout(g)\n\u001b[1;32m----> <a href='vscode-notebook-cell:/c%3A/Users/tjostmou/Documents/Python/__packages__/Pypelines/pypelines/feature_test.ipynb#W4sZmlsZQ%3D%3D?line=4'>5</a>\u001b[0m draw(g, pos\u001b[39m=\u001b[39;49m pos, with_labels \u001b[39m=\u001b[39;49m \u001b[39mTrue\u001b[39;49;00m)\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:121\u001b[0m, in \u001b[0;36mdraw\u001b[1;34m(G, pos, ax, **kwds)\u001b[0m\n\u001b[0;32m    118\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39mnot\u001b[39;00m \u001b[39min\u001b[39;00m kwds:\n\u001b[0;32m    119\u001b[0m     kwds[\u001b[39m\"\u001b[39m\u001b[39mwith_labels\u001b[39m\u001b[39m\"\u001b[39m] \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mlabels\u001b[39m\u001b[39m\"\u001b[39m \u001b[39min\u001b[39;00m kwds\n\u001b[1;32m--> 121\u001b[0m draw_networkx(G, pos\u001b[39m=\u001b[39;49mpos, ax\u001b[39m=\u001b[39;49max, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwds)\n\u001b[0;32m    122\u001b[0m ax\u001b[39m.\u001b[39mset_axis_off()\n\u001b[0;32m    123\u001b[0m plt\u001b[39m.\u001b[39mdraw_if_interactive()\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:303\u001b[0m, in \u001b[0;36mdraw_networkx\u001b[1;34m(G, pos, arrows, with_labels, **kwds)\u001b[0m\n\u001b[0;32m    300\u001b[0m \u001b[39mif\u001b[39;00m pos \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m    301\u001b[0m     pos \u001b[39m=\u001b[39m nx\u001b[39m.\u001b[39mdrawing\u001b[39m.\u001b[39mspring_layout(G)  \u001b[39m# default to spring layout\u001b[39;00m\n\u001b[1;32m--> 303\u001b[0m draw_networkx_nodes(G, pos, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mnode_kwds)\n\u001b[0;32m    304\u001b[0m draw_networkx_edges(G, pos, arrows\u001b[39m=\u001b[39marrows, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39medge_kwds)\n\u001b[0;32m    305\u001b[0m \u001b[39mif\u001b[39;00m with_labels:\n",
+      "File \u001b[1;32mc:\\Users\\tjostmou\\anaconda3\\envs\\Inflow\\Lib\\site-packages\\networkx\\drawing\\nx_pylab.py:427\u001b[0m, in \u001b[0;36mdraw_networkx_nodes\u001b[1;34m(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, edgecolors, label, margins)\u001b[0m\n\u001b[0;32m    425\u001b[0m     xy \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray([pos[v] \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m nodelist])\n\u001b[0;32m    426\u001b[0m \u001b[39mexcept\u001b[39;00m \u001b[39mKeyError\u001b[39;00m \u001b[39mas\u001b[39;00m err:\n\u001b[1;32m--> 427\u001b[0m     \u001b[39mraise\u001b[39;00m nx\u001b[39m.\u001b[39mNetworkXError(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mNode \u001b[39m\u001b[39m{\u001b[39;00merr\u001b[39m}\u001b[39;00m\u001b[39m has no position.\u001b[39m\u001b[39m\"\u001b[39m) \u001b[39mfrom\u001b[39;00m \u001b[39merr\u001b[39;00m\n\u001b[0;32m    429\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(alpha, Iterable):\n\u001b[0;32m    430\u001b[0m     node_color \u001b[39m=\u001b[39m apply_alpha(node_color, alpha, nodelist, cmap, vmin, vmax)\n",
+      "\u001b[1;31mNetworkXError\u001b[0m: Node 'other_steps.step1' has no position."
+     ]
+    },
+    {
+     "data": {
+      "image/png": "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fjruvffeuOeee+Iv/uIv4vnnn4/LLrvshK9ZKpWitbX1qF9/4IPP+efm/HNz/rk5/9xG4/zLfo4vAACciUbu28IAAHAaE74AAKQgfAEASEH4AgCQwmkTvmvWrIlp06ZFdXV1NDQ0xNatW487/3vf+15ceumlUV1dHZdffnls2rRpjHbKaCjn/NetWxfXXnttjB8/PsaPHx9NTU3v+88Lp7dyf///3vr162PcuHExd+7c0d0go6rc83/nnXdi8eLFMXny5CiVSnHJJZf4d8AZrNzzX716dXz0ox+Nc845J+rr62PJkiXx29/+dox2y0j58Y9/HHPmzIkpU6bEuHHj4vnnn3/fNVu2bIlPfvKTUSqV4iMf+Ug89dRT5V+4OA2sX7++qKqqKp588sniv/7rv4rbbrutOP/884vu7u6jzv/JT35SVFZWFg8++GDx6quvFvfee29x9tlnF6+88soY75yRUO7533zzzcWaNWuKHTt2FDt37iz+7u/+rqitrS3++7//e4x3zkgo9/x/78033yymTp1aXHvttcVf//Vfj81mGXHlnv+hQ4eKWbNmFTfccEPx0ksvFW+++WaxZcuWorOzc4x3zkgo9/y/853vFKVSqfjOd75TvPnmm8ULL7xQTJ48uViyZMkY75yTtWnTpmL58uXFs88+W0RE8dxzzx13/u7du4tzzz23aGlpKV599dXiG9/4RlFZWVls3ry5rOueFuE7e/bsYvHixYO/7u/vL6ZMmVK0tbUddf7nPve54sYbbxwy1tDQUPz93//9qO6T0VHu+f+xw4cPF+edd17x7W9/e7S2yCgazvkfPny4uPrqq4tvfetbxcKFC4XvGazc8//mN79ZXHTRRUVfX99YbZFRVO75L168uPj0pz89ZKylpaW45pprRnWfjK4TCd8vf/nLxSc+8YkhY/PmzSuam5vLutYp/6pDX19fbNu2LZqamgbHKioqoqmpKTo6Oo66pqOjY8j8iIjm5uZjzuf0NZzz/2PvvvtuvPfee3HBBReM1jYZJcM9/69+9asxceLEuOWWW8Zim4yS4Zz/97///WhsbIzFixdHXV1dXHbZZbFy5cro7+8fq20zQoZz/ldffXVs27Zt8OsQu3fvjk2bNsUNN9wwJnvm1Bmp9iv7T24bafv374/+/v7BP/nt9+rq6mLXrl1HXdPV1XXU+V1dXaO2T0bHcM7/j919990xZcqUI35DcPobzvm/9NJL8cQTT0RnZ+cY7JDRNJzz3717d/zHf/xHfP7zn49NmzbFG2+8EV/84hfjvffei9bW1rHYNiNkOOd/8803x/79++NTn/pUFEURhw8fjjvuuCPuueeesdgyp9Cx2q+3tzd+85vfxDnnnHNC73PK7/jCyVi1alWsX78+nnvuuaiurj7V22GUHThwIObPnx/r1q2LCRMmnOrtcAoMDAzExIkT4/HHH4+ZM2fGvHnzYvny5bF27dpTvTXGwJYtW2LlypXx2GOPxfbt2+PZZ5+NjRs3xgMPPHCqt8YZ4pTf8Z0wYUJUVlZGd3f3kPHu7u6YNGnSUddMmjSprPmcvoZz/r/30EMPxapVq+KHP/xhXHHFFaO5TUZJuef/85//PN56662YM2fO4NjAwEBERJx11lnx2muvxcUXXzy6m2bEDOf3/+TJk+Pss8+OysrKwbGPfexj0dXVFX19fVFVVTWqe2bkDOf877vvvpg/f37ceuutERFx+eWXx8GDB+P222+P5cuXR0WF+3kfVMdqv5qamhO+2xtxGtzxraqqipkzZ0Z7e/vg2MDAQLS3t0djY+NR1zQ2Ng6ZHxHx4osvHnM+p6/hnH9ExIMPPhgPPPBAbN68OWbNmjUWW2UUlHv+l156abzyyivR2dk5+PrsZz8b119/fXR2dkZ9ff1Ybp+TNJzf/9dcc0288cYbg//BExHx+uuvx+TJk0XvGWY45//uu+8eEbe//4+g3/2MFB9UI9Z+5f3c3ehYv359USqViqeeeqp49dVXi9tvv704//zzi66urqIoimL+/PnF0qVLB+f/5Cc/Kc4666zioYceKnbu3Fm0trZ6nNkZrNzzX7VqVVFVVVU888wzxa9+9avB14EDB07VR+AklHv+f8xTHc5s5Z7/nj17ivPOO6/4h3/4h+K1114rfvCDHxQTJ04svva1r52qj8BJKPf8W1tbi/POO6/4t3/7t2L37t3Fv//7vxcXX3xx8bnPfe5UfQSG6cCBA8WOHTuKHTt2FBFRPPLII8WOHTuKX/ziF0VRFMXSpUuL+fPnD87//ePM/umf/qnYuXNnsWbNmjP3cWZFURTf+MY3igsvvLCoqqoqZs+eXfznf/7n4F+77rrrioULFw6Z/93vfre45JJLiqqqquITn/hEsXHjxjHeMSOpnPP/8Ic/XETEEa/W1tax3zgjotzf//8/4XvmK/f8X3755aKhoaEolUrFRRddVHz9618vDh8+PMa7ZqSUc/7vvfde8ZWvfKW4+OKLi+rq6qK+vr744he/WPzv//7v2G+ck/KjH/3oqP8u//15L1y4sLjuuuuOWDNjxoyiqqqquOiii4p//dd/Lfu644rC/xsAAOCD75R/xxcAAMaC8AUAIAXhCwBACsIXAIAUhC8AACkIXwAAUhC+AACkIHwBAEhB+AIAkILwBQAgBeELAEAKwhcAgBT+HzgRrWHQVr4zAAAAAElFTkSuQmCC",
+      "text/plain": [
+       "<Figure size 640x480 with 1 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "from networkx import draw\n",
+    "g = pline.get_graph()[1]\n",
+    "display(g.nodes)\n",
+    "pos = tree_layout(g)\n",
+    "draw(g, pos= pos, with_labels = True)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'initial': <demoPipeClass.initial StepObject>}"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "pline.demoPipeClass.steps"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Inflow",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/pypelines/pipe.py b/pypelines/pipe.py
index 8934883..28fa983 100644
--- a/pypelines/pipe.py
+++ b/pypelines/pipe.py
@@ -1,6 +1,7 @@
 from . step import BaseStep
 from . multisession import BaseMultisessionAccessor
 from . sessions import Session
+from . disk import PickleObject
 
 from functools import wraps
 import inspect
@@ -10,37 +11,37 @@ from typing import Callable, Type, Iterable, Protocol, TYPE_CHECKING
 if TYPE_CHECKING:
     from .pipeline import BasePipeline
 
-class PipeMetaclass(type):
+# class PipeMetaclass(type):
     
-    def __new__(cls : Type, pipe_name : str, bases : Iterable[Type], attributes : dict) -> Type:
-        return super().__new__(cls, pipe_name, bases, attributes)
+#     def __new__(cls : Type, pipe_name : str, bases : Iterable[Type], attributes : dict) -> Type:
+#         return super().__new__(cls, pipe_name, bases, attributes)
     
-    def __init__(cls : Type, pipe_name : str, bases : Iterable[Type], attributes : dict) -> None:
+#     def __init__(cls : Type, pipe_name : str, bases : Iterable[Type], attributes : dict) -> None:
         
-        steps = getattr(cls,"steps",{})
+#         steps = getattr(cls,"steps",{})
 
-        for name, attribute in attributes.items():
-            if getattr(attribute, "is_step", False):
-                steps[name] = PipeMetaclass.step_with_attributes(attribute , pipe_name , name)
+#         for name, attribute in attributes.items():
+#             if getattr(attribute, "is_step", False):
+#                 steps[name] = PipeMetaclass.step_with_attributes(attribute , pipe_name , name)
 
-        setattr(cls,"steps",steps)
+#         setattr(cls,"steps",steps)
 
-    @staticmethod
-    def step_with_attributes(step : BaseStep, pipe_name : str, step_name : str) -> BaseStep:
+#     @staticmethod
+#     def step_with_attributes(step : BaseStep, pipe_name : str, step_name : str) -> BaseStep:
         
-        setattr(step, "pipe_name", pipe_name) 
-        setattr(step, "step_name", step_name) 
+#         setattr(step, "pipe_name", pipe_name) 
+#         setattr(step, "step_name", step_name) 
 
-        return step
+#         return step
     
-class BasePipe(metaclass = PipeMetaclass):
+class BasePipe :#(metaclass = PipeMetaclass):
     # this class must implements only the logic to link blocks together.
     # It is agnostic about what way data is stored, and the way the blocks function. 
     # Hence it is designed to be overloaded, and cannot be used as is.
 
-    use_versions = True
     single_step = False
     step_class = BaseStep
+    disk_class = PickleObject
     multisession_class = BaseMultisessionAccessor
 
     def __init__(self, parent_pipeline : "BasePipeline") -> None :
@@ -48,25 +49,36 @@ class BasePipe(metaclass = PipeMetaclass):
         self.multisession = self.multisession_class(self)
         self.pipeline = parent_pipeline
         self.pipe_name = self.__class__.__name__
-        print(self.pipe_name)
+        #print(self.pipe_name)
+
+        self.steps = {}
+        for (step_name, step) in inspect.getmembers( self , predicate = inspect.ismethod ):
+            if getattr(step, "is_step", False): 
+                self.steps[step_name] = step
+
+        if len(self.steps) < 1 :
+            raise ValueError(f"You should register at least one step class with @stepmethod in {self.pipe_name} class. { self.steps = }")
 
         if len(self.steps) > 1 and self.single_step:
-            raise ValueError(f"Cannot set single_step to True if you registered more than one step inside {self.pipe_name} class")
+            raise ValueError(f"Cannot set single_step to True if you registered more than one step inside {self.pipe_name} class. { self.steps = }")
         
+        #if self.single_step is None : 
+        #    self.single_step = False if len(self.steps) > 1 else True
+
         # this loop allows to populate self.steps from the now instanciated version of the step method.
         # Using only instanciated version is important to be able to use self into it later, 
         # without confusing ourselved with uninstanciated versions in the steps dict
 
-        for step_name, _ in self.steps.items():
-            step = getattr(self , step_name) # get the instanciated step method from name. 
+        for step_name, step in self.steps.items():
             step = self.step_class(self.pipeline, self, step, step_name)
-            self.steps[step_name] = step
+            self.steps[step_name] = step #replace the bound_method by a step_class using that bound method, so that we attach the necessary components to it.
             setattr(self, step_name, step)
 
         # attaches itself to the parent pipeline
         if self.single_step :
             step = list(self.steps.values())[0]
             self.pipeline.pipes[self.pipe_name] = step
+            step.steps = self.steps #just add steps to this step serving as a pipe, so that it behaves similarly to a pipe for some pipelines function requiring this attribute to exist.
             setattr(self.pipeline, self.pipe_name, step)
         else :
             self.pipeline.pipes[self.pipe_name] = self
diff --git a/pypelines/pipeline.py b/pypelines/pipeline.py
index 01af955..78c97fd 100644
--- a/pypelines/pipeline.py
+++ b/pypelines/pipeline.py
@@ -7,16 +7,20 @@ if TYPE_CHECKING:
 
 class BasePipeline:
 
-    pipes = {}
+    def __init__(self,name):
+        self.pipeline_name = name
+        self.pipes = {}
+        self.resolved = False
     
     def register_pipe(self, pipe_class : type) -> type:
         """Wrapper to instanciate and attache a a class inheriting from BasePipe it to the Pipeline instance.
         The Wraper returns the class without changing it."""
-        pipe_class(self)
-
+        instance = pipe_class(self)
+        #print(f"Added instance of Pipe {instance.pipe_name} to instance of Pipeline {self.__class__.__name__} {self = }")
+        self.resolved = False
         return pipe_class
         
-    def resolve(self, instance_name : str) :
+    def resolve_instance(self, instance_name : str) :
         pipe_name , step_name = instance_name.split(".")
         try :
             pipe = self.pipes[pipe_name]
@@ -25,32 +29,64 @@ class BasePipeline:
             return pipe.steps[step_name]
         except KeyError :
             raise KeyError(f"No instance {instance_name} has been registered to the pipeline")
+        
+    def resolve(self):
+        if self.resolved:
+            return
+        
+        for pipe in self.pipes.values() :
+
+            for step in pipe.steps.values() :
+                instanciated_requires = []
+                for req in step.requires :
+                    if isinstance(req,str):
+                        req = self.resolve_instance(req)
+                    instanciated_requires.append(req)
+                step.requires = instanciated_requires
+            
+        self.resolved = True
 
     def get_requirement_stack(self, instance, required_steps = None, parents = None, max_recursion = 100):
+
         if required_steps is None :
             required_steps = []
     
         if parents is None:
             parents = []
-            
-        if isinstance(instance,str):
-            instance = self.resolve(instance)
-    
+
+        self.resolve()
+
         if instance in parents :
             raise RecursionError(f"Circular import : {parents[-1]} requires {instance} wich exists in parents hierarchy : {parents}")
             
         parents.append(instance)
         if len(parents) > max_recursion :
             raise ValueError("Too much recursion, unrealistic number of pipes chaining. Investigate errors or increase max_recursion")
-        instanciated_requires = []
         
         for requirement in instance.requires:
             required_steps, requirement = self.get_requirement_stack(requirement, required_steps, parents, max_recursion)
             if not requirement in required_steps:
                 required_steps.append(requirement)
-            instanciated_requires.append(requirement)
-            
-        instance.requires = instanciated_requires
+
         parents.pop(-1)
         
-        return required_steps, instance
\ No newline at end of file
+        return required_steps, instance
+    
+    def get_graph(self):
+        from networkx import DiGraph
+
+        self.resolve()
+
+        callable_graph = DiGraph()
+        display_graph = DiGraph()
+        for pipe in self.pipes.values() :
+
+            for step in pipe.steps.values() :
+                callable_graph.add_node(step)
+                display_graph.add_node(step.full_name)
+                for req in step.requires :
+                    callable_graph.add_edge(req, step)
+                    display_graph.add_edge(req.full_name, step.full_name)
+
+        return callable_graph, display_graph
+            
\ No newline at end of file
diff --git a/pypelines/step.py b/pypelines/step.py
index e2caa58..fd32cc2 100644
--- a/pypelines/step.py
+++ b/pypelines/step.py
@@ -8,37 +8,50 @@ from typing import Callable, Type, Iterable, Protocol, TYPE_CHECKING
 if TYPE_CHECKING:
     from .pipeline import BasePipeline
     from .pipe import BasePipe
+    from .disk import BaseDiskObject
 
-def stepmethod(requires = [], version = None):
+
+def stepmethod(requires=[], version=None):
     # This method allows to register class methods inheriting of BasePipe as steps.
     # It basically just step an "is_step" stamp on the method that are defined as steps.
     # This stamp will later be used in the metaclass __new__ to set additionnal usefull attributes to those methods
     def registrate(function):
-
         function.requires = [requires] if not isinstance(requires, list) else requires
         function.is_step = True
         function.use_version = False if version is None else True
         function.version = version
         return function
+
     return registrate
 
-class BaseStep:
 
-    def __init__(self, pipeline : "BasePipeline", pipe : "BasePipe", step : "BaseStep", step_name : str):
-        self.pipeline = pipeline # save an instanciated access to the pipeline parent
-        self.pipe = pipe # save an instanciated access to the pipe parent
-        self.step = step # save an instanciated access to the step function (undecorated)
+class BaseStep:
+    def __init__(
+        self,
+        pipeline: "BasePipeline",
+        pipe: "BasePipe",
+        step: "BaseStep",
+        step_name: str,
+    ):
+        self.pipeline = pipeline  # save an instanciated access to the pipeline parent
+        self.pipe = pipe  # save an instanciated access to the pipe parent
+        self.step = (
+            step  # save an instanciated access to the step function (undecorated)
+        )
         self.pipe_name = pipe.pipe_name
         self.step_name = step_name
+        self.full_name = f"{self.pipe_name}.{self.step_name}"
         self.use_version = self.step.use_version
         self.version = self.step.version
 
         self.single_step = self.pipe.single_step
         self.requires = self.step.requires
         self.is_step = True
-        
-        self.requirement_stack = partial( self.pipeline.get_requirement_stack, instance = self )
-        self.step_version = partial( self.pipe.step_version, step = self )
+
+        self.requirement_stack = partial(
+            self.pipeline.get_requirement_stack, instance=self
+        )
+        # self.step_version = partial( self.pipe.step_version, step = self )
 
         update_wrapper(self, self.step)
         self._make_wrapped_functions()
@@ -55,39 +68,51 @@ class BaseStep:
         self.make_wrapped_generate()
 
     def make_wrapped_save(self):
-        self.save = self.pipe.dispatcher(self._version_wrapper(self.pipe.file_saver))
-    
+        def wrapper(session, data, extra=""):
+            disk_object = self.pipe.disk_class(session, self, extra=extra)
+            disk_object.check_disk()
+            return disk_object.save(data)
+
+        self.save = self.pipe.dispatcher(wrapper)
+
     def make_wrapped_load(self):
-        self.load = self.pipe.dispatcher(self._version_wrapper(self.pipe.file_loader))
-    
+        def wrapper(session, extra=""):
+            disk_object = self.pipe.disk_class(session, self, extra=extra)
+            disk_object.check_disk()
+            return disk_object.load()
+
+        self.load = self.pipe.dispatcher(wrapper)
+
     def make_wrapped_generate(self):
-        self.generate = loggedmethod(
-            self._version_wrapper(
-                self.pipe.dispatcher(
-                    self._load_or_generate_wrapper(
-                        self._save_after_generate_wrapper(
-                            self.pipe.pre_run_wrapper(self.step)
-                            )
-                        )
-                    )
+        def wrapper(session, *args, extra="", **kwargs):
+            disk_object = self.pipe.disk_class(session, self, extra=extra)
+            return loggedmethod(
+                self._load_or_generate_wrapper(
+                    self._save_after_generate_wrapper(
+                        self.pipe.pre_run_wrapper(self.step), disk_object
+                    ),
+                    disk_object,
                 )
-            )
-
+            )(session, *args, extra = extra, **kwargs)
 
+        self.generate = self.pipe.dispatcher(wrapper)
 
     def step_current_version(self) -> str:
-        #simply returns the current string of the version that is in the config file.
+        # simply returns the current string of the version that is in the config file.
         return "version"
         ...
 
     def _version_wrapper(self, function):
         @wraps(function)
-        def wrapper(*args,**kwargs):
+        def wrapper(*args, **kwargs):
             version = self.step_current_version(self)
             return function(*args, version=version, **kwargs)
+
         return wrapper
 
-    def _load_or_generate_wrapper(self, function: Callable):  
+    def _load_or_generate_wrapper(
+        self, function: Callable, disk_object: "BaseDiskObject"
+    ):
         """
         Decorator to load instead of calculating if not refreshing and saved data exists
         """
@@ -114,7 +139,7 @@ class BaseStep:
 
             kwargs = kwargs.copy()
             extra = kwargs.get("extra", "")
-            version = kwargs.get("version", "")
+            # version = kwargs.get("version", "")
             skipping = kwargs.pop("skip", False)
             # we raise if file not found only if skipping is True
             refresh = kwargs.get("refresh", False)
@@ -136,35 +161,38 @@ class BaseStep:
                 )
 
             if not refresh:
-                if skipping and self.pipe.file_checker(session_details, extra=extra, version=version):
-                    logger.load_info(
+                if disk_object.check_disk() and skipping:
+                    logger.info(
                         f"File exists for {self.pipe_name}{'.' + extra if extra else ''}. Loading and processing have been skipped"
                     )
                     return None
                 logger.debug(f"Trying to load saved data")
                 try:
-                    result = self.pipe.file_loader(session_details, extra=extra, version=version)
-                    logger.load_info(
+                    result = (
+                        disk_object.load()
+                    )  # self.pipe.file_loader(session_details, extra=extra, version=version)
+                    logger.info(
                         f"Found and loaded {self.pipe_name}{'.' + extra if extra else ''} file. Processing has been skipped "
                     )
                     return result
                 except IOError:
-                    logger.load_info(
+                    logger.info(
                         f"Could not find or load {self.pipe_name}{'.' + extra if extra else ''} saved file."
                     )
 
-            logger.load_info(
+            logger.info(
                 f"Performing the computation to generate {self.pipe_name}{'.' + extra if extra else ''}. Hold tight."
             )
             return function(session_details, *args, **kwargs)
 
         return wrap
 
-    def _save_after_generate_wrapper(self, function: Callable):
+    def _save_after_generate_wrapper(
+        self, function: Callable, disk_object: "BaseDiskObject"
+    ):
         # decorator to load instead of calculating if not refreshing and saved data exists
         @wraps(function)
         def wrap(session, *args, **kwargs):
-
             logger = logging.getLogger("save_pipeline")
 
             kwargs = kwargs.copy()
@@ -176,11 +204,12 @@ class BaseStep:
             if session is not None:
                 if save_pipeline:
                     # we overwrite inside saver, if file exists and save_pipeline is True
-                    self.pipe.file_saver(session, result, extra=extra, version=version)
+                    disk_object.save(result)
+                    # self.pipe.file_saver(session, result, extra=extra, version=version)
             else:
                 logger.warning(
                     f"Cannot guess data saving location for {self.pipe_name}: 'session_details' argument must be supplied."
                 )
             return result
 
-        return wrap
\ No newline at end of file
+        return wrap
diff --git a/scripts/self_install_local_editmode.cmd b/scripts/self_install_local_editmode.cmd
new file mode 100644
index 0000000..a552cdc
--- /dev/null
+++ b/scripts/self_install_local_editmode.cmd
@@ -0,0 +1,4 @@
+call conda activate Inflow
+cd ..
+pip install -e .
+PAUSE
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 96e1e45..52084d4 100644
--- a/setup.py
+++ b/setup.py
@@ -18,14 +18,14 @@ def get_version(rel_path):
     raise RuntimeError('Unable to find version string.')
 
 setup(
-    name= 'analines',
+    name= 'pypelines',
     version= get_version(Path('pypelines', '__init__.py')),
     packages=find_packages(),
     url= 'https://gitlab.pasteur.fr/haisslab/data-management/pypelines',
     license= 'MIT',
     author= 'Timothé Jost-MOUSSEAU',
     author_email= 'timothe.jost-mousseau@pasteur.com',
-    description= 'Framework to organize pprocessing files outputs.',
+    description= 'Framework to organize processing code outputs to/from disk, processing chaining and versionning with a common easy to use api',
     classifiers=[
         'Development Status :: 3 - Alpha',
         'Intended Audience :: Developers',
@@ -39,10 +39,6 @@ setup(
         'Programming Language :: Python :: 3.11',
     ],
     install_requires=[
-        "numpy>=1.23",
-        "opencv-python>=4.6",
-        "ffmpeg>=1.4",
-        "tifffile>=2022.10"
     ],
     entry_points={},
     scripts={},
diff --git a/tests/__pycache__/tests.cpython-311.pyc b/tests/__pycache__/tests.cpython-311.pyc
index b7fd70566d32d16f28c1d314b77bf84174b64f1a..0ea4c0a8ee5a68e3022394f6a8c3bd49ac3e10a5 100644
GIT binary patch
delta 19
ZcmaFL|CFC=IWI340}$k_+{ksC9RN5a1#kcW

delta 19
ZcmaFL|CFC=IWI340}wo8+Q@aA9RN4I1w#M;

-- 
GitLab