ZEMAX | 編程語言 (ZPL) 簡介
用戶可以使用Zemax編程語言 (Zemax Programming Language,ZPL)?在OpticStudio中編寫自己的程序。這些程序可以實現(xiàn):
自動重復鍵盤和鼠標的操作
基于OpticStudio的數(shù)據(jù)進行計算
以特定格式輸出數(shù)據(jù)
以圖表或表格的形式生成數(shù)據(jù)
以及很多其它的功能!
創(chuàng)建ZPL宏程序非常簡單。本文概述了ZPL的主要功能、變量示例,描述了ZPL中重要的函數(shù)和關(guān)鍵詞。
作者 Dan Hill, updated by Alessandra Croce
簡介
ZPL是不區(qū)分大小寫的“宏”或“腳本”語言,并且是擴展OpticStudio計算范圍的最簡單方法。它是根據(jù)BASIC建模的,并且是一種解釋型語言。這意味著編寫ZPL宏非常容易,但是這也意味著進行復雜計算時,其執(zhí)行速度要比完全編譯的代碼慢。
ZPL腳本可以調(diào)用OpticStudio中已編譯的函數(shù)(關(guān)鍵字和操作數(shù)),并且在以下情況下很實用:
當您需要特殊格式的數(shù)據(jù)
實現(xiàn)不在程序中的功能或計算,例如數(shù)據(jù)提取,導出或簡單繪圖
在沒有適當?shù)牟僮鲾?shù)時進行優(yōu)化(創(chuàng)建自定義操作數(shù))
創(chuàng)建自定義/復雜求解(創(chuàng)建自定義求解)
自動重復鍵盤的操作
請注意,ZPL不能用于編輯用戶自定義表面或物體,若有需要,您可以使用DLL。
ZPL包含五個基本概念:變量 (variables)、運算符 (operations)、函數(shù) (functions)、關(guān)鍵詞 (keywords)?和注釋?(comments)。以下將對這些概念進行介紹,可以在OpticStudio幫助手冊的“編程?(?Programming)?選項卡>?關(guān)于ZPL(About the ZPL)?”部分查閱更多信息。
ZPL的目標是為沒有太多編程經(jīng)驗的光學工程師提供強大的編程工具,該工具可以快速執(zhí)行,并且易于學習。OpticStudio還支持ZOS-API,這是API級別的接口,外部程序(例如Matlab或Python)可以通過ZOS-API訪問OpticStudio的功能。想要了解更多信息,請查看文章?" 什么是 ZOS-API ,作用是什么?"?。
賦值、變量和數(shù)組
基本的賦值語法為:
variable = expression
其中 “ = ” 意為“將值設(shè)為”。
變量可以是數(shù)值 (numeric)?或字符串 (string),這取決于它們所包含的數(shù)據(jù)類型。表達式可以是確切值、其它變量或復雜的數(shù)學表達式/函數(shù)。只有數(shù)組變量需要在使用前聲明,因此例如?x = 7
?無需提前聲明數(shù)字變量?x
即可工作。如下有效賦值的示例:
x = 4
y = 3
z = x + y
字符串變量名稱中的最后一個字符必須帶有 $ 字符:
newstring$ = "Here is the new string"
變量始終保持為雙精度64位值。它們的名稱有一些必須遵守的限制。變量名稱不應(yīng):
超過28個字符
包含用作運算符的任何特殊字符 (*, !, <, &, 等)
包含任何空格 (改為使用 “ _ ”)
與關(guān)鍵字或函數(shù)相同
數(shù)組
ZPL還支持數(shù)組(或向量)變量,有4個預定義的向量,分別稱為VEC1, VEC2, VEC3,
和VEC4
, 主要由其他命令(例如GETPSF
,?GETMTF
, 等)使用,它們的大小由SETVECSIZE?
關(guān)鍵字設(shè)置。
用戶自定義數(shù)組變量必須在使用前用DECLARE?
關(guān)鍵字聲明。它們最多可以由4維構(gòu)成,并可以為雙精度或整數(shù)數(shù)據(jù)類型。必須使用RELEASE?
關(guān)鍵字釋放分配給數(shù)組的內(nèi)存。
可以使用以下語法給用戶自定義數(shù)組賦值:
arrayname(index1, index2, …) = value
可以使用以下語法提取值:
value = arrayname(index1, index2, …)
關(guān)鍵字和函數(shù)
ZPL中的命令分為兩類:
使用關(guān)鍵字可以在 OpticStudio 中執(zhí)行或更改某些內(nèi)容,例如:
RAYTRACE?
通過系統(tǒng)追跡特定的光線SETUNITS?
設(shè)置系統(tǒng)單位PRINT?
打印一些內(nèi)容到屏幕或文件使用函數(shù)可以在 OpticStudio 中報告某些內(nèi)容,例如:
y_height = RAYY(5)
, 報告表面5上的光線截距的Y坐標lens_units$ = $UNITS()
, 報告系統(tǒng)的鏡頭單位
本文將給出關(guān)鍵字和函數(shù)的一些示例,這些示例涵蓋了OpticStudio中可用的整個光線追跡和物理光學計算范圍。請參閱OpticStudio幫助文件,以查看所有支持的函數(shù),關(guān)鍵字和常規(guī)ZPL功能。
關(guān)鍵字
關(guān)鍵字和函數(shù)是對OpticStudio中已編譯例程的調(diào)用,通常與功能區(qū)?(?Ribbon Bar?)?中相關(guān)功能的工作原理非常相似。
RAYTRACE?
=>

LOADARCHIVE?
=>

?它們的執(zhí)行速度與內(nèi)部命令一樣快,而調(diào)用命令的消耗卻很小。因此,不要認為ZPL太“慢”!但是請記住,宏中的顯式計算將被解釋執(zhí)行,因此與已編譯的程序相比速度較慢。如果宏內(nèi)部的計算速度很重要,請改用 ZOS-API.NET 。
關(guān)鍵字可以指導程序流程(IF或FOR語句),或運行光線追跡或調(diào)整透鏡參數(shù)等。例如,使OpticStudio將系統(tǒng)優(yōu)化10圈,可以發(fā)送以下命令:
OPTIMIZE 10
同樣,執(zhí)行此代碼與您按下“優(yōu)化(?Optimize?)”按鈕并在圖形用戶界面中選擇“?10圈(?10 Cycles?)”完全相同。
關(guān)鍵字和操作數(shù)
在Zemax早期,編寫了諸如GETMTF?
和GETZERNIKE?
之類的關(guān)鍵字以訪問相應(yīng)的分析功能。但是,隨著代碼庫的增加,這很快變得很單調(diào)。因此,通過其關(guān)聯(lián)的優(yōu)化操作數(shù)可以訪問大多數(shù)分析功能。這可以通過評價函數(shù)執(zhí)行,也可以直接使用?OPEV()?
or或?OPEW()
數(shù)值函數(shù)從宏中調(diào)用操作數(shù)本身來執(zhí)行。有關(guān)更多詳細信息,請參見?"如何使用 OPEV 和 OPEW 獲取ZPL宏中任意優(yōu)化操作數(shù)的值"?。
函數(shù)
如前所述,函數(shù)與關(guān)鍵字不同,因為它們不執(zhí)行或更改文件中的任何內(nèi)容,而是使OpticStudio生成有關(guān)某些內(nèi)容的報告。ZPL支持多種函數(shù),包括數(shù)值和字符串。數(shù)值函數(shù)的示例是:
x?=?SQRT(y)y?=?ABSO(z*TANG(e*numpoints))pi?=?4*ATAN(1)
相反,字符串函數(shù)以 $ 符號開頭,例如:
$DATE()$LENSNAME()surf3_glass$?=?$GLASS(3)
與關(guān)鍵字不同,函數(shù)只能在賦值的右側(cè),或者在作為關(guān)鍵字參數(shù)的表達式中使用。某些函數(shù)(例如PWAV()(報告系統(tǒng)的主波長))返回的值與參數(shù)無關(guān),因此不需要提供該值。但是,仍然需要括號。
運算和邏輯運算符
ZPL支持基本的數(shù)值運算(加法,減法,除法,乘法)和字符串運算(加法)。兩種運算的示例如下:
Z = (X + 1)/(Y * 6)
R$ = "Hello " + "World"
將字符串"Hello World"
賦給變量R$
其他數(shù)值和字符串函數(shù),例如SINE(), SQRT(), $GETSTRING()
, 等,可用于更復雜的運算??梢允褂美ㄌ杹碜远x運算序列,否則默認運算序列為:函數(shù)(例如SQRT()
), 邏輯運算符(例如>
), 乘法和除法,加法和減法。
ZPL還支持邏輯運算符,包括數(shù)值和字符串。這些可用于邏輯測試以及對多個表達式的比較。邏輯運算的結(jié)果為“真(TRUE)”(任何非零值)或“假(FALSE)”(零)。OpticStudio將零視為“假”,將任何非零值視為“真”。
數(shù)值邏輯運算符表格如下:
& (AND)> (GREATER THAN)| (OR)< (LESS THAN)^ (XOR)> = (GREATER or EQUAL)! (NOT)< = (LESS or EQUAL)= = (EQUAL)! = (NOT EQUAL)
數(shù)值邏輯運算符的示例如下:
IF(A > 5) THEN PRINT "A is greater than 5"
字符串邏輯運算符的表格如下:
$ = = (EQUAL)$ > = (GREATER or EQUAL)$ > (GREATER THAN)$ < = (LESS or EQUAL)$ < (LESS THAN)$ ! = (NOT EQUAL)
字符串邏輯運算符示例如下:
IF (C$ $== B$) THEN PRINT "Strings are identical"
賦值與邏輯運算符
錯誤使用運算符 “=
” 和邏輯運算符 “= =
?”很常見。
例如,下圖中的宏:

在此宏中,“a = b
”是賦值,讀取為“將變量a的值設(shè)置為等于變量b的值”。由于操作成功,所以O(shè)pticStudio將a的值設(shè)置為等于b,并返回“真”。因此,宏可寫為:
IF (TRUE)
PRINT "a equals b"
ELSE
PRINT "a does not equal b"
ENDIF
在這種情況下,OpticStudio會發(fā)現(xiàn)錯誤并返回:
Syntax error: Illegal assignment (a = b).
可以使用邏輯運算“a == b
”來進行正確的操作。
IF 與 FOR 條件循環(huán)
ZPL可以進行IF與FOR的條件循環(huán)。
IF循環(huán)的語法如下:
IF (expression)
(commands)
ELSE
(commands)
ENDIF
或
IF (expression) THEN (single command)
IF循環(huán)通常與邏輯運算符一起用作表達式語句中的測試條件。例如:
IF (X < Y)
PRINT "X is less than Y"
ELSE
PRINT "X is greater than Y"
ENDIF
請注意,有一些要留給用戶來發(fā)現(xiàn)的錯誤,例如,如果x = y會怎樣?
FOR循環(huán)的語法如下:
FOR variable, start_value, stop_value, increment
(commands)
NEXT
例如:
FOR i, 1, 10, 1
PRINT i
NEXT
同時定義變量和起始值的以下語法也是有效的:
FOR i = 1, 10, 1
請注意,start_value和stop_value可以是顯式數(shù)字,也可以是任何計算結(jié)果為數(shù)字的變量或表達式。增量應(yīng)該是整數(shù),或者是任何取值為整數(shù)的變量或表達式。
調(diào)用宏和子例程
關(guān)鍵字?CALLMACRO?
可以用一個宏(父級)調(diào)用另一個宏(子級)。數(shù)字和字符串緩沖區(qū)可以在父宏和子宏之間共享數(shù)據(jù)。示例宏“ Parent.ZPL”和“ Child.ZPL”都包含在OpticStudio安裝文件中,并在幫助文件的“編程?(?Programming?)?選項卡>關(guān)于ZPL?(?About the ZPL?)?>從宏中調(diào)用宏?(?Calling a Macro from within a Macro?)”部分進行了描述。
關(guān)鍵字GOSUB
可以執(zhí)行跳轉(zhuǎn)到SUB
指示的子例程。子例程完成執(zhí)行后,控制其值返回到GOSUB
關(guān)鍵字之后的行。在整個宏中,可以多次調(diào)用子例程。請注意,它們是在同一個宏中定義的,與前述的分離的父/子宏的情況不同。有關(guān)子例程的更多信息,請參見OpticStudio幫助文件的“編程(?Programming?)選項卡>關(guān)于ZPL(?About the ZPL?)?>關(guān)鍵字(?KEYWORDS?)?> GOSUB,SUB,RETURN和END”部分。
RAYTRACE, RAYTRACEX 和相關(guān)功能
對于要在序列模式下使用的宏,最重要的關(guān)鍵字之一是RAYTRACE
,它追跡給定波長的單條光線(由歸一化視場和光瞳坐標確定)。關(guān)鍵字沒有其他作用,語法為:
RAYTRACE hx, hy, px, py, wave
例如:
RAYTRACE 0, 1, 0, 0, PWAV()
,在主波長處追跡主光線。
然后,您可以使用后續(xù)函數(shù)提取任何相關(guān)的光線追跡數(shù)據(jù),例如:
RAYX(x), RAYY(x),
和?RAYZ(x)
,返回表面 x 上的光線的X-,Y-和Z-坐標RAYL(x), RAYM(x),
和?RAYN(x)
,返回表面x上的光線的方向余弦值RANX(x), RANY(x),
和?RANZ(x)
,返回光線擊中表面x處的表面法線余弦值RAYT(x)
返回光線到表面 x 的光路長度OPDC()
?返回光線相對于主光線的光程差
例如,以下代碼追跡波長2的邊緣光線。然后將像面上光線的Y坐標截距提取并打印在屏幕上:
RAYTRACE 0, 0, 0, 1, 2
PRINT "The chief ray height is ", RAYY(NSUR())
函數(shù)RAYE()
報告追跡光線時可能發(fā)生的任何錯誤:
如果在光線追跡過程中未發(fā)生任何錯誤,則返回零。
負值表示在該表面上發(fā)生了全內(nèi)反射,該表面序號數(shù)是返回值的絕對值
正值表示光線錯過了返回的表面編號
檢查RAYE()
是可選操作,但是,如果RAYE()
不返回零,則上述數(shù)據(jù)提取函數(shù)可能會返回無效數(shù)據(jù)。
函數(shù)RAYV()
可用于檢查光線是否存在漸暈,即是否被孔徑擋住了。該函數(shù)返回光線存在漸暈的表面編號;如果光線未發(fā)生漸暈,則返回零。請記住,如果光線照射到孔徑上,仍會被追跡,并且可以通過使用RAYV()
測試是否發(fā)生漸暈來將其排除在計算之外。
RAYTRACEX
關(guān)鍵字是RAYTRACE
的實用擴展。它調(diào)用OpticStudio光線追跡例程,從任意表面起始追跡當前系統(tǒng)中特定的光線。語法為:
RAYTRACEX x, y, z, l, m, n, surf, wave
如上所述,然后可以使用與RAYTRACE
相同的后續(xù)功能提取有關(guān)光線追跡的數(shù)據(jù)。
ZPL 中的注釋
最后,您可以使用注釋來標注ZPL宏是如何工作的。任何以“!”為起始的行,或任何“#”后輸入的字符都將作為注釋,這些內(nèi)容在執(zhí)行ZPL宏時被忽略。OpticStudio將僅執(zhí)行將這些組件包在一起的腳本。
例如,想像您需要優(yōu)化鏡頭,計算評價函數(shù)值,并將該值乘以5的對數(shù),相應(yīng)的ZPL如下所示:

執(zhí)行ZPL宏的速度非???,并且ZPL是非常容易學習和使用的語言。為了幫助您入門,知識庫中有一些介紹Zemax編程語言某些功能的文章,并且OpticStudio下載文件中提供了許多示例。