#!/usr/bin/perl -W
#--------------------------------------------------------------
# This example PERL script:
# - calls the TRDS_SL program from http://x-server.gmca.aps.anl.gov/
# - gets and saves the data.
# The example is equivalent to the following page:
# http://x-server.gmca.aps.anl.gov/cgi/WWW_form.exe?template=TRDS_sl_omega.htm
#
# PERL interpreter is available by default on UNIX and MAC OS. Freeware
# PERL distibution for Windows can be installed either as a part of Cygwin
# (http://www.cygwin.com), or as a standalone package available from
# ActiveState (http://www.activestate.com/).
#
# To access data from remote web site, this script makes use of PERL LWP
# module (WWW library for Perl). The latter is usually a part of standard
# PERL distribution; otherwise it can be freely downloaded from CPAN
# (http://www.cpan.org/).
#
# This example script can be freely distributed and modified without any
# restrictions.
#
# Author: Sergey Stepanov
#
# Version-1: 2006/11/08
#--------------------------------------------------------------
use strict;
use LWP::Simple; # World-Wide Web library for Perl (libwww-perl)
### General parameters:
my $url = "http://x-server.gmca.aps.anl.gov";
my $prg = "${url}/cgi/TRDS_frm.exe?";
my $unzip = "${url}/cgi/WWWunzip.exe?";
### X-rays:
my $xway = 1; # 1 - wavelength, 2 - energy, 3 - line type
my $wave = 1.540562; # works with xway=2 or xway=3
# my $line = "Cu-Ka1"; # works with xway=3 only
my $line = ''; # works with xway=3 only
my $ipol = 1; # 1=sigma-polarization; 2=pi-polarization
### Substrate:
my $subway = 1; # 1=database_code, 2=chemical_formula, 3=x0_value
my $code = 'GaAs'; # Database_code: works with subway=1 only
my $chem = ''; # Chemical formula: works with subway=2 only
my $rho = ''; # Density (g/cm3): required for chemical formula
my @x0 = (0.,0.); # Direct input of chi_0: works with subway=3
my $w0 = 1.; # Debye-Waller type correction for x0: with any subway
### Database Options for dispersion corrections df1, df2:
### -1 - Automatically choose DB for f',f"
### 0 - Use X0h data (5-25 keV or 0.5-2.5 A) -- recommended for Bragg diffraction.
### 2 - Use Henke data (0.01-30 keV or 0.4-1200 A) -- recommended for soft x-rays.
### 4 - Use Brennan-Cowan data (0.03-700 keV or 0.02-400 A)
my $df1df2 = -1;
### Substrate surface:
### (only one of the two parameters can be non-zero):
my $sigma = 3.; # rms roughness at substrate interface (Angstrom)
### Type of scan:
### 1: Theta-scans at fixed 2Theta
### 2: Theta-2Theta scans at fixed Theta-offsets
### 3: 2Theta (detector) scans at fixed Theta
### 4: qx scans at fixed qz
my $scan = 1;
my $scanmin = 0.; # minimum scan angle (range)
my $scanmax = 2.; # maximum scan angle (range)
my $nscan = 201; # number of scan points
my $offmin = 2.; # minimum offset angle (range)
my $offmax = 2.; # maximum offset angle (range)
my $noff = 1; # number of offset points
my $unis = 0; # scan/offset angle units: 0=degr.,1=min,2=mrad,3=sec,4=urad
my $unia = 0; # qx,qz units: 0=1/A (do not change!)
### What to compute at the specular rod:
my $spec = 1; # 0=diffuse scattering, 1=specular reflectivity
### Accelerators:
my $Fourier = 0; # 1=Use K instead of exp(K)-1 (small rms roughness),
# 0=use exp(K)-1.
my $Born = 0; # 1=Use semi-Born approximation (ignore scattering
# from reflected waves), 0=use DWBA (all waves)
### Roughness models and parameters:
### See bried documentation at
### http://x-server.gmca.aps.anl.gov/TRDS_sl.html
my $Lh = 1000.; # lateral correlation length of roughness in Angstrem
my $jagg = 1.; # rougness jaggedness (acceptable range: 0.1-1)
my $Lv = ''; # vertical correlation length of roughness in Angstrem
my $skew = 0.; # angle of skew rougness correlation between interfaces
my $uniw = 0; # skew angle units: 0=degr.,1=min,2=mrad,3=sec,4=urad
### Hint:
### The script can be called in a loop or
### from a fitting program. Then, it may be
### helpful to pass some parameters to the
### script as command line arguments:
# my $Lh = $ARGV[0];
# my $jagg = $ARGV[1];
### Affine-type rougness models (see basic theory in Sinha,Sirota,Garoff,Stanley,
### Phys.Rev.B, 38 (1988) 2297, and program implementation details in Kaganer,
### Stepanov, Koehler, Physica B, 221, (1996) 33).
### 1: Uncorrelated roughness
### 2: Completely correlated roughness
### 3: Ming's model -- Ming,Krol,Soo,Kao,Park,Wang, Phys.Rev.B 47 (1993) 16373.
### 4: Lagally's model -- Phang,Savage,Kariotis,Lagally, J.Appl.Phys. 74 (1993) 3181.
### 5: Holy's model -- Holy,Baumbach, Phys.Rev.B 49 (1994) 10669.
### 6: Spiller's model (*very slow!*) -- Spiller,Stearns,Krumrey, J.Appl.Phys. 74 (1993) 107.
### Models of scattering from atomic steps at vicinal interfaces (see details in
### Kondrashkina,Stepanov,Opitz,Schmidbauer,Koehler,Hey,Wassermeier,Novikov,
### Phys.Rev.B, 56 (1997) 10469).
### 7: Classic Pukite's model -- Pukite,Lent,Cohen, Surf.Sci. 161 (1985) 39.
### 8: Smoothed Pukite's model -- Pukite,Lent,Cohen, Surf.Sci. 161 (1985) 39.
### 9: Pershan's model -- Rabedeau,Tidswell,Pershan,Bevk,Freer, Appl.Phys.Lett. 59 (1991) 3422.
my $model = 2;
my $Lh2 = ''; # lateral size of vertically correlated roughness
# in Angstem for Lagally's model.
my $Qm = 0.; # miscut angle for all scattering-from-steps models (7-9)
my $unim = 0; # miscut angle units: 0=degr.,1=min,2=mrad,3=sec,4=urad
my $add = 0; # add affine roughness to scattering-from-steps models (7-9)
my $stepH = 0.; # effect.rms height of steps (Angstrem) for smoothed Pukite's model (8)
my $spread = 0.; # terraces size spread (Angstrem) for Pershan's model (9)
### Surface layer profile
### (can also be read from
## a filename specified in
### the command line):
my $profile = '';
### This is an example of non-empty profile:
### (use with care because the length of calculations
### is proportional to the 4th power of the number of
### layers, n^4). Long calculations may not return
### results within browser timeout. There is a way to
### detouch them from the browser session, but this
### script does not implement detouched sessions.
# my $profile = '
# t=20 w0=0.5 sigma=5 !surface oxide, organic contamination or dust
# period=3
# t=100 code=GaAs sigma=4
# t=70 code=AlAs sigma=4
# end period
# ';
### Encode strings that may contain illegal characters for CGI:
$line = &encode_url_string($line);
$code = &encode_url_string($code);
$chem = &encode_url_string($chem);
$profile = &encode_url_string($profile);
#-----------------------------------------------------------
### Submit task:
my $address=${prg}.
"&xway=${xway}".
"&wave=${wave}".
"&line=${line}".
"&ipol=${ipol}".
"&subway=${subway}".
"&code=${code}".
"&chem=${chem}".
"&rho=${rho}".
"&x0=(${x0[0]},${x0[1]})".
"&w0=${w0}".
"&df1df2=${df1df2}".
"&sigma=${sigma}".
"&scan=${scan}".
"&scanmin=${scanmin}".
"&scanmax=${scanmax}".
"&nscan=${nscan}".
"&offmin=${offmin}".
"&offmax=${offmax}".
"&noff=${noff}".
"&unis=${unis}".
"&unia=${unia}".
"&spec=${spec}".
"&Fourier=${Fourier}".
"&Born=${Born}".
"&Lh=${Lh}".
"&jagg=${jagg}".
"&Lv=${Lv}".
"&skew=${skew}".
"&uniw=${uniw}".
"&model=${model}".
"&Lh2=${Lh2}".
"&Qm=${Qm}".
"&unim=${unim}".
"&add=${add}".
"&stepH=${stepH}".
"&spread=${spread}".
"&watch=0".
"&profile=${profile}";
### Request X0h data from the server:
print STDOUT "Request string:\n${address}\n";
my $buffer = get($address);
$buffer =~ s/[\015\012]//g; # remove CR/LF
### Find job ID on the server:
my $jobID = $buffer;
if ( $buffer =~ /Download ZIPped results:/ ) {
### Remove all text before and after job name in the string like:
### Download ZIPped results: TDSxxxxx.zip
$jobID =~ s/^.*Download ZIPped results: //; # remove all before error message
$buffer =~ s/<\/font>.*$//; # remove all after error message
$buffer =~ s/
/\n/g; # replace HTML tags
$buffer =~ s/\ / /g; # replace HTML tags
print STDOUT "Saving log: ${jobID}.tbl\n";
&getstore("${unzip}jobname=${jobID}&filext=TBL","${jobID}.tbl");
print STDOUT "\nERROR message:\n${buffer}\n";
$status = 1;
}
else {
### Normal completion:
print STDOUT "Request was successfull, job ID=${jobID}\n";
if ( $buffer =~ /Display DAT file/ ) {
$status = &getcheckstore($unzip,$jobID,"dat");
if (! $status) {$data_found++;}
} else {
$status = 1; # no data
}
### GRD files are produced for 2D maps only ($nscan>1 && $noff>1):
if ( $buffer =~ /Display GRD file/ ) {
$status = &getcheckstore($unzip,"${jobID}","grd");
if (! $status) {$data_found++;}
}
if ($data_found == 0) {$status = 1;} # no data
}
print STDOUT "Saving packed results: ${jobID}.zip\n";
&getstore("${url}/x-ray/${jobID}.zip","${jobID}.zip");
print STDOUT "Done!\n";
exit $status;
############################################################################
#sub encode_url_string ($);
sub encode_url_string {
my $KeepUnencoded = 'a-zA-Z 0-9_\\-@.=';
my ($toencode) = @_;
### ord - find a character's numeric representation
### "^": if not in the Unencoded list
$toencode=~s/([^$KeepUnencoded])/sprintf("%%%02X",ord($1))/ego;
### Change spaces to "+":
$toencode=~s/ /+/gm;
return $toencode;
}
############################################################################
#sub getcheckstore ($$$);
sub getcheckstore {
my $unzip = shift(@_);
my $prefix = shift(@_);
my $ext = shift(@_);
print STDOUT "Saving data: ${prefix}.${ext}\n";
my $data = get("${unzip}jobname=${prefix}&filext=${ext}");
$data =~ s/\015//g; # Perl for Windows workaround
if ( $data =~ /stop/ ) { # stop1.gif is returned when no data
print STDOUT "!!! No data on server!\n";
return 1;
} else {
open (DAT,"> ${prefix}.${ext}") or die "Cannot open ${prefix}.${ext}";
print DAT ${data};
close(DAT);
return 0;
}
}
############################################################################