#=============================================== # PESFit #=============================================== package PESFit; use TkFittingCommon2; @ISA = qw(TkFittingCommon2); #公開したいサブルーチン #@EXPORT = qw(DelSpace Reduce01 MakePath RegExpQuote); use strict; use Utils; use IniFile; use CSV; use MyTk::GraphFrameArray; use MyTk::MyDragDrop; use GraphData; use Sci qw($NA $hbar $e $me $pi $eVToJ); use Sci::Science; use Sci::PES; use Sci::Ellipsometry; use Sci::Optimize; use Sci::ChemicalReaction; #============================================================ # 変数等取得関数 #============================================================ my $ProgramName = "PES2016"; #============================================================ # コンストラクタ、デストラクタ #============================================================ #呼び出されることはない sub new { my ($class, $app, @a) = @_; # my ($module, $app, $canvas) = @_; my $self = TkFittingCommon2->new($app, @a); my $this = bless $self, $class; # my $this = {}; # bless $this; $this->SetApplication($app) if($app); # $this->SetCanvas($canvas) if($canvas); return $this; } sub DESTROY { my $this = shift; $this->SUPER::DESTROY(@_); } #============================================================ # 継承クラスで定義しなおす関数 #============================================================ sub CreateLeftFrame { my ($this, $ConfigSide, @args) = @_; # return $this->SUPER::CreateLeftFrame(); return undef; } sub CreateSelectFilePane { my ($this) = @_; # return $this->SUPER::CreateSelectFilePane(); return undef; } sub CreateFileContentPane { return undef; } sub CreateWidgets { my ($this, $DoSuperOnly) = @_; $DoSuperOnly = 0 if(!defined $DoSuperOnly); my $mw = $this->mw(); $this->{ini} = new IniFile(undef, 0, 0); $this->{dini} = new IniFile(undef, 0, 0); $this->{ini}->{nStepBG} = 1; $this->{ini}->{nGL} = 3; # $this->{DataFile} = new Ellipsometry; $this->InitializeParameters($this->{ini}, $this->{dini}); $this->SUPER::CreateWidgets(); return if($DoSuperOnly); $mw->SetTitle("$ProgramName / TkPlot"); $this->App()->SetProgram("$ProgramName / TkPlot"); #=================================================== # ペインを作製 #=================================================== my $EntryWidth = $this->{EntryWidth} = 12; $mw->{NoteBook} = $this->MakeNotebookPanes($mw, $EntryWidth, $this->{ini}->pVariable("nFilmLayers", 1), $this->{ini}->pVariable("nLorentz", 3), $this->{ini}->pVariable("nDrude", 0), $this->{ini}->pVariable("nStepBG", 2), $this->{ini}->pVariable("nGL", 3), [qw(Main Vars1 Vars2 ViewRange LSQ GaussLorentz Setup GraphFrame)], [qw(nPESStepBG nGaussLorentz)], ); $mw->{NoteBook}->pack(-fill => 'both', -expand => 'yes'); $this->UpdateParameters(); #ツールバーのOpenボタンをファイル読み込みにバインドする my $Samplefmask = '*.csv;*.spe;*.jel;*.asp;*.smo;*isa;*.ref;*.pal;*.bef;*.aft;*.txt'; $mw->{OpenButton}->configure( -command => sub { $this->{SampleCSV} = $this->ChooseFile("open", $Samplefmask, "ChooseSampleFile", "SampleCSV", $this->{SampleFileFrame}); }, ) if($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); }, ], ); my $IniFile = $this->App()->IniFile(); # $this->SetGeometry($IniFile->GetString("Window", "geometry", '')); $this->InitWindowPosition($IniFile->GetString("Window", "geometry", '')); $this->OnDestroy( sub { $this->App()->IniFile()->WriteString("Window", "geometry", $this->geometry()); # $this->Close(); } ); # $this->{FileNameEntry}->bind('' => sub { $this->Close(); } ); $this->bind('' => sub { my ($widget) = @_; if($widget =~ /PESFit=/) { $this->App()->IniFile()->WriteString("Window", "geometry", $this->geometry()); } } ); } sub BuildMainPane { my ($this, $MainPaneFrame, $EntryWidth) = @_; my $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->BuildFooter($MainPaneFrame, $EntryWidth); my $savefmask = '*.prm'; $this->{ParameterFileFrame} = $this->MakeChooseFileEntry( $Frame, 'Param', 'Param:', $this->{ini}->pVariable("ParameterFile", ""), '&Choose', sub { $this->ChooseFile("save", $savefmask, "ChooseParameterFile", @_); }, 1, sub { $this->SaveParameterFile("SaveParam", '', @_); }, 1, sub { $this->EditFile('EditParam', @_); }, [] ); $this->{ParameterFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $Samplefmask = '*.csv;*.spe;*.jel;*.asp;*.smo;*isa;*.ref;*.pal;*.bef;*.aft;*.txt'; $this->{SampleFileFrame} = $this->MakeChooseFileEntry( $Frame, 'SampleCSV', 'Sample:', $this->{ini}->pVariable("SampleCSVFile", ""), '&Choose', sub { $this->{SampleCSV} = $this->ChooseFile("open", $Samplefmask, "ChooseSampleFile", @_); $this->AssignGraphData(); $this->Draw(); }, 0, sub {}, 1, sub { $this->EditFile('EditSampleCSV', @_); }, ['X1', 'Y1'] ); $this->{SampleFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $this->{SampleFileFrame}->{pXDataLabel} = ['.*E.*', '.*eV.*']; $this->{SampleFileFrame}->{pYDataLabel} = ['.*signal.*', 'i.*', '.*']; $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->mw()->{LSQFrame2} = $this->MakeLSQPanes( $Frame, $EntryWidth, 'Fitting', [qw(FittingRange)], [], [], ['FitXMin', 'Emin:', 'FitXMax', 'Emax:', 'nSkipData', 'nSkip:'], ['EPS', 'EPS:', 'nMaxIter', 'MaxIter:', 'nSaveSpectraInterval', 'SaveIntvl:'], ); $this->mw()->{LSQFrame2}->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); $Frame = $MainPaneFrame->MyLabFrame( -label => 'Model', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); my $lsb5 = $this->{ChooseAppFunctionListBox} = $Frame->MyBrowseEntry( -variable => $this->{ini}->pVariable('AppFunction', 'Gauss'), -label => "App Function:", -state => "readonly", -takefocus => 1, -width => 8, -Selections => ['Gauss', 'Lorentz'], -SelIndex => 0, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $lsb5->configure(-browsecmd => sub { $this->SelChangeListBox("AppFunction", $this->{ChooseAppFunctionListBox}); }); my $CT = $this->{ini}->{ConductionType}; my $lsb6 = $this->{ChooseConductionTypeListBox} = $Frame->MyBrowseEntry( -variable => $this->{ini}->pVariable('ConductionType', 'Metal'), -label => "Conduction Type:", -state => "readonly", -takefocus => 1, -width => 10, -Selections => ['Metal', 'Semiconductor'], -SelIndex => 0, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $lsb6->configure(-browsecmd => sub { $this->SelChangeListBox("ConductionType", $this->{ChooseConductionTypeListBox}); }); $this->{ini}->{ConductionType} = $CT; $lsb6->SetText($this->{ini}->{ConductionType}) if(defined $this->{ini}->{ConductionType}); $Frame = $MainPaneFrame->MyLabFrame( -label => 'Fermi-Dirac distribution', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $this->MakeCheckEntry($Frame, "EF", "EF:", $this->{dini}->pVariable('EFcheck', 0), $this->{ini}->pVariable('EF', 0.0), "%g", $EntryWidth, "eV", 0, 0); $this->MakeCheckEntry($Frame, "T", "T:", $this->{dini}->pVariable('Tcheck', 0), $this->{ini}->pVariable('T', 300.0), "%g", $EntryWidth, "K", 0, 1); $this->MakeCheckEntry($Frame, "Wa", "Wa:", $this->{dini}->pVariable('Wacheck', 1), $this->{ini}->pVariable('Wa', 0.1), "%g", $EntryWidth, "eV", 0, 2); $Frame = $MainPaneFrame->MyLabFrame( -label => 'Constant / Step BGs', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); my $EntryWidth2 = 8; $this->MakeCheckEntry($Frame, "BG", "BG:", $this->{dini}->pVariable('BGcheck', 0), $this->{ini}->pVariable('BG', 0.0), "%g", $EntryWidth2, "", 0, 0); $this->MakeCheckEntry($Frame, "EBGSL0", "E0(SL):", $this->{dini}->pVariable('EBGSL0check', 0), $this->{ini}->pVariable('EBGSL0', 0.0), "%g", $EntryWidth2, "", 0, 1); $this->MakeCheckEntry($Frame, "BGSL0", "BG0(SL):", $this->{dini}->pVariable('BGSL0check', 0), $this->{ini}->pVariable('BGSL0', 0.0), "%g", $EntryWidth2, "", 0, 2); $this->MakeCheckEntry($Frame, "EBGSL1", "E1(SL):", $this->{dini}->pVariable('EBGSL1check', 0), $this->{ini}->pVariable('EBGSL1', 0.0), "%g", $EntryWidth2, "", 0, 3); for(my $i = 0 ; $i < $this->{ini}->{nStepBG} ; $i++) { $this->MakeCheckEntry($Frame, "EBG0$i", "E0:", $this->{dini}->pVariable("EBG0${i}check", 0), $this->{ini}->pVariable("EBG0$i", 0.0), "%g", $EntryWidth2, "eV", $i+1, 0); $this->MakeCheckEntry($Frame, "BGLeft$i", "Left:", $this->{dini}->pVariable("BGLeft${i}check", 0), $this->{ini}->pVariable("BGLeft$i", 0.0), "%g", $EntryWidth2, "", $i+1, 1); $this->MakeCheckEntry($Frame, "WBG$i", "W:", $this->{dini}->pVariable("WBG${i}check", 0), $this->{ini}->pVariable("WBG$i", 0.3), "%g", $EntryWidth2, "eV", $i+1, 2); } $Frame = $MainPaneFrame->MyLabFrame( -label => 'Conduction / Valnce bands, Cut off, Secondary electron exponent', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $this->MakeCheckEntry($Frame, "ECBM", "ECBM:", $this->{dini}->pVariable('ECBMcheck', 0), $this->{ini}->pVariable('ECBM', 0.0), "%g", $EntryWidth, "eV", 0, 0); $this->MakeCheckEntry($Frame, "D0CB", "D0:", $this->{dini}->pVariable('D0CBcheck', 0), $this->{ini}->pVariable('D0CB', 0.0), "%g", $EntryWidth, "", 0, 1); $this->MakeCheckEntry($Frame, "k0Metal", "k0(metal):", $this->{dini}->pVariable('k0Metalcheck', 0), $this->{ini}->pVariable('k0Metal', 0.0), "%g", $EntryWidth, "", 0, 2); $this->MakeCheckEntry($Frame, "EVBM", "EVBM:", $this->{dini}->pVariable('EVBMcheck', 0), $this->{ini}->pVariable('EVBM', 0.0), "%g", $EntryWidth, "eV", 1, 0); $this->MakeCheckEntry($Frame, "D0VB", "D0:", $this->{dini}->pVariable('D0VBcheck', 0), $this->{ini}->pVariable('D0VB', 0.0), "%g", $EntryWidth, "", 1, 1); $this->MakeCheckEntry($Frame, "Ecut", "Ecut:", $this->{dini}->pVariable('Ecutcheck', 0), $this->{ini}->pVariable('Ecut', 0.0), "%g", $EntryWidth, "eV", 2, 0); $this->MakeCheckEntry($Frame, "K0Ecut", "K0:", $this->{dini}->pVariable('K0Ecutcheck', 0), $this->{ini}->pVariable('K0Ecut', 0.0), "%g", $EntryWidth, "", 2, 1); $this->MakeCheckEntry($Frame, "BGcut", "BG:", $this->{dini}->pVariable('BGcutcheck', 0), $this->{ini}->pVariable('BGcut', 0.0), "%g", $EntryWidth, "", 2, 2); $this->MakeCheckEntry($Frame, "C0Exp", "C0:", $this->{dini}->pVariable('C0Expcheck', 0), $this->{ini}->pVariable('C0Exp', 0.0), "%g", $EntryWidth, "", 3, 0); $this->MakeCheckEntry($Frame, "WExp", "W:", $this->{dini}->pVariable('WExpcheck', 0), $this->{ini}->pVariable('WExp', 1.0), "%g", $EntryWidth, "eV", 3, 1); $this->MakeCheckEntry($Frame, "BetaExp", "beta:", $this->{dini}->pVariable('BetaExpcheck', 0), $this->{ini}->pVariable('BetaExp', 1.0), "%g", $EntryWidth, "", 3, 2); # $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $Frame = $MainPaneFrame->MyLabFrame( -label => 'Gauss-Lorentz functions', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); for(my $i = 0 ; $i < $this->{ini}->{nGL} ; $i++) { $this->MakeCheckEntry($Frame, "GLE0$i", "E0:", $this->{dini}->pVariable("GLE0${i}check", 0), $this->{ini}->pVariable("GLE0$i", 0.0), "%g", $EntryWidth, "eV", 2*$i, 0); $this->MakeCheckEntry($Frame, "GLC0$i", "C0:", $this->{dini}->pVariable("GLC0${i}check", 0), $this->{ini}->pVariable("GLC0$i", 0.0), "%g", $EntryWidth, "", 2*$i, 1); $this->MakeCheckEntry($Frame, "GLWL$i", "WL:", $this->{dini}->pVariable("GLWL${i}check", 0), $this->{ini}->pVariable("GLWL$i", 0.3), "%g", $EntryWidth, "", 2*$i, 2); $this->MakeCheckEntry($Frame, "GLGFraction$i", "GaussF:", $this->{dini}->pVariable("GLGFraction${i}check", 0), $this->{ini}->pVariable("GLGFraction$i", 1.0), "%g", $EntryWidth, "", 2*$i+1, 1); $this->MakeCheckEntry($Frame, "GLGWRatio$i", "WRatio:", $this->{dini}->pVariable("GLGWRatio${i}check", 0), $this->{ini}->pVariable("GLGWRatio$i", 1.0), "%g", $EntryWidth, "", 2*$i+1, 2); } $Frame = $MainPaneFrame->MyLabFrame( -label => 'IGZO', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); $this->MakeLabelEntry($Frame, "Composition", "Composition:", $this->{ini}->pVariable("Composition", 'InGaZnO4'), "%s", 10, '', 0, 0); $this->MakeLabelEntry($Frame, "MW", "MW:", $this->{ini}->pVariable("MW", 0.0), "%f", 10, 'g/mol', 0, 1, "disable"); $this->MakeLabelEntry($Frame, "Density", "Density:", $this->{ini}->pVariable("Density", 6.0), "%f", 10, 'g/cm3', 0, 2); $this->MakeLabelEntry($Frame, "EVBCut", "E(VB cut):", $this->{ini}->pVariable("EVBCut", 0.0), "%g", 10, 'eV', 1, 0); $this->MakeLabelEntry($Frame, "EZn3d", "E(Zn3d):", $this->{ini}->pVariable("EZn3d", 0.0), "%g", 10, 'eV', 2, 0); $this->MakeLabelEntry($Frame, "Evalley", "E(valley):", $this->{ini}->pVariable("Evalley", 0.0), "%g", 10, 'eV', 2, 1); $this->MakeLabelEntry($Frame, "EO2p", "E(O2p):", $this->{ini}->pVariable("EO2p", 0.0), "%g", 10, 'eV', 2, 2); $this->MakeLabelEntry($Frame, "O2pNe", "Ne(O2p):", $this->{ini}->pVariable("NeO2p", 0.0), "%10.4g", 10, '/cm3', 3, 0, "disable"); $this->MakeLabelEntry($Frame, "NeHall", "Ne(Hall):", $this->{ini}->pVariable("NeHall", 0.0), "%10.4g", 10, 'cm-3', 4, 0); $this->BuildFooter($MainPaneFrame, $EntryWidth); $this->UpdateParameters(); } sub BuildVars1Pane { my ($this, $MainPaneFrame, $EntryWidth) = @_; my $Frame = $MainPaneFrame->MyLabFrame( -label => 'Fermi-Dirac distribution', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); my $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); my @list = qw(EF T Wa); foreach my $key (@list) { $this->MakeParameterConditionColumn($Frame, "$key", "$key:", "%12.6g", $this->{dini}->pVariable("$key", 0.0), $this->{dini}->pVariable("${key}check", 0), $this->{dini}->pVariable("${key}scale", 0.1), $this->{dini}->pVariable("${key}min", ''), $this->{dini}->pVariable("${key}max", ''), $EntryWidth, $row++); } $Frame = $MainPaneFrame->MyLabFrame( -label => 'Constant / Step BGs', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); @list = qw(BG); foreach my $key (@list) { $this->MakeParameterConditionColumn($Frame, "$key", "$key:", "%12.6g", $this->{dini}->pVariable("$key", 0.0), $this->{dini}->pVariable("${key}check", 0), $this->{dini}->pVariable("${key}scale", 0.1), $this->{dini}->pVariable("${key}min", ''), $this->{dini}->pVariable("${key}max", ''), $EntryWidth, $row++); } my $nBG = ($this->{ini}->{nStepBG} > 3)? $this->{ini}->{nStepBG} : 3; for(my $i = 0 ; $i < $nBG ; $i++) { my @list = qw(EBG0 BGLeft WBG); foreach my $key0 (@list) { my $key = "$key0$i"; $this->MakeParameterConditionColumn($Frame, "$key", "$key:", "%12.6g", $this->{dini}->pVariable("$key", 0.0), $this->{dini}->pVariable("${key}check", 0), $this->{dini}->pVariable("${key}scale", 0.1), $this->{dini}->pVariable("${key}min", ''), $this->{dini}->pVariable("${key}max", ''), $EntryWidth, $row++); } } $Frame = $MainPaneFrame->MyLabFrame( -label => 'Conduction / Valnce bands, Cut off, Secondary electron exponent', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); @list = qw(ECBM D0CB k0Metal EVBM D0VB Ecut K0Ecut BGcut C0Exp WExp BetaExp); foreach my $key (@list) { $this->MakeParameterConditionColumn($Frame, "$key", "$key:", "%12.6g", $this->{dini}->pVariable("$key", 0.0), $this->{dini}->pVariable("${key}check", 0), $this->{dini}->pVariable("${key}scale", 0.1), $this->{dini}->pVariable("${key}min", ''), $this->{dini}->pVariable("${key}max", ''), $EntryWidth, $row++); } $this->BuildFooter($MainPaneFrame, $EntryWidth); $this->UpdateParameters(); } sub BuildVars2Pane { my ($this, $MainPaneFrame, $EntryWidth) = @_; my $Frame = $MainPaneFrame->MyLabFrame( -label => 'Gauss-Lorentz functions', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); my $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); for(my $i = 0 ; $i < $this->{ini}->{nGL} ; $i++) { my @list = qw(GLE0 GLC0 GLWL GLGFraction GLGWRatio); foreach my $key0 (@list) { my $key = "$key0$i"; $this->MakeParameterConditionColumn($Frame, "$key", "$key:", "%12.6g", $this->{dini}->pVariable("$key", 0.0), $this->{dini}->pVariable("${key}check", 0), $this->{dini}->pVariable("${key}scale", 0.1), $this->{dini}->pVariable("${key}min", ''), $this->{dini}->pVariable("${key}max", ''), $EntryWidth, $row++); } } $this->BuildFooter($MainPaneFrame, $EntryWidth); $this->UpdateParameters(); } sub BuildLSQPane { my ($this, $MainPaneFrame, $EntryWidth) = @_; my $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->mw()->{LSQFrame} = $this->MakeLSQPanes( $Frame, $EntryWidth, 'Fitting', [qw(LSQMethod FittingRange FittingConditions)], # [qw(LSQMethod FitTo FittingRange FittingConditions)], ['Amoeba::Simplex', 'PDL::Simplex', 'ModifiedNewton'], ['PES'], ['FitXMin', 'Emin:', 'FitXMax', 'Emax:', 'nSkipData', 'nSkip:'], ['EPS', 'EPS:', 'nMaxIter', 'MaxIter:', 'nSaveSpectraInterval', 'SaveIntvl:'], ); $this->mw()->{LSQFrame}->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); # $this->mw()->{LSQFrame}->{FitToListBox}->SetText('alpha'); $this->BuildFooter($MainPaneFrame, $EntryWidth); } sub BuildViewRangePane { my ($this, $MainFrame, $EntryWidth) = @_; $this->SUPER::BuildViewRangePane($MainFrame, $EntryWidth, [ ['x'], ['x'] ], [ ['x'], ['x'] ] ); if($this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1ViewY0Button}) { $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1ViewY0Button}->Select(); $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1ViewY0Entry}->SetText(0.0); } $this->BuildFooter($MainFrame, $EntryWidth); } sub BuildFooter { my ($this, $MainFrame, $EntryWidth) = @_; my $Frame1 = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); # my $ButtonFrame = $this->MakeFittingButtons($Frame1, ("RePlot", "RestoreScale", "Re&calc", "&Fit", "Flip X", "&Save")); my $ButtonFrame = $this->MakeFittingButtons($Frame1, ("Re&calc", "&Fit", "Flip X", "IGZO VB", "&Save")); $ButtonFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); # $this->{RestoreScaleButton}->configure( # -command => sub { $this->RestoreScale(); }, # ); my $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->{ChooseExcitatioListBox} = $ButtonFrame->MyBrowseEntry( -label => "Excitation:", -state => "readonly", -takefocus => 1, -width => 15, -Selections => ["He I(21.2eV)", "He IIalpha(40.80eV)", "He IIbeta(48.36eV)", "Ne I(16.7eV)", "Ne II(26.9eV)", "Al Ka(1486.6eV)", "Mg Ka(1253.6eV)", "HX-PES(BL47XU, 7935.2eV)", "HX-PES(BL15XU, 5950.2eV)"], -SelIndex => 0, )->pack(-side => 'left'); } #sub RestoreScale #{ # my ($this, $ResetViewRange, $CreateGraphFrame, $AssignGraphData, $Draw) = @_; # $ResetViewRange = 1 if(!defined $ResetViewRange); # $this->RePlot($ResetViewRange, $CreateGraphFrame, $AssignGraphData, $Draw, $this->{ini}->{FlipX}); #} #sub RestoreViewScale #{ # my ($this, $ResetViewRange, $CreateGraphFrame, $AssignGraphData, $Draw) = @_; # $this->RestoreScale(); #} sub RePlot { my ($this, $ResetViewRange, $CreateGraphFrame, $AssignGraphData, $Draw) = @_; $this->Recalc(); } #=================================================== # データ処理 #=================================================== sub FlipX { my ($this, $FlipRange) = @_; $FlipRange = 1 if(!defined $FlipRange); my $App = $this->App(); # my $optics = new Optics; my $ini = $this->{ini}; return if(!defined $this->{DataFile}); #print "FlipX\n"; my $X1Label = $this->{SampleFileFrame}->{X1ListBox}->GetText(); # my $Y1Label = $this->{SampleFileFrame}->{Y1ListBox}->GetText(); my $pX = $this->{DataFile}->GetData($X1Label) if($X1Label); # my $pY1 = $this->{DataFile}->GetData($Y1Label) if($Y1Label); my $nData = $this->{DataFile}->nData(); for(my $i = 0 ; $i < $nData ; $i++) { $pX->[$i] = -$pX->[$i]; } ## $this->{DataFile}->CalMinMax(); ## ($ini->{FitXmin}, $ini->{FitXmax}) = $this->{DataFile}->GetXMinMax(); ($ini->{FitXMin}, $ini->{FitXMax}) = (-$ini->{FitXMax}, -$ini->{FitXMin}) if($FlipRange); # if($FlipRange) { if(!$this->{ini}->{FlipX}) { $this->{ini}->{FlipX} = 1; } else { $this->{ini}->{FlipX} = 0; } # $this->AssignGraphData(1); # $this->RestoreScale(1, 1, 1, 1); $this->SUPER::RePlot(); $this->RestoreViewScale(); } sub BuildOptimize { my ($this, $IsPrint) = @_; $IsPrint = 1 if(!defined $IsPrint); my $ini = $this->{ini}; my $dini = $this->{dini}; my $optimize = $this->{Optimize} = new Optimize;; $optimize->AddParameters( "EF", \$ini->{EF}, $dini->{EFcheck}, $dini->{EFscale}, $dini->{EFmin}, $dini->{EFmax}, sub { $ini->{EF} = $_[0]; }, "Wa", \$ini->{Wa}, $dini->{Wacheck}, $dini->{Wascale}, $dini->{Wamin}, $dini->{Wamax}, sub { $ini->{Wa} = $_[0]; }, "BG", \$ini->{BG}, $dini->{BGcheck}, $dini->{BGscale}, $dini->{BGmin}, $dini->{BGmax}, sub { $ini->{BG} = $_[0]; }, "BGSL0", \$ini->{BGSL0}, $dini->{BGSL0check}, $dini->{BGSL0scale}, $dini->{BGSL0min}, $dini->{BGSL0max}, sub { $ini->{BGSL0} = $_[0]; }, "EBGSL0", \$ini->{EBGSL0}, $dini->{EBGSL0check}, $dini->{EBGSL0scale}, $dini->{EBGSL0min}, $dini->{EBGSL0max}, sub { $ini->{EBGSL0} = $_[0]; }, "EBGSL1", \$ini->{EBGSL1}, $dini->{EBGSL1check}, $dini->{EBGSL1scale}, $dini->{EBGSL1min}, $dini->{EBGSL1max}, sub { $ini->{EBGSL1} = $_[0]; }, ); for(my $i = 0 ; $i < $this->{ini}->{nStepBG} ; $i++) { my $ii = $i; $optimize->AddParameters( "EBG0$ii", \$ini->{"EBG0$ii"}, $dini->{"EBG0${ii}check"}, $dini->{"EBG0${ii}scale"}, $dini->{"EBG0${ii}min"}, $dini->{"EBG0${ii}max"}, sub { $ini->{"EBG0$ii"} = $_[0]; }, "BGLeft$ii", \$ini->{"BGLeft$ii"}, $dini->{"BGLeft${ii}check"}, $dini->{"BGLeft${ii}scale"}, $dini->{"BGLeft${ii}min"}, $dini->{"BGLeft${ii}max"}, sub { $ini->{"BGLeft$ii"} = $_[0]; }, "WBG$ii", \$ini->{"WBG$ii"}, $dini->{"WBG${ii}check"}, $dini->{"WBG${ii}scale"}, $dini->{"WBG${ii}min"}, $dini->{"WBG${ii}max"}, sub { $ini->{"WBG$ii"} = $_[0]; }, ); } $optimize->AddParameters( "ECBM", \$ini->{ECBM}, $dini->{ECBMcheck}, $dini->{ECBMscale}, $dini->{ECBMmin}, $dini->{ECBMmax}, sub { $ini->{ECBM} = $_[0]; }, "D0CB", \$ini->{D0CB}, $dini->{D0CBcheck}, $dini->{D0CBscale}, $dini->{D0CBmin}, $dini->{D0CBmax}, sub { $ini->{D0CB} = $_[0]; }, "k0Metal", \$ini->{k0Metal}, $dini->{k0Metalcheck}, $dini->{k0Metalscale}, $dini->{k0Metalmin}, $dini->{k0Metalmax}, sub { $ini->{k0Metal} = $_[0]; }, "EVBM", \$ini->{EVBM}, $dini->{EVBMcheck}, $dini->{EVBMscale}, $dini->{EVBMmin}, $dini->{EVBMmax}, sub { $ini->{EVBM} = $_[0]; }, "D0VB", \$ini->{D0VB}, $dini->{D0VBcheck}, $dini->{D0VBscale}, $dini->{D0VBmin}, $dini->{D0VBmax}, sub { $ini->{D0VB} = $_[0]; }, "Ecut", \$ini->{Ecut}, $dini->{Ecutcheck}, $dini->{Ecutscale}, $dini->{Ecutmin}, $dini->{Ecutmax}, sub { $ini->{Ecut} = $_[0]; }, "K0Ecut", \$ini->{K0Ecut}, $dini->{K0Ecutcheck}, $dini->{K0Ecutscale}, $dini->{K0Ecutmin}, $dini->{K0Ecutmax}, sub { $ini->{K0Ecut} = $_[0]; }, "BGcut", \$ini->{BGcut}, $dini->{BGcutcheck}, $dini->{BGcutscale}, $dini->{BGcutmin}, $dini->{BGcutmax}, sub { $ini->{BGcut} = $_[0]; }, "C0Exp", \$ini->{C0Exp}, $dini->{C0Expcheck}, $dini->{C0Expscale}, $dini->{C0Expmin}, $dini->{C0Expmax}, sub { $ini->{C0Exp} = $_[0]; }, "WExp", \$ini->{WExp}, $dini->{WExpcheck}, $dini->{WExpscale}, $dini->{WExpmin}, $dini->{WExpmax}, sub { $ini->{WExp} = $_[0]; }, "BetaExp", \$ini->{BetaExp}, $dini->{BetaExpcheck}, $dini->{BetaExpscale}, $dini->{BetaExpmin}, $dini->{BetaExpmax}, sub { $ini->{BetaExp} = $_[0]; }, ); for(my $i = 0 ; $i < $this->{ini}->{nGL} ; $i++) { my $ii = $i; $optimize->AddParameters( "GLE0$ii", \$ini->{"GLE0$ii"}, $dini->{"GLE0${ii}check"}, $dini->{"GLE0${ii}scale"}, $dini->{"GLE0${ii}min"}, $dini->{"GLE0${ii}max"}, sub { $ini->{"GLE0$ii"} = $_[0]; }, "GLC0$ii", \$ini->{"GLC0$ii"}, $dini->{"GLC0${ii}check"}, $dini->{"GLC0${ii}scale"}, $dini->{"GLC0${ii}min"}, $dini->{"GLC0${ii}max"}, sub { $ini->{"GLC0$ii"} = $_[0]; }, "GLWL$ii", \$ini->{"GLWL$ii"}, $dini->{"GLWL${ii}check"}, $dini->{"GLWL${ii}scale"}, $dini->{"GLWL${ii}min"}, $dini->{"GLWL${ii}max"}, sub { $ini->{"GLWL$ii"} = $_[0]; }, "GLGFraction$ii", \$ini->{"GLGFraction$ii"}, $dini->{"GLGFraction${ii}check"}, $dini->{"GLGFraction${ii}scale"}, $dini->{"GLGFraction${ii}min"}, $dini->{"GLGFraction${ii}max"}, sub { $ini->{"GLGFraction$ii"} = $_[0]; }, "GLGWRatio$ii", \$ini->{"GLGWRatio$ii"}, $dini->{"GLGWRatio${ii}check"}, $dini->{"GLGWRatio${ii}scale"}, $dini->{"GLGWRatio${ii}min"}, $dini->{"GLGWRatio${ii}max"}, sub { $ini->{"GLGWRatio$ii"} = $_[0]; }, ); } } sub IGZOVB { my ($this) = @_; return if(!defined $this->{DataFile}); my $ini = $this->{ini}; my $dini = $this->{dini}; my $X1Label = $this->{SampleFileFrame}->{X1ListBox}->GetText(); my $Y1Label = $this->{SampleFileFrame}->{Y1ListBox}->GetText(); my $XMin = $ini->{FitXMin}; my $XMax = $ini->{FitXMax}; my $nSkipData = $ini->{nSkipData}; my $pX = $this->{DataFile}->GetData($X1Label) if($X1Label); my $pY1 = $this->{DataFile}->GetData($Y1Label) if($Y1Label); my $path = $this->{ini}->{ParameterFile}; $path = $this->{ini}->{SampleCSVFile} if(!$path); my ($drive, $directory, $filename, $ext1, $lastdir, $filebody) = Deps::SplitFilePath($path); my $dir = Deps::ExtractDirectory($path); my $TxtFile = Deps::MakePath($dir, "$filebody-IGZOVB.txt", 0); $this->print("\nSave IGZO VB text data to [$TxtFile].\n"); my $txt = new JFile($TxtFile, "w"); if(!$txt) { $this->print("Error: Can not write to [$TxtFile].\n"); return; } $this->Recalc(1);# if(!defined $this->{pCalX}); my $R = new ChemicalReaction(undef, undef, 'Composition'); my $Composition = $ini->{Composition}; $R->AnalyzeAReaction('Reagents', $Composition); my $pHash = $R->ReagentsHash(); my $pElements = $R->ElementsArray("Reagents"); my $w = 0.0; my $nO = 0; my $nM = 0; for(my $i = 0 ; $i < @$pElements ; $i++) { my $e = $pElements->[$i]; my $n = $R->nElement("Reagents", $e); #print "$e: $n\n"; my $pAtomDB = AtomType::GetAtomDBHash($e); if($pAtomDB->{name} eq 'O') { $nO += $n; } else { $nM += $n; } #print " Z=$pAtomDB->{Z}: M=$pAtomDB->{mass}\n"; $w += $n * $pAtomDB->{mass}; } $ini->{MW} = $w; # $ini->{MW} = $R->MolecularWeight($Composition); # $ini->{NeO2p} = $ini->{Density} / $ini->{MW} * $NA * 6.0 * $nO / ($nO + $nM); $ini->{NeO2p} = $ini->{Density} / $ini->{MW} * $NA * 6.0 * $nO;# / ($nO + $nM); print "$ini->{Composition}:\n"; print " Density : $ini->{Density} g/cm3\n"; print " MW : $ini->{MW} g/mol\n"; print " nM : $nM\n"; print " nO : $nO\n"; print " Ne(O 2p): $ini->{NeO2p} cm-3\n"; $txt->print("Sample : $filebody\n"); $txt->print(" Composition: $ini->{Composition}:\n"); $txt->print(" Density : $ini->{Density} g/cm3\n"); $txt->print(" MW : $ini->{MW} g/mol\n"); $txt->print(" nM : $nM\n"); $txt->print(" nO : $nO\n"); $txt->print(" Ne(O 2p) : $ini->{NeO2p} cm-3\n"); my $pE = $this->{pCalX}; my $nData = @$pE; my $h = $pE->[1] - $pE->[0]; my $pObs = $this->{pObsY}; my $pPES = $this->{pCalY}; my $pCB = $this->{pCalCB}; my $pVB = $this->{pCalVB}; my $pCBFD = $this->{pCalCBFD}; my $pVBFD = $this->{pCalVBFD}; my $pGLArray = $this->{pCalGLArray}; my $pFD = $this->{pCalFD}; my $pBG = $this->{pCalBG}; my $nSmooth = 21; my $pSmoothen = Algorism::AdaptiveSmoothing($pObs, $nSmooth); my $EminRel = $ini->{EVBM} - 12.0; # my $EminRel = ($ini->{EVBM} > 0.0)? $ini->{EVBM} - 12.0 : $ini->{EVBM} + 12.0; if($ini->{EVBCut} == 0.0) { $ini->{EVBCut} = $EminRel; } else { $EminRel = $ini->{EVBCut}; } my (@Eminmax, @Iminmax, @Diff2minmax); my $nEminmax = 0; # 微分の計算 my @diff; for(my $i = 0 ; $i < $nData ; $i++) { if(3 <= $i and $i <= $nData-4) { $diff[$i] = Algorism::Differentiate7WithIndex($pSmoothen, $i, $h); } elsif($i == 0) { $diff[$i] = ($pSmoothen->[1] - $pSmoothen->[0]) / $h; } else { $diff[$i] = ($pSmoothen->[$i] - $pSmoothen->[$i-1]) / $h; } } my $diff0 = Algorism::Differentiate7WithIndex($pSmoothen, 3, $h); for(my $i = 4 ; $i < $nData-3 ; $i++) { my $E = $pE->[$i]; my $I = $pSmoothen->[$i]; next if($E < $EminRel); last if($E > $ini->{EVBM}); my$diff = $diff[$i]; # my$diff = Algorism::Differentiate7WithIndex($pSmoothen, $i, $h); my$diff2 = Algorism::Differentiate7WithIndex(\@diff, $i, $h); if($diff * $diff0 <= 0.0) { $Eminmax[$nEminmax] = $E; $Iminmax[$nEminmax] = $I; $Diff2minmax[$nEminmax] = $diff2; $nEminmax++; print "Eminmax: $E I = $I\n"; $txt->print("Eminmax: $E I = $I\n"); } $diff0 = $diff; } # Zn 3d top, Valleyを探す my ($EZn3dTop, $IZn3dTop, $CurveZn3dTop); my ($Evalley, $Ivalley, $Curvevalley); my $i; for($i = 0 ; $i < @Eminmax ; $i++) { if($Diff2minmax[$i] < 0) { ($EZn3dTop, $IZn3dTop, $CurveZn3dTop) = ($Eminmax[$i], $Iminmax[$i], $Diff2minmax[$i]); last; } } for( ; $i < @Eminmax ; $i++) { if($Diff2minmax[$i] > 0) { ($Evalley, $Ivalley, $Curvevalley) = ($Eminmax[$i], $Iminmax[$i], $Diff2minmax[$i]); last; } } my ($EO2pTop, $IO2pTop, $iO2pTop, $CurveO2pTop) = (undef, 0); for(my $i = 0 ; $i < $nData ; $i++) { my $E = $pE->[$i]; my $I = $pSmoothen->[$i]; next if($E <= $Evalley); last if($E > $ini->{EVBM}); if($I > $IO2pTop) { $EO2pTop = $E; $IO2pTop = $I; $iO2pTop = $i; } } printf "Estimated: E(Zn 3d top) = %8.6f eV\tI=%d (curvature: %8.6g)\n", $EZn3dTop, $IZn3dTop, $CurveZn3dTop; printf "Estimated: E(valley) = %8.6f eV\tI=%d (curvature: %8.6g)\n", $Evalley, $Ivalley, $Curvevalley; $CurveO2pTop = Algorism::Differentiate7WithIndex(\@diff, $iO2pTop, $h); printf "Estimated: E(O 2p top) = %8.6f eV\tI=%d (curvature: %8.6g)\n", $EO2pTop, $IO2pTop, $CurveO2pTop; $txt->printf("Estimated: E(Zn 3d top) = %8.6f eV\tI=%d (curvature: %8.6g)\n", $EZn3dTop, $IZn3dTop, $CurveZn3dTop); $txt->printf("Estimated: E(valley) = %8.6f eV\tI=%d (curvature: %8.6g)\n", $Evalley, $Ivalley, $Curvevalley); $txt->printf("Estimated: E(O 2p top) = %8.6f eV\tI=%d (curvature: %8.6g)\n", $EO2pTop, $IO2pTop, $CurveO2pTop); if($ini->{EZn3d} != 0.0) { $EZn3dTop = $ini->{EZn3d}; my $y = Algorism::Interpolate($pE, $pSmoothen, $EZn3dTop); printf " Use: E(Zn 3d top) = %8.6f eV\tI=%d\n", $EZn3dTop, $y; $txt->printf(" Use: E(Zn 3d top) = %8.6f eV\tI=%d\n", $EZn3dTop, $y); } else { $ini->{EZn3d} = $EZn3dTop; } if($ini->{Evalley} != 0.0) { $Evalley = $ini->{Evalley}; my $y = Algorism::Interpolate($pE, $pSmoothen, $Evalley); printf " Use: E(valley) = %8.6f eV\tI=%d\n", $Evalley, $y; $txt->printf(" Use: E(valley) = %8.6f eV\tI=%d\n", $Evalley, $y); } else { $ini->{Evalley} = $Evalley; } if($ini->{EO2p} != 0.0) { $EO2pTop = $ini->{EO2p}; my $y = Algorism::Interpolate($pE, $pSmoothen, $EO2pTop); printf " Use: E(O 2p top) = %8.6f eV\tI=%d\n", $EO2pTop, $y; $txt->printf(" Use: E(O 2p top) = %8.6f eV\tI=%d\n", $EO2pTop, $y); } else { $ini->{EO2p} = $EO2pTop; } my @Subtracted; for(my $i = 0 ; $i < @$pE ; $i++) { $Subtracted[$i] = $pObs->[$i] - $pBG->[$i]; # $Subtracted[$i] = $pObs->[$i] - $pCBFD->[$i] - $pVBFD->[$i] - $pBG->[$i]; for(my $j = 0 ; $j < $this->{ini}->{nGL} ; $j++) { $Subtracted[$i] -= $pGLArray->[$j][$i]; } } my $pIntegrated = Algorism::IntegrateByRectangle($pE, \@Subtracted); my $Svalley = Algorism::Interpolate($pE, $pIntegrated, $Evalley); for(my $i = 0 ; $i < @$pE ; $i++) { $pIntegrated->[$i] -= $Svalley; } my $SVB = Algorism::Interpolate($pE, $pIntegrated, $ini->{EVBM}); my $SZn3d = -Algorism::Interpolate($pE, $pIntegrated, $ini->{EVBCut}); my $pCBFDIntegrated = Algorism::IntegrateByRectangle($pE, $pCBFD); my $SCB = Algorism::Interpolate($pE, $pCBFDIntegrated, $ini->{EF} + 1.0) - Algorism::Interpolate($pE, $pCBFDIntegrated, $ini->{ECBM}); $path = Deps::MakePath($dir, "$filebody-IGZOVB.csv", 0); $this->print("\nSave IGZO VB data to [$path].\n"); my $out = new JFile($path, "w"); if(!$out) { $this->print("Error: Can not write to [$path].\n"); return; } $out->print("\n"); $out->print("Sample,$filebody\n"); $out->print("kai,$ini->{kai}\n"); my @array = qw(BG T Wa EF ECBM D0CB EVBM D0VB); foreach my $key (@array) { $out->print("$key,$ini->{$key}\n"); } my @p; for(my $i = 0 ; $i < $ini->{nGL} ; $i++) { $p[$i]->{GLE0} = $ini->{"GLE0$i"}; $p[$i]->{GLC0} = $ini->{"GLC0$i"}; $p[$i]->{GLWL} = $ini->{"GLWL$i"}; $p[$i]->{GLGFraction} = $ini->{"GLGFraction$i"}; $p[$i]->{GLGWRatio} = $ini->{"GLGWRatio$i"}; } @p = sort { $a->{GLE0} <=> $b->{GLE0} } @p; for(my $i = 0 ; $i < @p ; $i++) { $out->printf("E0%d,%f\n", $i+1, $p[$i]->{GLE0}); $out->printf("C%d,%f\n", $i+1, $p[$i]->{GLC0}); $out->printf("WL%02d,%f\n", $i+1, $p[$i]->{GLWL}); $out->printf("GaussF%02d,%f\n", $i+1, $p[$i]->{GLGFraction}); $out->printf("WRatio%02d,%f\n", $i+1, $p[$i]->{GLGWRatio}); } $out->print("\n"); $out->print("Sample,$filebody\n"); $out->print("Composition,$ini->{Composition}:\n"); $out->print("Density,$ini->{Density}\n"); $out->print("Ne(O 2p),$ini->{NeO2p}\n"); $out->print("Imax(O 2p),$IO2pTop\n"); $out->print("S(O 2p),$SVB\n"); $out->print("S(CB),$SCB\n"); $out->print("\n"); # my $kNormalize = 1.0 / $IO2pTop; my $kNormalize = ($SVB == 0.0)? 0.0 : $ini->{NeO2p} / $SVB; my $kNormalizeCB = ($SCB == 0.0)? 0.0 : $ini->{NeHall} / $SCB; my $D0VSTD = $ini->{D0VB} * $kNormalize * 1.0e6 / sqrt($eVToJ) / $eVToJ; my $D0CSTD = $ini->{D0CB} * $kNormalizeCB * 1.0e6 / sqrt($eVToJ) / $eVToJ; my $dEBM = $ini->{EF} - $ini->{ECBM}; my $mhDOS = $hbar*$hbar * ($D0VSTD * $pi*$pi / sqrt(2.0))**(2.0/3.0) / $me; my $meDOS = $hbar*$hbar * ($D0CSTD * $pi*$pi / sqrt(2.0))**(2.0/3.0) / $me; my $h1 = $hbar * 2.0 * $pi; my $meBM = ($dEBM <= 0.0)? 0 : $h1*$h1 * ($ini->{NeHall}*1.0e6 * 3.0/16.0/sqrt(2.0)/$pi)**(2.0/3.0) / ($dEBM * $e) / $me; $out->printf("EVBM,%f\n", $ini->{EVBM} - $ini->{EVBM}); $out->printf("D0V,%f\n", $ini->{D0VB} * $kNormalize); $out->printf("mh(DOS),%f (from DV0)\n", $mhDOS); $out->printf("ECBM,%f\n", $ini->{EVBM} - $ini->{EVBM}); $out->printf("D0C,%f\n", $ini->{D0CB} * $kNormalizeCB); $out->printf("me(DOS),%f (from DC0)\n", $meDOS); $out->print("\n"); printf("EVBM : %g eV\n", $ini->{EVBM}); printf("ECBM : %g eV\n", $ini->{ECBM}); printf("EF - EC: %g - %g = %g eV\n", $ini->{EF}, $ini->{ECBM}, $dEBM); printf("VB Areas: kNormarizeVB = Ne(O 2p) / S(O 2p) = %e\n", $kNormalize); printf("NV: %e cm-3eV^(-1/2) %e m-3J^(-1/2) (calibrated by Ne(O 2p))\n", $ini->{D0VB} * $kNormalize, $D0VSTD); printf("mh(DOS): $mhDOS me\n"); printf("CB Areas: kNormarizeCB = Ne(Hall) / S(CB) = %e\n", $kNormalizeCB); printf("NC: %e cm-3eV^(-1/2) %e m-3J^(-1/2) (calibrated by Ne(Hall))\n", $ini->{D0CB} * $kNormalizeCB, $D0CSTD); printf("me(DOS): $meDOS me\n"); printf("me(BM) : $meBM me\n"); $txt->printf("\n"); $txt->printf("EF : %g eV\n", $ini->{EF}); $txt->printf("ECBM : %g eV\n", $ini->{ECBM}); $txt->printf("EVBM : %g eV\n", $ini->{EVBM}); $txt->printf("E(Zn 3d top): %8.6f eV\n", $EZn3dTop); $txt->printf("E(valley) : %8.6f eV\n", $Evalley); $txt->printf("E(O 2p top) : %8.6f eV\n", $EO2pTop); $txt->printf("E(VB cutoff): %8.6f eV\n", $ini->{EVBCut}); $txt->printf("Ne(O 2p) : $ini->{NeO2p}\n"); $txt->printf("Imax(O 2p): $IO2pTop\n"); $txt->printf("S(Zn 3d) : %10.4g (integrated from E(cut)=%g to E(valley)=%g eV)\n", $SZn3d, $ini->{EVBCut}, $Evalley); $txt->printf("S(O 2p) : %10.4g (integrated from E(valley)=%g to E(VBM)=%g eV)\n", $SVB, $Evalley, $ini->{EVBM}); $txt->printf("S(CB) : %10.4g (integrated from E(CBM)=%g to EF+1.0=%g eV)\n", $SCB, $ini->{ECBM}, $ini->{EF} + 1.0); $txt->printf(" Ne(O 2p) calibrated: %e cm-3\n", $SCB / $SVB * $ini->{NeO2p}); $txt->printf(" Ne(Hall) : %e cm-3\n", $ini->{NeHall}); $txt->printf("\n"); $txt->printf("VB Areas: kNormarizeVB = Ne(O 2p) / S(O 2p) = %e\n", $kNormalize); $txt->printf("NV : %e cm-3eV^(-1/2) %e m-3J^(-1/2) (calibrated by Ne(O 2p))\n", $ini->{D0VB} * $kNormalize , $D0VSTD); $txt->printf("mh(DOS) : $mhDOS me\n"); $txt->printf("CB Areas: kNormarizeCB = Ne(Hall) / S(CB) = %e\n", $kNormalizeCB); $txt->printf("NC : %e cm-3eV^(-1/2) %e m-3J^(-1/2) (calibrated by Ne(Hall))\n", $ini->{D0CB} * $kNormalizeCB, $D0CSTD); $txt->printf("EF - EC : %g - %g = %g eV\n", $ini->{EF}, $ini->{ECBM}, $dEBM); $txt->printf("me(DOS) : $meDOS me\n"); $txt->printf("me(BM) : $meBM me\n"); $txt->print("\n"); $txt->printf("VB Peak Areas: kNormarize = Ne(O 2p) / S(O 2p) = %e\n", $kNormalize); for(my $i = 0 ; $i < @p ; $i++) { my $S = Sci::GaussLorentzArea($ini->{"GLC0$i"}, $ini->{"GLWL$i"}, $ini->{"GLGFraction$i"}, $ini->{"GLGWRatio$i"}); $out->printf("E0%d,%f\n", $i+1, $p[$i]->{GLE0} - $ini->{EVBM}); $out->printf("C%d,%f\n", $i+1, $p[$i]->{GLC0} * $kNormalize); $out->printf("WL%02d,%f\n", $i+1, $p[$i]->{GLWL}); # $out->printf("GaussF%02d,%f\n", $i+1, $p[$i]->{GLGFraction}); # $out->printf("WRatio%02d,%f\n", $i+1, $p[$i]->{GLGWRatio}); $out->printf("Area%02d(cm-3),%f\n", $i+1, $S * $kNormalize); $txt->printf("Peak #%d:\n", $i+1); $txt->printf(" E0-EVBM: %f eV [%f eV]\n", $p[$i]->{GLE0} - $ini->{EVBM}, $p[$i]->{GLE0}); $txt->printf(" C : %f cm-3\n", $p[$i]->{GLC0} * $kNormalize); $txt->printf(" WL : %f eV\n", $p[$i]->{GLWL}); $txt->printf(" GaussF : %f\n", $p[$i]->{GLGFraction}); $txt->printf(" WRatio : %f\n", $p[$i]->{GLGWRatio}); $txt->printf(" Area : %e cm-3 [S=%g]\n", $S * $kNormalize, $S); } $out->print("\n"); $out->print("Sample,$filebody\n"); $out->print("Composition,$ini->{Composition}\n"); $out->print("Density,$ini->{Density},g/cm3\n"); $out->print("MW,$ini->{MW},g/mol\n"); $out->print("nM,$nM\n"); $out->print("nO,$nO\n"); $out->print("\n"); $out->print("EF,$ini->{EF},eV\n"); $out->print("ECBM,$ini->{ECBM},eV\n"); $out->print("EVBM,$ini->{EVBM},eV\n"); $out->print("E(O 2p top),$EO2pTop,eV\n"); $out->print("E(valley),$Evalley,eV\n"); $out->print("E(Zn 3d top),$EZn3dTop,eV\n"); $out->print("E(VB cutoff),$ini->{EVBCut},eV\n"); $out->print("\n"); $out->print("Ne(O 2p),$ini->{NeO2p},cm-3\n"); $out->print("S(Zn 3d),$SZn3d,eV\n"); $out->print("S(O 2p),$SVB,eV\n"); $out->print("S(CB),$SCB,\n"); $out->print("Ne(O 2p) calibrated,", $SCB / $SVB * $ini->{NeO2p}, ",cm-3\n"); $out->print("Ne(Hall),$ini->{NeHall},cm-3\n"); my $Sf = ($ini->{NeHall} == 0)? 0.0 : $SCB / $SVB * $ini->{NeO2p} / $ini->{NeHall}; $out->print("Sf(O2p/Hall),", $Sf, "\n"); $out->print("\n"); $out->print("mh(DOS),$mhDOS,me\n"); $out->print("me(DOS),$meDOS,me\n"); $out->print("me(BM),$meBM,me\n"); $out->print("dE(BM),", $ini->{EF} - $ini->{ECBM}, ",eV\n"); $out->print("Eg,", $ini->{ECBM} - $ini->{EVBM}, ",eV\n"); $out->print("EF-EVBM,", $ini->{EF} - $ini->{EVBM}, ",eV\n"); $out->Close(); $path = Deps::MakePath($dir, "$filebody-Sepctra.csv", 0); $this->print("\nSave Spectra data to [$path].\n"); $out = new JFile($path, "w"); if(!$out) { $this->print("Error: Can not write to [$path].\n"); return; } $out->print("E,PES(obs),PES(smooth),PES(cal),BG(cal),PES(BG subtracted),CB(cal),VB(cal),CB*FD(cal),VB*FD(cal),Integrated(cal)"); for(my $i = 0 ; $i < $this->{ini}->{nGL} ; $i++) { $out->print(",GL${i}(cal)"); } $out->print(",PES(GL/BG subtracted),FD(cal)\n"); for(my $i = 0 ; $i < $nData ; $i++) { $out->print("$pE->[$i],$pObs->[$i],$pSmoothen->[$i],$pPES->[$i],$pBG->[$i],", $pObs->[$i] - $pBG->[$i], ",$pCB->[$i],$pVB->[$i],$pCBFD->[$i],$pVBFD->[$i],$pIntegrated->[$i]"); for(my $j = 0 ; $j < $this->{ini}->{nGL} ; $j++) { $out->print(",$pGLArray->[$j][$i]"); } $out->print(",$Subtracted[$i],$pFD->[$i]\n"); } $out->Close(); $txt->Close(); } sub Recalc { my ($this, $UseAllData) = @_; return if(!defined $this->{DataFile}); $UseAllData = 0 if(!defined $UseAllData); my $ini = $this->{ini}; # $ini->{AppFunction} = $this->{ChooseAppFunctionListBox}->GetText(); my $ConductionType = $this->{ini}->{ConductionType}; #$this->{ChooseConductionTypeListBox}->GetText(); my $IsMetal = 0; $IsMetal = 1 if($ConductionType eq 'Metal'); my $X1Label = $this->{SampleFileFrame}->{X1ListBox}->GetText(); my $Y1Label = $this->{SampleFileFrame}->{Y1ListBox}->GetText(); my $XMin = $ini->{FitXMin}; my $XMax = $ini->{FitXMax}; my $nSkipData = $ini->{nSkipData}; my $pX = $this->{DataFile}->GetData($X1Label) if($X1Label); my $pY1 = $this->{DataFile}->GetData($Y1Label) if($Y1Label); my (@X, @Y); my $c = 0; for(my $i = 0 ; $i < @$pX ; $i++) { my $x = $pX->[$i]; if(!$UseAllData and ($x < $XMin or $XMax < $x)) { next; } next if($nSkipData > 0 and $i % $nSkipData != 0); $X[$c] = $x; $Y[$c] = $pY1->[$i]; $c++; } $this->{pCalX} = \@X; # my ($pY, $pCB, $pVB, $pCBFD, $pVBFD, $pGLArray, $pFD, $pBG) = PES::CalTotalDOSSpectrum(\@X, $this->{ini}, $IsMetal); my ($pY, $pCB, $pVB, $pCBFD, $pVBFD, $pGLArray, $pFD, $pBG) = PES::CalTotalDOSSpectrum(\@X, $this->{ini}, $IsMetal, $pX, $pY1); $this->{pObsY} = \@Y; $this->{pCalY} = $pY; $this->{pCalCB} = $pCB; $this->{pCalVB} = $pVB; $this->{pCalCBFD} = $pCBFD; $this->{pCalVBFD} = $pVBFD; $this->{pCalGLArray} = $pGLArray; $this->{pCalFD} = $pFD; $this->{pCalBG} = $pBG; $this->SUPER::RePlot(); } sub Fit { my ($this) = @_; return if(!defined $this->{DataFile}); my $App = $this->App(); my $optics = new Optics; my $ini = $this->{ini}; $this->UpdateParameters(); $this->BuildOptimize(); my $Method = $this->mw()->{LSQFrame}->{LSQMethodListBox}->GetText(); #$this->{LSQMethodListBox}->GetText(); my $optimize = $this->{Optimize}; print "Method: $Method\n"; print "nMaxIter: $ini->{nMaxIter}\n"; # $this->{ini}->{AppFunction} = $this->{ChooseAppFunctionListBox}->GetText(); my $ConductionType = $this->{ini}->{ConductionType}; #$this->{ChooseConductionTypeListBox}->GetText(); my $IsMetal = 0; $IsMetal = 1 if($ConductionType eq 'Metal'); my $X1Label = $this->{SampleFileFrame}->{X1ListBox}->GetText(); my $Y1Label = $this->{SampleFileFrame}->{Y1ListBox}->GetText(); my $XMin = $ini->{FitXMin}; my $XMax = $ini->{FitXMax}; my $nSkipData = $ini->{nSkipData}; my $pX = $this->{DataFile}->GetData($X1Label) if($X1Label); my $pY1 = $this->{DataFile}->GetData($Y1Label) if($Y1Label); my (@X, @Y); my $c = 0; for(my $i = 0 ; $i < @$pX ; $i++) { my $x = $pX->[$i]; next if($x < $XMin or $XMax < $x); next if($nSkipData > 0 and $i % $nSkipData != 0); $X[$c] = $x; $Y[$c] = $pY1->[$i]; $c++; } #========================================================= # 最適化の実行 #========================================================= $optimize->SetnS2Calculation(0); my ($OptVars, $MinVal) = $optimize->Optimize( $Method, undef, undef, undef, $ini->{EPS}, $ini->{nMaxIter}, $ini->{iPrintLevel}, sub { $this->CalS2(\@X, \@Y, $IsMetal, @_); }, undef, sub { Optimize::BuildDifferentialMatrixes(@_); }, ); print "\nOptimized at:\n"; $optimize->RecoverParameters($OptVars); $optimize->PrintParameters(1, $OptVars, $MinVal, 1); $this->SetS2($MinVal); $this->UpdateParameters(); $this->Recalc(); } sub CalS2 { my ($this, $pX, $pY, $IsMetal, $pVars, $iPrintLevel) = @_; #print "pVars=", join(',', @$pVars); my $X1Label = $this->{SampleFileFrame}->{X1ListBox}->GetText(); my $Y1Label = $this->{SampleFileFrame}->{Y1ListBox}->GetText(); my $pObsX = $this->{DataFile}->GetData($X1Label) if($X1Label); my $pObsY = $this->{DataFile}->GetData($Y1Label) if($Y1Label); my $optimize = $this->{Optimize}; my $ini = $this->{ini}; # my $dini = $this->{dini}; $optimize->RecoverParameters($pVars); # my ($pCalY) = PES::CalTotalDOSSpectrum($pX, $ini, $IsMetal); my ($pCalY) = PES::CalTotalDOSSpectrum($pX, $ini, $IsMetal, $pObsX, $pObsY); my $S2 = 0.0; my $SumI2 = 0.0; my $c = 0; for(my $i = 0 ; $i < @$pX ; $i++) { # my $x = $pX->[$i]; my $d = ($pCalY->[$i] - $pY->[$i]); #print "(E,d) = ($x, $d)\n"; $S2 += $d * $d; $SumI2 += $pY->[$i] * $pY->[$i]; $c++; } $S2 = sqrt($S2 / $SumI2); # $S2 = sqrt($S2 / $c) if($c > 0); $ini->{kai} = $S2; $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->SetS2($S2); $this->Recalc(); $this->RePlot(); } $this->UpdateParameters(); $this->mw()->update(); return $S2; } sub Save { my ($this) = @_; $this->Recalc() if(!defined $this->{pCalX}); my $path = $this->{ini}->{ParameterFile}; $path = $this->{ini}->{SampleCSVFile} if(!$path); # my $dir = Deps::ExtractDirectory($path); # $path = Deps::MakePath($dir, "PES.csv", 0); my ($drive, $directory, $filename, $ext1, $lastdir, $filebody) = Deps::SplitFilePath($path); $path = Deps::MakePath("$drive$directory", "$filebody-PES.csv", 0); $this->print("\nSave decomposed spectra to [$path].\n"); my $out = new JFile($path, "w"); if(!$out) { $this->print("Error: Can not write to [$path].\n"); return; } $out->print("E,PES(obs),PES(cal),CB(cal),VB(cal),CB*FD(cal),VB*FD(cal)"); for(my $i = 0 ; $i < $this->{ini}->{nGL} ; $i++) { $out->print(",GL${i}(cal)"); } $out->print(",FD(cal),BG(cal),PES(obs)-BG(cal)\n"); my $pE = $this->{pCalX}; my $pObs = $this->{pObsY}; my $pPES = $this->{pCalY}; my $pCB = $this->{pCalCB}; my $pVB = $this->{pCalVB}; my $pCBFD = $this->{pCalCBFD}; my $pVBFD = $this->{pCalVBFD}; my $pGLArray = $this->{pCalGLArray}; my $pFD = $this->{pCalFD}; my $pBG = $this->{pCalBG}; for(my $i = 0 ; $i < @$pE ; $i++) { $out->print("$pE->[$i],$pObs->[$i],$pPES->[$i],$pCB->[$i],$pVB->[$i],$pCBFD->[$i],$pVBFD->[$i]"); for(my $j = 0 ; $j < $this->{ini}->{nGL} ; $j++) { $out->print(",$pGLArray->[$j][$i]"); } $out->print(",$pFD->[$i],$pBG->[$i],", $pObs->[$i] - $pBG->[$i], "\n"); } $out->Close(); } sub SaveParameterFile { my ($this, $Option, $filepath, $name, $Frame) = @_; $filepath = $Frame->{PathEntry}->GetText() if($filepath eq ''); $this->{ini}->{SampleX1} = $this->{SampleFileFrame}->{X1ListBox}->GetText(); $this->{ini}->{SampleY1} = $this->{SampleFileFrame}->{Y1ListBox}->GetText(); # $this->{ini}->{AppFunction} = $this->{ChooseAppFunctionListBox}->GetText(); # $this->{ini}->{ConductionType} = $this->{ChooseConductionTypeListBox}->GetText(); $this->{ini}->{YAxisPlotType} = $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1YAxisListBox}->GetText(); if(!defined $filepath or $filepath eq '') { $filepath = $this->{ini}->{Sample1CSVFile}; $filepath = $this->{ini}->{SampleCSVFile} if(!defined $filepath or $filepath eq ''); $filepath = $this->{ini}->{SubstrateCSVFile} if(!defined $filepath or $filepath eq ''); $filepath = 'save.prm' if(!defined $filepath or $filepath eq ''); $filepath =~ s/\.[^\.]+$/\.prm/i; # $filepath =~ s/\.csv$/\.prm/i; $filepath = Deps::ExtractFileName($filepath); $filepath = $this->ChooseSaveFile($filepath, '*.prm'); if($filepath) { my $ext = Deps::ExtractExtention($filepath); if(!defined $ext or $ext eq '') { $filepath = Deps::ReplaceExtension($filepath, ".prm"); } $this->{ini}->{ParameterFile} = $filepath; } else { return; } } $this->{ini}->SetIniFile($filepath, undef, 1); $this->App()->print("\nSaveParameterFile:\n"); $this->ComposeParameters($this->{dini}, $this->{ini}); $this->{ini}->WriteAll(); $this->DecomposeParameters($this->{ini}, $this->{dini}); } sub ReadParameterFile { my ($this, $filepath) = @_; my $ini = $this->{ini}; my $dini = $this->{dini}; $this->Initialize(1, 1); $this->App()->print("\nRead paramter from [$filepath].\n"); $this->{ini}->ReadAll($filepath); my $ConductionType = $this->{ini}->{ConductionType}; $this->DecomposeParameters($ini, $dini); $this->RefreshMainPane($this->{EntryWidth}); $this->{ini}->{ConductionType} = $ConductionType; $this->{ini}->{FitXMin} += 0.0; $this->{ini}->{FitXMax} += 0.0; my $DataFrame = $this->{SampleFileFrame}; $this->{ini}->{SampleX1} = $this->{ini}->{X} if(!defined $this->{ini}->{SampleX1}); $this->{ini}->{SampleY1} = $this->{ini}->{Y1} if(!defined $this->{ini}->{SampleY1}); $DataFrame->{X1ListBox}->SetText($this->{ini}->{SampleX1}) if($this->{ini}->{SampleX1}); $DataFrame->{Y1ListBox}->SetText($this->{ini}->{SampleY1}) if($this->{ini}->{SampleY1}); # $this->{ChooseAppFunctionListBox}->SetText($this->{ini}->{AppFunction}); # $this->{ChooseConductionTypeListBox}->SetText($this->{ini}->{ConductionType}); if($this->{ini}->{SampleCSVFile}) { my $path = $this->{ini}->{SampleCSVFile}; $path = $this->GetValidDataPath($path, $filepath, $this->{ini}->{ParameterFile}); my $ret = $this->ReadSampleDataFile($path, 1, 0, 0); return undef unless($ret); $this->{ini}->{SampleCSVFile} = $path; $this->{ini}->{ParameterFile} = $filepath; if($this->{ini}->{FlipX}) { $this->FlipX(0); $this->{ini}->{FlipX} = 1; } } $this->{ChooseConductionTypeListBox}->SetText($this->{ini}->{ConductionType}); $this->RePlot(0, 1, 0, 0); $this->RefreshViewRangePane($this->{EntryWidth}); my $YAxisListBox = $this->{ini}->{YAxisPlotType}; #$this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1YAxisListBox}; if($YAxisListBox) { $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1YAxisListBox}->SetText($this->{ini}->{YAxisPlotType}) if($this->{ini}->{YAxisPlotType}); } $this->FlipX(); $this->FlipX(); $this->RePlot(1, 0, 1, 1); # $this->RePlot(); return 1; } sub ReadSampleDataFile { my ($this, $filepath, $IsPrint, $UpdateRange, $IsPlot, $Frame) = @_; $UpdateRange = 1 if(!defined $UpdateRange); $IsPlot = 1 if(!defined $IsPlot); $Frame = $this->{SampleFileFrame} if(!defined $Frame); my $App = $this->App(); my $pXDataLabel = $Frame->{pXDataLabel}; my $pYDataLabel = $Frame->{pYDataLabel}; #print "type=$type\n"; $this->Initialize(0, 1); my $pData = $this->{DataFile} = new Ellipsometry; $this->{Path} = $filepath; my ($nData, $pLabelArray, @pDataArray) = $pData->Read($filepath); if(!defined $nData) { $App->print("Error: Can not read [$filepath].\n"); return $this->{Path} = undef; } print "pDataArray[0],[1]=$pDataArray[0],$pDataArray[1]\n"; if($filepath =~ /\.txt$/i) { if($pDataArray[0] =~ /ARRAY/) { my $p = $pDataArray[0]; @pDataArray = @$p; } } # if($pDataArray[0] =~ /ARRAY/) { # my $p = $pDataArray[0]; # @pDataArray = @$p; # } if(!Utils::IsConstantStepArray($pDataArray[0], 0.01)) { $App->print("Error: The data step for X is not constant.\n"); return $this->{Path} = undef; } my $nDataArray = $this->{DataFile}->nDataArray(); $Frame->{X1ListBox}->DeleteAllItem() if(defined $Frame->{X1ListBox}); $Frame->{Y1ListBox}->DeleteAllItem() if(defined $Frame->{Y1ListBox}); for(my $i = 0 ; $i < $nDataArray ; $i++) { $Frame->{X1ListBox}->AddItem($pLabelArray->[$i]) if(defined $Frame->{X1ListBox}); $Frame->{Y1ListBox}->AddItem($pLabelArray->[$i]) if(defined $Frame->{Y1ListBox}); } $Frame->{X1ListBox}->SetCurSel(@$pXDataLabel) if(defined $Frame->{X1ListBox}); $Frame->{Y1ListBox}->SetCurSel(@$pYDataLabel) if(defined $Frame->{Y1ListBox}); $pData->GetXData(@$pXDataLabel); $pData->GetYData(@$pYDataLabel); $pData->CalMinMax(); ($this->{ini}->{FitXmin}, $this->{ini}->{FitXmax}) = $pData->GetXMinMax() if(!defined $this->{ini}->{FitXmin} or $this->{ini}->{FitXmin} eq ''); if($UpdateRange or !defined $this->{ini}->{FitXMin}) { ($this->{ini}->{FitXMin}, $this->{ini}->{FitXMax}) = Utils::CalMinMax($pDataArray[0]); } if($IsPlot) { $this->RePlot($UpdateRange); } else { $this->CreateGraphFrame() if(!$this->GetGraphFrameArray()); $this->AssignGraphData(); } if(0) { if($this->{ini}->{FitEmax}) { if($this->{ini}->{FitEmin} >= 0 or (-$this->{ini}->{FitEmin} < $this->{ini}->{FitEmax})) { $this->{ini}->{FlipX} = 0; $this->FlipX(); # ($this->{ini}->{FitXMin}, $this->{ini}->{FitXMax}) = ($this->{ini}->{FitXMax}, $this->{ini}->{FitXMin}); } } } return $filepath; } sub CreateGraphFrame { my ($this, $canvas, $TargetData, $DoUpdate) = @_; return if(!$DoUpdate and $this->GetGraphFrameArray()); $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 $RefreshGraphScaleFrame = (defined $this->{GraphFrameArray})? 0 : 1; my $GraphFrameArray = $this->{GraphFrameArray} = new GraphFrameArray($this->mw()); $GraphFrameArray->SetCanvasSize($w, $h); $GraphFrameArray->AddGraphFrame(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); my $FramePosStr0 = $App->{GraphFrame0Position}; $GraphFrame0->SetPositionByStr($FramePosStr0); my $XScale0 = $GraphFrame0->GetXScale(0); my $YScale0 = $GraphFrame0->GetYScale(0); $XScale0->SetScaleStringVisible(1); $XScale0->SetCaptionVisible(1); $GraphFrame0->SetViewRange(0, 0, 1, 1); if($RefreshGraphScaleFrame) { my $EntryWidth = $this->{EntryWidth}; $this->RefreshViewRangePane($EntryWidth); } } sub AssignGraphData { my ($this, $ResetViewRange) = @_; # my ($this, $ResetViewRange, $FlipX) = @_; $ResetViewRange = 1 if(!defined $ResetViewRange); return if(!defined $this->{ini}->{SampleCSVFile}); return if(!defined $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1YAxisListBox}); my $GraphFrameArray = $this->GetGraphFrameArray(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); $GraphFrame0->ClearAllData(); my $X1Label = $this->{SampleFileFrame}->{X1ListBox}->GetText(); $X1Label = 'X' if(!$X1Label); my $Y1Label = $this->{SampleFileFrame}->{Y1ListBox}->GetText(); $Y1Label = 'Y1' if(!$Y1Label); $GraphFrame0->SetXCaption($X1Label); $GraphFrame0->SetYCaption($Y1Label); $GraphFrame0->SetFlipX($this->{ini}->{FlipX}); my $pX = $this->{DataFile}->GetData($X1Label) if($X1Label); my $pY1 = $this->{DataFile}->GetData($Y1Label) if($Y1Label); my $nData = $this->{DataFile}->nData(); if($pX) { $GraphFrame0->AddGraphData($pX, $pY1, 2, "black", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "${Y1Label}") if($pY1); } my $pCalX = $this->{pCalX}; my $pCalY = $this->{pCalY}; my $pCB = $this->{pCalCB}; my $pVB = $this->{pCalVB}; my $pCBFD = $this->{pCalCBFD}; my $pVBFD = $this->{pCalVBFD}; my $pGLArray = $this->{pCalGLArray}; my $pFD = $this->{pCalFD}; my $pBG = $this->{pCalBG}; if($pCalX) { $GraphFrame0->AddGraphData($pCalX, $pCalY, 0, "", "circle", 3, "", 1, "red", "XAutoSkip", "Energy", "FT ${Y1Label}(real)") if($pCalY); $GraphFrame0->AddGraphData($pCalX, $pCB, 1, "blue", "", 3, "", 1, "red", "XAutoSkip", "Energy", "CB(cal)") if($pCB); $GraphFrame0->AddGraphData($pCalX, $pVB, 1, "blue", "", 3, "", 1, "red", "XAutoSkip", "Energy", "VB(cal)") if($pVB); $GraphFrame0->AddGraphData($pCalX, $pCBFD, 1, "green", "", 3, "", 1, "red", "XAutoSkip", "Energy", "CB*FD(cal)") if($pCBFD); $GraphFrame0->AddGraphData($pCalX, $pVBFD, 1, "green", "", 3, "", 1, "red", "XAutoSkip", "Energy", "VB*FD(cal)") if($pVBFD); for(my $i = 0 ; $i < $this->{ini}->{nGL} ; $i++) { $GraphFrame0->AddGraphData($pCalX, $pGLArray->[$i], 1, "blue", "", 3, "", 1, "red", "XAutoSkip", "Energy", "GL${i}(cal)") if($pGLArray->[$i]); } $GraphFrame0->AddGraphData($pCalX, $pBG, 1, "cyan", "", 3, "", 1, "red", "XAutoSkip", "Energy", "BG(cal)") if($pBG); } $GraphFrame0->SetXScalePlotType('x'); $GraphFrame0->SetYScalePlotType('x'); $this->SetViewRange($ResetViewRange);#, $FlipX); } sub Initialize { my ($this, $InitializeParameterFile, $InitializeData) = @_; $this->{DataFile} = new Ellipsometry; if($InitializeParameterFile) { $this->{ini}->{SampleCSVFile} = ''; $this->{ini}->{FlipX} = 0; $this->{ini}->{FitXMin} = ''; $this->{ini}->{FitXMax} = ''; } if($InitializeData) { $this->{pCalX} = undef; $this->{pCalY} = undef; } } sub InitializeParameters { my ($this, $ini, $dini) = @_; $this->AddParameters($ini, $dini, "EF", 0.0, 1, 1.0, '', ''); $this->AddParameters($ini, $dini, "T", 300.0, 0, 10.0, 0.0, ''); $this->AddParameters($ini, $dini, "Wa", 0.1, 1, 0.2, 0.0, ''); $this->AddParameters($ini, $dini, "BG", 0.0, 1, 1000.0, 0.0, ''); $this->AddParameters($ini, $dini, "EBGSL0", 0.0, 0, 0.2, '', ''); $this->AddParameters($ini, $dini, "EBGSL1", 0.0, 0, 0.2, '', ''); $this->AddParameters($ini, $dini, "kBGSL", 0.0, 0, 1000.0, 0.0, ''); my $n = ($this->{ini}->{nStepBG} >= 5)? $this->{ini}->{nStepBG} : 5; for(my $i = 0 ; $i < $n ; $i++) { $this->AddParameters($ini, $dini, "EBG0$i", 0.0, 0, 1.0, '', ''); $this->AddParameters($ini, $dini, "BGLeft$i", 0.0, 0, 1000.0, 0.0, ''); $this->AddParameters($ini, $dini, "WBG$i", 0.1, 0, 1.0, 0.0, ''); } $this->AddParameters($ini, $dini, "ECBM", 0.0, 0, 1.0, '', ''); $this->AddParameters($ini, $dini, "D0CB", 0.0, 0, 1000.0, 0.0, ''); $this->AddParameters($ini, $dini, "k0Metal", 0.0, 0, 1000.0, '', ''); $this->AddParameters($ini, $dini, "EVBM", -3.0, 0, 1.0, '', ''); $this->AddParameters($ini, $dini, "D0VB", 0.0, 0, 1000.0, 0.0, ''); $this->AddParameters($ini, $dini, "Ecut", 0.0, 0, 1.0, '', ''); $this->AddParameters($ini, $dini, "K0Ecut", 0.0, 0, 1000.0, 0.0, ''); $this->AddParameters($ini, $dini, "BGcut", 0.0, 0, 1000.0, 0.0, ''); $this->AddParameters($ini, $dini, "C0Exp", 0.0, 0, 1000.0, 0.0, ''); $this->AddParameters($ini, $dini, "WExp", 1.0, 0, 1.0, 0.0, ''); $this->AddParameters($ini, $dini, "BetaExp", 1.0, 0, 0.5, 0.0, ''); $n = ($this->{ini}->{nGL} >= 10)? $this->{ini}->{nGL}: 10; for(my $i = 0 ; $i < $n ; $i++) { $this->AddParameters($ini, $dini, "GLE0$i", 0.0, 0, 0.2, '', ''); $this->AddParameters($ini, $dini, "GLC0$i", 0.0, 0, 1000.0, 0.0, ''); $this->AddParameters($ini, $dini, "GLWL$i", 0.3, 0, 0.1, 0.0, ''); $this->AddParameters($ini, $dini, "GLGFraction$i", 1.0, 0, 0.1, 0.0, 1.0); $this->AddParameters($ini, $dini, "GLGWRatio$i", 1.0, 0, 0.1, 0.0, ''); } } 1;