Commit b39b19cb2dcf9c1765a83a15b77c1fced7d73e82
1 parent
0ac251c1
Add nthreads parameter to ctlike and cterror (#2421)
Showing
17 changed files
with
83 additions
and
33 deletions
ChangeLog
| @@ -10,7 +10,7 @@ | @@ -10,7 +10,7 @@ | ||
| 10 | Add Exponential spectral model to science verification (#2454) | 10 | Add Exponential spectral model to science verification (#2454) |
| 11 | Fix bug when using precomputed model in csresspec (#2448) | 11 | Fix bug when using precomputed model in csresspec (#2448) |
| 12 | Parallelise cslightcrv, csphasecrv, csspec, cssens, csphagen, cspull and | 12 | Parallelise cslightcrv, csphasecrv, csspec, cssens, csphagen, cspull and |
| 13 | - cstsdist (#2421) | 13 | + cstsdist and add nthreads parameter to ctlike and cterror (#2421) |
| 14 | Keep existing library path in installation script on Mac OS X (#2420) | 14 | Keep existing library path in installation script on Mac OS X (#2420) |
| 15 | csphagen produces Xspec compliant data (#2404) | 15 | csphagen produces Xspec compliant data (#2404) |
| 16 | Add show_rmf.py example script | 16 | Add show_rmf.py example script |
NEWS
| @@ -74,7 +74,7 @@ None | @@ -74,7 +74,7 @@ None | ||
| 74 | 74 | ||
| 75 | cterror - Likelihood profile error computation | 75 | cterror - Likelihood profile error computation |
| 76 | ---------------------------------------------- | 76 | ---------------------------------------------- |
| 77 | -None | 77 | +Add hidden "nthreads" parameter to control parallel computations (#2421). |
| 78 | 78 | ||
| 79 | 79 | ||
| 80 | ctexpcube - CTA exposure cube generation | 80 | ctexpcube - CTA exposure cube generation |
| @@ -84,7 +84,7 @@ None | @@ -84,7 +84,7 @@ None | ||
| 84 | 84 | ||
| 85 | ctlike - Maximum likelihood fitting | 85 | ctlike - Maximum likelihood fitting |
| 86 | ----------------------------------- | 86 | ----------------------------------- |
| 87 | -None | 87 | +Add hidden "nthreads" parameter to control parallel computations (#2421). |
| 88 | 88 | ||
| 89 | 89 | ||
| 90 | ctmapcube - CTA map cube generation | 90 | ctmapcube - CTA map cube generation |
cscripts/cslightcrv.py
| @@ -530,7 +530,8 @@ class cslightcrv(ctools.csobservation): | @@ -530,7 +530,8 @@ class cslightcrv(ctools.csobservation): | ||
| 530 | # Do maximum likelihood model fitting | 530 | # Do maximum likelihood model fitting |
| 531 | if obs.size() > 0: | 531 | if obs.size() > 0: |
| 532 | like = ctools.ctlike(obs) | 532 | like = ctools.ctlike(obs) |
| 533 | - like['edisp'] = self['edisp'].boolean() | 533 | + like['edisp'] = self['edisp'].boolean() |
| 534 | + like['nthreads'] = 1 # Avoids OpenMP conflict | ||
| 534 | like.run() | 535 | like.run() |
| 535 | 536 | ||
| 536 | # Skip bin if no event was present | 537 | # Skip bin if no event was present |
cscripts/csphasecrv.py
| @@ -443,7 +443,8 @@ class csphasecrv(ctools.csobservation): | @@ -443,7 +443,8 @@ class csphasecrv(ctools.csobservation): | ||
| 443 | 443 | ||
| 444 | # Do maximum likelihood model fitting | 444 | # Do maximum likelihood model fitting |
| 445 | like = ctools.ctlike(obs) | 445 | like = ctools.ctlike(obs) |
| 446 | - like['edisp'] = self['edisp'].boolean() | 446 | + like['edisp'] = self['edisp'].boolean() |
| 447 | + like['nthreads'] = 1 # Avoids OpenMP conflict | ||
| 447 | like.run() | 448 | like.run() |
| 448 | 449 | ||
| 449 | # Renormalize models to phase selection | 450 | # Renormalize models to phase selection |
| @@ -464,11 +465,13 @@ class csphasecrv(ctools.csobservation): | @@ -464,11 +465,13 @@ class csphasecrv(ctools.csobservation): | ||
| 464 | # Set empty models container | 465 | # Set empty models container |
| 465 | fitmodels = gammalib.GModels() | 466 | fitmodels = gammalib.GModels() |
| 466 | 467 | ||
| 467 | - result = {'phstr' :phstr, | ||
| 468 | - 'fitmodels' :fitmodels} | 468 | + # Set results |
| 469 | + result = {'phstr': phstr, 'fitmodels': fitmodels} | ||
| 469 | 470 | ||
| 471 | + # Return results | ||
| 470 | return result | 472 | return result |
| 471 | 473 | ||
| 474 | + | ||
| 472 | # Public methods | 475 | # Public methods |
| 473 | def run(self): | 476 | def run(self): |
| 474 | """ | 477 | """ |
cscripts/cspull.py
| @@ -2,7 +2,7 @@ | @@ -2,7 +2,7 @@ | ||
| 2 | # ========================================================================== | 2 | # ========================================================================== |
| 3 | # This script generates the pull distribution for all model parameters. | 3 | # This script generates the pull distribution for all model parameters. |
| 4 | # | 4 | # |
| 5 | -# Copyright (C) 2011-2017 Juergen Knoedlseder | 5 | +# Copyright (C) 2011-2018 Juergen Knoedlseder |
| 6 | # | 6 | # |
| 7 | # This program is free software: you can redistribute it and/or modify | 7 | # This program is free software: you can redistribute it and/or modify |
| 8 | # it under the terms of the GNU General Public License as published by | 8 | # it under the terms of the GNU General Public License as published by |
| @@ -25,6 +25,7 @@ from cscripts import obsutils | @@ -25,6 +25,7 @@ from cscripts import obsutils | ||
| 25 | from cscripts import ioutils | 25 | from cscripts import ioutils |
| 26 | from cscripts import mputils | 26 | from cscripts import mputils |
| 27 | 27 | ||
| 28 | + | ||
| 28 | # ============================================ # | 29 | # ============================================ # |
| 29 | # Global functions for multiprocessing support # | 30 | # Global functions for multiprocessing support # |
| 30 | # ============================================ # | 31 | # ============================================ # |
| @@ -282,6 +283,7 @@ class cspull(ctools.csobservation): | @@ -282,6 +283,7 @@ class cspull(ctools.csobservation): | ||
| 282 | like['srcname'] = model.name() | 283 | like['srcname'] = model.name() |
| 283 | like['edisp'] = edisp | 284 | like['edisp'] = edisp |
| 284 | like['statistic'] = statistic | 285 | like['statistic'] = statistic |
| 286 | + like['nthreads'] = 1 # Avoids OpenMP conflict | ||
| 285 | like['debug'] = self._logDebug() | 287 | like['debug'] = self._logDebug() |
| 286 | like['chatter'] = self['chatter'].integer() | 288 | like['chatter'] = self['chatter'].integer() |
| 287 | like.run() | 289 | like.run() |
| @@ -289,6 +291,7 @@ class cspull(ctools.csobservation): | @@ -289,6 +291,7 @@ class cspull(ctools.csobservation): | ||
| 289 | like = ctools.ctlike(obs) | 291 | like = ctools.ctlike(obs) |
| 290 | like['edisp'] = edisp | 292 | like['edisp'] = edisp |
| 291 | like['statistic'] = statistic | 293 | like['statistic'] = statistic |
| 294 | + like['nthreads'] = 1 # Avoids OpenMP conflict | ||
| 292 | like['debug'] = self._logDebug() | 295 | like['debug'] = self._logDebug() |
| 293 | like['chatter'] = self['chatter'].integer() | 296 | like['chatter'] = self['chatter'].integer() |
| 294 | like.run() | 297 | like.run() |
cscripts/cssens.py
| @@ -27,6 +27,7 @@ from cscripts import modutils | @@ -27,6 +27,7 @@ from cscripts import modutils | ||
| 27 | from cscripts import ioutils | 27 | from cscripts import ioutils |
| 28 | from cscripts import mputils | 28 | from cscripts import mputils |
| 29 | 29 | ||
| 30 | + | ||
| 30 | # ============================================ # | 31 | # ============================================ # |
| 31 | # Global functions for multiprocessing support # | 32 | # Global functions for multiprocessing support # |
| 32 | # ============================================ # | 33 | # ============================================ # |
| @@ -434,9 +435,10 @@ class cssens(ctools.csobservation): | @@ -434,9 +435,10 @@ class cssens(ctools.csobservation): | ||
| 434 | # Fit test source to the simulated events in the observation | 435 | # Fit test source to the simulated events in the observation |
| 435 | # container | 436 | # container |
| 436 | fit = ctools.ctlike(sim) | 437 | fit = ctools.ctlike(sim) |
| 437 | - fit['edisp'] = self['edisp'].boolean() | ||
| 438 | - fit['debug'] = self['debug'].boolean() | ||
| 439 | - fit['chatter'] = self['chatter'].integer() | 438 | + fit['edisp'] = self['edisp'].boolean() |
| 439 | + fit['nthreads'] = 1 # Avoids OpenMP conflict | ||
| 440 | + fit['debug'] = self['debug'].boolean() | ||
| 441 | + fit['chatter'] = self['chatter'].integer() | ||
| 440 | fit.run() | 442 | fit.run() |
| 441 | 443 | ||
| 442 | # Get model fitting results | 444 | # Get model fitting results |
cscripts/csspec.py
| @@ -23,6 +23,7 @@ import gammalib | @@ -23,6 +23,7 @@ import gammalib | ||
| 23 | import ctools | 23 | import ctools |
| 24 | from cscripts import mputils | 24 | from cscripts import mputils |
| 25 | 25 | ||
| 26 | + | ||
| 26 | # ============================================ # | 27 | # ============================================ # |
| 27 | # Global functions for multiprocessing support # | 28 | # Global functions for multiprocessing support # |
| 28 | # ============================================ # | 29 | # ============================================ # |
| @@ -674,8 +675,9 @@ class csspec(ctools.csobservation): | @@ -674,8 +675,9 @@ class csspec(ctools.csobservation): | ||
| 674 | self._log_header3(gammalib.EXPLICIT, 'Performing fit') | 675 | self._log_header3(gammalib.EXPLICIT, 'Performing fit') |
| 675 | 676 | ||
| 676 | # Perform maximum likelihood fit. Skip bins that have no events. | 677 | # Perform maximum likelihood fit. Skip bins that have no events. |
| 677 | - like = ctools.ctlike(obs) | ||
| 678 | - like['edisp'] = self['edisp'].boolean() | 678 | + like = ctools.ctlike(obs) |
| 679 | + like['edisp'] = self['edisp'].boolean() | ||
| 680 | + like['nthreads'] = 1 # Avoids OpenMP conflict | ||
| 679 | if like.obs().nobserved() > 0: | 681 | if like.obs().nobserved() > 0: |
| 680 | like.run() | 682 | like.run() |
| 681 | 683 |
cscripts/cstsdist.py
| @@ -26,6 +26,7 @@ from cscripts import modutils | @@ -26,6 +26,7 @@ from cscripts import modutils | ||
| 26 | from cscripts import ioutils | 26 | from cscripts import ioutils |
| 27 | from cscripts import mputils | 27 | from cscripts import mputils |
| 28 | 28 | ||
| 29 | + | ||
| 29 | # ============================================ # | 30 | # ============================================ # |
| 30 | # Global functions for multiprocessing support # | 31 | # Global functions for multiprocessing support # |
| 31 | # ============================================ # | 32 | # ============================================ # |
| @@ -235,8 +236,9 @@ class cstsdist(ctools.csobservation): | @@ -235,8 +236,9 @@ class cstsdist(ctools.csobservation): | ||
| 235 | 236 | ||
| 236 | # Fit model | 237 | # Fit model |
| 237 | fit = ctools.ctlike(sim) | 238 | fit = ctools.ctlike(sim) |
| 238 | - fit['debug'] = self['debug'].boolean() | ||
| 239 | - fit['chatter'] = self['chatter'].integer() | 239 | + fit['nthreads'] = 1 # Avoids OpenMP conflict |
| 240 | + fit['debug'] = self['debug'].boolean() | ||
| 241 | + fit['chatter'] = self['chatter'].integer() | ||
| 240 | fit.run() | 242 | fit.run() |
| 241 | 243 | ||
| 242 | # Get model fitting results | 244 | # Get model fitting results |
doc/source/admin/release_history/1.6.rst
| @@ -34,6 +34,9 @@ Improvements | @@ -34,6 +34,9 @@ Improvements | ||
| 34 | Transparently update parameter files | 34 | Transparently update parameter files |
| 35 | * [`2490 <https://cta-redmine.irap.omp.eu/issues/2490>`_] - | 35 | * [`2490 <https://cta-redmine.irap.omp.eu/issues/2490>`_] - |
| 36 | Change formula for number of true energy bins in :ref:`csphagen` | 36 | Change formula for number of true energy bins in :ref:`csphagen` |
| 37 | +* [`2421 <https://cta-redmine.irap.omp.eu/issues/2421>`_] - | ||
| 38 | + Add `nthreads` parameter to :ref:`ctlike` and :ref:`cterror` to control | ||
| 39 | + parallel computations | ||
| 37 | * [`2404 <https://cta-redmine.irap.omp.eu/issues/2404>`_] - | 40 | * [`2404 <https://cta-redmine.irap.omp.eu/issues/2404>`_] - |
| 38 | :ref:`csphagen` produces Xspec compliant data | 41 | :ref:`csphagen` produces Xspec compliant data |
| 39 | * Add ``show_rmf.py`` example script | 42 | * Add ``show_rmf.py`` example script |
doc/source/users/reference_manual/cslightcrv.rst
| @@ -31,10 +31,10 @@ are necessary to run internally the :ref:`csphagen` script (``inexclusion``, ``c | @@ -31,10 +31,10 @@ are necessary to run internally the :ref:`csphagen` script (``inexclusion``, ``c | ||
| 31 | ``xref``, ``yref``, ``srcshape``, ``rad``, ``bkgmethod``, ``bkgregmin``, ``maxoffset``, | 31 | ``xref``, ``yref``, ``srcshape``, ``rad``, ``bkgmethod``, ``bkgregmin``, ``maxoffset``, |
| 32 | ``etruemin``, ``etruemax``, ``etruebins``). | 32 | ``etruemin``, ``etruemax``, ``etruebins``). |
| 33 | 33 | ||
| 34 | -:ref:`cslightcrv` supports multiprocessing. By default the analysis in each time bin will | ||
| 35 | -be performed in parallel over as many processes as the number of CPUs available on your | ||
| 36 | -machine. The maximum number of parallel processes can be set by the user through the | ||
| 37 | -``nthreads`` hidden parameter. | 34 | +:ref:`cslightcrv` supports multiprocessing. By default the analysis in each time bin |
| 35 | +will be performed in parallel over as many processes as the number of CPUs | ||
| 36 | +available on your machine. The maximum number of parallel processes can be set | ||
| 37 | +by the user through the ``nthreads`` hidden parameter. | ||
| 38 | 38 | ||
| 39 | :ref:`cslightcrv` writes the fitted model parameters and their statistical errors | 39 | :ref:`cslightcrv` writes the fitted model parameters and their statistical errors |
| 40 | in a FITS file. In addition, it computes for each time bin the statistical | 40 | in a FITS file. In addition, it computes for each time bin the statistical |
doc/source/users/reference_manual/csphasecrv.rst
| @@ -31,10 +31,10 @@ are necessary to run internally the :ref:`csphagen` script (``inexclusion``, ``c | @@ -31,10 +31,10 @@ are necessary to run internally the :ref:`csphagen` script (``inexclusion``, ``c | ||
| 31 | ``xref``, ``yref``, ``srcshape``, ``rad``, ``bkgmethod``, ``bkgregmin``, ``maxoffset``, | 31 | ``xref``, ``yref``, ``srcshape``, ``rad``, ``bkgmethod``, ``bkgregmin``, ``maxoffset``, |
| 32 | ``etruemin``, ``etruemax``, ``etruebins``). | 32 | ``etruemin``, ``etruemax``, ``etruebins``). |
| 33 | 33 | ||
| 34 | -:ref:`csphasecrv` supports multiprocessing. By default the analysis in each phase bin will | ||
| 35 | -be performed in parallel over as many processes as the number of CPUs available on your | ||
| 36 | -machine. The maximum number of parallel processes can be set by the user through the | ||
| 37 | -``nthreads`` hidden parameter. | 34 | +:ref:`csphasecrv` supports multiprocessing. By default the analysis in each phase bin |
| 35 | +will be performed in parallel over as many processes as the number of CPUs | ||
| 36 | +available on your machine. The maximum number of parallel processes can be set | ||
| 37 | +by the user through the ``nthreads`` hidden parameter. | ||
| 38 | 38 | ||
| 39 | The script writes the fit results into a FITS file. The script also produces one | 39 | The script writes the fit results into a FITS file. The script also produces one |
| 40 | XML file per phase bin that contains the best-fit model for that bin. | 40 | XML file per phase bin that contains the best-fit model for that bin. |
doc/source/users/reference_manual/cterror.rst
| @@ -83,6 +83,9 @@ General parameters | @@ -83,6 +83,9 @@ General parameters | ||
| 83 | Standard parameters | 83 | Standard parameters |
| 84 | ------------------- | 84 | ------------------- |
| 85 | 85 | ||
| 86 | +``(nthreads = 0) [integer]`` | ||
| 87 | + Number of parallel processes (0=use all available CPUs). | ||
| 88 | + | ||
| 86 | ``(chatter = 2) [integer]`` | 89 | ``(chatter = 2) [integer]`` |
| 87 | Verbosity of the executable: | 90 | Verbosity of the executable: |
| 88 | ``chatter = 0``: no information will be logged | 91 | ``chatter = 0``: no information will be logged |
doc/source/users/reference_manual/ctlike.rst
| @@ -112,6 +112,9 @@ General parameters | @@ -112,6 +112,9 @@ General parameters | ||
| 112 | Standard parameters | 112 | Standard parameters |
| 113 | ------------------- | 113 | ------------------- |
| 114 | 114 | ||
| 115 | +``(nthreads = 0) [integer]`` | ||
| 116 | + Number of parallel processes (0=use all available CPUs). | ||
| 117 | + | ||
| 115 | ``(chatter = 2) [integer]`` | 118 | ``(chatter = 2) [integer]`` |
| 116 | Verbosity of the executable: | 119 | Verbosity of the executable: |
| 117 | ``chatter = 0``: no information will be logged | 120 | ``chatter = 0``: no information will be logged |
src/cterror/cterror.cpp
| @@ -33,6 +33,11 @@ | @@ -33,6 +33,11 @@ | ||
| 33 | #include "GTools.hpp" | 33 | #include "GTools.hpp" |
| 34 | #include "GOptimizer.hpp" | 34 | #include "GOptimizer.hpp" |
| 35 | 35 | ||
| 36 | +/* __ OpenMP section _____________________________________________________ */ | ||
| 37 | +#ifdef _OPENMP | ||
| 38 | +#include <omp.h> | ||
| 39 | +#endif | ||
| 40 | + | ||
| 36 | /* __ Method name definitions ____________________________________________ */ | 41 | /* __ Method name definitions ____________________________________________ */ |
| 37 | #define G_ERR_BISECTION "cterror::error_bisection(double&, double&)" | 42 | #define G_ERR_BISECTION "cterror::error_bisection(double&, double&)" |
| 38 | 43 | ||
| @@ -477,6 +482,14 @@ void cterror::get_parameters(void) | @@ -477,6 +482,14 @@ void cterror::get_parameters(void) | ||
| 477 | (*this)["outmodel"].query(); | 482 | (*this)["outmodel"].query(); |
| 478 | } | 483 | } |
| 479 | 484 | ||
| 485 | + // Set number of OpenMP threads | ||
| 486 | + #ifdef _OPENMP | ||
| 487 | + int nthreads = (*this)["nthreads"].integer(); | ||
| 488 | + if (nthreads > 0) { | ||
| 489 | + omp_set_num_threads(nthreads); | ||
| 490 | + } | ||
| 491 | + #endif | ||
| 492 | + | ||
| 480 | // Write parameters into logger | 493 | // Write parameters into logger |
| 481 | log_parameters(TERSE); | 494 | log_parameters(TERSE); |
| 482 | 495 |
src/cterror/cterror.par
| @@ -40,8 +40,9 @@ max_iter, i, h, 50,1,1000, "Maximum number of iterations" | @@ -40,8 +40,9 @@ max_iter, i, h, 50,1,1000, "Maximum number of iterations" | ||
| 40 | # | 40 | # |
| 41 | # Standard parameters | 41 | # Standard parameters |
| 42 | #==================== | 42 | #==================== |
| 43 | -chatter, i, h, 2,0,4, "Chattiness of output" | ||
| 44 | -clobber, b, h, yes,,, "Overwrite existing output files with new output files?" | ||
| 45 | -debug, b, h, no,,, "Activate debugging mode?" | ||
| 46 | -mode, s, h, ql,,, "Mode of automatic parameters" | ||
| 47 | -logfile, f, h, cterror.log,,, "Log filename" | 43 | +nthreads, i, h, 0,0,1000, "Number of parallel processes (0=use all available CPUs)" |
| 44 | +chatter, i, h, 2,0,4, "Chattiness of output" | ||
| 45 | +clobber, b, h, yes,,, "Overwrite existing output files with new output files?" | ||
| 46 | +debug, b, h, no,,, "Activate debugging mode?" | ||
| 47 | +mode, s, h, ql,,, "Mode of automatic parameters" | ||
| 48 | +logfile, f, h, cterror.log,,, "Log filename" |
src/ctlike/ctlike.cpp
| @@ -32,6 +32,11 @@ | @@ -32,6 +32,11 @@ | ||
| 32 | #include "ctlike.hpp" | 32 | #include "ctlike.hpp" |
| 33 | #include "GTools.hpp" | 33 | #include "GTools.hpp" |
| 34 | 34 | ||
| 35 | +/* __ OpenMP section _____________________________________________________ */ | ||
| 36 | +#ifdef _OPENMP | ||
| 37 | +#include <omp.h> | ||
| 38 | +#endif | ||
| 39 | + | ||
| 35 | /* __ Method name definitions ____________________________________________ */ | 40 | /* __ Method name definitions ____________________________________________ */ |
| 36 | 41 | ||
| 37 | /* __ Debug definitions __________________________________________________ */ | 42 | /* __ Debug definitions __________________________________________________ */ |
| @@ -422,6 +427,14 @@ void ctlike::get_parameters(void) | @@ -422,6 +427,14 @@ void ctlike::get_parameters(void) | ||
| 422 | static_cast<GOptimizerLM*>(&m_opt)->logger(NULL); | 427 | static_cast<GOptimizerLM*>(&m_opt)->logger(NULL); |
| 423 | } | 428 | } |
| 424 | 429 | ||
| 430 | + // Set number of OpenMP threads | ||
| 431 | + #ifdef _OPENMP | ||
| 432 | + int nthreads = (*this)["nthreads"].integer(); | ||
| 433 | + if (nthreads > 0) { | ||
| 434 | + omp_set_num_threads(nthreads); | ||
| 435 | + } | ||
| 436 | + #endif | ||
| 437 | + | ||
| 425 | // Write parameters into logger | 438 | // Write parameters into logger |
| 426 | log_parameters(TERSE); | 439 | log_parameters(TERSE); |
| 427 | 440 |
src/ctlike/ctlike.par
| @@ -38,8 +38,9 @@ fix_spat_for_ts, b, h, no,,, "Fix spatial parameters for TS computation?" | @@ -38,8 +38,9 @@ fix_spat_for_ts, b, h, no,,, "Fix spatial parameters for TS computation?" | ||
| 38 | # | 38 | # |
| 39 | # Standard parameters | 39 | # Standard parameters |
| 40 | #==================== | 40 | #==================== |
| 41 | -chatter, i, h, 2,0,4, "Chattiness of output" | ||
| 42 | -clobber, b, h, yes,,, "Overwrite existing output files with new output files?" | ||
| 43 | -debug, b, h, no,,, "Activate debugging mode?" | ||
| 44 | -mode, s, h, ql,,, "Mode of automatic parameters" | ||
| 45 | -logfile, f, h, ctlike.log,,, "Log filename" | 41 | +nthreads, i, h, 0,0,1000, "Number of parallel processes (0=use all available CPUs)" |
| 42 | +chatter, i, h, 2,0,4, "Chattiness of output" | ||
| 43 | +clobber, b, h, yes,,, "Overwrite existing output files with new output files?" | ||
| 44 | +debug, b, h, no,,, "Activate debugging mode?" | ||
| 45 | +mode, s, h, ql,,, "Mode of automatic parameters" | ||
| 46 | +logfile, f, h, ctlike.log,,, "Log filename" |