3
################################################################################
5
# Johan Alwall (alwall@slac.stanford.edu)
7
# DESCRIPTION : script to replace particle codes in MG/ME event files
9
# replace.pl infile.lhe outfile.lhe
10
# Asks for list of particles to replace. To replace electrons and neutrinos
11
# with electrons, muons and taus, give
15
# To replace electrons and positrons in W-W+ pair production please run
16
# script twice, ones for the e-/ve~, once for e+/ve.
17
# Automatically increases cross section with correct factor.
18
################################################################################
21
use List::Util qw[min max];
23
print "Running script replace.pl to replace particle codes in event file.\n";
25
###########################################################################
27
###########################################################################
28
# Set tag names for later
29
my $begin_header = '<header>';
30
my $end_header = '</header>';
31
my $begin_event = '<event>';
32
my $end_event = '</event>';
33
my $begin_init = '<init>';
34
my $end_init = '</init>';
36
# Parse the command line arguments
38
die "Usage: replace.pl infile.lhe outfile.lhe\n";
40
my $outfile = pop(@ARGV);
41
my $infile = pop(@ARGV);
43
open INFILE, "<$infile" or die ("Error: Couldn't open file $infile\n");
45
###########################################################################
46
# Read which particles to replace
47
###########################################################################
49
print "Enter particles to be replaced in syntax PID : PID1 PID2 PID3 ...\n";
50
print "(note that they will be replaced together, so must be same number of\n";
51
print " particles in each line)\n";
52
print "Enter \"done\" or <return> when ready\n";
58
while ($line !~ m/^\s*done\s*$/i && $line !~ m/^\s*$/){
59
# Remove leading whitespace
61
if($line =~ m/^(-?\d+)\s*\:\s*((-?\d+\s+)+)/){
62
@tmp = split (/\s+/,$2);
63
if($i == 0) { $nparts = $#tmp+1; }
64
elsif($#tmp+1 != $nparts){
65
die "Error: Not same number of particles in each replace: ",$#tmp+1," $nparts\n";
68
$particles{$i}=[ @tmp ];
69
print "Replacing $i with @{$particles{$i}}\n";
71
elsif($line !~ m/^#/){
72
print "Please use syntax PID1 : PID2 PID3 ... or \"done\" or <return> when ready\n";
76
@keys = keys %particles;
77
if($#keys < 0) {die "Error: No particles to replace\n";}
78
print "Multiplying cross section and weight by $nparts\n";
80
###########################################################################
81
# Go through file and perform replacements
82
###########################################################################
84
open OUTFILE, ">$outfile" or die ("Error: Couldn't open file $outfile for writing\n");
86
# No. events and cross-section numbers file
87
$nevents = $xsec = $trunc = $unitwgt = -1;
89
# Keep track in which block we are
96
while (my $line = <INFILE>) {
98
# Extract <MGGenerationInfo> information
99
if ($line =~ m/$end_header/) {
100
if($nevents == -1 || $xsec == -1 || $trunc == -1 || $unitwgt == -1) {
101
die "Error: Couldn't find number of events and cross section in $infile.\n";
104
print OUTFILE "<ReplaceParticleInfo>\n";
105
printf OUTFILE "# Number of Events : %11i\n",$nevents;
106
printf OUTFILE "# Integrated weight (pb) : %11.4E\n",$xsec;
107
printf OUTFILE "# Truncated wgt (pb) : %11.4E\n",$trunc;
108
printf OUTFILE "# Unit wgt : %11.4E\n",$unitwgt;
110
print OUTFILE " ", $rdnseed+1, " = gseed ! Random seed for next iteration of replace.pl\n";}
111
print OUTFILE "</ReplaceParticleInfo>\n";
112
if($rdnseed > 0) {print "Initialize random seed with $rdnseed\n";srand($rdnseed);}
113
else {print "Warning: Random seed 0, use default random seed (unreproducible)\n";}
115
if ($line =~ m/$end_init/) { $initblock=0; }
116
if ($line =~ m/$end_event/) {
121
if ($headerblock == 1) {
123
if ($line =~ m/^#\s+Number of Events\s*:\s*(.*)\n/) { $nevents = $1; }
124
if ($line =~ m/^#\s+Integrated weight \(pb\)\s*:\s*(.*)\n/) { $xsec = $1*$nparts; }
125
if ($line =~ m/^#\s+Truncated wgt \(pb\)\s*:\s*(.*)\n/) { $trunc = $1*$nparts; }
126
if ($line =~ m/^#\s+Unit wgt\s*:\s*(.*)\n/) { $unitwgt = $1*$nparts; }
127
if ($line =~ m/^\s*(\d+)\s*=\s*gseed/) { $rdnseed = $1; }
128
} elsif ($initblock > 0) {
132
# Remove leading whitespace and split
134
@param = split(/\s+/, $line);
135
if ($#param != 3) { die "Error: Wrong number of params in init ($#param)"; }
139
$line = sprintf " %18.11E %18.11E %18.11E %3i\n",$param[0],$param[1],$param[2],$param[3];
143
} elsif ($eventblock > 0) {
145
# Remove leading whitespace and split
146
$line =~ m/^\s*(.*)/;
148
# print OUTFILE $line;
151
@param = split(/\s+/, $1);
152
if($eventblock == 1){
153
if ($#param != 5) { die "Error: Wrong number of params in event $eventcount \($#param / 5\)"; }
155
$line = sprintf "%2i %3i %13.6E %13.6E %13.6E %13.6E\n",$param[0],$param[1],$param[2],$param[3],$param[4],$param[5];
157
# Randomly choose a particle from the lists
158
$rnumber = int(rand($nparts));
161
# @param = split(/\s+/, $1);
162
if ($#param != 12) { die "Error: Wrong number of params in event $eventcount \($#param / 12\)"; }
163
if($particles{$param[0]}){
164
$line = sprintf "%9i %4i %4i %4i %4i %4i %18.10E %18.10E %18.10E %18.10E %18.10E %1.0f. %2.0f.\n",
165
$particles{$param[0]}[$rnumber],$param[1],$param[2],$param[3],$param[4],$param[5],$param[6],$param[7],$param[8],$param[9],$param[10],$param[11],$param[12];
172
if ($line =~ m/$begin_header/) { $headerblock = 1; }
173
if ($line =~ m/$begin_init/) { $initblock=1; }
174
if ($line =~ m/$begin_event/) { $eventblock=1; }
176
print OUTFILE "$line";
182
print "Wrote $eventcount events\n";
183
if( $eventcount < $nevents ) { print "Warning: $infile ended early\n"; }