Roll back
[u/mrichter/AliRoot.git] / PYTHIA8 / pythia8175 / include / SusyLesHouches.h
1 // SusyLesHouches.h is a part of the PYTHIA event generator.
2 // Copyright (C) 2013 Torbjorn Sjostrand.
3 // Main authors of this file: N. Desai, P. Skands
4 // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
5 // Please respect the MCnet Guidelines, see GUIDELINES for details.
6
7 // Header file for SUSY Les Houches Accord Interface
8 // Is independent of the rest of the PYTHIA implementation and thus could
9 // be re-used stand-alone or merged into other applications, subject to 
10 // the MCnet Guidelines mentioned above.
11
12 #ifndef SLHA_H
13 #define SLHA_H
14
15 // Stdlib header files for string and character manipulation.
16 #include <string>
17 #include <cctype>
18 // Stdlib header files for containers.
19 #include <vector>
20 #include <map>
21 // Stdlib header files for input/output.
22 #include <iostream>
23 #include <iomanip>
24 #include <fstream>
25 #include <sstream>
26 // Stdlib header files for mathematics.
27 #include <cmath>
28 #include <cstdlib>
29
30 // Stdlib namespace
31 using namespace std;
32
33 //************************* SLHA AUX CLASSES *****************************//
34
35 namespace Pythia8 { 
36
37   //class LHblock: the generic SLHA block (see below for matrices)
38   //Explicit typing required, e.g. block<double> minpar;
39   template <class T> class LHblock {    
40     
41   public: 
42     
43     //Constructor. 
44     LHblock<T>() : idnow(0),qDRbar(0),i(0) {} ;    
45     
46     //Does block exist?
47     bool exists() { return int(entry.size()) == 0 ? false : true ; };
48     //Clear block
49     void clear() { entry.clear(); };    
50     
51     //set: set block entry values.
52     //Possible return values from set:
53     // 0: normal return. Entry did not previously exist and has been created.
54     // 1: normal return. Entry did previously exist and has been overwritten.
55     //-1: failure. 
56     int set(int iIn,T valIn) { 
57       int alreadyexisting=exists(iIn)?1:0;
58       entry[iIn]=valIn; 
59       return alreadyexisting;
60     };
61     // Read index and value from SLHA data line
62     int set(istringstream& linestream, bool indexed=true) {
63       i = 0;
64       if (indexed) linestream >> i >> val;
65       else linestream >> val;
66       return linestream ? set(i,val) : -1;
67     };
68     // With i already given, read value from remaining SLHA data line
69     int set(int iIn,istringstream& linestream) {
70       linestream >> val;
71       return linestream ? set(iIn,val) : -1;
72     };
73     // Shorthand for entry[0]. Used e.g. for block ALPHA.
74     void set(T valIn) { entry[0]=valIn; };
75
76     // Does entry i already exist in this block?
77     bool exists(int iIn) {return entry.find(iIn) != entry.end() 
78       ? true : false;};
79
80     // Indexing with (). Output only.
81     T operator()() {
82       if (exists(0)) {return entry[0];} else {T dummy(0); return dummy;};
83     };
84     T operator()(int iIn) {
85       if (exists(iIn)) {return entry[iIn];} else {T dummy(0); return dummy;};
86     };
87
88     // Size of map
89     int size() {return int(entry.size());};
90
91     // First and next key code
92     int first() { idnow = entry.begin()->first; return idnow; };
93     int next() { 
94       typename map<int,T>::iterator itnow;
95       itnow = ++entry.find(idnow);
96       if ( itnow == entry.end() ) itnow=entry.begin();
97       return idnow = itnow->first;
98     };
99
100     // Simple print utility
101     void print() {
102       bool finished=false;
103       int ibegin=first();
104       i=ibegin;
105       while (!finished) {
106         cout << "  "<< i << " " << entry[i] <<endl;
107         i=next();
108         if (i == ibegin) finished=true;
109       };       
110     };
111
112     // Special for DRbar running blocks.
113     void setq(double qIn) { qDRbar=qIn; }
114     double q() { return qDRbar; }
115  
116   protected: 
117     map<int,T> entry;    
118
119   private:
120     int idnow;
121     double qDRbar;
122     //Auxiliary vars
123     int i; 
124     T val;
125   };
126
127   // Derived class for generic blocks containing vectors of strings.
128   class LHgenericBlock : public LHblock<string> {    
129
130   public:
131     
132     //Constructor. 
133     LHgenericBlock() { } ;    
134
135     // Read index and value from SLHA data line
136     int set(string lineIn) {
137       entry[entry.size()] = lineIn;
138       return 0;
139     };
140     
141   };
142
143   // class LHmatrixBlock: the generic SLHA matrix 
144   // Explicit sizing required, e.g.LHmatrixBlock<4> nmix;
145   template <int size> class LHmatrixBlock {    
146   public: 
147     //Constructor. Set uninitialized and explicitly zero.
148     LHmatrixBlock<size>() :  initialized(false),qDRbar(0),i(0),j(0),val(0){  
149       for (i=1;i<=size;i++) {
150         for (j=1;j<=size;j++) {
151           entry[i][j]=0.0;
152         };
153       };
154     };    
155     
156     // Assignment
157     LHmatrixBlock& operator=(const LHmatrixBlock& m) { 
158       if (this != &m) { 
159         for (i=0;i<size;i++) for (j=0;j<=size;j++) entry[i][j] = m(i,j);
160         qDRbar = m.qDRbar; 
161         initialized = m.initialized; 
162       } 
163       return *this; };
164
165     // Does this matrix contain any entries?
166     bool exists() { return initialized; };
167     // Clear initialized flag
168     void clear() { initialized=false; };
169
170     // Set matrix entry
171     int set(int iIn,int jIn, double valIn) { 
172       if (iIn>0 && jIn>0 && iIn<=size && jIn<=size) {
173         entry[iIn][jIn]=valIn;
174         initialized=true;
175         return 0;
176       } else {
177         return -1;
178       };
179     };
180
181     // Set entry from linestream (used during file read)
182     int set(istringstream& linestream) {
183       linestream >> i >> j >> val;
184       return linestream ? set(i,j,val) : -1;
185     };
186
187     // () Overloading: Get entry
188     double operator()(int iIn, int jIn) const {
189       return (iIn <= size && jIn <= size && iIn > 0 && jIn > 0) ? 
190         entry[iIn][jIn] : 0.0;
191     };
192
193     // Set and get scale for DRbar running LHblocks.
194     void setq(double qIn) { qDRbar=qIn; }
195     double q() { return qDRbar; }
196
197     // Simple print utility, to be elaborated on.
198     void print() {
199       for (i=1;i<=size;i++) {
200         cout << "   "<<i << " " ;
201         for (j=1;j<=size;j++) cout << entry[i][j] << " ";
202         cout << endl;
203       };
204     };
205
206   private:
207     bool initialized;
208     double entry[size+1][size+1];
209     double qDRbar;
210     //Auxiliary vars
211     int i,j; 
212     double val;
213   };
214
215   // class tensorBlock: the generic SLHA tensor
216   // Explicit sizing required, e.g. tensorBlock<3> rvlam;
217   template <int size> class LHtensor3Block {    
218   public: 
219     //Constructor. Set uninitialized and explicitly zero.
220     LHtensor3Block<size>() : initialized(false),qDRbar(0),i(0),j(0),k(0),val(0){ 
221        
222       for (i=1;i<=size;i++) {
223         for (j=1;j<=size;j++) {
224           for (k=1;k<=size;k++) {
225             entry[i][j][k]=0.0;
226           };
227         };
228       };
229     };    
230     
231     // Assignment
232     LHtensor3Block& operator=(const LHtensor3Block& m) { 
233       if (this != &m) { 
234         for (i=0;i<size;i++) for (j=0;j<=size;j++) for (k=0;k<=size;k++) 
235           entry[i][j][k] = m(i,j,k);
236         qDRbar = m.qDRbar; 
237         initialized = m.initialized; 
238       } 
239       return *this; };
240     
241     // Does this matrix contain any entries?
242     bool exists() { return initialized; };
243     // Clear initialized flag
244     void clear() { initialized=false; };
245     
246     // Set matrix entry
247     int set(int iIn,int jIn, int kIn, double valIn) { 
248       if (iIn>0 && jIn>0 && kIn>0 && iIn<=size && jIn<=size && kIn<=size) {
249         entry[iIn][jIn][kIn]=valIn;
250         initialized=true;
251         return 0;
252       } else {
253         return -1;
254       };
255     };
256
257     // Set entry from linestream (used during file read)
258     int set(istringstream& linestream) {
259       linestream >> i >> j >> k >> val;
260       return linestream ? set(i,j,k,val) : -1;
261     };
262
263     // () Overloading: Get entry
264     double operator()(int iIn, int jIn, int kIn) const {
265       return (iIn <= size && jIn <= size && kIn <= size && iIn > 0 
266         && jIn > 0 && kIn > 0) ? entry[iIn][jIn][kIn] : 0.0;
267     };
268
269     // Set and get scale for DRbar running LHblocks.
270     void setq(double qIn) { qDRbar=qIn; }
271     double q() { return qDRbar; }
272
273     // Simple print utility, to be elaborated on.
274     void print() {
275       for (i=1;i<=size;i++) {   
276         for (j=1;j<=size;j++) {
277           cout << "   "<<i << " "<<j << " " ;
278           for (k=1;k<=size;k++) {
279             cout << entry[i][j][k] << " ";         
280             cout << endl; 
281           };
282         };
283       };
284     };
285
286   private:
287     bool initialized;
288     double entry[size+1][size+1][size+1];
289     double qDRbar;
290     //Auxiliary vars
291     int i,j,k; 
292     double val;
293   };
294
295   //*************************** DECAY TABLES ***************************//
296
297   class LHdecayChannel {
298   public: 
299
300   LHdecayChannel() : brat(0.0),comment("") {};
301     LHdecayChannel(double bratIn, int nDaIn, vector<int> idDaIn, 
302       string cIn="") { setChannel(bratIn,nDaIn,idDaIn,cIn);
303     }
304
305     // Functions to set decay channel information
306     void setChannel(double bratIn, int nDaIn, vector<int> idDaIn, 
307       string cIn="") {
308       brat    = bratIn;
309       for (int i=0; i<=nDaIn; i++) {
310         if (i < int(idDaIn.size())) idDa.push_back(idDaIn[i]);
311         comment = cIn;
312       }
313     }
314     void setBrat(double bratIn) {brat=bratIn;}
315     void setIdDa(vector<int> idDaIn) {idDa = idDaIn;}
316     
317     // Functions to get decay channel information
318     double getBrat() {return brat;}
319     int getNDa() {return int(idDa.size());}
320     vector<int> getIdDa() {return idDa;}
321     string getComment() {return comment;}
322     
323   private:
324     double brat;
325     vector<int> idDa;
326     string comment;
327       
328   };
329
330   class LHdecayTable {        
331   public: 
332     
333   LHdecayTable() : id(0), width(0.0) {};
334   LHdecayTable(int idIn) : id(idIn), width(0.0) {};
335   LHdecayTable(int idIn, double widthIn) : id(idIn), width(widthIn) {};
336     
337     // Functions to get PDG code (id) and width
338     int    getId() {return id;}
339     double getWidth() {return width;} 
340     
341     // Functions to set PDG code (id) and width
342     void setId(int idIn) {id = idIn;}
343     void setWidth(double widthIn) {width=widthIn;}
344
345     // Function to reset size and width (width -> 0 by default)
346     void reset(double widthIn=0.0) {table.resize(0); width=widthIn;}
347     
348     // Function to add another decay channel
349     void addChannel(LHdecayChannel channelIn) {table.push_back(channelIn);}
350     void addChannel(double bratIn, int nDaIn, vector<int> idDaIn, 
351       string cIn="") {
352       LHdecayChannel newChannel(bratIn, nDaIn, idDaIn, cIn);
353       table.push_back(newChannel);
354     }
355
356     // Function to return number of decay channels
357     int size() {return int(table.size());}
358
359     // Function to return a branching ratio
360     double getBrat(int iChannel) {
361       if (iChannel >= 0 && iChannel < int(table.size())) {
362         return table[iChannel].getBrat();
363       } else {
364         return 0.0;
365       }
366     }
367     // Function to return daughter PDG codes 
368     vector<int> getIdDa(int iChannel) {
369       if (iChannel >= 0 && iChannel < int(table.size())) {
370         return table[iChannel].getIdDa();
371       } else {
372         vector<int> dum;
373         return dum;
374       }
375     }
376     // Function to return a decay channel
377     LHdecayChannel getChannel(int iChannel) {
378       if (iChannel >= 0 && iChannel < int(table.size())) {
379         return table[iChannel];
380       } else {
381         LHdecayChannel dum;
382         return dum;
383       }
384     }
385     
386   private:
387     int id;
388     double width;
389     vector<LHdecayChannel> table;
390
391   };
392
393 //==========================================================================
394
395 class SusyLesHouches {
396
397 public:
398
399   //Constructor, with and without filename.
400   SusyLesHouches(int verboseIn=1) : verbose(verboseIn), 
401     headerPrinted(false), footerPrinted(false), filePrinted(false),
402     slhaRead(false), lhefRead(false), lhefSlha(false), useDecay(true) {};
403   SusyLesHouches(string filename, int verboseIn=1) : verbose(verboseIn), 
404     headerPrinted(false), footerPrinted(false), filePrinted(false),
405     slhaRead(true), lhefRead(false), lhefSlha(false), useDecay(true) 
406     {readFile(filename);};
407
408   //***************************** SLHA FILE I/O *****************************//
409   // Read and write SLHA files 
410   int readFile(string slhaFileIn="slha.spc",int verboseIn=1, 
411     bool useDecayIn=true); 
412   //int writeFile(string filename): write SLHA file on filename
413
414   //Output utilities
415   void printHeader();   // print Header
416   void printFooter();   // print Footer
417   void printSpectrum(int ifail=0); // print Spectrum
418
419   // Check spectrum and decays
420   int checkSpectrum();
421   int checkDecays();
422
423   // File Name (can be either SLHA or LHEF)
424   string slhaFile;
425
426   // Class for SLHA data entry
427   class Entry {
428     
429   public:
430     //Constructor. 
431     Entry() : isIntP(false), isDoubleP(false), 
432       isStringP(false), n(0), d(0.0), s(""), commentP("") {}
433     
434     // Generic functions to inquire whether an int, double, or string
435     bool isInt(){return isIntP;}
436     bool isDouble(){return isDoubleP;}
437     bool isString(){return isStringP;}
438
439     // = Overloading: Set entry to int, double, or string
440     Entry& operator=(double& val)  {
441       d=val;isIntP=false;isDoubleP=true;isStringP=false;
442       return *this;      
443     };
444     Entry& operator=(int& val)  {
445       n=val;isIntP=true;isDoubleP=false;isStringP=false;
446       return *this;
447     };
448     Entry& operator=(string& val)  {
449       s=val;isIntP=false;isDoubleP=false;isStringP=true;
450       return *this;
451     };
452     
453     // Set and Get comment
454     void setComment(string comment) {commentP=comment;}
455     void getComment(string comment) {comment=commentP;}
456
457     // Generic functions to get value
458     bool get(int& val) {val=n; return isIntP;}
459     bool get(double& val) {val=d; return isDoubleP;}
460     bool get(string& val) {val=s; return isStringP;}
461
462   private:
463     bool isIntP, isDoubleP, isStringP;    
464     int n;
465     double d;
466     string s;
467     string commentP;
468     
469   };
470
471   //*************************** THE SLHA1 BLOCKS ***************************//
472   //Blocks for model definition:
473   LHblock<int> modsel;
474   LHblock<int> modsel21;
475   LHblock<double> modsel12;
476   LHblock<double> minpar;
477   LHblock<double> extpar;
478   LHblock<double> sminputs;
479   //Blocks for RGE program specific output
480   LHblock<string> spinfo;
481   LHblock<string> spinfo3;
482   LHblock<string> spinfo4;
483   //Blocks for DCY program specific output
484   LHblock<string> dcinfo;
485   LHblock<string> dcinfo3;
486   LHblock<string> dcinfo4;
487   //Blocks for mass and coupling spectrum
488   LHblock<double> mass;
489   LHmatrixBlock<4> nmix;
490   LHmatrixBlock<2> umix;
491   LHmatrixBlock<2> vmix;
492   LHmatrixBlock<2> stopmix;
493   LHmatrixBlock<2> sbotmix;
494   LHmatrixBlock<2> staumix;
495   LHblock<double> alpha;
496   LHblock<double> hmix;
497   LHblock<double> gauge;
498   LHblock<double> msoft;
499   LHmatrixBlock<3> au;
500   LHmatrixBlock<3> ad;
501   LHmatrixBlock<3> ae;
502   LHmatrixBlock<3> yu;
503   LHmatrixBlock<3> yd;
504   LHmatrixBlock<3> ye;
505
506   //************************ THE SLHA1 DECAY TABLES ************************//
507   vector<LHdecayTable> decays;
508   map<int,int> decayIndices;
509
510   //********************* THE BSM-SLHA QNUMBERS BLOCKS *********************//
511   vector< LHblock<int> > qnumbers;     // Zero'th entry is PDG code
512   vector< string > qnumbersName;
513   vector< string > qnumbersAntiName;
514
515   //*************************** THE SLHA2 BLOCKS ***************************//
516   //Additions to SLHA1
517   LHblock<double> qextpar;  
518
519   //FLV Input
520   LHblock<double> vckmin;  // The input CKM Wolfenstein parms.
521   LHblock<double> upmnsin; // The input PMNS PDG parms.
522   LHmatrixBlock<3> msq2in; // The input upper off-diagonal msq2
523   LHmatrixBlock<3> msu2in; // The input upper off-diagonal msu2
524   LHmatrixBlock<3> msd2in; // The input upper off-diagonal msd2
525   LHmatrixBlock<3> msl2in; // The input upper off-diagonal msl2
526   LHmatrixBlock<3> mse2in; // The input upper off-diagonal mse2
527   LHmatrixBlock<3> tuin;   // The input upper off-diagonal TU
528   LHmatrixBlock<3> tdin;   // The input upper off-diagonal TD
529   LHmatrixBlock<3> tein;   // The input upper off-diagonal TE
530   //FLV Output
531   LHmatrixBlock<3> vckm;    // The output DRbar running Re{VCKM} at Q
532   LHmatrixBlock<3> upmns;   // The output DRbar running Re{UPMNS} at Q
533   LHmatrixBlock<3> msq2;    // The output DRbar running msq2 at Q
534   LHmatrixBlock<3> msu2;    // The output DRbar running msu2 at Q
535   LHmatrixBlock<3> msd2;    // The output DRbar running msd2 at Q
536   LHmatrixBlock<3> msl2;    // The output DRbar running msl2 at Q
537   LHmatrixBlock<3> mse2;    // The output DRbar running mse2 at Q
538   LHmatrixBlock<3> tu;      // The output DRbar running TU at Q
539   LHmatrixBlock<3> td;      // The output DRbar running TD at Q
540   LHmatrixBlock<3> te;      // The output DRbar running TE at Q
541   LHmatrixBlock<6> usqmix;  // The Re{} up squark mixing matrix
542   LHmatrixBlock<6> dsqmix;   // The Re{} down squark mixing matrix
543   LHmatrixBlock<6> selmix;   // The Re{} selectron mixing matrix
544   LHmatrixBlock<3> snumix;   // The Re{} sneutrino mixing matrix
545   LHmatrixBlock<3> snsmix;   // The scalar sneutrino mixing matrix
546   LHmatrixBlock<3> snamix;   // The pseudoscalar neutrino mixing matrix
547   
548   //RPV Input
549   LHtensor3Block<3> rvlamllein; // The input LNV lambda couplings
550   LHtensor3Block<3> rvlamlqdin; // The input LNV lambda' couplings
551   LHtensor3Block<3> rvlamuddin; // The input BNV lambda'' couplings
552   LHtensor3Block<3> rvtllein;   // The input LNV T couplings
553   LHtensor3Block<3> rvtlqdin;   // The input LNV T' couplings
554   LHtensor3Block<3> rvtuddin;   // The input BNV T'' couplings
555   LHblock<double> rvkappain;    // The input LNV kappa couplings
556   LHblock<double> rvdin;        // The input LNV D terms
557   LHblock<double> rvm2lh1in;    // The input LNV m2LH1 couplings
558   LHblock<double> rvsnvevin;    // The input LNV sneutrino vevs
559   //RPV Output
560   LHtensor3Block<3> rvlamlle;   // The output LNV lambda couplings
561   LHtensor3Block<3> rvlamlqd;   // The output LNV lambda' couplings
562   LHtensor3Block<3> rvlamudd;   // The output BNV lambda'' couplings
563   LHtensor3Block<3> rvtlle;     // The output LNV T couplings
564   LHtensor3Block<3> rvtlqd;     // The output LNV T' couplings
565   LHtensor3Block<3> rvtudd;     // The output BNV T'' couplings
566   LHblock<double> rvkappa;      // The output LNV kappa couplings
567   LHblock<double> rvd;          // The output LNV D terms
568   LHblock<double> rvm2lh1;      // The output LNV m2LH1 couplings
569   LHblock<double> rvsnvev;      // The output LNV sneutrino vevs
570   LHmatrixBlock<7> rvnmix;      // The RPV neutralino mixing matrix
571   LHmatrixBlock<5> rvumix;      // The RPV chargino L mixing matrix
572   LHmatrixBlock<5> rvvmix;      // The RPV chargino R mixing matrix
573   LHmatrixBlock<5> rvhmix;      // The RPV neutral scalar mixing matrix
574   LHmatrixBlock<5> rvamix;      // The RPV neutral pseudoscalar mixing matrix
575   LHmatrixBlock<8> rvlmix;      // The RPV charged fermion mixing matrix
576   
577   //CPV Input
578   LHblock<double> imminpar;
579   LHblock<double> imextpar;
580   //CPV Output
581   LHmatrixBlock<4> cvhmix;   // The CPV Higgs mixing matrix
582   LHmatrixBlock<4> imcvhmix; // Optional: imaginary components
583   LHmatrixBlock<3> imau,imad,imae; // Im{} of AU, AD, AE
584   LHblock<double> imhmix;
585   LHblock<double> immsoft;
586
587   //CPV + FLV Input
588   LHmatrixBlock<3> immsq2in;  // The Im{} input upper off-diagonal msq2
589   LHmatrixBlock<3> immsu2in;  // The Im{} input upper off-diagonal msu2
590   LHmatrixBlock<3> immsd2in;  // The Im{} input upper off-diagonal msd2
591   LHmatrixBlock<3> immsl2in;  // The Im{} input upper off-diagonal msl2
592   LHmatrixBlock<3> immse2in;  // The Im{} input upper off-diagonal mse2
593   LHmatrixBlock<3> imtuin,imtdin,imtein; // The Im{} input upper off-diagonal T
594   //CPV + FLV Output
595   LHmatrixBlock<3> imvckm;  // The output DRbar running Im{VCKM} at Q
596   LHmatrixBlock<3> imupmns; // The output DRbar running Im{UPMNS} at Q
597   LHmatrixBlock<3> immsq2;  // The output DRbar running msq2 at Q
598   LHmatrixBlock<3> immsu2;  // The output DRbar running msu2 at Q
599   LHmatrixBlock<3> immsd2;  // The output DRbar running msd2 at Q
600   LHmatrixBlock<3> immsl2;  // The output DRbar running msl2 at Q
601   LHmatrixBlock<3> immse2;  // The output DRbar running mse2 at Q
602   LHmatrixBlock<3> imtu,imtd,imte; // Im{} of TU, TD, TE
603   LHmatrixBlock<6> imusqmix;// The Im{} up squark mixing matrix
604   LHmatrixBlock<6> imdsqmix; // The Im{} down squark mixing matrix
605   LHmatrixBlock<6> imselmix; // The Im{} selectron mixing matrix
606   LHmatrixBlock<3> imsnumix; // The Im{} sneutrino mixing matrix
607   LHmatrixBlock<4> imnmix;   // The Im{} neutralino mixing matrix
608   LHmatrixBlock<4> imumix;   // The Im{} chargino L mixing matrix
609   LHmatrixBlock<4> imvmix;   // The Im{} chargino R mixing matrix
610   
611   //NMSSM Input
612   //    All input is in EXTPAR
613   //NMSSM Output
614   LHblock<double> nmssmrun;  // The LHblock of NMSSM running parameters
615   LHmatrixBlock<3> nmhmix;   // The NMSSM scalar Higgs mixing
616   LHmatrixBlock<3> nmamix;   // The NMSSM pseudoscalar Higgs mixing
617   LHmatrixBlock<5> nmnmix;   // The NMSSM neutralino mixing
618   LHmatrixBlock<5> imnmnmix; //   Im{} (for future use)
619   
620   //*************************** SET BLOCK VALUE ****************************//
621   template <class T> int set(string,T);
622   template <class T> int set(string,int,T);
623   template <class T> int set(string,int,int,T);
624   template <class T> int set(string,int,int,int,T);
625
626   //********************* GENERIC/USER-DEFINED BLOCKS **********************//
627   // bool getEntry(name, indices, value) 
628   //      = true if LHblock and entry exists (value returned in value,  
629   //        typecast by user in call)
630   //      = false otherwise
631   map<string, LHgenericBlock> genericBlocks;
632   template <class T> bool getEntry(string, T&);
633   template <class T> bool getEntry(string, int, T&);
634   template <class T> bool getEntry(string, int, int, T&);
635   template <class T> bool getEntry(string, int, int, int, T&);
636   template <class T> bool getEntry(string, vector<int>, T&);
637
638   // Output of messages from SLHA interface
639   void message(int, string,string ,int line=0);
640
641   //***************************** SLHA PRIVATE *****************************//
642 private:
643   //SLHA I/O
644   int verbose;
645   bool headerPrinted, footerPrinted, filePrinted;
646   bool slhaRead, lhefRead, lhefSlha, useDecay;
647
648 };
649
650 //--------------------------------------------------------------------------
651
652 // utilities to set generic blocks
653
654 template <class T> int SusyLesHouches::set(string blockName, T val) {
655
656   // Make sure everything is interpreted as lower case (for safety)
657   for (int iC=0; iC<int(blockName.size()); ++iC) 
658     blockName[iC] = tolower(blockName[iC]);
659
660   // Add new generic block if not already existing
661   if (genericBlocks.find(blockName) == genericBlocks.end()) {
662     LHgenericBlock gBlock;
663     genericBlocks[blockName]=gBlock;
664   }
665
666   // Convert input value to string
667   ostringstream lineStream;
668   lineStream << val;
669   return genericBlocks[blockName].set(lineStream.str());
670
671 }
672
673 template <class T> int SusyLesHouches::set(string blockName, int indx, T val) {
674
675   // Make sure everything is interpreted as lower case (for safety)
676   for (int iC=0; iC<int(blockName.size()); ++iC) 
677     blockName[iC] = tolower(blockName[iC]);
678
679   // Add new generic block if not already existing
680   if (genericBlocks.find(blockName) == genericBlocks.end()) {
681     LHgenericBlock gBlock;
682     genericBlocks[blockName]=gBlock;
683   }
684
685   // Convert input value to string
686   ostringstream lineStream;
687   lineStream << indx<<" "<<val;
688   return genericBlocks[blockName].set(lineStream.str());
689
690 }
691
692 template <class T> int SusyLesHouches::set(string blockName, int indx, 
693                                            int jndx, T val) {
694
695   // Make sure everything is interpreted as lower case (for safety)
696   for (int iC=0; iC<int(blockName.size()); ++iC) 
697     blockName[iC] = tolower(blockName[iC]);
698
699   // Add new generic block if not already existing
700   if (genericBlocks.find(blockName) == genericBlocks.end()) {
701     LHgenericBlock gBlock;
702     genericBlocks[blockName]=gBlock;
703   }
704
705   // Convert input value to string
706   ostringstream lineStream;
707   lineStream << indx<<" "<<jndx<<" "<<val;
708   return genericBlocks[blockName].set(lineStream.str());
709
710 }
711
712 template <class T> int SusyLesHouches::set(string blockName, int indx, 
713                                            int jndx, int kndx, T val) {
714
715   // Make sure everything is interpreted as lower case (for safety)
716   for (int iC=0; iC<int(blockName.size()); ++iC) 
717     blockName[iC] = tolower(blockName[iC]);
718
719   // Add new generic block if not already existing
720   if (genericBlocks.find(blockName) == genericBlocks.end()) {
721     LHgenericBlock gBlock;
722     genericBlocks[blockName]=gBlock;
723   }
724
725   // Convert input value to string
726   ostringstream lineStream;
727   lineStream << indx<<" "<<jndx<<" "<<kndx<<" "<<val;
728   return genericBlocks[blockName].set(lineStream.str());
729
730 }
731
732 // utilities to read generic blocks
733
734 template <class T> bool SusyLesHouches::getEntry(string blockName, T& val) {
735
736   // Make sure everything is interpret as lower case (for safety)
737   for (int iC=0; iC<int(blockName.size()); ++iC) 
738     blockName[iC] = tolower(blockName[iC]);  
739
740   // Safety checks
741   if (genericBlocks.find(blockName) == genericBlocks.end()) {
742     message(1,"getEntry","attempting to extract entry from non-existent block "
743             +blockName);
744     return false;
745   }
746   if (genericBlocks[blockName].size() == 0) {
747     message(1,"getEntry","attempting to extract entry from zero-size block "
748             +blockName);
749     return false;
750   }
751   if (genericBlocks[blockName].size() >= 2) {
752     message(1,"getEntry","attempting to extract un-indexed entry "
753       "from multi-entry block "+blockName);
754     return false;
755   }
756   // Attempt to extract value as class T 
757   LHgenericBlock block = genericBlocks[blockName];
758   istringstream linestream(block(0));
759   linestream >> val; 
760   if ( !linestream ) {
761     message(1,"getEntry","problem extracting un-indexed entry "
762       "from block "+blockName);
763     return false;
764   } 
765   // If made it all the way here, value was successfully extracted. 
766   // Return true.
767   return true;
768 }
769
770 template <class T> bool SusyLesHouches::getEntry(string blockName, int indx, 
771                                                  T& val) {
772
773   // Make sure everything is interpret as lower case (for safety)
774   for (int iC=0; iC<int(blockName.size()); ++iC) 
775     blockName[iC] = tolower(blockName[iC]);  
776
777   // Safety checks
778   if (genericBlocks.find(blockName) == genericBlocks.end()) {
779     message(1,"getEntry","attempting to extract entry from non-existent block "
780             +blockName);
781     return false;
782   }
783   if (genericBlocks[blockName].size() == 0) {
784     message(1,"getEntry","attempting to extract entry from zero-size block "
785             +blockName);
786     return false;
787   }
788   // Attempt to extract indexed value as class T 
789   LHgenericBlock block = genericBlocks[blockName];
790   // Loop over block contents, search for indexed entry with index i
791   for (int jEntry = 0; jEntry < block.size(); jEntry++) {
792     istringstream linestream(block(jEntry));
793     // Buffer line according to format selected by T
794     int indxNow;
795     T valNow;
796     linestream >> indxNow >> valNow;
797     // If index found and value was readable, return true
798     if (linestream && indxNow == indx) {
799       val = valNow;
800       return true;
801     }
802   }
803   // If index not found or unreadable, return false
804   message(1,"getEntry","problem extracting indexed entry from block "
805           +blockName);
806   return false;
807 }
808
809 template <class T> bool SusyLesHouches::getEntry(string blockName, int indx, 
810                                                  int jndx, T& val) {
811
812   // Make sure everything is interpret as lower case (for safety)
813   for (int iC=0; iC<int(blockName.size()); ++iC) 
814     blockName[iC] = tolower(blockName[iC]);  
815
816   // Safety checks
817   if (genericBlocks.find(blockName) == genericBlocks.end()) {
818     message(1,"getEntry","attempting to extract entry from non-existent block "
819             +blockName);
820     return false;
821   }
822   if (genericBlocks[blockName].size() == 0) {
823     message(1,"getEntry","attempting to extract entry from zero-size block "
824             +blockName);
825     return false;
826   }
827   // Attempt to extract matrix-indexed value as class T 
828   LHgenericBlock block = genericBlocks[blockName];
829   // Loop over block contents, search for indexed entry with indices i, j
830   for (int jEntry = 0; jEntry < block.size(); jEntry++) {
831     istringstream linestream(block(jEntry));
832     // Buffer line according to format selected by T
833     int indxNow, jndxNow;
834     T valNow;
835     linestream >> indxNow >> jndxNow >> valNow;
836     // If index found and value was readable, return true
837     if (linestream && indxNow == indx && jndxNow == jndx) {
838       val = valNow;
839       return true;
840     }
841   }
842   // If index not found or unreadable, return false
843   message(1,"getEntry","problem extracting matrix-indexed entry from block "
844           +blockName);
845   return false;
846 }
847
848 template <class T> bool SusyLesHouches::getEntry(string blockName, int indx, 
849                                                  int jndx, int kndx, T& val) {
850
851   // Make sure everything is interpret as lower case (for safety)
852   for (int iC=0; iC<int(blockName.size()); ++iC) 
853     blockName[iC] = tolower(blockName[iC]);  
854
855   // Safety checks
856   if (genericBlocks.find(blockName) == genericBlocks.end()) {
857     message(1,"getEntry","attempting to extract entry from non-existent block "
858             +blockName);
859     return false;
860   }
861   if (genericBlocks[blockName].size() == 0) {
862     message(1,"getEntry","attempting to extract entry from zero-size block "
863             +blockName);
864     return false;
865   }
866   // Attempt to extract tensor-indexed value as class T 
867   LHgenericBlock block = genericBlocks[blockName];
868   // Loop over block contents, search for indexed entry with indices i, j, k
869   for (int jEntry = 0; jEntry < block.size(); jEntry++) {
870     istringstream linestream(block(jEntry));
871     // Buffer line according to format selected by T
872     int indxNow, jndxNow, kndxNow;
873     T valNow;
874     linestream >> indxNow >> jndxNow >> kndxNow >> valNow;
875     // If index found and value was readable, return true
876     if (linestream && indxNow == indx && jndxNow == jndx && kndxNow == kndx) {
877       val = valNow;
878       return true;
879     }
880   }
881   // If index not found or unreadable, return false
882   message(1,"getEntry","problem extracting tensor-indexed entry from block "
883           +blockName);
884   return false;
885  }
886
887 }
888 #endif
889
890
891