BLCommand.hh

Go to the documentation of this file.
00001 //      BLCommand.hh
00002 /*
00003 This source file is part of G4beamline, http://g4beamline.muonsinc.com
00004 Copyright (C) 2003,2004,2005,2006 by Tom Roberts, all rights reserved.
00005 
00006 This program is free software; you can redistribute it and/or
00007 modify it under the terms of the GNU General Public License
00008 as published by the Free Software Foundation; either version 2
00009 of the License, or (at your option) any later version.
00010 
00011 This program is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU General Public License for more details.
00015 
00016 http://www.gnu.org/copyleft/gpl.html
00017 */
00018 
00019 #ifndef BLCOMMAND_HH
00020 #define BLCOMMAND_HH
00021 
00022 #include <vector>
00023 #include <map>
00024 #include <iostream>
00025 #include <fstream>
00026 
00027 #include "globals.hh"
00028 #include "G4RotationMatrix.hh"
00029 #include "G4VisAttributes.hh"
00030 #include "G4Material.hh"
00031 
00032 #include "BLEvaluator.hh"
00033 
00034 typedef std::vector<G4String> BLArgumentVector;
00035 typedef std::map<G4String,G4String> BLArgumentMap;
00036 
00037 const G4String IndentDesc("             ");
00038 const G4String IndentArg("                           ");
00039 
00040 const G4String DefaultDoubleFmt = "%.4g";
00041 
00042 /**     class BLCommandPos - postion of the command input
00043  *      (used to get the input position for do loops)
00044  *      see also: BLCommand::setPos().
00045  **/
00046 class BLCommandPos {
00047         std::istream *in;
00048         std::streampos pos;
00049         friend class BLCommand;
00050 public:
00051         BLCommandPos(std::istream *_in) {
00052                 in = _in;
00053                 pos = in->tellg();
00054         }
00055         bool isValid() { return pos != (std::streampos)-1; }
00056 };
00057 
00058 /**     enum BLCmdType -- types of commands (for help index).
00059  **/
00060 enum BLCmdType {BLCMDTYPE_HELP,BLCMDTYPE_CONTROL,BLCMDTYPE_LAYOUT,
00061                 BLCMDTYPE_BEAM,BLCMDTYPE_AUX,BLCMDTYPE_ELEMENT,
00062                 BLCMDTYPE_PLACE,BLCMDTYPE_CUTS,BLCMDTYPE_DATA,
00063                 BLCMDTYPE_PHYSICS,BLCMDTYPE_OTHER };
00064 
00065 
00066 /**     class BLCommand - interface to define a command.
00067  *
00068  *      The standard usage for a command without a BLElement is to derive
00069  *      from this class and define a static instance using the default 
00070  *      constructor. In the derived-class default constructor the command is 
00071  *      registered, calls to setSynopsis() and setDescription() provide help
00072  *      text, and initial values are given to all class variables. This
00073  *      instance is used to execute the command, and normally no other
00074  *      instances are needed.
00075  *
00076  *      The static instance is used to keep the default arguments for the
00077  *      element.
00078  *
00079  *      Standard usage for a command for a BLElement is to derive a class
00080  *      from BLElement (which is derived from BLCommand), and do the above
00081  *      in its default constructor. The derived command() function then
00082  *      creates an instance of the class. Only the static instance is used
00083  *      to execute the command, but other instances implement the various
00084  *      elements (to be placed later in the input file).
00085  *
00086  *      See BLCMDdemo.cc and BLCMDtubs.cc for examples (.hh files are
00087  *      not needed for most commands, as their classes are not needed
00088  *      anywhere but in their implementation file).
00089  *
00090  *      NOTE: ONLY the default object should use the default constructor!
00091  **/
00092 class BLCommand {
00093         enum TokenType { NONE, ARGNAME, ARGVALUE };
00094         static std::map<G4String,BLCommand*> *mapCommand;
00095         static int errors;
00096         /// nextToken() will return the next token in line; called only by
00097         /// doCommand(). Side-effect: updates place and sets type.
00098         static G4String nextToken(const G4String& line, 
00099                                 G4String::size_type& place, TokenType& type);
00100         /// printArgDesc will print the description of an argument, using
00101         /// wrapWords().
00102         void printArgDesc(G4String name, G4String _description);
00103         static std::istream *in;
00104         friend class BLCMDplace;
00105 protected:
00106         enum ArgumentMode { PROCESS, COUNT, HELP, PRINT, CHANGE };
00107         ArgumentMode argMode;
00108         bool argFound;
00109         G4String argName;
00110         G4String argValue;
00111         G4String synopsis;
00112         G4String description;
00113         G4String printArgString;
00114         int nArgs;
00115         int nFixed;
00116         int nTunable;
00117         BLCmdType type;
00118         friend class BLCMDhelp;
00119 protected:
00120         /// Default Constructor.
00121         BLCommand() : synopsis(), description()
00122                 { }
00123 
00124         /// Destructor.
00125         virtual ~BLCommand();
00126 
00127         /// Copy Constructor.
00128         BLCommand(const BLCommand& r) : synopsis(), description()
00129                 { }
00130 
00131         // general functions for use by derived classes:
00132 
00133         /// registerCommand() registers the command.
00134         /// Used only in the default constructor -- ensures mapCommand is
00135         /// properly initialized regardless of order.
00136         void registerCommand(BLCmdType _type);
00137 
00138         /// deleteCommand() will delete a command by name
00139         void deleteCommand(G4String &name)
00140                 { if(mapCommand) mapCommand->erase(name); }
00141 
00142         /// setSynopsis() gives a 1-line (64 char) description of what the 
00143         /// command does. Used by the help command with no arguments.
00144         /// The string should be 64 characters or less, and should not contain
00145         /// any newline; no word wrapping.
00146         /// Used only in the default constructor.
00147         void setSynopsis(const char * _synopsis) 
00148                 { synopsis = _synopsis; }
00149 
00150         /// setDescription() gives a more complete description of the command,
00151         /// when help for this specific command is requested.
00152         /// When printed by the help() function, word wrapping is performed,
00153         /// but lines beginning with whitespace are kept intact.
00154         /// Named arguments are automatically described by the help() function,
00155         /// but positional arguments should be described here.
00156         /// Words are wrapped using wrapWords().
00157         /// Used only in the default constructor.
00158         void setDescription(const char * _description) 
00159                 { description = _description; }
00160 
00161         /// argString() declares a string-valued argument. name should be a
00162         /// valid C identifier 15 chars or less, and description should be
00163         /// a short description (wrapWords() is used).
00164         /// Used only in the defineNamedArgs() function.
00165         /// permitChange affects whether this argument can be set when
00166         /// an element is placed.
00167         void argString(G4String& var, G4String name, G4String description,
00168                         bool permitChange=true);
00169 
00170         /// argDouble() declares a G4double-valued argument. name should be a
00171         /// valid C identifier 15 chars or less, and description should be
00172         /// a short description (wrapWords() is used).
00173         /// Used only in the defineNamedArgs() function.
00174         /// units should be the human units for the argument, because
00175         /// the value of var is always in internal units. fmt and units are
00176         /// used when argMode=PRINT.
00177         /// permitChange affects whether this argument can be set when
00178         /// an element is placed.
00179         void argDouble(G4double& var, G4String name, G4String description,
00180                 G4double units=1.0, G4String fmt=DefaultDoubleFmt,
00181                 bool permitChange=true);
00182 
00183         /// argTunable() declares a G4double-valued argument that is tunable 
00184         /// (see the tune command in BLCMDtune.cc). name should be a
00185         /// valid C identifier 15 chars or less, and description should be
00186         /// a short description (wrapWords() is used).
00187         /// Used only in the defineNamedArgs() function.
00188         /// units should be the human units for the argument, because
00189         /// the value of var is always in internal units. fmt and units are
00190         /// used when argMode=PRINT.
00191         /// Tunable arguments can always be set when an element is placed,
00192         /// and will be changed during the tracking of the Tune Particle
00193         /// if their value includes a tune variable. See BLTune.hh for a 
00194         /// description of how tunable arguments are handled.
00195         void argTunable(G4double& var, G4String name, G4String description,
00196                 G4double units=1.0, G4String fmt=DefaultDoubleFmt);
00197 
00198         /// argInt() declares a integer-valued argument. name should be a
00199         /// valid C identifier 15 chars or less, and description should be
00200         /// a short description (wrapWords() is used).
00201         /// Used only in the defineNamedArgs() function.
00202         /// permitChange affects whether this argument can be set when
00203         /// an element is placed.
00204         void argInt(G4int& var, G4String name, G4String description,
00205                         bool permitChange=true);
00206 
00207         /// handleNamedArgs() handles all named arguments to the command (i.e.
00208         /// those defined in defineNamedArgs()). For use in the command() 
00209         /// function.
00210         /// returns 0 if OK, -1 on error.
00211         int handleNamedArgs(BLArgumentMap& namedArgs);
00212 
00213         /// help() prints the help information for this command.
00214         /// detailed=false prints only the name and synopsis; true prints
00215         /// the description and arguments also.
00216         virtual void help(bool detailed);
00217 
00218         /// wrapWords() will wrap words for descriptions in help().
00219         /// In text, lines beginning with whitespace are preserved as is,
00220         /// including blank lines. Otherwise, newlines aren't needed in text.
00221         /// indent1 is the start of the first line, and indent is used
00222         /// at the start of succeeding lines ("" is OK); indents are counted
00223         /// in the line width. The returned string always ends with "\n".
00224         G4String wrapWords(G4String text, G4String indent1, G4String indent,
00225                                                         G4String::size_type width=79);
00226 
00227         /// printArgs() will print (to stdout) the named arguments of the
00228         /// command entered, for log purposes.
00229         /// Calls defineNamedArgs() with argMode=PRINT to print the args.
00230         /// indent1 is the indent for the first line.
00231         void printArgs(G4String indent1);
00232 public:
00233         // Functions implemented by the derived class:
00234 
00235         /// commandName() returns the name of the command.
00236         virtual G4String commandName() = 0;
00237 
00238         /// command() executes the command associated with this element.
00239         /// argv and namedArgs come from parsing the command-line:
00240         /// argv has a vector of any positional arguments (without "=");
00241         /// namedArgs has a map of any named arguments of the form name=value.
00242         /// Returns 0 if OK, -1 on error.
00243         /// NOTE: for classes derived via BLElement.hh, arguments can be given
00244         /// when an object is defined and when it is placed. For that to work,
00245         /// argument values must not be used in the command() function unless
00246         /// they are defined with permitChange=false (in the above argString...
00247         /// functions). Also the correct units must be given to argDouble().
00248         virtual int command(BLArgumentVector& argv,
00249                                                 BLArgumentMap& namedArgs) = 0;
00250 
00251         /// defineNamedArgs() defines the named arguments for the command. 
00252         /// This function should consist ONLY of a series of calls to
00253         /// argString(), argDouble(), and argInt().
00254         /// Used by handleNamedArgs(), help(), and print() (they manipulate
00255         /// the behavior of the argXXX() functions via argMode).
00256         virtual void defineNamedArgs();
00257 
00258         /// argChanged() will be called whenever some argument value has
00259         /// changed. Derived classes should define it and perform any internal
00260         /// computations that depend on argument values. Many/most derived
00261         /// classes won't need to use it. In particular, after argChanged()
00262         /// returns the functions getHeight(), getWidth() and getLength()
00263         /// must return the correct values for the current arguments.
00264         /// BEWARE: a single argument change may call this multiple times.
00265         /// Applies only to named arguments, not positional ones.
00266         virtual void argChanged() { }
00267 
00268         /// print() will print to stdout the command. The default versions
00269         /// will do for most commands and elements. name can be "".
00270         /// prints commandname() and name in the space of IndentArg, followed
00271         /// by the values of all named arguments, in the order they appear
00272         /// in defineNamedArgs().
00273         virtual void print(G4String name);
00274 
00275         /// Print() -- alternate version for commands with special arguments.
00276         /// does not use defineNamedArgs() to print arguments, but rather
00277         /// prints namedArgs.
00278         void print(G4String name, BLArgumentMap& namedArgs);
00279 
00280         /// getName() returns the element's name; do not confuse this with
00281         /// commandName(). Re-defined by BLElement.
00282         virtual G4String getName() const { return "??"; }
00283 
00284         /// undefined() returns a quiet Not-A-Number, for initializing
00285         /// arguments to determine if the user set them or not.
00286         static double undefined();
00287 
00288         /// isUndefined() determines wheter an argument has been set.
00289         static bool isUndefined(double v);
00290 public:
00291         // general functions:
00292 
00293         /// getCmdType() returns the type of this command
00294         BLCmdType getCmdType() { return type; }
00295 
00296         /// isValidCommand() returns true if cmd is a valid command.
00297         static bool isValidCommand(G4String& cmd)
00298                 { return mapCommand != 0 && mapCommand->count(cmd) > 0; }
00299 
00300         /// doCommand() will parse line and perform a single command.
00301         /// Returns 0 if OK, -1 if error.
00302         static int doCommand(G4String& line);
00303 
00304         /// parseArgs() will parse the arguments of a command line.
00305         /// Arguments are appended to argv[] and added to namedArgs.
00306         /// Returns 0 if OK, -1 if syntax error.
00307         static int parseArgs(const G4String &line, BLArgumentVector &argv,
00308                                                 BLArgumentMap &namedArgs);
00309 
00310         /// readFile() reads a file of commands and executes them.
00311         /// "-" is stdin. Returns the number of errors encountered,
00312         /// or -1 if filename cannot be read.
00313         static int readFile(G4String filename);
00314 
00315         /// printError() prints an error message, using sprintf-style args.
00316         /// It also increments the errorCount.
00317         static void printError(const char *fmt, ...);
00318 
00319         /// getErrorCount() will return the number of errors so far.
00320         static int getErrorCount() { return errors; }
00321 
00322         /// getNextCommand() returns the next command. backslash-newline has
00323         /// been handled, and the line is stripped of whitespace at both ends.
00324         /// returns 0 if error or EOF. The pointer should NOT be deleted.
00325         static G4String *getNextCommand();
00326 
00327         /// getPos() returns the current position of the Command input stream
00328         static BLCommandPos getPos();
00329 
00330         /// setPos() will set the Command input stream to a specified position
00331         void setPos(BLCommandPos &pos);
00332 
00333         // general utility functions for use by other classes
00334 
00335         /// getMaterial() searches the G4Material list and returns the entry
00336         /// corresponding to name. Searches the NIST database if the material
00337         /// is not already defined. Prepends "G4_" if necessary.
00338         /// prints an error and exits if the material is not found, so all
00339         /// materials MUST be defined before they are used, unless they can
00340         /// be found in the geant4 NIST database.
00341         static G4Material *getMaterial(G4String materialName, bool error=true);
00342 
00343         /// getVisAttrib() returns the appropriate G4VisAttributes.
00344         static G4VisAttributes *getVisAttrib(G4String color);
00345 
00346         /// stringToRotationMatrix() converts a string "X90,Y45" into a 
00347         /// G4RotationMatrix.
00348         /// This is an active rotation, in that the object is first rotated
00349         /// around the parent's X axis by 90 degrees, then the object is
00350         /// further rotated around the parent's Y axis by 45 degrees.
00351         /// The return value points to a G4RotationMatrix on the heap, so
00352         /// it is persistent. Angles are in degrees, can have decimals,
00353         /// and can be negative. Axes are X, Y, Z.
00354         /// NOTE: This is expensive and should not be used during tracking.
00355         static G4RotationMatrix *stringToRotationMatrix(G4String rotation);
00356 
00357         /// dumpRotation() dumps info about a rotation matrix to stdout.
00358         /// NOTE: This is expensive and should not be used during tracking.
00359         static void dumpRotation(const G4RotationMatrix *rot, const char *str);
00360 
00361         /// splitString() splits a string at each instance of any character
00362         /// in delim, returning a vector<G4String>. If trim is true, each
00363         /// returned string has whitespace removed from its front and rear.
00364         /// Successive delimiters, or delimiters at the beginning or end,
00365         /// generate an empty string.
00366         /// NOTE: This is expensive and should not be used during tracking.
00367         static std::vector<G4String> splitString(const G4String &s, 
00368                                         const G4String &delim, bool trim=false);
00369 
00370         /// getDouble() converts a string expression to a double, returning
00371         /// nan if the string is not a valid expression using double constants
00372         /// and standard C operators and functions; whitespace is permitted as
00373         /// in C but an empty or all-whitespace string is invalid.
00374         /// Callers can use std::isnan(double) or gsl_isnan(double) to test
00375         /// for validity.
00376         /// NOTE: This is expensive and should not be used during tracking.
00377         static double getDouble(const G4String &s)
00378                 { BLEvaluator e; return e.evaluate(s); }
00379 
00380         /// getList() converts a string containing a delimited list
00381         /// of double expressions to a vector<G4double>. Any character in
00382         /// delim separates entries. Functions and operators known to
00383         /// BLEvaluator can be used in each entry of the list.
00384         /// Empty entries (null or consisting only of whitespace) are invalid.
00385         /// Returns an empty list if any entry is an invalid expression.
00386         /// NOTE: This is expensive and should not be used during tracking.
00387         static std::vector<G4double> getList(const G4String &s,
00388                                                         const G4String &delim);
00389 
00390         /// matchList() returns true if s matches any pattern in
00391         /// patternList, whch is a comma-separated list of file-glob patterns.
00392         /// NOTE: This is expensive and should not be used during tracking.
00393         static bool matchList(const G4String s, const G4String patternList);
00394 };
00395 
00396 #endif // BLCOMMAND_HH
g4beamline