-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMarcEchelle_exported.m
3036 lines (2574 loc) · 175 KB
/
MarcEchelle_exported.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
classdef MarcEchelle_exported < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
UIFigure matlab.ui.Figure
NumberofChannelsLabel matlab.ui.control.Label
NumberofChannelsSpinner matlab.ui.control.Spinner
ChannelPropsUITable matlab.ui.control.Table
CommonPropsUITable matlab.ui.control.Table
CommonPortPositionLabel matlab.ui.control.Label
DistinctPortsLabel matlab.ui.control.Label
ChannelNumberSpinnerLabel matlab.ui.control.Label
TSPChannel1 matlab.ui.control.Spinner
ChannelNumberSpinner_2Label matlab.ui.control.Label
TSPChannel2 matlab.ui.control.Spinner
TSPChannel1Label matlab.ui.control.Label
TSPChannel2Label matlab.ui.control.Label
ProgramTitleLabel matlab.ui.control.Label
ProgramSubTitle1Label matlab.ui.control.Label
MaterialChooserDropDownLabel matlab.ui.control.Label
MaterialChooserDropDown matlab.ui.control.DropDown
ITUChannelChooserButton matlab.ui.control.Button
Footnote1 matlab.ui.control.Label
GratingorderEditFieldLabel matlab.ui.control.Label
GratingorderEditField matlab.ui.control.NumericEditField
MinradiusmEditFieldLabel matlab.ui.control.Label
MinradiusmEditField matlab.ui.control.NumericEditField
MaxradiusmEditFieldLabel matlab.ui.control.Label
MaxradiusmEditField matlab.ui.control.NumericEditField
TSPradiusoffsetmEditFieldLabel matlab.ui.control.Label
TSPradiusoffsetmEditField matlab.ui.control.NumericEditField
GratingopeningangleLabel matlab.ui.control.Label
GratingopeningangleEditField matlab.ui.control.NumericEditField
CalculateButton matlab.ui.control.Button
ImageKIT matlab.ui.control.Image
Image matlab.ui.control.Image
ResultsPanel matlab.ui.container.Panel
toeasecalculationsasseenfromcommonportpositionLabel matlab.ui.control.Label
RealminradiusmEditFieldLabel matlab.ui.control.Label
RealminradiusmField matlab.ui.control.NumericEditField
RealmaxradiusmEditFieldLabel matlab.ui.control.Label
RealmaxradiusmField matlab.ui.control.NumericEditField
RealopeningangleEditFieldLabel matlab.ui.control.Label
RealopeningangleField matlab.ui.control.NumericEditField
GratingpointsfoundEditFieldLabel matlab.ui.control.Label
GratingpointsfoundField matlab.ui.control.NumericEditField
reducedLabel matlab.ui.control.Label
AreaReducedField matlab.ui.control.NumericEditField
fullLabel matlab.ui.control.Label
AreaFullField matlab.ui.control.NumericEditField
AreaoffreespaceareamLabel matlab.ui.control.Label
SiO2Label matlab.ui.control.Label
AreaSiO2Field matlab.ui.control.NumericEditField
PortSearchBoundingBoxUITable matlab.ui.control.Table
BoundingBoxforPortSearchLabel matlab.ui.control.Label
ShowEllipsesCheckBox matlab.ui.control.CheckBox
ShowCirclesCheckBox matlab.ui.control.CheckBox
ShowPortSearchIntersectionsCheckBox matlab.ui.control.CheckBox
ShowGratingAdditionsCheckBox matlab.ui.control.CheckBox
BragggratingdefinitionPanel matlab.ui.container.Panel
PeriodsEditFieldLabel matlab.ui.control.Label
PeriodsEditField matlab.ui.control.NumericEditField
PeriodlengthnmEditFieldLabel matlab.ui.control.Label
PeriodlengthEditField matlab.ui.control.NumericEditField
SiO2lengthnmEditFieldLabel matlab.ui.control.Label
SiO2lengthEditField matlab.ui.control.NumericEditField
BoundarydistancenmLabel matlab.ui.control.Label
BoundarydistanceEditField matlab.ui.control.NumericEditField
ReflectorspacingnmLabel matlab.ui.control.Label
ReflectorSpacingEditField matlab.ui.control.NumericEditField
PortlayoutdefinitionPanel matlab.ui.container.Panel
WaveguidewidthnmEditFieldLabel matlab.ui.control.Label
WaveguidewidthEditField matlab.ui.control.NumericEditField
TaperendwidthnmLabel matlab.ui.control.Label
TaperendwidthEditField matlab.ui.control.NumericEditField
TaperlengthnmLabel matlab.ui.control.Label
TaperlengthEditField matlab.ui.control.NumericEditField
WGstublengthnmLabel matlab.ui.control.Label
WaveguidestublengthEditField matlab.ui.control.NumericEditField
TapershiftnmLabel matlab.ui.control.Label
TapershiftEditField matlab.ui.control.NumericEditField
TrenchwidthnmLabel matlab.ui.control.Label
TrenchwidthEditField matlab.ui.control.NumericEditField
Trench2widthnmLabel matlab.ui.control.Label
Trench2widthEditField matlab.ui.control.NumericEditField
COMSOLModelButton matlab.ui.control.Button
GDS2LayoutButton matlab.ui.control.Button
COMSOLSimulationPanel matlab.ui.container.Panel
MinWavelengthnmLabel matlab.ui.control.Label
ComsolMinWavelengthEditField matlab.ui.control.NumericEditField
MaxWavelengthnmLabel matlab.ui.control.Label
ComsolMaxWavelengthEditField matlab.ui.control.NumericEditField
WavelengthstepnmLabel matlab.ui.control.Label
ComsolWavelengthStepEditField matlab.ui.control.NumericEditField
ComsolBorderButton matlab.ui.control.StateButton
ComsolSBendsButton matlab.ui.control.StateButton
FreespaceareaLabel matlab.ui.control.Label
NoofPartitionsEditFieldLabel matlab.ui.control.Label
NoOfPartitionsEditField matlab.ui.control.NumericEditField
GDSIIDefinitionsPanel matlab.ui.container.Panel
EchelleNameIDEditFieldLabel matlab.ui.control.Label
EchelleNameIDEditField matlab.ui.control.EditField
GDSdatabaseunitLabel matlab.ui.control.Label
GDS2DBUnitEditField matlab.ui.control.NumericEditField
GDSuserunitLabel matlab.ui.control.Label
GDS2UserUnitEditField matlab.ui.control.NumericEditField
SbendWaveguidesPanel matlab.ui.container.Panel
WaveguidelengthnmLabel matlab.ui.control.Label
WaveguideLengthEditField matlab.ui.control.NumericEditField
EndpointpitchnmLabel matlab.ui.control.Label
WaveguidePitchEditField matlab.ui.control.NumericEditField
CurvediscretizationLabel matlab.ui.control.Label
WGCurveDiscretizationEditField matlab.ui.control.NumericEditField
ProgramSubTitle2Label matlab.ui.control.Label
BevelingPanel matlab.ui.container.Panel
AttenuatorBevelnmLabel matlab.ui.control.Label
GDS2AttBevelEditField matlab.ui.control.NumericEditField
minAngleLabel matlab.ui.control.Label
GDS2AttBevelAngleEditField matlab.ui.control.NumericEditField
BevelnmLabel matlab.ui.control.Label
GDS2BevelEditField matlab.ui.control.NumericEditField
BlazeshiftmEditFieldLabel matlab.ui.control.Label
BlazeshiftmEditField matlab.ui.control.NumericEditField
ParallelComputingCheckBox matlab.ui.control.CheckBox
CladdingBlockModeCheckBox matlab.ui.control.CheckBox
BlockTrenchwidthnmLabel matlab.ui.control.Label
BlockModeTrenchwidthEditField matlab.ui.control.NumericEditField
end
properties (Access = private)
% Echelle Layout Program v2
% by Dr.-Ing. Marc Schneider (KIT)
% programming started at 2021-03-30
% parallelized channel search added 22.02.2022
% Block mode for increased cladding width added for GDS output 23.08.2022
% ReflectorSpacing added to avoid DRC errors 05.09.2022
%
% required toolboxes/add-ons/programs:
% - GDSII Toolbox v1.41 from Ulf Griesmann
% - Comsol
%
% prefered additional toolboxes:
% - Parallel Computing Toolbox (Matlab)
%
ProgramVersionString1='Echelle Layout Program 2'
ProgramVersionString2='by Dr.-Ing. Marc Schneider (KIT)'
ProgramVersionString3='v1.3 from 2022-09-05'
%convenience-'#defines'
PushFigureWindowToSpecificPosition=true;
% Table of effective refractive indices for different Si-thicknesses calculated by COMSOL with "E:\Dokumente\Simulationen\COMSOL\EffectiveRefractiveIndex\EffectiveRefractiveIndex_ModalAnalysis_li293.mph"
% Si thicknesses: 215-225nm + 245-255nm, SiO2 thickness bottom 2ľm, top 1ľm, data from COMSOL built in: Si: Li-293K, SiO2: Malitson
% EffectiveRefractiveIndicesFileName='E:\Dokumente\Simulationen\COMSOL\EffectiveRefractiveIndex\EffectiveRefractiveIndices_Wavelength1480-1630nm_SiliconThickness215-225nm+245-255nm.xlsx';
% EffectiveRefractiveIndicesFileName='D:\EigeneProgramme\Matlab\Test2\EffectiveRefractiveIndices_Wavelength1480-1630nm_SiliconThickness215-225nm+245-255nm.xlsx';
EffectiveRefractiveIndicesFileName='.\EffectiveRefractiveIndices_Wavelength1480-1630nm_SiliconThickness205-225nm+245-255nm.xlsx';
EffectiveRefractiveIndices % Table with the effective refractive indices and the wavelength in the first column
EffectiveRefractiveIndexDefault='SiThickness220nm'
EffectiveRefractiveIndex % Current matrix of wavelength in first column and effective refractive index of choosen material in second column
CommonProps % Table with properties of common port (X,Y-Position in ľm)
ChannelProps % Table with properties of the channels (Channel Number, X,Y-Position in ľm, Wavelength in nm, refractive index)
NoOfChannels % Number of distinct channels, excluding the common channel
TSPChannels % Channel numbers of the two initial focus points of the 'Two Stigmatic Points' method.
GratingOrder % Diffraction order of the Echelle grating
RadiusMin % Radius of large half axis of the smallest ellipse defining the grating points with the common port and the 1. stigmatic point as foci
RadiusMax % Maximum Radius of large half axis of the largest ellipse defining the grating points with the common port and the 1. stigmatic point as foci
RadiusOffset2TSP % Offset for the radius of the large half axis of the ellipse with the common port and the 2. stigmatic point as foci to shift the grating point trajectory
GratingOpeningAngle % Opening angle of the grating defining the maximum radius of the ellipses besids RadiusMax
BlazeShift % Offset to PortsCenterOfGravity to calculate blaze angle of grating in the direction of the connection between the common port and the center of gravity of the distinct ports
BlazeShiftXY % Absolute position offset for BlazeShift
PortSearchBoundingBox %Table with coordinates of bounding box in which the circle intersections for searching the position of non-TSP-ports are averaged; 1. column x-coordinates, 2. column y-coordinates
fastFigure % handle to additional figure window
fastFigureNumber % Number of that figure window
fastAxes % handle to axes in additional figure windows
fastFigurePosition % Position and size of figure window
ITUChannelChooserApp % Sub-App to choose and set ITU channels
ITUChannelChooserParameters % Parameters to ITUChannelChooserApp
DialogBoxApp % Dialog box app
DialogBoxParameters %Parameters to test dialog box window
EllipseIntersectionsSearchWedgeOpeningAngle=20; % Opening angle to search consecutive ellipse intersections
EllipseIntersections %Array of intersection points of the two stigmatic point ellipses with [AbsoluteX, AbsoluteY, RelativeR, RelativePhi], AbsoluteX and-Y are the positions of the intersection points, RelativeR and -Phi are the positions in polar coordinates, relative to the common port position
PortsCenterOfGravity %Average position of all ports, used to calculate reflector tilt angle [x, y]
GratingCenter %Center of grating, used to calculate tilt angle of ports [x, y]
GratingPointsReflectorDirections %angle in radians of each reflector on the grating, calculated with respect to port center of gravity
GratingPointsReflectorHalfAngles %angle in radians of line through each pair of neighboring grating points, calculated with respect to port center of gravity, defining the borders of the bragg gratings; first and last are outside the grating trajectory
PortDirections %angle in radians of each port, calculated with respect to grating center; common port is LAST port (app.PortDirections(app.NoOfChannels+1)) !!!
PortWGPositions %center point of wavveguide end of each port [x, y; x, y; ...]; common port is LAST port (app.PortDirections(app.NoOfChannels+1)) !!!
GratingTrajectoryReversed=0; % flag which indicates, if the grating trajectory goes from left to right (=0) or from right to left (=1)
BraggPeriods % number of periods of Bragg reflectors as reflecting elements of Echelle grating
BraggPeriodLength % length of one Bragg reflector period consisting of SiO2-part and Si-part
BraggSiO2Length % length of the SiO2-part of one Bragg reflector
BoundaryDistance % distance between bragg reflectors and Si-boundary, used for COMSOL model and layout (in layout also distance between boundary and ports)
% BraggReflectors % Cell array with all corner coordinates of all Bragg reflectors: rows: reflector (one for each grating point), columns: each period of the reflectors, cell: coordinates of the corners [x1 y1; x2 y2; x3 y3; x4 y4]
BraggReflectors % Cell array with all corner coordinates of all Bragg reflectors: rows: reflector (one for each grating point), columns: each period of the reflectors, cell: coordinates of the corners [x1 x2 x3 x4; y1 y2 y3 y4]
ReflectorSpacing % distance between two bragg reflectors to avoid sharp angles and small feature errors from design rule checks
TaperLength % length of taper for channel port
TaperWidth % width of taper end at free space end
TaperWGWidth % width of taper end at waveguide end
WaveguideStubLength % length of waveguide stub at the waveguide end of the taper with constant width
TaperShift % axial shift of tapers; negative values towards grating trajectory, positive values away from grating trajectory
TrenchWidth % width of SiO2 trench around the waveguide; the width is the additional width of the trench to one side, the resulting full width is 2*TrenchWidth+TaperWGWidth
Trench2Width % width of SiO2 trench around the waveguide at S-bend port end; the width is the additional width of the trench to one side, the resulting full width is 2*TrenchWidth+TaperWGWidth
% PortTapers % Cell array with all corner coordinates of all port waveguide tapers: rows: taper (common port is LAST port (app.PortDirections(app.NoOfChannels+1)) ), column: just one containing the taper, cell: coordinates of the corners [x1 y1; x2 y2; x3 y3; x4 y4]
PortTapers % Cell array with all corner coordinates of all port waveguide tapers: rows: taper (common port is LAST port (app.PortDirections(app.NoOfChannels+1)) ), column: just one containing the taper, cell: coordinates of the corners [x1 x2 x3 x4 x5 x6; y1 y2 y3 y4 y5 y6]
PortTrenches % Cell array with all corner coordinates of all port trenches: rows: trench(common port is LAST port (app.PortDirections(app.NoOfChannels+1)) ), column: just one containing the trench, cell: coordinates of the corners [x1 x2 x3 x4 x5 x6; y1 y2 y3 y4 y5 y6]
PortTrenchesCon % Array with boundary coordinates for cladding (Trenches) of port waveguides. Consolidated from port trenches. 1. row x-values, 2. row y-values
SiBoundary % Array with coordinates of SI boundary, used for COMSOL model (and layout); 1. row x-values, 2. row y-values
SiBoundaryGDS2 % Array with coordinates of SI boundary for GDS2 layout, used for COMSOL model (and layout); 1. row x-values, 2. row y-values
SiBoundaryGDS2T % Array with coordinates of SI boundary, merged with port tapers for GDS2 layout; 1. row x-values, 2. row y-values
%SiO2SlabEnhancement % Value in nanometers to shift the borders of the SiBoundaryGDS2 out for its cladding
SiO2BoundaryGDS2 % Array with coordinates of SiO2 boundary for GDS2 layout; 1. row x-values, 2. row y-values
AreaSiBoundary % Area of SiBoundary polygon in ľm˛
AreaSiBoundaryGDS2 % % Area of SiBoundaryGDS2 polygon in ľm˛
AreaSiO2BoundaryGDS2 % % Area of SiO2BoundaryGDS2 polygon in ľm˛
AttenuatorLeft % Array with coordinates of left attenuator boundary, used for GDSII layout; 1. row x-values, 2. row y-values
AttenuatorRight % Array with coordinates of right attenuator boundary, used for GDSII layout; 1. row x-values, 2. row y-values
EchelleID % Text: Name or ID of Echelle grating for GDS2 layout
GDSWaveguideLength % length of additional waveguide for GDSII layout to assemble all channels, also used for Comsol model if s-bends are activated
GDSWaveguidePitch % pitch of additional waveguides for GDSII layout to assemble all channels, also used for Comsol model if s-bends are activated
GDSWGCurveDiscretization % Number of linear sections to approximate the S-bends between port tapers and well-ordered connection points, also used for Comsol model if s-bends are activated
GDS2DBUnit % database unit of the GDS file (coordinate discretization); for 1e-9 all coordinates are snapped to a nm grid
GDS2UserUnit % user unit of the GDS file (unit for any coordinate descriptions); for 1e-6 all coordinates are in ľm
GDS2AttBevelAngle % minimum corner angle below which beveling for attenuators is done
GDS2AttBevel % side length of bevels for attenuators in nm
GDS2Bevel % side length of bevels for everything else in nm
ComsolMinWavelength % Minimum wavelength for COMSOL simulations, defines mesh size and sweep start
ComsolMaxWavelength % Maximum wavelength for COMSOL simulations, defines sweep end
ComsolWavelengthStep % Step size for COMSOL wavelength sweep
ComsolNoOfPartitions % The number of domains into which the free space area is divided for (much) faster meshing in Comsol
ComsolBorder % defines, which border should be used for Comsol model: 1: Full border as in GDS file, 0: reduced border (reduced width at waveguide ports)
ComsolSBends % defines, if S-Bend-waveguides are attached to the Comsol model or not
BlockModeTrenchwidth % Trench or cladding width if Block mode is active; special for processes, which need the cladding a certain amount larger than the core
end
methods (Access = private)
function NewTable = CreateChannelPropsTable(app,NoOfChannels)
NewTable=table([1:NoOfChannels]',zeros(NoOfChannels,1),zeros(NoOfChannels,1),ones(NoOfChannels,1)*1550,zeros(NoOfChannels,1));
NewTable.Properties.VariableNames={'ChannelNo','X','Y','Wavelength','ERI'};
NewTable.Properties.VariableDescriptions={'Channel No.','X (ľm)','Y (ľm)','Wavelength (nm)','Effective Refractive Index'};
end
function UpdateTableColoring(app)
addStyle(app.ChannelPropsUITable,uistyle('BackgroundColor',[1 1 1]));
addStyle(app.ChannelPropsUITable,uistyle('BackgroundColor',[0.8 1.0 0.8]),'cell',[app.TSPChannels(1), 1]);
addStyle(app.ChannelPropsUITable,uistyle('BackgroundColor',[0.8 1.0 1.0]),'cell',[app.TSPChannels(2), 1]);
if app.TSPChannels(1)==app.TSPChannels(2)
addStyle(app.ChannelPropsUITable,uistyle('BackgroundColor',[1.0 0.2 0.2]),'cell',[app.TSPChannels(1), 1]);
end
end
function ERIMatrix = UpdateERIMatrix(app,VariableName)
% build new matrix/array with wavelengths in first column and
% effective refractive index of currently choosen material
% system in second column
ERIMatrix=app.EffectiveRefractiveIndices{:,1};
ERIMatrix=[ERIMatrix, app.EffectiveRefractiveIndices.(VariableName)];
end
function ERI=CalculateEffectiveRefractiveIndex(app, CurrentWavelength)
% find indices from wavelengths in refractive index table adjacent to
% desired wavelength
x1 = find(app.EffectiveRefractiveIndex(:,1)<=CurrentWavelength,1,'last');
x2 = find(app.EffectiveRefractiveIndex(:,1)>CurrentWavelength,1,'first');
if isempty(x1)
x1=x2;
x2=x2+1;
uialert(app.UIFigure,sprintf('Wavelength of %d nm too small, refractive index extrapolated and highly inaccurate',CurrentWavelength),'DANGER!',"Icon","error","Modal",true);
end
if isempty(x2)
x2=x1;
x1=x1-1;
uialert(app.UIFigure,sprintf('Wavelength of %d nm too large, refractive index extrapolated and highly inaccurate',CurrentWavelength),'DANGER!',"Icon","error","Modal",true);
end
% get wavelengths to these indices
lambda1 = app.EffectiveRefractiveIndex(x1,1);
lambda2 = app.EffectiveRefractiveIndex(x2,1);
% get effective refractive indices to these wavelengths
n1 = app.EffectiveRefractiveIndex(x1,2);
n2 = app.EffectiveRefractiveIndex(x2,2);
% calculate the intermediate position of the desired wavelength
d=(CurrentWavelength-lambda1)/(lambda2-lambda1);
% linear interpolation of effective refractive index for the
% intermediate wavelength; as the graph for the effective
% refractive index is rather linear and the number of
% calculated points is high, linear interpolation is sufficient
ERI=n1+d*(n2-n1);
if isempty(ERI)
ERI=1;
end
end
function TheTable = UpdateChannelERI(app,TheTable)
% update the effective refractive index in the ChannelProps
% table
for (i=1:app.NoOfChannels)
TheTable.ERI(i)=CalculateEffectiveRefractiveIndex(app, TheTable.Wavelength(i));
end
end
function CalculateEllipseIntersections(app,myAxes)
firstpoint=true;
app.EllipseIntersections=[];
firstAngle=NaN;
MaxAngleReached=false;
i=0;
plot(myAxes,app.CommonProps.X(1),app.CommonProps.Y(1),"ro");
plot(myAxes,app.ChannelProps.X(app.TSPChannels(1)),app.ChannelProps.Y(app.TSPChannels(1)),"*","MarkerEdgeColor",[0 0.5 0]);
plot(myAxes,app.ChannelProps.X(app.TSPChannels(2)),app.ChannelProps.Y(app.TSPChannels(2)),"*","MarkerEdgeColor",[0 0.5 0]);
while (MaxAngleReached==false)
% for i=0:40
Radius1=app.RadiusMin+i*(app.ChannelProps.Wavelength(app.TSPChannels(1))/app.ChannelProps.ERI(app.TSPChannels(1))*app.GratingOrder/2*1e-3);
Radius2=app.RadiusMin+app.RadiusOffset2TSP+i*(app.ChannelProps.Wavelength(app.TSPChannels(2))/app.ChannelProps.ERI(app.TSPChannels(2))*app.GratingOrder/2*1e-3);
% DrawEllipse(app.UIAxes,app.CommonProps.X(1),app.CommonProps.Y(1),app.ChannelProps.X(app.TSPChannels(1)),app.ChannelProps.Y(app.TSPChannels(1)), app.RadiusMin+i*(app.ChannelProps.Wavelength(app.TSPChannels(1))/app.ChannelProps.ERI(app.TSPChannels(1))*app.GratingOrder*1e-3),120);
% DrawEllipse(app.UIAxes,app.CommonProps.X(1),app.CommonProps.Y(1),app.ChannelProps.X(app.TSPChannels(2)),app.ChannelProps.Y(app.TSPChannels(2)), app.RadiusMin+app.RadiusOffset2TSP+i*(app.ChannelProps.Wavelength(app.TSPChannels(2))/app.ChannelProps.ERI(app.TSPChannels(2))*app.GratingOrder*1e-3),120);
if app.ShowEllipsesCheckBox.Value==true
DrawEllipse(myAxes,app.CommonProps.X(1),app.CommonProps.Y(1),app.ChannelProps.X(app.TSPChannels(1)),app.ChannelProps.Y(app.TSPChannels(1)), Radius1,120, [ 0.75, 0.75, 0.75]);
DrawEllipse(myAxes,app.CommonProps.X(1),app.CommonProps.Y(1),app.ChannelProps.X(app.TSPChannels(2)),app.ChannelProps.Y(app.TSPChannels(2)), Radius2,120, [ 0.75, 0.75, 1.0]);
end
if ~firstpoint
% all subsequent intersetions must be within a 20°-wedge of the previous intersection
app.EllipseIntersections=[app.EllipseIntersections; EllipseIntersectionFinder2(myAxes, app.CommonProps.X(1),app.CommonProps.Y(1), app.ChannelProps.X(app.TSPChannels(1)),app.ChannelProps.Y(app.TSPChannels(1)), app.ChannelProps.X(app.TSPChannels(2)),app.ChannelProps.Y(app.TSPChannels(2)), Radius1, Radius2, app.EllipseIntersections(end, 4), 20, 'red')];
else
% First intersection must be in upper half and is the leftmost intersection, if there are more than one
app.EllipseIntersections=EllipseIntersectionFinder2(myAxes, app.CommonProps.X(1),app.CommonProps.Y(1), app.ChannelProps.X(app.TSPChannels(1)),app.ChannelProps.Y(app.TSPChannels(1)), app.ChannelProps.X(app.TSPChannels(2)),app.ChannelProps.Y(app.TSPChannels(2)), Radius1, Radius2, 90, 180, 'red');
firstAngle=app.EllipseIntersections(1,4);
if (isnan(firstAngle)==false)
firstpoint=false;
end
end
if (abs(firstAngle-app.EllipseIntersections(end,4))>=app.GratingOpeningAngle) || (Radius1>=app.RadiusMax) || (Radius2>=app.RadiusMax)
MaxAngleReached=true;
end
i=i+1;
end
%app.EllipseIntersections
%Strip NaN-values
%if the intersection list is not empty, look for and strip NaN values
if isempty(app.EllipseIntersections)==false
lastrow=0;
i=1;
while (i<=size(app.EllipseIntersections,1)) && (isnan(app.EllipseIntersections(i,4))==false)
lastrow=i;
i=i+1;
end
if lastrow==0 %List doesn't start with valid number; shouldn't occure, but...
app.EllipseIntersections=[];
else
app.EllipseIntersections=app.EllipseIntersections(1:lastrow,:); %cut out all intersection until the first NaN
end
end
%app.EllipseIntersections
end
function CalculateChannelPositions(app,myAxes)
app.TSPChannels(1);
app.TSPChannels(2);
app.NoOfChannels;
app.RadiusOffset2TSP;
d2 = uiprogressdlg(app.UIFigure,'Title','Calculating Channel Positions','Message','Channel No.');
d2.Value = 0;
%d2.Message = 'Calculating channel positions';
%calculate the radius offset for each single channel
RadiusOffset=zeros(app.NoOfChannels,1);
for i=1:app.NoOfChannels
RadiusOffset(i)=(app.RadiusOffset2TSP/(app.TSPChannels(2)-app.TSPChannels(1)))*(i-app.TSPChannels(1));
end
%RadiusOffset
%create array with the number channels colums and the number of grating points rows to store all radii for
%calculating the remaining ports
Radius=zeros( size(app.EllipseIntersections,1), app.NoOfChannels);
%Radius for each single channel is
for chan=1:app.NoOfChannels
if (chan~=app.TSPChannels(1))&&(chan~=app.TSPChannels(2))
for intersection=1:size(app.EllipseIntersections,1)
Radius(intersection,chan)=app.RadiusMin+RadiusOffset(chan)+ (intersection-1)*(app.ChannelProps.Wavelength(chan)/app.ChannelProps.ERI(chan)*app.GratingOrder/2*1e-3);
end
end
end
%Radius
%Calculate the remaining pathlengths from the intersection points to the respective ports now
Pathlength=zeros( size(app.EllipseIntersections,1), app.NoOfChannels);
for chan=1:app.NoOfChannels
if (chan~=app.TSPChannels(1))&&(chan~=app.TSPChannels(2))
for intersection=1:size(app.EllipseIntersections,1)
Pathlength(intersection,chan)=Radius(intersection,chan)*2-sqrt((app.EllipseIntersections(intersection,1)-app.CommonProps.X(1))^2+(app.EllipseIntersections(intersection,2)-app.CommonProps.Y(1))^2);
end
end
end
%Pathlength
if app.ShowCirclesCheckBox.Value==true
for chan=1:app.NoOfChannels
if (chan~=app.TSPChannels(1))&&(chan~=app.TSPChannels(2))
for intersection=1:size(app.EllipseIntersections,1)
app.plotcircle(myAxes, app.EllipseIntersections(intersection,1), app.EllipseIntersections(intersection,2), Pathlength(intersection,chan),'black');
end
end
end
end
plot(myAxes,[app.PortSearchBoundingBox.X(1) app.PortSearchBoundingBox.X(2) app.PortSearchBoundingBox.X(2) app.PortSearchBoundingBox.X(1) app.PortSearchBoundingBox.X(1)],[app.PortSearchBoundingBox.Y(1) app.PortSearchBoundingBox.Y(1) app.PortSearchBoundingBox.Y(2) app.PortSearchBoundingBox.Y(2) app.PortSearchBoundingBox.Y(1)],'Color',[0.5 , 0.5, 0.5],'LineStyle',':');
% fprintf('\nFinding channel positions...');
%find for each channel find the intersections of circles around grating points with radius in 'Pathlength'
for chan=1:app.NoOfChannels
% fprintf('\n%i',chan);
d2.Value = chan/app.NoOfChannels;
if (chan~=app.TSPChannels(1))&&(chan~=app.TSPChannels(2))
finalPortIntersection=[0, 0];
ValidIntersectionCounter=0;
for intersection1=1:(size(app.EllipseIntersections,1)-1)
% fprintf('.');
for intersection2=(intersection1+1):size(app.EllipseIntersections,1)
% fprintf('.');
CurrentIntersections=CircleIntersectionFinder(app.EllipseIntersections(intersection1,1), app.EllipseIntersections(intersection1,2), Pathlength(intersection1,chan), app.EllipseIntersections(intersection2,1), app.EllipseIntersections(intersection2,2), Pathlength(intersection2,chan));
if app.ShowPortSearchIntersectionsCheckBox.Value==true
plot(myAxes,CurrentIntersections(:,1),CurrentIntersections(:,2),"d","MarkerEdgeColor",[0 0.5 0]);
end
%Check, if and which of the IntersectionsAre inside the port search bounding box
if app.isInPortSearchBoundingBox(CurrentIntersections(1,1),CurrentIntersections(1,2))==true
finalPortIntersection=finalPortIntersection+CurrentIntersections(1,:);
ValidIntersectionCounter=ValidIntersectionCounter+1;
end
if app.isInPortSearchBoundingBox(CurrentIntersections(2,1),CurrentIntersections(2,2))==true
finalPortIntersection=finalPortIntersection+CurrentIntersections(2,:);
ValidIntersectionCounter=ValidIntersectionCounter+1;
end
end
end
if ValidIntersectionCounter>0
finalPortIntersection=finalPortIntersection/ValidIntersectionCounter;
%finalPortIntersection
plot(myAxes,finalPortIntersection(1),finalPortIntersection(2),'*',"MarkerEdgeColor",[1 0 0]);
app.ChannelProps.X(chan)=finalPortIntersection(1);
app.ChannelProps.Y(chan)=finalPortIntersection(2);
app.ChannelPropsUITable.Data=table2cell(app.ChannelProps(1:app.NoOfChannels,:));
else
uialert(app.UIFigure,sprintf('No valid port position found for channel no. %d',chan),'Warning!',"Icon","warning","Modal",true);
end
end
end
fprintf('\n');
close(d2);
% CircleIntersections
% circinter=CircleIntersectionFinder(app.EllipseIntersections(intersection1,1), app.EllipseIntersections(intersection1,2), Pathlength(intersection1,chan), app.EllipseIntersections(intersection2,1), app.EllipseIntersections(intersection2,2), Pathlength(intersection2,chan));
% plot(myAxes,circinter(:,1),circinter(:,2),"d","MarkerEdgeColor",[0 0.5 0]);
end
function CalculateChannelPositionsPar(app,myAxes)
app.TSPChannels(1);
app.TSPChannels(2);
app.NoOfChannels;
app.RadiusOffset2TSP;
d2 = uiprogressdlg(app.UIFigure,'Title','Calculating Channel Positions','Message','Channel No.');
d2.Value = 0;
%d2.Message = 'Calculating channel positions';
%calculate the radius offset for each single channel
RadiusOffset=zeros(app.NoOfChannels,1);
for i=1:app.NoOfChannels
RadiusOffset(i)=(app.RadiusOffset2TSP/(app.TSPChannels(2)-app.TSPChannels(1)))*(i-app.TSPChannels(1));
end
%RadiusOffset
%create array with the number channels colums and the number of grating points rows to store all radii for
%calculating the remaining ports
Radius=zeros( size(app.EllipseIntersections,1), app.NoOfChannels);
%Radius for each single channel is
for chan=1:app.NoOfChannels
if (chan~=app.TSPChannels(1))&&(chan~=app.TSPChannels(2))
for intersection=1:size(app.EllipseIntersections,1)
Radius(intersection,chan)=app.RadiusMin+RadiusOffset(chan)+ (intersection-1)*(app.ChannelProps.Wavelength(chan)/app.ChannelProps.ERI(chan)*app.GratingOrder/2*1e-3);
end
end
end
%Radius
%Calculate the remaining pathlengths from the intersection points to the respective ports now
Pathlength=zeros( size(app.EllipseIntersections,1), app.NoOfChannels);
for chan=1:app.NoOfChannels
if (chan~=app.TSPChannels(1))&&(chan~=app.TSPChannels(2))
for intersection=1:size(app.EllipseIntersections,1)
Pathlength(intersection,chan)=Radius(intersection,chan)*2-sqrt((app.EllipseIntersections(intersection,1)-app.CommonProps.X(1))^2+(app.EllipseIntersections(intersection,2)-app.CommonProps.Y(1))^2);
end
end
end
%Pathlength
if app.ShowCirclesCheckBox.Value==true
for chan=1:app.NoOfChannels
if (chan~=app.TSPChannels(1))&&(chan~=app.TSPChannels(2))
for intersection=1:size(app.EllipseIntersections,1)
app.plotcircle(myAxes, app.EllipseIntersections(intersection,1), app.EllipseIntersections(intersection,2), Pathlength(intersection,chan),'black');
end
end
end
end
plot(myAxes,[app.PortSearchBoundingBox.X(1) app.PortSearchBoundingBox.X(2) app.PortSearchBoundingBox.X(2) app.PortSearchBoundingBox.X(1) app.PortSearchBoundingBox.X(1)],[app.PortSearchBoundingBox.Y(1) app.PortSearchBoundingBox.Y(1) app.PortSearchBoundingBox.Y(2) app.PortSearchBoundingBox.Y(2) app.PortSearchBoundingBox.Y(1)],'Color',[0.5 , 0.5, 0.5],'LineStyle',':');
% fprintf('\nFinding channel positions...');
%find for each channel find the intersections of circles around grating points with radius in 'Pathlength'
for chan=1:app.NoOfChannels
% fprintf('\n%i',chan);
d2.Value = chan/app.NoOfChannels;
if (chan~=app.TSPChannels(1))&&(chan~=app.TSPChannels(2))
finalPortIntersection=[0, 0];
ValidIntersectionCounter=0;
% Vorbereitungen für parfor-Loop
appShowPortSearchIntersectionsCheckBoxValue=app.ShowPortSearchIntersectionsCheckBox.Value;
appEllipseIntersections=app.EllipseIntersections;
appPortSearchBoundingBox=app.PortSearchBoundingBox;
BBxmin=app.PortSearchBoundingBox.X(1);
BBxmax=app.PortSearchBoundingBox.X(2);
BBymin=app.PortSearchBoundingBox.Y(1);
BBymax=app.PortSearchBoundingBox.Y(2);
if (BBxmin>BBxmax)
help=BBxmax;
BBxmax=BBxmin;
BBxmin=help;
end
if (BBymin>BBymax)
help=BBymax;
BBymax=BBymin;
BBymin=help;
end
parfor intersection1=1:(size(appEllipseIntersections,1)-1)
% fprintf('.');
for intersection2=(intersection1+1):size(appEllipseIntersections,1)
% fprintf('.');
CurrentIntersections=CircleIntersectionFinder(appEllipseIntersections(intersection1,1), appEllipseIntersections(intersection1,2), Pathlength(intersection1,chan), appEllipseIntersections(intersection2,1), appEllipseIntersections(intersection2,2), Pathlength(intersection2,chan));
%% if appShowPortSearchIntersectionsCheckBoxValue==true
%% plot(myAxes,CurrentIntersections(:,1),CurrentIntersections(:,2),"d","MarkerEdgeColor",[0 0.5 0]);
%% end
%Check, if and which of the IntersectionsAre inside the port search bounding box
%if isInPortSearchBoundingBoxPar(CurrentIntersections(1,1),CurrentIntersections(1,2),appPortSearchBoundingBox)==true
if ((CurrentIntersections(1,1)>=BBxmin)&&(CurrentIntersections(1,1)<=BBxmax)&&(CurrentIntersections(1,2)>=BBymin)&&(CurrentIntersections(1,2)<=BBymax)==true)
finalPortIntersection=finalPortIntersection+CurrentIntersections(1,:);
ValidIntersectionCounter=ValidIntersectionCounter+1;
end
%if isInPortSearchBoundingBoxPar(CurrentIntersections(2,1),CurrentIntersections(2,2),appPortSearchBoundingBox)==true
if ((CurrentIntersections(2,1)>=BBxmin)&&(CurrentIntersections(2,1)<=BBxmax)&&(CurrentIntersections(2,2)>=BBymin)&&(CurrentIntersections(2,2)<=BBymax)==true)
finalPortIntersection=finalPortIntersection+CurrentIntersections(2,:);
ValidIntersectionCounter=ValidIntersectionCounter+1;
end
end
end
if ValidIntersectionCounter>0
finalPortIntersection=finalPortIntersection/ValidIntersectionCounter;
%finalPortIntersection
plot(myAxes,finalPortIntersection(1),finalPortIntersection(2),'*',"MarkerEdgeColor",[1 0 0]);
app.ChannelProps.X(chan)=finalPortIntersection(1);
app.ChannelProps.Y(chan)=finalPortIntersection(2);
app.ChannelPropsUITable.Data=table2cell(app.ChannelProps(1:app.NoOfChannels,:));
else
uialert(app.UIFigure,sprintf('No valid port position found for channel no. %d',chan),'Warning!',"Icon","warning","Modal",true);
end
end
end
fprintf('\n');
close(d2);
% CircleIntersections
% circinter=CircleIntersectionFinder(app.EllipseIntersections(intersection1,1), app.EllipseIntersections(intersection1,2), Pathlength(intersection1,chan), app.EllipseIntersections(intersection2,1), app.EllipseIntersections(intersection2,2), Pathlength(intersection2,chan));
% plot(myAxes,circinter(:,1),circinter(:,2),"d","MarkerEdgeColor",[0 0.5 0]);
end
function plotcircle(app, myAxes, x,y,r,color)
th = 0:pi/10000:2*pi;
f = r * exp(j*th) + x+j*y;
plot(myAxes, real(f), imag(f),'Color', color, 'Linestyle','-');
end
function result = isInPortSearchBoundingBox(app,x,y)
xmin=app.PortSearchBoundingBox.X(1);
xmax=app.PortSearchBoundingBox.X(2);
ymin=app.PortSearchBoundingBox.Y(1);
ymax=app.PortSearchBoundingBox.Y(2);
if (xmin>xmax)
help=xmax;
xmax=xmin;
xmin=help;
end
if (ymin>ymax)
help=ymax;
ymax=ymin;
ymin=help;
end
if (x>=xmin)&&(x<=xmax)&&(y>=ymin)&&(y<=ymax)
result=true;
else
result=false;
end
end
function CalculatePortsCenterOfGravity(app,myAxes)
% Pos=[app.CommonProps.X(1), app.CommonProps.Y(1)];
Pos=[0, 0];
for chan=1:app.NoOfChannels
Pos=Pos+[app.ChannelProps.X(chan), app.ChannelProps.Y(chan)];
end
Pos=Pos./app.NoOfChannels; %Center of gravity of distinct ports
shiftdir=(Pos-[app.CommonProps.X(1), app.CommonProps.Y(1)])/norm( Pos-[app.CommonProps.X(1), app.CommonProps.Y(1)] );
app.BlazeShiftXY=app.BlazeShift*shiftdir;
Pos=(Pos+[app.CommonProps.X(1), app.CommonProps.Y(1)])./2; % average of center of gravity of distinct ports and of common port
Pos=Pos+app.BlazeShiftXY; % shift the ports center of gravity for BlazeShift
if app.ShowGratingAdditionsCheckBox.Value==true
plot(myAxes,Pos(1),Pos(2),'x',"MarkerEdgeColor",[0.5 1 0], 'MarkerSize', 12);
end
app.PortsCenterOfGravity=Pos;
end
function CalculateGratingCenter(app, myAxes)
app.GratingCenter=[];
if isempty(app.EllipseIntersections)==false
%calculate the line through the center of the grating with respect to the center of gravity of the ports
%first shift the end points of the grating so that the ports center of gravity is the new origin
x1=app.EllipseIntersections(1,1)-app.PortsCenterOfGravity(1);
y1=app.EllipseIntersections(1,2)-app.PortsCenterOfGravity(2);
x2=app.EllipseIntersections(end,1)-app.PortsCenterOfGravity(1);
y2=app.EllipseIntersections(end,2)-app.PortsCenterOfGravity(2);
%convert to polar coordinates
phi1=atan2(y1,x1);
phi2=atan2(y2,x2);
%r1=sqrt(x1^2+y1^2);
%r2=sqrt(x2^2+y2^2);
phicenter=(phi1+phi2)/2;
cosphicenter=cos(phicenter);
sinphicenter=sin(phicenter);
%calculate distance from each grating point to line through port center of gravity with angle phicenter
%first calculate line
%two points on the line:
%centerline_x1=app.PortsCenterOfGravity(1);
%centerline_y1=app.PortsCenterOfGravity(2);
%centerline_x2=cos(phicenter)+app.PortsCenterOfGravity(1);
%centerline_y2=sin(phicenter)+app.PortsCenterOfGravity(2);
%line formula
%gvec=posvec+t*dirvec
%gvec=[centerline_x1; centerline_y1]+t*([centerline_x2; centerline_y2]-[centerline_x1; centerline_y1])
%gvec=[centerline_x1; centerline_y1]+t*([cos(phicenter); sin(phicenter)]
%distance to qvec=[app.EllipseIntersections(i,1); app.EllipseIntersections(i,2)]?
%d=abs( dirvec cross (qvec-posvec) )/abs(dirvec)
%abs(dirvec)=1 ==> d=abs( dirvec cross (qvec-posvec) )
%d=abs([cos(phicenter); sin(phicenter)] * ([app.EllipseIntersections(i,1); app.EllipseIntersections(i,2)]-[centerline_x1; centerline_y1]) );
%in 2D vector '*' is the determinant of the two vectors put into a matrix
%d=abs( det( [dirvec , (qvec-posvec)] ) )
d=1e6; %set initial d to large value
gratingpointnumber=0;
for i=1:size(app.EllipseIntersections,1)
dnew=abs(det([[cosphicenter; sinphicenter],[app.EllipseIntersections(i,1); app.EllipseIntersections(i,2)]-[app.PortsCenterOfGravity(1); app.PortsCenterOfGravity(2)]]) );
if dnew<d
d=dnew; %set new lowest distance
gratingpointnumber=i; %and save the respective grating point for that lowest distance
end
end
%get the distance of the nearest grating point to the ports center of gravity
dx=app.EllipseIntersections(gratingpointnumber,1)-app.PortsCenterOfGravity(1);
dy=app.EllipseIntersections(gratingpointnumber,2)-app.PortsCenterOfGravity(2);
r=sqrt(dx^2+dy^2);
%now get the point on the line with distance r to ports center of gravity
%x=r*cosphicenter+app.PortsCenterOfGravity(1);
%y=r*sinphicenter+app.PortsCenterOfGravity(2);
%app.GratingCenter=[x, y];
app.GratingCenter=[r*cosphicenter+app.PortsCenterOfGravity(1), r*sinphicenter+app.PortsCenterOfGravity(2)];
end
if app.ShowGratingAdditionsCheckBox.Value==true
plot(myAxes,app.GratingCenter(1),app.GratingCenter(2),'x',"MarkerEdgeColor",[0.5 1 0], 'MarkerSize', 12);
plot(myAxes,[app.PortsCenterOfGravity(1); app.GratingCenter(1)], [app.PortsCenterOfGravity(2); app.GratingCenter(2)], "r-");
plot(myAxes,[app.PortsCenterOfGravity(1); app.EllipseIntersections(1,1)], [app.PortsCenterOfGravity(2); app.EllipseIntersections(1,2)], "r-");
plot(myAxes,[app.PortsCenterOfGravity(1); app.EllipseIntersections(end,1)], [app.PortsCenterOfGravity(2); app.EllipseIntersections(end,2)], "r-");
end
end
function CalculateGratingReflectorDirections(app, myAxes)
if isempty(app.EllipseIntersections)==false
app.GratingPointsReflectorDirections=zeros(size(app.EllipseIntersections,1),1);
for i=1:size(app.EllipseIntersections,1)
app.GratingPointsReflectorDirections(i)=atan2(app.EllipseIntersections(i,2)-app.PortsCenterOfGravity(2) , app.EllipseIntersections(i,1)-app.PortsCenterOfGravity(1));
if app.ShowGratingAdditionsCheckBox.Value==true
plot(myAxes,[app.EllipseIntersections(i,1); app.EllipseIntersections(i,1)+10*cos(app.GratingPointsReflectorDirections(i))], [app.EllipseIntersections(i,2); app.EllipseIntersections(i,2)+10*sin(app.GratingPointsReflectorDirections(i))], 'g-');
end
end
end
if (app.GratingPointsReflectorDirections(end)-app.GratingPointsReflectorDirections(1))<0
app.GratingTrajectoryReversed=0;
else
app.GratingTrajectoryReversed=1;
end
end
function CalculateGratingReflectors(app, myAxes)
if isempty(app.EllipseIntersections)==false
app.BraggReflectors=cell(size(app.EllipseIntersections,1),app.BraggPeriods);
app.SiBoundary=zeros(2,size(app.EllipseIntersections,1));
app.SiO2BoundaryGDS2=app.SiBoundary;
% first calculate the angles of the lines between grating points, which define the borders of the bragg
% gratings
app.GratingPointsReflectorHalfAngles=zeros(size(app.EllipseIntersections,1)+1,1);
for i=2:size(app.EllipseIntersections,1)
app.GratingPointsReflectorHalfAngles(i)=(atan2(app.EllipseIntersections(i-1,2)-app.PortsCenterOfGravity(2) , app.EllipseIntersections(i-1,1)-app.PortsCenterOfGravity(1)) + atan2(app.EllipseIntersections(i,2)-app.PortsCenterOfGravity(2) , app.EllipseIntersections(i,1)-app.PortsCenterOfGravity(1)) )/2;
end
app.GratingPointsReflectorHalfAngles(1)= 2*atan2(app.EllipseIntersections(1,2)-app.PortsCenterOfGravity(2) , app.EllipseIntersections(1,1)-app.PortsCenterOfGravity(1))-app.GratingPointsReflectorHalfAngles(2);
app.GratingPointsReflectorHalfAngles(end)= 2*atan2(app.EllipseIntersections(size(app.EllipseIntersections,1),2)-app.PortsCenterOfGravity(2) , app.EllipseIntersections(size(app.EllipseIntersections,1),1)-app.PortsCenterOfGravity(1)) - app.GratingPointsReflectorHalfAngles(end-1);
%app.GratingPointsReflectorHalfAngles
%{
if app.ShowGratingAdditionsCheckBox.Value==true
for i=1:size(app.EllipseIntersections,1)+1
plot(myAxes,[app.PortsCenterOfGravity(1)+app.RadiusMin*cos(app.GratingPointsReflectorHalfAngles(i)); app.PortsCenterOfGravity(1)+app.RadiusMax*cos(app.GratingPointsReflectorHalfAngles(i))], [app.PortsCenterOfGravity(2)+app.RadiusMin*sin(app.GratingPointsReflectorHalfAngles(i)); app.PortsCenterOfGravity(2)+app.RadiusMax*sin(app.GratingPointsReflectorHalfAngles(i))], 'b-');
end
end
%}
% calculate the corner points of all Bragg elements and store them into app.BraggReflectors
% vector representation of border lines
% bvec=[app.PortsCenterOfGravity(1);app.PortsCenterOfGravity(2)] + s*[cos(app.GratingPointsReflectorHalfAngles(i));sin(app.GratingPointsReflectorHalfAngles(i))]
% points, which define the bragg grating, beginning with grating points
% pvec=[app.EllipseIntersections(j,1);app.EllipseIntersections(j,2)] + t*[cos(app.GratingPointsReflectorDirections(j)); sin(app.GratingPointsReflectorDirections(j))]
% t=0, app.BraggSiO2Length*1e-3, app.BraggPeriodLength*1e-3, (app.BraggPeriodLength+app.BraggSiO2Length)*1e-3,
% 2*app.BraggPeriodLength*1e-3, ...
% vector representation of first bragg grating line through grating points
% qvec=pvec + t*[sin(app.GratingPointsReflectorDirections(j));-cos(app.GratingPointsReflectorDirections(j))]
% part of line definitions for left and right boundaries
pos1=[app.PortsCenterOfGravity(1);app.PortsCenterOfGravity(2)];
for i=1:size(app.EllipseIntersections,1)
% second part of line definitions for left and right boundaries
dir1a=[cos(app.GratingPointsReflectorHalfAngles(i));sin(app.GratingPointsReflectorHalfAngles(i))];
dir1b=[cos(app.GratingPointsReflectorHalfAngles(i+1));sin(app.GratingPointsReflectorHalfAngles(i+1))];
% part of line definitions for bottom boundary
dir2=[sin(app.GratingPointsReflectorDirections(i));-cos(app.GratingPointsReflectorDirections(i))];
for j=1:app.BraggPeriods
% second part of line definitions for bottom boundary
pos2=[app.EllipseIntersections(i,1)+((j-1)*app.BraggPeriodLength)*1e-3*cos(app.GratingPointsReflectorDirections(i));
app.EllipseIntersections(i,2)+((j-1)*app.BraggPeriodLength)*1e-3*sin(app.GratingPointsReflectorDirections(i))];
% additional line definition for top boundary (direction vector is the same as before: dir2
pos3=[app.EllipseIntersections(i,1)+((j-1)*app.BraggPeriodLength +app.BraggSiO2Length)*1e-3*cos(app.GratingPointsReflectorDirections(i));
app.EllipseIntersections(i,2)+((j-1)*app.BraggPeriodLength +app.BraggSiO2Length)*1e-3*sin(app.GratingPointsReflectorDirections(i))];
% find the corner points of the Bragg element of the current period...
% bottom left
bp1=app.LineLineIntersection(pos1 , dir1a , pos2 , dir2 );
% bottom right
bp2=app.LineLineIntersection(pos1 , dir1b , pos2 , dir2 );
% top left
bp3=app.LineLineIntersection(pos1 , dir1a , pos3 , dir2 );
% top right
bp4=app.LineLineIntersection(pos1 , dir1b , pos3 , dir2 );
%to avoid sharp angles and small features error in certain design rule checks, the calculated points are shifted a little to make the reflectors smaller and give them some space in between
newbp1=app.MovePoint(bp1, bp2, app.ReflectorSpacing*1E-3/2);
newbp2=app.MovePoint(bp2, bp1, app.ReflectorSpacing*1E-3/2);
newbp3=app.MovePoint(bp3, bp4, app.ReflectorSpacing*1E-3/2);
newbp4=app.MovePoint(bp4, bp3, app.ReflectorSpacing*1E-3/2);
% ...and put the coordinates into the respective cell
% app.BraggReflectors{i,j}=[ bp1(1), bp1(2); bp2(1), bp2(2); bp4(1), bp4(2); bp3(1), bp3(2)];
app.BraggReflectors{i,j}=[ newbp1(1), newbp2(1), newbp4(1), newbp3(1); newbp1(2), newbp2(2), newbp4(2), newbp3(2)];
% let's show the stuff, if the user wants
if app.ShowGratingAdditionsCheckBox.Value==true
plot(myAxes,[newbp1(1);newbp2(1);newbp4(1);newbp3(1);newbp1(1)],[newbp1(2);newbp2(2);newbp4(2);newbp3(2);newbp1(2)], 'b-');
%plot(myAxes,[app.BraggReflectors{i,j}(:,1); app.BraggReflectors{i,j}(1,1)], [app.BraggReflectors{i,j}(:,2); app.BraggReflectors{i,j}(1,2)], 'b-');
end
%plot(myAxes, bp3(1), bp3(2), "rx");
end
% and calculate some border points
app.SiBoundary(:,i)=[app.EllipseIntersections(i,1)+(app.BraggPeriodLength*app.BraggPeriods+app.BoundaryDistance)*1e-3*cos(app.GratingPointsReflectorDirections(i));
app.EllipseIntersections(i,2)+(app.BraggPeriodLength*app.BraggPeriods+app.BoundaryDistance)*1e-3*sin(app.GratingPointsReflectorDirections(i))];
% app.SiO2BoundaryGDS2(:,i)=app.SiBoundary(:,i)+[app.SiO2SlabEnhancement*1e-3*cos(app.GratingPointsReflectorDirections(i)) ; app.SiO2SlabEnhancement*1e-3*sin(app.GratingPointsReflectorDirections(i))]; %shift the border for the cladding even further out
app.SiO2BoundaryGDS2(:,i)=app.SiBoundary(:,i);
end
%celldisp(app.BraggReflectors)
if app.GratingTrajectoryReversed==0
LeftDirectionIndex=1;
LeftHalfAngleIndex=1;
LeftReflectorIndex=1;
RightDirectionIndex=size(app.GratingPointsReflectorDirections,1);
RightHalfAngleIndex=size(app.GratingPointsReflectorHalfAngles,1);
RightReflectorIndex=size(app.BraggReflectors,1);
else
LeftDirectionIndex=size(app.GratingPointsReflectorDirections,1);
LeftHalfAngleIndex=size(app.GratingPointsReflectorHalfAngles,1);
LeftReflectorIndex=size(app.BraggReflectors,1);
RightDirectionIndex=1;
RightHalfAngleIndex=1;
RightReflectorIndex=1;
app.SiBoundary=flip(app.SiBoundary,2); % reverse order of path of border points
app.SiO2BoundaryGDS2=flip(app.SiO2BoundaryGDS2,2);
end
% additional most 'top left' point of boundary around bragg grating
dir1a=[sin(app.GratingPointsReflectorDirections(LeftDirectionIndex));-cos(app.GratingPointsReflectorDirections(LeftDirectionIndex))];
dir1b=[cos(app.GratingPointsReflectorHalfAngles(LeftHalfAngleIndex));sin(app.GratingPointsReflectorHalfAngles(LeftHalfAngleIndex))];
pos1=[app.BraggReflectors{LeftReflectorIndex,end}(1,4); app.BraggReflectors{LeftReflectorIndex,end}(2,4)]-dir1a*app.BoundaryDistance*1e-3+dir1b*app.BoundaryDistance*1e-3;
%pos1SiO2=[app.BraggReflectors{LeftReflectorIndex,end}(1,4); app.BraggReflectors{LeftReflectorIndex,end}(2,4)]-dir1a*(app.BoundaryDistance+app.SiO2SlabEnhancement)*1e-3+dir1b*(app.BoundaryDistance+app.SiO2SlabEnhancement)*1e-3;
pos1SiO2=[app.BraggReflectors{LeftReflectorIndex,end}(1,4); app.BraggReflectors{LeftReflectorIndex,end}(2,4)]-dir1a*(app.BoundaryDistance)*1e-3+dir1b*(app.BoundaryDistance)*1e-3;
% additional most 'bottom left' point of boundary around bragg grating
dir2=[sin(app.GratingPointsReflectorDirections(LeftDirectionIndex));-cos(app.GratingPointsReflectorDirections(LeftDirectionIndex))];
pos2=[app.BraggReflectors{LeftReflectorIndex,1}(1,1); app.BraggReflectors{LeftReflectorIndex,1}(2,1)]-dir2*app.BoundaryDistance*1e-3;
%pos2SiO2=[app.BraggReflectors{LeftReflectorIndex,1}(1,1); app.BraggReflectors{LeftReflectorIndex,1}(2,1)]-dir2*(app.BoundaryDistance+app.SiO2SlabEnhancement)*1e-3;
pos2SiO2=[app.BraggReflectors{LeftReflectorIndex,1}(1,1); app.BraggReflectors{LeftReflectorIndex,1}(2,1)]-dir2*(app.BoundaryDistance)*1e-3;
% additional most 'top right' point of boundary around bragg grating
dir3a=[sin(app.GratingPointsReflectorDirections(RightDirectionIndex));-cos(app.GratingPointsReflectorDirections(RightDirectionIndex))];
dir3b=[cos(app.GratingPointsReflectorHalfAngles(RightHalfAngleIndex));sin(app.GratingPointsReflectorHalfAngles(RightHalfAngleIndex))];
pos3=[app.BraggReflectors{RightReflectorIndex,end}(1,3); app.BraggReflectors{RightReflectorIndex,end}(2,3)]+dir3a*app.BoundaryDistance*1e-3+dir3b*app.BoundaryDistance*1e-3;
%pos3SiO2=[app.BraggReflectors{RightReflectorIndex,end}(1,3); app.BraggReflectors{RightReflectorIndex,end}(2,3)]+dir3a*(app.BoundaryDistance+app.SiO2SlabEnhancement)*1e-3+dir3b*(app.BoundaryDistance+app.SiO2SlabEnhancement)*1e-3;
pos3SiO2=[app.BraggReflectors{RightReflectorIndex,end}(1,3); app.BraggReflectors{RightReflectorIndex,end}(2,3)]+dir3a*(app.BoundaryDistance)*1e-3+dir3b*(app.BoundaryDistance)*1e-3;
% additional most 'bottom right' point of boundary around bragg grating
dir4=[sin(app.GratingPointsReflectorDirections(RightDirectionIndex));-cos(app.GratingPointsReflectorDirections(RightDirectionIndex))];
pos4=[app.BraggReflectors{RightReflectorIndex,1}(1,2); app.BraggReflectors{RightReflectorIndex,1}(2,2)]+dir4*app.BoundaryDistance*1e-3;
%pos4SiO2=[app.BraggReflectors{RightReflectorIndex,1}(1,2); app.BraggReflectors{RightReflectorIndex,1}(2,2)]+dir4*(app.BoundaryDistance+app.SiO2SlabEnhancement)*1e-3;
pos4SiO2=[app.BraggReflectors{RightReflectorIndex,1}(1,2); app.BraggReflectors{RightReflectorIndex,1}(2,2)]+dir4*(app.BoundaryDistance)*1e-3;
%{
% additional most 'top left' point of boundary around bragg grating
dir1a=[sin(app.GratingPointsReflectorDirections(1));-cos(app.GratingPointsReflectorDirections(1))];
dir1b=[cos(app.GratingPointsReflectorHalfAngles(1));sin(app.GratingPointsReflectorHalfAngles(1))];
pos1=[app.BraggReflectors{1,end}(1,4); app.BraggReflectors{1,end}(2,4)]-dir1a*app.BoundaryDistance*1e-3+dir1b*app.BoundaryDistance*1e-3;
% additional most 'bottom left' point of boundary around bragg grating
dir2=[sin(app.GratingPointsReflectorDirections(1));-cos(app.GratingPointsReflectorDirections(1))];
pos2=[app.BraggReflectors{1,1}(1,1); app.BraggReflectors{1,1}(2,1)]-dir2*app.BoundaryDistance*1e-3;
% additional most 'top right' point of boundary around bragg grating
dir3a=[sin(app.GratingPointsReflectorDirections(end));-cos(app.GratingPointsReflectorDirections(end))];
dir3b=[cos(app.GratingPointsReflectorHalfAngles(end));sin(app.GratingPointsReflectorHalfAngles(end))];
pos3=[app.BraggReflectors{end,end}(1,3); app.BraggReflectors{end,end}(2,3)]+dir3a*app.BoundaryDistance*1e-3+dir3b*app.BoundaryDistance*1e-3;
% additional most 'bottom right' point of boundary around bragg grating
dir4=[sin(app.GratingPointsReflectorDirections(end));-cos(app.GratingPointsReflectorDirections(end))];
pos4=[app.BraggReflectors{end,1}(1,2); app.BraggReflectors{end,1}(2,2)]+dir4*app.BoundaryDistance*1e-3;
%}
app.SiBoundary=[pos2 pos1 app.SiBoundary(:,:) pos3 pos4];
app.SiO2BoundaryGDS2=[pos2SiO2 pos1SiO2 app.SiO2BoundaryGDS2(:,:) pos3SiO2 pos4SiO2];
% use some points of the Si-boundary for the top parts of the attenuators in the GDS2 layout...
app.AttenuatorLeft = [ pos2 pos1 app.SiBoundary(:,3)*0.8+pos1*0.2 ]; % fixed to 20% of the way between the respective points
app.AttenuatorRight = [ app.SiBoundary(:,end-2)*0.8+pos3*0.2 pos3 pos4 ]; % fixed to 20% of the way between the respective points
%plot(myAxes,app.BraggReflectors{1,end}(1,4),app.BraggReflectors{1,end}(2,4),'rd');
% if app.ShowGratingAdditionsCheckBox.Value==true
% plot(myAxes,app.SiBoundary(1,:),app.SiBoundary(2,:), 'b-');
% end
end
end
function ipoint = LineLineIntersection(app, p1, p1dir, p3, p3dir)
ipoint=NaN(2,1);
%finds intersection point of two lines
%aline=p1+s*p1dir
%bline=p3+t*p3dir
%first convert the vector form of the lines into the coordinate form
p2=p1+p1dir;
p4=p3+p3dir;
% then use the formula from https://de.wikipedia.org/wiki/Schnittpunkt
%denom=(p4(2)-p3(2))*(p2(1)-p1(1))-(p2(2)-p1(2))*(p4(1)-p3(1));
%ps(1)=(p4(1)-p3(1))*(p2(1)*p1(2)-p1(1)*p2(2))-(p2(1)-p1(1))*(p4(1)*p3(2)-p3(1)*p4(2))/denom;
%ps(2)=(p1(2)-p2(2))*(p4(1)*p3(2)-p3(1)*p4(2))-(p3(2)-p4(2))*(p2(1)*p1(2)-p1(1)*p2(2))/denom;
%ipoint=ps;
%and that's wrong. SHIT! Änderung eingereicht...
% a*x+b*y=c
% with p1=(x1,y1) and p2=(x2,y2)
% ==> (x,y)=(x1,y1)+t*(x2-x1, y2-y1)
% ==> a=y2-y1 b=x1-x2 c=x1*y2-x2*y1
% => a1=y2-y1 b1=x1-x2 c1=x1*y2-x2*y1
% and a2=y4-y3 b2=x3-x4 c2=x3*y4-x4*y3
% Cramersche Regel (https://de.wikipedia.org/wiki/Schnittpunkt ,
% https://de.wikipedia.org/wiki/Cramersche_Regel)
% ==> xs=(b2*c1-b1*c2)/(a1*b2-a2*b1) ys=(a1*c2-a2*c1)/(a1*b2-a2*b1)
denom=((p2(2)-p1(2))*(p3(1)-p4(1))-(p4(2)-p3(2))*(p1(1)-p2(1)));
ipoint(1)=((p3(1)-p4(1))*(p1(1)*p2(2)-p2(1)*p1(2))-(p1(1)-p2(1))*(p3(1)*p4(2)-p4(1)*p3(2)))/denom;
ipoint(2)=((p2(2)-p1(2))*(p3(1)*p4(2)-p4(1)*p3(2))-(p4(2)-p3(2))*(p1(1)*p2(2)-p2(1)*p1(2)))/denom;
end
function ipoint = MovePoint(app, p1, p2, dist)
% finds a new point on straight between p1 and p2 with distance dist to p1
ipoint=NaN(2,1);
dir=(p2-p1)/norm(p2-p1);
ipoint=p1+dir*dist;
end
function CalculatePortDirections(app, myAxes)
if isempty(app.GratingCenter)==false
app.PortDirections=zeros(app.NoOfChannels+1,1);
for i=1:app.NoOfChannels
app.PortDirections(i)=atan2(app.ChannelProps.Y(i)-app.GratingCenter(2), app.ChannelProps.X(i)-app.GratingCenter(1));
if app.ShowGratingAdditionsCheckBox.Value==true
plot(myAxes,[app.ChannelProps.X(i); app.ChannelProps.X(i)+10*cos(app.PortDirections(i))], [app.ChannelProps.Y(i); app.ChannelProps.Y(i)+10*sin(app.PortDirections(i))], 'g-');
end
end
app.PortDirections(app.NoOfChannels+1)=atan2(app.CommonProps.Y(1)-app.GratingCenter(2), app.CommonProps.X(1)-app.GratingCenter(1));
if app.ShowGratingAdditionsCheckBox.Value==true
plot(myAxes,[app.CommonProps.X(1); app.CommonProps.X(1)+10*cos(app.PortDirections(app.NoOfChannels+1))], [app.CommonProps.Y(1); app.CommonProps.Y(1)+10*sin(app.PortDirections(app.NoOfChannels+1))], 'g-');
end
end
end
% calculate angle between lines connecting p1 to p2 to p3
function angle=CalculateAngle(app, p1, p2, p3)
CAdir1 = p1-p2;
CAdir2 = p3-p2;
%Formula from https://de.mathworks.com/matlabcentral/answers/180131-how-can-i-find-the-angle-between-two-vectors-including-directional-information
angle = atan2d(CAdir1(1)*CAdir2(2)-CAdir1(2)*CAdir2(1),CAdir1(1)*CAdir2(1)+CAdir1(2)*CAdir2(2));
end
% This function shifts the new bevel points a certain length from the corner