#=============================================== # TkFittingCommon #=============================================== package TkFittingCommon; use TkPlotModule; @ISA = qw(TkPlotModule); #公開したいサブルーチン #@EXPORT = qw(DelSpace Reduce01 MakePath RegExpQuote); use strict; #use Tk::JPEG; use Utils; use IniFile; use CSV; use Tk; use Tk::Balloon; use MyTk::Dialog; use MyTk::MyFrame; use MyTk::MyLabFrame; use MyTk::MyLabel; use MyTk::MyEntry; use MyTk::MyListbox; use MyTk::MyBrowseEntry; use MyTk::MyText; use MyTk::MyButton; use MyTk::MyCheckbutton; use MyTk::MyMenubutton; use MyTk::MyCanvas; use MyTk::MyAdjuster; use MyTk::MyScale; use Tk::NoteBook; use MyTk::GraphFrameArray; use GraphData; use Sci::Ellipsometry; #============================================================ # 変数等取得関数 #============================================================ sub FileType { return shift->{FileType}; } sub SetFileType { my ($this,$t)=@_; return $this->{FileType} = $t; } sub FileName { my ($this)=@_; $this->{FileName} = '' if(!defined $this->{FileName}); return shift->{FileName}; } sub SetFileName { my ($this,$f)=@_; return $this->{FileName} = $f; } sub SetDataArray { my ($this, $da)=@_; return $this->{DataArray} = $da; } sub DataArray { return shift->{DataArray}; } sub GetColor { return shift->{Color}; } sub ColorMapImage { return shift->{ColorMapImage}; } sub SetColorMapImage { my ($this,$m)=@_; return shift->{ColorMapImage} = $m; } #============================================================ # コンストラクタ、デストラクタ #============================================================ #呼び出されることはない sub new { my ($module, $app) = @_; my $this = {}; bless $this; return $this; } sub DESTROY { my $this = shift; $this->SUPER::DESTROY(@_); } #============================================================ # 継承クラスで定義しなおす関数 #============================================================ sub InsertToolBar { my ($this, $frame) = @_; #print "this=$this\n"; #ツールバーに追加 # $this->mw()->{ShowRecalcDataButton} = $frame->MyCheckbutton( # -text => 'Show Recalc data', # -takefocus => 1, # -variable => $this->{ini}->pVariable('ShowRecalcData', 1), # -indicatoron => 0, # -command => sub { $this->RePlot(0, 0, 1, 1); }, # )->pack(-side => 'left', -fill => 'x'); $this->mw()->{ShowSamplePlotButton} = $frame->MyCheckbutton( -text => 'Show Sample', -takefocus => 1, -variable => $this->{ini}->pVariable('ShowSamplePlot', 1), -indicatoron => 0, -command => sub { $this->RePlot(0, 0, 1, 1); }, )->pack(-side => 'left', -fill => 'x'); $this->mw()->{ShowCalcPlotButton} = $frame->MyCheckbutton( -text => 'Show CalcPlot', -takefocus => 1, -variable => $this->{ini}->pVariable('ShowCalcPlot', 1), -indicatoron => 0, -command => sub { $this->RePlot(0, 0, 1, 1); }, )->pack(-side => 'left', -fill => 'x'); $this->mw()->{ShowPbPPlotButton} = $frame->MyCheckbutton( -text => 'Show PbP', -takefocus => 1, -variable => $this->{ini}->pVariable('ShowPbPPlot', 1), -indicatoron => 0, -command => sub { $this->RePlot(0, 0, 1, 1); }, )->pack(-side => 'left', -fill => 'x'); $this->mw()->{AutoUpdateButton} = $frame->MyCheckbutton( -text => 'Auto Update', -takefocus => 1, -variable => $this->{ini}->pVariable('AutoUpdate', 0), -indicatoron => 0, )->pack(-side => 'left', -fill => 'x'); $frame->MyLabel(-text => "S2:")->pack(-side => 'left', -fill => 'x'); $this->mw()->{PrevS2Entry} = $frame->MyEntry( -width => 12, -textvariable => $this->{ini}->pVariable('PrevS2', 0.0), -format => "%12.6g", )->pack(-side => 'left', -fill => 'x'); $frame->MyLabel(-text => "=>")->pack(-side => 'left', -fill => 'x'); $this->mw()->{LatestS2Entry} = $frame->MyEntry( -width => 12, -textvariable => $this->{ini}->pVariable('LatestS2', 0.0), -format => "%12.6g", )->pack(-side => 'left', -fill => 'x'); } sub Initialize { my ($this, $InitializeParameterFile, $InitializeData) = @_; $this->{DataFile} = new Ellipsometry; if($InitializeParameterFile) { $this->{ini}->{SampleCSVFile} = ''; $this->{ini}->{FlipX} = 0; } if($InitializeData) { $this->{pFreq} = undef; $this->{pReal} = undef; $this->{pImag} = undef; } } sub MakeCheckbutton { my ($this, $Frame, $name, $Label, $pVariable, $OnValue, $OffValue) = @_; $OnValue = 1 if(!defined $OnValue); $OffValue = 0 if(!defined $OffValue); $this->{"${name}Checkbutton"} = $Frame->MyCheckbutton( -text => $Label, -variable => $pVariable, -onvalue => $OnValue, -offvalue => $OffValue, )->pack(-side => 'left'); return $this->{"${name}Checkbutton"}; } sub ChooseASaveFile { my ($this, $filepath, $defpath, $fmask) = @_; if(!defined $filepath or $filepath eq '') { $filepath = $this->ChooseSaveFile($defpath, $fmask); } if(!$filepath or $filepath eq '') { return undef; } return $filepath; } sub ChooseSaveFile { my ($this, $path, $fmask, $widget) = @_; $path = 'save.csv' if(!defined $path); $fmask = '*.csv' if(!defined $fmask); $path = $widget->GetText() if($widget); $path = 'out.csv' if(!$path); my $App = $this->App(); my $mw = $this->mw(); my $dir = $this->App()->{WorkDir}; chdir($dir) if($dir); my $defstr = $path; my $message = 'Choose file'; my $filepath = Dialog::OpenFileDialog($mw, 'save', $fmask, $defstr, $message, $dir); if($filepath) { my $DirPath = $this->SetWorkDir($filepath); if($widget) { $widget->SetText($filepath); } } return $filepath; } sub ChooseAFile { my ($this, $type, $mode, $fmask, $defstr, $message, $widget, $Option) = @_; my $dir = ''; unless($widget) { $dir = $this->App()->{WorkDir}; chdir($dir); } my $filepath = Dialog::OpenFileDialog($this->mw(), 'open', $fmask, $defstr, $message, $dir); return undef if(!defined $filepath or $filepath eq ''); my $DirPath = $this->SetWorkDir($filepath); $widget->SetText($filepath) if($widget); return $filepath; } sub ChooseFile { my ($this, $type, $widget, $Option) = @_; #print "ChooseFile: type=$type\n"; my $App = $this->App(); my $canvas = $this->Canvas(); my $mw = $this->mw(); my $mode = 'open'; #'save' my $fmask = '*.csv;*.spe;*.jel;*.asp;*.smo;*isa;*.ref;*.pal;*.bef;*.aft;*.txt'; $fmask = '*.prm' if($Option eq 'ChooseParameterFile'); my $filepath = $this->ChooseAFile($type, $mode, $fmask, '', "Choose file", $widget, $Option); return undef if(!defined $filepath or $filepath eq ''); my $ret; if($Option eq 'ChooseParameterFile') { $ret = $this->ReadParameterFile($filepath); return undef unless($ret); # $this->CreateGraphFrame(); # $this->AssignGraphData(); # $this->Draw(); } elsif($Option =~ /ChooseSample.*File/i) { $ret = $this->ReadSampleDataFile($filepath); return undef unless($ret); # $this->CreateGraphFrame(); # $this->AssignGraphData(); # $this->Draw(); } elsif($Option =~ /ChooseSubstrateFile/i) { $ret = $this->ReadSubstrateDataFile($filepath); return undef unless($ret); # $this->CreateGraphFrame(); # $this->AssignGraphData(); # $this->Draw(); } return $ret; } sub ButtonPressed { my ($this, $event, $type) = @_; my $App = $this->App(); #print "TkFittingCommon::ButtonPressed: this=$this event=$event\n"; if($type eq 'FlipX') { $this->FlipX(); } elsif($type eq 'Recalc') { $this->Recalc(); } elsif($type eq 'Fit') { $this->Fit(); } elsif($type eq 'PointByPoint') { $this->PointByPoint(); } elsif($type eq 'SaveParam') { $this->SaveParameterFile($this->{ini}->{ParameterFile}); return; } elsif($type eq 'EditParam') { my $Editor = $this->App()->{EditorPath}; my $File = $this->{ini}->{ParameterFile}; my $command = "$Editor $File"; system($command); return; } elsif($type eq 'EditSampleCSV') { my $Editor = $this->App()->{EditorPath}; my $File = $this->{ini}->{SampleCSVFile}; my $command = "$Editor $File"; system($command); return; } else { no strict; $this->$type(); use strict; # print "Error in TkFittingCommon::ButtonPressed: Invalid type [$type] for [$event].\n"; } } sub MakeChooseFileEntry { my ($this, $Frame, $name, $Label, $pVariable, $ButtonLabel, $pFunction, $Option) = @_; #print "TkFittingCommon::MakeChooseFileEntry: name=$name label=$Label\n"; $Frame->MyLabel(-text => $Label)->pack(-side => 'left'); $this->{"${name}FileEntry"} = $Frame->MyEntry( -takefocus => 1, -textvariable => $pVariable )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $this->{"${name}FileEntry"}->focus(); $this->{"${name}FilePathButton"} = $Frame->MyButton( -text => $ButtonLabel, -takefocus => 1, -command => sub { &$pFunction($name, $this->{"${name}FileEntry"}, $Option); }, )->pack(-side => 'left'); return $this->{"${name}FileEntry"}; } sub MakeLabelEntry { my ($this, $Frame, $name, $label1, $pVariable, $format, $EntryWidth, $label2, $row, $column, $state) = @_; #print "name=$name, pVariable=$pVariable, v=$$pVariable, format=$format\n"; $state = 'normal' if(!defined $state); if(!$pVariable) { $this->{$name} = ''; $pVariable = \{$this->{$name}}; } $$pVariable = Utils::DelSpace(sprintf($format, $$pVariable)) if($pVariable and $$pVariable); my $ChildFrame = $Frame; #->MyFrame(); $ChildFrame->{Label1} = $ChildFrame->MyLabel(-text => $label1)->grid(-row => $row, -column => 3*$column+0, -columnspan => 1, -sticky => 'e' ); my @a = ( -name => $name, # -text => $val, -textvariable => $pVariable, -state => $state, -format => $format, ); if(defined $EntryWidth) { @a = ( @a, -width => $EntryWidth, ); } $ChildFrame->{Entry} = $Frame->MyEntry( @a )->grid(-row => $row, -column => 3*$column+1, -columnspan => 1, -sticky => 'e' ); $ChildFrame->{Entry}->bind('', sub { $this->EntryFocusedOut($ChildFrame->{Entry}, 'FocusOut', $name); } ); $ChildFrame->{Label2} = $ChildFrame->MyLabel(-text => $label2)->grid(-row => $row, -column => 3*$column+2, -columnspan => 1, -sticky => 'w' ); $ChildFrame->{Label2}->bind('', [ sub { $this->EntryFocusedIn(@_); }, 'FocusIn', $name]); $ChildFrame->{Label2}->bind('', [ sub { $this->EntryFocusedOut(@_); }, 'FocusOut', $name]); $this->{pEntryArray} = [] if(!$this->{pEntryArray}); push(@{$this->{pEntryArray}}, $ChildFrame->{Entry}); return $ChildFrame; #$this->{"${name}Entry"} = $ent; } sub MakeCheckEntry { my ($this, $Frame, $name, $label1, $pCheckVariable, $pVariable, $format, $EntryWidth, $label2, $row, $column, $state) = @_; my $Synchronize; $state = 'normal' if(!defined $state); if($state =~ /sync.*\s+norm/i) { $state = 'normal'; $Synchronize = 1; } elsif($state =~ /sync.*\s+rev/i) { $state = 'normal'; $Synchronize = -1; } #print "name=$name p=$pVariable,$$pVariable form=$format check: $pCheckVariable, $$pCheckVariable f=$format\n"; $$pVariable = Utils::DelSpace(sprintf($format, $$pVariable)); my $ChildFrame = $Frame; my $ButtonLabel = "${name}Button"; my $EntryLabel = "${name}Entry"; $ChildFrame->{$ButtonLabel} = $ChildFrame->MyCheckbutton( -text => $label1, -variable => $pCheckVariable, -onvalue => 1, -offvalue => 0, -indicatoron => 'no', )->grid(-row => $row, -column => 3*$column+0, -columnspan => 1, -sticky => 'e' ); $ChildFrame->{$ButtonLabel}->{status} = $$pCheckVariable; # $button->configure(-command => sub { print "$label1 is pressed [", $button->GetText(), "]\n"; }); #print "name=$name p=$pVariable,$$pVariable w=$EntryWidth form=$format check: $pCheckVariable, $$pCheckVariable f=$format state=$state\n"; $ChildFrame->{$EntryLabel} = $ChildFrame->MyEntry( -name => $name, -width => $EntryWidth, # -text => $val, -textvariable => $pVariable, -state => $state, -format => $format, )->grid(-row => $row, -column => 3*$column+1, -columnspan => 1, -sticky => 'e' ); $ChildFrame->MyLabel(-text => $label2)->grid(-row => $row, -column => 3*$column+2, -columnspan => 1, -sticky => 'w' ); # $ChildFrame->{$EntryLabel}->bind('', [\&EntryFocusedIn, $this, 'FocusIn', $name]); # $ChildFrame->{$EntryLabel}->bind('', [\&EntryFocusedOut, $this, 'FocusOut', $name]); $ChildFrame->{$EntryLabel}->bind('', [ sub { $this->EntryFocusedIn(@_); }, 'FocusIn', $name]); $ChildFrame->{$EntryLabel}->bind('', [ sub { $this->EntryFocusedOut(@_); }, 'FocusOut', $name]); if(defined $Synchronize) { my $onstr = 'disabled'; my $offstr = 'normal'; if($Synchronize < 0) { $onstr = 'normal'; $offstr = 'disabled'; if(!$ChildFrame->{$ButtonLabel}->{status}) { $ChildFrame->{$EntryLabel}->configure(-state => 'disabled'); } } else { if($ChildFrame->{$ButtonLabel}->{status}) { $ChildFrame->{$EntryLabel}->configure(-state => 'disabled'); } } $ChildFrame->{$ButtonLabel}->configure( -command => sub { if($$pCheckVariable) { # if($ChildFrame->{$ButtonLabel}->{status}) { $ChildFrame->{$ButtonLabel}->{status} = 1; $ChildFrame->{$EntryLabel}->configure(-state => $onstr); } else { $ChildFrame->{$ButtonLabel}->{status} = 0; $ChildFrame->{$EntryLabel}->configure(-state => $offstr); } } ); } $this->{pEntryArray} = [] if(!$this->{pEntryArray}); push(@{$this->{pEntryArray}}, $ChildFrame->{$EntryLabel}); # return $ChildFrame->{$ButtonLabel} = $button; # return $ChildFrame->{$EntryLabel} = $ChildFrame->{$EntryLabel}; #$ent; return $ChildFrame; } sub MakeParameterConditionHeading { my ($this, $Frame, $row, $column) = @_; $column = 0 if(!defined $column); $Frame->MyLabel(-text => 'Variable')->grid(-row => $row, -column => $column+0, -columnspan => 1, -sticky => 'w' ); $Frame->MyLabel(-text => 'value')->grid( -row => $row, -column => $column+1, -columnspan => 2, -sticky => 'w' ); $Frame->MyLabel(-text => 'scale')->grid( -row => $row, -column => $column+3, -columnspan => 1, -sticky => 'w' ); $Frame->MyLabel(-text => 'min')->grid( -row => $row, -column => $column+4, -columnspan => 1, -sticky => 'w' ); $Frame->MyLabel(-text => 'max')->grid( -row => $row, -column => $column+5, -columnspan => 1, -sticky => 'w' ); } sub MakeParameterConditionColumn { my ($this, $Frame, $VarName, $Label, $format, $VarDefault, $CheckDefault, $ScaleDefault, $MinDefault, $MaxDefault, $EntryWidth, $row, $state) = @_; $state = 'normal' if(!defined $state); #print "$VarName: $CheckDefault\n"; $this->MakeCheckEntry($Frame, $VarName, $Label, $this->{dini}->pVariable("${VarName}check", $CheckDefault), $this->{ini}->pVariable($VarName, $VarDefault), $format, $EntryWidth, '', $row, 0); $Frame->MyEntry( -name => $VarName, -width => $EntryWidth-4, -textvariable => $this->{dini}->pVariable("${VarName}scale", $ScaleDefault), -format => $format, -takefocus => 1, -state => $state )->grid(-row => $row, -column => 3, -columnspan => 1, -sticky => 'e' ); $Frame->MyEntry( -name => $VarName, -width => $EntryWidth-2, -textvariable => $this->{dini}->pVariable("${VarName}min", $MinDefault), -format => $format, -takefocus => 1, -state => $state )->grid(-row => $row, -column => 4, -columnspan => 1, -sticky => 'e' ); $Frame->MyEntry( -name => $VarName, -width => $EntryWidth-2, -textvariable => $this->{dini}->pVariable("${VarName}max", $MaxDefault), -format => $format, -takefocus => 1, -state => $state )->grid(-row => $row, -column => 5, -columnspan => 1, -sticky => 'e' ); } sub MakeFittingRangeFrame { my ($this, $Frame, $MinVarName, $MinLabel, $pMinVar, $MinFormat, $MinUnit, $MaxVarName, $MaxLabel, $pMaxVar, $MaxFormat, $MaxUnit, $SkipVarName, $SkipLabel, $pSkipVar, $SkipFormat, $SkipUnit, $EntryWidth) = @_; $EntryWidth = 12 if(!defined $EntryWidth); $this->MakeLabelEntry($Frame, $MinVarName, $MinLabel, $pMinVar, $MinFormat, $EntryWidth, $MinUnit, 0, 0); $this->MakeLabelEntry($Frame, $MaxVarName, $MaxLabel, $pMaxVar, $MaxFormat, $EntryWidth, $MaxUnit, 0, 1); $this->MakeLabelEntry($Frame, $SkipVarName, $SkipLabel, $pSkipVar, $SkipFormat, 5, $SkipUnit, 0, 2); $Frame->MyButton( -text => 'viewrange', -takefocus => 1, -command => sub { $this->GetViewRange(0, 'X', $MinVarName, $MaxVarName); }, )->grid(-row => 0, -column => 11, -stick => 'e'); return $Frame; } sub MakeFittingButtons { my ($this, $Frame, @args) = @_; my $ChildFrame = $Frame->MyFrame(); for(my $i = 0 ; $i < @args ; $i ++) { if($args[$i] eq 'Recalc') { $this->{RecalcButton} = $ChildFrame->MyButton( -text => 'Re&calc', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', 'Recalc'); }, )->pack(-side => 'left'); } elsif($args[$i] eq 'Fit') { $this->{FitButton} = $ChildFrame->MyButton( -text => '&Fit', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', 'Fit'); }, )->pack(-side => 'left'); } elsif($args[$i] eq 'PbP') { $this->{PointByPointButton} = $ChildFrame->MyButton( -text => 'Point By Point', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', 'PointByPoint'); }, )->pack(-side => 'left'); } elsif($args[$i] eq 'SaveComponents') { $this->{SaveComponentsButton} = $ChildFrame->MyButton( -text => '&Save Components', -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', 'SaveComponents'); }, )->pack(-side => 'left'); } else { my ($text, $funchead) = ($args[$i] =~ /^(.*):(.*?)$/); if(!defined $funchead) { $text = $args[$i]; $funchead = $text; } $funchead =~ s/&//g; $funchead =~ s/\s//g; $this->{"${funchead}Button"} = $ChildFrame->MyButton( -text => $text, -takefocus => 1, -command => sub { $this->ButtonPressed('RButtonDown', $funchead); }, )->pack(-side => 'left'); } } return $ChildFrame; } sub RefreshMainPane { my ($this, $EntryWidth, @a) = @_; $this->mw()->{MainPaneFrame}->destroy(); $this->mw()->{MainPaneFrame} = $this->mw()->{MainPage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->BuildMainPane($this->mw()->{MainPaneFrame}, $EntryWidth); } sub RefreshLayersPane { my ($this, $EntryWidth, @a) = @_; $this->mw()->{LayersPaneFrame}->destroy(); $this->mw()->{LayersPaneFrame} = $this->mw()->{LayersPage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->BuildLayersPane($this->mw()->{LayersPaneFrame}, $EntryWidth); } sub RefreshMiscParamConditionPane { my ($this, $EntryWidth, @a) = @_; $this->mw()->{MiscParamConditionPaneFrame}->destroy(); $this->mw()->{MiscParamConditionPaneFrame} = $this->mw()->{MiscParamConditionPage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->BuildMiscParamConditionPane($this->mw()->{MiscParamConditionPaneFrame}, $EntryWidth); } sub RefreshLorentzParamConditionPane { my ($this, $EntryWidth, @a) = @_; $this->mw()->{LorentzParamConditionPaneFrame}->destroy(); $this->mw()->{LorentzParamConditionPaneFrame} = $this->mw()->{LorentzParamConditionPage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->BuildLorentzParamConditionPane($this->mw()->{LorentzParamConditionPaneFrame}, $EntryWidth); } sub RefreshDrudeParamConditionPane { my ($this, $EntryWidth, @a) = @_; $this->mw()->{"DrudeParamConditionPaneFrame"}->destroy(); $this->mw()->{"DrudeParamConditionPaneFrame"} = $this->mw()->{"DrudeParamConditionPage"}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->BuildDrudeParamConditionPane($this->mw()->{DrudeParamConditionPaneFrame}, $EntryWidth); } sub RefreshViewRangePane { my ($this, $EntryWidth, @a) = @_; return if(!defined $this->mw()->{ViewRangePaneFrame}); $this->mw()->{ViewRangePaneFrame}->destroy(); $this->mw()->{ViewRangePaneFrame} = $this->mw()->{ViewRangePage}->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->BuildViewRangePane($this->mw()->{ViewRangePaneFrame}, $EntryWidth); } sub BuildViewRangePane { my ($this, $MainFrame, $EntryWidth, $ppXAxisPlotArrayArray, $ppYAxisPlotArrayArray) = @_; my $GraphFrameArray = $this->{GraphFrameArray}; if($GraphFrameArray) { for(my $i = 0 ; ; $i++) { my $ii = $i; my $i1 = $i + 1; my $GraphFrame = $GraphFrameArray->GetGraphFrame($i); last if(!defined $GraphFrame); my $Frame1 = $MainFrame->MyLabFrame( -label => "GraphFrame $i1", -labelside => 'acrosstop', )->pack(-anchor => 'nw'); $MainFrame->{"GraphFrame${i1}XAxisListBox"} = $Frame1->MyBrowseEntry( -label => "", -state => "readonly", -takefocus => 1, -width => 5, -Selections => $ppXAxisPlotArrayArray->[$i], -SelIndex => 0, )->grid(-row => 2*$i1+1, -column => 1, -sticky => 'e'); $MainFrame->{"GraphFrame${i1}YAxisListBox"} = $Frame1->MyBrowseEntry( -label => "", -state => "readonly", -takefocus => 1, -width => 5, -Selections => $ppYAxisPlotArrayArray->[$i], -SelIndex => 0, )->grid(-row => 2*$i1+2, -column => 1, -sticky => 'e'); $this->{dini}->{"GraphFrame${i1}ViewX0check"} = 0; $this->{dini}->{"GraphFrame${i1}ViewX1check"} = 0; $this->{dini}->{"GraphFrame${i1}ViewY0check"} = 0; $this->{dini}->{"GraphFrame${i1}ViewY1check"} = 0; my $f = $this->MakeCheckEntry($Frame1, "GraphFrame${i1}ViewX0", "X0:", $this->{dini}->pVariable("GraphFrame${i1}ViewX0check", 0), $this->{dini}->pVariable("GraphFrame${i1}ViewX0", 0.0), "%12.6g", $EntryWidth, "", 2*$i1+1, 2, 'synchronize reverse'); $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}ViewX0Button"} = $f->{Button}; $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}ViewX0Entry"} = $f->{Entry}; $this->MakeCheckEntry($Frame1, "GraphFrame${i1}ViewX1", "X1:", $this->{dini}->pVariable("GraphFrame${i1}ViewX1check", 0), $this->{dini}->pVariable("GraphFrame${i1}ViewX1", 0.0), "%12.6g", $EntryWidth, "", 2*$i1+1, 3, 'synchronize reverse'); $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}ViewX1Button"} = $f->{Button}; $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}ViewX1Entry"} = $f->{Entry}; $Frame1->MyButton( -text => 'viewrange', -takefocus => 1, -command => sub { $this->GetViewRange($ii, 'X'); }, )->grid(-row => 2*$i1+1, -column => 11, -stick => 'e'); $this->MakeCheckEntry($Frame1, "GraphFrame${i1}ViewY0", "Y0:", $this->{dini}->pVariable("GraphFrame${i1}ViewY0check", 0), $this->{dini}->pVariable("GraphFrame${i1}ViewY0", 0.0), "%12.6g", $EntryWidth, "", 2*$i1+2, 2, 'synchronize reverse'); $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}ViewY0Button"} = $f->{Button}; $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}ViewY0Entry"} = $f->{Entry}; $this->MakeCheckEntry($Frame1, "GraphFrame${i1}ViewY1", "Y1:", $this->{dini}->pVariable("GraphFrame${i1}ViewY1check", 0), $this->{dini}->pVariable("GraphFrame${i1}ViewY1", 0.0), "%12.6g", $EntryWidth, "", 2*$i1+2, 3, 'synchronize reverse'); $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}ViewY1Button"} = $f->{Button}; $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}ViewY1Entry"} = $f->{Entry}; $Frame1->MyButton( -text => 'viewrange', -takefocus => 1, -command => sub { $this->GetViewRange($ii, 'Y'); }, )->grid(-row => 2*$i1+2, -column => 11, -stick => 'e'); } } } sub EntryFocusedIn { my ($this, $obj, $event, $type) = @_; #print "In: obj=$obj, this=$this, event=$event, type=$type\n"; if($event eq 'FocusIn') { $obj->{PrevValue} = $obj->GetText(); } } sub EntryFocusedOut { my ($this, $obj, $event, $type) = @_; #print "Out: obj=$obj, this=$this, event=$event, type=$type\n"; my $ini = $this->{ini}; my $dini = $this->{dini}; if($event eq 'FocusOut') { } if($ini->{AutoUpdate} and defined $dini->{"${type}check"} and $obj->{PrevValue} != $obj->GetText()) { $this->Recalc(); # $this->CreateGraphFrame(); $this->AssignGraphData(0); $this->Draw(); } else { $this->UpdateParameters(); } } sub SelChangeListBox { my ($this, $type, $lb) = @_; #print "this:$this lb=$lb\n"; # my $s = $lb->GetText(); # if($type eq 'LayerModel') { # if($s eq "C12A7:e-(sub)") { # } # } return if(!$this->{ini}->{AutoUpdate}); $this->Recalc(); # $this->CreateGraphFrame(); $this->AssignGraphData(0); $this->Draw(); } sub UpdateParameters { my ($this) = @_; return if(!defined $this->{pEntryArray}); my $pEA = $this->{pEntryArray}; for(my $i = 0 ; $i < @$pEA ; $i++) { $pEA->[$i]->Update(); } } sub SetS2 { my ($this, $S2, $UpdateBoth) = @_; $UpdateBoth = 1 if(!defined $UpdateBoth); if($UpdateBoth) { $this->{ini}->{PrevS2} = $this->mw()->{LatestS2Entry}->GetText(); $this->{ini}->{LatestS2} = $S2; $this->mw()->{PrevS2Entry}->SetText($this->{ini}->{PrevS2}); $this->mw()->{LatestS2Entry}->SetText($S2); } else { $this->{ini}->{LatestS2} = $S2; $this->mw()->{LatestS2Entry}->SetText($S2); } } sub GetViewRange { my ($this, $iGraphFrame, $XY, $MinKey, $MaxKey) = @_; my $GraphFrameArray = $this->GetGraphFrameArray(); return if(!defined $GraphFrameArray); my $GraphFrame = $GraphFrameArray->GetGraphFrame($iGraphFrame); return if(!defined $GraphFrame); my $i1 = $iGraphFrame + 1; my $funcname = "GetView${XY}Range"; my ($min, $max) = $GraphFrame->$funcname(); if(!defined $MinKey) { ($this->{dini}->{"GraphFrame${i1}View${XY}0"}, $this->{dini}->{"GraphFrame${i1}View${XY}1"}) = ($min, $max); #print "F=", $this->mw()->{NoteBook}->{ViewRangePaneFrame}, "\n"; #print "F(GraphFrame${i1}View${XY}0Button)=", $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}View${XY}0Button"}, "\n"; $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}View${XY}0Button"}->Select(); $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}View${XY}0Entry"}->configure(-state => 'normal'); $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}View${XY}1Button"}->Select(); $this->mw()->{NoteBook}->{ViewRangePaneFrame}->{"GraphFrame${i1}View${XY}1Entry"}->configure(-state => 'normal'); } else { ($this->{ini}->{$MinKey}, $this->{ini}->{$MaxKey}) = ($min, $max); # ($this->{ini}->{FitEmin}, $this->{ini}->{FitEmax}) = ($min, $max); } #print "$MinKey=$this->{ini}->{$MinKey}\n"; $this->UpdateParameters(); return ($min, $max); } #=================================================== # データ処理 #=================================================== sub GetValidDataPath { # CurrentPath: Parameter File that is being readed # TrialPath: Data File Path recorded in the Parameter File ($CurrentPath) # RecordedPath: Parameter File recorded in the reading Parameter File my ($this, $TrialPath, $CurrentPath, $RecordedPath) = @_; my $DirectorySeparator = Deps::DirectorySeparator(); my $RegSeparator = Utils::RegExpQuote($DirectorySeparator); $TrialPath =~ s/$RegSeparator/\//g; $CurrentPath =~ s/$RegSeparator/\//g; $RecordedPath =~ s/$RegSeparator/\//g; my $OrgTrialPath = $TrialPath; #print "TrialPath : $TrialPath\n"; #print "CurrentPath : $CurrentPath\n"; #print "RecordedPath: $RecordedPath\n"; my @CurrentDirs = Utils::Split('/', $CurrentPath); my @RecordedDirs = Utils::Split('/', $RecordedPath); my @TrialDirs = Utils::Split('/', $TrialPath); my $nCurrentDirs = @CurrentDirs; my $nRecordedDirs = @RecordedDirs; my $nTrialDirs = @TrialDirs; #print "nc=$nCurrentDirs nr=$nRecordedDirs\n"; my $nCommon = 0; my $NewPath = $TrialDirs[$nTrialDirs-1]; for(my $i = 1 ; $i < $nCurrentDirs ; $i++) { #print "i=$i: ", $CurrentDirs[$nCurrentDirs-$i-1], " / ", $RecordedDirs[$nRecordedDirs-$i-1], "\n"; unless(uc $CurrentDirs[$nCurrentDirs-$i-1] eq uc $RecordedDirs[$nRecordedDirs-$i-1]) { $nCommon = $i; last; } else { my $dir = $TrialDirs[$nTrialDirs-$i-1]; $NewPath = "$dir/$NewPath"; } } #print "nCommon = $nCommon\n"; #print "NewPath=$NewPath\n"; for(my $i = $nCommon ; $i < $nCurrentDirs ; $i++) { my $dir = $CurrentDirs[$nCurrentDirs-$i-1]; $NewPath = "$dir/$NewPath"; } #print "NewPath=$NewPath\n"; if(-e $NewPath) { $NewPath =~ s/\//$DirectorySeparator/g; return $NewPath; } if(-e $OrgTrialPath) { $OrgTrialPath =~ s/\//$DirectorySeparator/g; return $OrgTrialPath; } # Extract difference from the recorded and reading ParameterFiles. my ($drive0, $directory0, $filename0, $ext0, $lastdir0, $filebody0) = Deps::SplitFilePath($CurrentPath); my ($drive1, $directory1, $filename1, $ext1, $lastdir1, $filebody1) = Deps::SplitFilePath($RecordedPath); my ($drive2, $directory2, $filename2, $ext2, $lastdir2, $filebody2) = Deps::SplitFilePath($OrgTrialPath); #print "Check current directory [$drive0\\$directory0]\n"; $TrialPath = Deps::MakePath("$drive0$directory0", $filename2, 0); #print "f : $TrialPath\n"; if(-e $TrialPath) { $TrialPath =~ s/\//$DirectorySeparator/g; return $TrialPath; } #print "Replace [$drive2] to [$drive0] for [$TrialPath].\n"; $TrialPath = $OrgTrialPath; $TrialPath =~ s/$drive2/$drive0/; if(-e $TrialPath) { $TrialPath =~ s/\//$DirectorySeparator/g; return $TrialPath; } #print "OrgTrialPath : $OrgTrialPath\n"; $OrgTrialPath =~ s/\//$DirectorySeparator/g; return $OrgTrialPath; } sub GetValidDataPath_old { my ($this, $TrialPath, $CurrentPath, $RecordedPath) = @_; return $TrialPath if(-f $TrialPath); if(0) { print "Trial : $TrialPath\n"; print "Param : $CurrentPath\n"; print "Recorded: $RecordedPath\n"; } my $ParentDir = Deps::ExtractDirectory($RecordedPath); $ParentDir =~ s/\\/\//g; my $PresentDir = Deps::ExtractDirectory($CurrentPath); $PresentDir =~ s/\\/\//g; my $RelPath = Utils::MakeRelativePath($TrialPath, $ParentDir); #print "RelPath: $RelPath\n"; my $MergedPath = Deps::MakePath($PresentDir, $RelPath); $MergedPath =~ s/\//\\/g; #print "MergedPath: $MergedPath\n"; my $ReducePath = Utils::ReduceDirectory($MergedPath, "\\"); #print "ReducePath: $ReducePath\n"; return $ReducePath; } 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->{ini}->{ParameterFile} = $filepath; $this->DecomposeParameters($ini, $dini); $this->{ChooseXListBox}->SetText($this->{ini}->{X}) if($this->{ChooseXListBox}); $this->{ChooseY1ListBox}->SetText($this->{ini}->{Y1}) if($this->{ChooseY1ListBox}); $this->{ChooseAppFunctionListBox}->SetText($this->{ini}->{AppFunction}) if($this->{ChooseAppFunctionListBox}); $this->{ChooseConductionTypeListBox}->SetText($this->{ini}->{ConductionType}) if($this->{ChooseConductionTypeListBox}); if($this->{ini}->{SampleCSVFile}) { my $ret = $this->ReadSampleDataFile($this->{ini}->{SampleCSVFile}, 1, 0); return undef unless($ret); #print "F: $this->{ini}->{FlipX}\n"; if($this->{ini}->{FlipX}) { $this->FlipX(); $this->{ini}->{FlipX} = 1; } } return 1; } sub AddParameters { my ($this, $ini, $dini, @args) = @_; for(my $i = 0 ; $i < @args ; $i += 6) { my $key = $args[$i]; $ini->{$key} = $args[$i+1] if(!defined $ini->{$key}); $dini->{$key} = $args[$i+1] if(!defined $dini->{$key}); $dini->{"${key}check"} = $args[$i+2] if(!defined $dini->{"${key}check"}); $dini->{"${key}scale"} = $args[$i+3] if(!defined $dini->{"${key}scale"}); $dini->{"${key}min"} = $args[$i+4] if(!defined $dini->{"${key}min"}); $dini->{"${key}max"} = $args[$i+5] if(!defined $dini->{"${key}max"}); #print "AddParameters: $key: $dini->{$key}\n"; } } sub ComposeParameters { my ($this, $dini, $ini) = @_; foreach my $key (sort keys %$dini) { next if($key eq 'SystemKeyHead' or $key =~ /^System\//); next if($key =~ /check$/ or $key =~ /scale$/ or $key =~ /min$/ or $key =~ /max$/); my $value = $ini->{"${key}"}; #print "key=$key: $value\n"; next if(!defined $value); my $id = $dini->{"${key}check"}; my $scale = $dini->{"${key}scale"}; my $min = $dini->{"${key}min"}; my $max = $dini->{"${key}max"}; $value = 0 if(!defined $value); $id = 0 if(!defined $id); $scale = 0.1 if(!defined $scale); $min = '' if(!defined $min); $max = '' if(!defined $max); $ini->{$key} = "$value:$id:$scale:$min:$max"; } return $ini; } sub DecomposeParameters { my ($this, $ini, $dini) = @_; foreach my $key (sort keys %$ini) { next if($key eq 'SystemKeyHead' or $key =~ /^System\//); next if(!defined $ini->{$key}); my ($value, $id, $scale, $min, $max) = ($ini->{$key} =~ /^\s*([^:]*?)\s*:\s*([^:]*?)\s*:\s*([^:]*?)\s*:\s*([^:]*?)\s*:\s*([^:]*?)\s*$/); next if(!defined $value or ($value eq '' and $scale eq '')); #print "[$key][$value][$id][$scale][$min][$max]\n"; printf "%20s: %12.6g[%d] Scale=%8.4g (%s-%s)\n", $key, $value, $id, $scale, $min, $max; if(!defined $min or $min =~ /^[uU]/) { $min = ''; } if(!defined $max or $max =~ /^[uU]/) { $max = ''; } $dini->{$key} = $ini->{$key} = $value; $dini->{"${key}check"} = $id; #print "dini{${key}check}=", $dini->{"${key}check"}, "\n"; $dini->{"${key}scale"} = $scale; $dini->{"${key}min"} = $min; $dini->{"${key}max"} = $max; } return $dini; } sub ReadASampleDataFile { my ($this, $filepath, $pData, $pChooseXYListBoxArray, $IsPrint, $UpdateRange) = @_; $UpdateRange = 1 if(!defined $UpdateRange); my $App = $this->App(); my ($nData, $pLabelArray, @pDataArray) = $pData->Read($filepath); if(!defined $nData) { $App->print("Error: Can not read [$filepath].\n"); return undef; } my $nDataArray = $pData->nDataArray(); #print "nDataArray: $nDataArray\n"; for(my $i = 0 ; $i < @$pChooseXYListBoxArray ; $i++) { my $pLB = $pChooseXYListBoxArray->[$i]; $pLB->DeleteAllItem(); for(my $j = 0 ; $j < $nDataArray ; $j++) { $pLB->AddItem($pLabelArray->[$j]); } } return ($nData, $pLabelArray, @pDataArray); } sub CreateGraphFrame { my ($this, $canvas, $TargetData, $nGraphFrame) = @_; $canvas = $this->Canvas(); $nGraphFrame = 1 if(!defined $nGraphFrame); my $App = $this->App(); my $font = $App->{GraphFrameFont}; my @font = split(/,/, $font) if($font); my $w = $canvas->width(); my $h = $canvas->height(); my $GraphFrameArray = $this->{GraphFrameArray} = new GraphFrameArray($this->mw()); $GraphFrameArray->SetCanvasSize($w, $h); my @GraphFrame; for(my $i = 0 ; $i < $nGraphFrame ; $i++) { $GraphFrameArray->AddGraphFrame(); $GraphFrame[$i] = $GraphFrameArray->GetGraphFrame($i); my $FramePosStr0 = $App->{"GraphFrame${i}Position"}; my $XScale0 = $GraphFrame[$i]->GetXScale(0); my $YScale0 = $GraphFrame[$i]->GetYScale(0); $GraphFrame[$i]->SetPositionByStr($FramePosStr0); $GraphFrame[$i]->SetXCaption("x$i"); $GraphFrame[$i]->SetYCaption("y$i"); $XScale0->SetScaleStringVisible(1); $XScale0->SetCaptionVisible(1); $GraphFrame[$i]->SetViewRange(0, 0, 1, 1); } return ($GraphFrameArray, @GraphFrame); } sub SetViewRange { my ($this, $ResetViewRange) = @_; return if(!$ResetViewRange); my $GraphFrameArray = $this->GetGraphFrameArray(); return if(!defined $GraphFrameArray); for(my $i = 0 ; ; $i++) { my $GraphFrame = $GraphFrameArray->GetGraphFrame($i); last if(!defined $GraphFrame); my $i1 = $i + 1; $GraphFrame->CalMinMax(); my ($x0, $y0, $x1, $y1) = $GraphFrame->CalAdjustViewRange(0.05, 0.05, 0.05, 0.05); #print "Frame $i1 ($x0, $y0, $x1, $y1) \n"; if($this->{dini}->{"GraphFrame${i1}ViewX0check"}) { $x0 = $this->{dini}->{"GraphFrame${i1}ViewX0"}; } elsif(defined $x0) { $this->{dini}->{"GraphFrame${i1}ViewX0"} = $x0; } if($this->{dini}->{"GraphFrame${i1}ViewX1check"}) { $x1 = $this->{dini}->{"GraphFrame${i1}ViewX1"}; } elsif(defined $x1) { $this->{dini}->{"GraphFrame${i1}ViewX1"} = $x1; } if($this->{dini}->{"GraphFrame${i1}ViewY0check"}) { $y0 = $this->{dini}->{"GraphFrame${i1}ViewY0"}; } elsif(defined $y0) { $this->{dini}->{"GraphFrame${i1}ViewY0"} = $y0; } if($this->{dini}->{"GraphFrame${i1}ViewY1check"}) { $y1 = $this->{dini}->{"GraphFrame${i1}ViewY1"}; } elsif(defined $y1) { $this->{dini}->{"GraphFrame${i1}ViewY1"} = $y1; } if($i == 0) { my ($x0, $y0, $x1, $y1) = $GraphFrame->SetViewRange($x0, $y0, $x1, $y1, 1); #print "x2=$x0, $y0, $x1, $y1\n"; } else { my ($x0, $y0, $x1, $y1) = $GraphFrame->SetViewRange($x0, $y0, $x1, $y1, 0); } $this->UpdateParameters(); } } sub ConvertXY { my ($this, $ConvFunc, $pX, $pY) = @_; my (@x, @y); my $n = @$pX; for(my $i = 0 ; $i < $n ; $i++) { ($x[$i], $y[$i]) = &$ConvFunc($pX->[$i], $pY->[$i]); } return (\@x, \@y); } sub LinearY { my ($this, $x, $y) = @_; return ($x, $y); } sub LogAbsY { my ($this, $x, $y) = @_; return ($x, Sci::FuncLog10Abs($y)); } sub Tauc { my ($this, $x, $y) = @_; return ($x, sqrt($x * $y)); } sub SquareRoot { my ($this, $x, $y) = @_; return ($x, sqrt($y)); } sub Square { my ($this, $x, $y) = @_; return ($x, $y*$y); } sub RestoreScale { my ($this, $ResetViewRange, $CreateGraphFrame, $AssignGraphData, $Draw) = @_; $ResetViewRange = 1 if(!defined $ResetViewRange); $this->RePlot($ResetViewRange, $CreateGraphFrame, $AssignGraphData, $Draw); } sub RePlot { my ($this, $ResetViewRange, $CreateGraphFrame, $AssignGraphData, $Draw) = @_; $ResetViewRange = 0 if(!defined $ResetViewRange); $CreateGraphFrame = 0 if(!defined $CreateGraphFrame); $AssignGraphData = 1 if(!defined $AssignGraphData); $Draw = 1 if(!defined $Draw); if($CreateGraphFrame or $ResetViewRange) { $this->CreateGraphFrame(); } $this->CreateGraphFrame() if(!$this->GetGraphFrameArray()); $this->AssignGraphData($ResetViewRange) if($AssignGraphData); $this->Draw() if($Draw); } sub Draw { my ($this, $canvas, $TargetData) = @_; my $mw = $this->mw(); $canvas = $this->Canvas() if(!$canvas); # my $FileType = $this->FileType(); my $App = $this->App(); my $font = $App->{'GraphFrameFont'}; my @font = split(/,/, $font) if($font); my $GraphFrameArray = $this->GetGraphFrameArray(); return unless($GraphFrameArray); $canvas->ClearAll(); $mw->RefreshCanvas(); if($font) { $canvas->SetFont(\@font); $GraphFrameArray->SetFont(\@font); } my $w = $canvas->width(); my $h = $canvas->height(); $GraphFrameArray->SetCanvasSize($w, $h); $this->mw()->WriteStatusBar("Drawing Ellipsometry..."); # $this->ReadFiles($this->FileName(), $TargetData); # $this->CreateGraphFrame($canvas, $TargetData); # $this->AssignGraphData(); $mw->Balloon()->detach($canvas); $GraphFrameArray->Draw($canvas); $this->mw()->WriteStatusBar("Finish Ellipsometry."); } 1;