#======================================================== # MultiColumnData #======================================================== package MultiColumnData; use strict; use JFile; use GraphData; use CSV; eval('use Sci::Algorism'); eval('use Sci::Ellipsometry'); #my $in = new MultiColumnData; #my $in = new MultiColumnData($f, 1); #my $in = new MultiColumnData($pX, $pY); #my ($nData, $pLabelArray, @DataArray) = $in->Read($path, 0); #$in->ReadAll($filepath)) { #$in->SetXYData(\@x, \@y); #$nDataArray = $in->nDataArray(); #$nData = $in->{DataFile}->nData(); #($pX, $pY) = $in->SetXYDataByLabels("Energy.*", ".*DOS.*"); #$pX = $in->GetXData(0); #$pY = $in->GetYData(1); #$pX = $in->GetXData("Wave.*"); #$pY = $in->GetYData("Int.*"); #$pX = $in->{DataFile}->GetData($XLabel); #$pMCDaxx = $in->Duplicate('E.*', 'a(xx)'); #$pSortedT = $in->SortXYByX(1); #($xmin, $xmax, $ymin, $ymax) = $in->GetMinMax(); #$Ipd = $in->XVal($Ip, $xmax); #============================================================ # 変数等取得関数 #============================================================ sub ClearAll { my $this = shift; $this->{FileType} = ''; $this->{FilePath} = ''; $this->{IncidentAngle} = 0.0; $this->{SkipBlankData} = 0; } sub SkipBlankData { return shift->{SkipBlankData}; } sub SetSkipBlankData { my ($this, $f) = @_; return $this->{SkipBlankData} = $f; } sub SetpX { my($this,$p)=@_; return shift->{pX} = $p; } sub SetpY { my($this,$p)=@_; return shift->{pY} = $p; } sub pX { return shift->{pX}; } sub pY { return shift->{pY}; } sub XMin { return shift->{XMin}; } sub XMax { return shift->{XMax}; } sub YMin { return shift->{YMin}; } sub YMax { return shift->{YMax}; } sub GetXMinMax { my $this = shift; return ($this->{XMin}, $this->{XMax}); } sub GetYMinMax { my $this = shift; return ($this->{YMin}, $this->{YMax}); } sub GetMinMax { my $this = shift; return ($this->{XMin}, $this->{XMax}, $this->{YMin}, $this->{YMax}); } sub IncidentAngle { return shift->{IncidentAngle}; } sub SetIncidentAngle { my ($this,$a)=@_; ($a) = ($a =~ /([\d\.eEdD+-]+)/); return $this->{IncidentAngle} = $a; } sub Title { return shift->{Title}; } sub SetTitle { my ($this,$t)=@_; return $this->{Title} = $t; } sub FileName { return shift->{'FilePath'}; } sub SetFileName { my ($this,$f)=@_; return $this->{FilePath} = $f; } sub FilePath { return shift->{'FilePath'}; }; sub SetFilePath { my ($this,$f)=@_; return $this->{FilePath} = $f; }; sub FileType { my ($this) = @_; return '' if(!defined $this->{FileType}); return $this->{FileType}; } sub SetFileType { my ($this,$t)=@_; return shift->{FileType} = $t; } sub LabelArray { return shift->{LabelArray}; } sub SetLabelArray { my ($this,$la)=@_; return $this->{LabelArray} = $la; } sub DataArray { my ($this, $idx) = @_; return $this->{DataArray} if(!defined $idx); return $this->{DataArray}->[$idx]; } sub SetDataArray { my ($this,$da)=@_; return $this->{DataArray} = $da; } sub AddData { my ($this, $label, $pData) = @_; my $pLabelArray = $this->LabelArray(); my $pDataArray = $this->DataArray(); push(@$pLabelArray, $label); push(@$pDataArray, $pData); $this->CalMinMax(); } sub AddDataByConversion { my ($this, $label, $pData, $convfunc) = @_; my @y; my $nData = scalar @$pData; for(my $i = 0 ; $i < $nData ; $i++) { $y[$i] = Optics::nmToeV($pData->[$i]); } $this->AddData($label, \@y); } sub nDataArray { my $la = shift->LabelArray(); return scalar @$la if($la); return 0; } sub LabelIndexHash { return shift->{LabelIndexHash}; } sub SetLabelIndexHash { my ($this,$lh)=@_; return $this->{LabelIndexHash} = $lh; } sub CreateBlankDataArray { my ($this, $pLabelArray) = @_; $pLabelArray = $this->LabelArray() if(!defined $pLabelArray); my @a; for(my $i = 0 ; $i < @$pLabelArray ; $i++) { $a[$i] = []; } return $this->SetDataArray(\@a); } sub nData { my ($this, $idx) = @_; if(!defined $idx) { if($this->{pX}) { my $pX = $this->{pX}; return scalar @$pX; } else { $idx = 0; } } my $da = $this->DataArray(); return 0 if(!$da); my $d0 = $da->[$idx]; return 0 if(!$d0); return scalar @$d0; } sub X { my ($this, $idx) = @_; return $this->{pX}->[$idx]; } sub Y { my ($this, $idx) = @_; return $this->{pY}->[$idx]; } #============================================================ # 静的関数 #============================================================ sub BuildLabelIndexHash { my ($this) = @_; my $pLabelList = $this->LabelArray(); my %hash; for(my $i = 0 ; $i < @$pLabelList ; $i++) { #print "Hash: $i: $pLabelList->[$i]\n"; $hash{$pLabelList->[$i]} = $i; } return $this->SetLabelIndexHash(\%hash); } sub AddItem { my ($this, %hash) = @_; my $pLabelArray = $this->LabelArray(); my $pDataArray = $this->DataArray(); # my $pLabelIndexHash = $this->LabelIndexHash(); my $nData = $this->nData(); my @data; for(my $i = 0 ; $i < @$pLabelArray ; $i++) { my $label = $pLabelArray->[$i]; #print "$i: $label: $hash{$label}\n"; if(defined $hash{$label}) { $data[$i] = $hash{$label}; } else { $data[$i] = ''; } $pDataArray->[$i]->[$nData] = $data[$i]; } #exit; # push(@$pDataArray, \@data); my $n = $this->nData(); #print "n=$n, ", scalar @$pDataArray, "\n"; } sub GetArraysFromFile { my ($path) = @_; my $CSV = new CSV(); return (undef) if(!$CSV->Read($path)); my $pLabelArray = $CSV->LabelArray(); my $pDataArray = $CSV->DataArray(); return (0, $pLabelArray, @$pDataArray) if(!$pDataArray); my $pdata = $pDataArray->[0]; my $nData = 0; $nData = @$pdata if($pdata); return ($nData, $pLabelArray, @$pDataArray); } sub RemakeDataArrayFromFile { my ($path, $pX, $IsXStepConstant) = @_; my ($nData, $pLabelArray, @DataArray) = GetArraysFromFile($path); return undef if(!defined $nData); my @ConvDataArray; my $data = new GraphData; for(my $i = 1 ; $i < @DataArray ; $i++) { $data->SetXDataArray($i-1, $DataArray[0]); $data->SetYDataArray($i-1, $DataArray[$i]); $ConvDataArray[$i-1] = (); } $data->CalMinMax(); my (@e1, @e2); for(my $i = 0 ; $i < @$pX ; $i++) { my $x = $pX->[$i]; #print "$i: $x: "; for(my $id = 0 ; $id < @DataArray-1 ; $id++) { if($IsXStepConstant) { $ConvDataArray[$id]->[$i] = $data->YValForConstantXStep($id, $x); } else { $ConvDataArray[$id]->[$i] = $data->YVal($id, $x); } #print "$ConvDataArray[$id]->[$i] "; } #print "\n"; } return @ConvDataArray; } #============================================================ # コンストラクタ、デストラクタ #============================================================ BEGIN { } sub new { my ($module, $filename, $IsNumerical, $YLabel) = @_; my $this = {}; bless $this; #print "p=$filename\n"; if($filename =~ /^ARRAY\(/ and $IsNumerical =~ /^ARRAY\(/) { #$Data->SetXYData(\@x, \@y); $this->SetXYData($filename, $IsNumerical); } else { $this->Read($filename, $IsNumerical, $YLabel); } return $this; } sub DESTROY { my $this = shift; } #============================================================ # 一般関数 #============================================================ sub Initialize { my ($this) = @_; $this->ClearAll(); } sub Open { my ($this, $filename, $mode) = @_; if($this->{JFile}) { $this->{JFile}->Close(); undef $this->{JFile}; } return $this->{JFile} = new JFile($filename, $mode); } sub Close { my ($this) = @_; if($this->{JFile}) { $this->{JFile}->Close(); undef $this->{JFile}; } } sub CalMinMaxStep { my ($this, @labels) = @_; if(!defined $labels[0]) { my $pX = $this->{pX}; my $pY = $this->{pY}; ($this->{XMin}, $this->{XMax}) = Utils::CalMinMaxStep($pX) if($pX); ($this->{YMin}, $this->{YMax}) = Utils::CalMinMaxStep($pY) if($pY); return ($this->{XMin}, $this->{XMax}, $this->{YMin}, $this->{YMax}); } else { my $pData = $this->GetData(@labels); return Utils::CalMinMaxStep($pData) if($pData); return undef; } } sub CalMinMax { my ($this, @labels) = @_; if(!defined $labels[0]) { my $pX = $this->{pX}; my $pY = $this->{pY}; ($this->{XMin}, $this->{XMax}) = Utils::CalMinMax($pX) if($pX); ($this->{YMin}, $this->{YMax}) = Utils::CalMinMax($pY) if($pY); return ($this->{XMin}, $this->{XMax}, $this->{YMin}, $this->{YMax}); } else { my $pData = $this->GetData(@labels); return Utils::CalMinMax($pData) if($pData); return undef; } } sub HashByXDataKey { my ($this, $key, $UseRegEx, $CaseSensitive) = @_; $UseRegEx = 0 if(!defined $UseRegEx); $CaseSensitive = 1 if(!defined $CaseSensitive); my $pX = $this->{pX}; $pX = $this->GetData(0) if(!defined $pX); my $nData = @$pX; my $iHit; if(!$UseRegEx and !$CaseSensitive) { $key = lc $key; } for(my $i = 0 ; $i < $nData ; $i++) { if($UseRegEx) { if($CaseSensitive) { if($pX->[$i] =~ /$key/) { $iHit = $i; last; } } else { if($pX->[$i] =~ /$key/i) { $iHit = $i; last; } } } else { if($CaseSensitive) { if($pX->[$i] eq $key) { $iHit = $i; last; } } else { if(lc $pX->[$i] eq $key) { $iHit = $i; last; } } } } return () if(!defined $iHit); return $this->HashByIndex($iHit); } sub HashByIndex { my ($this, $idx) = @_; my $pLabelArray = $this->LabelArray(); # my $pData = $this->GetData($idx); my %Hash; for(my $i = 0 ; $i < @$pLabelArray ; $i++) { #print " $i: $pLabelArray->[$i]: $pData->[$i]\n"; $Hash{$pLabelArray->[$i]} = $this->GetData($i)->[$idx]; #$pData->[$i]; } return \%Hash; } sub ValByIndex { my ($this, $idx, $i) = @_; my $pData = $this->GetData($idx); return $pData->[$i]; } sub XValByIndex { my ($this, $i) = @_; return $this->{pX}[$i]; } sub YValByIndex { my ($this, $i) = @_; return $this->{pY}[$i]; } sub XVal { my ($this, $pX, $pY, $y, $EPS, $nMaxIter, $xmin, $xmax, $xinit, $dx, $Debug) = @_; if($pX !~ /^ARRAY\(/) { ($this, $y, $EPS, $nMaxIter, $xmin, $xmax, $xinit, $dx, $Debug) = @_; $pX = $this->{pX}; $pY = $this->{pY}; } $EPS = 1.0e-6 if(!defined $EPS); $nMaxIter = 100 if(!defined $nMaxIter); ($xmin, $xmax) = Utils::CalMinMax($pX) if(!defined $xmin or !defined $xmax); $dx = ($xmax - $xmin) * 0.01 if(!defined $dx); $xinit = 0.5 * ($xmin + $xmax) if(!defined $xinit); # return $this->XValByBinaryMethod($pX, $pY, $y, $EPS, $nMaxIter, $xmin, $xmax, $xinit, $dx, $Debug); return $this->XValByNewtonMethod($pX, $pY, $y, $EPS, $nMaxIter, $xmin, $xmax, $xinit, $dx, $Debug); } sub XValByNewtonMethod { my ($this, $pX, $pY, $y, $EPS, $nMaxIter, $xmin, $xmax, $xinit, $dx, $Debug) = @_; if($pX !~ /^ARRAY\(/) { ($this, $y, $EPS, $nMaxIter, $xmin, $xmax, $xinit, $dx, $Debug) = @_; $pX = $this->{pX}; $pY = $this->{pY}; } $EPS = 1.0e-6 if(!defined $EPS); $nMaxIter = 100 if(!defined $nMaxIter); ($xmin, $xmax) = Utils::CalMinMax($pX) if(!defined $xmin or !defined $xmax); $dx = ($xmax - $xmin) * 0.01 if(!defined $dx); $xinit = 0.5 * ($xmin + $xmax) if(!defined $xinit); $Debug = 0 if(!defined $Debug); my $x = $xinit; for(my $i = 0 ; $i <= $nMaxIter ; $i++) { if($i >= $nMaxIter) { print "Error in MultiColumnData::XValByNewtonMethod: Not converged in $nMaxIter iteration to EPS=$EPS.\n" if($Debug); return undef; } if($x < $xmin or $xmax < $x) { print "Error in MultiColumnData::XValByNewtonMethod: X [$x] gets out from the data range [$xmin - $xmax].\n" if($Debug); return undef; } my $y0 = $this->YVal($pX, $pY, $x); my $error =abs($y0 - $y); if($error < $EPS) { print "Convergence reached at iter=$i within EPS=$error [$EPS].\n" if($Debug); last; } my $y1 = $this->YVal($pX, $pY, $x + $dx); my $dydx = ($y1 - $y0) / $dx; $x -= ($y0 - $y) / $dydx; } return $x; } sub XValByBinaryMethod { my ($this, $pX, $pY, $y, $EPS, $nMaxIter, $xmin, $xmax, $dx, $Debug) = @_; if($pX !~ /^ARRAY\(/) { ($this, $y, $EPS, $nMaxIter, $xmin, $xmax, $dx, $Debug) = @_; $pX = $this->{pX}; $pY = $this->{pY}; } $EPS = 1.0e-6 if(!defined $EPS); $nMaxIter = 100 if(!defined $nMaxIter); ($xmin, $xmax) = Utils::CalMinMax($pX) if(!defined $xmin or !defined $xmax); $dx = ($xmax - $xmin) * 0.01 if(!defined $dx); $Debug = 0 if(!defined $Debug); my $nData = @$pX; my $i = -1; while(1) { $i++; if($i > $nMaxIter) { print "Error in MultiColumnData::XValByBinaryMethod: Not converged in $nMaxIter iteration to EPS=$EPS.\n"; return undef; } last if(abs($xmax-$xmin) < $EPS); #print "X=$pX,$pY,$xmin,$xmax\n"; my $ymin = $this->YVal($pX, $pY, $xmin); my $ymax = $this->YVal($pX, $pY, $xmax); my $xhalf = 0.5 * ($xmin + $xmax); my $yhalf = $this->YVal($pX, $pY, $xhalf); #print "y=$ymin,$ymax,$yhalf\n"; my $check0 = ($y - $ymin) * ($yhalf - $y); print " 0: $check0 = $y, $ymin / $yhalf, $y\n" if($Debug); if($check0 >= 0.0) { $xmax = $xhalf; next; } my $check1 = ($y - $yhalf) * ($ymax - $y); print " 1: $check1 = $y, $ymin / $yhalf, $y\n" if($Debug); if($check1 >= 0.0) { $xmin = $xhalf; next; } return undef; } my $ymin = $this->YVal($pX, $pY, $xmin); my $ymax = $this->YVal($pX, $pY, $xmax); my $x = $xmax + ($xmax-$xmin)/($ymax-$ymin) * ($y-$ymin); print "Last: x=$xmin, $xmax ($x, $y)\n" if($Debug); return $x; } sub YValLinear { my ($this, $pX, $pY, $x) = @_; if(!defined $x) { ($this, $x) = @_; $pX = $this->{pX}; $pY = $this->{pY}; } return Algorism::Interpolate($pX, $pY, $x); } sub YVal { my ($this, $pX, $pY, $x) = @_; if(!defined $x) { ($this, $x) = @_; $pX = $this->{pX}; $pY = $this->{pY}; } return Algorism::InterpolateByCubicSpline($pX, $pY, $x); } sub ConevrtToNumerical { my ($this, @DataArray) = @_; my $nDataArray = @DataArray; for(my $i = 0 ; $i < $nDataArray ; $i++) { my $pData = $DataArray[$i]; my $nData = @$pData; for(my $j = 0 ; $j < $nData ; $j++) { next if(!defined $pData->[$j] or $pData->[$j] eq ''); $pData->[$j] += 0.0; } } } sub SetXYData { my ($this, $pX, $pY) = @_; return $this->SetXYDataByArrays($pX, $pY) if($pX =~ /^ARRAY\(/); return $this->SetXYDataByLabels($pX, $pY); } sub SetXYDataByArrays { my ($this, $pX, $pY) = @_; $this->SetpX($pX); $this->SetpY($pY); $this->CalMinMax(); } sub SetXYDataByLabels { my ($this, $XLabel, $YLabel) = @_; my $pX = $this->GetXData($XLabel); my $pY = $this->GetYData($YLabel); return ($pX, $pY); } sub MultiplyX { my ($this, $K) = @_; my $pX = $this->{pX}; my $n = @$pX; for(my $i = 0 ; $i < $n ; $i++) { $pX->[$i] *= $K; } return $pX; } sub MultiplyY { my ($this, $K) = @_; my $pY = $this->{pY}; my $n = @$pY; for(my $i = 0 ; $i < $n ; $i++) { $pY->[$i] *= $K; } return $pY; } sub GetXData { my ($this, @labels) = @_; #print "X(labels)=", join(', ', @labels), "\n"; return $this->{pX} if(@labels == 0); return $this->{pX} = $this->GetData(@labels); } sub GetYData { my ($this, @labels) = @_; return $this->{pY} if(@labels == 0); return $this->{pY} = $this->GetData(@labels); } sub GetData { my ($this, @labels) = @_; my $pLabelArray = $this->LabelArray(); my $pDataArray = $this->DataArray(); my $nDataArray = $this->nDataArray(); #print "labels[0]=", join(',', @labels), " Name=", $this->FileName(), "\n"; return $pDataArray->[$labels[0]] if($labels[0] =~ /^\d+$/i); for(my $l = 0 ; $l < @labels ; $l++) { my $label = $labels[$l]; for(my $i = 0 ; $i < $nDataArray ; $i++) { #print "l=$l, i=$i: pla=$pLabelArray->[$i] / label=$label\n"; if($pLabelArray->[$i] eq $label or $pLabelArray->[$i] =~ /^$label$/i) { #print " get $i pDA=$pDataArray->[$i]\n"; return $pDataArray->[$i]; } } } return undef; } sub Duplicate { my ($this, $XLabel, $YLabel) = @_; my ($pX, $pY); if($XLabel) { $pX = $this->GetData($XLabel); } else { $pX = $this->{pX}; } if($YLabel) { $pY = $this->GetData($YLabel); } else { $pY = $this->{pY}; } return undef if(!$pX or !$pY); my $p = new MultiColumnData($pX, $pY); $p->CalMinMax(); return $p; } sub IntegrateByTrapezoid { my ($this, $pX, $pY) = @_; $pX = $this->{pX} if(!defined $pX); $pY = $this->{pY} if(!defined $pY); my $pI = Algorism::IntegrateByTrapezoid($pX, $pY); my $p = new MultiColumnData($pX, $pI); $p->CalMinMax(); return $p; } sub ReverseData { my ($this) = @_; my $n = $this->nData(); my $pDataArray = $this->DataArray(); for(my $i = 0 ; $i < @$pDataArray ; $i++) { my $p = $pDataArray->[$i]; for(my $j = 0 ; $j < $n / 2 ; $j++) { ($p->[$j], $p->[$n-1-$j]) = ($p->[$n-1-$j], $p->[$j]); } } } sub FindLabelIndex { my ($this, $pLabels, $pLabelArray) = @_; $pLabelArray = $this->LabelArray() if(!defined $pLabelArray); my $nLabelArray = @$pLabelArray; for(my $l = 0 ; $l < @$pLabels ; $l++) { my $label = $pLabels->[$l]; for(my $i = 0 ; $i < $nLabelArray ; $i++) { if($pLabelArray->[$i] eq $label or $pLabelArray->[$i] =~ /^$label$/i) { return $i; } } } return undef; } sub SortXYByX { my ($this, $f) = @_; my $pX = $this->{pX}; my $pY = $this->{pY}; return undef if(!defined $pX or !defined $pY); my $nData = @$pX; my @SortArray; for(my $i = 0 ; $i < $nData ; $i++) { my @a; $a[0] = $pX->[$i]; $a[1] = $pY->[$i]; $SortArray[$i] = \@a; } if(defined $f and $f < 0) { @SortArray = sort { $b->[0] <=> $a->[0] } @SortArray; } else { @SortArray = sort { $a->[0] <=> $b->[0] } @SortArray; } my (@X, @Y); for(my $i = 0 ; $i < $nData ; $i++) { my $p = $SortArray[$i]; $X[$i] = $p->[0]; $Y[$i] = $p->[1]; } my $Data = new MultiColumnData; $Data->SetXYDataByArrays(\@X, \@Y); return $Data; } sub Read { my ($this, $filename, $IsNumerical, $YLabel) = @_; $IsNumerical = 1 if(!defined $IsNumerical); my ($nData, $pLabelArray, @DataArray) = $this->ReadAll($filename, $YLabel); return undef if(!defined $pLabelArray); #print "nData=$nData\n"; if($IsNumerical) { $this->ConevrtToNumerical(@DataArray); } $this->SetXYDataByLabels(0, 1); return ($nData, $pLabelArray, @DataArray); } sub ReadAll { my ($this, $filename, $YLabel) = @_; $filename = $this->FilePath() unless($filename); my $ext = Deps::ExtractExtention($filename); $this->SetFileName($filename); if($ext =~ /\.spe$/i or $ext =~ /\.jel$/i or $ext =~ /\.bef$/i or $ext =~ /\.aft$/i) { return $this->ReadSPE($filename); } if($ext =~ /\.pal$/i or $ext =~ /\.job$/i) { return $this->ReadSPEPal($filename); } if($ext =~ /\.ref$/i or $ext =~ /\.asp$/i or $ext =~ /\.isa$/i) { return $this->ReadASP($filename, $YLabel); } if($ext =~ /\.R$/i) { return $this->ReadR($filename); } elsif($ext =~ /\.csv$/i) { $this->SetIncidentAngle(0.0); my ($nData, $pLabelArray, @DataArray) = CSV::GetArraysFromFileSimple($filename, undef, $this->SkipBlankData()); # my ($nData, $pLabelArray, @DataArray) = CSV::GetArraysFromFile($filename); if(!defined $nData) { print "Error in MultiColumnData::ReadAll: Can not read [$filename].\n"; $this->SetTitle(''); $this->SetFileType(''); return undef; } $this->SetTitle(Deps::ExtractFileBody($filename)); $this->SetFileType("SPE"); $this->SetLabelArray($pLabelArray); $this->SetDataArray(\@DataArray); return ($nData, $pLabelArray, @DataArray); } print "Error in MultiColumnData::ReadAll: File type [$ext] is not supported for [$filename].\n"; return undef; } sub ReadSPE { my ($this, $filename) = @_; $filename = $this->FilePath() unless($filename); my $in = $this->Open($filename, "r"); if(!$in) { #print "\n\nError\n\n"; return undef; } else { #print "\n\nRead success\n\n"; } $in->SetSuppressCharCodeConversion(1); my $line = $in->SkipTo("## COMMENTS:"); if(!defined $line) { $in->Close(); return (-1); } $this->SetTitle($in->ReadLine(1)); #print "title: $this->{Title}\n"; #print "Ellipsometry::Read: e2\n"; $in->SkipTo("# INCIDENCE ANGLE:"); #print "Ellipsometry::Read: e3\n"; $this->SetIncidentAngle($in->ReadLine()); #print "Ellipsometry::Read: angle: $this->{IncidentAngle}\n"; $in->SkipTo("# FIRST POINT:"); $line = $in->ReadLine(); $line =~ s/\s*eV\s*//; $this->{EFirst} = $line; $in->SkipTo("# LAST POINT:"); $line = $in->ReadLine(); $line =~ s/\s*eV\s*//; $this->{ELast} = $line; $in->SkipTo("# INCREMENT:"); $line = $in->ReadLine(); $line =~ s/\s*eV\s*//; $this->{EStep} = $line; $in->SkipTo("# DATA:"); $line = $in->ReadLine(); my @LabelList = Utils::Split("\\s+", $line); my @DataArray; for(my $i = 0 ; $i < @LabelList ; $i++) { if($LabelList[$i] eq '銜' or $LabelList[$i] eq 'r') { $LabelList[$i] = 'e1'; } elsif($LabelList[$i] eq '鉗' or $LabelList[$i] eq 'i') { $LabelList[$i] = 'e2'; } $DataArray[$i] = []; } my $c = 0; my @E; while(!$in->eof()) { my $line = $in->ReadLine(); my @a = Utils::Split("\\s+", $line); last if(@a == 0); for(my $i = 0 ; $i < @LabelList ; $i++) { $DataArray[$i]->[$c] = $a[$i]; #print "$a[$i],"; } #print "\n"; $E[$c] = $this->{EFirst} + $c * $this->{EStep}; $c++; } $in->Close(); $this->SetFileType("SPE"); if($LabelList[0] eq 'hv' or $LabelList[0] eq 'E') { $this->SetLabelArray(\@LabelList); $this->SetDataArray(\@DataArray); } else { $this->SetLabelArray(['E', @LabelList]); $this->SetDataArray([\@E, @DataArray]); } my $pData0 = $DataArray[0]; my $nData = @$pData0; if($nData == 0) { print "Warning: Ellipsometry::Read: nData is zero.\n"; } my $pLabelArray = $this->LabelArray(); my $pDataArray = $this->DataArray(); #print "AA: ($nData, $pLabelArray, @$pDataArray)\n"; return ($nData, $pLabelArray, @$pDataArray); } sub ReadSPEPal { my ($this, $filename) = @_; $filename = $this->FilePath() unless($filename); my $in = $this->Open($filename, "r"); return undef if(!$in); $in->SetSuppressCharCodeConversion(1); my $line = $in->SkipTo("## COMMENTS:"); if(!defined $line) { $in->Close(); return (-1); } $this->SetTitle($in->ReadLine(1)); $in->SkipTo("# FIRST POINT:"); $line = $in->ReadLine(); $line =~ s/\s*eV\s*//; $this->{EFirst} = $line; $in->SkipTo("# LAST POINT:"); $line = $in->ReadLine(); $line =~ s/\s*eV\s*//; $this->{ELast} = $line; $in->SkipTo("# INCREMENT:"); $line = $in->ReadLine(); $line =~ s/\s*eV\s*//; $this->{EStep} = $line; $in->SkipTo("# DATA:"); $line = $in->ReadLine(); my @LabelList = Utils::Split("\\s+", $line); my @DataArray; for(my $i = 0 ; $i < @LabelList ; $i++) { if($LabelList[$i] eq '銜' or $LabelList[$i] eq 'r') { $LabelList[$i] = 'e1'; } elsif($LabelList[$i] eq '鉗' or $LabelList[$i] eq 'i') { $LabelList[$i] = 'e2'; } $DataArray[$i] = []; } my $c = 0; my @E; while(!$in->eof()) { my $line = $in->ReadLine(); my @a = Utils::Split("\\s+", $line); last if(@a == 0); for(my $i = 0 ; $i < @LabelList ; $i++) { $DataArray[$i]->[$c] = $a[$i]; } $E[$c] = $this->{EFirst} + $c * $this->{EStep}; $c++; } $in->Close(); $this->SetFileType("SPEPal"); if($LabelList[0] eq 'hv' or $LabelList[0] eq 'E') { $this->SetLabelArray(\@LabelList); $this->SetDataArray(\@DataArray); } else { $this->SetLabelArray(['E', @LabelList]); $this->SetDataArray([\@E, @DataArray]); } my $pData0 = $DataArray[0]; my $nData = @$pData0; if($nData == 0) { print "Warning: Ellipsometry::Read: nData is zero.\n"; } my $pLabelArray = $this->LabelArray(); my $pDataArray = $this->DataArray(); #print "AA: ($nData, $pLabelArray, @$pDataArray)\n"; return ($nData, $pLabelArray, @$pDataArray); } sub ReadASP { my ($this, $filename, $YLabel) = @_; my ($nData, $pLabelArray, @DataArray) = $this->ReadSPE($filename); return $this->ReadU4000ASP($filename, $YLabel) if($nData == -1); return ($nData, $pLabelArray, @DataArray); } sub ReadU4000ASPXY { my ($this, $filename, $YLabel) = @_; $filename = $this->FilePath() unless($filename); $YLabel = 'y' if(!defined $YLabel); print "Read U4000 ASP XY data.\n"; $this->SetIncidentAngle(0.0); my $in = $this->Open($filename, "r"); if(!$in) { return undef; } my @LabelList = ('wl(nm)', 'E(eV)', $YLabel); my @DataArray; for(my $i = 0 ; $i < @LabelList ; $i++) { $DataArray[$i] = []; } my $nData = 0; for(my $i = 0 ; ; $i++) { my $line = $in->ReadLine(1); last if(!defined $line); Utils::DelSpace($line); last if($line eq ''); my ($wl, $y) = Utils::Split("\\s*,\\s*", $line); ($wl, $y) = Utils::Split("\\s+", $line) if(!defined $y); last if(!defined $y); my $E = Optics::nmToeV($wl); $DataArray[0]->[$i] = $wl; $DataArray[1]->[$i] = $E; $DataArray[2]->[$i] = $y; $nData++; #print "$wl($E): $y\n"; } $in->Close(); $this->SetFileType("U4000-ASP"); $this->SetLabelArray(\@LabelList); $this->SetDataArray(\@DataArray); return ($nData, \@LabelList, @DataArray); } sub ReadU4000ASP { my ($this, $filename, $YLabel) = @_; $filename = $this->FilePath() unless($filename); $YLabel = 'T' if(!defined $YLabel); print "Read U4000 ASP data.[$YLabel]\n"; $this->SetIncidentAngle(0.0); my $in = $this->Open($filename, "r"); if(!$in) { return undef; } my $nData = $in->ReadLine(); if(Utils::Split("[\\s,]+", $nData) > 1) { $in->Close(); return $this->ReadU4000ASPXY($filename, $YLabel); } $nData += 0.0; my $wlStart = $in->ReadLine() + 0; my $wlEnd = $in->ReadLine() + 0; $in->ReadLine(); $in->ReadLine(); my $wlStep = $in->ReadLine() * -1.0; my @LabelList = ('wl(nm)', 'E(eV)', $YLabel); my @DataArray; for(my $i = 0 ; $i < @LabelList ; $i++) { $DataArray[$i] = []; } for(my $i = 0 ; $i < $nData ; $i++) { my $line = $in->ReadLine(1); my ($wl, $y) = Utils::Split("\\s*,\\s*", $line); ($wl, $y) = Utils::Split("\\s+", $line) if(!defined $y); if(!defined $y) { $y = $wl; $wl = $wlStart + $i * $wlStep; } my $E = Optics::nmToeV($wl); $DataArray[0]->[$i] = $wl; $DataArray[1]->[$i] = $E; $DataArray[2]->[$i] = $y; #print "$wl($E): $y\n"; } $in->Close(); $this->SetFileType("U4000-ASP"); $this->SetLabelArray(\@LabelList); $this->SetDataArray(\@DataArray); return ($nData, \@LabelList, @DataArray); } sub ReadSPring8NIMSHXPES { my ($this, $filename, $YLabel) = @_; $filename = $this->FilePath() unless($filename); $YLabel = 'I' if(!defined $YLabel); print "Read SPring-8/NIMS HX-PE data.[$YLabel]\n"; $this->SetIncidentAngle(0.0); my $in = $this->Open($filename, "r"); if(!$in) { return undef; } my $ret = $in->SkipTo('\[Data '); print "ret=[$ret]n"; if(!$ret) { return undef; } my @LabelList = ("E(eV)", "I"); my @DataArray = ([], []); my $nData = 0; while(1) { my $line = $in->ReadLine(1); my ($x, $y) = Utils::Split("\\s+", $line); if(!defined $y) { last; } $DataArray[0]->[$nData] = $x; $DataArray[1]->[$nData] = $y; $nData++; #print "$nData: $x, $y\n"; } $in->Close(); $this->SetFileType("SPring-8/NIMS-HXPES"); $this->SetLabelArray(\@LabelList); $this->SetDataArray(\@DataArray); print "End: Read SPring-8/NIMS HX-PE data.\n"; return ($nData, \@LabelList, @DataArray); } sub ReadR { my ($this, $filename) = @_; $filename = $this->FilePath() unless($filename); my $in = $this->Open($filename, "r"); if(!$in) { return undef; } else { } $this->SetIncidentAngle(0.0); my $line = $in->ReadLine(); my @LabelList = Utils::Split("\\s+", $line); my @DataArray; for(my $i = 0 ; $i < @LabelList ; $i++) { $DataArray[$i] = []; } my $c = 0; my @E; while(!$in->eof()) { my $line = $in->ReadLine(); my @a = Utils::Split("\\s+", $line); last if(@a == 0); for(my $i = 0 ; $i < @LabelList ; $i++) { $DataArray[$i]->[$c] = $a[$i]; } $c++; } $in->Close(); $this->SetFileType("R"); $this->SetLabelArray(\@LabelList); $this->SetDataArray(\@DataArray); if($c == 0) { print "Warning: Ellipsometry::Read: nData is zero.\n"; } return ($c, \@LabelList, @DataArray); } 1;