mabuchilab / QNET

Computer algebra package for quantum mechanics and photonic quantum networks
https://qnet.readthedocs.io/
MIT License
71 stars 23 forks source link

.show() method fails #84

Closed eunjongkim closed 5 years ago

eunjongkim commented 5 years ago

Description

Hi, I'm trying to learn the qnet package for my research. I was wondering if I'm doing this in a right way or this method is broken. I assume the error is related to filepath of the temporary file generated..

What I Did

This is the command I ran:

from qnet import *
from sympy import I, sqrt, exp
init_printing()

ϕ = symbols(r"phi", real=True)
Gϕ = SLH(Matrix([[exp(I*ϕ)]]), Matrix([[0]]), 0)
Gϕ.show()

and this is what I got:

<ipython-input-10-e2bcc04e367d> in <module>()
----> 1 Gϕ.show()

~\AppData\Local\conda\conda\envs\qnet2-env\lib\site-packages\qnet\algebra\core\circuit_algebra.py in show(self)
    200         from IPython.display import Image, display
    201 
--> 202         fname = self.render()
    203         display(Image(filename=fname))
    204 

~\AppData\Local\conda\conda\envs\qnet2-env\lib\site-packages\qnet\algebra\core\circuit_algebra.py in render(self, fname)
    221             fname = tmp_dir + "/tmp_{}.png".format(hash(time))
    222 
--> 223         if circuit_visualization.draw_circuit(self, fname):
    224             done = False
    225             for k in range(20):

~\AppData\Local\conda\conda\envs\qnet2-env\lib\site-packages\qnet\visualization\circuit_pyx.py in draw_circuit(circuit, filename, direction, hunit, vunit, rhmargin, rvmargin, rpermutation_length, draw_boxes, permutation_arrows)
    307         c.writetofile(filename)
    308     elif any(filename.endswith(suffix) for suffix in ('.png', '.jpg')):
--> 309         c.writeGSfile(filename)
    310     return True

~\AppData\Local\conda\conda\envs\qnet2-env\lib\site-packages\pyx\canvas.py in writeGSfile(self, filename, device, input, **kwargs)
    472         if input == "eps":
    473             cmd.append("-")
--> 474             p = config.Popen(cmd, stdin=config.PIPE)
    475             self.writeEPSfile(p.stdin, **kwargs)
    476             p.stdin.close()

~\AppData\Local\conda\conda\envs\qnet2-env\lib\site-packages\pyx\config.py in Popen(cmd, *args, **kwargs)
    188         info += " located at {}".format(shutil.which(cmd[0]))
    189     logger_execute.info(info)
--> 190     return subprocess.Popen(cmd, *args, **kwargs)
    191 
    192 PIPE = subprocess.PIPE

~\AppData\Local\conda\conda\envs\qnet2-env\lib\subprocess.py in __init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, encoding, errors)
    707                                 c2pread, c2pwrite,
    708                                 errread, errwrite,
--> 709                                 restore_signals, start_new_session)
    710         except:
    711             # Cleanup if the child failed starting.

~\AppData\Local\conda\conda\envs\qnet2-env\lib\subprocess.py in _execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_start_new_session)
    995                                          env,
    996                                          os.fspath(cwd) if cwd is not None else None,
--> 997                                          startupinfo)
    998             finally:
    999                 # Child is launched. Close the parent's copy of those pipe

FileNotFoundError: [WinError 2] The system cannot find the file specified
danielwe commented 5 years ago

Thrilled to hear back from some users of QNET!

Unfortunately, I'm unable to reproduce your error. Can you give more information about your environment?

I'm running Ubuntu 18.04, using conda to manage python environments. I set up an environment to investigate your issue as follows:

conda create -n test python=3.6 ipykernel
conda activate test
python -m ipykernel install --user --name test --display-name "Python 3 (test)"
git clone https://github.com/mabuchilab/QNET.git
pip install -e ./QNET
pip install pyx
jupyter notebook

Then I ran your code in a new notebook created with the new Python 3 (test) kernel, and here's what it looks like: screenshot from 2018-10-05 14-44-25

If you're using a text console and not a jupyter notebook or qtconsole, you will not see the graphics, but just a text repr that says <IPython.core.display.Image object>.

Note: the warning messages from PyX that are showing in my notebook can be suppressed by running the following code at the top of the notebook:

import logging
logging.getLogger("pyx").setLevel("ERROR")

This is a nuisance that QNET should take care of itself in the not too far future.

eunjongkim commented 5 years ago

Thanks for the reply @danielwe , I followed the exact same steps as you mentioned, and I still get the same error:

image image

Perhaps this is a windows-specific bug that needs to be addressed. One possible culprit is this part

c:\users\ekim7\qnet\src\qnet\algebra\core\circuit_algebra.py in render(self, fname)
    221             fname = tmp_dir + "/tmp_{}.png".format(hash(time))

I think for windows path must be expressed as

fname = tmp_dir + "\\tmp_{}.png".format(hash(time))

But that was insufficient for me to get rid of this error..

goerz commented 5 years ago

Yeah, incompatibility with Windows is definitely the culprit here. Those path concatenations should be done with os.path.join. I don't really have access to any Windows machine, so this will be tricky for me to test at the moment.

goerz commented 5 years ago

I think there are some Continuous-Integration services available for Github that test on Windows, and we should probably look into those if we want to support Windows.

danielwe commented 5 years ago

Good news, I was able to reproduce the error in a Windows VM. It occurs already in the import statement. I will look further into it as time allows over the next days, and see if Windows support is a realistic goal.

danielwe commented 5 years ago

So here's the problem: on Windows, neither MikTeX nor TeX Live installations expose the ghostscript executable gs, which is called by pyx, the visualization library used by QNET. The FileNotFoundError comes from trying to call gs, not from the slightly malformed temp file path---turns out, Windows can usually handle file paths with forward slashes, and even mixed forward and backward slashes (still, we should eventually change to using os.path or pathlib to construct such paths).

Both distributions do however expose a ghostscript executable/wrapper: MikTeX calls it mgs, and TeX Live rungs. So if you have MikTeX, one way to make QNET visualizations work on Windows is to change the following line in src/qnet/visualization/circuit_pyx.py:

         c.writeGSfile(filename)

to

         c.writeGSfile(filename, gs="mgs")

If you have TeX Live, replace mgs with rungs.

I guess we should implement a check for which of gs, mgs, rungs, or perhaps gswin32c, is available and executable upon import.

danielwe commented 5 years ago

Does the latest commit solve the problem on your system, @eunjongkim?

eunjongkim commented 5 years ago

@danielwe I just checked that the latest commit, together with a minor change

fname = tmp_dir + "\\tmp_{}.png".format(hash(time))

to take into account windows path worked. Thanks for the update!

danielwe commented 5 years ago

Have you tried without your manual modification? On my Windows setup, it works regardless. I'll soon go through and fix this and any similar instances I can find, but I'm curious whether the current code actually fails on certain setups or not.

eunjongkim commented 5 years ago

It seems to work for me as well without the manual modification.