#=============================================== # TkFittingSimple #=============================================== package TkFittingSimple; 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::Science; use Sci::Ellipsometry; use Sci::Optimize; #============================================================ # 大域変数・変数等取得関数 #============================================================ my $ProgramName; #============================================================ # コンストラクタ、デストラクタ #============================================================ #呼び出されることはない sub new { my ($class, $app, $programname, @a) = @_; $ProgramName = $programname; my $self = TkFittingCommon2->new($app, @a); my $this = bless $self, $class; $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}->{nOrder} = 5; $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", 6), [qw(Main Vars ViewRange LSQ Setup GraphFrame)], # [qw(Main ViewRange LSQ GaussLorentz Setup GraphFrame)], [qw()], # [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'; $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->OnDestroy( sub { $this->Close(); } ); # $this->{FileNameEntry}->bind('' => sub { $this->Close(); } ); $this->bind('' => sub { $this->App()->IniFile()->WriteString("Window", "geometry", $this->geometry()); } ); } 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 $Samplefmask = '*.*'; #'*.csv;*.spe;*.jel;*.asp;*.smo;*isa;*.ref;*.pal;*.bef;*.aft'; $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, 8, #$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'); $this->BuildVariablesFrame($MainPaneFrame, 'Variables'); $this->BuildFooter($MainPaneFrame, $EntryWidth); $this->UpdateParameters(); } sub BuildVariablesFrame { my ($this, $MainFrame, $Label) = @_; my $pVariableHashArray = $this->{pVariableHashArray}; return if(!defined $pVariableHashArray); my $Frame = $MainFrame->MyLabFrame( -label => $Label, -labelside => 'acrosstop', )->pack(-anchor => 'nw'); my $EntryWidth = 12; my $nc = $this->{pParameterHash}->{nCheckEntryColumn}; $nc = 1 if(!defined $nc); for(my $i = 0 ; $i < @$pVariableHashArray ; $i++) { my $p = $pVariableHashArray->[$i]; my $vname = $p->{Name}; $this->MakeCheckEntry($Frame, $vname, "$vname:", $this->{dini}->pVariable("${vname}check", $p->{ID}), $this->{ini}->pVariable(${vname}, $p->{Val}), "%g", $EntryWidth, "", $i / $nc, $i % $nc); } } sub BuildVarsPane { my ($this, $MainPaneFrame, $EntryWidth) = @_; my $Frame = $MainPaneFrame->MyLabFrame( -label => 'Variables', -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $EntryWidth = 12; my $pVariableHashArray = $this->{pVariableHashArray}; my $row = 1; $this->MakeParameterConditionHeading($Frame, 0, 0); for(my $i = 0 ; $i < @$pVariableHashArray ; $i++) { my $p = $pVariableHashArray->[$i]; my $vname = $p->{Name}; $this->MakeParameterConditionColumn($Frame, $vname, "$vname:", "%12.6g", $p->{Val}, $p->{ID}, $p->{Scale}, $p->{Min}, $p->{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, ("Re&calc", "&Fit", "&Save")); $ButtonFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); } #=================================================== # 初期化 #=================================================== 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) = @_; } sub AddParameters2 { my ($this, $pVariableHashArray, %hash) = @_; $this->{pVariableHashArray} = $pVariableHashArray; $this->{pParameterHash} = {} if(!defined $this->{pParameterHash}); foreach my $key (keys %hash) { $this->{pParameterHash}->{$key} = $hash{$key}; } my $ini = $this->{ini}; my $dini = $this->{dini}; for(my $i = 0 ; $i < @$pVariableHashArray ; $i++) { my $p = $pVariableHashArray->[$i]; $this->AddParameters($ini, $dini, $p->{Name}, $p->{Val}, $p->{ID}, $p->{Scale}, $p->{Min}, $p->{Max}); } } #=================================================== # ファイル処理 #=================================================== sub ChooseFile { #action = 'open'; #'save' #fmask = '*.csv;*.spe;*.jel;*.asp;*.smo;*isa;*.ref;*.pal;*.bef;*.aft;*.prm'; my ($this, $action, $fmask, $Option, $name, $Frame) = @_; #print "TkFittingCommon2::ChooseFile: a=$action, f=$fmask, n=$name, F=$Frame, o=$Option\n"; my $App = $this->App(); my $canvas = $this->Canvas(); my $mw = $this->mw(); my $Entry = $Frame->{PathEntry}; my $filepath = $this->ChooseAFile($name, $action, $fmask, '', "Choose file", $Entry, $Option); return undef if(!defined $filepath or $filepath eq ''); my $ret; if($Option eq 'ChooseParameterFile') { $ret = $this->ReadParameterFile($filepath, 1, $Frame); } elsif($Option =~ /ChooseSample.*File/i) { $ret = $this->ReadSampleDataFile($filepath, 1, $Frame); } return undef unless($ret); $this->CreateGraphFrame() if(!$this->GetGraphFrameArray()); return $ret; } sub SaveParameterFile { my ($this, $Option, $filepath, $name, $Frame) = @_; $filepath = $Frame->{PathEntry}->GetText() if($filepath eq '' and defined $Frame->{PathEntry}); my $mw = $this->mw(); my $NoteBook = $mw->{NoteBook}; if($this->{SampleFileFrame}) { $this->{ini}->{SampleX1} = $this->{SampleFileFrame}->{X1ListBox}->GetText() if($this->{SampleFileFrame}->{X1ListBox}); $this->{ini}->{SampleY1} = $this->{SampleFileFrame}->{Y1ListBox}->GetText() if($this->{SampleFileFrame}->{Y1ListBox}); } if($NoteBook and $NoteBook->{ViewRangePaneFrame}) { $this->{ini}->{YAxisPlotType} = $NoteBook->{ViewRangePaneFrame}->{GraphFrame1YAxisListBox}->GetText(); } if(!defined $filepath or $filepath eq '') { $filepath = $this->{ini}->{SampleCSVFile}; $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:\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); $this->DecomposeParameters($ini, $dini); $this->RefreshMainPane($this->{EntryWidth}); 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}); 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; } $this->RefreshViewRangePane($this->{EntryWidth}); my $YAxisListBox = $this->{ini}->{YAxisPlotType}; if($YAxisListBox) { $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1YAxisListBox}->SetText($this->{ini}->{YAxisPlotType}) if($this->{ini}->{YAxisPlotType}); } $this->CreateGraphFrame() if(!$this->GetGraphFrameArray()); $this->AssignGraphData(); $this->Draw(); return 1; } sub ReadSampleDataFile { my ($this, $filepath, $IsPrint, $UpdateRange, $IsPlot, $Frame) = @_; $UpdateRange = 1 if(!defined $UpdateRange); $IsPlot = 1 if(!defined $IsPlot); my $App = $this->App(); $Frame = $this->{SampleFileFrame} if(!defined $Frame); 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; } # 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}); my $pX = $pData->GetXData(@$pXDataLabel); $pData->GetYData(@$pYDataLabel); if($pX->[1] < $pX->[0]) { $this->{DataFile}->ReverseData(); } $pData->CalMinMax(); ($this->{ini}->{FitEmin}, $this->{ini}->{FitEmax}) = $pData->GetXMinMax() if(!defined $this->{ini}->{FitEmin} or $this->{ini}->{FitEmin} 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(); } return $filepath; } sub Save { my ($this) = @_; $this->Recalc() if(!defined $this->{pCalX}); my $path = $this->{ini}->{ParameterFile}; $path = $this->{ini}->{SampleCSVFile} if(!$path); $path = 'FittingResult.csv' if($path eq ''); my ($drive, $directory, $filename, $ext1, $lastdir, $filebody) = Deps::SplitFilePath($path); $path = Deps::MakePath("$drive$directory", "$filebody-FittingResult.csv", 0); $this->print("\nSave fitting result to [$path].\n"); my $ini = $this->{ini}; my $pVariableHashArray = $this->{pVariableHashArray}; my $out = new JFile($path, "w"); if(!$out) { $this->print("Error: Can not write to [$path].\n"); return; } $out->print("E,I(obs),I(cal)\n"); my $pE = $this->{pCalX}; my $pObs = $this->{pObsY}; my $pCal = $this->{pCalY}; for(my $i = 0 ; $i < @$pE ; $i++) { my $p = $pVariableHashArray->[$i]; if($p) { my $vname = $p->{Name}; $out->print("$pE->[$i],$pObs->[$i],$pCal->[$i],$vname,$ini->{$vname}\n"); } else { $out->print("$pE->[$i],$pObs->[$i],$pCal->[$i]\n"); } } $out->Close(); } #=================================================== # 計算 #=================================================== sub BuildOptimize { my ($this, $IsPrint) = @_; $IsPrint = 1 if(!defined $IsPrint); my $ini = $this->{ini}; my $dini = $this->{dini}; my $pVariableHashArray = $this->{pVariableHashArray}; my $optimize = $this->{Optimize} = new Optimize;; for(my $i = 0 ; $i < @$pVariableHashArray ; $i++) { my $vname = $pVariableHashArray->[$i]->{Name}; my $ii = $i; $optimize->AddParameters( $vname, \$ini->{$vname}, $dini->{"${vname}check"}, $dini->{"${vname}scale"}, $dini->{"${vname}min"}, $dini->{"${vname}max"}, sub { $ini->{$vname} = $_[0]; }, ); } } sub Recalc { my ($this) = @_; return if(!defined $this->{DataFile}); my $ini = $this->{ini}; 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 $pXS = $this->{DataFile}->GetData($X1Label) if($X1Label); my $pYS = $this->{DataFile}->GetData($Y1Label) if($Y1Label); my (@X, @Y); my $c = 0; for(my $i = 0 ; $i < @$pXS ; $i++) { my $x = $pXS->[$i]; next if($x < $XMin or $XMax < $x); next if($nSkipData > 0 and $i % $nSkipData != 0); $X[$c] = $x; $Y[$c] = $pYS->[$i]; $c++; } my $pVariableHashArray = $this->{pVariableHashArray}; my @v; for(my $i = 0 ; $i < @$pVariableHashArray ; $i++) { $v[$i] = $ini->{$pVariableHashArray->[$i]->{Name}}; } my ($pYTotal) = $this->CalCurve(\@X, \@v); $this->{pObsX} = \@X; $this->{pObsY} = \@Y; $this->{pCalX} = \@X; $this->{pCalY} = $pYTotal; $this->SUPER::RePlot(); } sub Fit { my ($this) = @_; return if(!defined $this->{DataFile}); 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"; 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 $pXS = $this->{DataFile}->GetData($X1Label) if($X1Label); my $pYS = $this->{DataFile}->GetData($Y1Label) if($Y1Label); my (@X, @Y); my $c = 0; for(my $i = 0 ; $i < @$pXS ; $i++) { my $x = $pXS->[$i]; next if($x < $XMin or $XMax < $x); next if($nSkipData > 0 and $i % $nSkipData != 0); $X[$c] = $x; $Y[$c] = $pYS->[$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, @_); }, 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 CalCurve { my ($this, $pX, $pVars) = @_; my @YTotal; for(my $i = 0 ; $i < @$pX ; $i++) { $YTotal[$i] = $this->CalY($pX->[$i], $pVars); } return (\@YTotal); } sub CalS2 { my ($this, $pX, $pY, $pVars, $iPrintLevel) = @_; #print "pVars=", join(',', @$pVars), "\n"; my $optimize = $this->{Optimize}; my $ini = $this->{ini}; $optimize->RecoverParameters($pVars); my $S2 = 0.0; my $c = 0; for(my $i = 0 ; $i < @$pX ; $i++) { my $x = $pX->[$i]; my $YCal = $this->CalY($x, $pVars); my $d = $YCal - $pY->[$i]; $S2 += $d * $d; $c++; } $S2 = sqrt($S2 / $c) if($c > 0); $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 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) = @_; $ResetViewRange = 1 if(!defined $ResetViewRange); my $ini = $this->{ini}; # return if(!defined $ini->{SampleCSVFile}); return if(!defined $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{GraphFrame1YAxisListBox}); my $GraphFrameArray = $this->GetGraphFrameArray(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); $GraphFrame0->ClearAllData(); my ($X1Label, $Y1Label); my $DataKey = "DataFile"; my $FrameKey = "SampleFileFrame"; my $pData = $this->{$DataKey}; return if(!defined $pData); my $nData = $pData->nData(); return if($nData <= 0); my $Frame = $this->{$FrameKey}; $X1Label = $Frame->{X1ListBox}->GetText(); $Y1Label = $Frame->{Y1ListBox}->GetText(); $X1Label = 'X' if(!$X1Label); $Y1Label = 'Y1' if(!$Y1Label); my $pX = $pData->GetData($Frame->{X1ListBox}->GetText()); my $pY1 = $pData->GetData($Frame->{Y1ListBox}->GetText()); $GraphFrame0->SetXCaption($X1Label); $GraphFrame0->SetYCaption($Y1Label); my $color = "black"; my $label = "Sample data"; my $fname = $ini->{"SampleCSVFile"}; if($pX) { $GraphFrame0->AddGraphData($pX, $pY1, 2, $color, "", 6, $color, 0, $color, "XAutoSkip", "Energy", "$fname - $label") if($pY1); } my $pCalX = $this->{pCalX}; my $pCalY = $this->{pCalY}; if($pCalX) { $GraphFrame0->AddGraphData($pCalX, $pCalY, 0, "", "circle", 3, "", 1, "red", "XAutoSkip", "Energy", "Calc (total)") if($pCalY); } $GraphFrame0->SetXScalePlotType('x'); $GraphFrame0->SetYScalePlotType('x'); $this->SetViewRange($ResetViewRange);#, $FlipX); } sub RePlot { my ($this, $ResetViewRange, $CreateGraphFrame, $AssignGraphData, $Draw) = @_; $this->Recalc(); } 1;