File indexing completed on 2025-08-05 08:16:09
0001
0002
0003 use strict;
0004 use Getopt::Long;
0005
0006 sub CreateInclude;
0007 sub CreateImplementation;
0008 sub CreateMakefile;
0009 sub CreateAutogen;
0010 sub CreateConfigure;
0011
0012 if ($#ARGV < 0)
0013 {
0014 print "Repo + Location: coresoftware:offline/framework/fun4all\n";
0015 print "Usage:\n";
0016 print "CreateSubsysRecoModule.pl <Module Name>\n";
0017 print "options:\n";
0018 print "--all : create also autogen.sh, configure.ac and Makefile.am\n";
0019 print "--overwrite : overwrite existing files\n";
0020 exit(0);
0021 }
0022
0023 my $createall;
0024 my $overwrite;
0025 GetOptions("all" => \$createall, "overwrite" => \$overwrite);
0026 my $modulename = $ARGV[0];
0027 my %listoffiles = ();
0028 my $classname = sprintf("%s",$ARGV[0]);
0029 if ($classname =~ )
0030 {
0031 print "Module name contains invalid characters - allowed are alphanumeric (lower and upper caps) and _\n";
0032 exit(1);
0033 }
0034 if (substr($classname,0,1) =~ )
0035 {
0036 print "Module name must start with a letter\n";
0037 exit(1);
0038 }
0039
0040 my $includefile = sprintf("%s.h", $classname);
0041 my $implementfile = sprintf("%s.cc", $classname);
0042 $listoffiles{$includefile} = $classname;
0043 $listoffiles{$implementfile} = $classname;
0044 if (defined $createall)
0045 {
0046 $listoffiles{"autogen.sh"} = $classname;
0047 $listoffiles{"configure.ac"} = $classname;
0048 $listoffiles{"Makefile.am"} = $classname;
0049 }
0050
0051
0052
0053 if (! defined $overwrite)
0054 {
0055 foreach my $file (keys %listoffiles)
0056 {
0057 if (-f $file)
0058 {
0059 print "$file exists but overwrite option not set\n";
0060 exit(1);
0061 }
0062
0063 }
0064 }
0065
0066 CreateInclude($includefile);
0067 CreateImplementation($implementfile);
0068 if (defined $createall)
0069 {
0070 CreateAutogen();
0071 CreateMakefile();
0072 CreateConfigure();
0073 }
0074 exit(0);
0075
0076 sub CreateImplementation()
0077 {
0078 my $file = shift;
0079 open(F,">$file");
0080 print F "//____________________________________________________________________________..\n";
0081 print F "//\n";
0082 print F "// This is a template for a Fun4All SubsysReco module with all methods from the\n";
0083 print F "// \$OFFLINE_MAIN/include/fun4all/SubsysReco.h baseclass\n";
0084 print F "// You do not have to implement all of them, you can just remove unused methods\n";
0085 print F "// here and in $includefile.\n";
0086 print F "//\n";
0087 print F "// $classname(const std::string &name = \"$classname\")\n";
0088 print F "// everything is keyed to $classname, duplicate names do work but it makes\n";
0089 print F "// e.g. finding culprits in logs difficult or getting a pointer to the module\n";
0090 print F "// from the command line\n";
0091 print F "//\n";
0092 print F "// $classname\:\:~$classname()\n";
0093 print F "// this is called when the Fun4AllServer is deleted at the end of running. Be\n";
0094 print F "// mindful what you delete - you do loose ownership of object you put on the node tree\n";
0095 print F "//\n";
0096 print F "// int $classname\:\:Init(PHCompositeNode *topNode)\n";
0097 print F "// This method is called when the module is registered with the Fun4AllServer. You\n";
0098 print F "// can create historgrams here or put objects on the node tree but be aware that\n";
0099 print F "// modules which haven't been registered yet did not put antyhing on the node tree\n";
0100 print F "//\n";
0101 print F "// int $classname\:\:InitRun(PHCompositeNode *topNode)\n";
0102 print F "// This method is called when the first event is read (or generated). At\n";
0103 print F "// this point the run number is known (which is mainly interesting for raw data\n";
0104 print F "// processing). Also all objects are on the node tree in case your module's action\n";
0105 print F "// depends on what else is around. Last chance to put nodes under the DST Node\n";
0106 print F "// We mix events during readback if branches are added after the first event\n";
0107 print F "//\n";
0108 print F "// int $classname\:\:process_event(PHCompositeNode *topNode)\n";
0109 print F "// called for every event. Return codes trigger actions, you find them in\n";
0110 print F "// \$OFFLINE_MAIN/include/fun4all/Fun4AllReturnCodes.h\n";
0111 print F "// everything is good:\n";
0112 print F "// return Fun4AllReturnCodes::EVENT_OK\n";
0113 print F "// abort event reconstruction, clear everything and process next event:\n";
0114 print F "// return Fun4AllReturnCodes::ABORT_EVENT; \n";
0115 print F "// proceed but do not save this event in output (needs output manager setting):\n";
0116 print F "// return Fun4AllReturnCodes::DISCARD_EVENT; \n";
0117 print F "// abort processing:\n";
0118 print F "// return Fun4AllReturnCodes::ABORT_RUN\n";
0119 print F "// all other integers will lead to an error and abort of processing\n";
0120 print F "//\n";
0121 print F "// int $classname\:\:ResetEvent(PHCompositeNode *topNode)\n";
0122 print F "// If you have internal data structures (arrays, stl containers) which needs clearing\n";
0123 print F "// after each event, this is the place to do that. The nodes under the DST node are cleared\n";
0124 print F "// by the framework\n";
0125 print F "//\n";
0126 print F "// int $classname\:\:EndRun(const int runnumber)\n";
0127 print F "// This method is called at the end of a run when an event from a new run is\n";
0128 print F "// encountered. Useful when analyzing multiple runs (raw data). Also called at\n";
0129 print F "// the end of processing (before the End() method)\n";
0130 print F "//\n";
0131 print F "// int $classname\:\:End(PHCompositeNode *topNode)\n";
0132 print F "// This is called at the end of processing. It needs to be called by the macro\n";
0133 print F "// by Fun4AllServer::End(), so do not forget this in your macro\n";
0134 print F "//\n";
0135 print F "// int $classname\:\:Reset(PHCompositeNode *topNode)\n";
0136 print F "// not really used - it is called before the dtor is called\n";
0137 print F "//\n";
0138 print F "// void $classname\:\:Print(const std::string &what) const\n";
0139 print F "// Called from the command line - useful to print information when you need it\n";
0140 print F "//\n";
0141 print F "//____________________________________________________________________________..\n";
0142 print F "\n";
0143
0144 print F "#include \"$classname.h\"\n";
0145 print F "\n";
0146
0147 print F "#include <fun4all/Fun4AllReturnCodes.h>\n";
0148 print F "\n";
0149
0150 print F "#include <phool/PHCompositeNode.h>\n";
0151 print F "\n";
0152
0153 print F "//____________________________________________________________________________..\n";
0154 print F "$classname\:\:$classname(const std::string &name):\n";
0155 print F " SubsysReco(name)\n";
0156 print F "{\n";
0157 print F " std::cout << \"$classname\:\:$classname(const std::string &name) Calling ctor\" << std::endl;\n";
0158 print F "}\n";
0159 print F "\n";
0160
0161 print F "//____________________________________________________________________________..\n";
0162 print F "$classname\:\:~$classname()\n";
0163 print F "{\n";
0164 print F " std::cout << \"$classname\:\:~$classname() Calling dtor\" << std::endl;\n";
0165 print F "}\n";
0166 print F "\n";
0167
0168 print F "//____________________________________________________________________________..\n";
0169 print F "int $classname\:\:Init(PHCompositeNode *topNode)\n";
0170 print F "{\n";
0171 print F " std::cout << \"$classname\:\:Init(PHCompositeNode *topNode) Initializing\" << std::endl;\n";
0172 print F " return Fun4AllReturnCodes::EVENT_OK;\n";
0173 print F "}\n";
0174 print F "\n";
0175
0176 print F "//____________________________________________________________________________..\n";
0177 print F "int $classname\:\:InitRun(PHCompositeNode *topNode)\n";
0178 print F "{\n";
0179 print F " std::cout << \"$classname\:\:InitRun(PHCompositeNode *topNode) Initializing for Run XXX\" << std::endl;\n";
0180 print F " return Fun4AllReturnCodes::EVENT_OK;\n";
0181 print F "}\n";
0182 print F "\n";
0183
0184 print F "//____________________________________________________________________________..\n";
0185 print F "int $classname\:\:process_event(PHCompositeNode *topNode)\n";
0186 print F "{\n";
0187 print F " std::cout << \"$classname\:\:process_event(PHCompositeNode *topNode) Processing Event\" << std::endl;\n";
0188 print F " return Fun4AllReturnCodes::EVENT_OK;\n";
0189 print F "}\n";
0190 print F "\n";
0191
0192 print F "//____________________________________________________________________________..\n";
0193 print F "int $classname\:\:ResetEvent(PHCompositeNode *topNode)\n";
0194 print F "{\n";
0195 print F " std::cout << \"$classname\:\:ResetEvent(PHCompositeNode *topNode) Resetting internal structures, prepare for next event\" << std::endl;\n";
0196 print F " return Fun4AllReturnCodes::EVENT_OK;\n";
0197 print F "}\n";
0198 print F "\n";
0199
0200 print F "//____________________________________________________________________________..\n";
0201 print F "int $classname\:\:EndRun(const int runnumber)\n";
0202 print F "{\n";
0203 print F " std::cout << \"$classname\:\:EndRun(const int runnumber) Ending Run for Run \" << runnumber << std::endl;\n";
0204 print F " return Fun4AllReturnCodes::EVENT_OK;\n";
0205 print F "}\n";
0206 print F "\n";
0207
0208 print F "//____________________________________________________________________________..\n";
0209 print F "int $classname\:\:End(PHCompositeNode *topNode)\n";
0210 print F "{\n";
0211 print F " std::cout << \"$classname\:\:End(PHCompositeNode *topNode) This is the End...\" << std::endl;\n";
0212 print F " return Fun4AllReturnCodes::EVENT_OK;\n";
0213 print F "}\n";
0214 print F "\n";
0215
0216 print F "//____________________________________________________________________________..\n";
0217 print F "int $classname\:\:Reset(PHCompositeNode *topNode)\n";
0218 print F "{\n";
0219 print F " std::cout << \"$classname\:\:Reset(PHCompositeNode *topNode) being Reset\" << std::endl;\n";
0220 print F " return Fun4AllReturnCodes::EVENT_OK;\n";
0221 print F "}\n";
0222 print F "\n";
0223
0224 print F "//____________________________________________________________________________..\n";
0225 print F "void $classname\:\:Print(const std::string &what) const\n";
0226 print F "{\n";
0227 print F " std::cout << \"$classname\:\:Print(const std::string &what) const Printing info for \" << what << std::endl;\n";
0228 print F "}\n";
0229 close(F);
0230 }
0231
0232 sub CreateInclude()
0233 {
0234 my $file = shift;
0235 open(F,">$file");
0236 my $includeguard = uc(sprintf("%s_H",$classname));
0237 print F "// Tell emacs that this is a C++ source\n";
0238 print F "// -*- C++ -*-.\n";
0239 print F "#ifndef $includeguard\n";
0240 print F "#define $includeguard\n";
0241 print F "\n";
0242 print F "#include <fun4all/SubsysReco.h>\n";
0243 print F "\n";
0244 print F "#include <string>\n";
0245
0246 print F "\n";
0247 print F "class PHCompositeNode;\n";
0248 print F "\n";
0249 print F "class $classname : public SubsysReco\n";
0250 print F "{\n";
0251 print F " public:\n";
0252 print F "\n";
0253 print F " $classname(const std::string &name = \"$classname\");\n";
0254 print F "\n";
0255 print F " ~$classname() override;\n";
0256 print F "\n";
0257 print F " /** Called during initialization.\n";
0258 print F " Typically this is where you can book histograms, and e.g.\n";
0259 print F " register them to Fun4AllServer (so they can be output to file\n";
0260 print F " using Fun4AllServer::dumpHistos() method).\n";
0261 print F " */\n";
0262 print F " int Init(PHCompositeNode *topNode) override;\n";
0263 print F "\n";
0264 print F " /** Called for first event when run number is known.\n";
0265 print F " Typically this is where you may want to fetch data from\n";
0266 print F " database, because you know the run number. A place\n";
0267 print F " to book histograms which have to know the run number.\n";
0268 print F " */\n";
0269 print F " int InitRun(PHCompositeNode *topNode) override;\n";
0270 print F "\n";
0271 print F " /** Called for each event.\n";
0272 print F " This is where you do the real work.\n";
0273 print F " */\n";
0274 print F " int process_event(PHCompositeNode *topNode) override;\n";
0275 print F "\n";
0276 print F " /// Clean up internals after each event.\n";
0277 print F " int ResetEvent(PHCompositeNode *topNode) override;\n";
0278 print F "\n";
0279 print F " /// Called at the end of each run.\n";
0280 print F " int EndRun(const int runnumber) override;\n";
0281 print F "\n";
0282 print F " /// Called at the end of all processing.\n";
0283 print F " int End(PHCompositeNode *topNode) override;\n";
0284 print F "\n";
0285
0286 print F " /// Reset\n";
0287 print F " int Reset(PHCompositeNode * /*topNode*/) override;\n";
0288 print F "\n";
0289
0290 print F " void Print(const std::string &what = \"ALL\") const override;\n";
0291 print F "\n";
0292
0293 print F " private:\n";
0294 print F "};\n";
0295 print F "\n";
0296
0297 print F "#endif // $includeguard\n";
0298 close(F);
0299 }
0300
0301 sub CreateAutogen()
0302 {
0303 open(F,">autogen.sh");
0304 print F "#!/bin/sh\n";
0305 print F "srcdir=`dirname \$0`\n";
0306 print F "test -z \"\$srcdir\" && srcdir=.\n";
0307 print F "\n";
0308 print F "(cd \$srcdir; aclocal -I \${OFFLINE_MAIN}/share;\\\n";
0309 print F "libtoolize --force; automake -a --add-missing; autoconf)\n";
0310 print F "\n";
0311 print F "\$srcdir/configure \"\$\@\"\n";
0312 close(F);
0313 chmod 0755, "autogen.sh";
0314 }
0315
0316 sub CreateConfigure()
0317 {
0318 my $loname = lc($classname);
0319 open(F,">configure.ac");
0320 print F "AC_INIT($loname,[1.00])\n";
0321 print F "AC_CONFIG_SRCDIR([configure.ac])\n";
0322 print F "\n";
0323
0324 print F "AM_INIT_AUTOMAKE\n";
0325 print F "AC_PROG_CXX(CC g++)\n";
0326 print F "\n";
0327
0328 print F "LT_INIT([disable-static])\n";
0329 print F "\n";
0330
0331 print F "dnl no point in suppressing warnings people should \n";
0332 print F "dnl at least see them, so here we go for g++: -Wall\n";
0333 print F "if test \$ac_cv_prog_gxx = yes; then\n";
0334 print F " CXXFLAGS=\"\$CXXFLAGS -Wall -Werror\"\n";
0335 print F "fi\n";
0336 print F "\n";
0337
0338 print F "AC_CONFIG_FILES([Makefile])\n";
0339 print F "AC_OUTPUT\n";
0340 close(F);
0341 }
0342
0343 sub CreateMakefile()
0344 {
0345 open(F,">Makefile.am");
0346 print F "AUTOMAKE_OPTIONS = foreign\n";
0347 print F "\n";
0348
0349 print F "AM_CPPFLAGS = \\\n";
0350 print F " -I\$(includedir) \\\n";
0351 print F " -I\$(OFFLINE_MAIN)/include \\\n";
0352 print F " -isystem\$(ROOTSYS)/include\n";
0353 print F "\n";
0354
0355 print F "AM_LDFLAGS = \\\n";
0356 print F " -L\$(libdir) \\\n";
0357 print F " -L\$(OFFLINE_MAIN)/lib \\\n";
0358 print F " -L\$(OFFLINE_MAIN)/lib64\n";
0359 print F "\n";
0360
0361 print F "pkginclude_HEADERS = \\\n";
0362 print F " $classname.h\n";
0363 print F "\n";
0364
0365 print F "lib_LTLIBRARIES = \\\n";
0366 print F " lib$classname.la\n";
0367 print F "\n";
0368
0369 print F "lib${classname}_la_SOURCES = \\\n";
0370 print F " $classname.cc\n";
0371 print F "\n";
0372
0373 print F "lib${classname}_la_LIBADD = \\\n";
0374 print F " -lphool \\\n";
0375 print F " -lSubsysReco\n";
0376 print F "\n";
0377
0378 print F "BUILT_SOURCES = testexternals.cc\n";
0379 print F "\n";
0380
0381 print F "noinst_PROGRAMS = \\\n";
0382 print F " testexternals\n";
0383 print F "\n";
0384
0385 print F "testexternals_SOURCES = testexternals.cc\n";
0386 print F "testexternals_LDADD = lib$classname.la\n";
0387 print F "\n";
0388
0389 print F "testexternals.cc:\n";
0390 print F "\techo \"//*** this is a generated file. Do not commit, do not edit\" > \$\@\n";
0391 print F "\techo \"int main()\" >> \$\@\n";
0392 print F "\techo \"{\" >> \$\@\n";
0393 print F "\techo \" return 0;\" >> \$\@\n";
0394 print F "\techo \"}\" >> \$\@\n";
0395 print F "\n";
0396
0397 print F "clean-local:\n";
0398 print F "\trm -f \$(BUILT_SOURCES)\n";
0399 close(F);
0400 }