xzos / PyZDDE

Zemax/ OpticStudio Extension using Python
MIT License
154 stars 64 forks source link

Unable to use zSaveDetector #71

Closed shbhuk closed 7 years ago

shbhuk commented 7 years ago

Hi, I am trying to use zSaveDetector which gives me error code -2. I am using a Rectangular detector in NSC mode. Post running a ray trace using zNSCTrace I use the zSaveDetector command

ln = pyz.createLink()
ln.zGetRefresh()
zmxfile = os.path.split(ln.zGetFile())[1]
ln.zNSCTrace(1,0,timeout=5000)
ln.zSaveDetector(1,36,location+'sample.ddr')
shbhuk commented 7 years ago

I get the code 0 (successful) when I give the filename as just 'sample.ddr'. However it is still not in the Lens file folder.

Else, is it possible to directly save the detector as a txt file?

shbhuk commented 7 years ago

I also tried using zGetDetectorViewer, it saves a txt file, however gives an AttributeError: NoneType object has no attribute group.

Further if I want to specify which detector file to be saved, how should I go about that?

indranilsinharoy commented 7 years ago

@shbhuk. Hi, I'm sorry for replying late. I just don't have any bandwidth to look into this before the coming weekend. I'll work on it then. Thanks for reporting. Regards, Indranil.

shbhuk commented 7 years ago

Alright. Look forward to hear from you.

Thanks.

indranilsinharoy commented 7 years ago

Hi @shbhuk ,

I think there is a problem with your location string. Are you using double backslashes or single backslashes in your directory path? The reason I suspect that is because the function seems to work in my test. This is what I did:

First, I loaded the sample file Interference Example 2- A Mach-Zehnder Interferometer.ZMX from ...\Documents\ZEMAX\Samples\Non-sequential\Coherence Interference and Diffraction into Zemax NSC mode. Then, I traced the rays and saved the detector from the Jupyter QtConsole:

ln = pyz.createLink(1)
zmxfile = ln.zGetFile()
ln.zNSCTrace(surfNum=1, srcNum=0, split=1, usePolar=1)
import os
filename = os.path.join(os.path.split(zmxfile)[0], 'sample.DDR')
ln.zSaveDetector(surfNum=1, objNum=9, fileName=filename)
ln.close()

Note that I the function ln.zSaveDetector() returned 0.

Following ray tracing, when I do:

os.listdir(os.path.split(zmxfile)[0])

I see the following output (note the sample.DDR file in the end):

['Interference Example 1- A Simple Interferometer.SES',
 'Interference Example 1- A Simple Interferometer.ZDA',
 'Interference Example 1- A Simple Interferometer.ZMX',
 'Interference Example 2- A Mach-Zehnder Interferometer.SES',
 'Interference Example 2- A Mach-Zehnder Interferometer.ZDA',
 'Interference Example 2- A Mach-Zehnder Interferometer.ZMX',
 'Interference Example 3- Coherence Length Reduces Fringe Visibility.SES',
 'Interference Example 3- Coherence Length Reduces Fringe Visibility.ZDA',
 'Interference Example 3- Coherence Length Reduces Fringe Visibility.ZMX',
 'Interference Example 4- Diffraction Limited Imaging.SES',
 'Interference Example 4- Diffraction Limited Imaging.ZDA',
 'Interference Example 4- Diffraction Limited Imaging.ZMX',
 'sample.DDR']

Please let me know if you could resolve your problem. I will close the issue after that. Thank you, and sorry for keeping you waiting.

indranilsinharoy commented 7 years ago

Also, the answer to your second question (I get the code 0 (successful) when I give the filename as just 'sample.ddr'. However it is still not in the Lens file folder.) is that Zemax seems to save the file in the current working directory where the Python interpreter is running. Although, I haven't tested all possibilities, in my case, I had launched Jupyter QtConsole from C:\Users\Indranil\Documents (checked using pwd in QtConsole), and Zemax saved the file---using the name Zemaxsample.DDR---in that directory.

shbhuk commented 7 years ago

Hi, As far as saving it as*.ddrfile is concerned, you are right about it being related to the location string. Generally since I need to interface with Linux often I try to use single forward slashes. I get this error when I use I them. I do get the error for single back-slashes as well.

I get the 0 output (ddr file) when I use double backslash, or use os.path.joinas you have mentioned in your example.

shbhuk commented 7 years ago

Now that I can obtain a DDR file, is it possible to obtain a detector specific text file? As mentioned above , when I use - zGetDetectorViewer I get a text file from the first detector in the object list (by default), is there any way to change that. If not, I guess I could insert a temporary detector as the first object (perhaps) and insert the sample ddr file and then save it as a text file (for further analysis). Let me know if there is a simpler method.

The last query that I have is -zGetDetectorViewer does save it as a txt file, however gives an -

AttributeError: 'NoneType' object has no attribute 'group'.

Thus none of the parameters are returned, ie. dvwInfo.

The full traceback for the error is -

zobj.ln.zGetDetectorViewer(txtFile=location+'Sample.txt')

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-22-d98f40e2f16a> in <module>()
----> 1 zobj.ln.zGetDetectorViewer(txtFile=location+'Sample.txt')

c:\users\shbhu\appdata\local\enthought\canopy\user\lib\site-packages\pyzdde-2.0.3-py2.7.egg\pyzdde\zdde.pyc in zGetDetectorViewer(self, settingsFile, displayData, txtFile, keepFile, timeout)
   9395 
   9396         pyz = _sys.modules[__name__]
-> 9397         ret = _zfu.readDetectorViewerTextFile(pyz, textFileName, displayData)
   9398 
   9399         if not keepFile:

c:\users\shbhu\appdata\local\enthought\canopy\user\lib\site-packages\pyzdde-2.0.3-py2.7.egg\pyzdde\zfileutils.pyc in readDetectorViewerTextFile(pyz, textFileName, displayData)
    668     if peakIrrLineNum:
    669         peakIrr = float(pyz._re.search(r'\d{1,4}\.\d{3,8}[Ee][-\+]\d{3}', 
--> 670                                        line_list[peakIrrLineNum]).group())
    671         totPow = float(pyz._re.search(r'\d{1,4}\.\d{3,8}[Ee][-\+]\d{3}', 
    672                                       line_list[peakIrrLineNum + 1]).group())

AttributeError: 'NoneType' object has no attribute 'group' 

P.S.: This time the location is with two double backslashes. I am not sure why is peakIrrLineNum empty.

indranilsinharoy commented 7 years ago

@shbhuk

I get a text file from the first detector in the object list (by default), is there any way to change that.

Use the function zSetDetectorViewerSettings() or zModifyDetectorViewerSettings() to change the detector number, and other relevant parameters.

I think that setting the parameters using zSetDetectorViewerSettings() should also solve your other problem. Here is what I did in my local machine, and I can see both the text file output and an image:

In [1]: import os
In [2]: ln = pyz.createLink(1)
In [4]: zmxfile = ln.zGetFile()
In [5]: ln.zNSCTrace(surfNum=1, srcNum=0, split=1, usePolar=1)
Out[5]: 0
...
In [10]: cfgfile = ln.zSetDetectorViewerSettings(settingsFile=None, surfNum=1, detectNum=9, showAs=0, smooth=1, dType=1)
...
In [12]: # txtfilename = os.path.join(os.path.split(zmxfile)[0], 'sample.txt')
...
In [16]: txtfile = 'C:\\Users\\indranil\\sample.txt'
...
In [22]: dvwInfo, dvwData = ln.zGetDetectorViewer(settingsFile=cfgfile, displayData=True, txtFile=txtfile, keepFile=True)
In [23]: dvwInfo
Out[23]: dvwInfo(surfNum=1, detNum=9, width=5.0, height=5.0, xPix=500, yPix=500, totHits=300000, peakIrr=9.082, totPow=0.40687, smooth=1, dType='Coherent Irradiance', x=0.0, y=23.25, z=96.5, tiltX=0.0, tiltY=0.0, tiltZ=0.0, posUnits='Millimeters', units='Watts/cm^2', rowOrCol=None, rowColNum=None, rowColVal=None)
In [24]: plt.imshow(dvwData)
Out[24]: <matplotlib.image.AxesImage at 0x1a1064d9198>
In [25]: plt.show()

Along with the image, the text file was also available in the right place.

Note that in In [16]: I used a text file location where you don't need any special privilege to write. If you get an error like AssertionError: zGetTextFile returned -1, it most likely is because Zemax / PyZDDE was unable to dump the text file in the desired directory. For example, in my case, the line In [12]: didn't quite work.

Hope that helps. Regards, Indranil.

shbhuk commented 7 years ago

Hey thanks for the SetDetectorViewerSettings bit. However this problem still persists. I believe the pyz._getFirstLineOfInterest(line_list, 'Peak\sIrradiance') is returning a None value which is basically causing this error.

Do you know in which cases does it do so? The source code (zdde.py line 12202) says that if does not find a matching pattern it returns None

indranilsinharoy commented 7 years ago

I think that there is a mismatch between what data type you are asking Zemax to compute/dump to the text file and what the zGetDetectorViewer() expects. Can you make sure that you are using the correct dType setting in zSetDetectorViewerSettings() function? Also, check in the text file dumped by the function and see if a line starting with "Peak Irradiance" is present or not. It is possible that there could be a bug. Can you please reproduce your problem with the Zemax supplied sample file Interference Example 2- A Mach-Zehnder Interferometer.ZMX and send me your code? (I'm reopening the issue for now).

shbhuk commented 7 years ago

Hi, So I am now using the sample file you mentioned above. The code is as follows -

import os
import pyzdde.zdde as pyz

ln = pyz.createLink()
ln.zGetRefresh()
zmxfile = os.path.split(ln.zGetFile())[1]
ln.zNSCTrace(surfNum=1, srcNum=0, split=1, usePolar=1)

cfgfile = ln.zSetDetectorViewerSettings(settingsFile=None, surfNum=1, detectNum=9, showAs=0, smooth=1, dType=1)
filename = os.path.join(os.path.split(zmxfile)[0], 'sample.DDR')
txtfile="C:\\Users\\shbhu\\Box Sync\\Seq to NS\\Zeroref_global\\sample.txt"
dvwInfo, dvwData = ln.zGetDetectorViewer(settingsFile=cfgfile, displayData=True, txtFile=txtfile, keepFile=True)

Here I tried dType 0 and 1 and they give the same AttributeError as mentioned above. However dType = 2 (coherent phase) does not give an error.'

indranilsinharoy commented 7 years ago

The example I provided above uses dType = 1 :

In [10]: cfgfile = ln.zSetDetectorViewerSettings(settingsFile=None, surfNum=1, \
detectNum=9, showAs=0, smooth=1, dType=1)

and I didn't get the AttributeError.

Can you open the text file outputted by the function (with dType=1), and see if "Peak Irradiance" is present or not? It should be about the 12th line (counting blank lines).

shbhuk commented 7 years ago

It is present -

Detector Viewer Listing

File : C:\Users\shbhu\Documents\Zemax\Samples\Non-sequential\Coherence Interference and Diffraction\Interference Example 2- A Mach-Zehnder Interferometer.ZMX
Title: Mach Zender Interferometer
Date : 15-May-17

Detector 9, NSCG Surface 1: camera
Size 5.000 W X 5.000 H Millimeters, Pixels 500 W X 500 H, Total Hits = 600000

Peak Irradiance : 8.8431E+00 Watts/cm^2
Total Power     : 8.1375E-01 Watts

Smoothing       : 1
Data Type       : Incoherent Irradiance
Detector X      : 0.0000
Detector Y      : 23.2500
Detector Z      : 96.5000
Detector Tilt X : 0.0000
Detector Tilt Y : 0.0000
Detector Tilt Z : 0.0000
Position Units  : Millimeters
Units           : Watts/cm^2
shbhuk commented 7 years ago

I apologize, the one posted above was Incoherent. For Coherent (dtype=1) it is -

Detector Viewer Listing

File : C:\Users\shbhu\Documents\Zemax\Samples\Non-sequential\Coherence Interference and Diffraction\Interference Example 2- A Mach-Zehnder Interferometer.ZMX
Title: Mach Zender Interferometer
Date : 15-May-17

Detector 9, NSCG Surface 1: camera
Size 5.000 W X 5.000 H Millimeters, Pixels 500 W X 500 H, Total Hits = 600000

Peak Irradiance : 1.8164E+01 Watts/cm^2
Total Power     : 8.1375E-01 Watts

Smoothing       : 1
Data Type       : Coherent Irradiance
Detector X      : 0.0000
Detector Y      : 23.2500
Detector Z      : 96.5000
Detector Tilt X : 0.0000
Detector Tilt Y : 0.0000
Detector Tilt Z : 0.0000
Position Units  : Millimeters
Units           : Watts/cm^2
indranilsinharoy commented 7 years ago

Ok, then there could a problem with the text encoding (unicode or ascii). Ensure that the text encoding set in Zemax preferences and PyZDDE are the same. Use pyz.getTextEncoding() and/or pyz.setTextEncoding()

See my comments here: https://github.com/indranilsinharoy/PyZDDE/issues/66

shbhuk commented 7 years ago

Hi, Both the text encoding formats are set to 'unicode' - Zemax and PyZDDE.

The other suggestions do not work either, i.e. shorter path name or cfg file change

shbhuk commented 7 years ago

I think its alright if you are busy with other stuff. For now I have implemented a work around the AttributeError using -

        try:
            self.ln.zGetDetectorViewer(displayData=True,txtFile=txtfile,keepFile=True,timeout=600)              
        except Exception,error:
            if os.path.isfile(txtfile)==False:
                raise
indranilsinharoy commented 7 years ago

@shbhuk , I'm not sure what's going on exactly. It seems to be working as expected in my tests (as I have shown above)!

shbhuk commented 6 years ago

Hi, This error seems to be recurring.

When I run

    try:
        self.ln.zGetDetectorViewer(displayData=True,settingsFile=settingsFile,txtFile=txtfile,keepFile=True,timeout=600)              
    except(Exception):
        if os.path.isfile(txtfile)==False:
            raise

FileNotFoundError: [Errno 2] No such file or directory: 'C:/Users/shbhu/CCB_file_check/Spot_1_waveno_1.txt' 

Seemed to work fine earlier. Recently switched from Python 2.7 to 3.5 That is the only switch. Any clues?

shbhuk commented 6 years ago

Or else, if you could just propose a method to download the .txt file from the detector which has the intensity values per pixel.