#=============================================== # TkCPMOpticalAbsorption #=============================================== package TkCPMOpticalAbsorption; use clib::TkEllipsometry2; @ISA = qw(TkEllipsometry2); #公開したいサブルーチン #@EXPORT = qw(DelSpace Reduce01 MakePath RegExpQuote); use strict; use Sci qw($pi $kB $c $e $e0 $me $mp $mn $h $hbar $torad $todeg); use Sci::Algorism; #============================================================ # 変数等取得関数 #============================================================ #============================================================ # コンストラクタ、デストラクタ #============================================================ #============================================================ # 継承クラスで定義しなおす関数 #============================================================ sub CreateWidgets { my ($this) = @_; my $App = $this->App(); my $args = $App->Args(); my $mw = $this->mw(); my $ProgramName = "CPM & OpticalAbsorptionFit2008"; $this->{ini} = new IniFile(undef, 0, 0); $this->{dini} = new IniFile(undef, 0, 0); $this->InitializeParameters($this->{ini}, $this->{dini}); $this->SUPER::CreateWidgets(1); $mw->SetTitle("$ProgramName / TkPlot"); $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), [qw(Main Layers ViewRange LSQ Misc Lorentz Drude GraphFrame)], [qw(nFilmLayer nLorentz nDrude)], ); $mw->{NoteBook}->pack(-fill => 'both', -expand => 'yes'); $this->UpdateParameters(); #ツールバーのOpenボタンをファイル読み込みにバインドする my $opticalfmask = '*.csv;*.spe;*.jel;*.asp;*.smo;*isa;*.ref;*.pal;*.bef;*.aft'; $mw->{OpenButton}->configure( -command => sub { $this->{AbsorptionCSV} = $this->ChooseFile("open", $opticalfmask, "ChooseSampleFile", "AbsorptionCSV", $this->{AbsorptionFileFrame}); }, ) if($mw->{OpenButton}); } sub BuildMiscParamConditionPane { my ($this, $MainFrame, $EntryWidth) = @_; my $Frame = $MainFrame->MyLabFrame( -label => 'Tauc model', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); my $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); $this->MakeParameterConditionColumn($Frame, "TaucEg", "Eg:", "%12.6g", 3.0, 0, 0.1, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "TaucA", "A:", "%12.6g", 1.0e4, 0, 3.0e3, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "Taucn", "n:", "%12.6g", 2.0, 0, 0.5, 0.0, '', $EntryWidth, $row++); $Frame = $MainFrame->MyLabFrame( -label => 'Urbach tail', -labelside => 'acrosstop', )->pack(-side => 'top', -fill => 'x'); $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); $this->MakeParameterConditionColumn($Frame, "UrbachE0", "E0:", "%12.6g", 3.2, 0, 0.1, 0.0, '', $EntryWidth, $row++); $this->MakeParameterConditionColumn($Frame, "UrbachEu", "Eu:", "%12.6g", 0.1, 0, 0.03, 0.0, '', $EntryWidth, $row++); } sub BuildLSQPane { my ($this, $MainFrame, $EntryWidth) = @_; my $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->mw()->{LSQFrame} = $this->MakeLSQPanes( $Frame, $EntryWidth, 'Fitting', [qw(LSQMethod FitTo FittingRange FittingConditions)], ['Amoeba::Simplex', 'PDL::Simplex', 'ModifiedNewton'], ['RT', 'T', 'R', 'alpha'], ['FitEmin', 'Emin:', 'FitEmax', '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($MainFrame, $EntryWidth); } sub BuildFooter { my ($this, $MainFrame, $EntryWidth) = @_; my $Frame1 = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $ButtonFrame = $this->MakeFittingButtons($Frame1, qw(RePlot RestoreScale CalRT CalAbs)); $ButtonFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); $ButtonFrame = $this->MakeFittingButtons($Frame1, qw(Fit PbP SaveComponents)); $ButtonFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); } sub RefreshViewRangePane { my ($this, $EntryWidth, @a) = @_; return if(!defined $this->mw()->{NoteBook}->{ViewRangePaneFrame}); $this->mw()->{NoteBook}->{ViewRangePaneFrame}->destroy(); #print "n=", $this->mw()->{NoteBook}, "\n"; #print "n=", $this->mw()->{NoteBook}->{ViewRangePage}, "\n"; $this->mw()->{NoteBook}->{ViewRangePaneFrame} = $this->mw()->{NoteBook}->{ViewRangePage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->BuildViewRangePane($this->mw()->{NoteBook}->{ViewRangePaneFrame}, $EntryWidth); } sub BuildViewRangePane { my ($this, $MainFrame, $EntryWidth) = @_; $this->SUPER::BuildViewRangePane($MainFrame, $EntryWidth, [ ['x'], ['x'] ], [ ['x', 'log(|x|)', '(ahv)^1/2 (Tauc)', 'a^1/2 (Indirect)', 'a^2 (Direct'], ['x'] ] ); $MainFrame->{GraphFrame1YAxisListBox}->SetText('log(|x|)') if($MainFrame->{GraphFrame1YAxisListBox}); $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'); my $fparammask = '*.prm'; $this->{ParameterFileFrame} = $this->MakeChooseFileEntry($Frame, 'Param', 'Param:', $this->{ini}->pVariable("ParameterFile", ""), '&Choose', sub { $this->ChooseFile("open", $fparammask, "ChooseParameterFile", @_); }, 1, sub { $this->SaveParameterFile("SaveParam", '', @_); }, 1, sub { $this->EditFile('EditParameterCSV', @_); }, [] ); $this->{ParameterFileFrame}->pack(-anchor => 'nw', -fill => 'x'); my $fmask = '*.csv;*.spe;*.jel;*.asp;*.smo;*isa;*.ref;*.pal;*.bef;*.aft'; $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); if($this->{ini}->{nFilmLayers} > 0) { $this->{"Sample${iTop}FileFrame"} = $this->MakeChooseFileEntry($Frame, "Sample${iTop}CSV", "Sample:", $this->{ini}->pVariable("Sample${iTop}CSVFile", ""), '&Choose', sub { $this->{"Sample${iTop}CSV"} = $this->ChooseFile("open", $fmask, "ChooseSample${iTop}File", @_); }, 0, sub {}, 1, sub { $this->EditFile("EditSample${iTop}CSV", @_); }, [] ); $this->{"Sample${iTop}FileFrame"}->pack(-anchor => 'nw', -fill => 'x'); $this->{"Sample${iTop}FileFrame"}->{pXDataLabel} = ['.*E.*', '.*eV.*']; $this->{"Sample${iTop}FileFrame"}->{pYDataLabel} = ['alpha.*']; } for(my $i = $this->{ini}->{nFilmLayers}-1 ; $i >= 1 ; $i--) { $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->{"Sample${i}FileFrame"} = $this->MakeChooseFileEntry($Frame, "Sample${i}CSV", "Film${i}:", $this->{ini}->pVariable("Sample${i}CSVFile", ""), '&Choose', sub { $this->{"Sample${i}CSV"} = $this->ChooseFile("open", $fmask, "ChooseSample${i}File", @_); }, 0, sub {}, 1, sub { $this->EditFile("EditSample${i}CSV", @_); }, [] ); $this->{"Sample${i}FileFrame"}->pack(-anchor => 'nw', -fill => 'x'); $this->{"Sample${i}FileFrame"}->{pXDataLabel} = ['.*E.*', '.*eV.*']; $this->{"Sample${i}FileFrame"}->{pYDataLabel} = ['alpha.*']; } $Frame = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->{SubstrateFileFrame} = $this->MakeChooseFileEntry($Frame, 'SubstrateCSV', 'Substrate:', $this->{ini}->pVariable("SubstrateCSVFile", ""), '&Choose', sub { $this->{SubstrateCSV} = $this->ChooseFile("open", $fmask, "ChooseSubstrateFile", @_); }, 0, sub {}, 1, sub { $this->EditFile('EditSubstrateCSV', @_); }, [] ); $this->{SubstrateFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $this->{SubstrateFileFrame}->{pXDataLabel} = ['.*E.*', '.*eV.*']; $this->{SubstrateFileFrame}->{pYDataLabel} = ['alpha.*']; $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, $MainPaneFrame, $EntryWidth) = @_; my $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); 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 $opticalfmask = '*.csv;*.spe;*.jel;*.asp;*.smo;*isa;*.ref;*.pal;*.bef;*.aft'; $this->{AbsorptionFileFrame} = $this->MakeChooseFileEntry( $Frame, 'AbsorptionCSV', 'Absorption:', $this->{ini}->pVariable("AbsorptionCSVFile", ""), '&Choose', sub { $this->{AbsorptionCSV} = $this->ChooseFile("open", $opticalfmask, "ChooseSampleFile", @_); $this->AssignGraphData(); $this->Draw(); }, 0, sub {}, 1, sub { $this->EditFile('EditAbsorptionCSV', @_); }, ['X1', 'Y1'] ); $this->{AbsorptionFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $this->{AbsorptionFileFrame}->{pXDataLabel} = ['.*E.*', '.*eV.*']; $this->{AbsorptionFileFrame}->{pYDataLabel} = ['alpha.*']; $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->{CPMFileFrame} = $this->MakeChooseFileEntry( $Frame, 'CPMCSV', 'CPM:', $this->{ini}->pVariable("CPMCSVFile", ""), '&Choose', sub { $this->{CPMCSV} = $this->ChooseFile("open", $opticalfmask, "ChooseSampleFile", @_); $this->AssignGraphData(); $this->Draw(); }, 0, sub {}, 1, sub { $this->EditFile('EditCPMCSV', @_); }, ['X1', 'Y1'] ); $this->{CPMFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $this->{CPMFileFrame}->{pXDataLabel} = ['.*E.*', '.*eV.*']; $this->{CPMFileFrame}->{pYDataLabel} = ['alpha.*']; $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->mw()->{LSQFrame2} = $this->MakeLSQPanes( $Frame, $EntryWidth, 'Fitting', [qw(FittingRange)], [], [], ['FitEmin', 'Emin:', 'FitEmax', 'Emax:', 'nSkipData', 'nSkip:'], [] ); $this->mw()->{LSQFrame2}->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); $Frame = $MainPaneFrame->MyLabFrame( -label => 'Connection', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $this->MakeCheckEntry($Frame, "KCPM", "KCPM:", $this->{dini}->pVariable('KCPMcheck', 0) , $this->{ini}->pVariable('KCPM', 1.0 ), "%12.6g", $EntryWidth, "", 0, 0); $this->MakeLabelEntry($Frame, "ConnectE", "Econnect:", $this->{ini}->pVariable('ConnectE', 3.0), "%6.3f", $EntryWidth, "", 0, 1); $this->{SaveConnectButton} = $Frame->MyButton( -text => '&Connect', -takefocus => 1, -command => sub { $this->Connect(); }, )->grid(-row => 0, -column => 7); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw'); my $TaucFrame = $this->MakeTaucPane($Frame, $EntryWidth); $TaucFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw'); my $UrbachFrame = $this->MakeUrbachPane($Frame, $EntryWidth); $UrbachFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw'); my $LorentzFrame = $this->MakeLorentzPane($Frame, $EntryWidth, $this->{ini}->{nLorentz}); $LorentzFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw'); my $DrudeFrame = $this->MakeDrudePane($Frame, $EntryWidth, $this->{ini}->{nDrude}); $DrudeFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); $this->BuildFooter($MainPaneFrame, $EntryWidth); } sub ReadParameterFile { my ($this, $filepath, $IsPrint, $Frame) = @_; my $ini = $this->{ini}; my $dini = $this->{dini}; $this->Initialize(1, 1); $this->App()->print("\nRead paramter from [$filepath].\n"); $this->{ini}->ReadAll($filepath); $this->DecomposeParameters($ini, $dini); my $EntryWidth = $this->{EntryWidth}; $this->RefreshMainPane($EntryWidth); $this->RefreshLayersPane($EntryWidth); $this->RefreshMiscParamConditionPane($EntryWidth); $this->RefreshLorentzParamConditionPane($EntryWidth); $this->RefreshDrudeParamConditionPane($EntryWidth); $this->mw()->{NFilmLayerListBox}->SetCurSel($ini->{nFilmLayers}); $this->mw()->{NLorentzListBox}->SetCurSel($ini->{nLorentz}); $this->mw()->{NDrudeListBox}->SetCurSel($ini->{nDrude}); $this->mw()->{LSQFrame}->{LSQMethodListBox}->SetText($this->{ini}->{Method}) if($this->{ini}->{Method}); $this->mw()->{LSQFrame}->{FitToListBox}->SetText($this->{ini}->{FitTo}) if($this->{ini}->{FitTo}); my $DataFrame = $this->{AbsorptionFileFrame}; $DataFrame->{X1ListBox}->SetText($this->{ini}->{AbsorptionX1}) if($this->{ini}->{AbsorptionX1}); $DataFrame->{Y1ListBox}->SetText($this->{ini}->{AbsorptionY1}) if($this->{ini}->{AbsorptionY1}); $DataFrame = $this->{CPMFileFrame}; $DataFrame->{X1ListBox}->SetText($this->{ini}->{CPMX1}) if($this->{ini}->{CPMX1}); $DataFrame->{Y1ListBox}->SetText($this->{ini}->{CPMY1}) if($this->{ini}->{CPMY1}); if($this->{ini}->{AbsorptionCSVFile}) { $this->{AbsorptionCSV} = $this->ReadSampleDataFile( $this->{ini}->{AbsorptionCSVFile} = $this->GetValidDataPath( $this->{ini}->{AbsorptionCSVFile}, $filepath, $this->{ini}->{ParameterFile}, ), 1, $this->{AbsorptionFileFrame}); } if($this->{ini}->{CPMCSVFile}) { $this->{CPMCSV} = $this->ReadSampleDataFile( $this->{ini}->{CPMCSVFile} = $this->GetValidDataPath( $this->{ini}->{CPMCSVFile}, $filepath, $this->{ini}->{ParameterFile}, ), 1, $this->{CPMFileFrame}, 0); } if($this->{ini}->{SubstrateCSVFile}) { $this->{SubstrateCSV} = $this->ReadSampleDataFile( $this->{ini}->{SubstrateCSVFile} = $this->GetValidDataPath( $this->{ini}->{SubstrateCSVFile}, $filepath, $this->{ini}->{ParameterFile}, ), 1, $this->{SubstrateFileFrame}, 0); } for(my $i = $this->{ini}->{nFilmLayers} ; $i >= 1 ; $i--) { next if(!defined $this->{ini}->{"Sample${i}CSVFile"}); $this->{"Sample${i}CSV"} = $this->ReadSampleDataFile( $this->{ini}->{"Sample${i}CSVFile"} = $this->GetValidDataPath( $this->{ini}->{"Sample${i}CSVFile"}, $filepath, $this->{ini}->{ParameterFile}, ), 1, $this->{"Sample${i}FileFrame"}, 0); } $this->{ini}->{ParameterFile} = $filepath; $this->RePlot(0, 1, 0, 0); $this->RefreshViewRangePane($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->RePlot(1, 0, 1, 1); return $ini; } sub SaveParameterFile { my ($this, $Option, $filepath, $name, $Frame) = @_; $filepath = $Frame->{PathEntry}->GetText() if($filepath eq ''); $this->{ini}->{Method} = $this->mw()->{LSQFrame}->{LSQMethodListBox}->GetText(); $this->{ini}->{FitTo} = $this->mw()->{LSQFrame}->{FitToListBox}->GetText(); my $DataFrame = $this->{AbsorptionFileFrame}; $this->{ini}->{AbsorptionX1} = $DataFrame->{X1ListBox}->GetText(); $this->{ini}->{AbsorptionY1} = $DataFrame->{Y1ListBox}->GetText(); $DataFrame = $this->{CPMFileFrame}; $this->{ini}->{CPMX1} = $DataFrame->{X1ListBox}->GetText(); $this->{ini}->{CPMY1} = $DataFrame->{Y1ListBox}->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/\.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 to [$filepath]\n"); $this->ComposeParameters($this->{dini}, $this->{ini}); $this->{ini}->WriteAll(); $this->DecomposeParameters($this->{ini}, $this->{dini}); } sub ReadSampleDataFile { my ($this, $filepath, $IsPrint, $Frame, $IsPlot) = @_; my $App = $this->App(); my $pXDataLabel = $Frame->{pXDataLabel}; my $pYDataLabel = $Frame->{pYDataLabel}; $IsPlot = 1 if(!defined $IsPlot); $this->Initialize(0, 1); my $pData = new Ellipsometry; print "Read [$filepath].\n"; $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; } my $nDataArray = $pData->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}->{FitEmin}, $this->{ini}->{FitEmax}) = $pData->GetXMinMax() if(!defined $this->{ini}->{FitEmin} or $this->{ini}->{FitEmin} eq ''); if($IsPlot) { $this->RePlot(); } return $pData; #$filepath; } sub InitializeParameters { my ($this, $ini, $dini) = @_; #print "Init\n"; $this->AddParameters($ini, $dini, "TaucEg", 3.0, 0, 0.1, 0.0, ''); $this->AddParameters($ini, $dini, "TaucA", 1.0e4, 0, 3.0e3, 0.0, ''); $this->AddParameters($ini, $dini, "Taucn", 2.0, 0, 0.5, 0.0, ''); $this->AddParameters($ini, $dini, "UrbachE0", 3.2, 0, 0.1, 0.0, ''); $this->AddParameters($ini, $dini, "UrbachEu", 0.1, 0, 0.03, 0.0, ''); } sub SaveComponents { my ($this) = @_; my $App = $this->App(); my $ini = $this->{ini}; return if(!defined $this->{Ellipsometry}); my $BasePath = $ini->{SampleCSVFile}; $BasePath = $ini->{ParameterFile} if(!$BasePath); my ($drive, $directory, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($BasePath); my $BaseDir = "$drive$directory"; $App->print(" Base dir: $BaseDir\n"); my $Frame = $this->{AbsorptionFileFrame}; my $XLabel = $Frame->{X1ListBox}->GetText(); my $Y1Label = $Frame->{Y1ListBox}->GetText(); my $pObsE = $this->{AbsorptionCSV}->GetData($XLabel); my $pObsAlpha = $this->{AbsorptionCSV}->GetData($Y1Label); my $nData = $this->{AbsorptionCSV}->nData(); my ($pE, $pAlpha, $pTauc, $pUrbach, $S2) = $this->CalAlphaArrays($pObsE, $pObsAlpha); my $File = Deps::MakePath($BaseDir, "Components.csv", 0); $App->print("\nSave Components to [$File]\n"); my $out = new JFile($File, "w"); if($out) { my $c = 0; $out->print("E(eV),alpha(obs),alpha(cal),alpha(Tauc),alpha(Urbach)\n"); 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); $out->print("$E,$pObsAlpha->[$i],$pAlpha->[$c],$pTauc->[$c],$pUrbach->[$c]\n"); $c++; } $out->Close(); } else { $App->print(" Error: Can not write to [$File].\n"); } } #=================================================== # データ処理 #=================================================== 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 $optics = new Optics; my $Layers = new MultiLayer; $this->{Layers} = $Layers; $Layers->SetIncidentAngle($ini->{TAngle}); 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; } $Surface->AddDielectricModel( "EMA1", "EMA", "Model", "Average", "pMaterials", [$$pAnalyzeLayer, $Air], "pVolumeFractions", [$ini->{SurfaceVf}, 1.0 - $ini->{SurfaceVf}], ); for(my $i = $this->{ini}->{nFilmLayers} ; $i >= 1 ; $i--) { my $FileName = $ini->{"Sample${i}CSVFile"}; if($ini->{"Sample${i}CSVFile"}) { my @ret = $Films[$i]->AddDielectricModel( "Film${i}", "EFileForTranparent", "Path", $FileName, ); if(@ret == 0) { print "Error: Can not read [$FileName].\n"; return; } } } $$pAnalyzeLayer->AddDielectricModel( "Constant1", "Constant", "e1inf", 0.0, "e2inf", 0.0, ); 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"}, ); } if($this->{ini}->{nFilmLayers} > 0 and $ini->{SubstrateCSVFile}) { my @ret = $Substrate->AddDielectricModel( "Substrate", "EFileForTranparent", "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); $Layers->PrintLayers() if($IsPrint); #========================================================= # フィッティング設定 #========================================================= return if(!$BuildOptimize); my $iAnalyzeFilm = 1; my $optimize = new Optimize(); $this->{Optimize} = $optimize; $optimize->AddParameters( "Film-e2", $Layers->pVariable($iAnalyzeFilm, 'Constant1::e2inf'), 1, 0.001, 0.0, '', # $dini->{e2infcheck}, $dini->{e2infscale}, $dini->{e2infmin}, $dini->{e2infmax}, sub { $Layers->SetVariable($iAnalyzeFilm, 'Constant1::e2inf', $_[0]); $ini->{e2inf} = $_[0]; }, ); } sub PointByPoint { my ($this) = @_; my $App = $this->App(); my $ini = $this->{ini}; my $el = $this->{Ellipsometry}; $this->UpdateParameters(); $this->BuildLayerModel(1, 1); my $Layers = $this->{Layers}; my $optimize = $this->{Optimize}; $Layers->SetIncidentAngle($ini->{TAngle}); my $pObsE = $this->{CPMCSV}->GetData('.*eV.*', '.*E.*'); my $pObsAlpha = $this->{CPMCSV}->GetData('alpha.*'); my $nData = @$pObsE; my $Method = $this->mw()->{LSQFrame}->{LSQMethodListBox}->GetText(); my $FitTo = $this->mw()->{LSQFrame}->{FitToListBox}->GetText(); my $KCPM = $this->{ini}->{KCPM}; my (@PbPE, @PbPe2, @PbPS2, @PbPAlpha); my $iAnalyzeFilm = $this->{ini}->{nFilmLayers}; my $pe2inf = $Layers->pVariable($iAnalyzeFilm, 'Constant1::e2inf'), my $c = 0; #print "parameters\n"; #$optimize->PrintParameters(1); $$pe2inf = 0.0; for(my $i = 0 ; $i < $nData ; $i++) { next if($ini->{nSkipData} > 0 and $i % $ini->{nSkipData} != 0); my $E = $pObsE->[$i]; next if((defined $ini->{FitEmin} and $ini->{FitEmin} ne '' and $E < $ini->{FitEmin}) or (defined $ini->{FitEmax} and $ini->{FitEmax} ne '' and $ini->{FitEmax} < $E) ); my $ObsAlpha = $KCPM * $pObsAlpha->[$i]; my $scale = $$pe2inf * 0.001; $scale = 1.0e-8 if($scale <= 0.0); $optimize->{diffv} = $scale; my ($OptVars, $MinVal) = $optimize->Optimize( $Method, undef, undef, [$scale], $ini->{EPS}*$scale*$scale*1e4, $ini->{nMaxIter}, $ini->{iPrintLevel}, sub { $this->CalS2ForPointByPoint($optimize, $FitTo, $Layers, $E, $ObsAlpha, @_); }, undef, sub { Optimize::BuildDifferentialMatrixes(@_); }, ); $optimize->RecoverParameters($OptVars); my ($e1, $e2) = $Layers->pLayer($iAnalyzeFilm)->CalEps($E); my ($n, $k) = Optics::EpsToNK($e1, $e2); my $wl = Optics::eVTonm($E); my $CalAlpha = Optics::KToAlpha($wl, $k); printf "E=%5.2f eV: e2=%8.5g alpha=%8.4g => %8.4g cm-1 (S2=%8.3g)\n", $E, $$pe2inf, $ObsAlpha, $CalAlpha, $MinVal; $PbPE[$c] = $E; $PbPe2[$c] = $$pe2inf; $PbPS2[$c] = $MinVal; $PbPAlpha[$c] = $CalAlpha; $c++; } $this->{PbPE} = \@PbPE; $this->{PbPe2} = \@PbPe2; $this->{PbPAlpha} = \@PbPAlpha; $this->{PbPS2} = \@PbPS2; $this->RePlot(1); } sub CalS2ForPointByPoint { my ($this, $optimize, $FitTo, $Layers, $E, $Alpha, $pVars, $iPrintLevel) = @_; my $ini = $this->{ini}; my $iAnalyzeFilm = $this->{ini}->{nFilmLayers}; $optimize->RecoverParameters($pVars); my $d = $ini->{"Film${iAnalyzeFilm}Thickness"} * 1.0e-7; # cm my ($rs123, $rp123, $ts123, $tp123, $Rtots, $Rtotp, $Ttots, $Ttotp) = $Layers->CalFresnelCoefficient($E); my $R = ($Rtots + $Rtotp) / 2.0; my $T = ($Ttots + $Ttotp) / 2.0; my $CalAlpha = -log($R + $T) / $d; #print "E2=$E alpha=$Alpha cal=$CalAlpha\n"; my $S2 = $CalAlpha - $Alpha; $S2 = $S2 * $S2; #print "S2=$S2 ($CalAlpha)\n"; $this->mw()->update(); return $S2; } sub Recalc { my ($this) = @_; $this->CalAbs(); } sub CalAbs { my ($this) = @_; $this->UpdateParameters(); my $el = $this->{AbsorptionCSV}; my $X1Label = $this->{AbsorptionFileFrame}->{X1ListBox}->GetText(); my $Y1Label = $this->{AbsorptionFileFrame}->{Y1ListBox}->GetText(); my $pObsE = $this->{AbsorptionCSV}->GetData($X1Label); my $pObsAlpha = $this->{AbsorptionCSV}->GetData($Y1Label); my $nData = $this->{AbsorptionCSV}->nData(); my ($pE, $pCalAlpha, $pTauc, $pUrbach, $S2) = $this->CalAlphaArrays($pObsE, $pObsAlpha); $this->{pCalAlphaEArray} = $pE; $this->{pCalAlphaArray} = $pCalAlpha; $this->RePlot(); } sub CalRT { my ($this) = @_; $this->UpdateParameters(); $this->BuildLayerModel(1, 1); my ($pE, $pR, $pT) = $this->CalRTArrays($this->{Layers}); $this->{pEArray} = $pE; $this->{pRArray} = $pR; $this->{pTArray} = $pT; $this->RePlot(); } sub CalRTArrays { my ($this, $Layers) = @_; my $ini = $this->{ini}; $Layers->SetIncidentAngle($ini->{TAngle}); my $Frame = $this->{AbsorptionFileFrame}; my $XLabel = $Frame->{X1ListBox}->GetText(); my $Y1Label = $Frame->{Y1ListBox}->GetText(); my $pObsE = $this->{AbsorptionCSV}->GetData($XLabel, '.*E.*', '.*eV.*'); my $pObsAlpha = $this->{AbsorptionCSV}->GetData($Y1Label); my $nData = $this->{AbsorptionCSV}->nData(); my ($emin, $emax) = $this->{AbsorptionCSV}->GetXMinMax(); if(!defined $ini->{FitEmin} or $ini->{FitEmin} eq '') { $ini->{FitEmin} = $emin; } if(!defined $ini->{FitEmax} or $ini->{FitEmax} eq '') { $ini->{FitEmax} = $emax; } my (@E, @R, @T); my $c = 0; my $nf = $ini->{nFilmLayers}; my $d = $ini->{"Film${nf}Thickness"} * 1.0e-7; # cm 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 ($rs123, $rp123, $ts123, $tp123, $Rtots, $Rtotp, $Ttots, $Ttotp) = $Layers->CalFresnelCoefficient($E); my $R = ($Rtots + $Rtotp) / 2.0; my $T = ($Ttots + $Ttotp) / 2.0; $E[$c] = $E; $R[$c] = $R; $T[$c] = $T; #my $Abs = 1.0 - $R[$c] - $T[$c]; my $alpha = -log($R + $T) / $d; printf "E=%6.3f eV: alpha=%10.4g cm-1\n", $E, $alpha; $c++; } return (\@E, \@R, \@T); } sub Fit { my ($this) = @_; my $ini = $this->{ini}; my $dini = $this->{dini}; $this->UpdateParameters(); $this->CalAbs(); my $Method = $this->mw()->{LSQFrame}->{LSQMethodListBox}->GetText(); print "Method: $Method\n"; print "nMaxIter: $ini->{nMaxIter}\n"; my $Frame = $this->{AbsorptionFileFrame}; my $XLabel = $Frame->{X1ListBox}->GetText(); my $Y1Label = $Frame->{Y1ListBox}->GetText(); my $pObsE = $this->{AbsorptionCSV}->GetData($XLabel); my $pObsAlpha = $this->{AbsorptionCSV}->GetData($Y1Label); #========================================================= # 最適化の実行 #========================================================= my $optimize = $this->{Optimize} = new Optimize(); $optimize->AddParameters( "Eg", \$ini->{TaucEg}, $dini->{TaucEgcheck}, $dini->{TaucEgscale}, $dini->{TaucEgmin}, $dini->{TaucEgmax}, sub { $ini->{TaucEg} = $_[0]; }, "A", \$ini->{TaucA}, $dini->{TaucAcheck}, $dini->{TaucAscale}, $dini->{TaucAmin}, $dini->{TaucAmax}, sub { $ini->{TaucA} = $_[0]; }, "n", \$ini->{Taucn}, $dini->{Taucncheck}, $dini->{Taucnscale}, $dini->{Taucnmin}, $dini->{Taucnmax}, sub { $ini->{Taucn} = $_[0]; }, "E0", \$ini->{UrbachE0}, $dini->{UrbachE0check}, $dini->{UrbachE0scale}, $dini->{UrbachE0min}, $dini->{UrbachE0max}, sub { $ini->{UrbachE0} = $_[0]; }, "Eu", \$ini->{UrbachEu}, $dini->{UrbachEucheck}, $dini->{UrbachEuscale}, $dini->{UrbachEumin}, $dini->{UrbachEumax}, sub { $ini->{UrbachEu} = $_[0]; }, ); #$Method = "ModifiedNewton"; $optimize->SetnS2Calculation(0); my ($OptVars, $MinVal) = $optimize->Optimize( $Method, undef, undef, undef, $ini->{EPS}, $ini->{nMaxIter}, $ini->{iPrintLevel}, sub { $this->CalS2($pObsE, $pObsAlpha, @_); }, undef, sub { Optimize::BuildDifferentialMatrixes(@_); }, ); $optimize->RecoverParameters($OptVars); print "\nOptimized at:\n"; $optimize->PrintParameters(1, $OptVars, $MinVal, 1); $this->SetS2($MinVal); $this->UpdateParameters(); $this->CalAbs(); $this->RePlot(0); } sub CalS2 { my ($this, $pObsE, $pObsAlpha, $pVars, $iPrintLevel) = @_; #print "pVars=", join(',', @$pVars); my $optimize = $this->{Optimize}; my $ini = $this->{ini}; $optimize->RecoverParameters($pVars); my ($pE, $pAlpha, $pTauc, $pUrbach, $S2) = $this->CalAlphaArrays($pObsE, $pObsAlpha); $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->CalAbs(); $this->RePlot(); } $this->mw()->update(); return $S2; } sub CalAlphaArrays { my ($this, $pObsE, $pObsAlpha) = @_; my $ini = $this->{ini}; return if(!defined $pObsE); my $Eg = $ini->{TaucEg}; my $A = $ini->{TaucA}; my $n = $ini->{Taucn}; my $Eu = $ini->{UrbachEu}; my $E0 = $ini->{UrbachE0}; my $nData = @$pObsE; my (@E, @Alpha, @Tauc, @Urbach); 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(($ini->{FitEmin} ne '' and $E < $ini->{FitEmin}) or ($ini->{FitEmax} ne '' and $ini->{FitEmax} < $E)); $E[$c] = $E; if($E < $Eg) { $Alpha[$c] = 0.0; } else { $Alpha[$c] += $A * ($E - $Eg)**$n; } $Tauc[$c] = $Alpha[$c]; $c++; } my $S2 = 0.0; my $C = Algorism::InterpolateByCubicSpline(\@E, \@Alpha, $E0); #print "Alpha=$C at E0=$E0\n"; $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(($ini->{FitEmin} ne '' and $E < $ini->{FitEmin}) or ($ini->{FitEmax} ne '' and $ini->{FitEmax} < $E)); my $Au = $C * exp(($E - $E0) / $Eu); if($E < $E0) { $Alpha[$c] = $Au; $Urbach[$c] = $Au; } else { $Urbach[$c] = 0.0; } my $d = $Alpha[$c] - $pObsAlpha->[$i]; $S2 += $d * $d; $c++; } $S2 = sqrt($S2 / $c); return (\@E, \@Alpha, \@Tauc, \@Urbach, $S2); } sub Connect { my ($this) = @_; my ($pX1, $pY1, $X1Label, $Y1Label); my $key = 'Absorption'; if(defined $this->{"${key}FileFrame"} and defined $this->{"${key}CSV"}) { $X1Label = $this->{"${key}FileFrame"}->{X1ListBox}->GetText(); $Y1Label = $this->{"${key}FileFrame"}->{Y1ListBox}->GetText(); $pX1 = $this->{"${key}CSV"}->GetData($X1Label); $pY1 = $this->{"${key}CSV"}->GetData($Y1Label); } $key = 'CPM'; if(defined $this->{"${key}FileFrame"} and defined $this->{"${key}CSV"}) { $X1Label = $this->{"${key}FileFrame"}->{X1ListBox}->GetText(); $Y1Label = $this->{"${key}FileFrame"}->{Y1ListBox}->GetText(); $pX1 = $this->{"${key}CSV"}->GetData($X1Label); $pY1 = $this->{"${key}CSV"}->GetData($Y1Label); } my $E = $this->{ini}->{ConnectE}; my $AbsorptionY = $this->{"AbsorptionCSV"}->YVal($E); my $CPMY = $this->{"CPMCSV"}->YVal($E); $this->{ini}->{KCPM} = $AbsorptionY / $CPMY; $this->UpdateParameters(); $this->RePlot(1); } sub CreateGraphFrame { my ($this, $canvas, $TargetData) = @_; $canvas = $this->Canvas(); my $App = $this->App(); 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->SetXCaption(""); my $XScale0 = $GraphFrame0->GetXScale(0); my $YScale0 = $GraphFrame0->GetYScale(0); $GraphFrame0->SetPositionByStr($FramePosStr0); $GraphFrameArray->AddGraphFrame(); my $GraphFrame1 = $GraphFrameArray->GetGraphFrame(1); my $FramePosStr1 = $App->{"GraphFrame1Position"}; my $XScale1 = $GraphFrame1->GetXScale(0); my $YScale1 = $GraphFrame1->GetYScale(0); $GraphFrame1->SetPositionByStr($FramePosStr1); $GraphFrame0->SetXCaption(""); $XScale0->SetScaleStringVisible(1); $XScale0->SetCaptionVisible(1); $GraphFrame1->SetXCaption(""); $GraphFrame1->SetYCaption("T,R"); $XScale1->SetScaleStringVisible(1); $XScale1->SetCaptionVisible(1); $GraphFrame0->AddSynchronousFrame('x', $GraphFrame1); $GraphFrame1->AddSynchronousFrame('x', $GraphFrame0); $GraphFrameArray->SetShowScaleDialogCallback(sub { $this->ShowScaleDialog(@_) } ); $GraphFrame0->SetViewRange(0, 0, 1, 1); $GraphFrame1->SetViewRange(0, 0, 1, 1); if($RefreshGraphScaleFrame) { my $EntryWidth = $this->{EntryWidth}; # $this->RefreshLayersPane($EntryWidth); $this->RefreshViewRangePane($EntryWidth); } } sub AssignGraphData { my ($this, $ResetViewRange) = @_; $ResetViewRange = 1 if(!defined $ResetViewRange); return if(!defined $this->{ini}->{AbsorptionCSVFile}); return if(!defined $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1YAxisListBox}); #my @YList = ('x', 'log(|x|)', '(ahv)^1/2 (Tauc)', 'a^1/2 (Indirect)', 'a^2 (Direct'); my $YAxisPlotType = $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1YAxisListBox}->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 ($pX1, $pY1, @X1Label, @Y1Label); my $key = 'Absorption'; if(defined $this->{"${key}FileFrame"} and defined $this->{"${key}CSV"}) { $X1Label[0] = $this->{"${key}FileFrame"}->{X1ListBox}->GetText(); $Y1Label[0] = $this->{"${key}FileFrame"}->{Y1ListBox}->GetText(); $pX1 = $this->{"${key}CSV"}->GetData($X1Label[0]); $pY1 = $this->{"${key}CSV"}->GetData($Y1Label[0]); my $nData = $this->{"${key}CSV"}->nData(); if($pX1) { my $l = $Y1Label[0]; $l =~ s/\([^\)]*\)/\(opt\)/; my ($pConvX, $pConvY) = $this->ConvertXY($YConvFunc, $pX1, $pY1); $GraphFrame0->AddGraphData($pConvX, $pConvY, 2, 'black', "", 6, "red", 0, "red", "XAutoSkip", "Energy", $l); } } $key = 'CPM'; if(defined $this->{"${key}FileFrame"} and defined $this->{"${key}CSV"}) { $X1Label[1] = $this->{"${key}FileFrame"}->{X1ListBox}->GetText(); $Y1Label[1] = $this->{"${key}FileFrame"}->{Y1ListBox}->GetText(); $pX1 = $this->{"${key}CSV"}->GetData($X1Label[1]); $pY1 = $this->{"${key}CSV"}->GetData($Y1Label[1]); my $KCPM = $this->{ini}->{KCPM}; my @ConvY; my $nData = $this->{"${key}CSV"}->nData(); for(my $i = 0 ; $i < $nData ; $i++) { $ConvY[$i] = $KCPM * $pY1->[$i]; } if($pX1) { my $l = $Y1Label[1]; $l =~ s/\([^\)]\)/\(CPM\)/; my ($pConvX, $pConvY) = $this->ConvertXY($YConvFunc, $pX1, \@ConvY); $GraphFrame0->AddGraphData($pConvX, $pConvY, 2, 'blue', "", 6, "red", 0, "red", "XAutoSkip", "Energy", $l); } } my $pCalE = $this->{pEArray}; my $pCalR = $this->{pRArray}; my $pCalT = $this->{pTArray}; if($pCalE) { $GraphFrame1->AddGraphData($pCalE, $pCalR, 0, "black", "circle", 3, "", 1, "black", "XAutoSkip", "Energy", "R (cal)"); $GraphFrame1->AddGraphData($pCalE, $pCalT, 0, "blue", "circle", 3, "", 1, "black", "XAutoSkip", "Energy", "T (cal)"); } my $pPbPE = $this->{PbPE}; my $pPbPAlpha = $this->{PbPAlpha}; # $this->{PbPe2} = \@PbPe2; # $this->{PbPS2} = \@PbPS2; if($pPbPE) { my ($pConvX, $pConvY) = $this->ConvertXY($YConvFunc, $pPbPE, $pPbPAlpha); $GraphFrame0->AddGraphData($pConvX, $pConvY, 0, "red", "circle", 3, "red", 1, "red", "XAutoSkip", "Energy", "alpha(cal)"); } my $pCalAlphaE = $this->{pCalAlphaEArray}; my $pCalAalpha = $this->{pCalAlphaArray}; if($pCalAlphaE) { my ($pConvX, $pConvY) = $this->ConvertXY($YConvFunc, $pCalAlphaE, $pCalAalpha); $GraphFrame0->AddGraphData($pConvX, $pConvY, 0, "darkgreen", "circle", 3, "", 1, "darkgreen", "XAutoSkip", "Energy", "alpha (cal)"); } my $XScale0 = $GraphFrame0->GetXScale(0); $XScale0->SetScaleStringVisible(0); $GraphFrame0->SetXCaption(''); $GraphFrame0->SetYCaption($AbsorptionLabel); #$Y1Label[0]); $GraphFrame1->SetXCaption($X1Label[0]); $GraphFrame1->SetYCaption("T,R"); $GraphFrame0->SetXScalePlotType('x'); $GraphFrame0->SetYScalePlotType('x'); $GraphFrame1->SetXScalePlotType('x'); $GraphFrame1->SetYScalePlotType('x'); $this->SetViewRange($ResetViewRange); } 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); } 1;