#=============================================== # TkOpticalSpectrumEMAMultiLayersRT #=============================================== package TkOpticalSpectrumEMAMultiLayersRT; use clib::TkEllipsometry; @ISA = qw(TkEllipsometry); #公開したいサブルーチン #@EXPORT = qw(DelSpace Reduce01 MakePath RegExpQuote); use strict; use Sci qw($pi $kB $c $e $e0 $me $mp $mn $h $hbar $torad $todeg); use MyTk::MyDragDrop; #============================================================ # 変数等取得関数 #============================================================ #============================================================ # コンストラクタ、デストラクタ #============================================================ #============================================================ # 継承クラスで定義しなおす関数 #============================================================ sub CreateWidgets { my ($this) = @_; my $App = $this->App(); my $args = $App->Args(); $this->{ini} = new IniFile(undef, 0, 0); $this->{dini} = new IniFile(undef, 0, 0); $this->{Ellipsometry} = new Ellipsometry; $this->SUPER::CreateWidgets(1); my $Title = "OpticalSpectrumFit2008 for Films(EMA)/Substrate RT / TkPlot"; $this->mw()->SetTitle($Title); $this->App()->SetProgram($Title); $this->{ini}->pVariable("nFilmLayers", 1); $this->{ini}->pVariable("nComponents", 3); $this->{ini}->pVariable("nLorentz", 5); $this->{ini}->pVariable("nDrude", 1); my $nf = $args->GetGetArg("nFilmLayers"); my $nc = $args->GetGetArg("nComponents"); my $nl = $args->GetGetArg("nLorentz"); my $nd = $args->GetGetArg("nDrude"); $this->{ini}->{nFilmLayers} = $nf if(defined $nf and $nf ne ''); $this->{ini}->{nComponents} = $nc if(defined $nc and $nc ne ''); $this->{ini}->{nLorentz} = $nl if(defined $nl and $nl ne ''); $this->{ini}->{nDrude} = $nd if(defined $nd and $nd ne ''); for(my $i = 1 ; $i <= $this->{ini}->{nFilmLayers} ; $i++) { $this->AddParameters($this->{ini}, $this->{dini}, "Film${i}Thickness", 100.0, 0,100.0e-9, 0.0, ''); } for(my $i = 1 ; $i <= $this->{ini}->{nComponents} ; $i++) { my $v = 1.0; $v = 0.0 if($i > 1); $this->AddParameters($this->{ini}, $this->{dini}, "Vf$i", $v, 0, 0.01, 0.0, 1.0); } #=================================================== # ペインを作製 #=================================================== my $EntryWidth = $this->{EntryWidth} = 12; my $TabWidth = 100; $this->mw()->{NoteBook} = $this->mw()->NoteBook()->pack(-fill => 'both', -expand => 'yes'); $this->mw()->{MainPage} = $this->mw()->{NoteBook}->add("Main", -label => 'Main', -justify => 'left', -wraplength => $TabWidth); $this->mw()->{MainPaneFrame} = $this->mw()->{MainPage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->mw()->{LayersPage} = $this->mw()->{NoteBook}->add("Layers", -label => 'Layers', -justify => 'left', -wraplength => $TabWidth); my $Frame = $this->mw()->{LayersPage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $lsb1 = $this->{ChooseNFilmeLayerListBox} = $Frame->MyBrowseEntry( -label => "# of Film Layers:", -state => "readonly", -takefocus => 1, -width => 2, -Selections => [qw(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)], -SelIndex => $this->{ini}->{nFilmLayers}, )->pack(-side => 'left'); #grid(-row => 0, -column => 0, -columnspan => 1, -sticky => 'e' ); $lsb1->configure(-browsecmd => sub { $this->{ini}->{nFilmLayers} = $this->{ChooseNFilmeLayerListBox}->GetText(); # + 0; $this->RefreshMainPane($EntryWidth, @_); $this->RefreshLayersPane($EntryWidth, @_); $this->RefreshMiscParamConditionPane($EntryWidth, @_); } ); $lsb1 = $this->{ChooseNLorentzListBox} = $Frame->MyBrowseEntry( -label => "Lorentz functions:", -state => "readonly", -takefocus => 1, -width => 2, -Selections => [qw(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)], -SelIndex => $this->{ini}->{nLorentz}-1, )->pack(-side => 'left'); #grid(-row => 0, -column => 0, -columnspan => 1, -sticky => 'e' ); $lsb1->configure(-browsecmd => sub { $this->{ini}->{nLorentz} = $this->{ChooseNLorentzListBox}->GetText(); # + 0; $this->RefreshMainPane($EntryWidth, @_); $this->RefreshLorentzParamConditionPane($EntryWidth, @_); } ); $lsb1 = $this->{ChooseNDrudeListBox} = $Frame->MyBrowseEntry( -label => "Drude functions:", -state => "readonly", -takefocus => 1, -width => 2, -Selections => [qw(1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)], -SelIndex => $this->{ini}->{nDrude}-1, )->pack(-side => 'left'); #grid(-row => 0, -column => 0, -columnspan => 1, -sticky => 'e' ); $lsb1->configure(-browsecmd => sub { $this->{ini}->{nDrude} = $this->{ChooseNDrudeListBox}->GetText(); # + 0; $this->RefreshMainPane($EntryWidth, @_); $this->RefreshDrudeParamConditionPane($EntryWidth, @_); } ); $this->mw()->{LayersPaneFrame} = $this->mw()->{LayersPage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->mw()->{ViewRangePage} = $this->mw()->{NoteBook}->add("ViewRange", -label => 'ViewRange', -justify => 'left', -wraplength => $TabWidth); $this->mw()->{ViewRangePaneFrame} = $this->mw()->{ViewRangePage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->mw()->{LSQPage} = $this->mw()->{NoteBook}->add("LSQ", -label => 'LSQ');#, -justify => 'left', -wraplength = > $TabWidth); $this->mw()->{LSQPaneFrame} = $this->mw()->{LSQPage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); foreach my $key qw(Misc Lorentz Drude) { my $title = $key; $title = 'Common' if($key eq 'Misc'); $this->mw()->{"${key}ParamConditionPage"} = $this->mw()->{NoteBook}->add("$key Params", -label => $title, -justify => 'left', -wraplength => $TabWidth); $this->mw()->{"${key}ParamConditionPaneFrame"} = $this->mw()->{"${key}ParamConditionPage"}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); } $this->mw()->{GraphFramePage} = $this->mw()->{NoteBook}->add("GraphFrame", -label => 'GraphFrame'); $this->mw()->{GraphFramePaneFrame} = $this->mw()->{GraphFramePage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->BuildMainPane($this->mw()->{MainPaneFrame}, $EntryWidth); $this->BuildLayersPane($this->mw()->{LayersPaneFrame}, $EntryWidth); $this->BuildViewRangePane($this->mw()->{ViewRangePaneFrame}, $EntryWidth); $this->BuildLSQPane($this->mw()->{LSQPaneFrame}, $EntryWidth); $this->BuildMiscParamConditionPane($this->mw()->{MiscParamConditionPaneFrame}, $EntryWidth); $this->BuildLorentzParamConditionPane($this->mw()->{LorentzParamConditionPaneFrame}, $EntryWidth); $this->BuildDrudeParamConditionPane($this->mw()->{DrudeParamConditionPaneFrame}, $EntryWidth); $this->BuildGraphFramePane($this->mw()->{GraphFramePaneFrame}, $EntryWidth); #ツールバーのOpenボタンをファイル読み込みにバインドする $this->mw()->{OpenButton}->configure( -command => sub { $this->ChooseFile('Sample2CSVFile', $this->{SPEFileFileEntry}); }, ) if($this->mw()->{OpenButton}); my $DragDrop = new MyDragDrop(); $DragDrop->ConfigureDrop( $this->mw(), [ "\\.prm\$", $this->{ParamFileEntry}, sub { $this->ReadParameterFile($_[0]); }, ], [ ".*", $this->{Sample1CSVFileEntry}, sub { $this->{Sample1CSVFileEntry}->SetText($_[0]); $this->ReadSampleDataFile($_[0], 1, 1); }, ], ); } sub BuildViewRangePane { my ($this, $MainFrame, $EntryWidth) = @_; $this->SUPER::BuildViewRangePane($MainFrame, $EntryWidth, [ ['x'], ['x'] ], [ ['x'], ['x', 'log(|x|)', '(ahv)^1/2 (Tauc)', 'a^1/2 (Indirect)', 'a^2 (Direct'] ] ); $MainFrame->{GraphFrame1YAxisListBox}->SetText('log(|x|)') if($MainFrame->{GraphFrame1YAxisListBox}); $this->BuildFooter($MainFrame, $EntryWidth); } sub BuildFooter { my ($this, $MainFrame, $EntryWidth) = @_; my $Frame1 = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $ButtonFrame = $this->MakeFittingButtons($Frame1, ("Re&calc", "&Fit", "Point By Point", "Save for &SCOUT", "Save Layers", "Save Eps")); $ButtonFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); $ButtonFrame = $this->MakeFittingButtons($Frame1, ("RePlot", "RestoreScale")); $ButtonFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); } sub BuildGraphFramePane { my ($this, $MainFrame, $EntryWidth) = @_; my $App = $this->App(); my $IniFile = $App->IniFile(); my $Style = $App->Args()->GetGetArg("style"); $Style = "General" unless($Style); for(my $i = 0 ; ; $i++) { last if(!$App->{"GraphFrame${i}Position"}); my $i1 = $i + 1; my $Frame = $MainFrame->MyFrame()->pack(-fill => 'x'); $Frame->MyLabel(-text => "GraphFrame$i:")->pack(-side => 'left'); $Frame->MyEntry( -textvariable => \$App->{"GraphFrame${i}Position"}, #\$PositionStr[$i], -state => 'normal', -format => '%s', -takefocus => 1, )->pack(-side => 'left', -fill => 'x'); } my $Frame = $MainFrame->MyFrame()->pack(-fill => 'x'); $Frame->MyButton( -text => 'Save', -takefocus => 1, -command => sub { $App->SaveSetting(); $this->CreateGraphFrame(undef, undef, 1); $this->RePlot(1); }, )->pack(-side => 'left'); } sub BuildDrudeParamConditionPane { my ($this, $MainFrame, $EntryWidth) = @_; my $Frame = $MainFrame->MyLabFrame( -label => 'Drude parameters', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); my $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); for(my $i = 0 ; $i < $this->{ini}->{nDrude} ; $i++) { my $i1 = $i + 1; $this->MakeParameterConditionColumn($Frame, "DrudeEp${i1}", "Ep[${i1}]:", "%12.6g", 0.0, 0, 0.1, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "Drudetau${i1}", "tau[${i1}]:", "%12.6g", 1.0e-14, 0, 1.0e-15, 0.0, '', $EntryWidth, $row++); } } sub BuildLorentzParamConditionPane { my ($this, $MainFrame, $EntryWidth) = @_; my $Frame = $MainFrame->MyLabFrame( -label => 'Lorentz parameters', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); my $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); for(my $i = 0 ; $i < $this->{ini}->{nLorentz} ; $i++) { my $i1 = $i + 1; $this->MakeParameterConditionColumn($Frame, "E0${i1}", "E0[${i1}]:", "%12.6g", 2.64, 0, 0.1, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "Ne${i1}", "Ne[${i1}]:", "%12.6g", 2e26, 0, 1e26, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "G${i1}", "G[${i1}]:", "%12.6g", 0.5, 0, 0.1, 0.0, '', $EntryWidth, $row++); } } sub BuildMiscParamConditionPane { my ($this, $MainFrame, $EntryWidth) = @_; my $Frame = $MainFrame->MyLabFrame( -label => 'Common parameters', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); my $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); $this->MakeParameterConditionColumn($Frame, "SurfaceThickness", "Surface thickness:", "%12.6g", 0.0, 0, 1.0e-9, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "SurfaceVf", "Vf:", "%12.6g", 1.0, 0, 0.1, 0.0, 1.0, $EntryWidth, $row++); for(my $i = $this->{ini}->{nFilmLayers} ; $i >= 1 ; $i--) { $this->MakeParameterConditionColumn($Frame, "Film${i}Thickness", "Film${i} thickness:", "%12.6g", 100.0, 1, 10.0e-9, 0.0, '', $EntryWidth, $row++); } $this->MakeParameterConditionColumn($Frame, "SubstrateThickness", "Substrate thickness:", "%12.6g", 0.5, 0, 0.1, 0.0, '', $EntryWidth, $row++); $Frame = $MainFrame->MyLabFrame( -label => 'Scattering', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); $this->MakeParameterConditionColumn($Frame, "Scale", "T scale:", "%12.6g", 1.0, 0, 0.1, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "RScale", "R scale:", "%12.6g", 1.0, 0, 0.1, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "Rayleighl0", "Rayleigh lamba0:", "%12.6g", 0.0, 0, 0.1, 0.0, '', $EntryWidth, $row++); $Frame = $MainFrame->MyLabFrame( -label => 'Dielectric background', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); $this->MakeParameterConditionColumn($Frame, "e1inf", "e1:", "%12.6g", 0.155, 1, 0.1, '', '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "e2inf", "e2:", "%12.6g", 0.0, 0, 0.1, '', '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "Caucy2", "Caucy2:", "%12.6g", 0.0, 0, 0.1, '', '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "Caucy4", "Caucy4:", "%12.6g", 0.0, 0, 0.1, '', '', $EntryWidth, $row++); $Frame = $MainFrame->MyLabFrame( -label => 'Tauc-Lorentz', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); $this->MakeParameterConditionColumn($Frame, "A", "A:", "%12.6g", 122.8, 0, 10.0, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "C", "C:", "%12.6g", 10.8, 0, 1.0, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "Eg", "Eg:", "%12.6g", 4.4, 0, 0.5, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "En0", "En0:", "%12.6g", 155.9, 0, 1.0, 0.0, '', $EntryWidth, $row++); $Frame = $MainFrame->MyLabFrame( -label => 'EMA', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); for(my $i = 1 ; $i <= $this->{ini}->{nComponents} ; $i++) { my $v = 1.0; $v = 0.0 if($v > 1); $this->MakeParameterConditionColumn($Frame, "Vf$i", "Vf$i:", "%12.6g", $v, 0, 0.1, 0.0, 1.0, $EntryWidth, $row++); } } sub BuildLSQPane { my ($this, $MainFrame, $EntryWidth) = @_; my $Frame = $MainFrame->MyLabFrame( -label => 'Fitting', -labelside => 'acrosstop', )->pack(-anchor => 'nw', -fill => 'x'); my $lsb4 = $this->{ChooseLSQMethodListBox} = $Frame->MyBrowseEntry( -label => "LSQ Method:", -state => "readonly", -takefocus => 1, -width => 5, -Selections => ['Amoeba::Simplex', 'PDL::Simplex', 'ModifiedNewton'], -SelIndex => 0, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $lsb4->configure(-browsecmd => [\&SelChangeListBox, $this, "LSQMethod", $this->{ChooseLSQMethodListBox}]); my $lsb5 = $this->{ChooseFitToListBox} = $Frame->MyBrowseEntry( -label => "Fit to:", -state => "readonly", -takefocus => 1, -width => 5, -Selections => ['RT', 'R', 'T'], -SelIndex => 0, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $Frame = $MainFrame->MyLabFrame( -label => 'Fitting2', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); my $Frame1 = $Frame->MyFrame()->pack(-anchor => 'nw'); $this->MakeFittingRangeFrame($Frame1, 'FitEmin', 'Emin:', $this->{ini}->pVariable('FitEmin', ''), "%s", "eV", 'FitEmax', 'Emax:', $this->{ini}->pVariable('FitEmax', ''), "%s", "eV", 'nSkipData', 'nSkip:', $this->{ini}->pVariable('nSkipData', 2), "%d", "", $EntryWidth); $Frame1 = $Frame->MyFrame()->pack(-anchor => 'nw'); $this->MakeLabelEntry($Frame1, "EPS", "EPS:", $this->{ini}->pVariable('EPS', 1.0e-5), "%12.4g", $EntryWidth, "", 1, 0); $this->MakeLabelEntry($Frame1, "nMaxIter", "MaxIter:", $this->{ini}->pVariable('nMaxIter', 1000), "%d", $EntryWidth, "", 1, 1); $this->MakeLabelEntry($Frame1, "nSaveSpectraInterval", "SaveIntvl:", $this->{ini}->pVariable('nSaveSpectraInterval', 10), "%d", $EntryWidth, "", 1, 2); $this->BuildFooter($MainFrame, $EntryWidth); } sub BuildLayersPane { my ($this, $MainFrame, $EntryWidth) = @_; my $iTop = $this->{ini}->{nFilmLayers}; my $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->MakeChooseFileEntry($Frame, 'Param', 'Param:', $this->{ini}->pVariable("ParameterFile", ""), '&Choose', sub { $this->ChooseFile(@_); }, "ChooseParameterFile"); $this->{SaveParamButton} = $Frame->MyButton( -text => '&Save', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', 'SaveParam'); }, )->pack(-side => 'left'); $this->{EditParamButton} = $Frame->MyButton( -text => 'ed', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', 'EditParam'); }, )->pack(-side => 'left'); $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); if($this->{ini}->{nFilmLayers} > 0) { $this->MakeChooseFileEntry($Frame, "Sample${iTop}CSV", "Sample:", $this->{ini}->pVariable("Sample${iTop}CSVFile", ""), '&Choose', sub { $this->ChooseFile(@_); }, "ChooseSample${iTop}File"); $this->{EditDataButton} = $Frame->MyButton( -text => 'ed', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', "EditSample${iTop}CSV"); }, )->pack(-side => 'left'); } for(my $i = $this->{ini}->{nFilmLayers}-1 ; $i >= 1 ; $i--) { $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->MakeChooseFileEntry($Frame, "Sample${i}CSV", "Film${i}:", $this->{ini}->pVariable("Sample${i}CSVFile", ""), '&Choose', sub { $this->ChooseFile(@_); }, "ChooseSample${i}File"); $this->{EditDataButton} = $Frame->MyButton( -text => 'ed', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', "EditSample${i}CSV"); }, )->pack(-side => 'left'); } $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->MakeChooseFileEntry($Frame, 'SubstrateCSV', 'Substrate:', $this->{ini}->pVariable("SubstrateCSVFile", ""), '&Choose', sub { $this->ChooseFile(@_); }, "ChooseSubstrateFile"); $this->{EditDataButton} = $Frame->MyButton( -text => 'ed', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', 'EditSubstrateCSV'); }, )->pack(-side => 'left'); $Frame = $MainFrame->MyLabFrame( -label => 'EMA', -labelside => 'acrosstop', )->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); my $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->{ChooseEMAModelListBox} = $ChildFrame->MyBrowseEntry( -label => "EMA model:", -state => "readonly", -takefocus => 1, -width => 15, -Selections => ['Maxwell-Garnett', 'Bruggemann', 'Average'], -SelIndex => 0, )->pack(-side => 'left'); #grid(-row => 0, -column => 0, -columnspan => 1, -sticky => 'e' ); $this->{ini}->{Vf1} = 1.0 if(!defined $this->{ini}->{Vf1}); for(my $i = 1 ; $i <= $this->{ini}->{nComponents} ; $i++) { my $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $ii = $i; $this->MakeChooseFileEntry($ChildFrame, "Component${ii}CSV", "Component${ii}:", $this->{ini}->pVariable("Component${ii}CSVFile", ""), '&Choose', sub { $this->ChooseFile(@_); }, "ChooseComponent${ii}File"); $this->{EditDataButton} = $ChildFrame->MyButton( -text => 'ed', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', "EditComponent${ii}CSV"); }, )->pack(-side => 'left'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw');#, -fill => 'x'); $this->MakeCheckEntry($ChildFrame, "Vf${ii}", "Vf:", $this->{dini}->pVariable("Vf${ii}check", 0) , $this->{ini}->pVariable("Vf${ii}", 0.0), "%12.6g", $EntryWidth, "", 0, 0); } my $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw');#, -fill => 'x'); $this->MakeLabelEntry($ChildFrame, "KVf", "KVf:", $this->{ini}->pVariable("KVf", 1000.0), "%12.6g", $EntryWidth, "", 0, 0); $Frame = $MainFrame->MyLabFrame( -label => 'Structure', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); my $Frame1 = $Frame->MyFrame()->pack(-anchor => 'nw'); $this->MakeLabelEntry($Frame1, "TAngle", "TAngle:", $this->{ini}->pVariable('TAngle', 0.0), "%8.4f", $EntryWidth, "deg", 0, 0); $this->MakeLabelEntry($Frame1, "RAngle", "RAngle:", $this->{ini}->pVariable('RAngle', 0.0), "%8.4f", $EntryWidth, "deg", 0, 1); $Frame1 = $Frame->MyFrame()->pack(-anchor => 'nw'); my $lsb6 = $this->{ChooseLayerModelListBox} = $Frame1->MyBrowseEntry( -label => "Layer Model:", -state => "readonly", -takefocus => 1, -width => 20, -Selections => ["Films/Substrate", "Surface(EMA)/Films/Substrate", "Films/Interface(EMA)/Substrate"], -SelIndex => 0, )->grid(-row => 0, -column => 3, -columnspan => 1, -sticky => 'e' ); $lsb6->configure(-browsecmd => [\&SelChangeListBox, $this, "LayerModel", $this->{ChooseLayerModelListBox}]); $Frame1 = $Frame->MyFrame()->pack(-anchor => 'nw'); $this->MakeCheckEntry($Frame1, "SurfaceThickness", "Surface thickness:", $this->{dini}->pVariable('SurfaceThicknesscheck', 1), $this->{ini}->pVariable('SurfaceThickness', 0.0), "%12.6g", $EntryWidth, "nm", 0, 0); $this->MakeCheckEntry($Frame1, "SurfaceVf", "Vf:", $this->{dini}->pVariable('SurfaceVfcheck', 0), $this->{ini}->pVariable('SurfaceVf', 1.0), "%12.6g", $EntryWidth, "", 0, 1); for(my $i = $this->{ini}->{nFilmLayers} ; $i >= 1 ; $i--) { $this->MakeCheckEntry($Frame1, "Film${i}Thickness", "Film${i} thickness:", $this->{dini}->pVariable("Film${i}Thicknesscheck", 1), $this->{ini}->pVariable("Film${i}Thickness", 100.0), "%12.6g", $EntryWidth, "nm", $this->{ini}->{nFilmLayers}-$i+1, 0); } $Frame1 = $Frame->MyFrame()->pack(-anchor => 'nw'); $this->MakeCheckEntry($Frame1, "SubstrateThickness", "Substrate thickness:", $this->{dini}->pVariable('SubstrateThicknesscheck', 0), $this->{ini}->pVariable('SubstrateThickness', 0.5), "%12.6g", $EntryWidth, "mm", 0, 1); $this->BuildFooter($MainFrame, $EntryWidth); } sub BuildMainPane { my ($this, $MainFrame, $EntryWidth) = @_; my $iTop = $this->{ini}->{nFilmLayers}; my $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->MakeChooseFileEntry($Frame, 'Param', 'Param:', $this->{ini}->pVariable("ParameterFile", ""), '&Choose', sub { $this->ChooseFile(@_); }, "ChooseParameterFile"); $this->{SaveParamButton} = $Frame->MyButton( -text => '&Save', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', 'SaveParam'); }, )->pack(-side => 'left'); $this->{EditParamButton} = $Frame->MyButton( -text => 'ed', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', 'EditParam'); }, )->pack(-side => 'left'); $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $lsb1 = $this->{ChooseXListBox} = $Frame->MyBrowseEntry( -label => "X:", -state => "readonly", -takefocus => 1, -width => 5, -Selections => [], -SelIndex => 0, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $lsb1->configure(-browsecmd => [\&SelChangeListBox, $this, "X", $this->{ChooseXListBox}]); my $lsb2 = $this->{ChooseY1ListBox} = $Frame->MyBrowseEntry( -label => "Y1:", -state => "readonly", -takefocus => 1, -width => 5, -Selections => [], -SelIndex => 1, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $lsb2->configure(-browsecmd => [\&SelChangeListBox, $this, "Y1", $this->{ChooseY1ListBox}]); my $lsb3 = $this->{ChooseY2ListBox} = $Frame->MyBrowseEntry( -label => "Y2:", -state => "readonly", -takefocus => 1, -width => 5, -Selections => [], -SelIndex => 2, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $lsb3->configure(-browsecmd => [\&SelChangeListBox, $this, "Y2", $this->{ChooseY2ListBox}]); $Frame = $MainFrame->MyLabFrame( -label => 'Fitting', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $this->MakeFittingRangeFrame($Frame, 'FitEmin', 'Emin:', $this->{ini}->pVariable('FitEmin', ''), "%s", "eV", 'FitEmax', 'Emax:', $this->{ini}->pVariable('FitEmax', ''), "%s", "eV", 'nSkipData', 'nSkip:', $this->{ini}->pVariable('nSkipData', 2), "%d", "", $EntryWidth); if($this->{ini}->{nFilmLayers} > 0) { my $Frame1 = $MainFrame->MyLabFrame( -label => 'Structure', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $this->MakeCheckEntry($Frame1, "Film${iTop}Thickness", "Film${iTop} thickness:", $this->{dini}->pVariable("Film${iTop}Thicknesscheck", 1), $this->{ini}->pVariable("Film${iTop}Thickness", 100.0), "%12.6g", $EntryWidth, "nm", 0, 0); } my $Frame1 = $MainFrame->MyFrame()->pack(-anchor => 'nw'); $Frame = $MainFrame->MyLabFrame( -label => 'Scattering', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $this->MakeCheckEntry($Frame, "RScale", "R scale:", $this->{dini}->pVariable('RScalecheck', 1.0) , $this->{ini}->pVariable('RScale', 1.0), "%12.6g", $EntryWidth-4, "", 0, 0); $this->MakeCheckEntry($Frame, "Scale", "T scale:", $this->{dini}->pVariable('Scalecheck', 1.0) , $this->{ini}->pVariable('Scale', 1.0), "%12.6g", $EntryWidth-4, "", 0, 1); $this->MakeCheckEntry($Frame, "Rayleighl0", "Rayleigh lamba0:", $this->{dini}->pVariable('Rayleighl0check', 0) , $this->{ini}->pVariable('Rayleighl0', 0.0), "%12.6g", $EntryWidth-2, "", 0, 2); $Frame = $MainFrame->MyLabFrame( -label => 'Dielectric background', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $this->MakeCheckEntry($Frame, "e1inf", "e1:", $this->{dini}->pVariable('e1infcheck', 1) , $this->{ini}->pVariable('e1inf', 0.155), "%12.6g", $EntryWidth, "e0", 0, 0); $this->MakeCheckEntry($Frame, "e2inf", "e2:", $this->{dini}->pVariable('e2infcheck', 0) , $this->{ini}->pVariable('e2inf', 0.0 ), "%12.6g", $EntryWidth, "e0", 0, 1); $this->MakeCheckEntry($Frame, "Caucy2", "Caucy2:", $this->{dini}->pVariable('Caucy2check', 0) , $this->{ini}->pVariable('Caucy2', 0.0), "%12.6g", $EntryWidth, "", 1, 0); $this->MakeCheckEntry($Frame, "Caucy4", "Caucy4:", $this->{dini}->pVariable('Caucy4check', 0) , $this->{ini}->pVariable('Caucy4', 0.0), "%12.6g", $EntryWidth, "", 1, 1); $Frame = $MainFrame->MyLabFrame( -label => 'Tauc-Lorentz', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $this->MakeCheckEntry($Frame, "A", "A:", $this->{dini}->pVariable('Acheck', 0) , $this->{ini}->pVariable('A', 122.8), "%12.6g", $EntryWidth, "", 0, 0); $this->MakeCheckEntry($Frame, "C", "C:", $this->{dini}->pVariable('Ccheck', 0) , $this->{ini}->pVariable('C', 10.8), "%12.6g", $EntryWidth, "", 0, 1); $this->MakeCheckEntry($Frame, "Eg", "Eg:", $this->{dini}->pVariable('Egcheck', 0) , $this->{ini}->pVariable('Eg', 4.4), "%12.6g", $EntryWidth, "eV", 1, 0); $this->MakeCheckEntry($Frame, "En0", "En0:", $this->{dini}->pVariable('En0check', 0) , $this->{ini}->pVariable('En0', 155.9), "%12.6g", $EntryWidth, "eV", 1, 1); $Frame = $MainFrame->MyLabFrame( -label => "Lorentz", -labelside => 'acrosstop', )->pack(-anchor => 'nw'); for(my $i = 0 ; $i < $this->{ini}->{nLorentz} ; $i++) { my $i1 = $i + 1; $this->MakeCheckEntry($Frame, "E0${i1}", "E0:", $this->{dini}->pVariable("E0${i1}check", 0), $this->{ini}->pVariable("E0${i1}", 2.64), "%12.6g", $EntryWidth, "eV", $i, 0); $this->MakeCheckEntry($Frame, "Ne${i1}", "Ne:", $this->{dini}->pVariable("Ne${i1}check", 0), $this->{ini}->pVariable("Ne${i1}", 2e26), "%12.6g", $EntryWidth, "m-3", $i, 1); $this->MakeCheckEntry($Frame, "G${i1}", "G:", $this->{dini}->pVariable("G${i1}check", 0), $this->{ini}->pVariable("G${i1}", 2.64), "%12.6g", $EntryWidth, "eV", $i, 2); } $Frame = $MainFrame->MyLabFrame( -label => "Drude", -labelside => 'acrosstop', )->pack(-anchor => 'nw'); my $nc = 0; for(my $i = 0 ; $i < $this->{ini}->{nDrude} ; $i++) { my $i1 = $i + 1; $this->MakeCheckEntry($Frame, "DrudeEp${i1}", "Ep:", $this->{dini}->pVariable("DrudeEp${i1}check", 0), $this->{ini}->pVariable("DrudeEp${i1}", 0.0), "%12.6g", $EntryWidth, "eV", $i, 0); $this->MakeCheckEntry($Frame, "Drudetau${i1}", "tau:", $this->{dini}->pVariable("Drudetau${i1}check", 0), $this->{ini}->pVariable("Drudetau${i1}", 1.0e-14), "%12.6g", $EntryWidth, "s", $i, 1); $nc++; } # $Frame = $MainFrame->MyLabFrame( # -label => "Constrants", # -labelside => 'acrosstop', # )->pack(-anchor => 'nw'); $this->MakeLabelEntry($Frame, "Mobility", "mobility:", $this->{ini}->pVariable("Mobility", 0.0), "%12.6g", $EntryWidth, "cm2/Vs", $nc+0, 0); $this->MakeCheckEntry($Frame, "KMobility", "K:", $this->{dini}->pVariable("KMobilitycheck", 0), $this->{ini}->pVariable("KMobility", 0.01), "%12.6g", $EntryWidth, "", $nc+0, 1); $this->MakeLabelEntry($Frame, "MobilityCal", "(", $this->{ini}->pVariable("MobilityCal", 0.0), "%12.6g", $EntryWidth, ")", $nc+0, 2, "disable"); $this->MakeLabelEntry($Frame, "Ne", "Ne:", $this->{ini}->pVariable("Ne", 0.0), "%12.6g", $EntryWidth, "cm-3", $nc+1, 0); $this->MakeLabelEntry($Frame, "EffMass", "m*:", $this->{ini}->pVariable("EffMass", 0.0), "%12.6g", $EntryWidth, "me", $nc+1, 1, "disable"); $this->MakeLabelEntry($Frame, "Conductivity", "conductivity:", $this->{ini}->pVariable("Conductivity", 0.0), "%12.6g", $EntryWidth, "S/cm", $nc+2, 0); $this->MakeCheckEntry($Frame, "KConductivity", "K:", $this->{dini}->pVariable("KConductivitycheck", 0), $this->{ini}->pVariable("KConductivity", 0.01), "%12.6g", $EntryWidth, "", $nc+2, 1); $this->MakeLabelEntry($Frame, "ConductivityCal", "(", $this->{ini}->pVariable("ConductivityCal", 0.0), "%12.6g", $EntryWidth, ")", $nc+2, 2, "disable"); $Frame = $MainFrame->MyLabFrame( -label => "Point by Point", -labelside => 'acrosstop', )->pack(-anchor => 'nw'); my $button = $Frame->MyCheckbutton( -text => "Allow Negative e2", -variable => $this->{ini}->pVariable("PbPAllowNegativeE2", 0), -onvalue => 1, -offvalue => 0, -indicatoron => 'no', )->pack(-side => 'left'); $button = $Frame->MyCheckbutton( -text => "Use previous", -variable => $this->{ini}->pVariable("PbPUsePrevious", 1), -onvalue => 1, -offvalue => 0, -indicatoron => 'no', )->pack(-side => 'left'); $button = $Frame->MyCheckbutton( -text => "LSQ twice", -variable => $this->{ini}->pVariable("PbPDoubleLSQ", 1), -onvalue => 1, -offvalue => 0, -indicatoron => 'no', )->pack(-side => 'left'); $Frame->MyLabel( -text => ' Fix ', )->pack(-side => 'left'); $button = $Frame->MyCheckbutton( -text => "e1", -variable => $this->{ini}->pVariable("PbPFixe1", 0), -onvalue => 1, -offvalue => 0, -indicatoron => 'no', )->pack(-side => 'left'); $button = $Frame->MyCheckbutton( -text => "e2", -variable => $this->{ini}->pVariable("PbPFixe2", 0), -onvalue => 1, -offvalue => 0, -indicatoron => 'no', )->pack(-side => 'left'); $Frame->MyLabel( -text => 'to', )->pack(-side => 'left'); $Frame->MyEntry( -name => 'PbPFixedVal', -textvariable => $this->{ini}->pVariable("PbPFixVal", 0), -format => '', -width => 5, )->pack(-side => 'left'); $this->UpdateParameters(); $this->BuildFooter($MainFrame, $EntryWidth); } sub SelChangeListBox { my ($this, $type, $lb) = @_; #print "this:$this lb=$lb\n"; my $s = $lb->GetText(); if($type eq 'LayerModel') { if($s eq "Surface(EMA)/Films/Substrate") { $this->{SurfaceThicknessButton}->SetText("Surface thickness:"); } elsif($s eq "Films/Interface(EMA)/Substrate") { $this->{SurfaceThicknessButton}->SetText("Interface thickness:"); } else { } } # $this->CreateGraphFrame(); $this->AssignGraphData(); $this->Draw(); } #=================================================== # データ処理 #=================================================== sub BuildLayerModel { my ($this, $IsPrint, $BuildOptimize) = @_; $IsPrint = 1 if(!defined $IsPrint); $BuildOptimize = 1 if(!defined $BuildOptimize); my $ini = $this->{ini}; my $dini = $this->{dini}; my $el = $this->{Ellipsometry}; my $optics = new Optics; my $Layers = new MultiLayer; # $Layers->SetIncidentAngle($ini->{Angle}); $Layers->SetIncidentAngle($ini->{TAngle}); my $pObsE = $el->GetData('.*eV.*', '.*E.*'); my $pObsPsi = $el->GetData('Psi'); my $pObsDelta = $el->GetData('Delta'); my $pObsEps1 = $el->GetData('e1'); my $pObsEps2 = $el->GetData('e2'); my $pObsR = $el->GetData('R'); my $pObsT = $el->GetData('T'); my $nData = @$pObsE; my $nE = $nData; $ini->{FitEmin} = $pObsE->[0] if($ini->{FitEmin} eq ''); $ini->{FitEmax} = $pObsE->[$nData-1] if($ini->{FitEmax} eq ''); my $Emin = $ini->{FitEmin}; my $Emax = $ini->{FitEmax}; my $Estep = $pObsE->[1] - $pObsE->[0]; $Estep = 0.05 if(!defined $Estep); $nData = int( ($Emax - $Emin) / $Estep + 1.001); my $Air = new OpticalMaterial("air"); my $Surface = new OpticalMaterial("Specify", "Surface"); my @Films; for(my $i = $this->{ini}->{nFilmLayers} ; $i >= 1 ; $i--) { $Films[$i] = new OpticalMaterial("Specify", "Film${i}"); } my $Substrate = new OpticalMaterial("Specify", "Substrate"); my $pAnalyzeLayer; if($this->{ini}->{nFilmLayers} > 0) { $pAnalyzeLayer = \$Films[$this->{ini}->{nFilmLayers}]; } else { $pAnalyzeLayer = \$Substrate; } #print "pAnalyzeLayer: $$pAnalyzeLayer: ", $$pAnalyzeLayer->Name(), "\n"; $Surface->AddDielectricModel( "EMA1", "EMA", "Model", "Average", "pMaterials", [$$pAnalyzeLayer, $Air], "pVolumeFractions", [$ini->{SurfaceVf}, 1.0 - $ini->{SurfaceVf}], ); my @iComponent; my @Component; my @pVfComponent; my $Cc = 0; for(my $i = 1 ; $i <= $this->{ini}->{nComponents} ; $i++) { my $ii = $i; if($this->{ini}->{"Vf${ii}"} ne 0.0 or $this->{ini}->pVariable("Vf${ii}check")) { my $path = $this->{ini}->{"Component${ii}CSVFile"}; next if(!defined $path or $path eq ''); $iComponent[$Cc] = $i; $Component[$Cc] = new OpticalMaterial("Specify", "Component$ii"); # $pVfComponent[$Cc] = \$this->{ini}->{"Vf${ii}"}; $pVfComponent[$Cc] = $this->{ini}->{"Vf${ii}"}; my @ret = $Component[$Cc]->AddDielectricModel( "Component${ii}", "EFile", "Path", $path, ); if(@ret == 0) { print "Error: Can not read [$path].\n"; return; } $Cc++; } } $this->{nComponent} = scalar @iComponent; $this->{piComponent} = \@iComponent; $this->{pComponent} = \@Component; $this->{ppVfComponent} = \@pVfComponent; if(@Component == 1) { my $ii = $iComponent[0]; my $path = $this->{ini}->{"Component${ii}CSVFile"}; $$pAnalyzeLayer->AddDielectricModel( "Component${ii}", "EFile", "Path", $path, ); } elsif(@Component > 1) { my $EMAModel = $this->{ChooseEMAModelListBox}->GetText(); #print "EMA: $EMAModel\n"; $$pAnalyzeLayer->AddDielectricModel( "EMA1", "EMA", # "Model", "Maxwell-Garnett", "Model", $EMAModel, "pMaterials", \@Component, "pVolumeFractions", \@pVfComponent, ); } $$pAnalyzeLayer->AddDielectricModel( "Constant1", "Constant", "e1inf", $ini->{e1inf}, "e2inf", $ini->{e2inf}, ); $$pAnalyzeLayer->AddDielectricModel( "TaucLorentz1", "TaucLorentz", "A", $ini->{A}, "Eg", $ini->{Eg}, "En0", $ini->{En0}, "C", $ini->{C} ); $$pAnalyzeLayer->AddDielectricModel( "Caucy1", "Caucy", "pA", [$ini->{Caucy2}, $ini->{Caucy4}], "pn", [2, 4], ); for(my $i = 0 ; $i < $this->{ini}->{nLorentz} ; $i++) { my $i1 = $i + 1; $$pAnalyzeLayer->AddDielectricModel( "Lorentz$i1", "Lorentz", "Ne", $ini->{"Ne$i1"}, "E0", $ini->{"E0$i1"}, "G", $ini->{"G$i1"}, ); } for(my $i = 0 ; $i < $this->{ini}->{nDrude} ; $i++) { my $i1 = $i + 1; $$pAnalyzeLayer->AddDielectricModel( "Drude$i1", "Drude", "Ep", $ini->{"DrudeEp$i1"}, "tau", $ini->{"Drudetau$i1"}, ); } for(my $i = $this->{ini}->{nFilmLayers}-1 ; $i >= 1 ; $i--) { my $FileName = $ini->{"Sample${i}CSVFile"}; if($ini->{"Sample${i}CSVFile"}) { my @ret = $Films[$i]->AddDielectricModel( "Film${i}", "EFile", "Path", $FileName, ); if(@ret == 0) { print "Error: Can not read [$FileName].\n"; return; } } } if($this->{ini}->{nFilmLayers} > 0 and $ini->{SubstrateCSVFile}) { my @ret = $Substrate->AddDielectricModel( "Substrate", "EFile", "Path", $ini->{SubstrateCSVFile}, ); if(@ret == 0) { print "Error: Can not read [$ini->{SubstrateCSVFile}].\n"; return; } } $Layers->AddLayer($Air, -1.0, 0.0); if($this->{ChooseLayerModelListBox}->GetText() eq "Surface(EMA)/Films/Substrate") { $Layers->AddLayer($Surface, $ini->{SurfaceThickness}*1.0e-9, 1.0); } for(my $i = $this->{ini}->{nFilmLayers} ; $i >= 1 ; $i--) { #print "film$i d=", $ini->{"Film${i}Thickness"}, "\n"; $Layers->AddLayer($Films[$i], $ini->{"Film${i}Thickness"}*1.0e-9, 1.0); } if($this->{ChooseLayerModelListBox}->GetText() eq "Films/Interface(EMA)/Substrate") { $Layers->AddLayer($Surface, $ini->{SurfaceThickness}*1.0e-9, 1.0); } #print "sub d=$ini->{SubstrateThickness}\n"; $Layers->AddLayer($Substrate, $ini->{SubstrateThickness}*1.0e-3, 0.0); $Layers->AddLayer($Air, -1.0, 0.0); $this->{Layers} = $Layers; $Layers->PrintLayers() if($IsPrint); #========================================================= # フィッティング設定 #========================================================= return if(!$BuildOptimize); my $iAnalyzeFilm = 1; #$ini->{nFilmLayers}; my $iSubstrate = $ini->{nFilmLayers} + 1; my $ppA = $$pAnalyzeLayer->pVariable('Caucy1::pA'); my $pA = $$ppA; my $ppV = $Surface->pVariable('EMA1::pVolumeFractions'); my $pV = $$ppV; my $optimize = new Optimize(); $optimize->AddParameters( "Scale", \$ini->{Scale}, $dini->{Scalecheck}, $dini->{Scalescale}, $dini->{Scalemin}, $dini->{Scalemax}, sub { $ini->{Scale} = $_[0]; }, "RScale", \$ini->{RScale}, $dini->{RScalecheck}, $dini->{RScalescale}, $dini->{RScalemin}, $dini->{RScalemax}, sub { $ini->{RScale} = $_[0]; }, "Rayleighl0", \$ini->{Rayleighl0}, $dini->{Rayleighl0check}, $dini->{Rayleighl0scale}, $dini->{Rayleighl0min}, $dini->{Rayleighl0max}, sub { $ini->{Rayleighl0} = $_[0]; }, ); if($this->{ChooseLayerModelListBox}->GetText() eq "Surface(EMA)/Films/Substrate") { $iAnalyzeFilm++; $iSubstrate++; $optimize->AddParameters( "SurfaceThickness", $Layers->pLayerThickness(1), $dini->{SurfaceThicknesscheck}, $dini->{SurfaceThicknessscale}, $dini->{SurfaceThicknessmin}, $dini->{SurfaceThicknessmax}, sub { $Layers->SetLayerThickness(1, $_[0]); $ini->{SurfaceThickness} = $_[0]*1.0e9; }, "SurfaceVf", \$ini->{SurfaceVf}, $dini->{SurfaceVfcheck}, $dini->{SurfaceVfscale}, $dini->{SurfaceVfmin}, $dini->{SurfaceVfmax}, sub { $pV->[0] = $_[0]; $pV->[1] = 1.0 - $_[0]; $ini->{SurfaceVf} = $_[0]; }, ); }; if($this->{ChooseLayerModelListBox}->GetText() eq "Films/Interface(EMA)/Substrate") { $iSubstrate++; } for(my $i = 1 ; $i <= $this->{ini}->{nComponents} ; $i++) { my $ii = $i; $optimize->AddParameters( # "SurfaceThickness", $Layers->pVf(1, $ii), "Vf$ii", \$ini->{"Vf${ii}"}, $dini->{"Vf${ii}check"}, $dini->{"Vf${ii}scale"}, $dini->{"Vf${ii}min"}, $dini->{"Vf${ii}max"}, sub { # $Layers->SetVf(1, $ii, $_[0]); $ini->{"Vf${ii}"} = $_[0]; }, ); } my $ilayer = $iAnalyzeFilm - 1;; for(my $i = $this->{ini}->{nFilmLayers} ; $i >= 1 ; $i--) { my $ii = $i; $ilayer++; $optimize->AddParameters( "Film${i}Thickness", $Layers->pLayerThickness($ilayer), $dini->{"Film${i}Thicknesscheck"}, $dini->{"Film${i}Thicknessscale"}, $dini->{"Film${i}Thicknessmin"}, $dini->{"Film${i}Thicknessmax"}, sub { #print "i=$ii il=$ilayer 0=$_[0]\n"; $Layers->SetLayerThickness($ilayer, $_[0]); $ini->{"Film${ii}Thickness"} = $_[0]*1.0e9; } ); } $optimize->AddParameters( "SubstrateThickness", $Layers->pLayerThickness($iSubstrate), $dini->{SubstrateThicknesscheck}, $dini->{SubstrateThicknessscale}, $dini->{SubstrateThicknessmin}, $dini->{SubstrateThicknessmax}, sub { $Layers->SetLayerThickness($iSubstrate, $_[0]); $ini->{SubstrateThickness} = $_[0]*1.0e3; }, "Film-e1", $Layers->pVariable($iAnalyzeFilm, 'Constant1::e1inf'), $dini->{e1infcheck}, $dini->{e1infscale}, $dini->{e1infmin}, $dini->{e1infmax}, sub { $Layers->SetVariable($iAnalyzeFilm, 'Constant1::e1inf', $_[0]); $ini->{e1inf} = $_[0]; }, "Film-e2", $Layers->pVariable($iAnalyzeFilm, 'Constant1::e2inf'), $dini->{e2infcheck}, $dini->{e2infscale}, $dini->{e2infmin}, $dini->{e2infmax}, sub { $Layers->SetVariable($iAnalyzeFilm, 'Constant1::e2inf', $_[0]); $ini->{e2inf} = $_[0]; }, "Film-Caucy2", \$pA->[0], $dini->{Caucy2check}, $dini->{Caucy2scale}, $dini->{Caucy2min}, $dini->{Caucy2max}, sub { $ini->{Caucy2} = $pA->[0] = $_[0]; }, "Film-Caucy4", \$pA->[1], $dini->{Caucy4check}, $dini->{Caucy4scale}, $dini->{Caucy4min}, $dini->{Caucy4max}, sub { $ini->{Caucy4} = $pA->[1] = $_[0]; }, "Film-TLA", $Layers->pVariable($iAnalyzeFilm, 'TaucLorentz1::A'), $dini->{Acheck}, $dini->{Ascale}, $dini->{Amin}, $dini->{Amax}, sub { $Layers->SetVariable($iAnalyzeFilm, 'TaucLorentz1::A', $_[0]); $ini->{A} = $_[0]; }, "Film-TLC", $Layers->pVariable($iAnalyzeFilm, 'TaucLorentz1::C'), $dini->{Ccheck}, $dini->{Cscale}, $dini->{Cmin}, $dini->{Cmax}, sub { $Layers->SetVariable($iAnalyzeFilm, 'TaucLorentz1::C', $_[0]); $ini->{C} = $_[0]; }, "Film-TLEg", $Layers->pVariable($iAnalyzeFilm, 'TaucLorentz1::Eg'), $dini->{Egcheck}, $dini->{Egscale}, $dini->{Egmin}, $dini->{Egmax}, sub { $Layers->SetVariable($iAnalyzeFilm, 'TaucLorentz1::Eg', $_[0]); $ini->{Eg} = $_[0]; }, "Film-TLEn0", $Layers->pVariable($iAnalyzeFilm, 'TaucLorentz1::En0'), $dini->{En0check}, $dini->{En0scale}, $dini->{En0min}, $dini->{En0max}, sub { $Layers->SetVariable($iAnalyzeFilm, 'TaucLorentz1::En0', $_[0]); $ini->{En0} = $_[0]; }, ); for(my $i = 0 ; $i < $this->{ini}->{nLorentz} ; $i++) { my $i1 = $i + 1; $optimize->AddParameters( "Film-L${i1}E0", $Layers->pVariable($iAnalyzeFilm, "Lorentz${i1}::E0"), $dini->{"E0${i1}check"}, $dini->{"E0${i1}scale"}, $dini->{"E0${i1}min"}, $dini->{"E0${i1}max"}, sub { $Layers->SetVariable($iAnalyzeFilm, "Lorentz${i1}::E0", $_[0]); $ini->{"E0${i1}"} = $_[0]; }, "Film-L${i1}Ne", $Layers->pVariable($iAnalyzeFilm, "Lorentz${i1}::Ne"), $dini->{"Ne${i1}check"}, $dini->{"Ne${i1}scale"}, $dini->{"Ne${i1}min"}, $dini->{"Ne${i1}max"}, sub { $Layers->SetVariable($iAnalyzeFilm, "Lorentz${i1}::Ne", $_[0]); $ini->{"Ne${i1}"} = $_[0]; $ini->{"A${i1}"} = $optics->CalLorentzAfromNe($ini->{"Ne${i1}"}, 1.0); }, "Film-L${i1}G", $Layers->pVariable($iAnalyzeFilm, "Lorentz${i1}::G"), $dini->{"G${i1}check"}, $dini->{"G${i1}scale"}, $dini->{"G${i1}min"}, $dini->{"G${i1}max"}, sub { $Layers->SetVariable($iAnalyzeFilm, "Lorentz${i1}::G", $_[0]); $ini->{"G${i1}"} = $_[0]; }, ); } for(my $i = 0 ; $i < $this->{ini}->{nDrude} ; $i++) { my $i1 = $i + 1; $optimize->AddParameters( "Film-D${i1}Ep", $Layers->pVariable($iAnalyzeFilm, "Drude${i1}::Ep"), $dini->{"DrudeEp${i1}check"}, $dini->{"DrudeEp${i1}scale"}, $dini->{"DrudeEp${i1}min"}, $dini->{"DrudeEp${i1}max"}, sub { $Layers->SetVariable($iAnalyzeFilm, "Drude${i1}::Ep", $_[0]); $ini->{"DrudeEp${i1}"} = $_[0]; }, "Film-D${i1}tau", $Layers->pVariable($iAnalyzeFilm, "Drude${i1}::tau"), $dini->{"Drudetau${i1}check"}, $dini->{"Drudetau${i1}scale"}, $dini->{"Drudetau${i1}min"}, $dini->{"Drudetau${i1}max"}, sub { $Layers->SetVariable($iAnalyzeFilm, "Drude${i1}::tau", $_[0]); $ini->{"Drudetau${i1}"} = $_[0]; }, ); } if($this->{ChooseLayerModelListBox}->GetText() eq "Films/Interface(EMA)/Substrate") { $optimize->AddParameters( "SurfaceThickness", $Layers->pLayerThickness(2), $dini->{SurfaceThicknesscheck}, $dini->{SurfaceThicknessscale}, $dini->{SurfaceThicknessmin}, $dini->{SurfaceThicknessmax}, sub { $Layers->SetLayerThickness(2, $_[0]); $ini->{SurfaceThickness} = $_[0]*1.0e9; }, "SurfaceVf", \$ini->{SurfaceVf}, $dini->{SurfaceVfcheck}, $dini->{SurfaceVfscale}, $dini->{SurfaceVfmin}, $dini->{SurfaceVfmax}, sub { $pV->[0] = $_[0]; $pV->[1] = 1.0 - $_[0]; $ini->{SurfaceVf} = $_[0]; }, ); }; $this->{Optimize} = $optimize; } sub Recalc { my ($this) = @_; my $ini = $this->{ini}; my $dini = $this->{dini}; $this->UpdateParameters(); $this->BuildLayerModel(1, 0); my $el = $this->{Ellipsometry}; my $Layers = $this->{Layers}; my $pObsE = $el->GetData('.*eV.*', '.*E.*'); my $pObsR = $el->GetData('R.*'); my $pObsT = $el->GetData('T.*'); my $FitTo = $this->{ChooseFitToListBox}->GetText(); my ($pE, $pR, $pT, $S2) = $this->CalRTArrays($Layers, $pObsE, $pObsR, $pObsT, $FitTo); $this->{pEArray} = $pE; $this->{pRArray} = $pR; $this->{pTArray} = $pT; my $mucal = 0.0; my $sigmacal = 0.0; my $effmass = 0.0; my $Ne = $ini->{Ne} * 1.0e6; my $KNeee = $e * $e * $Ne / $e0 / $me; for(my $i = 0 ; $i < $this->{ini}->{nDrude} ; $i++) { my $i1 = $i + 1; my $wp2 = $ini->{"DrudeEp${i1}"} * 1.519e15; # in rad/s $wp2 *= $wp2; my $tau = $ini->{"Drudetau${i1}"}; if($Ne > 0.0) { my $m = $KNeee / $wp2; if($m > 0.0) { $effmass += 1.0/ $m; } } my $mu0 = $e0 * $wp2 * $tau; if($Ne > 0.0) { $mucal += $mu0 / $Ne / $e; } $sigmacal += $mu0; } $mucal *= 1.0e4; $sigmacal *= 1.0e-2; if($effmass > 0.0) { $effmass = 1.0 / $effmass; } $ini->{MobilityCal} = $mucal; $ini->{ConductivityCal} = $sigmacal; $ini->{EffMass} = $effmass; if($Ne > 0.0 and $dini->{KMobilitycheck}) { my $d = $ini->{Mobility} - $mucal; $S2 += $ini->{KMobility} * $d * $d; } if($dini->{KConductivitycheck}) { my $d = $ini->{Conductivity} - $sigmacal; $S2 += $ini->{KConductivity} * $d * $d; } #print "e=$e, $e0, $me\n"; #print "m: $mucal, s: $sigmacal\n"; $this->App()->print("Recalc: S2=$S2\n"); $this->SetS2($S2); return $S2; } sub PointByPoint { my ($this) = @_; my $App = $this->App(); my $ini = $this->{ini}; my $el = $this->{Ellipsometry}; $this->UpdateParameters(); $this->BuildLayerModel(0, 0); my $Layers = new MultiLayer; $Layers->SetIncidentAngle($ini->{TAngle}); # $Layers->SetIncidentAngle($ini->{Angle}); my $Air = new OpticalMaterial("air"); my @Films; for(my $i = $this->{ini}->{nFilmLayers} ; $i >= 1 ; $i--) { $Films[$i] = new OpticalMaterial("Specify", "Film${i}"); } my $Substrate = new OpticalMaterial("Specify", "Substrate"); my $pAnalyzeLayer; if($this->{ini}->{nFilmLayers} > 0) { $pAnalyzeLayer = \$Films[$this->{ini}->{nFilmLayers}]; } else { $pAnalyzeLayer = \$Substrate; } $$pAnalyzeLayer->AddDielectricModel( "Constant1", "Constant", "e1inf", $ini->{e1inf}, "e2inf", $ini->{e2inf}, ); for(my $i = $this->{ini}->{nFilmLayers}-1 ; $i >= 1 ; $i--) { my $FileName = $ini->{"Sample${i}CSVFile"}; if($ini->{"Sample${i}CSVFile"}) { print "Read [", $ini->{"Sample${i}CSVFile"}, "] for File$i\n"; my @ret = $Films[$i]->AddDielectricModel( "Film${i}", "EFile", "Path", $FileName, ); if(@ret == 0) { print "Error: Can not read [$FileName].\n"; return; } } } if($this->{ini}->{nFilmLayers} > 0 and $ini->{SubstrateCSVFile}) { print "Read [", $ini->{SubstrateCSVFile}, "] for Substrate\n"; my @ret = $Substrate->AddDielectricModel( "Substrate", "EFile", "Path", $ini->{SubstrateCSVFile}, ); if(@ret == 0) { print "Error: Can not read [$ini->{SubstrateCSVFile}].\n"; return; } } $Layers->AddLayer($Air, -1.0, 0.0); for(my $i = $this->{ini}->{nFilmLayers} ; $i >= 1 ; $i--) { $Layers->AddLayer($Films[$i], $ini->{"Film${i}Thickness"}*1.0e-9, 1.0); } $Layers->AddLayer($Substrate, $ini->{SubstrateThickness}*1.0e-3, 0.0); $Layers->AddLayer($Air, -1.0, 0.0); my $pObsE = $el->GetData('.*eV.*', '.*E.*'); my $pObsR = $el->GetData('R.*'); my $pObsT = $el->GetData('T.*'); my $nData = @$pObsE; my $IniSubstrate = $this->{Layers}->pLayer(1); #$ini->{nLayers}); # 1); my $Method = $this->{ChooseLSQMethodListBox}->GetText(); my $FitTo = $this->{ChooseFitToListBox}->GetText(); my (@PbPE, @PbPe1, @PbPe2, @PbPR, @PbPT, @PbPS2); my $c = 0; my ($e1ini, $e2ini); for(my $i = 0 ; $i < $nData ; $i++) { next if($ini->{nSkipData} > 0 and $i % $ini->{nSkipData} != 0); my $E = $pObsE->[$i]; next if($E < $ini->{FitEmin} or $ini->{FitEmax} < $E); # my $sf = $ini->{Scale} - $lwl2 * $lwl2; my $lwl = $ini->{Rayleighl0} / Optics::eVTonm($E); my $lwl2 = $lwl * $lwl; my $Tsf = $ini->{Scale} / (1.0 - $lwl2 * $lwl2); my $Rsf = $ini->{RScale} / (1.0 - $lwl2 * $lwl2); ($e1ini, $e2ini) = $IniSubstrate->CalEps($E); if($ini->{PbPUsePrevious} and $c > 1) { ($e1ini, $e2ini) = ($PbPe1[$c-1], $PbPe2[$c-1]); } my ($e1opt, $e2opt) = ($e1ini, $e2ini); #print "E=$E: eini=($e1ini,$e2ini)\n"; if($ini->{PbPFixe1}) { $e1opt = $ini->{PbPFixVal}; } if($ini->{PbPFixe2}) { $e2opt = $ini->{PbPFixVal}; } my $optimize = new Optimize(); if(!$ini->{PbPFixe1}) { $optimize->AddParameters( "e1", \$e1opt, 1, 0.1, '', '', sub { $Layers->SetVariable(1, 'Constant1::e1inf', $_[0]); $e1opt = $_[0]; }, ); } if(!$ini->{PbPFixe2}) { $optimize->AddParameters( "e2", \$e2opt, 1, 0.1, '', '', sub { $Layers->SetVariable(1, 'Constant1::e2inf', $_[0]); $e2opt = $_[0]; }, ); } my ($OptVars, $MinVal) = $optimize->Optimize( $Method, undef, undef, undef, $ini->{EPS}, $ini->{nMaxIter}, $ini->{iPrintLevel}, sub { $this->CalS2ForPontByPonint($optimize, $FitTo, $Layers, $E, $pObsR->[$i] * $Rsf, $pObsT->[$i] * $Tsf, @_); }, undef, sub { Optimize::BuildDifferentialMatrixes(@_); }, ); if($this->{ini}->{PbPDoubleLSQ} and $MinVal > 1.0e-15 and $c >= 1) { $App->printf("%6.2f: (%10.4g,%10.4g) => (%10.4g,%10.4g) [%10.4g] XXX\n", $E, $e1ini, $e2ini, $e1opt, $e2opt, $MinVal); ($e1ini, $e2ini) = ($PbPe1[$c-1], $PbPe2[$c-1]); if($ini->{PbPUsePrevious}) { ($e1ini, $e2ini) = $IniSubstrate->CalEps($E); } # $App->printf("%8s(%10.4g,%10.4g)\n", ' Try '$e1ini, $e2ini); my ($OptVars2, $MinVal2) = $optimize->Optimize( $Method, undef, undef, undef, $ini->{EPS}, $ini->{nMaxIter}, $ini->{iPrintLevel}, sub { $this->CalS2ForPontByPonint($optimize, $FitTo, $Layers, $E, $pObsR->[$i] * $Rsf, $pObsT->[$i] * $Tsf, @_); }, undef, sub { Optimize::BuildDifferentialMatrixes(@_); }, ); if($MinVal2 < $MinVal) { $MinVal = $MinVal2; for(my $i = 0 ; $i < @$OptVars ; $i++) { $OptVars->[$i] = $OptVars2->[$i]; } } } $optimize->RecoverParameters($OptVars); $App->printf("%6.2f: (%10.4g,%10.4g) => (%10.4g,%10.4g) [%10.4g]\n", $E, $e1ini, $e2ini, $e1opt, $e2opt, $MinVal); my ($Rtots, $Rtotp, $Ttots, $Ttotp) = $this->CalRT($E, $Layers); my $Rcal = ($Rtots + $Rtotp) / 2.0; my $Tcal = ($Ttots + $Ttotp) / 2.0; $PbPE[$c] = $E; $PbPe1[$c] = $e1opt; $PbPe2[$c] = $e2opt; $PbPR[$c] = $Rcal; $PbPT[$c] = $Tcal; $PbPS2[$c] = $MinVal; ($e1ini, $e2ini) = ($e1opt, $e2opt); $c++; } $this->{PbPE} = \@PbPE; $this->{PbPe1} = \@PbPe1; $this->{PbPe2} = \@PbPe2; $this->{PbPR} = \@PbPR; $this->{PbPT} = \@PbPT; $this->{PbPS2} = \@PbPS2; $this->RePlot(0); } sub SaveEps { my ($this) = @_; my $ini = $this->{ini}; my $path = $ini->{ParameterFile}; $path =~ s/\..*?$/-eps.csv/i; if($path !~ /\.csv$/i) { $path = "${path}-eps.csv"; } print "Save Eps to [$path].\n"; my $out = new JFile($path, "w"); if(!$out) { print "Error in SaveEps: Can not write to [$path].\n"; return; } $out->print("E(eV),e1,e2\n"); if(!$this->{Layers}) { $this->BuildLayerModel(0, 0); } my $Layers = $this->{Layers}; my $el = $this->{Ellipsometry}; my $pObsE = $el->GetData('.*eV.*', '.*E.*'); my $EStep = $pObsE->[1] - $pObsE->[0]; my $EStart = $ini->{FitEmin}; my $EStop = $ini->{FitEmax}; my $nE = int( ($EStop - $EStart) / $EStep + 1.01); for(my $i = 0 ; $i < $nE ; $i++) { my $E = $EStart + $i * $EStep; my ($e1, $e2) = $Layers->pLayer(1)->CalEps($E); printf("%6.3f\t%9.6f\t%9.6f\n", $E,$e1,$e2); $out->print("$E,$e1,$e2\n"); } $out->Close(); } sub CalS2ForPontByPonint { my ($this, $optimize, $FitTo, $Layers, $E, $R, $T, $pVars, $iPrintLevel) = @_; my $ini = $this->{ini}; my $el = $this->{Ellipsometry}; $optimize->RecoverParameters($pVars); my ($e1, $e2) = $Layers->pLayer(1)->CalEps($E); return 1.0e10 if(!$ini->{PbPAllowNegativeE2} and $e2 < 0.0); $Layers->SetIncidentAngle($ini->{TAngle}); $el->SetIncidentAngle($ini->{TAngle}); my ($Rtots, $Rtotp, $Ttots, $Ttotp) = $this->CalRT($E, $Layers); if(abs($ini->{TAngle} - $ini->{RAngle}) > 0.1) { $Layers->SetIncidentAngle($ini->{RAngle}); $el->SetIncidentAngle($ini->{RAngle}); my ($Rtotsr, $Rtotpr, $Ttotsr, $Ttotpr) = $this->CalRT($E, $Layers); $Rtots = $Rtotsr; $Rtotp = $Rtotpr; } my $Rcal = ($Rtots + $Rtotp) / 2.0; my $Tcal = ($Ttots + $Ttotp) / 2.0; #print "E=$E: e=($e1,$e2) R=($R,$T) / ($Rcal,$Tcal)\n"; # my $dR = $R - $Rcal; # my $dT = $T - $Tcal; # my $S2 = $dR * $dR + $dT * $dT; my $S2 = 0.0; if(defined $R and $FitTo =~ /R/) { my $dR = $R - $Rcal; $S2 += $dR * $dR; } if(defined $T and $FitTo =~ /T/) { my $dT = $T - $Tcal; $S2 += $dT * $dT; } #print "E=$E: S2=$S2\n"; $this->mw()->update(); return $S2; } sub Fit { my ($this) = @_; my $ini = $this->{ini}; my $dini = $this->{dini}; $this->UpdateParameters(); $this->BuildLayerModel(0, 1); my $optimize = $this->{Optimize}; my $Method = $this->{ChooseLSQMethodListBox}->GetText(); my $FitTo = $this->{ChooseFitToListBox}->GetText(); print "Method: $Method\n"; print "Fit to: $FitTo\n"; print "nMaxIter: $ini->{nMaxIter}\n"; my $el = $this->{Ellipsometry}; my $pObsE = $el->GetData('.*eV.*', '.*E.*'); my $pObsR = $el->GetData('R.*'); my $pObsT = $el->GetData('T.*'); #========================================================= # 最適化の実行 #========================================================= $optimize->SetnS2Calculation(0); # $this->{nS2} = 0; my ($OptVars, $MinVal) = $optimize->Optimize( $Method, undef, undef, undef, $ini->{EPS}, $ini->{nMaxIter}, $ini->{iPrintLevel}, sub { $this->CalS2($FitTo, $pObsE, $pObsR, $pObsT, @_); }, undef, sub { Optimize::BuildDifferentialMatrixes(@_); }, ); print "\nOptimized at:\n"; $optimize->PrintParameters(1); $optimize->RecoverParameters($OptVars); $this->SetS2($MinVal); $this->UpdateParameters(); $this->RePlot(0); } sub CalS2 { my ($this, $FitTo, $pObsE, $pObsR, $pObsT, $pVars, $iPrintLevel) = @_; #print "pVars=", join(',', @$pVars); my $optimize = $this->{Optimize}; my $ini = $this->{ini}; my $dini = $this->{dini}; $optimize->RecoverParameters($pVars); # $this->UpdateParameters(); $this->BuildLayerModel(0, 0); #$this->{Layers}->PrintLayers(); my ($pE, $pR, $pT, $S2) = $this->CalRTArrays($this->{Layers}, $pObsE, $pObsR, $pObsT, $FitTo); my $mucal = 0.0; my $sigmacal = 0.0; my $effmass = 0.0; my $Ne = $ini->{Ne} * 1.0e6; my $KNeee = $e * $e * $Ne / $e0 / $me; for(my $i = 0 ; $i < $this->{ini}->{nDrude} ; $i++) { my $i1 = $i + 1; my $wp2 = $ini->{"DrudeEp${i1}"} * 1.519e15; # in rad/s $wp2 *= $wp2; my $tau = $ini->{"Drudetau${i1}"}; if($Ne > 0.0) { my $m = $KNeee / $wp2; if($m > 0.0) { $effmass += 1.0/ $m; } } my $mu0 = $e0 * $wp2 * $tau; if($Ne > 0.0) { $mucal += $mu0 / $Ne / $e; } $sigmacal += $mu0; } $mucal *= 1.0e4; $sigmacal *= 1.0e-2; if($effmass > 0.0) { $effmass = 1.0 / $effmass; } $ini->{MobilityCal} = $mucal; $ini->{ConductivityCal} = $sigmacal; $ini->{EffMass} = $effmass; #print "Kcheck: $dini->{KMobilitycheck}, $dini->{KConductivitycheck}\n"; #print "S2=$S2 => "; if($Ne > 0.0 and $dini->{KMobilitycheck}) { my $d = $ini->{Mobility} - $mucal; $S2 += $ini->{KMobility} * $d * $d; } if($dini->{KConductivitycheck}) { my $d = $ini->{Conductivity} - $sigmacal; $S2 += $ini->{KConductivity} * $d * $d; } #print "m: $mucal, s: $sigmacal\n"; #print "$S2\n"; if($this->{nComponent} > 1) { my $totV = 0.0; for(my $i = 0 ; $i < $this->{nComponent} ; $i++) { $totV += $this->{ppVfComponent}->[$i]; } my $d = $totV - 1.0; $S2 += $ini->{KVf} * $d * $d; } $optimize->IncrementnS2(); my $nS2 = $optimize->nS2Calculation(); my $nS2Interval = $ini->{nSaveSpectraInterval}; print "S2[$nS2] = $S2 / "; $S2 += $optimize->CalPenalty(1.0e10, $pVars, 1); print "$S2\n"; $optimize->PrintParameters(1, $pVars, $S2, 0); if($nS2Interval > 0 and $nS2 % $nS2Interval == 0) { $this->Recalc(); # $this->CreateGraphFrame(); $this->AssignGraphData(0); $this->Draw(); } $this->UpdateParameters(); $this->mw()->update(); return $S2; } sub CalRT { my ($this, $E, $Layers) = @_; my $ini = $this->{ini}; # my ($Rtots, $Rtotp, $Ttots, $Ttotp) = $Layers->CalEpsRTForSubstrate($E, $this->{ini}->{Angle}); $Layers->SetIncidentAngle($ini->{TAngle}); $this->{Ellipsometry}->SetIncidentAngle($ini->{TAngle}); my ($rs123, $rp123, $ts123, $tp123, $Rtots, $Rtotp, $Ttots, $Ttotp) = $Layers->CalFresnelCoefficient($E); if(abs($ini->{TAngle} - $ini->{RAngle}) > 0.1) { $Layers->SetIncidentAngle($ini->{RAngle}); $this->{Ellipsometry}->SetIncidentAngle($ini->{RAngle}); my ($rs123r, $rp123r, $ts123r, $tp123r, $Rtotsr, $Rtotpr, $Ttotsr, $Ttotpr) = $Layers->CalFresnelCoefficient($E); $rs123 = $rs123r; $rp123 = $rp123r; $Rtots = $Rtotsr; $Rtotp = $Rtotpr; } return ($Rtots, $Rtotp, $Ttots, $Ttotp); } sub CalRTArrays { my ($this, $Layers, $pObsE, $pObsR, $pObsT, $FitTo) = @_; my $ini = $this->{ini}; # my $el = $this->{Ellipsometry}; # my $Angle = $ini->{Angle}; # $el->SetIncidentAngle($Angle); my $nData = @$pObsE; my (@E, @R, @T); my $S2 = 0.0; my $c = 0; for(my $i = 0 ; $i < $nData ; $i++) { next if($ini->{nSkipData} > 0 and $i % $ini->{nSkipData} != 0); my $E = $pObsE->[$i]; next if($E < $ini->{FitEmin} or $ini->{FitEmax} < $E); my $lwl = $ini->{Rayleighl0} / Optics::eVTonm($E); my $lwl2 = $lwl * $lwl; # my $sf = $ini->{Scale} - $lwl2 * $lwl2; my $Tsf = $ini->{Scale} / (1.0 - $lwl2 * $lwl2); my $Rsf = $ini->{RScale} / (1.0 - $lwl2 * $lwl2); # my ($rs, $rp, $ts, $tp, $Rs, $Rp, $Ts, $Tp) = $Layers->CalFresnelCoefficient($E); $Layers->SetIncidentAngle($ini->{TAngle}); $this->{Ellipsometry}->SetIncidentAngle($ini->{TAngle}); my ($Rs, $Rp, $Ts, $Tp) = $this->CalRT($E, $this->{Layers}); if(abs($ini->{TAngle} - $ini->{RAngle}) > 0.1) { $Layers->SetIncidentAngle($ini->{RAngle}); $this->{Ellipsometry}->SetIncidentAngle($ini->{RAngle}); my ($Rsr, $Rpr, $Tsr, $Tpr) = $this->CalRT($E, $this->{Layers}); $Rs = $Rsr; $Rp = $Rpr; } #print "$E,[$i]: $rs, $rp\n"; my $R = ($Rs + $Rp) / 2.0; my $T = ($Ts + $Tp) / 2.0; $E[$c] = $E; $R[$c] = $R; $T[$c] = $T; if($FitTo eq 'RT' and $pObsR and $pObsT) { my $dT = ($pObsT->[$i] * $Tsf - $T); my $dR = ($pObsR->[$i] * $Rsf - $R); $S2 += $dT * $dT + $dR * $dR; } elsif($FitTo =~ /R/ and $pObsR) { my $d = ($pObsR->[$i] * $Rsf - $R); $S2 += $d * $d; } elsif($FitTo =~ /T/ and $pObsT) { my $d = ($pObsT->[$i] * $Tsf - $T); $S2 += $d * $d; } else { print "Error: Invalid Fitting Target [$FitTo].\n"; return; } $c++; } $S2 = sqrt($S2 / $c); return (\@E, \@R, \@T, $S2); } sub ReadParameterFile { my ($this, $filepath) = @_; my $DirectorySeparator = Deps::DirectorySeparator(); my $RegSeparator = Utils::RegExpQuote($DirectorySeparator); my $ini = $this->{ini}; my $dini = $this->{dini}; $this->Initialize(1, 1); $this->App()->print("\nRead paramter from [$filepath].\n"); $this->{ini}->{nLorentz} = 5; $this->{ini}->{nDerude} = 1; delete $this->{ini}->{nFilmLayers}; delete $this->{ini}->{SubstrateCSVFile}; delete $this->{ini}->{SampleCSVFile}; delete $this->{ini}->{Sample1CSVFile}; delete $this->{ini}->{Sample2CSVFile}; delete $this->{ini}->{Film1Thickness}; $this->{ini}->ReadAll($filepath); my $RecordedPath = $this->{ini}->{ParameterFile}; $this->{ini}->{ParameterFile} = $filepath; $this->{ini}->{TAngle} = $this->{ini}->{Angle} if(!defined $this->{ini}->{TAngle}); $this->{ini}->{TAngle} = 0.0 if(!defined $this->{ini}->{TAngle}); $this->{ini}->{RAngle} = $this->{ini}->{Angle} if(!defined $this->{ini}->{RAngle}); $this->{ini}->{RAngle} = 0.0 if(!defined $this->{ini}->{RAngle}); if(!defined $this->{ini}->{nFilmLayers}) { if(!defined $this->{ini}->{SubstrateCSVFile} or $this->{ini}->{SubstrateCSVFile} eq '') { $this->{ini}->{SubstrateCSVFile} = $this->{ini}->{SampleCSVFile}; # $this->{ini}->{Sample1CSVFile} = $this->{ini}->{SampleCSVFile}; $this->{ini}->{nFilmLayers} = 0; } else { for(my $i = 1 ; $i < 20 ; $i++) { if(!defined $this->{ini}->{"Sample${i}CSVFile"} or $this->{ini}->{"Sample${i}CSVFile"} eq '') { $this->{ini}->{nFilmLayers} = $i; last; } } } } if(!defined $this->{ini}->{Sample1CSVFile} or $this->{ini}->{Sample1CSVFile} eq '') { $this->{ini}->{nFilmLayer} = 1; $this->{ini}->{Sample1CSVFile} = $this->{ini}->{SampleCSVFile} if(!defined $this->{ini}->{Sample1CSVFile} or $this->{ini}->{Sample1CSVFile} eq ''); $this->{ini}->{Film1Thickness} = $this->{ini}->{FilmThickness} if(!defined $this->{ini}->{Film1Thickness} or $this->{ini}->{Film1Thickness} eq 100); } $this->DecomposeParameters($ini, $dini); for(my $i = 1 ; $i <= $ini->{nLorentz} ; $i++) { if(!defined $dini->{"E0${i}check"}) { $this->AddParameters($ini, $dini, "E0$i", 2.6, 0, 1.0, 0.0, ''); $this->AddParameters($ini, $dini, "Ne$i", 0.0, 0, 1.0e27, 0.0, ''); $this->AddParameters($ini, $dini, "G$i", 0.4, 0, 1.0, 0.0, ''); $this->ComposeParameters($ini, $dini); } } for(my $i = 1 ; $i <= $ini->{nDrude} ; $i++) { if(!defined $dini->{"DrudeEp${i}check"}) { $this->AddParameters($ini, $dini, "DrudeEp$i", 0.0, 0, 1.0, 0.0, ''); $this->AddParameters($ini, $dini, "Drudetau$i", 1.0e-14, 0, 1.0e-13, 0.0, ''); $this->ComposeParameters($ini, $dini); } } my $EntryWidth = $this->{EntryWidth}; $this->RefreshMainPane($EntryWidth); $this->RefreshLayersPane($EntryWidth); $this->RefreshMiscParamConditionPane($EntryWidth); $this->RefreshLorentzParamConditionPane($EntryWidth); $this->RefreshDrudeParamConditionPane($EntryWidth); $this->{ChooseLSQMethodListBox}->SetText($this->{ini}->{Method}) if($this->{ChooseLSQMethodListBox}); $this->{ChooseFitToListBox}->SetText($this->{ini}->{FitTo}) if($this->{ChooseFitToListBox}); $this->{ChooseLayerModelListBox}->SetText($this->{ini}->{LayerModel}) if($this->{ChooseLayerModelListBox}); $this->{ChooseModelListBox}->SetText($this->{ini}->{Model}) if($this->{ChooseModelListBox} and $this->{ini}->{Model}); $this->{ChooseXListBox}->SetText($this->{ini}->{X}) if($this->{ChooseXListBox} and $this->{ini}->{X}); $this->{ChooseY1ListBox}->SetText($this->{ini}->{Y1}) if($this->{ChooseY1ListBox} and $this->{ini}->{Y1}); $this->{ChooseY2ListBox}->SetText($this->{ini}->{Y2}) if($this->{ChooseY2ListBox} and $this->{ini}->{Y2}); $this->{ChooseNFilmeLayerListBox}->SetCurSel($this->{ini}->{nFilmLayers}); $this->{ChooseNLorentzListBox}->SetCurSel($this->{ini}->{nLorentz}-1); $this->{ChooseNDrudeListBox}->SetCurSel($this->{ini}->{nDrude}-1); for(my $i = 1 ; $i <= $this->{ini}->{nFilmLayers} ; $i++) { my $path = $this->{ini}->{"Sample${i}CSVFile"}; $path = $this->GetValidDataPath($path, $filepath, $RecordedPath); my $ret = $this->ReadSampleDataFile($path, 1); next unless($ret); $this->{ini}->{"Sample${i}CSVFile"} = $path; } for(my $i = 1 ; $i <= $this->{ini}->{nComponents} ; $i++) { my $path = $this->{ini}->{"Component${i}CSVFile"}; $path = $this->GetValidDataPath($path, $filepath, $RecordedPath); my $ret = $this->ReadSampleDataFile($path, 1); next unless($ret); $this->{ini}->{"Component${i}CSVFile"} = $path; } if($this->{ini}->{SubstrateCSVFile}) { my $path = $this->{ini}->{SubstrateCSVFile}; $this->{ini}->{SubstrateCSVFile} = $this->GetValidDataPath($path, $filepath, $RecordedPath); my $ret; if($this->{ini}->{nFilmLayers} > 0) { $ret = $this->ReadSubstrateDataFile($this->{ini}->{SubstrateCSVFile}, 1, 0); } else { $ret = $this->ReadSampleDataFile($this->{ini}->{SubstrateCSVFile}, 1, 0); } return undef unless($ret); } $this->RePlot(0, 1, 0, 0); $this->RefreshViewRangePane($EntryWidth); my $YAxisListBox = $this->{ini}->{YAxisPlotType}; if($YAxisListBox) { #print "FF=", $this->mw()->{ViewRangePaneFrame}, " - ", $this->mw()->{ViewRangePaneFrame}->{GraphFrame2YAxisListBox}, "\n"; $this->mw()->{ViewRangePaneFrame}->{GraphFrame2YAxisListBox}->SetText($this->{ini}->{YAxisPlotType}) if($this->{ini}->{YAxisPlotType}); } $this->RePlot(1, 0, 1, 1); return 1; } sub ReadSubstrateDataFile { my ($this, $filepath, $IsPrint) = @_; my $App = $this->App(); #print "type=$type\n"; if($this->{ini}->{nFilmLayers} == 0) { return $this->ReadSampleDataFile($this->{ini}->{SubstrateCSVFile} = $filepath, 1, 1); } $this->{Layers} = undef; $this->{Optimize} = undef; $this->{Substrate} = new Ellipsometry; $this->{SubstratePath} = $filepath; my ($nData, $pLabelArray, @pDataArray) = $this->{Substrate}->Read($filepath); if(!defined $nData) { $App->print("Error: Can not read [$filepath].\n"); return $this->{SubstratePath} = undef; } $this->CreateGraphFrame() if(!$this->GetGraphFrameArray()); $this->RefreshViewRangePane($this->{EntryWidth}); if($this->{ini}->{nFilmLayers} == 0) { $this->RePlot(1); } # $this->CreateGraphFrame(); # $this->AssignGraphData(); return $filepath; } sub ReadSampleDataFile { my ($this, $filepath, $IsPrint, $RePlot) = @_; my $App = $this->App(); $RePlot = 1 if(!defined $RePlot); #print "type=$type\n"; $this->Initialize(0, 1); $this->{Path} = $filepath; my ($nData, $pLabelArray, @pDataArray) = $this->{Ellipsometry}->Read($filepath); if(!defined $nData) { $App->print("Error: Can not read [$filepath].\n"); return $this->{Path} = undef; } my $nDataArray = $this->{Ellipsometry}->nDataArray(); #print "nDataArray: $nDataArray\n"; $this->{"ChooseXListBox"}->DeleteAllItem(); $this->{"ChooseY1ListBox"}->DeleteAllItem(); $this->{"ChooseY2ListBox"}->DeleteAllItem(); for(my $i = 0 ; $i < $nDataArray ; $i++) { #print "$i: $pLabelArray->[$i]\n"; $this->{"ChooseXListBox"}->AddItem($pLabelArray->[$i]); $this->{"ChooseY1ListBox"}->AddItem($pLabelArray->[$i]); $this->{"ChooseY2ListBox"}->AddItem($pLabelArray->[$i]); } $this->{"ChooseXListBox"}->SetCurSel('.*E.*', '.*eV.*'); $this->{"ChooseY1ListBox"}->SetCurSel('R', 'e1', 'n', 'Psi'); $this->{"ChooseY2ListBox"}->SetCurSel('T', 'e2', 'k', 'Delta'); $this->CreateGraphFrame() if(!$this->GetGraphFrameArray()); $this->RefreshViewRangePane($this->{EntryWidth}); if($RePlot) { $this->RePlot(1); } else { # $this->CreateGraphFrame(); # $this->AssignGraphData(); } return $filepath; } sub SaveForSCOUT { my ($this) = @_; my $App = $this->App(); my $optics = new Optics; my $ini = $this->{ini}; my $pE = $this->{Ellipsometry}->GetData('E.*', '.*eV.*'); my $pR = $this->{Ellipsometry}->GetData('R.*'); my $pT = $this->{Ellipsometry}->GetData('T.*'); my $nData = @$pE; my $path = $this->ChooseSaveFile(); return if(!defined $path); my $out = new JFile; if(!$out->Open($path, "w")) { $App->print("Error: Can not write to [$path].\n"); return undef; } $out->print("E(eV),wl(nm),R,T\n"); for(my $i = 0 ; $i < $nData ; $i++) { my $E = $pE->[$i]; my $wl = Optics::eVTonm($E); my $R = $pR->[$i]; my $T = $pT->[$i]; $out->print("$E,$wl,$R,$T\n"); } $out->Close(); $path = "$path.txt"; $App->print("Parameters are stored in [$path].\n"); $out = new JFile; if(!$out->Open($path, "w")) { $App->print("Error: Can not write to [$path].\n"); return undef; } $out->print("[Background]\n"); $out->print("e1 : $ini->{e1inf}\n"); $out->print("e2 : $ini->{e2inf}\n"); $out->print("\n"); $out->print("[Tauc-Lorentz]\n"); $out->print("A : $ini->{A}\n"); $out->print("C : $ini->{C}\n"); my $EgK = Optics::eVToKiser($ini->{Eg}); $out->printf("Eg : %12.6g eV %12.6g cm-1\n", $ini->{Eg}, $EgK); $EgK = Optics::eVToKiser($ini->{En0}); $out->printf("En0: %12.6g eV %512.6g cm-1\n", $ini->{En0}, $EgK); $out->print("\n"); for(my $i = 1 ; ; $i++) { last if(!defined $ini->{"Ne$i"}); $out->print("[Lorentz$i]\n"); $EgK = Optics::eVToKiser($ini->{"E0$i"}); $out->printf("E0 : %12.6g %12.6g cm-1\n", $ini->{"E0$i"}, $EgK); $EgK = Optics::eVToKiser($ini->{"G$i"}); $out->printf("G : %12.6g eV %12.6g cm-1\n", $ini->{"G$i"}, $EgK); my $A = $optics->CalLorentzAfromNe($ini->{"Ne$i"}, 1.0); $out->printf("Ne : %12.6g cm-3 A=%12.6g\n", $ini->{"Ne$i"}, $A); $out->print("\n"); } for(my $i = 1 ; ; $i++) { last if(!defined $ini->{"DrudeEp$i"}); $out->print("[Drude$i]\n"); $EgK = Optics::eVToKiser($ini->{"DrudeEp$i"}); $out->printf("Ep : %12.6g %12.6g cm-1\n", $ini->{"DrudeEp$i"}, $EgK); my $EgeV = Optics::HzToeV(1.0 / $ini->{"Drudetau$i"}); $EgK = Optics::eVToKiser($EgeV); $out->printf("tau: %12.6g s %12.6g cm-1 %12.6g eV\n", $ini->{"Drudetau$i"}, $EgK, $EgeV); $out->print("\n"); } $out->Close(); } sub CreateGraphFrame { my ($this, $canvas, $TargetData) = @_; $canvas = $this->Canvas(); my $App = $this->App(); my $font = $App->{'GraphFrameFont'}; my @font = split(/,/, $font) if($font); my $w = $canvas->width(); my $h = $canvas->height(); # my $FileType = $this->FileType(); # return undef unless($FileType); # my $pDataArray = $this->DataArray(); # return unless($pDataArray); my $GraphFrameArray = $this->{'GraphFrameArray'} = new GraphFrameArray($this->mw()); $GraphFrameArray->SetCanvasSize($w, $h); $GraphFrameArray->AddGraphFrame(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); my $FramePosStr0 = $App->{"GraphFrame0Position"}; $GraphFrame0->SetXCaption(""); my $XScale0 = $GraphFrame0->GetXScale(0); my $YScale0 = $GraphFrame0->GetYScale(0); $GraphFrame0->SetPositionByStr($FramePosStr0); $XScale0->SetScaleStringVisible(0); $XScale0->SetCaptionVisible(1); $GraphFrameArray->AddGraphFrame(); my $GraphFrame1 = $GraphFrameArray->GetGraphFrame(1); $GraphFrame1->SetYCaption(""); my $FramePosStr1 = $App->{"GraphFrame1Position"}; my $XScale1 = $GraphFrame1->GetXScale(0); my $YScale1 = $GraphFrame1->GetYScale(0); $GraphFrame1->SetPositionByStr($FramePosStr1); $XScale1->SetScaleStringVisible(1); $XScale1->SetCaptionVisible(1); $GraphFrame0->SetViewRange(0, 0, 1, 1); $GraphFrame1->SetViewRange(0, 0, 1, 1); } sub ShowScaleDialog { my ($this, $GraphFrame, $command, $Title, @a) = @_; #$command: "XScale" "YScale" #最初の4つのundefはViewRangeに現在値を使う #次の2つのundefはPlotTypeに現在値を使う設定 #そのあとの1,0は、X,Y軸のPlotTypeの同期をおこなうかどうか #最後の1は、ScaleDialogでOKを押されたらグラフの再描画を行う #  Y軸のViewRangeは同期するが、PlotTypeの同期は無視する return $GraphFrame->ShowScaleDialog($Title, undef, undef, undef, undef, undef, undef, 1, 0, 1); } sub AdjustViewRange($$) { my ($this) = @_; my $GraphFrameArray = $this->GetGraphFrameArray(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); $GraphFrame0->SetViewRange($GraphFrame0->GetViewRange(), 1) if($GraphFrame0); } sub AssignGraphData { my ($this, $ResetViewRange) = @_; return if(!defined $this->mw()->{ViewRangePaneFrame}->{GraphFrame2YAxisListBox}); $ResetViewRange = 1 if(!defined $ResetViewRange); my $ini = $this->{ini}; #my @YList = ('x', 'log(|x|)', '(ahv)^1/2 (Tauc)', 'a^1/2 (Indirect)', 'a^2 (Direct'); my $YAxisPlotType = $this->mw()->{ViewRangePaneFrame}->{GraphFrame2YAxisListBox}->GetText(); my $YConvFunc = sub { my ($x,$y)=@_; $this->LinearY($x,$y); }; my $AbsorptionLabel = 'Absorption'; if($YAxisPlotType eq 'x') { } elsif($YAxisPlotType eq 'log(|x|)') { $YConvFunc = sub { my ($x,$y)=@_; $this->LogAbsY($x,$y); }; $AbsorptionLabel = 'log(|abs|)'; } elsif($YAxisPlotType =~ /Tauc/) { $YConvFunc = sub { my ($x,$y)=@_; $this->Tauc($x,$y); }; $AbsorptionLabel = '(ahv)^1/2'; } elsif($YAxisPlotType =~ /Indirect\)/) { $YConvFunc = sub { my ($x,$y)=@_; $this->SquareRoot($x,$y); }; $AbsorptionLabel = '(ahv)^1/2'; } elsif($YAxisPlotType =~ /Direct\)/) { $YConvFunc = sub { my ($x,$y)=@_; $this->Square($x,$y); }; $AbsorptionLabel = '(ahv)^1/2'; } $AbsorptionLabel =~ s/ \(.*?\)$//; my $GraphFrameArray = $this->GetGraphFrameArray(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); my $GraphFrame1 = $GraphFrameArray->GetGraphFrame(1); $GraphFrame0->ClearAllData(); $GraphFrame1->ClearAllData(); my $XLabel = $this->{"ChooseXListBox"}->GetText(); $XLabel = 'X' if(!$XLabel); my $Y1Label = $this->{"ChooseY1ListBox"}->GetText(); $Y1Label = 'Y1' if(!$Y1Label); my $Y2Label = $this->{"ChooseY2ListBox"}->GetText(); $Y2Label = 'Y2' if(!$Y2Label); $GraphFrame0->SetXCaption($XLabel); my $pX = $this->{Ellipsometry}->GetData($XLabel, '.*E.*', '.*eV.*'); my $pY1 = $this->{Ellipsometry}->GetData($Y1Label); my $pY2 = $this->{Ellipsometry}->GetData($Y2Label); my $nData = $this->{Ellipsometry}->nData(); my $YLabel = ''; $YLabel .= $Y1Label if($pY1); $YLabel .= ",$Y2Label" if($pY2); $GraphFrame0->SetXCaption(""); $GraphFrame0->SetYCaption("$Y1Label,$Y2Label"); if($ini->{ShowSamplePlot} and $pX) { my $ini = $this->{ini}; my (@y1, @y2); for(my $i = 0 ; $i < @$pX ; $i++) { my $E = $pX->[$i]; my $lwl = $ini->{Rayleighl0} / Optics::eVTonm($E); my $lwl2 = $lwl * $lwl; # my $sf = $ini->{Scale} - $lwl2 * $lwl2; my $Tsf = $ini->{Scale} / (1.0 - $lwl2 * $lwl2); my $Rsf = $ini->{RScale} / (1.0 - $lwl2 * $lwl2); if($pY1) { $y1[$i] = $pY1->[$i] * $Rsf; } if($pY2) { $y2[$i] = $pY2->[$i] * $Tsf; } } $GraphFrame0->AddGraphData($pX, \@y1, 2, "black", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "${Y1Label}(obs)") if($pY1); $GraphFrame0->AddGraphData($pX, \@y2, 2, "red", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "${Y2Label}(obs)") if($pY2); } if($ini->{ShowSamplePlot} and $pX and $pY1 and $pY2) { my @alpha; my $il = $this->{ini}->{nFilmLayers}; my $d; if($this->{ini}->{nFilmLayers} > 0) { $d = $this->{ini}->{"Film${il}Thickness"} * 1.0e-7; # cm } else { $d = $this->{ini}->{"SubstrateThickness"} * 1.0e-1; # cm } for(my $i = 0 ; $i < @$pX ; $i++) { my $E = $pX->[$i]; my $lwl = $ini->{Rayleighl0} / Optics::eVTonm($E); my $lwl2 = $lwl * $lwl; my $Tsf = $ini->{Scale} / (1.0 - $lwl2 * $lwl2); my $Rsf = $ini->{RScale} / (1.0 - $lwl2 * $lwl2); my $R = $pY1->[$i] * $Rsf; my $T = $pY2->[$i] * $Tsf; my $Tc = $T / (1.0 - $R); $Tc = 1.0 if($Tc <= 0.0); $alpha[$i] = -log($Tc) / $d; } my ($pConvX, $pConvY) = $this->ConvertXY($YConvFunc, $pX, \@alpha); $GraphFrame1->AddGraphData($pConvX, $pConvY, 2, "black", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "alpha(obs)"); } my $pCalE = $this->{pEArray}; my $pCalR = $this->{pRArray}; my $pCalT = $this->{pTArray}; if($ini->{ShowCalcPlot} and $pCalE) { $GraphFrame0->AddGraphData($pCalE, $pCalR, 0, "black", "circle", 3, "", 1, "black", "XAutoSkip", "Energy", "${Y1Label}(cal)") if($pCalR and $pY1); # 1, "black", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "${Y1Label}(cal)") if($pCalR and $pY1); $GraphFrame0->AddGraphData($pCalE, $pCalT, 0, "red", "circle", 3, "", 1, "red", "XAutoSkip", "Energy", "${Y2Label}(cal)") if($pCalT and $pY2); # 1, "red", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "${Y2Label}(cal)") if($pCalT and $pY2); my @alpha; my $il = $this->{ini}->{nFilmLayers}; my $d; if($this->{ini}->{nFilmLayers} > 0) { $d = $this->{ini}->{"Film${il}Thickness"} * 1.0e-7; # cm } else { $d = $this->{ini}->{"SubstrateThickness"} * 1.0e-1; # cm } for(my $i = 0 ; $i < @$pCalR ; $i++) { my $R = $pCalR->[$i]; my $T = $pCalT->[$i]; #print "E=$pCalE->[$i]: R,T=$R,$T\n"; my $Tc; if($R == 1.0) { $Tc = 0.0; } else { $Tc = $T / (1.0 - $R); } $Tc = 1.0 if($Tc <= 0.0); #print "R=$R,$T,$Tc\n"; $alpha[$i] = -log($Tc) / $d; } my ($pConvX, $pConvY) = $this->ConvertXY($YConvFunc, $pCalE, \@alpha); $GraphFrame1->AddGraphData($pConvX, $pConvY, 0, "black", "circle", 3, "", 1, "black", "XAutoSkip", "Energy", "alpha(cal)"); } if($ini->{ShowPbPPlot} and $this->{PbPE}) { $GraphFrame0->AddGraphData($this->{PbPE}, $this->{PbPR}, 0, "", "square", 3, "", 1, "black", "XAutoSkip", "Energy", "${Y1Label}(PbP)"); # 1, "black", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "${Y1Label}(PbP)"); $GraphFrame0->AddGraphData($this->{PbPE}, $this->{PbPT}, 0, "", "square", 3, "", 1, "red", "XAutoSkip", "Energy", "${Y2Label}(PbP)"); # 1, "red", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "${Y2Label}(PbP)"); my @alpha; my $il = $this->{ini}->{nFilmLayers}; my $d; if($this->{ini}->{nFilmLayers} > 0) { $d = $this->{ini}->{"Film${il}Thickness"} * 1.0e-7; # cm } else { $d = $this->{ini}->{"SubstrateThickness"} * 1.0e-1; # cm } my $pE = $this->{PbPE}; for(my $i = 0 ; $i < @$pE ; $i++) { # for(my $i = 0 ; $i < @$pCalR ; $i++) { my $R = $this->{PbPR}->[$i]; my $T = $this->{PbPT}->[$i]; my $Tc = $T / (1.0 - $R); $Tc = 1.0 if($Tc <= 0.0); #print "R=$R,$T,$Tc\n"; $alpha[$i] = -log($Tc) / $d; } my ($pConvX, $pConvY) = $this->ConvertXY($YConvFunc, $this->{PbPE}, \@alpha); $GraphFrame1->AddGraphData($pConvX, $pConvY, 0, "black", "square", 3, "", 1, "black", "XAutoSkip", "Energy", "alpha(PbP)"); } $GraphFrame0->SetXScalePlotType('x'); $GraphFrame0->SetYScalePlotType('x'); $GraphFrame1->SetXScalePlotType('x'); $GraphFrame1->SetYScalePlotType('x'); $GraphFrame1->SetXCaption("Energy / eV"); $GraphFrame1->SetYCaption(""); if($GraphFrame1) { $GraphFrame0->AddSynchronousFrame('x', $GraphFrame1); $GraphFrame1->AddSynchronousFrame('x', $GraphFrame0); } $this->SetViewRange($ResetViewRange); } sub InitializeParameters { my ($this, $ini, $dini) = @_; $this->SUPER::InitializeParameters($ini, $dini); $this->AddParameters($ini, $dini, "KConductivity", 0.0, 0, 0.01, 0.0, ''); $this->AddParameters($ini, $dini, "KMobility", 0.0, 0, 0.01, 0.0, ''); } 1;