/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ # This file is part of TrimSPGUI. # # TrimSPGUI is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # TrimSPGUI is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with TrimSPGUI. If not, see . # # Copyright 2009 by Zaher Salman and the LEM Group. # void TrimSPGUI::ToggleScanSingle() { # Toggle between scan/single run mode # First collect some information my %All=(); $All{"ScanSeq"}=ScanSeq->isChecked(); $All{"ERadio"}=ERadio->isChecked(); $All{"SigERadio"}=SigERadio->isChecked(); $All{"AngleRadio"}=AngleRadio->isChecked(); $All{"SigAngleRadio"}=SigAngleRadio->isChecked(); $All{"NProjRadio"}=NProjRadio->isChecked(); $All{"dRadio"}=dRadio->isChecked(); $All{"ScandL"}=ScandL->text(); $All{"ListRadio"}=ListRadio->isChecked(); $All{"LoopRadio"}=LoopRadio->isChecked(); $All{"NL"}=NL->text(); # Enable everything E->setDisabled(0); # E->setText("2000"); SigE->setDisabled(0); # SigE->setText("450"); Angle->setDisabled(0); # Angle->setText("0"); SigAngle->setDisabled(0); # SigAngle->setText("15"); NProj->setDisabled(0); # NProj->setText("10000"); for (my $i=1;$i<=$All{"NL"};$i++) { my $LayerAttrib = layerTable->item($i-1,2); $LayerAttrib->setEnabled(1); } # Enable depth increment for Energy scan only if ($All{"ERadio"} & $All{"ListRadio"}) { dzListLabel->setHidden(0); ScanListdz->setHidden(0); dzListLabel->setDisabled(0); ScanListdz->setDisabled(0); dzListLabel->setText("Corresponding depth increment (optional)"); } elsif ($All{"SigAngleRadio"} & $All{"ListRadio"}) { dzListLabel->setHidden(0); ScanListdz->setHidden(0); dzListLabel->setDisabled(0); ScanListdz->setDisabled(0); dzListLabel->setText("Corresponding energy"); } else { dzListLabel->setHidden(1); ScanListdz->setHidden(1); dzListLabel->setDisabled(1); ScanListdz->setDisabled(1); } if ($All{"ScanSeq"}==1) { # But if we are in scan mode disable the appropriate box # Start by enabling everything E->setDisabled(0); SigE->setDisabled(0); Angle->setDisabled(0); SigAngle->setDisabled(0); NProj->setDisabled(0); layerTable->setColumnReadOnly(2,0); # then disable one if ($All{"ERadio"}) { E->setDisabled(1); } elsif ($All{"SigERadio"}) { SigE->setDisabled(1); } elsif ($All{"AngleRadio"}) { Angle->setDisabled(1); } elsif ($All{"SigAngleRadio"}) { SigAngle->setDisabled(1); } elsif ($All{"NProjRadio"}) { NProj->setDisabled(1); } elsif($All{"dRadio"}) { my $LayerAttrib = layerTable->item($All{"ScandL"}-1,2); $LayerAttrib->setEnabled(0); } # and change title of tab to say enabled tabs->changeTab( ScansTab, trUtf8("Scans (Enabled)") ); } else { # Otherwise the title of the tab says disabled tabs->changeTab( ScansTab, trUtf8("Scans (Disabled)") ); } } void TrimSPGUI::PrepLayers() { my %All=(); $All{"NL"}=NL->text(); # Prepare enough Rows in table for layers my $OldNL=layerTable->numRows(); if ($OldNL<=$All{"NL"}) { layerTable->setNumRows($All{"NL"}); } else { for (my $i=$All{"NL"};$i<=$OldNL-1;$i++) { removeRowFromTable($i); } } } # layerTable->horizontalHeader()->setResizeMode(Qt::HeaderView::Stretch); # layerTable->adjustColumn(0); # layerTable->adjustColumn(1); # layerTable->adjustColumn(2); } void TrimSPGUI::removeRowFromTable() { # This function is to remove rows from table # I cannot use the standard removeRow() due to a bug in perl-qt3 # This is a good and simple workaround. # Takes as an input the row number to be removed my ($deadRow) = @_; # Loop over columns and take items of the row to remove for my $col (0..layerTable->numCols()-1) { my $dummy=layerTable->item($deadRow, $col); # In the items is not defined the row can be removed by simply # reducing the number of rows in table if ($dummy ne "") { layerTable->takeItem(layerTable->item($deadRow, $col)); for my $row ($deadRow..layerTable->numRows()-2) { my $item = layerTable->item($row+1, $col); layerTable->takeItem($item); layerTable->setItem($row, $col, $item); } } } layerTable->setNumRows(layerTable->numRows()-1); } void TrimSPGUI::ProjSmartDefaults() { my %All=(); # Get typeof projectile $All{"ProjType"}=ProjType->currentText(); if ($All{"ProjType"} eq "Muon") { # For a muon set Sigma E=450 eV and Sigman angle=15 degrees by default SigE->setText("450"); SigAngle->setText("15"); } elsif ( $All{"ProjType"} eq "Li8") { # For Li8 set Sigma E=0 eV and Sigam angle=0 degrees by default SigE->setText("0"); SigAngle->setText("0"); } } void TrimSPGUI::OpenHelpWindow() { my $HelpText=" This is a GUI that uses the Trim.SP simulation binary to calculate the implantation profiles of implanted projectiles in a multilayer thin film structure. Usage: Initially define your multilayer structure in the 'Layers' tab. This can be formed of a maximum of 7 layers. Each layer is defined by giving its chemical formula, its density in units of g/cm^3, and its thickness in Ångström. Next, choose the type of projectile to be implanted in the structure from the drop-down menu. Set the 'Number of projectiles' to be implanted, were a higher number will give better statistics. Finally define the rest of the pro- jectile parameters such as implantation energy, energy spread, etc. In the 'File names prefix' give a string which will be used to construct the input/output file names of the simulation. These files will be collected and saved in the subdirectory provided in 'Save in subdirectory' box. The 'Additional Parameters' tab allows you to change additional parameters in the simulation. Change these only if you know what you are doing, and have read the original documentation of the Trim.SP simulation. The 'Scans' tabs provides the ability to change the value of a certain parameter in the simulation, such as implantation energy, spread in energy, number of implanted projectiles, and the thickness of one layer. The values of this parameter can be changed by a regualr step size ('Loop' checkbox and parameters), or following a set of values ('List of values' checkbox and the comma separated values). In the second case, in addition to the scanned parameter, the user may be given an option to change another parameter. For example, when scanning through a list of energies, the user may give a corresponding depth increment for each energy value. Copyright 2009-2011 (C) by Zaher Salman and the LEM Group Last modified 23 Sep. 2011 "; my $HelpWindow = Qt::MessageBox::information( this, "TrimSP GUI Help Window",$HelpText); } void TrimSPGUI::CollectValues() { # This subroutine returns a hash with all the values collected from the GUI. my %All=(); $All{"NL"}=NL->text(); # Collect layers parameters for (my $i=1;$i<=$All{"NL"};$i++) { my $LComp = "L".$i."Comp"; my $Lrho="L".$i."rho"; my $Ld="L".$i."d"; $All{"$LComp"}=layerTable->text($i-1,0); $All{"$Lrho"}=layerTable->text($i-1,1); $All{"$Ld"}=layerTable->text($i-1,2); } # Collect projectile parameters $All{"ProjType"}=ProjType->currentText(); $All{"NProj"}=NProj->text(); if ($All{"NProj"}==0) { $All{"NProj"}=10000; NProj->setText("10000"); } $All{"z0"}=z0->text(); $All{"dz"}=dz->text(); $All{"E"}=E->text(); $All{"SigE"}=SigE->text(); $All{"Angle"}=Angle->text(); $All{"SigAngle"}=SigAngle->text(); $All{"Seed"}=Seed->text(); # Format projectile parameters $All{"NProj"}=sprintf("%8d",$All{"NProj"}); $All{"z0"}=sprintf("%6.2f",$All{"z0"}); $All{"dz"}=sprintf("%6.2f",$All{"dz"}); $All{"E"}=sprintf("%11.2f",$All{"E"}); $All{"SigE"}=sprintf("%8.2f",$All{"SigE"}); $All{"Angle"}=sprintf("%8.2f",$All{"Angle"}); $All{"SigAngle"}=sprintf("%8.2f",$All{"SigAngle"}); $All{"Seed"}=sprintf("%6.0f.",$All{"Seed"}); # Collect the additional parameters $All{"EF"}=EF->text(); $All{"ESB"}=ESB->text(); $All{"SHEATH"}=SHEATH->text(); $All{"ERC"}=ERC->text(); $All{"RD"}=RD->text(); $All{"CA"}=CA->text(); $All{"KK0"}=KK0->text(); $All{"KK0R"}=KK0R->text(); $All{"KDEE1"}=KDEE1->text(); $All{"KDEE2"}=KDEE2->text(); $All{"IPOT"}=IPOT->text(); $All{"IPOTR"}=IPOTR->text(); $All{"IRL"}=IRL->text(); # format additional parameters $All{"EF"}=sprintf("%8.2f",$All{"EF"}); $All{"ESB"}=sprintf("%8.2f",$All{"ESB"}); $All{"SHEATH"}=sprintf("%8.2f",$All{"SHEATH"}); $All{"ERC"}=sprintf("%8.2f",$All{"ERC"}); $All{"RD"}=sprintf("%5.0f.",$All{"RD"}); $All{"CA"}=sprintf("%6.2f",$All{"CA"}); $All{"KK0"}=sprintf("%3d",$All{"KK0"}); $All{"KK0R"}=sprintf("%3d",$All{"KK0R"}); $All{"KDEE1"}=sprintf("%3d",$All{"KDEE1"}); $All{"KDEE2"}=sprintf("%3d",$All{"KDEE2"}); $All{"IPOT"}=sprintf("%3d",$All{"IPOT"}); $All{"IPOTR"}=sprintf("%3d",$All{"IPOTR"}); $All{"IRL"}=sprintf("%2d",$All{"IRL"}); # Filenames etc. The filename should not have white spaces $All{"FNPre"}=FNPre->text(); $All{"FNPre"}=~ s/\s+//g; $All{"Path"}=Path->text(); # Scan parameters only if selected $All{"ScanSeq"}=ScanSeq->isChecked(); # if ($All{"ScanSeq"}) { $All{"ERadio"}=ERadio->isChecked(); $All{"SigERadio"}=SigERadio->isChecked(); $All{"AngleRadio"}=AngleRadio->isChecked(); $All{"SigAngleRadio"}=SigAngleRadio->isChecked(); $All{"NProjRadio"}=NProjRadio->isChecked(); $All{"dRadio"}=dRadio->isChecked(); $All{"ScandL"}=ScandL->text(); # Remove any white spaces $All{"ScandL"} =~ s/\s+//g; $All{"ListRadio"}=ListRadio->isChecked(); $All{"LoopRadio"}=LoopRadio->isChecked(); $All{"ScanList"}=ScanList->text(); # Remove any white spaces $All{"ScanList"} =~ s/\s+//g; $All{"ScanListdz"}=ScanListdz->text(); # Remove any white spaces $All{"ScanListdz"} =~ s/\s+//g; # These should be numeric $All{"SFrom"}=1*SFrom->text(); $All{"STo"}=1*STo->text(); $All{"SStep"}=1*SStep->text(); # } # Return values to caller return %All; } void TrimSPGUI::CreateInpFile() { use Chem; # The proper way I think is not to have scan sequences implimented here # but rather call this multiple times to generate the scan # To resolve this, the function CreateInpFile will expect a unique thickness for each layer, # one energy value, one energy sigma and one projectile number. # These will be stored in keys L1/2/3/4/5/6/7d, E, SigE and NProj, respectively. # Chemical formulas will be parsed on the fly for each layer. However, we will check if # all the layers have inputs for composition, thickness and density. If not fail and crash :) # Values of Z,A as well as other needed parameters are obtained from Chem.pm. # This is the form of the begining of the input file: my $TemplateFile= " ProjZ ProjAM E SigE Angle SigAngle EF ESB SHEATH ERC NProj Seed Seed Seed z0 RD dz CA KK0 KK0R KDEE1 KDEE2 IPOT IPOTR IRL"; # Then comes the number of layers (new format) for example 4 layers: # N_Layers=4 $TemplateFile=$TemplateFile."\n"."N_Layers=NL"."\n"; # Then loop over the layers and for each give the following structure my $TemplateLayer= "L1d L1rho L1CK L1ELZ1 L1ELZ2 L1ELZ3 L1ELZ4 L1ELZ5 L1ELW1 L1ELW2 L1ELW3 L1ELW4 L1ELW5 L1ELC1 L1ELC2 L1ELC3 L1ELC4 L1ELC5 L1ELE1 L1ELE2 L1ELE3 L1ELE4 L1ELE5 L10301 L10302 L10303 L10304 L10305 0.0000 0.0000 0.0000 0.0000 0.0000 L1ELST11 L1ELST21 L1ELST31 L1ELST41 L1ELST51 L1ELST12 L1ELST22 L1ELST32 L1ELST42 L1ELST52 L1ELST13 L1ELST23 L1ELST33 L1ELST43 L1ELST53 L1ELST14 L1ELST24 L1ELST34 L1ELST44 L1ELST54 L1ELST15 L1ELST25 L1ELST35 L1ELST45 L1ELST55 "; # Get values from form my %All = CollectValues(); my $ProjType=$All{"ProjType"}; $All{"ProjZ"}=sprintf("%6.2f",Chem::Zof($ProjType)); $All{"ProjAM"}=sprintf("%6.2f",Chem::Massof($ProjType)); my $Check=0; my $Layer=""; my $Li=""; # Loop over layers an create appropriate values for (my $i=1;$i<=$All{"NL"};$i++){ $Li = "L".$i; $Layer = $TemplateLayer; $Layer =~ s/L1/$Li/g; $TemplateFile=$TemplateFile.$Layer; $Check=0; # Composition of layers my $LComp="L".$i."Comp"; my $Comp = layerTable->text($i-1,0); $All{$LComp} = $Comp; my %LElComp=Chem::parse_formula($Comp); if ($Comp eq "") {$Check++;} # Densities of layers my $Lrho="L".$i."rho"; my $rho = layerTable->text($i-1,1); $All{$Lrho}=sprintf("%6.2f",$rho); if ($rho eq "") {$Check++;} # Thickness of layers my $Ld ="L".$i."d"; my $d = layerTable->text($i-1,2); $All{$Ld}=sprintf("%8.2f",$d); if ($d eq "") {$Check++;} # Sanity check, is the layer supposed to have value? are they all there? if ($Check!=0) { my $ErrMsg="Error: Layer $i is empty. Expecting it to be defined!\n"; print STDERR $ErrMsg; my $HelpWindow = Qt::MessageBox::information( this, "Error!",$ErrMsg); return "ERROR"; } my $tmp = "L".$i."CK"; $All{$tmp}=sprintf("%6.2f",1.0); my $Sum = 0; foreach (keys %LElComp) { $Sum=$Sum+$LElComp{$_}; } if ($Sum==0) {$Sum=1;} my @Els = keys %LElComp; for (my $NEl=1;$NEl<=5;$NEl++) { my $El = $Els[$NEl-1]; my $LEkey = "L".$i."EL"; my $ElZ = Chem::Zof($El); my $ElW = Chem::Massof($El); my $ElC = $LElComp{$El}/$Sum; my $ElE = Chem::Elastof($El); my $El030 = 30; if ($El eq "") { $El030 = 0.0;} $All{$LEkey."Z".$NEl}=sprintf("%8.4f",$ElZ); $All{$LEkey."W".$NEl}=sprintf("%8.4f",$ElW); $All{$LEkey."C".$NEl}=sprintf("%8.4f",$ElC); $All{$LEkey."E".$NEl}=sprintf("%8.4f",$ElE); $All{"L".$i."030".$NEl}=sprintf("%8.4f",$El030); my $ElST = Chem::Stopicru($El); my @ElSTs = split (/,/,$ElST); my $j=1; foreach (@ElSTs) { $LEkey = "L".$i."ELST".$NEl.$j; $j++; $All{$LEkey}=sprintf("%11.6f",$_); } } } foreach my $key (keys %All) { if ($All{$key} ne ""){ $TemplateFile =~ s/$key/$All{$key}/; # Seed repeats three times if ($key eq "Seed") { $TemplateFile =~ s/$key/$All{$key}/g;} } } return $TemplateFile; } void TrimSPGUI::StartSequenceOne() { my %All = CollectValues(); my @SValues=(); my @SdzValues=(); my $cmd=""; if (!$ENV{'TRIMBIN'}) { # If trim.sp binary is not defined give warning and return my $Warning = Qt::MessageBox::information( this, "Warning", "Warning:\n TrimSP binary is not found.\n Define using the Configuration tab."); return(0); } # Cleanup from old files if (-e "ausgabe1.inp") { system("rm -f ausgabe*"); } my $Progress=0; if ($All{"ScanSeq"}) { # For a scan $All{"ERadio"}=ERadio->isChecked(); $All{"SigERadio"}=SigERadio->isChecked(); $All{"AngleRadio"}=AngleRadio->isChecked(); $All{"SigAngleRadio"}=SigAngleRadio->isChecked(); $All{"NProjRadio"}=NProjRadio->isChecked(); $All{"dRadio"}=dRadio->isChecked(); $All{"ScandL"}=ScandL->text(); # Remove any white spaces $All{"ScandL"} =~ s/\s+//g; $All{"ListRadio"}=ListRadio->isChecked(); $All{"LoopRadio"}=LoopRadio->isChecked(); $All{"ScanList"}=ScanList->text(); # Remove any white spaces $All{"ScanList"} =~ s/\s+//g; $All{"ScanListdz"}=ScanListdz->text(); # Remove any white spaces $All{"ScanListdz"} =~ s/\s+//g; # These should be numeric $All{"SFrom"}=1*SFrom->text(); $All{"STo"}=1*STo->text(); $All{"SStep"}=1*SStep->text(); if ($All{"ListRadio"}) { @SValues=split(/,/,$All{"ScanList"}); @SdzValues=split(/,/,$All{"ScanListdz"}); if ($#SValues == $#SdzValues) {$All{"SdzFlag"}=1;} } elsif ($All{"LoopRadio"}) { for (my $Val=$All{"SFrom"};$Val<=$All{"STo"};$Val=$Val+$All{"SStep"}) { @SValues=(@SValues,$Val); } } my $ScanName = ""; if ($All{"ERadio"}) { $ScanName = "E"; } elsif ($All{"SigERadio"}) { $ScanName = "SigE"; } elsif ($All{"AngleRadio"}) { $ScanName = "Angle"; } elsif ($All{"SigAngleRadio"}) { $ScanName = "SigAngle"; } elsif ($All{"NProjRadio"}) { $ScanName = "NProj"; } elsif ($All{"dRadio"}) { $ScanName = "Ld".$All{"ScandL"}; } my $ScanAttrib = child($ScanName); my $iScan=0; foreach (@SValues) { if ($All{"dRadio"}) { $ScanAttrib->setText($All{"ScandL"},2,$_); } else { $ScanAttrib->setText($_); } if ( $All{"SdzFlag"} == 1) { if ($All{"ERadio"}==1) { dz->setText($SdzValues[$iScan]); } elsif ($All{"SigAngleRadio"}==1) { E->setText($SdzValues[$iScan]); } } my $eingabe1=CreateInpFile(); if ($eingabe1 eq "ERROR") {return 0;} my $FILENAME=$All{"FNPre"}."_".$ScanName.$_; open (INPF,q{>}, "$FILENAME.inp" ); print INPF $eingabe1; close(INPF); # Use windoz version # system("cp $FILENAME.inp eingabe1.inp; wine TrimSP7L.exe"); # Use Linux version $Progress=$Progress+90/$#SValues; Progress->setProgress($Progress); Progress->update(); $cmd = "cp $FILENAME.inp eingabe1.inp; ".$ENV{'TRIMBIN'}; system($cmd); foreach ("err","out","rge") { system("mv -f ausgabe1.$_ $FILENAME.$_"); } # Not needed if work path is changed # $cmd="mv -f $FILENAME.* ".$All{"Path"}; # system($cmd); $iScan++; } } else { # For a single run my $eingabe1=CreateInpFile(); if ($eingabe1 eq "ERROR") {return 0;} my $FILENAME=$All{"FNPre"}; open (INPF,q{>}, "$FILENAME.inp" ); print INPF $eingabe1; close(INPF); $Progress=20; Progress->setProgress($Progress); # Use windoz version # system("cp $FILENAME.inp eingabe1.inp; wine TrimSP7L.exe"); # Use Linux version $cmd = "cp $FILENAME.inp eingabe1.inp; ".$ENV{'TRIMBIN'}; system($cmd); foreach ("err","out","rge") { system("mv -f ausgabe1.$_ $FILENAME.$_"); } $Progress=90; Progress->setProgress($Progress); # If we change work directory this is not needed # $cmd="mv -f $FILENAME.* ".$All{"Path"}; # system($cmd); } # Move the fort.33 file into the subdirectory and change its name $cmd="rm -f eingabe1.inp; mv -f fort.33 ".$All{"Path"}."/".$All{"FNPre"}."_Seq_Results.dat"; system($cmd); $Progress=100; Progress->setProgress($Progress); return 1; } void TrimSPGUI::DirectoryBrowse() { my $FileBrowser = Qt::FileDialog::getExistingDirectory("./",this,"get existing directory","Choose a directory",1); if ($FileBrowser eq "") {$FileBrowser="./";} Path->setText($FileBrowser); # Create a subdirectory where all input/output files are saved my $cmd=""; if (-d $FileBrowser) { # Directory exists, do nothing } else { $cmd="mkdir $FileBrowser"; system($cmd); } # Change work directory accordingly chdir ("$FileBrowser"); # Return a string with the directory name return $FileBrowser ; } void TrimSPGUI::ConfirmQuit() { my $Ans = Qt::MessageBox::question( this, "Quit?","Are you sure you want to quit?","&Yes","&No","",0,1); if ($Ans==0) { # Then quit Qt::Application::exit( 0 ); } # Otherwize go back # print STDOUT $ENV{'TRIMBIN'}."\n"; } void TrimSPGUI::PlotProfiles() { my $files_ref=Qt::FileDialog::getOpenFileNames( "RGE Files (*.rge)", "./", this, "Select RGE files dialog", "Choose RGE file to plot"); my @files_tmp = @$files_ref; # Do "natural" sorting on the file name list # This will produce (hopefully) a plot with largest needed depth scale my @files = grep {s/(^|\D)0+(\d)/$1$2/g,1} sort grep {s/(\d+)/sprintf"%06.6d",$1/ge,1} @files_tmp; my $filenames=join(",",@files); if ($filenames ne "" ) { # my $Warning = Qt::MessageBox::information( this, "Big Fat Warning", # "Warning:\nClose the plot using the menu FILE -> Quit ROOT\nDO NOT CLOSE USING X."); my $TrimPath = $ENV{'PERLLIB'}; # Now that we have the file list send it to root macro for plotting. my $cmd='root -n -l "'.$TrimPath.'/plotRge.C(\"'.$filenames.'\")"&'; # my $pid = open(FTO,"$cmd"); # my $pid = open(FTO,"$cmd 2>&1 |"); # print "PID=$pid\n"; # while () { # print "$_"; # } # close(FTO); my $pid=system($cmd); } } void TrimSPGUI::PlotFraction() { my $file=Qt::FileDialog::getOpenFileName( ".", "Implantation sequence file (*.dat)", this, "open sequence data file dialog", "Choose a sequence data file"); if ($file ne "" ) { my $TrimPath = $ENV{'PERLLIB'}; # Now that we have the file name send it to root macro for plotting. my $cmd='root -n -l "'.$TrimPath.'/plotFrc.C(\"'.$file.'\")"&'; my $pid=system($cmd); } } void TrimSPGUI::OpenAboutWindow() { my $HelpText="TrimSPGUI is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. TrimSPGUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with TrimSPGUI. If not, see . Copyright 2009 by Zaher Salman and the LEM Group. "; my $HelpWindow = Qt::MessageBox::about( this, "About TrimSP GUI",$HelpText); } void TrimSPGUI::OpenFile() { # Types of different input my %Types = (); # 0 - text (this is default), 1 - spin box, 2 - radio button, 3 - combo box $Types{"NL"}=1 ; $Types{"ProjType"}= 3; $Types{"ScanSeq"}= 2; $Types{"ERadio"}= 2; $Types{"SigERadio"}= 2; $Types{"AngleRadio"}= 2; $Types{"SigAngleRadio"}= 2; $Types{"NProjRadio"}= 2; $Types{"dRadio"}= 2; $Types{"ScandL"}= 1; $Types{"ListRadio"}= 2; $Types{"ScanListdz"}= 0; $Types{"LoopRadio"}= 2; my $file=Qt::FileDialog::getOpenFileName( ".", "Initialization file (.* *.*)", this, "open file dialog", "Choose an initialization file"); # If the user gave a valid filename try to read it if ($file ne "") { open (INF,q{<},"$file" ); my @lines = ; close(INF); my $Attrib=""; foreach my $line (@lines) { # Remove white spaces $line =~ s/\s+//g; my @InitPar = split (/=/,$line); # Check it is not empty or title line if ($InitPar[0] ne "" && $InitPar[1] ne "") { # First take care of the layers, with patters L?Comp, L?rho, L?d my $CRow=$InitPar[0]; if ($InitPar[0] =~ m/L.*Comp$/ ) { $CRow =~ s/\D//g; layerTable->setText($CRow-1,0,$InitPar[1]); } elsif ($InitPar[0] =~ m/L.*rho$/ ) { $CRow =~ s/\D//g; layerTable->setText($CRow-1,1,$InitPar[1]); } elsif ($InitPar[0] =~ m/L.*d$/ ) { $CRow =~ s/\D//g; layerTable->setText($CRow-1,2,$InitPar[1]); } else { $Attrib = child($InitPar[0]); if ($Types{$InitPar[0]} == 1) { $Attrib->setValue($InitPar[1]); # Create enough rows in layerTable if ($InitPar[0] eq "NL") { layerTable->setNumRows($InitPar[1]); } } elsif ($Types{$InitPar[0]} == 2 ) { if($InitPar[1] == 1) { $Attrib->setChecked(1); } else { $Attrib->setChecked(0); } } elsif ($Types{$InitPar[0]} == 3) { $Attrib-> setCurrentText($InitPar[1]); } else { $Attrib->setText($InitPar[1]); } } } } } } void TrimSPGUI::SaveFile() { my %All = CollectValues(); my $InitFile=" [Layers] NL=$All{'NL'}"; for (my $i=1;$i<=$All{"NL"};$i++){ my $Li="L".$i; my $LComp=$Li."Comp"; my $Lrho=$Li."rho"; my $Ld=$Li."d"; $InitFile=$InitFile." $LComp=$All{$LComp} $Lrho=$All{$Lrho} $Ld=$All{$Ld} "; } $InitFile=$InitFile." [ProjectileParameters] ProjType=$All{'ProjType'} NProj=$All{'NProj'} z0=$All{'z0'} dz=$All{'dz'} E=$All{'E'} SigE=$All{'SigE'} Angle=$All{'Angle'} SigAngle=$All{'SigAngle'} Seed=$All{'Seed'} [Files] FNPre=$All{'FNPre'} Path=$All{'Path'} [ScanSequence] ScanSeq=$All{'ScanSeq'} ERadio=$All{'ERadio'} SigERadio=$All{'SigERadio'} AngleRadio=$All{'AngleRadio'} SigAngleRadio=$All{'SigAngleRadio'} NProjRadio=$All{'NProjRadio'} dRadio=$All{'dRadio'} ListRadio=$All{'ListRadio'} ScanList=$All{'ScanList'} ScanListdz=$All{'ScanListdz'} LoopRadio=$All{'LoopRadio'} SFrom=$All{'SFrom'} STo=$All{'STo'} SStep=$All{'SStep'} "; # Save to default file name "TriumSP.cfg" my $file = "TrimSP.cfg"; open (OUTF,q{>},"$file" ); print OUTF (" $InitFile"); close(OUTF); } void TrimSPGUI::SaveFileAs() { my %All = CollectValues(); my $InitFile=" [Layers] NL=$All{'NL'}"; for (my $i=1;$i<=$All{"NL"};$i++){ my $Li="L".$i; my $LComp=$Li."Comp"; my $Lrho=$Li."rho"; my $Ld=$Li."d"; $InitFile=$InitFile." $LComp=$All{$LComp} $Lrho=$All{$Lrho} $Ld=$All{$Ld} "; } $InitFile=$InitFile." [ProjectileParameters] ProjType=$All{'ProjType'} NProj=$All{'NProj'} z0=$All{'z0'} dz=$All{'dz'} E=$All{'E'} SigE=$All{'SigE'} Angle=$All{'Angle'} SigAngle=$All{'SigAngle'} Seed=$All{'Seed'} [Files] FNPre=$All{'FNPre'} Path=$All{'Path'} [ScanSequence] ScanSeq=$All{'ScanSeq'} ERadio=$All{'ERadio'} SigERadio=$All{'SigERadio'} AngleRadio=$All{'AngleRadio'} SigAngleRadio=$All{'SigAngleRadio'} NProjRadio=$All{'NProjRadio'} dRadio=$All{'dRadio'} ListRadio=$All{'ListRadio'} ScanList=$All{'ScanList'} ScanListdz=$All{'ScanListdz'} LoopRadio=$All{'LoopRadio'} SFrom=$All{'SFrom'} STo=$All{'STo'} SStep=$All{'SStep'} "; my $file=Qt::FileDialog::getSaveFileName( "TrimSP.cfg", "TrimSP GUI Initialization file (*.cfg)", this, "save file dialog", "Choose a filename to save under"); # If the user gave a filename the copy to it if ($file ne "") { open (OUTF,q{>},"$file" ); print OUTF (" $InitFile"); close(OUTF); } } void TrimSPGUI::GUIPath() { # This subroutine is used to define diffirent variables my $FileBrowser = Qt::FileDialog::getExistingDirectory("./",this,"get existing directory","Choose the directory where the TrimSP GUI is.",1); # If nothing is returned keep as is if ($FileBrowser eq "") { $FileBrowser=$ENV{'PERLLIB'}; } else { $ENV{'PERLLIB'}=$FileBrowser; } TrimGUIPath->setText($FileBrowser); # Return a string with the directory name return $FileBrowser ; } sub TrimBin { my $file=Qt::FileDialog::getOpenFileName( "$ENV{'TRIMBIN'}", "Trim.SP binary (.* *.* *)", this, "open file dialog", "Select the Trim.SP binary file"); # If the user gave a valid filename try to read it if ($file eq "") { $file=$ENV{'TRIMBIN'}; } else { $ENV{'TRIMBIN'}=$file; } TRIMBIN->setText($file); return $file; } void TrimSPGUI::TrimBin() { my $file=Qt::FileDialog::getOpenFileName( "$ENV{'TRIMBIN'}", "Trim.SP binary (.* *.* *)", this, "open file dialog", "Select the Trim.SP binary file"); # If the user gave a valid filename try to read it if ($file eq "") { $file=$ENV{'TRIMBIN'}; } else { $ENV{'TRIMBIN'}=$file; } TRIMBIN->setText($file); return $file; } void TrimSPGUI::findDensity() { use Chem; # Get sender name to know which layer my $sender = sender()->name(); my $CCol=sender()->currentColumn(); if ($CCol==0) { # The composition changed, find density my $CRow=sender()->currentRow(); my $Compound=sender()->text($CRow,$CCol); # See if you have the density my $Density=Chem::Densities($Compound); # If the density is in the database submit it sender()->setText($CRow,1,$Density); } }