#=============================================== # TkVNL #=============================================== package TkVNL; use Crystal::TranSIESTA; use TkPlotModule; @ISA = qw(TranSIESTA TkPlotModule); #公開したいサブルーチン #@EXPORT = qw(DelSpace Reduce01 MakePath RegExpQuote); use strict; use Utils; use MyTk::GraphFrameArray; use GraphData; #============================================================ # 変数等取得関数 #============================================================ #============================================================ # コンストラクタ、デストラクタ #============================================================ sub new { my ($module, $app) = @_; # my ($module, $app, $canvas) = @_; my $this = {}; bless $this; $this->SetApplication($app); # $this->SetCanvas($canvas); return $this; } sub DESTROY { my $this = shift; $this->SUPER::DESTROY(@_); } #============================================================ # 継承クラスで定義しなおす関数 #============================================================ sub CheckFileType { my ($path) = @_; return TranSIESTA::CheckFileType($path); } sub Read { my ($this, $filename, $TargetData) = @_; print "TkVNL::Read [$filename][$TargetData]\n"; my $s = ''; if($TargetData) { $s = " for $TargetData"; # return $this->Draw(undef, $TargetData); } print "\n"; print "TkVNL::Read: Read [$filename]$s\n"; my $App = $this->App(); $this->mw()->WriteStatusBar("Reading $filename$s..."); my $ret = $this->ReadFiles($filename, $TargetData); $this->mw()->WriteStatusBar("Finish reading $filename$s..."); $App->print(" Finish reading $filename$s...\n"); } sub CreateGraphFrame { my ($this, $canvas, $TargetData) = @_; $canvas = $this->Canvas(); # $this->SetCanvas($canvas) if($canvas); # $canvas = $this->Canvas() unless($canvas); my $App = $this->App(); my $font = $App->{'GraphFrameFont'}; my @font = split(/,/, $font) if($font); my $w = $canvas->width(); my $h = $canvas->height(); my $FileType = $this->FileType(); return undef unless($FileType); my $pDataArray = $this->DataArray(); return unless($pDataArray); $TargetData = $pDataArray->{'TargetData'} unless(defined $TargetData); # Canvas, GraphFrameの初期化 my $GraphFrameArray = $this->{'GraphFrameArray'} = new GraphFrameArray($this->mw()); # = new GraphFrameArray($this->mw(), $canvas); $GraphFrameArray->SetCanvasSize($w, $h); if($FileType eq "ATK 2.0 Output") { for(my $i = 0 ; ; $i++) { my $Data = $pDataArray->GetGraphData($i); last unless($Data); $GraphFrameArray->AddGraphFrame(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame($i); my $FramePosStr0 = $App->{"GraphFramePosition"}; my $XScale0 = $GraphFrame0->GetXScale(0); my $YScale0 = $GraphFrame0->GetYScale(0); $GraphFrame0->SetPositionByStr($FramePosStr0); $GraphFrame0->SetViewRange(0, 0, 1, 1); $GraphFrame0->SetSmoothLine(1); if(not defined $TargetData or $TargetData =~ /Convergence/i) { $GraphFrame0->SetYScalePlotType('log(|x|)'); } else { $GraphFrame0->SetYScalePlotType('x'); } if($i > 0) { $XScale0->SetScaleStringVisible(0); $XScale0->SetScaleVisible(0); $XScale0->SetCaptionVisible(0); $YScale0->SetScaleStringVisible(0); $YScale0->SetScaleVisible(0); $YScale0->SetCaptionVisible(0); } } } else { $GraphFrameArray->AddGraphFrame(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); my $FramePosStr0 = $App->{"GraphFramePosition"}; my $XScale0 = $GraphFrame0->GetXScale(0); my $YScale0 = $GraphFrame0->GetYScale(0); $GraphFrame0->SetPositionByStr($FramePosStr0); $GraphFrame0->SetXCaption("Energy"); $GraphFrame0->SetYCaption('PDOS'); $GraphFrame0->SetViewRange(0, 0, 1, 1); } } sub AssignGraphData { my ($this) = @_; my $GraphFrameArray = $this->GetGraphFrameArray(); return undef unless($GraphFrameArray); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); return undef unless($GraphFrame0); my $FileType = $this->FileType(); my $pDataArray = $this->DataArray(); return unless($pDataArray); my $Data = $pDataArray->GetGraphData(0); return unless($Data); my $nData = $Data->nData(); my $title = $Data->Title(); my $linecolor = "auto"; if($FileType eq "ATK 2.0 Output") { my @GraphFrame; for(my $id = 0 ; ; $id++) { $GraphFrame[$id] = $GraphFrameArray->GetGraphFrame($id); last unless($GraphFrame[$id]); my $Data = $pDataArray->GetGraphData($id); for(my $i = 0 ; ; $i++) { my $pX = $Data->GetDataArray("x$i"); my $pY = $Data->GetDataArray("y$i"); last unless($pY); my $pNe = $Data->{"Ne$i"}; if($pNe) { if($pNe->[0] < 0.5) { $linecolor = 'grey' if($id == 0); $linecolor = 'green' if($id == 1); } elsif($pNe->[0] < 1.5) { $linecolor = 'blue' if($id == 0); $linecolor = 'orange' if($id == 1); } else { $linecolor = 'black' if($id == 0); $linecolor = 'red' if($id == 1); } } else { $linecolor = 'black' if($id == 0); $linecolor = 'red' if($id == 1); } my $nData = $GraphFrame[$id]->AddGraphData($pX, $pY, 1, $linecolor, "", 6, "red", 0, "red", "XAutoSkip", $Data->{"x0_Name"}, $Data->{"y${i}_Name"}); my $data = $GraphFrame[$id]->GetPlotData($nData-1); } $GraphFrame[$id]->CalMinMax(); $GraphFrame[$id]->AdjustViewRange(0.05, 0.05, 0.05, 0.05); } if($GraphFrame[1]) { $GraphFrame[0]->AddSynchronousFrame('x', $GraphFrame[1]); $GraphFrame[0]->AddSynchronousFrame('y', $GraphFrame[1]); $GraphFrame[1]->AddSynchronousFrame('x', $GraphFrame[0]); $GraphFrame[1]->AddSynchronousFrame('y', $GraphFrame[0]); } } else { for(my $i = 0 ; ; $i++) { #print "Assign $i\n"; my $pX = $Data->GetDataArray("x$i"); my $pY = $Data->GetDataArray("y$i"); last unless($pY); my $nData = $GraphFrame0->AddGraphData($pX, $pY, 1, $linecolor, "", 6, "red", 0, "red", "XAutoSkip", $Data->{"x0_Name"}, $Data->{"y${i}_Name"}); my $data = $GraphFrame0->GetPlotData($nData-1); } $GraphFrame0->CalMinMax(); $GraphFrame0->AdjustViewRange(0.05, 0.05, 0.05, 0.05); } if($FileType eq "ATK 2.0 Output") { $GraphFrame0->SetXCaption($Data->{"x0_Name"}); $GraphFrame0->SetYCaption('Energy'); } else { $GraphFrame0->SetXCaption($Data->{"x0_Name"}); $GraphFrame0->SetYCaption($Data->{"y0_Name"}); } $this->AdjustViewRange(); } sub AdjustViewRange { my ($this) = @_; my $GraphFrameArray = $this->GetGraphFrameArray(); my $pGraphFrame = $GraphFrameArray->GetpGraphFrameArray(); my $FileType = $this->FileType(); if($FileType eq "ATK 2.0 Output") { my ($xmin, $xmax) = $pGraphFrame->[0]->GetViewXRange(); my ($ymin, $ymax) = $pGraphFrame->[0]->GetViewYRange(); for(my $id = 1 ; ; $id++) { my $GraphFrame = $GraphFrameArray->GetGraphFrame($id); last unless($GraphFrame); $GraphFrame->SetViewRange($xmin, $ymin, $xmax, $ymax); } } } sub Draw { my ($this, $canvas, $TargetData) = @_; my $mw = $this->mw(); $canvas = $this->Canvas(); $mw->RefleshCanvas(); my $FileType = $this->FileType(); my $App = $this->App(); #TargetDataが指定されていたらファイルを読み込みなおす if($TargetData) { $this->DataArray()->{'TargetData'} = $TargetData; print "TkVNL::Draw: Read for $TargetData\n"; $canvas->ClearAll(); $this->mw()->RefleshCanvas(); #変数の再取得 $mw = $this->mw(); $canvas = $this->Canvas(); $this->ReadFiles($this->FileName(), $TargetData); $this->CreateGraphFrame($canvas, $TargetData); $this->AssignGraphData(); $this->SetFileInfo($this->{'SectionListbox'}, $this->{'FileContentText'}); } $canvas = $this->Canvas($canvas); $mw = $this->mw(); my $GraphFrameArray = $this->GetGraphFrameArray(); my $pGraphFrame = $GraphFrameArray->GetpGraphFrameArray(); my @GraphFrame = @$pGraphFrame; my $w = $canvas->width(); my $h = $canvas->height(); my $font = $App->{'GraphFrameFont'}; my @font = split(/,/, $font) if($font); if($font) { $canvas->SetFont(\@font); $GraphFrameArray->SetFont(\@font); } $GraphFrameArray->SetCanvasSize($w, $h); $this->mw()->Balloon()->detach($canvas); $this->mw()->WriteStatusBar("Drawing..."); $GraphFrameArray->Draw($canvas); #バンド構造図の縦線を描画 if($FileType eq "ATK 2.0 Output" and (defined $TargetData and $TargetData eq 'EnergyBand') ) { my $pDataArray = $this->DataArray(); my $pBandBoundaryDistances = $pDataArray->{'BandBoundaryDistances'}; my $pBoundaryPositions = $this->{'DataArray'}->{'BandBoundaryPositions'}; my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); my ($x0, $y0, $x1, $y1) = $GraphFrame0->GetPosition(); my ($vx0, $vx1) = $GraphFrame0->GetViewXRange(); my %TagHash; for(my $i = 0 ; $i < @$pBandBoundaryDistances ; $i++) { my $b = $pBandBoundaryDistances->[$i]; next if($b < $vx0 or $vx1 < $b); my ($x, $y) = $GraphFrame0->ValueToPosition($b, 0); my $str = $pBoundaryPositions->[$i]; my $tag = "Boundary$i"; $b = Utils::Round($b, 4); $TagHash{$tag} = "($str) x=$b"; $canvas->DrawLine($x, $y0, $x, $y1, 1, "black", $tag); } $this->mw()->Balloon()->attach($canvas, -balloonposition => 'mouse', -msg => \%TagHash); } $this->mw()->WriteStatusBar("Finish Drawing"); } sub DeleteWidget { my ($this, $Frame) = @_; return undef unless($Frame); return 1; } sub AddWidget { my ($this, $Frame) = @_; return undef unless($Frame); # 左枠3列目作成: ファイルの内容を表示するセクションリストボックス # $this->mw()->CreateSectionListBox(); # 左枠4列目作成: ファイルの内容を表示するテキストボックス # $this->mw()->CreateFileContentTextBox(); return 1; } sub SetFileInfo { my ($this, $ListBox, $TextBox) = @_; return undef unless($ListBox); return undef unless($TextBox); $ListBox->ClearAll(); $TextBox->ClearText(); my $App = $this->App(); my @Font = split(/,/, $App->{"FileContentFont"}); $TextBox->configure(-font => \@Font) if(@Font > 0); my $DataArray = $App->TkData(); return undef unless($DataArray); my $GraphFrameArray = $this->GetGraphFrameArray(); my $pGraphFrame = $GraphFrameArray->GetpGraphFrameArray(); my $GraphFrame0 = $pGraphFrame->[0]; my $pDataArray = $DataArray->DataArray(); return undef unless($pDataArray); my $Data = $pDataArray->GetGraphData(0); return undef unless($Data); if($this->FileType() eq "ATK 2.0 Output") { $ListBox->AddItem("EnergyConvergence"); $ListBox->AddItem("ForceConvergence(largest)"); $ListBox->AddItem("EnergyBand"); # $ListBox->AddItem("ForceConvergence(AtomRange:1-3)"); # $ListBox->AddItem("ForceConvergence"); # $ListBox->AddItem("EnergyLevels"); } my $nData = $Data->nData(); my $title = $Data->Title(); $title = '' unless(defined $title); $TextBox->AddText("Title: $title\n"); $TextBox->AddText("$nData\n"); for(my $i = 0 ; $i < $nData ; $i++) { # my $x = $Data->x($i); my $str = ""; my $nX = $Data->nXColumn(); for(my $j = 0 ; $j < $nX ; $j++) { my $x = $Data->x($j, $i); next unless(defined $x); $x = sprintf("%7.3f", $x); $str = "$str\t$x"; } my $nY = $Data->nYColumn(); for(my $j = 0 ; $j < $nY ; $j++) { my $y = $Data->y($j, $i); next unless(defined $y); $y = sprintf("%9.3f", $y); my $convy = $GraphFrame0->YVal($y); $convy = sprintf("%9.3f", $convy); $str = "$str\t$y($convy)"; } $TextBox->AddText("$str\n"); } return 1; } sub ConfigureIniFileVariables { my ($this) = @_; my $App = $this->App(); $App->ConfigureIniFileVariables(); my $Style = $App->Args()->GetGetArg("style"); $Style = "General" unless($Style); $App->AddIniFileVariable("\\$Style\\GraphFrame_Position", "GraphFramePosition", "r0.20,0.80,0.80,0.10"); # $App->AddIniFileVariable("\\$Style\\GraphFrameDOS0_Position", "GraphFrameDOS0Position", "r0.20,0.80,0.80,0.45"); # $App->AddIniFileVariable("\\$Style\\GraphFrameDOS1_Position", "GraphFrameDOS1Position", "r0.20,0.45,0.80,0.10"); $App->ReadSetting(); } 1;