#=============================================== # TkGAMESS #=============================================== package TkGAMESS; use Crystal::GAMESS; use TkPlotModule; @ISA = qw(GAMESS 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) = @_; print "TkGAMESS::CheckFileType\n"; my $FileType; $FileType = GAMESS::CheckFileType($path); print "FT: $FileType\n"; # return $FileType; return new TkGAMESS if($FileType); return undef; } sub CreateGraphFrame { my ($this, $canvas) = @_; $canvas = $this->Canvas($canvas); # $this->SetCanvas($canvas) if($canvas); # $canvas = $this->Canvas() unless($canvas); my $App = $this->App(); my $pDataArray = $App->TkData(); my $font = $App->{'GraphFrameFont'}; my @font = split(/,/, $font) if($font); my $w = $canvas->width(); my $h = $canvas->height(); my $FileType = $this->FileType(); my $TargetData = $pDataArray->{'TargetData'}; # Canvas, GraphFrameの初期化 my $GraphFrameArray = $this->{'GraphFrameArray'} = new GraphFrameArray($this->mw()); $GraphFrameArray->SetCanvasSize($w, $h); $GraphFrameArray->AddGraphFrame(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); my $FramePosStr0 = $App->{"GraphFrame0Position"}; my $XScale0 = $GraphFrame0->GetXScale(0); my $YScale0 = $GraphFrame0->GetYScale(0); $GraphFrame0->SetPositionByStr($FramePosStr0); $GraphFrame0->SetXCaption(""); $GraphFrame0->SetYCaption('Energy / eV'); $GraphFrame0->SetViewRange(0, 0, 1, 1); $GraphFrame0->SetScaleVisible('x', 0); $GraphFrame0->SetScaleStringVisible('x', 0); $GraphFrame0->SetX0LineVisible(0); $GraphFrame0->SetY0LineVisible(0); } sub AssignGraphData { my ($this) = @_; my $GraphFrameArray = $this->GetGraphFrameArray(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); my $pDataArray = $this->DataArray(); my $FileType = $this->FileType(); my $TargetData = $pDataArray->{'TargetData'}; return unless($pDataArray); my $Data = $pDataArray->GetGraphData(0); return unless($Data); my $nData = $Data->nData(); my $title = $Data->Title(); for(my $i = 0 ; $i < 4 ; $i++) { my $pX = $Data->GetDataArray("x$i"); my $pY = $Data->GetDataArray("y$i"); last unless($pY); # my $nData = $GraphFrame0->AddGraphData($pX, $pY, # 0, "auto", "hbar", 300, "red", 0, "red", "XAutoSkip", # $Data->{"x${i}_Name"}, $Data->{"y${i}_Name"}); } $GraphFrame0->SetViewRange(0, $Data->YMin(), 1.0, $Data->YMax()); # $GraphFrame0->CalMinMax(); # $GraphFrame0->AdjustViewRange(0.05, 0.05, 0.05, 0.05); $this->AdjustViewRange(); } sub Draw { my ($this, $canvas, $TargetData) = @_; my $eVToHr = Sci::eVToHartree(); $canvas = $this->Canvas($canvas); my $mw = $this->mw(); $canvas->ClearAll(); $mw->RefleshCanvas(); my $GraphFrameArray = $this->GetGraphFrameArray(); my $pGraphFrame = $GraphFrameArray->GetpGraphFrameArray(); my @GraphFrame = @$pGraphFrame; my $App = $this->App(); my $font = $App->{'GraphFrameFont'}; my @font = split(/,/, $font) if($font); my $w = $canvas->width(); my $h = $canvas->height(); if($font) { $canvas->SetFont(\@font); $GraphFrameArray->SetFont(\@font); } $GraphFrameArray->SetCanvasSize($w, $h); $this->mw()->Balloon()->detach($canvas); $GraphFrameArray->Draw($canvas); #エネルギー準位をプロット $this->mw()->WriteStatusBar("Drawing Energy Levels..."); my $FileType = $this->FileType(); # $TargetData = $pDataArray->{'TargetData'} unless($TargetData); my $pDataArray = $this->DataArray(); #print "pDataArray: $pDataArray\n"; my $pData = $pDataArray->GetGraphData(0); #print "pData: $pData\n"; my %TagHash; my $nGroup = 4; $nGroup = 2 unless(defined $pData->{"y2"}); #print("nGraph: $nGroup\n"); for(my $id = 0 ; $id < 4 ; $id++) { my $pEnergy = $pData->{"y${id}"}; #print "pEnergy: $pEnergy\n"; my $Name = $pData->{"x${id}_Name"}; my $pSymmetry = $pData->{"Symmetry${id}"}; my $pstrOrbital = $pData->{"strOrbital${id}"}; next unless(defined $pEnergy); # my $pOcc = $pData->{"Occupation$id"}; my ($x0, $y0, $x1, $y1) = $pGraphFrame->[0]->GetPosition(); my ($vy0, $vy1) = $pGraphFrame->[0]->GetViewYRange(); my $BarBoxWidth = int(abs($x1 - $x0) / $nGroup); my $nData = @$pEnergy; my $xbase = $x0 + $id*$BarBoxWidth; my $xbase0 = $xbase + $BarBoxWidth * 0.1; my $BarWidth = $BarBoxWidth * 0.8; #print("Bar[$id]: $xbase - $xbase0 - ", $xbase0+$BarWidth, " ($x0 - $x1)\n"); for(my $i = 0 ; $i < $nData ; $i++) { my $eng = $pEnergy->[$i]; # my $occ = $pOcc->[$i]; my $occ = 1.0; $occ = 0.0 if($id == 1 or $id == 3); my ($x, $y) = $pGraphFrame->[0]->ValueToPosition(0, $eng); #print "y: $y0, $y, $y1\n"; my $r = ($y - $y0) / ($y1 - $y0); if(0 <= $r and $r <= 1.0) { my $str = "E=" . sprintf("%7.3f", $eng) . " eV" . " (" . sprintf("%7.4f", $eng*$eVToHr) . " Hr)" . " Ne=" . sprintf("%7.3f", $occ+0.0); #print "i=$i: str=[$str]\n"; if($pSymmetry->[$i]) { $str .= "\n" . $pSymmetry->[$i]; } if(defined $pstrOrbital->[$i]) { $str .= "$pstrOrbital->[$i]"; } my $tag = "$eng-$Name-$i"; $tag =~ s/\s/-/g; $TagHash{$tag} = $str; #print "str: $str, $tag\n"; my $w1 = $BarWidth * $occ / 1.0; my $w2 = $BarWidth - $w1; $canvas->DrawLine($xbase0, $y, $xbase0+$w1, $y, 1, "black", $tag); $canvas->DrawLine($xbase0+$w1, $y, $xbase0+$w1+$w2, $y, 1, "grey", $tag); $canvas->bind($tag, "", [\&HoverItem, $this, "Enter", $str, $y]); $canvas->bind($tag, "", [\&HoverItem, $this, "Leave", $str, $y]); } } } my ($x0, $y0, $x1, $y1) = $pGraphFrame->[0]->GetPosition(); my $l = ($x1 - $x0) / $nGroup; for(my $i = 0 ; $i < 4 ; $i++) { my $xc = $x0 + $l * ($i + 0.5); my $Name = $pData->{"x${i}_Name"}; $canvas->DrawText($xc, $y0+5, $Name, undef, "n"); } $this->mw()->WriteStatusBar("Finish Drawing Energy Levels..."); $this->mw()->Balloon()->attach($canvas, -balloonposition => 'mouse', -msg => \%TagHash); } 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); # $ListBox->AddItem("EnergyConvergence"); # $ListBox->AddItem("EnergyLevels"); my $nData = $Data->nData(); my $title = $Data->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(); } #============================================================ # bind応答関数 #============================================================ sub HoverItem { my ($canvas, $this, $event, $str, $y) = @_; if($event eq 'Enter') { $canvas->delete("SelEnergyLevel"); my $GraphFrameArray = $this->GetGraphFrameArray(); my $pGraphFrame = $GraphFrameArray->GetpGraphFrameArray(); my ($x00, $y00, $x01, $y01) = $pGraphFrame->[0]->GetPosition(); # $canvas->DrawLine($x00, $y, $x01, $y, 1, "grey", "SelEnergyLevel"); $this->mw()->WriteStatusBar($str); } elsif($event eq 'Leave') { $canvas->delete("SelEnergyLevel"); $this->mw()->WriteStatusBar(''); } } 1;