]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PYTHIA8/pythia8145/src/Settings.cxx
New pythia8 version
[u/mrichter/AliRoot.git] / PYTHIA8 / pythia8145 / src / Settings.cxx
1 // Settings.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2010 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5
6 // Function definitions (not found in the header) for the Settings class.
7
8 #include "Settings.h"
9
10 // Allow string and character manipulation.
11 #include <cctype>
12
13 namespace Pythia8 {
14
15 //==========================================================================
16
17 // Settings class.
18 // This class contains flags, modes, parms and words used in generation.
19
20 //--------------------------------------------------------------------------
21
22 // Read in database from specific file.
23
24 bool Settings::init(string startFile, bool append, ostream& os) {
25
26   // Don't initialize if it has already been done and not in append mode.
27   if (isInit && !append) return true;
28   int nError = 0;
29
30   // List of files to be checked. Start with input file. 
31   vector<string> files;
32   files.push_back(startFile);
33
34   // If nontrivial startfile path, then use that for other files as well.
35   string pathName = "";
36   if (startFile.rfind("/") != string::npos) 
37     pathName = startFile.substr(0, startFile.rfind("/") + 1);
38
39   // Loop over files. Open them for read.
40   for (int i = 0; i < int(files.size()); ++i) {
41     const char* cstring = files[i].c_str();
42     ifstream is(cstring);  
43
44     // Check that instream is OK.
45     if (!is.good()) {
46       os << "\n PYTHIA Error: settings file " << files[i] 
47          << " not found" << endl; 
48       return false;
49     }
50
51     // Read in one line at a time.
52     string line;
53     while ( getline(is, line) ) {
54
55       // Get first word of a line, to interpret it as tag.
56       istringstream getfirst(line);
57       string tag;
58       getfirst >> tag;
59
60       // Skip ahead if not interesting. Only look for new files in startfile.
61       if (tag != "<flag" && tag != "<flagfix" && tag != "<mode" 
62          && tag != "<modeopen" && tag != "<modepick" && tag != "<modefix" 
63          && tag != "<parm" && tag != "<parmfix" && tag != "<word" 
64          && tag != "<wordfix" && tag != "<aidx") continue;
65
66       // Read and append continuation line(s) if line does not contain >.
67       while (line.find(">") == string::npos) {   
68         string addLine;
69         getline(is, addLine);
70         line += " " + addLine;
71       } 
72       
73       // Remove extra blanks before an = sign.
74       while (line.find(" =") != string::npos) line.erase( line.find(" ="), 1);
75
76       // Add file also to be read.
77       if (tag == "<aidx") {
78         string name = attributeValue( line, "href");
79         if (name == "") {
80           os << " PYTHIA Error: failed to find name attribute in line " 
81              << line << endl;
82           ++nError;
83           continue;
84         }        
85         files.push_back(pathName + name + ".xml");
86         continue;
87       }
88
89       // Find name attribute.
90       string name = attributeValue( line, "name=");
91       if (name == "") {
92         os << " PYTHIA Error: failed to find name attribute in line " 
93            << line << endl;
94         ++nError;
95         continue;
96       }        
97
98       // Check that default value attribute present, and whether max and min.
99       if (line.find("default=") == string::npos) {
100         os << " PYTHIA Error: failed to find default value token in line " 
101            << line << endl;
102         ++nError;
103         continue;
104       }        
105       bool hasMin = (line.find("min=") != string::npos);
106       bool hasMax = (line.find("max=") != string::npos);
107     
108       // Check for occurence of a bool and add to flag map.
109       if (tag == "<flag" || tag == "<flagfix") {
110         bool value = boolAttributeValue( line, "default=");
111         addFlag( name, value);
112     
113       // Check for occurence of an int and add to mode map.
114       } else if (tag == "<mode" || tag == "<modeopen" 
115         || tag == "<modepick" || tag == "<modefix") {
116         int value  = intAttributeValue( line, "default="); 
117         int minVal = intAttributeValue( line, "min=");
118         int maxVal = intAttributeValue( line, "max=");
119         addMode( name, value, hasMin, hasMax, minVal, maxVal);    
120     
121       // Check for occurence of a double and add to parm map.
122       } else if (tag == "<parm" || tag == "<parmfix") {
123         double value  = doubleAttributeValue( line, "default="); 
124         double minVal = doubleAttributeValue( line, "min=");
125         double maxVal = doubleAttributeValue( line, "max=");
126         addParm( name, value, hasMin, hasMax, minVal, maxVal);
127     
128       // Check for occurence of a string and add to word map.
129       } else if (tag == "<word" || tag == "<wordfix") {
130         string value = attributeValue( line, "default="); 
131         addWord( name, value);
132       }
133
134     // End of loop over lines in input file and loop over files.
135     };
136   };
137
138   // Set up default e+e- and pp tunes, if nonvanishing.
139   int eeTune = mode("Tune:ee");
140   if (eeTune != 0) initTuneEE( eeTune);
141   int ppTune = mode("Tune:pp");
142   if (ppTune != 0) initTunePP( ppTune);
143
144   // Done.
145   if (nError > 0) return false;
146   isInit = true;
147   return true;
148
149 }
150
151 //--------------------------------------------------------------------------
152
153 // Overwrite existing database by reading from specific file.
154
155 bool Settings::reInit(string startFile, ostream& os) {
156
157   // Reset maps to empty.
158   flags.clear();
159   modes.clear();
160   parms.clear();
161   words.clear();
162
163   // Then let normal init do the rest.
164   isInit = false;
165   return init(startFile, false, os);
166
167
168
169 //--------------------------------------------------------------------------
170
171 // Read in updates from a character string, like a line of a file. 
172 // Is used by readString (and readFile) in Pythia.
173
174 bool Settings::readString(string line, bool warn, ostream& os) {
175
176   // If empty line then done.
177   if (line.find_first_not_of(" \n\t\v\b\r\f\a") == string::npos) return true;
178
179   // If first character is not a letter, then taken to be a comment line.
180   string lineNow = line;
181   int firstChar = lineNow.find_first_not_of(" \n\t\v\b\r\f\a");
182   if (!isalpha(lineNow[firstChar])) return true; 
183
184   // Replace an equal sign by a blank to make parsing simpler.
185   while (lineNow.find("=") != string::npos) {
186     int firstEqual = lineNow.find_first_of("=");
187     lineNow.replace(firstEqual, 1, " ");   
188   }
189
190   // Get first word of a line.
191   istringstream splitLine(lineNow);
192   string name;
193   splitLine >> name;
194
195   // Replace two colons by one (:: -> :) to allow for such mistakes.
196   while (name.find("::") != string::npos) {
197     int firstColonColon = name.find_first_of("::");
198     name.replace(firstColonColon, 2, ":");   
199   }
200      
201   // Check whether this is in the database. Done if not.
202   int inDataBase = 0;
203   if      (isFlag(name)) inDataBase = 1;   
204   else if (isMode(name)) inDataBase = 2;   
205   else if (isParm(name)) inDataBase = 3; 
206   else if (isWord(name)) inDataBase = 4; 
207   if (inDataBase == 0) {
208     if (warn) os << "\n PYTHIA Warning: input string not found in settings"
209       << " databases; skip:\n   " << line << endl;
210     return false;  
211   }  
212
213   // Find value. Warn if none found.
214   string valueString;
215   splitLine >> valueString;
216   if (!splitLine) {
217     if (warn) os << "\n PYTHIA Warning: variable recognized, but its value"
218       << " not meaningful; skip:\n   " << line << endl;
219     return false;  
220   }  
221
222   // Update flag map; allow many ways to say yes.
223   if (inDataBase == 1) {
224     bool value = boolString(valueString);
225     flag(name, value);
226
227   // Update mode map.
228   } else if (inDataBase == 2) {
229     istringstream modeData(valueString);
230     int value;
231     modeData >> value;
232     if (!modeData) {
233       if (warn) os << "\n PYTHIA Warning: variable recognized, but its value"
234         << " not meaningful; skip:\n   " << line << endl;
235       return false;  
236     }  
237     mode(name, value);
238         
239   // Update parm map.
240   } else if (inDataBase == 3) {
241     istringstream parmData(valueString);
242     double value;
243     parmData >> value;
244     if (!parmData) {
245       if (warn) os << "\n PYTHIA Warning: variable recognized, but its value"
246         << " not meaningful; skip:\n   " << line << endl;
247       return false;  
248     }  
249     parm(name, value);
250         
251   // Update word map.
252   } else {
253     word(name, valueString);
254   }
255
256   // Done.
257   return true;
258 }
259
260 //--------------------------------------------------------------------------
261  
262 // Write updates or everything to user-defined file.
263
264 bool Settings::writeFile(string toFile, bool writeAll) {
265
266   // Open file for writing.
267   const char* cstring = toFile.c_str();
268   ofstream os(cstring);  
269   if (!os) {
270     infoPtr->errorMsg("Error in Settings::writeFile:"
271       " could not open file", toFile);
272     return false;
273   }
274
275   // Hand over real work to next method.
276   return writeFile( os, writeAll);
277
278 }
279
280 //--------------------------------------------------------------------------
281  
282 // Write updates or everything to user-defined stream (or file).
283
284 bool Settings::writeFile(ostream& os, bool writeAll) {
285
286   // Write simple header as comment.
287   if (writeAll) os << "! List of all current PYTHIA ";
288   else          os << "! List of all modified PYTHIA ";
289   os << fixed << setprecision(3) << parm("Pythia:versionNumber")
290      << " settings.\n";
291
292   // Iterators for the flag, mode and parm tables.
293   map<string, Flag>::iterator flagEntry = flags.begin();
294   map<string, Mode>::iterator modeEntry = modes.begin();
295   map<string, Parm>::iterator parmEntry = parms.begin();
296   map<string, Word>::iterator wordEntry = words.begin();
297
298   // Loop while there is something left to do.
299   while (flagEntry != flags.end() || modeEntry != modes.end() 
300     || parmEntry != parms.end() || wordEntry != words.end()) {
301
302     // Check if a flag is next in lexigraphical order; if so print it.
303     if ( flagEntry != flags.end() 
304       && ( modeEntry == modes.end() || flagEntry->first < modeEntry->first ) 
305       && ( parmEntry == parms.end() || flagEntry->first < parmEntry->first )
306       && ( wordEntry == words.end() || flagEntry->first < wordEntry->first ) 
307       ) {
308       string state[2] = {"off", "on"};
309       bool valNow = flagEntry->second.valNow;
310       bool valDefault = flagEntry->second.valDefault;
311       if ( writeAll || valNow != valDefault )
312         os << flagEntry->second.name << " = " << state[valNow] << "\n";
313       ++flagEntry;
314      
315     // Else check if mode is next, and if so print it.
316     } else if ( modeEntry != modes.end() 
317       && ( parmEntry == parms.end() || modeEntry->first < parmEntry->first ) 
318       && ( wordEntry == words.end() || modeEntry->first < wordEntry->first ) 
319       ) {
320       int valNow = modeEntry->second.valNow;
321       int valDefault = modeEntry->second.valDefault;
322       if ( writeAll || valNow != valDefault ) 
323         os << modeEntry->second.name << " = " << valNow << "\n"; 
324       ++modeEntry;
325       
326     // Else check if parm is next, and if so print it; 
327     // fixed or scientific depending on value.
328     } else if ( parmEntry != parms.end()
329       && ( wordEntry == words.end() || parmEntry->first < wordEntry->first ) 
330       ) {
331       double valNow = parmEntry->second.valNow;
332       double valDefault = parmEntry->second.valDefault;      
333       if ( writeAll || valNow != valDefault ) {
334         os  << parmEntry->second.name << " = ";
335         if ( valNow == 0. ) os << fixed << setprecision(1); 
336         else if ( abs(valNow) < 0.001 ) os << scientific << setprecision(4); 
337         else if ( abs(valNow) < 0.1 ) os << fixed << setprecision(7); 
338         else if ( abs(valNow) < 1000. ) os << fixed << setprecision(5); 
339         else if ( abs(valNow) < 1000000. ) os << fixed << setprecision(3); 
340         else os << scientific << setprecision(4); 
341         os << valNow << "\n";
342       }
343       ++parmEntry;
344
345     // Else print word. 
346     } else {
347       string valNow = wordEntry->second.valNow;
348       string valDefault = wordEntry->second.valDefault; 
349       if ( writeAll || valNow != valDefault ) 
350         os << wordEntry->second.name << " = " << valNow << "\n";
351       ++wordEntry;
352     }
353   } ;
354
355   // Done.
356   return true;
357 }
358
359 //--------------------------------------------------------------------------
360  
361 // Print out table of database in lexigraphical order.
362
363 void Settings::list(bool doListAll,  bool doListString, string match,
364   ostream& os) {
365
366   // Table header; output for bool as off/on.
367   if (doListAll) 
368     os << "\n *-------  PYTHIA Flag + Mode + Parm + Word Settings (all) "
369        << " -------------------------------------------------------* \n";
370   else if (!doListString) 
371     os << "\n *-------  PYTHIA Flag + Mode + Parm + Word Settings (chang" 
372        << "es only)  ----------------------------------------------* \n" ;
373   else
374     os << "\n *-------  PYTHIA Flag + Mode + Parm + Word Settings (with " 
375        << "requested string)  -------------------------------------* \n" ;
376   os << " |                                                           "
377      << "                                                      | \n"
378      << " | Name                                          |           "
379      << "           Now |      Default         Min         Max | \n"
380      << " |                                               |           "
381      << "               |                                      | \n";
382  
383   // Convert input string to lowercase for match.
384   match = toLower(match);
385   if (match == "") match = "             ";
386
387   // Iterators for the flag, mode and parm tables.
388   map<string, Flag>::iterator flagEntry = flags.begin();
389   map<string, Mode>::iterator modeEntry = modes.begin();
390   map<string, Parm>::iterator parmEntry = parms.begin();
391   map<string, Word>::iterator wordEntry = words.begin();
392
393   // Loop while there is something left to do.
394   while (flagEntry != flags.end() || modeEntry != modes.end() 
395     || parmEntry != parms.end() || wordEntry != words.end()) {
396
397     // Check if a flag is next in lexigraphical order; if so print it.
398     if ( flagEntry != flags.end() 
399       && ( modeEntry == modes.end() || flagEntry->first < modeEntry->first ) 
400       && ( parmEntry == parms.end() || flagEntry->first < parmEntry->first )
401       && ( wordEntry == words.end() || flagEntry->first < wordEntry->first ) 
402       ) {
403       string state[2] = {"off", "on"};
404       bool valNow = flagEntry->second.valNow;
405       bool valDefault = flagEntry->second.valDefault;
406       if ( doListAll || (!doListString && valNow != valDefault)
407         || (doListString && flagEntry->first.find(match) != string::npos) )
408         os << " | " << setw(45) << left 
409            << flagEntry->second.name << " | " << setw(24) << right
410            << state[valNow] << " | " << setw(12) << state[valDefault] 
411            << "                         | \n";
412       ++flagEntry;
413      
414     // Else check if mode is next, and if so print it.
415     } else if ( modeEntry != modes.end() 
416       && ( parmEntry == parms.end() || modeEntry->first < parmEntry->first ) 
417       && ( wordEntry == words.end() || modeEntry->first < wordEntry->first ) 
418       ) {
419       int valNow = modeEntry->second.valNow;
420       int valDefault = modeEntry->second.valDefault;
421       if ( doListAll || (!doListString && valNow != valDefault)
422         || (doListString && modeEntry->first.find(match) != string::npos) ) {
423         os << " | " << setw(45) << left 
424            << modeEntry->second.name << " | " << setw(24) << right 
425            << valNow << " | " << setw(12) << valDefault; 
426         if (modeEntry->second.hasMin) 
427           os << setw(12) << modeEntry->second.valMin; 
428         else os << "            ";
429         if (modeEntry->second.hasMax) 
430           os << setw(12) << modeEntry->second.valMax; 
431         else os << "            ";
432         os << " | \n";
433       }
434       ++modeEntry;
435       
436     // Else check if parm is next, and if so print it; 
437     // fixed or scientific depending on value.
438     } else if ( parmEntry != parms.end()
439       && ( wordEntry == words.end() || parmEntry->first < wordEntry->first ) 
440       ) {
441       double valNow = parmEntry->second.valNow;
442       double valDefault = parmEntry->second.valDefault;      
443       if ( doListAll || (!doListString && valNow != valDefault ) 
444         || (doListString && parmEntry->first.find(match) != string::npos) ) {
445         os << " | " << setw(45) << left 
446            << parmEntry->second.name << right << " |             ";
447         for (int i = 0; i < 4; ++i) { 
448           if (i == 1) valNow = valDefault;  
449           if (i == 2) valNow = parmEntry->second.valMin;  
450           if (i == 3) valNow = parmEntry->second.valMax;  
451           if ( (i == 2 && !parmEntry->second.hasMin)
452             || (i == 3 && !parmEntry->second.hasMax) )
453             os << "            ";
454           else if ( valNow == 0. ) 
455             os << fixed << setprecision(1) << setw(12) << valNow; 
456           else if ( abs(valNow) < 0.001 ) 
457             os << scientific << setprecision(4) << setw(12) << valNow;  
458           else if ( abs(valNow) < 0.1 )
459             os << fixed << setprecision(7) << setw(12) << valNow; 
460           else if ( abs(valNow) < 1000. )
461             os << fixed << setprecision(5) << setw(12) << valNow; 
462           else if ( abs(valNow) < 1000000. )
463             os << fixed << setprecision(3) << setw(12) << valNow; 
464           else 
465             os << scientific << setprecision(4) << setw(12) << valNow; 
466           if (i == 0) os << " | ";
467         }  
468         os << " | \n";
469       }
470       ++parmEntry;
471
472     // Else print word. 
473     } else {
474       string valNow = wordEntry->second.valNow;
475       string valDefault = wordEntry->second.valDefault; 
476       int blankLeft = max(0, 60 - max(24, int(valNow.length()) ) 
477         - max(12, int(valDefault.length()) ) );  
478       string blankPad( blankLeft, ' '); 
479       if ( doListAll || (!doListString && valNow != valDefault)
480         || (doListString && wordEntry->first.find(match) != string::npos) )
481         os << " | " << setw(45) << left 
482            << wordEntry->second.name << " | " << setw(24) << right
483            << valNow << " | " << setw(12) << valDefault << blankPad 
484            << " | \n";
485       ++wordEntry;
486     }
487   } ;
488
489   // End of loop over database contents.
490   os << " |                                                           "
491      << "                                                      | \n"
492      << " *-------  End PYTHIA Flag + Mode + Parm + Word Settings  ---"
493      << "------------------------------------------------------* " << endl;
494
495 }
496
497 //--------------------------------------------------------------------------
498  
499 // Reset all values to their defaults.
500
501 void Settings::resetAll() {
502
503   // Loop through the flags table, resetting all entries.
504   for (map<string, Flag>::iterator flagEntry = flags.begin();
505     flagEntry != flags.end(); ++flagEntry) {
506     string name = flagEntry->first;
507     resetFlag(name);
508   }
509
510   // Loop through the modes table, resetting all entries.
511   for (map<string, Mode>::iterator modeEntry = modes.begin();
512     modeEntry != modes.end(); ++modeEntry) {
513     string name = modeEntry->first;
514     resetMode(name);
515   }
516
517   // Loop through the parms table, resetting all entries.
518   for (map<string, Parm>::iterator parmEntry = parms.begin(); 
519     parmEntry != parms.end(); ++parmEntry) {
520     string name = parmEntry->first;
521     resetParm(name);
522   }
523
524   // Loop through the words table, resetting all entries.
525   for (map<string, Word>::iterator wordEntry = words.begin();
526     wordEntry != words.end(); ++wordEntry) {
527     string name = wordEntry->first;
528     resetWord(name);
529   }
530
531 }
532
533 //--------------------------------------------------------------------------
534  
535 // Give back current value, with check that key exists.
536
537 bool Settings::flag(string keyIn) {
538   if (isFlag(keyIn)) return flags[toLower(keyIn)].valNow; 
539   infoPtr->errorMsg("Error in Settings::flag: unknown key", keyIn);
540   return false; 
541 }
542
543 int Settings::mode(string keyIn) {
544   if (isMode(keyIn)) return modes[toLower(keyIn)].valNow; 
545   infoPtr->errorMsg("Error in Settings::mode: unknown key", keyIn);
546   return 0; 
547 }
548
549 double Settings::parm(string keyIn) {
550   if (isParm(keyIn)) return parms[toLower(keyIn)].valNow; 
551   infoPtr->errorMsg("Error in Settings::parm: unknown key", keyIn);
552   return 0.; 
553 }
554
555 string Settings::word(string keyIn) {
556   if (isWord(keyIn)) return words[toLower(keyIn)].valNow; 
557   infoPtr->errorMsg("Error in Settings::word: unknown key", keyIn);
558   return " "; 
559 }
560
561 //--------------------------------------------------------------------------
562  
563 // Get a map of entries whose names contain the string "match".
564
565 map<string, Flag> Settings::getFlagMap(string match) {
566   // Make the match string lower case. Start with an empty map.
567   match = toLower(match);
568   map<string, Flag> flagMap;  
569   // Loop over the flag map (using iterator).
570   for (map<string,Flag>::iterator flagEntry = flags.begin();
571        flagEntry != flags.end(); ++flagEntry)
572     if (flagEntry->first.find(match) != string::npos) 
573       flagMap[flagEntry->first] = flagEntry->second;
574   return flagMap;
575 }
576
577 map<string, Mode> Settings::getModeMap(string match) {
578   // Make the match string lower case. Start with an empty map.
579   match = toLower(match);
580   map<string, Mode> modeMap;  
581   // Loop over the mode map (using iterator).
582   for (map<string,Mode>::iterator modeEntry = modes.begin();
583        modeEntry != modes.end(); ++modeEntry)
584     if (modeEntry->first.find(match) != string::npos) 
585       modeMap[modeEntry->first] = modeEntry->second;
586   return modeMap;
587 }
588
589 map<string, Parm> Settings::getParmMap(string match) {
590   // Make the match string lower case. Start with an empty map.
591   match = toLower(match);
592   map<string, Parm> parmMap;  
593   // Loop over the parm map (using iterator).
594   for (map<string,Parm>::iterator parmEntry = parms.begin();
595        parmEntry != parms.end(); ++parmEntry)
596     if (parmEntry->first.find(match) != string::npos) 
597       parmMap[parmEntry->first] = parmEntry->second;
598   return parmMap;
599 }
600
601 map<string, Word> Settings::getWordMap(string match) {
602   // Make the match string lower case. Start with an empty map.
603   match = toLower(match);
604   map<string, Word> wordMap;  
605   // Loop over the word map (using iterator).
606   for (map<string,Word>::iterator wordEntry = words.begin();
607        wordEntry != words.end(); ++wordEntry)
608     if (wordEntry->first.find(match) != string::npos) 
609       wordMap[wordEntry->first] = wordEntry->second;
610   return wordMap;
611 }
612
613 //--------------------------------------------------------------------------
614  
615 // Change current value, respecting limits.
616
617 void Settings::flag(string keyIn, bool nowIn) { 
618     if (isFlag(keyIn)) flags[toLower(keyIn)].valNow = nowIn; 
619 }
620
621 void Settings:: mode(string keyIn, int nowIn) { 
622   if (isMode(keyIn)) { 
623     string keyLower = toLower(keyIn);
624     Mode& modeNow = modes[keyLower];
625     if (modeNow.hasMin && nowIn < modeNow.valMin) 
626       modeNow.valNow = modeNow.valMin; 
627     else if (modeNow.hasMax && nowIn > modeNow.valMax) 
628       modeNow.valNow = modeNow.valMax;
629     else modeNow.valNow = nowIn; 
630     // Tune:ee and Tune:pp each trigger a whole set of changes.
631     if (keyLower == "tune:ee") initTuneEE( modeNow.valNow);
632     if (keyLower == "tune:pp") initTunePP( modeNow.valNow); 
633   } 
634
635
636 void Settings::parm(string keyIn, double nowIn) { 
637   if (isParm(keyIn)) {
638     Parm& parmNow = parms[toLower(keyIn)];
639     if (parmNow.hasMin && nowIn < parmNow.valMin) 
640       parmNow.valNow = parmNow.valMin; 
641     else if (parmNow.hasMax && nowIn > parmNow.valMax) 
642       parmNow.valNow = parmNow.valMax;
643     else parmNow.valNow = nowIn; 
644   } 
645 }  
646
647 void Settings::word(string keyIn, string nowIn) { 
648     if (isWord(keyIn)) words[toLower(keyIn)].valNow = nowIn; 
649 }
650
651 //--------------------------------------------------------------------------
652
653 // Change current value, disregarding limits.
654   
655 void Settings::forceMode(string keyIn, int nowIn) { 
656   if (isMode(keyIn)) {
657     string keyLower = toLower(keyIn);
658     Mode& modeNow   = modes[keyLower];
659     modeNow.valNow  = nowIn; 
660     // Tune:ee and Tune:pp each trigger a whole set of changes.
661     if (keyLower == "tune:ee") initTuneEE( modeNow.valNow);
662     if (keyLower == "tune:pp") initTunePP( modeNow.valNow); 
663   }
664 }
665
666 void Settings::forceParm(string keyIn, double nowIn) { 
667   if (isParm(keyIn)) parms[toLower(keyIn)].valNow = nowIn; 
668 }
669
670 //--------------------------------------------------------------------------
671      
672 // Restore current value to default.
673  
674 void Settings::resetFlag(string keyIn) {
675   if (isFlag(keyIn)) flags[toLower(keyIn)].valNow 
676     = flags[toLower(keyIn)].valDefault ; 
677 }
678   
679 void Settings::resetMode(string keyIn) {
680   string keyLower = toLower(keyIn);
681   if (isMode(keyIn)) modes[keyLower].valNow 
682     = modes[toLower(keyIn)].valDefault ; 
683
684   // For Tune:ee must also restore variables involved in tune.
685   if (keyLower == "tune:ee") {
686     resetParm("StringFlav:probStoUD");
687     resetParm("StringFlav:probQQtoQ");
688     resetParm("StringFlav:probSQtoQQ");
689     resetParm("StringFlav:probQQ1toQQ0");
690     resetParm("StringFlav:mesonUDvector");
691     resetParm("StringFlav:mesonSvector");
692     resetParm("StringFlav:mesonCvector");
693     resetParm("StringFlav:mesonBvector");
694     resetParm("StringFlav:etaSup");
695     resetParm("StringFlav:etaPrimeSup");
696     resetParm("StringFlav:popcornSpair");  
697     resetParm("StringFlav:popcornSmeson");  
698     resetParm("StringZ:aLund");
699     resetParm("StringZ:bLund");  
700     resetParm("StringZ:rFactB");  
701     resetParm("StringPT:sigma");  
702     resetParm("TimeShower:alphaSvalue");  
703     resetParm("TimeShower:pTmin");  
704     resetParm("TimeShower:pTminChgQ");
705   }  
706
707   // For Tune:pp must also restore variables involved in tune.
708   if (keyLower == "tune:pp") {
709     resetMode("PDF:pSet");  
710     resetParm("SigmaProcess:alphaSvalue");  
711     resetFlag("SigmaDiffractive:dampen");  
712     resetFlag("TimeShower:dampenBeamRecoil");  
713     resetFlag("TimeShower:phiPolAsym");  
714     resetParm("SpaceShower:alphaSvalue");  
715     resetFlag("SpaceShower:samePTasMI");  
716     resetParm("SpaceShower:pT0Ref");  
717     resetParm("SpaceShower:ecmRef");  
718     resetParm("SpaceShower:ecmPow");  
719     resetFlag("SpaceShower:rapidityOrder");  
720     resetFlag("SpaceShower:phiPolAsym");  
721     resetFlag("SpaceShower:phiIntAsym");  
722     resetParm("MultipleInteractions:alphaSvalue");   
723     resetParm("MultipleInteractions:pT0Ref");  
724     resetParm("MultipleInteractions:ecmRef");  
725     resetParm("MultipleInteractions:ecmPow");  
726     resetMode("MultipleInteractions:bProfile");  
727     resetParm("BeamRemnants:primordialKTsoft");  
728     resetParm("BeamRemnants:primordialKThard");  
729     resetParm("BeamRemnants:halfScaleForKT");  
730     resetParm("BeamRemnants:halfMassForKT");  
731     resetParm("BeamRemnants:reconnectRange"); 
732   }  
733
734 }
735
736 void Settings::resetParm(string keyIn) {
737   if (isParm(keyIn)) parms[toLower(keyIn)].valNow 
738     = parms[toLower(keyIn)].valDefault ; 
739 }
740
741 void Settings::resetWord(string keyIn) {
742   if (isWord(keyIn)) words[toLower(keyIn)].valNow 
743     = words[toLower(keyIn)].valDefault ; 
744 }
745
746 //--------------------------------------------------------------------------
747
748 // Set the values related to a tune of e+e- data, 
749 // i.e. mainly for final-state radiation and hadronization.
750
751 void Settings::initTuneEE( int eeTune) {
752
753   // Old flavour and FSR defaults carried over from very old JETSET tune,
754   // only with alphaS roughly tuned for "new" pT-ordered shower.
755   if (eeTune == 1) { 
756     parm("StringFlav:probStoUD",     0.30  );
757     parm("StringFlav:probQQtoQ",     0.10  );
758     parm("StringFlav:probSQtoQQ",    0.40  );
759     parm("StringFlav:probQQ1toQQ0",  0.05  );
760     parm("StringFlav:mesonUDvector", 1.00  );
761     parm("StringFlav:mesonSvector",  1.50  );
762     parm("StringFlav:mesonCvector",  2.50  );
763     parm("StringFlav:mesonBvector",  3.00  );
764     parm("StringFlav:etaSup",        1.00  );
765     parm("StringFlav:etaPrimeSup",   0.40  );
766     parm("StringFlav:popcornSpair",  0.50  );  
767     parm("StringFlav:popcornSmeson", 0.50  );  
768     parm("StringZ:aLund",            0.30  );
769     parm("StringZ:bLund",            0.58  );  
770     parm("StringZ:rFactB",           1.00  );  
771     parm("StringPT:sigma",           0.36  );  
772     parm("TimeShower:alphaSvalue",   0.137 );  
773     parm("TimeShower:pTmin",         0.5   );  
774     parm("TimeShower:pTminChgQ",     0.5   );  
775   }
776
777   // Marc Montull's tune to particle composition at LEP1 (August 2007).
778   else if (eeTune == 2) {  
779     parm("StringFlav:probStoUD",     0.22  );
780     parm("StringFlav:probQQtoQ",     0.08  );
781     parm("StringFlav:probSQtoQQ",    0.75  );
782     parm("StringFlav:probQQ1toQQ0",  0.025 );
783     parm("StringFlav:mesonUDvector", 0.5   );
784     parm("StringFlav:mesonSvector",  0.6   );
785     parm("StringFlav:mesonCvector",  1.5   );
786     parm("StringFlav:mesonBvector",  2.5   );
787     parm("StringFlav:etaSup",        0.60  );
788     parm("StringFlav:etaPrimeSup",   0.15  );
789     parm("StringFlav:popcornSpair",  1.0   );
790     parm("StringFlav:popcornSmeson", 1.0   );
791     parm("StringZ:aLund",            0.76  );
792     parm("StringZ:bLund",            0.58  );   // kept fixed
793     parm("StringZ:rFactB",           1.00  );   // kept fixed
794     parm("StringPT:sigma",           0.36  );   // kept fixed
795     parm("TimeShower:alphaSvalue",   0.137 );   // kept fixed 
796     parm("TimeShower:pTmin",         0.5   );   // kept fixed 
797     parm("TimeShower:pTminChgQ",     0.5   );   // kept fixed
798   }
799
800   // Full e+e- tune of flavours and FSR to LEP1 data within the 
801   // Rivet + Professor framework, by Hendrik Hoeth (June 2009).
802   else if (eeTune == 3) {  
803     parm("StringFlav:probStoUD",     0.19  );
804     parm("StringFlav:probQQtoQ",     0.09  );
805     parm("StringFlav:probSQtoQQ",    1.00  );
806     parm("StringFlav:probQQ1toQQ0",  0.027 );
807     parm("StringFlav:mesonUDvector", 0.62  );
808     parm("StringFlav:mesonSvector",  0.725 );
809     parm("StringFlav:mesonCvector",  1.06  );
810     parm("StringFlav:mesonBvector",  3.0   );
811     parm("StringFlav:etaSup",        0.63  );
812     parm("StringFlav:etaPrimeSup",   0.12  );
813     parm("StringFlav:popcornSpair",  0.5   );   // kept fixed
814     parm("StringFlav:popcornSmeson", 0.5   );   // kept fixed
815     parm("StringZ:aLund",            0.3   );   // kept fixed
816     parm("StringZ:bLund",            0.8   );  
817     parm("StringZ:rFactB",           0.67  );  
818     parm("StringPT:sigma",           0.304 );  
819     parm("TimeShower:alphaSvalue",   0.1383);  
820     parm("TimeShower:pTmin",         0.4   );   // kept fixed (near limit) 
821     parm("TimeShower:pTminChgQ",     0.4   );   // kept same as pTmin
822   }
823   
824 }
825
826 //--------------------------------------------------------------------------
827
828 // Set the values related to a tune of pp/ppbar data, 
829 // i.e. mainly for initial-state radiation and multiple interactions.
830
831 void Settings::initTunePP( int ppTune) {
832
833   // Old ISR and MI defaults from early and primitive comparisons with data.
834   if (ppTune == 1) {
835     mode("PDF:pSet",                         2     );  
836     parm("SigmaProcess:alphaSvalue",         0.1265);  
837     flag("SigmaDiffractive:dampen",          false );  
838     flag("TimeShower:dampenBeamRecoil",      false );  
839     flag("TimeShower:phiPolAsym",            false );  
840     parm("SpaceShower:alphaSvalue",          0.127 );  
841     flag("SpaceShower:samePTasMI",           true  );  
842     parm("SpaceShower:pT0Ref",               2.2   );  
843     parm("SpaceShower:ecmRef",               1800.0);  
844     parm("SpaceShower:ecmPow",               0.16  );  
845     flag("SpaceShower:rapidityOrder",        false );  
846     flag("SpaceShower:phiPolAsym",           false );  
847     flag("SpaceShower:phiIntAsym",           false );  
848     parm("MultipleInteractions:alphaSvalue", 0.127 );   
849     parm("MultipleInteractions:pT0Ref",      2.15  );  
850     parm("MultipleInteractions:ecmRef",      1800. );  
851     parm("MultipleInteractions:ecmPow",      0.16  );  
852     mode("MultipleInteractions:bProfile",    2     );  
853     parm("BeamRemnants:primordialKTsoft",    0.4   );  
854     parm("BeamRemnants:primordialKThard",    2.1   );  
855     parm("BeamRemnants:halfScaleForKT",      7.0   );  
856     parm("BeamRemnants:halfMassForKT",       2.0   );  
857     parm("BeamRemnants:reconnectRange",      2.5   ); 
858   }
859   
860   // "Tune 1" simple first tune by Peter Skands to ISR and MI, July 2009.
861   else if (ppTune == 2) {
862     mode("PDF:pSet",                         2     );  
863     parm("SigmaProcess:alphaSvalue",         0.1265);   
864     flag("SigmaDiffractive:dampen",          false );  
865     flag("TimeShower:dampenBeamRecoil",      false );  
866     flag("TimeShower:phiPolAsym",            false );  
867     parm("SpaceShower:alphaSvalue",          0.137 );  
868     flag("SpaceShower:samePTasMI",           false );  
869     parm("SpaceShower:pT0Ref",               2.0   );  
870     parm("SpaceShower:ecmRef",               1800.0);  
871     parm("SpaceShower:ecmPow",               0.0   );  
872     flag("SpaceShower:rapidityOrder",        false );  
873     flag("SpaceShower:phiPolAsym",           false );  
874     flag("SpaceShower:phiIntAsym",           false );  
875     parm("MultipleInteractions:alphaSvalue", 0.127 );   
876     parm("MultipleInteractions:pT0Ref",      2.25  );  
877     parm("MultipleInteractions:ecmRef",      1800. );  
878     parm("MultipleInteractions:ecmPow",      0.24  );  
879     mode("MultipleInteractions:bProfile",    1     );  
880     parm("BeamRemnants:primordialKTsoft",    0.5   );  
881     parm("BeamRemnants:primordialKThard",    2.0   );  
882     parm("BeamRemnants:halfScaleForKT",      1.0   );  
883     parm("BeamRemnants:halfMassForKT",       1.0   );  
884     parm("BeamRemnants:reconnectRange",      10.0  );  
885   }
886   
887   // Tune 2C, July 2010.
888   else if (ppTune == 3) {
889     mode("PDF:pSet",                         8     );  
890     parm("SigmaProcess:alphaSvalue",         0.135 );  
891     flag("SigmaDiffractive:dampen",          false );  
892     flag("TimeShower:dampenBeamRecoil",      true  );  
893     flag("TimeShower:phiPolAsym",            true  );  
894     parm("SpaceShower:alphaSvalue",          0.137 );  
895     flag("SpaceShower:samePTasMI",           false );  
896     parm("SpaceShower:pT0Ref",               2.0   );  
897     parm("SpaceShower:ecmRef",               1800.0);  
898     parm("SpaceShower:ecmPow",               0.0   );  
899     flag("SpaceShower:rapidityOrder",        true  );  
900     flag("SpaceShower:phiPolAsym",           true  );  
901     flag("SpaceShower:phiIntAsym",           true  );  
902     parm("MultipleInteractions:alphaSvalue", 0.135 );   
903     parm("MultipleInteractions:pT0Ref",      2.32  );  
904     parm("MultipleInteractions:ecmRef",      1800. );  
905     parm("MultipleInteractions:ecmPow",      0.21  );  
906     mode("MultipleInteractions:bProfile",    3     );  
907     parm("MultipleInteractions:expPow",      1.6   );  
908     parm("BeamRemnants:primordialKTsoft",    0.5   );  
909     parm("BeamRemnants:primordialKThard",    2.0   );  
910     parm("BeamRemnants:halfScaleForKT",      1.0   );  
911     parm("BeamRemnants:halfMassForKT",       1.0   );  
912     parm("BeamRemnants:reconnectRange",      3.0   );  
913   }
914   
915   // Tune 2M, July 2010.
916   else if (ppTune == 4) {
917     mode("PDF:pSet",                         4     );  
918     parm("SigmaProcess:alphaSvalue",         0.1265);  
919     flag("SigmaDiffractive:dampen",          false );  
920     flag("TimeShower:dampenBeamRecoil",      true  );  
921     flag("TimeShower:phiPolAsym",            true  );  
922     parm("SpaceShower:alphaSvalue",          0.130 );  
923     flag("SpaceShower:samePTasMI",           false );  
924     parm("SpaceShower:pT0Ref",               2.0   );  
925     parm("SpaceShower:ecmRef",               1800.0);  
926     parm("SpaceShower:ecmPow",               0.0   );  
927     flag("SpaceShower:rapidityOrder",        true  );  
928     flag("SpaceShower:phiPolAsym",           true  );  
929     flag("SpaceShower:phiIntAsym",           true  );  
930     parm("MultipleInteractions:alphaSvalue", 0.127 );   
931     parm("MultipleInteractions:pT0Ref",      2.455 );  
932     parm("MultipleInteractions:ecmRef",      1800. );  
933     parm("MultipleInteractions:ecmPow",      0.26  );  
934     mode("MultipleInteractions:bProfile",    3     );  
935     parm("MultipleInteractions:expPow",      1.15  );  
936     parm("BeamRemnants:primordialKTsoft",    0.5   );  
937     parm("BeamRemnants:primordialKThard",    2.0   );  
938     parm("BeamRemnants:halfScaleForKT",      1.0   );  
939     parm("BeamRemnants:halfMassForKT",       1.0   );  
940     parm("BeamRemnants:reconnectRange",      3.0   );  
941   }
942  
943   // Tune 4C, October 2010.
944   else if (ppTune == 5) {
945     mode("PDF:pSet",                         8     );  
946     parm("SigmaProcess:alphaSvalue",         0.135 );  
947     flag("SigmaDiffractive:dampen",          true  );
948     parm("SigmaDiffractive:maxXB",           65.0  );
949     parm("SigmaDiffractive:maxAX",           65.0  );
950     parm("SigmaDiffractive:maxXX",           65.0  );  
951     flag("TimeShower:dampenBeamRecoil",      true  );  
952     flag("TimeShower:phiPolAsym",            true  );  
953     parm("SpaceShower:alphaSvalue",          0.137 );  
954     flag("SpaceShower:samePTasMI",           false );  
955     parm("SpaceShower:pT0Ref",               2.0   );  
956     parm("SpaceShower:ecmRef",               1800.0);  
957     parm("SpaceShower:ecmPow",               0.0   );  
958     flag("SpaceShower:rapidityOrder",        true  );  
959     flag("SpaceShower:phiPolAsym",           true  );  
960     flag("SpaceShower:phiIntAsym",           true  );  
961     parm("MultipleInteractions:alphaSvalue", 0.135 );   
962     parm("MultipleInteractions:pT0Ref",      2.085 );  
963     parm("MultipleInteractions:ecmRef",      1800. );  
964     parm("MultipleInteractions:ecmPow",      0.19  );  
965     mode("MultipleInteractions:bProfile",    3     );  
966     parm("MultipleInteractions:expPow",      2.0   );  
967     parm("BeamRemnants:primordialKTsoft",    0.5   );  
968     parm("BeamRemnants:primordialKThard",    2.0   );  
969     parm("BeamRemnants:halfScaleForKT",      1.0   );  
970     parm("BeamRemnants:halfMassForKT",       1.0   );  
971     parm("BeamRemnants:reconnectRange",      1.5   );  
972   }
973
974 }
975
976 //--------------------------------------------------------------------------
977
978 // Convert string to lowercase for case-insensitive comparisons.
979 // Also remove initial and trailing blanks, if any.
980
981 string Settings::toLower(const string& name) { 
982
983   // Copy string without initial and trailing blanks.
984   if (name.find_first_not_of(" \n\t\v\b\r\f\a") == string::npos) return "";
985   int firstChar = name.find_first_not_of(" \n\t\v\b\r\f\a");
986   int lastChar  = name.find_last_not_of(" \n\t\v\b\r\f\a");
987   string temp   = name.substr( firstChar, lastChar + 1 - firstChar);
988
989   // Convert to lowercase letter by letter.
990   for (int i = 0; i < int(temp.length()); ++i) 
991     temp[i] = std::tolower(temp[i]); 
992   return temp; 
993
994 }
995
996 //--------------------------------------------------------------------------
997
998 // Allow several alternative inputs for true/false.
999
1000 bool Settings::boolString(string tag) {
1001
1002   string tagLow = toLower(tag);
1003   return ( tagLow == "true" || tagLow == "1" || tagLow == "on" 
1004   || tagLow == "yes" || tagLow == "ok" ); 
1005
1006 }  
1007
1008 //--------------------------------------------------------------------------
1009
1010 // Extract XML value string following XML attribute.
1011
1012 string Settings::attributeValue(string line, string attribute) {
1013
1014   if (line.find(attribute) == string::npos) return "";
1015   int iBegAttri = line.find(attribute); 
1016   int iBegQuote = line.find("\"", iBegAttri + 1);
1017   int iEndQuote = line.find("\"", iBegQuote + 1);
1018   return line.substr(iBegQuote + 1, iEndQuote - iBegQuote - 1);
1019
1020 }
1021
1022 //--------------------------------------------------------------------------
1023
1024 // Extract XML bool value following XML attribute.
1025
1026 bool Settings::boolAttributeValue(string line, string attribute) {
1027
1028   string valString = attributeValue(line, attribute);
1029   if (valString == "") return false;
1030   return boolString(valString);   
1031
1032 }
1033
1034 //--------------------------------------------------------------------------
1035
1036 // Extract XML int value following XML attribute.
1037
1038 int Settings::intAttributeValue(string line, string attribute) {
1039   string valString = attributeValue(line, attribute);
1040   if (valString == "") return 0; 
1041   istringstream valStream(valString);
1042   int intVal; 
1043   valStream >> intVal; 
1044   return intVal;     
1045
1046 }
1047
1048 //--------------------------------------------------------------------------
1049
1050 // Extract XML double value following XML attribute.
1051
1052 double Settings::doubleAttributeValue(string line, string attribute) {
1053   string valString = attributeValue(line, attribute);
1054   if (valString == "") return 0.; 
1055   istringstream valStream(valString);
1056   double doubleVal; 
1057   valStream >> doubleVal; 
1058   return doubleVal;     
1059
1060 }
1061
1062 //==========================================================================
1063
1064 } // end namespace Pythia8