This repository was archived by the owner on Jun 10, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCaTSper_exported.m
More file actions
5647 lines (4802 loc) · 262 KB
/
CaTSper_exported.m
File metadata and controls
5647 lines (4802 loc) · 262 KB
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 CaTSper_exported < matlab.apps.AppBase
% Properties that correspond to app components
properties (Access = public)
CaTSperUIFigure matlab.ui.Figure
TabGroup matlab.ui.container.TabGroup
TimeDomainTDTab matlab.ui.container.Tab
ColorOrderDropDown_TD matlab.ui.control.DropDown
ColorOrderLabel matlab.ui.control.Label
SetCurrentSettingsDefaultButton matlab.ui.control.Button
LegendButton_TD matlab.ui.control.StateButton
AssignTD_DataButton matlab.ui.control.Button
SaveData_TD matlab.ui.control.Button
LoadData_TD matlab.ui.control.Button
ResetSettingsButton matlab.ui.control.Button
MetadataInformationPanel matlab.ui.container.Panel
ThicknessDropDown matlab.ui.control.DropDown
ThicknessDropDownLabel matlab.ui.control.Label
mdReferenceThicknessDropDown matlab.ui.control.DropDown
ReferenceLabel matlab.ui.control.Label
mdSampleThicknessDropDown matlab.ui.control.DropDown
SampleLabel matlab.ui.control.Label
ThicknessSwitch_TD matlab.ui.control.Switch
md4DesEditField matlab.ui.control.EditField
md4EditField matlab.ui.control.NumericEditField
md4EditFieldLabel matlab.ui.control.Label
md3DesEditField matlab.ui.control.EditField
md3EditField matlab.ui.control.NumericEditField
md3EditFieldLabel matlab.ui.control.Label
md2DesEditField matlab.ui.control.EditField
md2EditField matlab.ui.control.NumericEditField
md2EditFieldLabel matlab.ui.control.Label
md1DesEditField matlab.ui.control.EditField
md1EditField matlab.ui.control.NumericEditField
md1EditFieldLabel matlab.ui.control.Label
FFTSettingsPanel matlab.ui.container.Panel
TransformButton matlab.ui.control.Button
FulllistnamingCheckBox matlab.ui.control.CheckBox
PlotWindowFunctionButton matlab.ui.control.Button
FunctionDropDown matlab.ui.control.DropDown
FunctionDropDownLabel matlab.ui.control.Label
ToTimeEditField matlab.ui.control.NumericEditField
MaxTimeLabel matlab.ui.control.Label
FromTimeEditField matlab.ui.control.NumericEditField
fromLabel_3 matlab.ui.control.Label
ManualWindowpsLabel matlab.ui.control.Label
truncatebeforethe1stetalonLabel matlab.ui.control.Label
AutoWindowButton matlab.ui.control.StateButton
WindowFunctionLabel matlab.ui.control.Label
ToEpolFreqEditField matlab.ui.control.NumericEditField
toLabel_2 matlab.ui.control.Label
FromEpolFreqEditField matlab.ui.control.NumericEditField
fromLabel_2 matlab.ui.control.Label
ExtrapolationRangeTHzLabel matlab.ui.control.Label
StartFrequencyTHzEditField matlab.ui.control.NumericEditField
StartFrequencyTHzEditFieldLabel matlab.ui.control.Label
UnwrappingLabel matlab.ui.control.Label
ZeroFillingpowerofSpinner matlab.ui.control.Spinner
ZeroFillingpowerofSpinnerLabel matlab.ui.control.Label
UpsamplingLabel matlab.ui.control.Label
ToFreqEditField matlab.ui.control.NumericEditField
toLabel matlab.ui.control.Label
FromFreqEditField matlab.ui.control.NumericEditField
fromLabel matlab.ui.control.Label
FrequencyRangeTHzLabel matlab.ui.control.Label
DatasetInformationPanel matlab.ui.container.Panel
dsPumpedDropDown matlab.ui.control.DropDown
PumpedLabel matlab.ui.control.Label
dsReferenceDropDown matlab.ui.control.DropDown
ReferenceDropDownLabel matlab.ui.control.Label
dsSampleDropDown matlab.ui.control.DropDown
SampleDropDownLabel matlab.ui.control.Label
ds4DesEditField matlab.ui.control.EditField
ds4EditFieldLabel matlab.ui.control.Label
ds3DesEditField matlab.ui.control.EditField
ds3EditFieldLabel matlab.ui.control.Label
ds2DesEditField matlab.ui.control.EditField
ds2EditFieldLabel matlab.ui.control.Label
ds1DesEditField matlab.ui.control.EditField
ds1EditFieldLabel matlab.ui.control.Label
GeneralInformationPanel matlab.ui.container.Panel
GeneralEtalonEditField matlab.ui.control.NumericEditField
stEtalonpsLabel matlab.ui.control.Label
GeneralRefractiveIndexEditField matlab.ui.control.NumericEditField
RefractiveIndexEditFieldLabel matlab.ui.control.Label
GeneralUserEditField matlab.ui.control.EditField
UserEditFieldLabel matlab.ui.control.Label
GeneralInstrumentEditField matlab.ui.control.EditField
InstrumentEditFieldLabel matlab.ui.control.Label
GeneralDateandTimeEditField matlab.ui.control.EditField
DateandTimeEditFieldLabel matlab.ui.control.Label
GeneralDescriptionEditField matlab.ui.control.EditField
DescriptionEditField_2Label_2 matlab.ui.control.Label
CheckDynamicRangeButton matlab.ui.control.Button
PlotForCustomisationButton_TD matlab.ui.control.Button
Plot2TDButton matlab.ui.control.Button
DELButton matlab.ui.control.Button
Plot1TDButton matlab.ui.control.Button
GridOffButton_3 matlab.ui.control.StateButton
ADDButton matlab.ui.control.Button
ALLButton matlab.ui.control.Button
ButtonGroupTD matlab.ui.container.ButtonGroup
BothButtonTD matlab.ui.control.RadioButton
SampleButtonTD matlab.ui.control.RadioButton
ReferenceButtonTD matlab.ui.control.RadioButton
SelectionListBox matlab.ui.control.ListBox
MeasurementListBox matlab.ui.control.ListBox
SelectionListBoxLabel matlab.ui.control.Label
MeasurementListBoxLabel matlab.ui.control.Label
UIAxes1 matlab.ui.control.UIAxes
UIAxes2 matlab.ui.control.UIAxes
FrequencyDomainFDTab matlab.ui.container.Tab
ColorOrderDropDown_FD matlab.ui.control.DropDown
ColorOrderLabel_2 matlab.ui.control.Label
LegendButton_FD matlab.ui.control.StateButton
AssignFD_DataButton matlab.ui.control.Button
SaveData_FD matlab.ui.control.Button
LoadData_FD matlab.ui.control.Button
DataManagementButton matlab.ui.control.Button
FDDatatoLabel matlab.ui.control.Label
FDDataAnalysisPanel matlab.ui.container.Panel
PlotForCustomisationButton_FD2 matlab.ui.control.Button
CalculateOpticalParametersButton matlab.ui.control.Button
Plot2FDButton_2 matlab.ui.control.Button
MultipleReflectionCountPanel matlab.ui.container.Panel
SampleNMREditField matlab.ui.control.NumericEditField
SampleEditField_2Label matlab.ui.control.Label
Plot1FDButton_2 matlab.ui.control.Button
DELFDButton_2 matlab.ui.control.Button
GridOffButton_2 matlab.ui.control.StateButton
ADDFDButton_2 matlab.ui.control.Button
RealImagButtonGroup matlab.ui.container.ButtonGroup
ImaginaryButton matlab.ui.control.RadioButton
RealButton matlab.ui.control.RadioButton
MagPhaseButtonGroup_2 matlab.ui.container.ButtonGroup
PhaseButton_2 matlab.ui.control.RadioButton
AmplitudeButton_2 matlab.ui.control.RadioButton
ThicknessPanel matlab.ui.container.Panel
ThicknessUnitLabel matlab.ui.control.Label
ThicknessSwitch_FD matlab.ui.control.Switch
ReferenceEditField matlab.ui.control.NumericEditField
ReferenceEditFieldLabel matlab.ui.control.Label
SampleEditField matlab.ui.control.NumericEditField
SampleEditFieldLabel matlab.ui.control.Label
ALLFDButton_2 matlab.ui.control.Button
DescriptionEditField_FD matlab.ui.control.EditField
FDSelectionListBox_2 matlab.ui.control.ListBox
YscaleButtonGroup_2 matlab.ui.container.ButtonGroup
linearButton_2 matlab.ui.control.RadioButton
logButton_2 matlab.ui.control.RadioButton
PlotDataButtonGroup matlab.ui.container.ButtonGroup
DielectricConstantButton matlab.ui.control.ToggleButton
RefractiveIndexButton matlab.ui.control.ToggleButton
AbsorptionCoefficientButton matlab.ui.control.ToggleButton
TransmittanceButton matlab.ui.control.ToggleButton
DescriptionEditField_2Label matlab.ui.control.Label
FDSelectionListBox_2Label matlab.ui.control.Label
PlotForCustomisationButton_FD1 matlab.ui.control.Button
RemoveAllButton matlab.ui.control.Button
RemoveButton matlab.ui.control.Button
Plot2FDButton matlab.ui.control.Button
Plot1FDButton matlab.ui.control.Button
GridOffButton matlab.ui.control.StateButton
DELFDButton matlab.ui.control.Button
MagPhaseButtonGroup matlab.ui.container.ButtonGroup
PhaseButton matlab.ui.control.RadioButton
AmplitudeButton matlab.ui.control.RadioButton
YscaleButtonGroup matlab.ui.container.ButtonGroup
linearButton matlab.ui.control.RadioButton
logButton matlab.ui.control.RadioButton
ADDFDButton matlab.ui.control.Button
ALLFDButton matlab.ui.control.Button
ButtonGroupFD matlab.ui.container.ButtonGroup
BothButtonFD matlab.ui.control.RadioButton
SampleButtonFD matlab.ui.control.RadioButton
ReferenceButtonFD matlab.ui.control.RadioButton
FDSelectionListBox matlab.ui.control.ListBox
FDListBox matlab.ui.control.ListBox
FDSelectionListBoxLabel matlab.ui.control.Label
FDListListBoxLabel matlab.ui.control.Label
UIAxes4 matlab.ui.control.UIAxes
UIAxes3 matlab.ui.control.UIAxes
DataManagmentDMTab matlab.ui.container.Tab
AssignDM_DataButton matlab.ui.control.Button
SaveData_DM matlab.ui.control.Button
DMTabGroup matlab.ui.container.TabGroup
FrequencyBaseTab matlab.ui.container.Tab
PlotButton matlab.ui.control.Button
YLabelEditField matlab.ui.control.EditField
YLabelEditFieldLabel matlab.ui.control.Label
XLabelEditField matlab.ui.control.EditField
XLabelEditFieldLabel matlab.ui.control.Label
XaxisDataEditField matlab.ui.control.EditField
XaxisDataEditFieldLabel matlab.ui.control.Label
MeasurementEditField matlab.ui.control.EditField
MeasurementEditFieldLabel matlab.ui.control.Label
RearrangeDataButton matlab.ui.control.Button
DisplayXLinesButton matlab.ui.control.Button
GetDatafromFrequencyTHzEditField matlab.ui.control.EditField
GetDatafromFrequencyTHzEditFieldLabel matlab.ui.control.Label
PeakBaseTab matlab.ui.container.Tab
PlotButton_2 matlab.ui.control.Button
YLabelEditField_2 matlab.ui.control.EditField
YLabelEditField_2Label matlab.ui.control.Label
XLabelEditField_2 matlab.ui.control.EditField
XLabelEditField_2Label matlab.ui.control.Label
XaxisDataEditField_2 matlab.ui.control.EditField
XaxisDataEditField_2Label matlab.ui.control.Label
MeasurementEditField_2 matlab.ui.control.EditField
MeasurementEditField_2Label matlab.ui.control.Label
RearrangeDataButton_2 matlab.ui.control.Button
PeakNumSpinner matlab.ui.control.Spinner
PeakNumSpinnerLabel matlab.ui.control.Label
LowerLimitTHzEditField matlab.ui.control.NumericEditField
LowerLimitTHzEditFieldLabel matlab.ui.control.Label
MinPeakProminenceEditField matlab.ui.control.NumericEditField
MinPeakProminenceEditFieldLabel matlab.ui.control.Label
Panel matlab.ui.container.Panel
GridOffButton_DM matlab.ui.control.StateButton
ColorOrderDropDown_DM matlab.ui.control.DropDown
ColorOrderLabel_3 matlab.ui.control.Label
PlotmeanandrangeButton matlab.ui.control.Button
PlotindividualdatasetsButton matlab.ui.control.Button
DPlotFrequencyxaxisPanel matlab.ui.container.Panel
DplotdoesnotsupportthebelowextractingfunctionLabel matlab.ui.control.Label
Plot1_3DButton matlab.ui.control.Button
data3DDropDown matlab.ui.control.DropDown
dataDropDownLabel matlab.ui.control.Label
CalculateButton matlab.ui.control.Button
NumberofDataEditField matlab.ui.control.NumericEditField
NumberofDataEditFieldLabel matlab.ui.control.Label
exABABCetcLabel matlab.ui.control.Label
YaxisDataFormulationEditField matlab.ui.control.EditField
YaxisDataFormulationEditFieldLabel matlab.ui.control.Label
XaxisDataDropDown matlab.ui.control.DropDown
XaxisDataDropDownLabel matlab.ui.control.Label
CforDropDown matlab.ui.control.DropDown
CforDropDownLabel matlab.ui.control.Label
BforDropDown matlab.ui.control.DropDown
BforDropDownLabel matlab.ui.control.Label
AforDropDown matlab.ui.control.DropDown
AforDropDownLabel matlab.ui.control.Label
DefinevariablesLabel matlab.ui.control.Label
SourceDataSetEditField matlab.ui.control.EditField
SourceDataSetEditFieldLabel matlab.ui.control.Label
ImportAllDataInverseSequenceButton matlab.ui.control.Button
ImportAllDataButton matlab.ui.control.Button
AvailableDataSetEditField matlab.ui.control.EditField
AvailableDataSetEditFieldLabel matlab.ui.control.Label
UIAxes9 matlab.ui.control.UIAxes
UIAxes10 matlab.ui.control.UIAxes
SaveTDFDDMButton matlab.ui.control.Button
ClearMemoryButton matlab.ui.control.Button
DeployButton matlab.ui.control.Button
ProjectsEditField matlab.ui.control.EditField
ImportTHzFilesButton matlab.ui.control.Button
DEBUGMsgLabel matlab.ui.control.Label
SystemStatusLabel matlab.ui.control.Label
CaTSperLabel matlab.ui.control.Label
Image matlab.ui.control.Image
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% CaTSper/ Cambridge Terahertz Spectrum Analyser
% The dotTHz project, 2023 Terahertz Applications Group
% Department of Chemical Engineering and Biotechnology
% University of Cambridge, UK (Prof Axel Zeitler's group)
%
% <<Version information>>
%
% <<Acknowledgement>>
% CaTSper source code is under MIT license
% <<Contact>>
% https://github.com/CamTHz - online repository
% https://thz.ceb.cam.ac.uk - research group website
% Lead developer: Jongmin Lee, jl2112@cam.ac.uk
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This in-line code annotation of CaTSper v2.0 aims to provide a detailed explanation of the
% script, function and processes of the CaTSper app
% Definitions of parameters are not annotated for conciseness.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
properties (Access = public)
fullpathname % Terapulse project file name and folder information
filename % Terapulse project file name
TD_data %time domain data extracted from HDF5 project file
TD_select %time domain measurment selection
TD_config % TD to FD transformation configuration
FD_data %frequency data transfered through DFT
FD_select %frequency data selection
FD_select_2 %frequency data selection in FD data analysis section
FD_config
DM_count % the number of data management data
DM_data % data manipluation data
DM_peaks % data management peaks
DR_boundary % dynamic range checker freqeuncy boundary
PRJ_count % the number of project files imported
thicknessUnit % cm, mm, um, and nm
configFile % configuration file
%#exclude config_default.json
end
properties (Access = private)
DialogApp % Dialog box appProperty15 % Description
end
methods (Access = private)
% TDanalysisUpdate calculates and stores the effective refractive index and
% the time delay for one internal reflection to occur for one
% sample measurement
function TDanalysisUpdate(app,TDindex)
% extracting the thickness value from the imported time
% domain data for one measurement
thickness = app.TD_data.metadata{TDindex}.thickness;
thicknessUnit = app.thicknessUnit;
% extracting the time delay value from the imported time
% domain data for one measurement
delta_t = app.TD_data.metadata{TDindex}.timeDelay;
% recalculate
% the following is performed provided the thickness value does not equal to 0
if ~isequal(thickness,0)
% calculate time domain effective refractive index, and
% round the value to 4 s.f. (3 d.p. equivalent)
% time delay value is in units of pico seconds
n_eff = round((delta_t*10^-12*3e8/(thickness*thicknessUnit) + 1)*1000)/1000;
% calculate the time delay for pulse to reach detector,
% when one internal reflection occurs
% time delay with one internation reflection = time delay
% for pulse travelling straight through sample + time delay
% for pulse to travel a distance equals to two times the
% sample thickness
% the second term is calculated from thickness information and the n_eff value
% determined from above
etl_t = delta_t + 2*thickness*thicknessUnit*n_eff/3e8*10^12;
else
% if thickness value is zero, set values to zero automatically
n_eff = 0;
mtpRelection = 0;
end
% update information
app.TD_data.metadata{TDindex}.refractiveIndex = n_eff;
app.TD_data.metadata{TDindex}.internalReflection = etl_t;
% display update
app.GeneralRefractiveIndexEditField.Value = n_eff;
app.stinternalreflectionpsEditField.Value = etl_t;
end
% FDdataDel empties values in row number 'FDindex' for
% different parameters associated with the frequency domain (FD) tab
% when certain conditions are met
function FDdataDel(app,FDindex)
app.FD_data.measList(FDindex) = [];
app.FD_data.metadata(FDindex) = [];
app.FD_data.frequency(FDindex) = [];
app.FD_data.ffd_references(FDindex) = [];
app.FD_data.ffd_samples(FDindex) = [];
app.FD_data.ref_amplitude(FDindex) = [];
app.FD_data.ref_phase(FDindex) = [];
app.FD_data.sam_amplitude(FDindex) = [];
app.FD_data.sam_phase(FDindex) = [];
app.FD_data.transmit_amplitude(FDindex) = [];
app.FD_data.transmit_phase(FDindex) = [];
if isfield(app.FD_data,'absorption_coefficient')
app.FD_data.absorption_coefficient(FDindex) = [];
app.FD_data.refractive_index(FDindex) = [];
app.FD_data.dielectric_constant_real(FDindex) = [];
app.FD_data.dielectric_constant_imaginary(FDindex) = [];
end
end
% TDdataDel empties arrays associated with the time domain (TD) tab
function TDdataDel(app)
app.TD_data = [];
app.MeasurementListBox.Items(:) = [];
app.SelectionListBox.Items(:) = [];
app.md1DesEditField.Value = '';
app.md2DesEditField.Value = '';
app.md3DesEditField.Value = '';
app.md4DesEditField.Value = '';
app.md1EditField.Value = 0;
app.md2EditField.Value = 0;
app.md3EditField.Value = 0;
app.md4EditField.Value = 0;
app.ds1DesEditField.Value = '';
app.ds2DesEditField.Value = '';
app.ds3DesEditField.Value = '';
app.ds3DesEditField.Value = '';
app.GeneralDateandTimeEditField.Value = '';
app.GeneralDescriptionEditField.Value = '';
app.GeneralInstrumentEditField.Value = '';
app.GeneralUserEditField.Value = '';
app.GeneralRefractiveIndexEditField.Value = 0;
app.GeneralEtalonEditField.Value = 0;
end
% plotTD_data plots the time domain data, choices can be made on plotting reference measurements only,
% sample measurements only or both reference and sample measurements;
% customisation on graph appearance (e.g. gridlines) can be made
function plotTD_data(app,axesNum)
plotList = app.TD_select;
plotType = app.ButtonGroupTD.SelectedObject.Text;
cnt = 1;
lgd = {};
if isequal(axesNum,"NEW")
% Create UIFigure and hide until all components are created
fig = figure('Visible', 'on');
fig.Position = [100 100 850 500];
fig.Name = "CaTSPer Time-domain Data";
% Create UIAxes
ax = uiaxes(fig);
xlabel(ax,"Time (ps)");
ylabel(ax,"E_{field intensity} (a.u.)");
ax.Box = 'on';
ax.LineWidth = 1;
ax.FontWeight = 'bold';
ax.Position = [10 10 800 450];
else
ax = axesNum;
% deleting graphics objects, that are specified by 'ax', from
% the axes
cla(ax)
end
showLegend = app.LegendButton_TD.Value;
cmap = app.ColorOrderDropDown_TD.Value;
cOrderFunction = str2func(cmap);
% deleting the legend
legend(ax,'off');
hold(ax,"on")
axis(ax,"tight");
% specifying number of different colours required for plotting
% as the number of items to be plotted
colorNum = length(plotList);
colorOrder = cOrderFunction(colorNum);
if isequal(plotType,'Both')
colorOrder = reshape(repmat(colorOrder',2,1), 3, 2*colorNum)';
end
% if 'app.GridOffButton_3.Value' = 1 (i.e. the button on the app
% is pressed), gridlines on the graph is turned off; otherwise,
% gridlines are displayed on the graphs
if app.GridOffButton_3.Value
grid(ax,"off")
else
grid(ax,"on")
end
% plotting all selected measurements (sample only,
% reference only or both sample and reference, depends on what one
% selects) in time domain
lgd = {};
ax.ColorOrder = colorOrder;
for idx = plotList
dsNum_Sample = app.TD_data.dsNum_Sample{idx};
dsNum_Reference = app.TD_data.dsNum_Reference{idx};
if isequal(dsNum_Reference,0)
app.ButtonGroupTD.SelectedObject = app.SampleButtonTD;
plotType = "Sample";
end
td_time = app.TD_data.ds{idx,dsNum_Sample}(1,:);
% extracting corresponding electric field intensity values
% for reference measurement
try
td_reference = app.TD_data.ds{idx,dsNum_Reference}(2,:);
catch
end
% extracting corresponding electric field intensity values
% for sample measurement
td_sample = app.TD_data.ds{idx,dsNum_Sample}(2,:);
% extracting sample name
sampleID = strjoin(app.TD_data.measList{idx});
% plotting graphs according one's selection
switch plotType
% plotting sample measurements only
case 'Sample'
plot(ax,td_time,td_sample,'linewidth',1);
lgd = [lgd; sampleID];
% plotting reference measurments only
case 'Reference'
plot(ax,td_time,td_reference,'linewidth',1);
lgd = [lgd; strcat(sampleID,'_Ref')];
% plotting both sample and reference measurements
otherwise
plot(ax,td_time,td_reference,td_time,td_sample,...
'linewidth',1);
lgd = [lgd; strcat(sampleID,'_Ref'); sampleID];
end
end
legend(ax,(lgd),'Interpreter','none');
if showLegend
legend(ax,"show");
else
legend(ax,"hide");
end
%%end
% the colour of each line is set by the color map
% auto-generated by the 'lines' function, which is a function of
% the required number of colours
hold(ax,"off")
end
% plotFD_data plots the frequency domain values, choices can be made on plotting reference
% measurements only, sample measurements only or both reference and sample measurements,
% customisation on graph appearance (e.g. gridlines) can be made
function plotFD_data(app,axesNum)
% extract datasets that are to be plotted
plotList = app.FD_select;
% extracting choice of plotting reference measurement only,
% sample measurement only or both reference and sample
% measurements
plotType = app.ButtonGroupFD.SelectedObject.Text;
% extracting choice of plotting amplitude or phase values
plotInfo = app.MagPhaseButtonGroup.SelectedObject.Text;
% extracting choice of plotting in log or linear scale
Yscale = app.YscaleButtonGroup.SelectedObject.Text;
cnt = 1;
lgd = {};
if isequal(axesNum,"NEW")
% Create UIFigure and hide until all components are created
fig = figure('Visible', 'on');
fig.Position = [100 100 850 500];
fig.Name = "CaTSPer Frequency-domain Data";
% Create UIAxes
ax = uiaxes(fig);
xlabel(ax,"Frequency (THz)");
ax.Box = 'on';
ax.LineWidth = 1;
ax.FontWeight = 'bold';
ax.Position = [10 10 800 450];
else
ax = axesNum;
end
% deleting graphics objects, that are specified by 'ax', from
% the axes
cla(ax)
% deleting the legend
legend(ax,'off');
hold(ax,"on")
% setting y-axis scale based on the selected choice of log or
% linear
ax.YScale = (Yscale);
showLegend = app.LegendButton_FD.Value;
cmap = app.ColorOrderDropDown_FD.Value;
cOrderFunction = str2func(cmap);
colorNum = length(plotList);
colorOrder = cOrderFunction(colorNum);
if isequal(plotType,'Both')
colorOrder = reshape(repmat(colorOrder',2,1), 3, 2*colorNum)';
end
ax.ColorOrder = colorOrder;
% if the 'grid off' button is selected, remove gridlines from
% the plot, otherwise gridlines will be displayed on the plot
if app.GridOffButton.Value
grid(ax,"off")
else
grid(ax,"on")
end
% plotting all selected measurements in frequency domain
for idx = plotList
fd_base = app.FD_data.frequency{idx} * 10^-12;
sampleID = app.FD_data.measList{idx};
% if amplitude is selected for plotting, extract the
% amplitude values for reference and sample measurements,
% and set the y-axis label and plot title to 'Amplitude'
if isequal(plotInfo,'Amplitude')
fd_reference = app.FD_data.ref_amplitude{idx};
fd_sample = app.FD_data.sam_amplitude{idx};
ylabel(ax,'E_{field intensity} (a.u.)');
title(ax,'Amplitude')
% if phase is selected for plotting instead, extract the
% phase values for reference and sample measurements,
% and set the y-axis label and plot title to 'Phase'
else
fd_reference = app.FD_data.ref_phase{idx};
fd_sample = app.FD_data.sam_phase{idx};
ylabel(ax,'Phase');
title(ax,'Phase')
end
% plotting graphs based on one's choices
switch plotType
% plotting sample measurements only
case 'Sample'
plot(ax,fd_base,fd_sample,'linewidth',1);
lgd = [lgd; sampleID];
% plotting reference measurements only
case 'Reference'
plot(ax,fd_base,fd_reference,'linewidth',1);
lgd = [lgd; strcat(sampleID,'_Ref')];
% plotting both sample and refeence measurements
otherwise
plot(ax,fd_base,fd_reference...
,fd_base,fd_sample,'linewidth',1);
lgd = [lgd; strcat(sampleID,'_Ref');sampleID];
end
end
% if only sample measurements are plotted, automatically display legend
% values as the measurement names
legend(ax,(lgd),'Location',"best",'Interpreter','none');
if showLegend
legend(ax,"show");
else
legend(ax,"hide");
end
hold(ax,"off")
end
% plotFD_data2 plots information (four possible options) extracted from terahertz data in
% frequency domain, and offers functionalities on customising graph appearance
function plotFD_data2(app,axesNum)
plotList = app.FD_select_2;
if isequal(axesNum,"NEW")
% Create UIFigure and hide until all components are
% created
fig = figure('Visible', 'on');
fig.Position = [100 100 850 500];
fig.Name = "CaTSPer Frequency-domain Data";
% Create UIAxes
ax = uiaxes(fig);
xlabel(ax,"Frequency (THz)");
ax.Box = 'on';
ax.LineWidth = 1;
ax.FontWeight = 'bold';
ax.Position = [10 10 800 450];
else
ax = axesNum;
end
% if no measurements are selected, no functions are executed
if isempty(plotList)
return;
end
% extracting the plot type selected (transmittance, absorption, refractive index or dielectric constant)
plotType = app.PlotDataButtonGroup.SelectedObject.Text;
% extracting the corresponding information to be plotted, this is
% different for different chosen plot types
plotInfo = app.MagPhaseButtonGroup_2.SelectedObject.Text;
% extracting the choice of plotting a linear or log graph
Yscale = app.YscaleButtonGroup_2.SelectedObject.Text;
% extracting the choice of plotting real or imaginary values
realImag = app.RealImagButtonGroup.SelectedObject.Text;
cnt = 1;
lgd = {};
% deleting graphics objects, that are specified by 'ax', from
% the axes
cla(ax)
% deleting the legend
legend(ax,'off');
hold(ax,"on")
% setting y-axis scale based on the selected parameter to be
% plotted
ax.YScale = (Yscale);
showLegend = app.LegendButton_FD.Value;
cmap = app.ColorOrderDropDown_FD.Value;
cOrderFunction = str2func(cmap);
colorNum = length(plotList);
colorOrder = cOrderFunction(colorNum);
ax.ColorOrder = colorOrder;
% if the 'grid off' button is selected, remove gridlines from
% the plot, otherwise gridlines will be displayed on the plot
if app.GridOffButton_2.Value
grid(ax,"off")
else
grid(ax,"on")
end
% if the size of the first dimension (row) of 'plotType' is 2, join
% all values on the first row of 'plotType' to form one single
% string
% if size(plotType,1) == 2;
% plotType = strjoin(plotType(1));
% end
for idx = plotList
% converting frequency values to THz
fd_base = app.FD_data.frequency{idx} * 10^-12;
% extracting sample name for legend
sampleID = app.FD_data.measList{idx};
lgd = [lgd; sampleID];
% if 'amplitude' option is chosen, plot amplitude values as
% y-values; and similarly for 'phase' option
if isequal(plotInfo,'Amplitude')
fd_transmit = app.FD_data.transmit_amplitude{idx};
ylabel(ax,'Amplitude');
else
fd_transmit = app.FD_data.transmit_phase{idx};
ylabel(ax,'Phase');
end
% plotting corresponding graphs based on selected option
switch plotType
% plotting amplitude/phase (depending on choice)
% against frequency
case "Transmittance"
plot(ax,fd_base,fd_transmit,'linewidth',1);
title(ax,'Transmittance');
% plotting absorption coefficient against frequency
case "Absorption Coefficient"
fd_absorption_coefficient = app.FD_data.absorption_coefficient{idx};
plot(ax,fd_base,fd_absorption_coefficient,'linewidth',1);
ylabel(ax,'Absorption Coefficient (cm^{-1})');
title(ax,'Absorption Coefficient');
case "Refractive Index"
% plotting real part of refractive index against frequency
if isequal(realImag,'Real')
fd_refIdx = app.FD_data.refractive_index{idx};
ylabel(ax,'n',"FontSize",13);
else
% plotting imaginary part of refractive index against frequency
fd_refIdx = app.FD_data.extinction_coefficient{idx};
ylabel(ax,'\kappa',"FontSize",13);
end
plot(ax,fd_base,fd_refIdx,'linewidth',1);
title(ax,'Refractive Index')
otherwise
% plotting real part of dielectric constant against frequency
if isequal(realImag,'Real')
fd_dielectric = app.FD_data.dielectric_constant_real{idx};
ylabel(ax,'\epsilon\prime',"FontSize",13);
% plotting imaginary part of dielectric constant against frequency
else
fd_dielectric = app.FD_data.dielectric_constant_imaginary{idx};
ylabel(ax,'\epsilon\prime\prime',"FontSize",13);
end
plot(ax,fd_base,fd_dielectric,'Linewidth',1);
title(ax,'Dielectric Constant');
end
end
% place legend in the most optimal location and display legend
% values as the measurement names
legend(ax,(lgd),'Location',"best",'Interpreter','none');
if showLegend
legend(ax,"show");
else
legend(ax,"hide");
end
hold(ax,"off")
end
% FD_PlotData_reset resets the buttons in FD data analysis tab to
% default, where the absorption, refractive index and dielectric
% constant functions are inactivated before measurements are added
function FD_PlotData_reset(app)
% app.TransmittanceButton.Enable = true;
app.AbsorptionCoefficientButton.Enable = false;
app.RefractiveIndexButton.Enable = false;
app.DielectricConstantButton.Enable = false;
end
% TDSunwrap unwraps the phase values from 0.8 THz (due to high SNR) to both directions,
% and then corrects the phase values in low THz (<0.1 THz) via
% linear extrapolation
function output = TDSunwrap(app,pData,freq)
% unwrapping functon
%freq = app.FD_data.frequency{idx};
strFreq = app.StartFrequencyTHzEditField.Value;
%unwrapping starting frequency: 0.8THz due to its high SNR
strFreq = strFreq * 1e12;
% find the index of the first element in 'freq' that has a value
% greater than 'srtFreq'
srtLoc = find(freq > strFreq,1);
% using srtLoc as a starting point, and in the order of increasing indices, unwrap phase values to the
% end of the data
pData1 = unwrap(pData(srtLoc:end));
% using srtLoc as a starting point, and in the order of decreasing indices, unwrap phase values to the
% start of the data
% this action reorders the data from back to front in pData2
pData2 = unwrap(pData(srtLoc:-1:1));
% reordering phase values, to from front to back, excluding the
% phase value at index strLoc, since its phase is already
% included in pData1
pData3 = pData2(end:-1:2);
% grouping all phase values into one single vector
pData = [pData3 pData1];
% default: extrapolate phase data from 0.2 to 0.4 THz to estimate the
% shift in phase and correct for it
% more noise seems to be resulted if the lower limit of the specified region
% takes a value less than 0.2 THz
epol_srtFreq = app.FromEpolFreqEditField.Value * 1e12;
epol_endFreq = app.ToEpolFreqEditField.Value * 1e12;
% find the index of the first element in 'freq' that has a value
% greater than 'epol_srtFreq'
epol_srtLoc = find(freq > epol_srtFreq,1);
% find the index of the first element in 'freq' that has a value
% greater than 'epol_endFreq'
epol_endLoc = find(freq > epol_endFreq,1);
% extracting frequency values from 'epol_srtFreq' to 'epol_endFreq'
epol_freq = freq(epol_srtLoc:epol_endLoc);
% extracting phase data that lies in frequency values from 'epol_srtFreq' to 'epol_endFreq'
epol_data = pData(epol_srtLoc:epol_endLoc);
% fitting a straight line of extracted phase against extracted
% frequency
p = polyfit(epol_freq,epol_data,1);
% find the intercept of the fitted line
shift = p(2); % y-axis intersection point value
% shift all phase data down by the intercept value
output = pData - shift;
end
% findDMPeaks finds peaks (the peak value and location) of the
% selected data sets based on specified parameters (e.g. minimum prominence value of peak)
function findDMPeaks(app)
% convert input values (specifying data sets) in text field from strings to numbers
dataList = str2num(app.SourceDataSetEditField.Value);
% extract the input minimum peak prominence value
pksProm = app.MinPeakProminenceEditField.Value;
% this parameter is not utilised in this version
lowLimit = app.LowerLimitTHzEditField.Value *10^12;
% extract peak number
pkNum = app.PeakNumSpinner.Value;
fig = app.CaTSperUIFigure;
ax = app.UIAxes9;
hold(ax,"on")
heightMat = [];
freqMat = [];
% if the 'DM_peaks' object is not empty, delete the object
if ~isempty(app.DM_peaks)
delete(app.DM_peaks);
end
% arrange y-axis data
for idx = dataList
% extracting frequency values in the data set
freq = app.FD_data.frequency{idx};
dmData = app.DM_data.base{idx};
% extracting calculated data management values (detailed
% later in another function) in the dataset
lb = sum(freq<=lowLimit); % lower boundary
if lb==0||lb==length(freq)
msg = strcat("Invalide lower limit");
app.LowerLimitTHzEditField.Value = 1;
uialert(fig,msg,'Warning');
return;
end
% finding peaks from dmData with freq as the x-vector, only
% peaks that has a prominence greater than 'pksProm' will be
% logged
[pks, locs] = findpeaks(dmData(lb:end),freq(lb:end),'MinPeakProminence',pksProm);
% if the specified number of peaks to be found is greater
% than the number of actual peaks found, display a warning
% message and reset the peak number to 1
if pkNum > length(pks)
msg = strcat('Cannot find Peak-',num2str(pkNum),' from Dataset-',num2str(idx));
uialert(fig,msg,'Warning');
app.PeakNumSpinner.Value = 1;
return;
end
% if peaks are found, collate peak maxima found from
% different data sets to one matrix, and similarly with the
% peak location, then plot the peaks and label them
if ~isempty(pks)
heightMat = [heightMat pks(pkNum)];
freqMat = [freqMat locs(pkNum)];
plot(ax,locs,pks,'o');
text(ax,locs+.1,pks,num2str((1:numel(pks))'));
end
end
hold(ax,"off")
% reversing the order of peak values and storing the values
app.DM_data.heightMat = flip(heightMat);
app.DM_data.freqMat = flip(freqMat);
end
% AdvFDbuttonsEnable enables/disables a set of buttons in the
% frequency domain tab
function AdvFDbuttonsEnable(app,tf)
app.AbsorptionCoefficientButton.Enable = tf;
app.RefractiveIndexButton.Enable = tf;
app.DielectricConstantButton.Enable = tf;
app.DataManagementButton.Enable = tf;
end
function timeDelay = getTimeDelay(app,ds1,ds2)
samTime = ds1(1,:);
samSig = ds1(2,:);
refTime = ds2(1,:);
refSig = ds2(2,:);
[Ref_max Ref_idx] = max(refSig);
maxPerLocs = find(refSig >(Ref_max*0.8));
maxLoc = maxPerLocs(round(length(maxPerLocs)/2));
time_shift = refTime(maxLoc);
refTime = refTime - time_shift;
samTime = samTime - time_shift;
Sam_max = max(samSig);
maxPerLocs = find(samSig >(Sam_max*0.8));
maxLoc = maxPerLocs(round(length(maxPerLocs)/2));
timeDelay = (round(samTime(maxLoc)*10^3))/10^3;
end
function loadDefaultSettings(app)
try
configData = jsondecode(fileread(app.configFile));
catch ME
fig = app.CaTSperUIFigure;
uialert(fig, sprintf('Failed to read config_default.json: %s', ME.message), 'Error');
return;
end
app.DR_boundary = configData.FFT_Settings.DR_boundary; % dynamic range frequency boundary
% Default FFT_Settings
app.FromFreqEditField.Value = configData.FFT_Settings.Frequency_Range(1);
app.ToFreqEditField.Value = configData.FFT_Settings.Frequency_Range(2);
app.ZeroFillingpowerofSpinner.Value = configData.FFT_Settings.FFT_Upsampling;
app.StartFrequencyTHzEditField.Value = configData.FFT_Settings.Unwrapping_Start_Frequency;
app.FromEpolFreqEditField.Value = configData.FFT_Settings.Extrapolation_Frequency_Range(1);
app.ToEpolFreqEditField.Value = configData.FFT_Settings.Extrapolation_Frequency_Range(2);
app.FromTimeEditField.Value = configData.FFT_Settings.Window_Function_Range(1);
app.ToTimeEditField.Value = configData.FFT_Settings.Window_Function_Range(2);
app.FunctionDropDown.Value = configData.FFT_Settings.Apodisation_Function;
% Default thickness metadata
app.mdSampleThicknessDropDown.Value = configData.Metadata_Settings.Sample_Thickness;
app.mdReferenceThicknessDropDown.Value = configData.Metadata_Settings.Reference_Thickness;
app.ThicknessDropDown.Value = configData.Metadata_Settings.Thickness_Unit;
% Default sample and referenece dataset
app.dsSampleDropDown.Value = configData.Dataset_Settings.Sample;
app.dsReferenceDropDown.Value = configData.Dataset_Settings.Reference;
app.dsPumpedDropDown.Value = configData.Dataset_Settings.Pump;
end
function mdThicknessSync(app,measIdx)
mdNum_SamThickness = app.TD_data.metadata{measIdx}.mdNum_SamThickness;
mdNum_RefThickness = app.TD_data.metadata{measIdx}.mdNum_RefThickness;
if isequal(mdNum_SamThickness,0)
sam_thickness = 0;
else
sam_thickness = app.TD_data.metadata{measIdx}.md{mdNum_SamThickness};
end
if isequal(mdNum_RefThickness,0)
ref_thickness = 0;
else
ref_thickness = app.TD_data.metadata{measIdx}.md{mdNum_RefThickness};
end
if isempty(ref_thickness)||isempty(sam_thickness)
fig = app.CaTSperUIFigure;
uialert(fig,'Invalide Metadata','Warning');