#=============================================== # TkDiffraction #=============================================== package TkDiffraction; use clib::TkFittingCommon2; @ISA = qw(TkFittingCommon2); #公開したいサブルーチン #@EXPORT = qw(DelSpace Reduce01 MakePath RegExpQuote); use strict; use Math::Complex; use Tk::JPEG; #use Image::Magick; use Utils; use IniFile; use CSV; use MultiColumnData; use GraphData; #use Crystal::Rietan; use Crystal::RietanFP; use MyTk::GraphFrameArray; use MyTk::MyDragDrop; use Sci qw($h $hbar $me $e $todeg $torad);# asin tan); use Sci::Diffraction; #============================================================ # 変数等取得関数 #============================================================ #============================================================ # コンストラクタ、デストラクタ #============================================================ #呼び出されることはない sub new { my ($module, $app) = @_; my $this = {}; bless $this; 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(); $ENV{PATH} = "\\Programs\\bin;$ENV{PATH}"; $this->{ini} = new IniFile(undef, 0, 0); $this->{dini} = new IniFile(undef, 0, 0); # $this->{ini}->{nStepBG} = 2; # $this->{ini}->{nGL} = 6; # $this->{DataFile} = new MultiColumnData; $this->InitializeParameters($this->{ini}, $this->{dini}); $this->{pDiffraction} = new Diffraction; $this->SUPER::CreateWidgets(); return if($DoSuperOnly); #=================================================== # ペインを作製 #=================================================== 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(XRD Diffraction Atom ViewRange Setup GraphFrame)], [qw(nPESStepBG nGaussLorentz)], ); $mw->{NoteBook}->pack(-fill => 'both', -expand => 'yes'); $this->UpdateParameters(); #ツールバーのOpenボタンをファイル読み込みにバインドする my $Samplefmask = '*.bmp;*.jpg;*.jpeg;*.tif;*.tiff'; $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); }, ], ); $this->ReadXraySource($this->{ChooseDiffractionSourceListBox}); $this->ReadXraySource($this->{ChooseXRDSourceListBox}); $this->ReadXraySource($this->{ChooseAtomSourceListBox}); $this->ReadAtoms($this->{ChooseAtomListBox}); $this->UpdateParameters(); $this->SetDiffractionMode(); } sub MakeSourceFrame { my ($this, $MainPaneFrame, $BaseName) = @_; my $ChildFrame = $MainPaneFrame->MyFrame(); my $Frame = $ChildFrame->MyFrame()->pack(-anchor => 'nw'); $this->{"Choose${BaseName}SourceListBox"} = $Frame->MyBrowseEntry( -variable => $this->{ini}->pVariable('Source', 'Cu'), -label => "Source:", -state => "readonly", -takefocus => 1, -width => 8, -Selections => [], -SelIndex => 0, -browsecmd => sub { $this->SetWavelength(); $this->SetASFDCParameters(); }, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $this->{"Choose${BaseName}TransitionListBox"} = $Frame->MyBrowseEntry( -variable => $this->{ini}->pVariable('Transition', 'Ka1'), -label => "Transition:", -state => "readonly", -takefocus => 1, -width => 8, -Selections => ['Ka1', 'Ka2', 'Ka(avrg)', 'Kb1', 'Kb2'], -SelIndex => 0, -browsecmd => sub { $this->SetWavelength(); }, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $Frame = $ChildFrame->MyFrame()->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); $Frame->MyLabel(-text => 'Electron energy:')->pack(-side => 'left'); #print "B: $BaseName\n"; $this->{"${BaseName}ElectronEnergyEntry"} = $Frame->MyEntry( -textvariable => $this->{ini}->pVariable("ElectronEnergy", 100.0), -takefocus => 1, -width => 8, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $Frame->MyLabel(-text => 'keV ')->pack(-side => 'left'); $this->{"${BaseName}ElectronEnergyEntry"}->bind('', sub { $this->SetWavelength(); } ); $Frame->MyLabel(-text => 'Wavelength:')->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $Frame->MyEntry( -textvariable => $this->{ini}->pVariable("SourceWavelength", 0.0), -takefocus => 1, -width => 8, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $Frame->MyLabel(-text => 'nm')->pack(-side => 'left'); return $ChildFrame; } sub BuildDiffractionPane { my ($this, $MainPaneFrame, $EntryWidth) = @_; my $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); $this->{ChooseDiffractionModeListBox} = $Frame->MyBrowseEntry( -variable => $this->{ini}->pVariable('DiffractionMode', 'RHEED'), -label => "Diffraction mode:", -state => "readonly", -takefocus => 1, -width => 8, -Selections => ["RHEED", "TED", "Laue(Transmission)", "Laue(Back)", "LEED"], # -SelIndex => 0, -browsecmd => sub { $this->SetDiffractionMode(); } )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -expand => 'yes', -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 $fmask1 = '*.cif'; $this->{CIFFileFrame} = $this->MakeChooseFileEntry( $Frame, 'CIF', 'CIF:', $this->{ini}->pVariable("CIFFile", ""), '&Choose', sub { $this->{CIFFile} = $this->ChooseFile("open", $fmask1, "ChooseCIFFile", @_); }, 0, sub {}, 1, sub { $this->EditFile('EditCIFFile', @_); }, [] ); $this->{CIFFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $fmask2 = '*.bmp;*.jpg;*.jpeg;*.tif;*.tiff'; $this->{ImageFileFrame} = $this->MakeChooseFileEntry( $Frame, 'ImageFile', 'ImageFile:', $this->{ini}->pVariable("ImageFile", ""), '&Choose', sub { $this->{ImageFile} = $this->ChooseFile("open", $fmask2, "ChooseImageFile", @_); }, 0, sub {}, 1, sub { $this->EditFile('EditImageFile', @_); }, [] ); $this->{ImageFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $fmask3 = '*.csv'; $this->{SourceSpectrumFileFrame} = $this->MakeChooseFileEntry( $Frame, 'SourceSpectrumFile', 'SourceSpectrum:', $this->{ini}->pVariable("SourceSpectrumFile", ""), '&Choose', sub { $this->{ImageFile} = $this->ChooseFile("open", $fmask3, "ChooseSourceSpectrumFile", @_); }, 0, sub {}, 1, sub { $this->EditFile('EditSourceSpectrumFile', @_); }, [] ); $this->{SourceSpectrumFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Source')->pack(-anchor => 'nw'); my $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $this->MakeSourceFrame($ChildFrame, "Diffraction")->pack(-anchor => 'nw'); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Range')->pack(-anchor => 'nw'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'hklmax:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("hmax", 15.0), -takefocus => 1, -width => 5)->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("kmax", 15.0), -takefocus => 1, -width => 5)->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("lmax", 15.0), -takefocus => 1, -width => 5)->pack(-side => 'left'); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Geometry')->pack(-anchor => 'nw'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Incident angle:')->pack(-side => 'left'); $this->{IncidentAngleEntry} = $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("IncidentAngle", 2.0), -takefocus => 1, -width => 8 )->pack(-side => 'left'); $ChildFrame->MyLabel(-text => 'degree')->pack(-side => 'left'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Incident plane hkl:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("IncidentPlaneh", 1), -takefocus => 1, -width => 5)->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("IncidentPlanek", 0), -takefocus => 1, -width => 5)->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("IncidentPlanel", 0), -takefocus => 1, -width => 5)->pack(-side => 'left'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Perpendicular hkl:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("Perpendicularh", 0), -takefocus => 1, -width => 5)->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("Perpendiculark", 1), -takefocus => 1, -width => 5)->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("Perpendicularl", 1), -takefocus => 1, -width => 5)->pack(-side => 'left'); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Screen size')->pack(-anchor => 'nw'); $Frame->MyLabel(-text => 'w:')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable("ScreenW", 8.9), -takefocus => 1, -width => 5)->pack(-side => 'left'); $Frame->MyLabel(-text => ' h:')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable("ScreenH", 11.4), -takefocus => 1, -width => 5)->pack(-side => 'left'); $Frame->MyLabel(-text => ' distance:')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable("ScreenDistance", 10.0), -takefocus => 1, -width => 5)->pack(-side => 'left'); $Frame->MyLabel(-text => 'cm')->pack(-side => 'left'); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Structure')->pack(-anchor => 'nw'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Biso:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("Biso", 0.5), -takefocus => 1, -width => 5)->pack(-side => 'left'); $ChildFrame->MyLabel(-text => 'angstrom^-2')->pack(-side => 'left'); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Image')->pack(-anchor => 'nw'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Brightness:')->pack(-side => 'left'); $this->{PhotoBrightnessEntry} = $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoBrightness", 100.0), -width => 5, )->pack(-side => 'left'); $this->{PhotoBrightnessEntry}->bind('', sub { $this->FocusIn("PhotoBrightnessEntry", $this->{PhotoBrightnessEntry}); } ); $this->{PhotoBrightnessEntry}->bind('', sub { $this->FocusOut("PhotoBrightnessEntry", $this->{PhotoBrightnessEntry}); } ); $ChildFrame->MyLabel(-text => '% Saturation:')->pack(-side => 'left'); $this->{PhotoSaturationEntry} = $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoSaturation", 100.0), -width => 5, )->pack(-side => 'left'); $this->{PhotoSaturationEntry}->bind('', sub { $this->FocusIn("PhotoSaturationEntry", $this->{PhotoSaturationEntry}); } ); $this->{PhotoSaturationEntry}->bind('', sub { $this->FocusOut("PhotoSaturationEntry", $this->{PhotoSaturationEntry}); } ); $ChildFrame->MyLabel(-text => '%')->pack(-side => 'left'); $this->{InvertImageButton} = $ChildFrame->MyCheckbutton( -text => "Solarization", -variable => $this->{ini}->pVariable("InvertImage", 0), -onvalue => 1, -offvalue => 0, -indicatoron => 'no', -takefocus => 1, -command => sub { $this->ImageResize(); $this->Image(); }, )->pack(-side => 'left'); $this->{PhotoSolarizationEntry} = $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoSolarization", 50.0), -width => 5, )->pack(-side => 'left'); $this->{PhotoSolarizationEntry}->bind('', sub { $this->FocusIn("PhotoSolarizationEntry", $this->{PhotoSolarizationEntry}); } ); $this->{PhotoSolarizationEntry}->bind('', sub { $this->FocusOut("PhotoSolarizationEntry", $this->{PhotoSolarizationEntry}); } ); $ChildFrame->MyLabel(-text => '%')->pack(-side => 'left'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Size: w:')->pack(-side => 'left'); $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoW", 0.0), -width => 8, -state => 'disable', )->pack(-side => 'left'); $ChildFrame->MyLabel(-text => ' h:')->pack(-side => 'left'); $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoH", 0.0), -width => 8, -state => 'disable', )->pack(-side => 'left'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Position: (')->pack(-side => 'left'); $this->{PhotoX0Entry} = $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoX0", 10.0), -takefocus => 1, -width => 8, )->pack(-side => 'left'); $this->{PhotoX0Entry}->bind('', sub { $this->FocusIn("PhotoX0Entry", $this->{PhotoX0Entry}); } ); $this->{PhotoX0Entry}->bind('', sub { $this->FocusOut("PhotoX0Entry", $this->{PhotoX0Entry}); } ); $ChildFrame->MyLabel(-text => ', ')->pack(-side => 'left'); $this->{PhotoY0Entry} = $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoY0", 10.0), -takefocus => 1, -width => 8, )->pack(-side => 'left'); $this->{PhotoY0Entry}->bind('', sub { $this->FocusIn("PhotoY0Entry", $this->{PhotoY0Entry}); } ); $this->{PhotoY0Entry}->bind('', sub { $this->FocusOut("PhotoY0Entry", $this->{PhotoY0Entry}); } ); $ChildFrame->MyLabel(-text => ')')->pack(-side => 'left'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Magnification: ')->pack(-side => 'left'); $this->{PhotoK0Entry} = $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoK0", 1.0), -takefocus => 1, -width => 8 )->pack(-side => 'left'); $this->{PhotoK0Entry}->bind('', sub { $this->FocusIn("PhotoK0Entry", $this->{PhotoK0Entry}); } ); $this->{PhotoK0Entry}->bind('', sub { $this->FocusOut("PhotoK0Entry", $this->{PhotoK0Entry}); } ); $ChildFrame->MyLabel(-text => ' wx:')->pack(-side => 'left'); $this->{PhotoKx0Entry} = $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoKx0", 1.0), -takefocus => 1, -width => 8 )->pack(-side => 'left'); $this->{PhotoKx0Entry}->bind('', sub { $this->FocusIn("PhotoKx0Entry", $this->{PhotoKx0Entry}); } ); $this->{PhotoKx0Entry}->bind('', sub { $this->FocusOut("PhotoKx0Entry", $this->{PhotoKx0Entry}); } ); $ChildFrame->MyLabel(-text => ' wy:')->pack(-side => 'left'); $this->{PhotoKy0Entry} = $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("PhotoKy0", 1.0), -takefocus => 1, -width => 8 )->pack(-side => 'left'); $this->{PhotoKy0Entry}->bind('', sub { $this->FocusIn("PhotoKy0Entry", $this->{PhotoKy0Entry}); } ); $this->{PhotoKy0Entry}->bind('', sub { $this->FocusOut("PhotoKy0Entry", $this->{PhotoKy0Entry}); } ); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Diffraction Spots')->pack(-anchor => 'nw'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Diffraction spot: Max size:')->pack(-side => 'left'); $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("MaxDiffractionSpotSize", 6), -takefocus => 1, -width => 8 )->pack(-side => 'left'); $this->{ini}->{DiffractionColor} = "#ff0000" if(!defined $this->{ini}->{DiffractionColor}); $this->{DiffractionColorButton} = $ChildFrame->MyButton( -text => "Color", -takefocus => 1, -background => $this->{ini}->{DiffractionColor}, -command => sub { $this->ChooseColor("DiffractionColor", $this->{DiffractionColorButton}); }, )->pack(-side => 'left', -fill => 'x'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Extinction spot: Max size:')->pack(-side => 'left'); $ChildFrame->MyEntry( -textvariable => $this->{ini}->pVariable("ExtinctionSpotSize", 1), -takefocus => 1, -width => 8 )->pack(-side => 'left'); $this->{ini}->{ExtinctionColor} = "#aaaaaa" if(!defined $this->{ini}->{ExtinctionColor}); $this->{ExtinctionColorButton} = $ChildFrame->MyButton( -text => "Color", -takefocus => 1, -background => $this->{ini}->{ExtinctionColor}, -command => sub { $this->ChooseColor("ExtinctionColor", $this->{ExtinctionColorButton}); }, )->pack(-side => 'left', -fill => 'x'); $this->BuildFooter($MainPaneFrame, $EntryWidth, ("CalDiffraction", "Source", "Image", "RePlot", "RestoreScale", "&Save", "SvLauePt:SaveLauePt")); } sub ChooseColor { my ($this, $VarName, $button) = @_; #print "b=$button\n"; my $ini = $this->{ini}; $ini->{$VarName} = Dialog::ChooseColorDialog($this, $button, "-background"); #"-color" => "yellow"); $button->configure(-background => $ini->{$VarName}); print "color=$ini->{$VarName}\n"; } sub FocusIn { my ($this, $name, $widget) = @_; $this->{PrevVal} = $widget->GetText(); } sub FocusOut { my ($this, $name, $widget) = @_; if(defined $this->{PrevVal} and $this->{PrevVal} != $widget->GetText() and $this->{ini}->{ImageFile} ne '') { $this->ImageResize() if($name =~ /PhotoK.*Entry/i or $name =~ /(Bright|Saturation|Solarization)/i); $this->Draw(); } } sub BuildXRDPane { 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 $fmask = '*.cif'; $this->{CIFFileFrame} = $this->MakeChooseFileEntry( $Frame, 'CIF', 'CIF:', $this->{ini}->pVariable("CIFFile", ""), '&Choose', sub { if($this->{ini}->{Source} eq 'Electron') { $this->{ini}->{Source} = 'Cu'; $this->{ini}->{Transition} = 'Ka1'; $this->SetWavelength(); $this->SetASFDCParameters(); } $this->{CIFFile} = $this->ChooseFile("open", $fmask, "ChooseCIFFile", @_); }, 0, sub {}, 1, sub { $this->EditFile('EditCIFFile', @_); }, [] ); $this->{CIFFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $fmask2 = '*.csv;*.int;*.pat;*.txt;*.asc'; $this->{XRDFileFrame} = $this->MakeChooseFileEntry( $Frame, 'XRD', 'XRD:', $this->{ini}->pVariable("XRDFile", ""), '&Choose', sub { if($this->{ini}->{Source} eq 'Electron') { $this->{ini}->{Source} = 'Cu'; $this->{ini}->{Transition} = 'Ka1'; $this->SetWavelength(); $this->SetASFDCParameters(); } $this->{XRDFile} = $this->ChooseFile("open", $fmask2, "ChooseXRDFile", @_); }, 0, sub {}, 1, sub { $this->EditFile('EditXRDFile', @_); }, [] ); $this->{XRDFileFrame}->pack(-anchor => 'nw', -fill => 'x'); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Source')->pack(-anchor => 'nw'); my $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $this->MakeSourceFrame($ChildFrame, "XRD")->pack(-anchor => 'nw'); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Range')->pack(-anchor => 'nw'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => '2Theta:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("Q2Start", 5.0), -takefocus => 1, -width => 8)->pack(-side => 'left'); $ChildFrame->MyLabel(-text => ' - ')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("Q2Stop", 120.0), -takefocus => 1, -width => 8)->pack(-side => 'left'); $ChildFrame->MyLabel(-text => ', ')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("Q2Step", 0.02), -takefocus => 1, -width => 8)->pack(-side => 'left'); $ChildFrame->MyLabel(-text => 'degrees')->pack(-side => 'left'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'hklmax:')->pack(-side => 'left'); $this->{XRDhmaxEntry} = $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDhmax", 5.0), -takefocus => 1, -width => 5, -state => 'disable')->pack(-side => 'left'); $this->{XRDkmaxEntry} = $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDkmax", 5.0), -takefocus => 1, -width => 5, -state => 'disable')->pack(-side => 'left'); $this->{XRDlmaxEntry} = $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDlmax", 5.0), -takefocus => 1, -width => 5, -state => 'disable')->pack(-side => 'left'); $ChildFrame->MyButton( -text => 'guess', -takefocus => 1, -command => sub { $this->GuessXRDhklmax(); }, )->pack(-side => 'left'); my $AutoGuesshklmaxButton = $ChildFrame->MyCheckbutton( -text => "Auto", -variable => $this->{ini}->pVariable("AutoGuesshklmax", 1), -onvalue => 1, -offvalue => 0, -indicatoron => 'no', )->pack(-side => 'left'); $AutoGuesshklmaxButton->configure( -command => sub { if($this->{ini}->{AutoGuesshklmax}) { $this->{XRDhmaxEntry}->configure(-state => 'disable'); $this->{XRDkmaxEntry}->configure(-state => 'disable'); $this->{XRDlmaxEntry}->configure(-state => 'disable'); } else { $this->{XRDhmaxEntry}->configure(-state => 'normal'); $this->{XRDkmaxEntry}->configure(-state => 'normal'); $this->{XRDlmaxEntry}->configure(-state => 'normal'); } } ); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Structure and profile')->pack(-anchor => 'nw'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'Scale:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDScale", 1.0), -takefocus => 1, -width => 8)->pack(-side => 'left'); $ChildFrame->MyButton( -text => 'guess', -takefocus => 1, -command => sub { $this->GuessXRDScale(); }, )->pack(-side => 'left'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'FWHM:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDFWHM", 0.1), -takefocus => 1, -width => 8)->pack(-side => 'left'); $ChildFrame->MyLabel(-text => 'degrees')->pack(-side => 'left'); $ChildFrame->MyLabel(-text => ' Biso:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("Biso", 0.5), -takefocus => 1, -width => 8)->pack(-side => 'left'); $ChildFrame->MyLabel(-text => 'angstrom^-2')->pack(-side => 'left'); $Frame = $MainPaneFrame->MyLabFrame(-label => 'Orientation')->pack(-anchor => 'nw'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'hkl:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDOrientationh", 0), -takefocus => 1, -width => 4)->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDOrientationk", 0), -takefocus => 1, -width => 4)->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDOrientationl", 1), -takefocus => 1, -width => 4)->pack(-side => 'left'); $this->{ChooseGrainShapeListBox} = $ChildFrame->MyBrowseEntry( -variable => $this->{ini}->pVariable('XRDGrainShape', 'sheet'), -label => "Grain Shape:", -state => "readonly", -takefocus => 1, -width => 8, -Selections => [qw(sheet needle)], -SelIndex => 0, )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $ChildFrame = $Frame->MyFrame()->pack(-anchor => 'nw'); $ChildFrame->MyLabel(-text => 'p1:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDOrientationp1", 1.0), -takefocus => 1, -width => 6)->pack(-side => 'left'); $ChildFrame->MyLabel(-text => 'p2:')->pack(-side => 'left'); $ChildFrame->MyEntry(-textvariable => $this->{ini}->pVariable("XRDOrientationp2", 0.0), -takefocus => 1, -width => 6)->pack(-side => 'left'); $this->BuildFooter($MainPaneFrame, $EntryWidth, ("CalXRD", "CalFhkl", "RePlot", "RestoreScale", "ASF", "&Save")); $this->BuildFooter($MainPaneFrame, $EntryWidth, ("Save Simple CIF", "Save P1 CIF")); } sub BuildAtomPane { 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'); $this->MakeSourceFrame($MainPaneFrame, "Atom")->pack(-anchor => 'nw'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw'); $this->{ChooseAtomListBox} = $Frame->MyBrowseEntry( -variable => $this->{ini}->pVariable('Atom', 'Al'), -label => "Atom:", -state => "readonly", -takefocus => 1, -width => 8, -Selections => [qw(H He Li Be B C N O F Ne)], -SelIndex => 5, -browsecmd => sub { $this->SetASFDCParameters($this->{ChooseAtomListBox}); } )->pack(-side => 'left', -expand => 'yes', -fill => 'x'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw'); $Frame->MyLabel(-text => 'a1=')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('a1', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('b1', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame->MyLabel(-text => 'a2=')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('a2', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('b2', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw'); $Frame->MyLabel(-text => 'a3=')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('a3', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('b3', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame->MyLabel(-text => 'a4=')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('a4', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('b4', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame = $MainPaneFrame->MyFrame()->pack(-anchor => 'nw'); $Frame->MyLabel(-text => 'a0=')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('c', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame->MyLabel(-text => 'df1=')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('df1', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame->MyLabel(-text => 'df2=')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('df2', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $Frame->MyLabel(-text => 'Z=')->pack(-side => 'left'); $Frame->MyEntry(-textvariable => $this->{ini}->pVariable('Z', ''), -takefocus => 1, -width => 8)->pack(-side => 'left'); $this->BuildFooter($MainPaneFrame, $EntryWidth, ("ASF", "RePlot", "RestoreScale", "&Save")); } 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 "this=$this, 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 ''); #print "O:$Option\n"; my $ret; if($Option eq 'ChooseParameterFile') { $ret = $this->ReadParameterFile($filepath, 1, $Frame); } elsif($Option =~ /ChooseCIFFile/i) { $this->ReadCIFFile($filepath); } elsif($Option =~ /ChooseXRDFile/i) { $this->ReadXRDFile($filepath); $this->RePlot(1, 1, 1, 1); } elsif($Option =~ /ChooseImageFile/i) { $this->ReadImageFile($filepath); } elsif($Option =~ /ChooseSourceSpectrumFile/i) { $this->ReadSourceSpectrumFile($filepath); } return undef unless($ret); $this->CreateGraphFrame() if(!$this->GetGraphFrameArray()); return $ret; } sub ReadCIFFile { my ($this, $filepath) = @_; $this->{pDiffraction}->ResetFhkl(1) if($this->{pDiffraction}); print "ReadCIFFile: Read [$filepath]\n"; $this->{pCIF} = new CIF(); if(!$this->{pCIF}->Read($filepath)) { print "Error: Can not read [$filepath]\n"; return; } $this->{pCrystal} = $this->{pCIF}->GetCCrystal(); } sub ReadXRDFile { my ($this, $filepath) = @_; my $type = RietanFP::CheckFileType($filepath); $type = '' if(!defined $type); print "ReadXRDFile: Read [$filepath] [t=$type]\n"; my ($nData, $pLabels, @DataArray); if($type eq '') { ($nData, $pLabels, @DataArray) = MultiColumnData->new()->Read($filepath, 1); $this->{XRDObsQ} = $DataArray[0]; $this->{XRDObsIntensity} = $DataArray[1]; } else { my $Rietan = new RietanFP; $Rietan->Read($filepath); my $pDataArray = $Rietan->{DataArray}; my $pData = $pDataArray->GetGraphData(0); print "pD=$pDataArray, $pData\n"; $this->{XRDObsQ} = $pData->{'2Q'}; $this->{XRDObsIntensity} = $pData->{Intensity}; $this->{XRDObsIntensity} = $pData->{ObsIntensity} if(!$this->{XRDObsIntensity}); $this->{XRDObsIntensity} = $pData->{CalIntensity} if(!$this->{XRDObsIntensity}); print " $this->{XRDObsQ}, $this->{XRDObsIntensity}\n"; } #print "D: ($nData, $pLabels, @DataArray)\n"; $this->{Target} = "XRD"; } sub ReadImageFile { my ($this, $filepath) = @_; my $mw = $this->mw(); my $canvas = $this->Canvas(); print "ReadImageFile: Read [$filepath]\n"; $this->{pImage} = $mw->Photo( -format => 'jpeg', -file => $filepath, ); $this->{ini}->{PhotoW} = $this->{pImage}->width(); $this->{ini}->{PhotoH} = $this->{pImage}->height(); $canvas = $this->Canvas() if(!defined $canvas);; my $w = $canvas->width(); my $h = $canvas->height(); my $RPhoto = $this->{ini}->{PhotoH} / $this->{ini}->{PhotoW}; my $RCanvas = $h / $w; if($RPhoto > $RCanvas) { $this->{ini}->{PhotoK0} = $h / $this->{ini}->{PhotoH}; } else { $this->{ini}->{PhotoK0} = $w / $this->{ini}->{PhotoW}; } $this->ImageResize(); $this->Image(); } sub ReadSourceSpectrumFile { my ($this, $filepath) = @_; print "ReadSourceSpectrumFile: Read [$filepath]\n"; $this->{pSourceSpectrum} = new MultiColumnData; if(!$this->{pSourceSpectrum}->ReadAll($filepath)) { $this->App()->print("Error in ReadSourceSpectrumFile: Can not read [$filepath].\n"); return; } my $pX = $this->{pSourceSpectrum}->GetXData("Wave.*"); my $pY = $this->{pSourceSpectrum}->GetYData("Int.*"); my $n = @$pX; #for(my $i = 0 ; $i < $n ; $i++) { # print "$i: $pX->[$i]\t$pY->[$i]\n"; #} #my $x = 1.54; #my $y = $data->YVal($x); #print "(x,y)=($x,$y)\n"; return ($pX, $pY, $n); } sub ImageResize { my ($this) = @_; my $ini = $this->{ini}; my $source = $ini->{ImageFile}; return if($source eq ''); my ($drive, $directory, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($source); my $target = "$drive${directory}~\$Dtmp-$filename"; $this->{FixImageMagnification} = 0; $this->{ConvertedImageFile} = $target; my $ws = $ini->{PhotoW}; my $hs = $ini->{PhotoH}; my $K0 = $ini->{PhotoK0}; #print "k=$ini->{PhotoKx0},$this->{ini}->{PhotoKy0}\n"; my $wt = int($ws * $K0 * $ini->{PhotoKx0}); my $ht = int($hs * $K0 * $ini->{PhotoKy0}); print "ImageResize: From [$source:$ws x $hs] to [$target: $wt x $ht] \n"; if(0) { my $image = Image::Magick->new; my $nRead = $image->Read($source); print "nRead = $nRead\n"; return if(!$nRead); $image->Resize(width => $wt, height => $ht); $image->Write('jpeg:a.jpg'); } # my $convert = "d:\\Programs\\bin\\convert"; my $convert = "convert"; my $option = "-quantize gray -modulate $ini->{PhotoBrightness},$ini->{PhotoSaturation}";# +contrast +contrast"; my $command = "$convert $option -scale ${wt}x${ht}! \"$source\" \"$target\""; if($this->{ini}->{InvertImage}) { $command = "$convert $option -solarize $ini->{PhotoSolarization} -scale ${wt}x${ht}! \"$source\" \"$target\""; } #my $command = "$convert -fill \"#FFFFFF80\" -opaque \"#FFFFFF00\" -solarize 0.0 -resize ${wt}x${ht}! \"$source\" \"$target\""; print "$command\n"; unlink($target); # `$command`; # if(-e $target) { if(!system($command)) { $this->{FixImageMagnification} = 1; } } sub SetDiffractionMode { my ($this) = @_; my $lb = $this->{ChooseDiffractionModeListBox}; my $mode = $lb->GetText(); if($mode =~ /RHEED/) { $this->{IncidentAngleEntry}->configure(-state => 'normal'); } else { $this->{IncidentAngleEntry}->configure(-state => 'disable'); } if($mode =~ /(RHEED|LEED|TED)/) { $this->{ChooseDiffractionSourceListBox}->SetText("Electron"); $this->SetWavelength(); } else { $this->{ChooseDiffractionSourceListBox}->SetText("Cu"); $this->SetWavelength(); } } sub SetASFDCParameters { my ($this) = @_; my $ini = $this->{ini}; my $atom = $ini->{Atom}; my $Source = $ini->{Source}; #print "Atom: $atom,$Source\n"; my $Rietan = new RietanFP; my ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$C, $b,$df1,$df2) = $Rietan->ReadASFParameters($atom, undef, $Source); $ini->{a1} = $A1; $ini->{b1} = $B1; $ini->{a2} = $A2; $ini->{b2} = $B2; $ini->{a3} = $A3; $ini->{b3} = $B3; $ini->{a4} = $A4; $ini->{b4} = $B4; $ini->{c} = $C; $ini->{df1} = $df1; $ini->{df2} = $df2; $ini->{Z} = $Rietan->{AtomicNumber}; #print "A=", join(', ', ($A1,$B1,$A2,$B2,$A3,$B3,$A4,$B4,$C, $b,$df1,$df2)), "\n"; } sub ReadAtoms { my ($this, $AtomsListBox) = @_; my $sel = $AtomsListBox->GetText(); $AtomsListBox->DeleteAllItem(); $AtomsListBox->AddItem(RietanFP::GetASFDCAtoms()); $AtomsListBox->SetCurSel($sel); $this->SetASFDCParameters(); } sub SetWavelength { my ($this) = @_; my $ini = $this->{ini}; if($ini->{Source} eq 'Electron') { $this->{XRDElectronEnergyEntry}->configure(-stat => 'normal') if( $this->{XRDElectronEnergyEntry}); $this->{DiffractionElectronEnergyEntry}->configure(-stat => 'normal') if( $this->{DiffractionElectronEnergyEntry}); $this->{AtomElectronEnergyEntry}->configure(-stat => 'normal') if( $this->{AtomElectronEnergyEntry}); my $l = Diffraction::ElectroneVTonm($ini->{ElectronEnergy} * 1.0e3, 0); $ini->{SourceWavelength} = Diffraction::ElectroneVTonm($ini->{ElectronEnergy} * 1.0e3); print "Electron wavelength: NonRelativistic: $l nm\n"; print " Relativistic: $ini->{SourceWavelength} nm\n"; return; } else { $this->{XRDElectronEnergyEntry}->configure(-stat => 'disable') if( $this->{XRDElectronEnergyEntry}); $this->{DiffractionElectronEnergyEntry}->configure(-stat => 'disable') if( $this->{DiffractionElectronEnergyEntry}); $this->{AtomElectronEnergyEntry}->configure(-stat => 'disable') if( $this->{AtomElectronEnergyEntry}); my $p = $this->{pXraySource}; my $s = $ini->{Source}; my $t = $ini->{Transition}; #print "s:$s: $t, p=$p\n"; $ini->{SourceWavelength} = 0.0; if($t eq 'Ka(avrg)') { $ini->{SourceWavelength} = $p->{"${s}Ka"} * 0.1 if(defined $p->{"${s}Ka"}); } elsif($t eq 'Kb(avrg)') { $ini->{SourceWavelength} = $p->{"${s}Kb"} * 0.1 if(defined $p->{"${s}Kb"}); } else { $ini->{SourceWavelength} = $p->{"$s$t"} * 0.1 if(defined $p->{"$s$t"}); } } } sub ReadXraySource { my ($this, $SourceListBox, $AtomsReadFromXraySource) = @_; $AtomsReadFromXraySource = 1 if($AtomsReadFromXraySource); $AtomsReadFromXraySource = 0; my $IniFile = $this->App()->IniFile(); my $sel = $SourceListBox->GetText(); $SourceListBox->DeleteAllItem(); $SourceListBox->AddItem("Electron"); if(!$AtomsReadFromXraySource) { $SourceListBox->AddItem(qw(Cr Fe Co Cu Mo Ag Kb)); } my %Val = $IniFile->GetSection("X-ray"); my %XraySource; foreach my $key (sort keys %Val) { my $val = $Val{$key}; #print "$key: $Val{$key}\n"; next if(length($key) > 2 or $key eq ''); my ($ka2, $ka1, $kb2, $kb1) = Utils::Split("\\s+", $val); $ka1 =~ s/\(.*\)// if(defined $ka1); $ka2 =~ s/\(.*\)// if(defined $ka2); $kb1 =~ s/\(.*\)// if(defined $kb1); $kb2 =~ s/\(.*\)// if(defined $kb2); $SourceListBox->AddItem($key) if($AtomsReadFromXraySource); $XraySource{"${key}Ka1"} = $ka1 if(defined $ka1); $XraySource{"${key}Ka2"} = $ka2 if(defined $ka2); $XraySource{"${key}Ka"} = (2*$ka1+$ka2)/3.0 if(defined $ka2); $XraySource{"${key}Kb1"} = $kb1 if(defined $kb1); $XraySource{"${key}Kb2"} = $kb2 if(defined $kb2); $XraySource{"${key}Kb"} = (2*$kb1+$kb2)/3.0 if(defined $kb2); } $this->{pXraySource} = \%XraySource; $SourceListBox->SetCurSel($sel); $this->SetWavelength(); } 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, ("ASF", "XRD", "Diffraction", "RePlot", "RestoreScale", "&Save")); } sub BuildFooter { my ($this, $MainFrame, $EntryWidth, @Buttons) = @_; my $Frame1 = $MainFrame->MyFrame()->pack(-anchor => 'nw', -fill => 'x'); my $ButtonFrame = $this->MakeFittingButtons($Frame1, @Buttons); $ButtonFrame->pack(-anchor => 'nw', -expand => 'yes', -fill => 'x'); } #=================================================== # データ処理 #=================================================== sub Initialize { my ($this, $InitializeParameterFile, $InitializeData) = @_; $this->{pDiffraction}->ResetFhkl(1) if($this->{pDiffraction}); if($InitializeParameterFile) { $this->{ini}->{SampleCSVFile} = ''; $this->{ini}->{FitXMin} = ''; $this->{ini}->{FitXMax} = ''; } if($InitializeData) { $this->{pCalX} = undef; $this->{pCalY} = undef; } } sub InitializeParameters { my ($this, $ini, $dini) = @_; # $this->AddParameters($ini, $dini, "EF", 0.0, 1, 1.0, '', ''); } sub RePlot { my ($this, $ResetViewRange, $CreateGraphFrame, $AssignGraphData, $Draw) = @_; $ResetViewRange = 0 if(!defined $ResetViewRange); $CreateGraphFrame = 1 if(!defined $CreateGraphFrame); $AssignGraphData = 1 if(!defined $AssignGraphData); $Draw = 1 if(!defined $Draw); if($CreateGraphFrame or $ResetViewRange) { $this->CreateGraphFrame(); } if($CreateGraphFrame or !$this->GetGraphFrameArray()) { $this->CreateGraphFrame(undef, undef, 1); $this->AssignGraphData(1); } elsif($AssignGraphData) { $this->AssignGraphData($ResetViewRange); } $this->Draw() if($Draw); } sub Source { my ($this) = @_; print "Plot Source X-ray\n"; $this->{Target} = "Source"; $this->RePlot(1); } sub CalDiffraction { my ($this) = @_; my $mode = $this->{ini}->{DiffractionMode}; if($mode eq 'RHEED') { $this->RHEED(); } elsif($mode eq 'LEED') { $this->LEED(); } elsif($mode eq 'TED') { $this->TED(); } elsif($mode =~ /Laue/) { $this->Laue(); } } #$LTransmission = 5.0; # cm, 透過Laue配置での試料-スクリーン距離 #$LBack = 3.0; # cm, 背面反射Laue配置での試料-スクリーン距離 sub Laue { my ($this) = @_; my $ini = $this->{ini}; my $Diffraction = $this->{pDiffraction}; $Diffraction->SetDiffractionMode($ini->{DiffractionMode}); $Diffraction->SetSource($ini->{Source}); # $Diffraction->SetWavelength($ini->{SourceWavelength}); $Diffraction->SetSourceSpectrum($this->{pSourceSpectrum}); $Diffraction->SetCrystal($this->{pCrystal}); $Diffraction->SetThermalVibrationFactor($ini->{Biso}); $Diffraction->SethklRange($ini->{hmax}, $ini->{kmax}, $ini->{lmax}); $Diffraction->SetIncidenthkl($ini->{IncidentPlaneh}, $ini->{IncidentPlanek}, $ini->{IncidentPlanel}); $Diffraction->SetPerpendicularhkl($ini->{Perpendicularh}, $ini->{Perpendiculark}, $ini->{Perpendicularl}); $Diffraction->SetScreenGeometry($ini->{ScreenW}, $ini->{ScreenH}, $ini->{ScreenDistance}); $Diffraction->SetQ2Min(0.1); $Diffraction->Prepare(); printf "Incident : %6.3f %6.3f %6.3f\n", $Diffraction->Incidenthkl(); printf "Perpendicular: %6.3f %6.3f %6.3f\n", $Diffraction->Perpendicularhkl(); printf "Horizontal : %6.3f %6.3f %6.3f\n", $Diffraction->Horizontalhkl(); $Diffraction->CalLauePattern(sub{ $this->mw()->update(); }); $this->{Target} = "Laue"; $this->RePlot(1); } sub TED { my ($this) = @_; my $ini = $this->{ini}; my $Diffraction = $this->{pDiffraction}; $Diffraction->SetDiffractionMode($ini->{DiffractionMode}); $Diffraction->SetSource($ini->{Source}); $Diffraction->SetWavelength($ini->{SourceWavelength}); $Diffraction->SetCrystal($this->{pCrystal}); $Diffraction->SetThermalVibrationFactor($ini->{Biso}); $Diffraction->SethklRange($ini->{hmax}, $ini->{kmax}, $ini->{lmax}); $Diffraction->SetIncidenthkl($ini->{IncidentPlaneh}, $ini->{IncidentPlanek}, $ini->{IncidentPlanel}); $Diffraction->SetPerpendicularhkl($ini->{Perpendicularh}, $ini->{Perpendiculark}, $ini->{Perpendicularl}); $Diffraction->SetScreenGeometry($ini->{ScreenW}, $ini->{ScreenH}, $ini->{ScreenDistance}); $Diffraction->SetQ2Min(0.1); $Diffraction->Prepare(); printf "Incident : %6.3f %6.3f %6.3f\n", $Diffraction->Incidenthkl(); printf "Perpendicular: %6.3f %6.3f %6.3f\n", $Diffraction->Perpendicularhkl(); printf "Horizontal : %6.3f %6.3f %6.3f\n", $Diffraction->Horizontalhkl(); $Diffraction->CalTEDPattern(sub{ $this->mw()->update(); }); $this->{Target} = "TED"; $this->RePlot(1); } sub RHEED { my ($this) = @_; my $ini = $this->{ini}; #print "RHEED in\n"; my $StopByError = 0; my $Diffraction = $this->{pDiffraction}; $Diffraction->SetDiffractionMode($ini->{DiffractionMode}); $Diffraction->SetSource($ini->{Source}); #print "RHEED in2\n"; $Diffraction->SetWavelength($ini->{SourceWavelength}); #print "RHEED in2a\n"; $Diffraction->SetCrystal($this->{pCrystal}, undef, $StopByError); #print "RHEED in2b\n"; $Diffraction->SetThermalVibrationFactor($ini->{Biso}); #print "RHEED in3\n"; $Diffraction->SethklRange($ini->{hmax}, $ini->{kmax}, $ini->{lmax}); $Diffraction->SetIncidentAngle($ini->{IncidentAngle}); $Diffraction->SetIncidenthkl($ini->{IncidentPlaneh}, $ini->{IncidentPlanek}, $ini->{IncidentPlanel}); $Diffraction->SetPerpendicularhkl($ini->{Perpendicularh}, $ini->{Perpendiculark}, $ini->{Perpendicularl}); #print "RHEED in4\n"; $Diffraction->SetScreenGeometry($ini->{ScreenW}, $ini->{ScreenH}, $ini->{ScreenDistance}); $Diffraction->SetQ2Min(0.1); #print "Prepare...\n"; $Diffraction->Prepare(); printf "Incident : %6.3f %6.3f %6.3f\n", $Diffraction->Incidenthkl(); printf "Perpendicular: %6.3f %6.3f %6.3f\n", $Diffraction->Perpendicularhkl(); printf "Horizontal : %6.3f %6.3f %6.3f\n", $Diffraction->Horizontalhkl(); $Diffraction->CalRHEEDPattern(sub{ $this->mw()->update(); }, $StopByError); $this->{Target} = "RHEED"; $this->RePlot(1); } sub LEED { my ($this) = @_; my $ini = $this->{ini}; my $Diffraction = $this->{pDiffraction}; $Diffraction->SetDiffractionMode($ini->{DiffractionMode}); $Diffraction->SetSource($ini->{Source}); $Diffraction->SetWavelength($ini->{SourceWavelength}); $Diffraction->SetCrystal($this->{pCrystal}); $Diffraction->SetThermalVibrationFactor($ini->{Biso}); $Diffraction->SethklRange($ini->{hmax}, $ini->{kmax}, $ini->{lmax}); $Diffraction->SetIncidenthkl($ini->{IncidentPlaneh}, $ini->{IncidentPlanek}, $ini->{IncidentPlanel}); $Diffraction->SetPerpendicularhkl($ini->{Perpendicularh}, $ini->{Perpendiculark}, $ini->{Perpendicularl}); $Diffraction->SetScreenGeometry($ini->{ScreenW}, $ini->{ScreenH}, $ini->{ScreenDistance}); $Diffraction->SetQ2Min(0.1); $Diffraction->Prepare(); printf "Incident : %6.3f %6.3f %6.3f\n", $Diffraction->Incidenthkl(); printf "Perpendicular: %6.3f %6.3f %6.3f\n", $Diffraction->Perpendicularhkl(); printf "Horizontal : %6.3f %6.3f %6.3f\n", $Diffraction->Horizontalhkl(); $Diffraction->CalLEEDPattern(sub{ $this->mw()->update(); }); $this->{Target} = "LEED"; $this->RePlot(1); } sub SaveSimpleCIF { my ($this) = @_; my $ini = $this->{ini}; print "\nSave Simple CIF\n"; my $CIFPath = $ini->{CIFFile}; print " Read [$CIFPath]: \n"; my $CIF = new CIF; if($CIF->Read($CIFPath)) { print " Succeeded.\n"; } else { print " Failed.\n"; return; } my ($drive, $directory, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($CIFPath); my $OutPath = Deps::MakePath("$drive$directory", "${filebody}-Simple.cif", 0); print " Save to [$OutPath]: "; if($CIF->WriteSimpleCIFFile($OutPath)) { print " Succeeded.\n"; } else { print " Failed.\n"; } } sub SaveP1CIF { my ($this) = @_; my $ini = $this->{ini}; my $Crystal = $this->{pCrystal}; $Crystal->ExpandCoordinates(); $Crystal->SetOutputMode("expanded"); print "\nSave P1 CIF\n"; my $CIFPath = $ini->{CIFFile}; print " Read [$CIFPath]: \n"; my $CIF = new CIF; if($CIF->Read($CIFPath)) { print " Succeeded.\n"; } else { print " Failed.\n"; return; } my ($drive, $directory, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($CIFPath); my $OutPath = Deps::MakePath("$drive$directory", "${filebody}-P1.cif", 0); print " Save to [$OutPath]: "; if($CIF->CreateCIFFileFromCCrystal($Crystal, $OutPath, 0, "win")) { print " Succeeded.\n"; } else { print " Failed.\n"; } } sub GuessXRDhklmax { my ($this) = @_; my $ini = $this->{ini}; my $Diffraction = $this->{pDiffraction}; $Diffraction->SetDiffractionMode("PowderXRD"); $Diffraction->SetSource($ini->{Source}); $Diffraction->SetWavelength($ini->{SourceWavelength}); $Diffraction->SetCrystal($this->{pCrystal}); $Diffraction->SetThermalVibrationFactor($ini->{Biso}); $Diffraction->SetPeakWidth($ini->{XRDFWHM}); $Diffraction->SetQ2Range($ini->{Q2Start}, $ini->{Q2Stop}, $ini->{Q2Step}); ($ini->{XRDhmax}, $ini->{XRDkmax}, $ini->{XRDlmax}) = $Diffraction->Guesshklmax(); } sub CalXRD { my ($this) = @_; my $ini = $this->{ini}; my $Diffraction = $this->{pDiffraction}; $Diffraction->SetCrystal($this->{pCrystal}); if($Diffraction->ppFArray()) { $this->CalFhkl(0) } else { $this->CalFhkl(1); } } sub CalFhkl { my ($this, $CalFhkl) = @_; $CalFhkl = 1 if(!defined $CalFhkl); my $ini = $this->{ini}; my $Diffraction = $this->{pDiffraction}; $Diffraction->SetCrystal($this->{pCrystal}); if($this->{ini}->{AutoGuesshklmax}) { $this->GuessXRDhklmax() } $Diffraction->ResetFhkl($CalFhkl); $Diffraction->SetDiffractionMode("PowderXRD"); $Diffraction->SetSource($ini->{Source}); $Diffraction->SetWavelength($ini->{SourceWavelength}); $Diffraction->SetThermalVibrationFactor($ini->{Biso}); $Diffraction->SetPeakWidth($ini->{XRDFWHM}); $Diffraction->SetQ2Range($ini->{Q2Start}, $ini->{Q2Stop}, $ini->{Q2Step}); $Diffraction->SethklRange($ini->{XRDhmax}, $ini->{XRDkmax}, $ini->{XRDlmax}); $Diffraction->SetOrienation($ini->{XRDOrientationh}, $ini->{XRDOrientationk}, $ini->{XRDOrientationl}, $ini->{XRDGrainShape}, $ini->{XRDOrientationp1}, $ini->{XRDOrientationp2}); $Diffraction->Prepare(); $Diffraction->CalPowderXRDPattern(sub{ $this->mw()->update(); }); my $Scale = $ini->{XRDScale}; #print "S: $Scale\n"; my $pY = $this->{pDiffraction}->pXRDIntensity(); for(my $i = 0 ; $i < @$pY ; $i++) { #print "i: $i, $pY->[$i]\n"; $pY->[$i] = $pY->[$i] * $Scale; } $this->{Target} = "XRD"; $this->RePlot(1); } sub ASF { my ($this, $StopByError) = @_; $StopByError = 0 if(!defined $StopByError); my $ini = $this->{ini}; my $Rietan = new RietanFP; $Rietan->ReadASFParameters($ini->{Atom}, undef, $ini->{Source}, $StopByError); $ini->{FitXMin} = 0.05 if(!defined $ini->{FitXMin}); $ini->{FitXMax} = 10.0 if(!defined $ini->{FitXMax}); $ini->{FitXStep} = 0.05 if(!defined $ini->{FitXStep}); my $XMin = $ini->{FitXMin}; my $XMax = $ini->{FitXMax}; my $XStep = $ini->{FitXStep}; my $nX = int( ($XMax - $XMin) / $XStep + 1.0001); my (@X, @Y1, @Y2); for(my $i = 0 ; $i < $nX ; $i++) { my $s = $XMin + $XStep * $i; $X[$i] = $s; my $asf; if($ini->{Source} eq 'Electron') { $asf = $Rietan->asfElectron($s, $StopByError); } else { $asf = $Rietan->asf($s, $StopByError); } $Y1[$i] = Re($asf); $Y2[$i] = Im($asf); print "$i: X=$s: asf=$asf\n"; } $this->{pASFX} = \@X; $this->{pASFRe} = \@Y1; $this->{pASFIm} = \@Y2; $this->{Target} = "ASF"; $this->RePlot(1); } sub SaveLauePt { my ($this) = @_; my $pCrystal = $this->{pCrystal}; my $CIFFile = $this->{ini}->{CIFFile}; if(!defined $pCrystal or !defined $CIFFile) { print "Error in SaveLauePt: CIF file is not red.\n"; return; } my $OutFile = Deps::ReplaceExtension($CIFFile, ".struct"); print "Save LauePt structure file for CIF [$CIFFile] to [$OutFile].\n"; my $out = new JFile($OutFile, "w"); if(!$out) { print "Error in SaveLauePt: Can not write to [$OutFile].\n"; return; } $out->print("! Text format structure file\n"); $out->print("\n"); my $Name = $pCrystal->CrystalName(); $out->print("$Name ! Crystal Name\n"); my ($a, $b, $c, $alpha, $beta, $gamma) = $pCrystal->LatticeParameters(); $out->printf("%8.4f %8.4f %8.4f ! Lattice constants a, b, c (A)\n", $a, $b, $c); $out->printf("%8.4f %8.4f %8.4f ! alpha, beta, gamma (degree)\n", $alpha, $beta, $gamma); $out->print("\n"); my @Sites = $pCrystal->GetCExpandedAtomSiteList(); my $nSites = @Sites; $out->print("$nSites ! Total number of atoms in the unit cell\n"); $out->print("\n"); $out->print("! Atom X Y Z Occupation\n"); for(my $i = 0 ; $i < $nSites ; $i++) { my $AtomName = $Sites[$i]->AtomNameOnly(); my ($x,$y,$z) = $Sites[$i]->Position(1); my $occupancy = $Sites[$i]->Occupancy(); $out->printf("%2s %5.4f %5.4f %5.4f %5.4f\n", $AtomName, $x, $y, $z, $occupancy); } $out->print("\n"); $out->print("0 ! Debye characteristic temperature (K)\n"); $out->print("0 ! Thermal expansion coefficient (10^-6/K)\n"); $out->Close(); print "Save LauePt structure file: Finished\n"; } sub Save { my ($this) = @_; return if(!defined $this->{pDiffraction}); my $pDiffraction = $this->{pDiffraction}; my $phkl = $pDiffraction->phklArray(); my $pWL = $pDiffraction->pWLArray(); my $pQ2 = $pDiffraction->pQ2Array(); my $ppF = $pDiffraction->ppFArray(); my $pI = $pDiffraction->pIntensityArray(); my $prI = $pDiffraction->prIntensityArray(); my $pISource = $pDiffraction->pISourceArray(); my $pX = $pDiffraction->pScreenXArray(); my $pY = $pDiffraction->pScreenYArray(); my $ParameterFile = $this->{ini}->{ParameterFile}; my ($drive, $directory, $filename, $ext, $lastdir, $filebody) = Deps::SplitFilePath($ParameterFile); my $path = "$drive$directory${filebody}-Diffractions.csv"; print "Save diffraction parameters to [$path].\n"; my $out = new JFile($path, "w"); if(!$out) { $this->print("Error: Can not write to [$path].\n"); return; } $out->print("h,k,l,WL,Q2,I(source),Fr,Fi,F,I,rI,X,Y\n"); my $n = @$phkl; for(my $i = 0 ; $i < $n ; $i++) { my $hklArray = $phkl->[$i]; my $FArray = $ppF->[$i]; my ($h, $k, $l) = @$hklArray; my ($Fr, $Fi, $F) = @$FArray; my $ISource = 1; $ISource = $pISource->[$i] if(defined $pISource->[$i]); $out->print("$h,$k,$l,$pWL->[$i],$pQ2->[$i],$ISource,$Fr,$Fi,$F,$pI->[$i],$prI->[$i],$pX->[$i],$pY->[$i]\n"); } $out->Close(); } sub SaveParameterFile { my ($this, $Option, $filepath, $name, $Frame) = @_; $filepath = $Frame->{PathEntry}->GetText() if($filepath eq ''); if($filepath eq '') { $filepath = $this->ChooseSaveFile("parameter.prm", '*.prm'); if($filepath) { $filepath = Deps::ReplaceExtension($filepath, ".prm"); $this->{ini}->{ParameterFile} = $filepath; } else { return; } } # $this->{ini}->{SampleX1} = $this->{SampleFileFrame}->{X1ListBox}->GetText(); $this->{ini}->SetIniFile($filepath, undef, 1); $this->App()->print("\nSaveParameterFile: [$filepath]\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 $RecordedPath = $this->{ini}->{ParameterFile}; $this->{ini}->{CIFFile} = $this->GetValidDataPath($this->{ini}->{CIFFile}, $filepath, $RecordedPath) if($this->{ini}->{CIFFile}); $this->{ini}->{XRDFile} = $this->GetValidDataPath($this->{ini}->{XRDFile}, $filepath, $RecordedPath) if($this->{ini}->{XRDFile}); $this->{ini}->{ImageFile} = $this->GetValidDataPath($this->{ini}->{ImageFile}, $filepath, $RecordedPath) if($this->{ini}->{ImageFile}); $this->{ini}->{SourceSpectrumFile} = $this->GetValidDataPath($this->{ini}->{SourceSpectrumFile}, $filepath, $RecordedPath) if($this->{ini}->{SourceSpectrumFile}); $this->{ini}->{ParameterFile} = $filepath; my $DataFrame = $this->{SampleFileFrame}; # $DataFrame->{X1ListBox}->SetText($this->{ini}->{SampleX1}) if($this->{ini}->{SampleX1}); 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; } if($this->{ini}->{CIFFile}) { $this->ReadCIFFile($this->{ini}->{CIFFile}); } if($this->{ini}->{XRDFile}) { $this->ReadXRDFile($this->{ini}->{XRDFile}); } if($this->{ini}->{ImageFile}) { my $mag = $this->{ini}->{PhotoK0}; $this->ReadImageFile($this->{ini}->{ImageFile}); $this->{ini}->{PhotoK0} = $mag; $this->ImageResize(); } if($this->{ini}->{SourceSpectrumFile}) { $this->ReadSourceSpectrumFile($this->{ini}->{SourceSpectrumFile}); } if($this->{ini}->{DiffractionColor}) { $this->{DiffractionColorButton}->configure(-background => $this->{ini}->{DiffractionColor}); } if($this->{ini}->{ExtinctionColor}) { $this->{ExtinctionColorButton}->configure(-background => $this->{ini}->{ExtinctionColor}); } $this->SetWavelength(); # $this->RePlot(0, 1, 0, 0); # $this->RefreshViewRangePane($this->{EntryWidth}); # $this->RePlot(1, 0, 1, 1); $this->RePlot(1, 1, 1, 1); return 1; } sub GuessXRDScale { my ($this) = @_; my $ini = $this->{ini}; my $pObsY = $this->{XRDObsIntensity}; my $pCalY = $this->{pDiffraction}->pXRDIntensity(); return if(!$pObsY or !$pCalY); my ($MaxObs, $MaxCal) = (0, 0); for(my $i = 0 ; $i < @$pObsY ; $i++) { my $y = $pObsY->[$i]; $MaxObs = $y if($y > $MaxObs); } for(my $i = 0 ; $i < @$pCalY ; $i++) { my $y = $pCalY->[$i]; $MaxCal = $y if($y > $MaxCal); } $ini->{XRDScale} *= $MaxObs / $MaxCal; } sub CreateGraphFrame { my ($this, $canvas, $TargetData, $DoUpdate) = @_; return if(!$DoUpdate and $this->GetGraphFrameArray()); my $Target = $this->{Target}; return if(!defined $Target); $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 $XScale0 = $GraphFrame0->GetXScale(0); my $YScale0 = $GraphFrame0->GetYScale(0); $XScale0->SetScaleStringVisible(1); $XScale0->SetCaptionVisible(1); $GraphFrame0->SetViewRange(0, 0, 1, 1); if($Target eq 'ASF') { $GraphFrameArray->AddGraphFrame(); my $FramePosStr0 = $App->{GraphFrame0Position}; $GraphFrame0->SetPositionByStr($FramePosStr0); my $GraphFrame1 = $GraphFrameArray->GetGraphFrame(1); my $FramePosStr1 = $App->{GraphFrame1Position}; $GraphFrame1->SetPositionByStr($FramePosStr1); $GraphFrame1->SetViewRange(0, 0, 1, 1); } elsif($Target =~ /(Source)/i) { my $FramePosStr0 = $App->{GraphFrame0Position}; $GraphFrame0->SetPositionByStr($FramePosStr0); } elsif($Target =~ /(XRD)/i) { $GraphFrameArray->AddGraphFrame(); my $FramePosStr0 = $App->{GraphFrame3Position}; $GraphFrame0->SetPositionByStr($FramePosStr0); my $GraphFrame1 = $GraphFrameArray->GetGraphFrame(1); my $FramePosStr1 = $App->{GraphFrame4Position}; $GraphFrame1->SetPositionByStr($FramePosStr1); $GraphFrame1->SetViewRange(0, 0, 1, 1); $XScale0->SetScaleStringVisible(0); $XScale0->SetCaptionVisible(0); my $XScale1 = $GraphFrame1->GetXScale(0); my $YScale1 = $GraphFrame1->GetYScale(0); $XScale1->SetScaleStringVisible(1); $XScale1->SetCaptionVisible(1); $YScale1->SetScaleStringVisible(0); $YScale1->SetCaptionVisible(0); $GraphFrame0->AddSynchronousFrame('x', $GraphFrame1); $GraphFrame1->AddSynchronousFrame('x', $GraphFrame0); } elsif($Target =~ /(TED|RHEED|LEED|Laue)/i) { my $FramePosStr0 = $App->{GraphFrame2Position}; $GraphFrame0->SetPositionByStr($FramePosStr0); } else { print "Error in CreateGraphFrame: Invalid Target [$Target].\n"; return; } 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 $this->{Target}); my $Target = $this->{Target}; my $GraphFrameArray = $this->GetGraphFrameArray(); my $GraphFrame0 = $GraphFrameArray->GetGraphFrame(0); $GraphFrame0->ClearAllData(); my ($W, $H, $D) = $this->{pDiffraction}->ScreenGeometry(); if(defined $H and $W > $H) { $H = $W; } else { $W = $H; } my $GraphFrame1; my ($pX, $pY1, $pY2); if($Target eq 'ASF') { $GraphFrame0->SetXCaption("s = sinQ/lambda (nm-1)"); $GraphFrame0->SetYCaption("Re(asf)"); $GraphFrame1 = $GraphFrameArray->GetGraphFrame(1); $GraphFrame1->ClearAllData(); $GraphFrame1->SetXCaption("s = sinQ/lambda (nm-1)"); $GraphFrame1->SetYCaption("Im(asf)"); $pX = $this->{pASFX}; $pY1 = $this->{pASFRe}; $pY2 = $this->{pASFIm}; my $nData = @$pX; if($pX) { $GraphFrame0->AddGraphData($pX, $pY1, 2, "black", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "Re(asf)") if($pY1); $GraphFrame1->AddGraphData($pX, $pY2, 2, "black", "", 6, "red", 0, "red", "XAutoSkip", "Energy", "Im(asf)") if($pY2); } $GraphFrame0->CalMinMax(); $GraphFrame1->CalMinMax(); $GraphFrame0->SetXScalePlotType('x'); $GraphFrame0->SetYScalePlotType('x'); $GraphFrame1->SetXScalePlotType('x'); $GraphFrame1->SetYScalePlotType('x'); if($ResetViewRange) { $this->SetViewRange($ResetViewRange); $GraphFrame1->SetViewYRange($pY2->[0] * 0.9, $pY2->[0] * 1.1); } } elsif($Target eq 'Source') { return if(!defined $this->{pSourceSpectrum}); $GraphFrame0->SetXCaption("Wavelength / A"); $GraphFrame0->SetYCaption("Relative intensity"); $pX = $this->{pSourceSpectrum}->GetXData("Wave.*"); $pY1 = $this->{pSourceSpectrum}->GetYData("Int.*"); my $nData = @$pX; if($pX) { $GraphFrame0->AddGraphData($pX, $pY1, 2, "black", "", 6, "red", 0, "red", "XAutoSkip", "Wavelength / A", "Intensity") if($pY1); } $GraphFrame0->CalMinMax(); $GraphFrame0->SetXScalePlotType('x'); $GraphFrame0->SetYScalePlotType('x'); $this->SetViewRange($ResetViewRange); } elsif($Target eq 'XRD') { $GraphFrame1 = $GraphFrameArray->GetGraphFrame(1); $GraphFrame1->ClearAllData(); $GraphFrame1->SetXCaption("2Theta / deg"); $GraphFrame0->SetYCaption("Intensity (a.u.)"); $GraphFrame1->SetYCaption(""); my $pObsX = $this->{XRDObsQ}; my $pObsY = $this->{XRDObsIntensity}; #print "Obs: $pObsX, $pObsY\n"; if($pObsX) { $GraphFrame0->AddGraphData($pObsX, $pObsY, 0, "", "circle", 3, "white", 1, "red", "XAutoSkip", "2Theta", "Intensity(a.u.)") if($pObsY); } $pX = $this->{pDiffraction}->pXRDQ2(); $pY1 = $this->{pDiffraction}->pXRDIntensity(); if($pX) { my $nData = @$pX; $GraphFrame0->AddGraphData($pX, $pY1, 1, "black", "", 6, "red", 0, "red", "XAutoSkip", "2Theta", "Intensity(a.u.)") if($pY1); } $GraphFrame0->CalMinMax(); $GraphFrame1->CalMinMax(); $GraphFrame0->SetXScalePlotType('x'); $GraphFrame0->SetYScalePlotType('x'); $GraphFrame1->SetXScalePlotType('x'); $GraphFrame1->SetYScalePlotType('x'); $this->SetViewRange($ResetViewRange); $GraphFrame0->SetViewXRange($ini->{Q2Start}, $ini->{Q2Stop}); $GraphFrame1->SetViewXRange($ini->{Q2Start}, $ini->{Q2Stop}); } elsif($Target =~ /(TED|RHEED|LEED|Laue)/i) { $GraphFrame0->SetXCaption(""); $GraphFrame0->SetYCaption(""); $pX = $this->{pDiffraction}->pScreenXArray(); $pY1 = $this->{pDiffraction}->pScreenYArray(); my $pI1 = $this->{pDiffraction}->pIntensityArray(); my $pTag = $this->{pDiffraction}->pTagArray(); my $nData = @$pX; if($pX) { $GraphFrame0->AddDiffractionData($pX, $pY1, $pI1, $pTag, sub { $this->HoverItem($Target, @_); }, "circle", $ini->{MaxDiffractionSpotSize}, $ini->{DiffractionColor}, "circle", $ini->{ExtinctionSpotSize}, $ini->{ExtinctionColor}, "X", "Y") if($pY1); } $GraphFrame0->CalMinMax(); $GraphFrame0->SetXScalePlotType('x'); $GraphFrame0->SetYScalePlotType('x'); if($ResetViewRange) { $this->SetViewRange($ResetViewRange); if($Target =~ /(RHEED)/i) { $GraphFrame0->SetViewRange(-$W/2.0, 0.0, $W/2.0, $H); } else { $GraphFrame0->SetViewRange(-$W/2.0, -$H/2.0, $W/2.0, $H/2.0); } } } else { print "Error in AssignGraphData: Invalid Target [$Target].\n"; return; } } sub Image { my ($this, $canvas, $TargetData) = @_; return if(!defined $this->{pImage}); my $Target = $this->{Target}; return if(defined $Target and $Target !~ /(RHEED|LEED|TED|Laue)/i); my $mw = $this->mw(); my $App = $this->App(); my $ini = $this->{ini}; return unless($ini->{ImageFile}); $canvas = $this->Canvas() if(!defined $canvas);; my $w = $canvas->width(); my $h = $canvas->height(); $canvas->ClearAll(); $mw->RefreshCanvas(); my $X0 = $ini->{PhotoX0}; my $Y0 = $ini->{PhotoY0}; my $K0 = $ini->{PhotoK0}; my $Kx0 = $ini->{PhotoKx0} * $K0; my $Ky0 = $ini->{PhotoKy0} * $K0; my $image; if($this->{FixImageMagnification}) { my $filename = $this->{ConvertedImageFile}; $image = $mw->Photo( -format => 'jpeg', -file => $filename ); my $w = $image->width(); my $h = $image->height(); $App->print("image: $w x $h from [$filename]\n"); } else { my $height = $this->{pImage}->height(); my $width = $this->{pImage}->width(); $App->print("image: $width x $height magnified by ($Kx0, $Ky0)\n"); $image = $mw->Photo(-width => $width*$Kx0, -height => $height*$Ky0); # $image->copy($this->{pImage}, -from => 0, 0, $width, $height, -to => 0, 0, $width*$Kx0, $height*$Ky0); if($Kx0 > 1.0 or $Ky0 > 1.0) { $image->copy($this->{pImage}, -zoom => $Kx0, $Ky0); } else { $image->copy($this->{pImage}, -shrink); } } $canvas->createImage($X0, $Y0, -image => $image, -anchor => 'nw', ); } sub Draw { my ($this, $canvas, $TargetData) = @_; my $mw = $this->mw(); my $App = $this->App(); my $ini = $this->{ini}; my $Target = $this->{Target}; $canvas = $this->Canvas() if(!defined $canvas);; my $w = $canvas->width(); my $h = $canvas->height(); my $font = $App->{GraphFrameFont}; my @font = split(/,/, $font) if($font); $canvas->ClearAll(); $mw->RefreshCanvas(); if(!defined $Target or $Target =~ /(RHEED|LEED|TED|Laue)/i and $ini->{ImageFile}) { $this->Image(); } if(defined $Target and $Target eq 'XRD' and (!defined $this->{pDiffraction} or !$this->{pDiffraction}->pData()) and (!defined $this->{XRDObsQ} or !$this->{XRDObsQ}) ) { return; } my $GraphFrameArray = $this->GetGraphFrameArray(); return unless($GraphFrameArray); if($font) { $canvas->SetFont(\@font); $GraphFrameArray->SetFont(\@font); } $GraphFrameArray->SetCanvasSize($w, $h); $this->mw()->WriteStatusBar("Drawing..."); $mw->Balloon()->detach($canvas); $GraphFrameArray->Draw($canvas); if($Target eq 'XRD') { my $PeakFrame = $GraphFrameArray->GetGraphFrame(1); my ($x0, $y0, $x1, $y1) = $PeakFrame->GetPosition(); my $BarBoxHeight = abs($y1 - $y0); my $BarLength = int($BarBoxHeight * 0.8); my $pQ2 = $this->{pDiffraction}->pQ2Array(); my $phkl = $this->{pDiffraction}->phklArray(); my $ppF = $this->{pDiffraction}->ppFArray(); my $prI = $this->{pDiffraction}->prIntensityArray(); my $pTag = $this->{pDiffraction}->pTagArray(); my %TagHash; my $nPeak = ($pQ2)? @$pQ2 : 0; my $ybase = $y1;# + $BarBoxHeight; for(my $i = 0 ; $i < $nPeak ; $i++) { my $phklArray = $phkl->[$i]; my $ppFArray = $ppF->[$i]; my ($h, $k, $l) = @$phklArray; my ($Fr, $Fi, $F) = @$ppFArray; my $Q2 = $pQ2->[$i]; my ($xa, $ya) = $PeakFrame->ValueToPosition($Q2, 0); my $ybasea = $ybase + $BarBoxHeight * 0.8; if($x0 < $xa and $xa < $x1) { my $stra = $pTag->[$i]; my $taga = "Position_${h}_${k}_${l}"; $TagHash{$taga} = $stra; my $color = "red"; $color = "grey" if($F < 1.0e-3); my $a = $canvas->DrawLine($xa, $ybasea, $xa, $ybasea-$BarLength, 1, $color, $taga); my %pDataInf; $pDataInf{index} = $i; $pDataInf{vx} = $Q2; $pDataInf{vy} = 0; $pDataInf{x} = $xa; $pDataInf{y} = $ya; $pDataInf{Tag} = $stra; $canvas->bind($taga, "", sub { $this->HoverItem($Target, "Enter", \%pDataInf); }); #$stra, $xa]); $canvas->bind($taga, "", sub { $this->HoverItem($Target, "Leave", \%pDataInf); }); #$stra, $xa]); } } $this->mw()->Balloon()->attach($canvas, -balloonposition => 'mouse', -msg => \%TagHash); } $this->mw()->WriteStatusBar("Finish Drawing."); } #============================================================ # bind応答関数 #============================================================ sub AdjustViewRange { my ($this) = @_; my $GraphFrameArray = $this->GetGraphFrameArray(); my $pGraphFrame = $GraphFrameArray->GetpGraphFrameArray(); my ($xmin, $xmax) = $pGraphFrame->[0]->GetViewXRange(); my $nGraphFrame = 2; for(my $i = 1 ; $i < $nGraphFrame ; $i++) { next unless($pGraphFrame->[$i]); my ($xmin0, $xmax0) = $pGraphFrame->[$i]->GetViewXRange(); $xmin = $xmin0 if($xmin0 < $xmin); $xmax = $xmax0 if($xmax < $xmax0); } for(my $i = 0 ; $i < @$pGraphFrame ; $i++) { next unless($pGraphFrame->[$i]); $pGraphFrame->[$i]->SetViewXRange($xmin, $xmax); # $pGraphFrame->[$i]->RecalcScale(); } } sub HoverItem { my ($this, $Target, $event, $pDataInf) = @_; return if($this->{EnteringHoverItem}); $this->{EnteringHoverItem} = 1; my $str = $pDataInf->{Tag}; $str =~ s/[\r\n]/ /g; if($Target =~ /(TED|RHEED|LEED|Laue)/i) { print "Diffraction: $str\n"; } else { if($event eq 'Enter') { my $x = $pDataInf->{x}; my $GraphFrameArray = $this->GetGraphFrameArray(); my $pGraphFrame = $GraphFrameArray->GetpGraphFrameArray(); my ($x00, $y00, $x01, $y01) = $pGraphFrame->[0]->GetPosition(); my ($x10, $y10, $x11, $y11) = $pGraphFrame->[1]->GetPosition(); # $this->Canvas()->DrawLine($x, $y01, $x, $y00, 1, "grey", "SelPeakPosition"); $this->mw()->WriteStatusBar($str); $str =~ s/[\r\n]/ /g; print "Peak: $str\n"; } elsif($event eq 'Leave') { # $this->Canvas()->delete("SelPeakPosition"); $this->mw()->WriteStatusBar(''); } } $this->{EnteringHoverItem} = 0; } sub ConfigureIniFileVariables { my ($this) = @_; my $App = $this->App(); $App->ConfigureIniFileVariables(); my $Style = $App->Args()->GetGetArg("style"); $Style = "General" unless($Style); $App->AddIniFileVariable("\\$Style\\GraphFrameXRD0_Position", "GraphFrame3Position", "r0.20,0.60,0.80,0.15"); $App->AddIniFileVariable("\\$Style\\GraphFrameXRD1_Position", "GraphFrame4Position", "r0.20,0.65,0.80,0.60"); $App->ReadSetting(); } 1;