本帖最后由 tinyheaven 于 2018-5-12 16:31 编辑
目的:提供一个范例。通过MATLAB,使用ZOS-API执行特定操作。
注:在
Python中的类似范例,可以点击http://customers.zemax.com/os/resources/learn/knowledgebase/zosapi-using-python
原链接:http://customers.zemax.com/os/resources/learn/knowledgebase/zosapi-using-matlab?lang=en-US
内容:
1.单光线序列追迹
2.创建NSC(非序列模式)并插入物体
3.在序列模式中改变变量
4.在序列模式中求解
5.插入操作数(索引到10个小数点)
6.使用Filter String(过滤器字符串),运行NSC(非序列模式)追迹
7.从一个ZRD文档中读取数据
8.批量光线(Batch Ray)序列追迹
作者:Michael Humphreys 发布时间:09/20/2016
应用:zemax,zemax-api.net,zemax编程
正文:有关ZOS-API的介绍,请在尝试运行这些代码之前,通过浏览以下资源以获取信息(必要的预备知识)。
Article: ZOS-API.NET: An Overview
Article: How to build and optimize a singlet using ZOS-API with Python
Article: How to create a User Analysis using ZOS-API
Webinar: Matlab & ZOS-API.NET
ZOS-API Matlab用户应该忽略一些内部函数:
AddChild
Equals
GetHashCode
RemoveChild
GetLifetimeService*
RunInternalCommand
ToString
CreateObjRef*
GetType
Disconnect*
InitializeLifetimeService*
标星号的方法会显示很多次,如果这些函数不被正确调用,可能会导致严重的运行问题。
1.序列光线追迹
下面代码将执行序列光线追迹,并将结果输出到output_file.txt。 目前,该API不支持详细的分析结果,因此结果对象将为空。
- % Single Ray Trace
- TheAnalyses = TheSystem.Analyses;
- newWin = TheAnalyses.New_Analysis(ZOSAPI.Analysis.AnalysisIDM.RayTrace);
- newWin_Settings = newWin.GetSettings();
- newWin_Settings.Hx = 0;
- newWin_Settings.Hy = 1;
- newWin_Settings.Px = 0;
- newWin_Settings.Py = 1;
- newWin_Settings.Wavelength.SetWavelengthNumber(2);
- newWin_Settings.Field.UseAllFields();
- newWin_Settings.Type = ZOSAPI.Analysis.Settings.Aberrations.RayTraceType.DirectionCosines;
- newWin.ApplyAndWaitForCompletion();
复制代码- % Get and Save the results
- newWin_Results = newWin.GetResults();
- newWin_Results.GetTextFile('c:\temp\output_file.txt');
复制代码
2.创建NSC(非序列模式)并插入物体
下面代码在Matlab中在非序列模式中创建一个新文件。 样板代码仅用.PrimarySystem,但通过使用此默认序列/非序列模式进行初始化,用户将无法修改正确的编辑器(不管模式是哪种,.LDE和.NCE仍然可用)。
- % Initializes new NSC system, inserts an object, changes an object type, and saves system
- % Initializes into NSC Mode
- TheSystem = TheApplication.CreateNewSystem(ZOSAPI.SystemType.NonSequential);
- TheApplication.ProgramDir
- % Creates new file
- TheSystem.New(false);
- % Non-sequential component editor & changing object
- TheNCE = TheSystem.NCE;
- Object_1 = TheNCE.InsertNewObjectAt(1);
- Object_2 = TheNCE.GetObjectAt(1);
- oType_1 = Object_1.GetObjectTypeSettings(ZOSAPI.Editors.NCE.ObjectType.StandardLens);
- Object_1.ChangeType(oType_1);
- % Saving System
- TheSystem.SaveAs('c:\temp\test_file.zmx');
复制代码
3.在序列模式中改变变量
下面的代码在Matlab中插入一个新的曲面,更改曲面类型,并分别将材质和参数1列设置为字符串变量和双变量。
- % Inserts new lens, changes surface type & changes parameter 1 value
- TheLDE.InsertNewSurfaceAt(1);
- Surface_1 = TheLDE.GetSurfaceAt(1);
- sT=Surface_1.GetSurfaceTypeSettings(ZOSAPI.Editors.LDE.SurfaceType.EvenAspheric);
- Surface_1.ChangeType(sT);
- colVal = Surface_1.GetSurfaceCell(ZOSAPI.Editors.LDE.SurfaceColumn.Material).Col;
- Surface_1.GetCellAt(colVal).Value = 'SF2';
- colVal = Surface_1.GetSurfaceCell(ZOSAPI.Editors.LDE.SurfaceColumn.Par1).Col;
- % can also use .IntegerValue for integers
- Surface_1.GetCellAt(colVal).DoubleValue = 0.1;
复制代码
4.在序列模式中求解
有些属性在Matlab中使用无效字符,被硬编码(hardcoded)到ZOS-API中,例如使用下划线开始属性名称。 例如,在单元格上设置F /#曲率求解记录为使用_S_FNumber作为属性,但这对于Matlab来说是无效的语法。 要列出给定对象的所有属性,只需在最后,不包含分号情况下,打印出对象,确定属性Matlab特定属性名称,并像通常使用ZOS-API文档一样使用它。
- % creates the LDE
- TheLDE = TheSystem.LDE;
- Surface_3 = TheLDE.InsertNewSurfaceAt(3);
- % lists the properties of the CreateSolveType method
- Solver = Surface_3.RadiusCell.CreateSolveType(ZOSAPI.Editors.SolveType.FNumber)
复制代码
完整的F数解决方案将如下所示:
- % creates the LDE
- TheLDE = TheSystem.LDE;
- Surface_3 = TheLDE.InsertNewSurfaceAt(3);
- % lists the properties of the CreateSolveType method
- Solver = Surface_3.RadiusCell.CreateSolveType(ZOSAPI.Editors.SolveType.FNumber);
- Solver.S_FNumber_.FNumber = 10;
- Surface_3.RadiusCell.SetSolveData(Solver);
复制代码
5.插入操作数(索引到10个小数点)
在LDE中对玻璃进行建模时,如果使用TheLDE.GetSurfaceAt(1).Material属性,LDE将始终为索引返回2个小数位,为阿贝数返回1个小数位。 为了看到更多小数位,必须使用Merit Function来获取值。
- % Set up primary optical system
- TheSystem = TheApplication.CreateNewSystem(ZOSAPI.SystemType.Sequential);
- surface = 1;
- % creates new file
- TheSystem.New(false);
- TheLDE = TheSystem.LDE;
- % sets surface 1 to N-BK7 and then changes this to a model material
- s1 = TheLDE.GetSurfaceAt(surface);
- s1.Material = 'N-BK7';
- s1.MaterialCell.CreateSolveType(ZOSAPI.Editors.SolveType.MaterialModel);
- % get value directly from LDE (only shows 2 sig figs)
- TheLDE = TheSystem.LDE;
- TheLDE.GetSurfaceAt(surface).Material
- % get value from merit function (shows double precision)
- TheMFE = TheSystem.MFE;
- mfo_1 = TheMFE.InsertNewOperandAt(1);
- mfo_1.ChangeType(ZOSAPI.Editors.MFE.MeritOperandType.INDX);
- mfo_1.GetCellAt(2).IntegerValue = surface; % surface
- mfo_1.GetCellAt(3).IntegerValue = 1; % wavelength
- % abbe number by using a boundary operand (independent of wavelength)
- mfo_2 = TheMFE.InsertNewOperandAt(2);
- mfo_2.ChangeType(ZOSAPI.Editors.MFE.MeritOperandType.MXAB);
- mfo_2.GetCellAt(2).IntegerValue = surface;
- mfo_2.GetCellAt(3).IntegerValue = surface;
- % updates the merit function and gets the values for index and abbe
- TheMFE.CalculateMeritFunction();
- index_1 = mfo_1.ValueCell.Value
- abbe_1 = mfo_2.ValueCell.Value
复制代码
6.使用Filter String(过滤器字符串),运行NSC(非序列模式)追迹
这允许用户设置非序列追迹,将过滤器字符串(Filter String)应用于ZRD文件,然后提取检测器( Detector Viewer)的文本结果。 您可以将property.Filter应用于NSCRayTrace或newDetector_settings属性。 此外,由于OpticStudio在镜头文件所在的当前目录中查找以保存和打开ray数据库,因此ZRD文件的文件位置必须是单独的。 请注意,ZOS-API尚不支持图像输出,因此如果您需要探测器的二维图,则需要在Matlab中重新创建。
- zrd_file = 'temp4.ZRD'; % this needs to be a RELATIVE path
- % Creat ray trace & modify settings
- NSCRayTrace = TheSystem.Tools.OpenNSCRayTrace();
- NSCRayTrace.SplitNSCRays = true;
- NSCRayTrace.ScatterNSCRays = false;
- NSCRayTrace.UsePolarization = true;
- NSCRayTrace.IgnoreErrors = true;
- NSCRayTrace.SaveRays = true;
- NSCRayTrace.Filter = 'H2';
- NSCRayTrace.SaveRaysFile = zrd_file;
- % Run ray trace
- NSCRayTrace.RunAndWaitForCompletion();
- NSCRayTrace.Close();
- % initializes Detector Viewer, saves the ZRD file & applies a Filter
- TheAnalyses = TheSystem.Analyses;
- newDetector = TheAnalyses.New_Analysis(ZOSAPI.Analysis.AnalysisIDM.DetectorViewer);
- newDetector_settings = newDetector.GetSettings();
- newDetector_settings.RayDatabaseFilename = zrd;
- newDetector.ApplyAndWaitForCompletion();
- % saves the Detector Viewer results
- newDetector_results = newDetector.GetResults();
- newDetector_results.GetTextFile('c:\temp\detector_viewer.txt');
复制代码
7.从一个ZRD文档中读取数据
这允许用户打开任何ZRD文件并提取您将以非序列模式从Ray Database Viewer中获取的相同信息。 请注意,Matlab不像编译代码那样快速读取像ZRD这样的大文件,所以Matlab比OpticStudio处理ZRD要花费更长的时间(以1-2个数量级)。 在编译的API代码中实现此解决方案(例如使用C#/ C ++语言)将会提高性能。
- % Set up primary optical system
- TheSystem = TheApplication.CreateNewSystem(ZOSAPI.SystemType.NonSequential);
- TheAnalyses = TheSystem.Analyses;
- % loads and runs ZRD ray database
- zrdFile = 'C:\Temp\nsc.ZRD';
- zrd = TheSystem.Tools.OpenRayDatabaseReader();
- zrd.ZRDFile = zrdFile;
- zrd.RunAndWaitForCompletion();
- zrd_results = zrd.GetResults();
- % reads data from ZRD file
- [success,ray_num,wave,wlum,segs] = zrd_results.ReadNextResult();
- while success > 0
- fprintf('Ray %i, Wave_Number %i, Wavelength %d, Segs %i, success %d \n',...
- ray_num,wave,wlum,segs, success);
- [success,segLevel,segPar,hitObj,HitFace,insideOf,rayStatus,x,y,z,l,m,n,...
- exr,exi,eyr,eyi,ezr,ezi,intensity,pathLength] = zrd_results.ReadNextSegment();
- while success > 0
- fprintf(' Segment: %+e, x: %+e, y: %+e, z: %+e, l: %+e, m: %+e, n: %+e \n',...
- segLevel,x,y,z,l,m,n);
- [success,segLevel,segPar,hitObj,HitFace,insideOf,rayStatus,x,y,z,l,m,n,...
- exr,exi,eyr,eyi,ezr,ezi,intensity,pathLength] = zrd_results.ReadNextSegment();
- end
- [success,ray_num,wave,wlum,segs] = zrd_results.ReadNextResult();
- end
复制代码
8.批量光线(Batch Ray)序列追迹
批量光线追迹允许用户通过系统将[Hx,Hy,Px,Py]定义的光线网格追踪到给定的平面。 可以从光线追踪中提取XYZ截距,LMN方向余弦,表面法向量,OPD和强度。 这些数据可以直接从API中提取,而无需将数据写入磁盘。 对于多个曲面,光线追迹应放置在FOR循环中。
- % Set up Batch Ray Trace
- raytrace = TheSystem.Tools.OpenBatchRayTrace();
- nsur = TheSystem.LDE.NumberOfSurfaces - 1;
- max_rays = 2; % number of rays to be traced minus 1 (will always trace hy=0 and hy=1)
- normUnPolData = raytrace.CreateNormUnpol(max_rays + 1,ZOSAPI.Tools.RayTrace.RaysType.Real,nsur);
- normUnPolData.ClearData();
- % Adding Rays to Batch, varying normalised object height hy
- waveNumber=2; hx = 0; px = 0; py = 0;
- hy_ary = [0:(1 / max_rays):1];
- for i = 1:max_rays+1
- normUnPolData.AddRay(waveNumber, hx, hy_ary(:,i), px, py, ...
- ZOSAPI.Tools.RayTrace.OPDMode.CurrentAndChief);
- end
- % Run Batch Ray Trace
- raytrace.RunAndWaitForCompletion();
- % Read and display results
- normUnPolData.StartReadingResults();
- fprintf('All results use hx=%4.2f, px=%4.2f, py=%4.2f\n', hx, px, py);
- for i= 1:max_rays+1
- [success, rayNumber, errCode, vigCode, x, y, z, l, m, n, l2, m2, n2,...
- opd, intensity] = normUnPolData.ReadNextResult();
- if success == 1
- fprintf('Ray Number %i, hy=%4.2f, Error Code %i, Vignette Code %i\n', ...
- rayNumber, hy_ary(:,i), errCode, vigCode);
- if errCode == 0
- fprintf(' x %5.2f, y %5.2f, z %5.2f, l %5.2f, m %5.2f, n %5.2f, ',...
- x, y, z, l, m, n);
- fprintf('l2 %5.2f, m2 %5.2f, n2 %5.2f, opd %5.2f, intensity %5.2f\n', ...
- l2, m2, n2, opd, intensity);
- end
- else
- fprintf('Ray trace for %i unsuccessful', i)
- end
- end
复制代码