From b1189c9152aa77f6520c442b2a3044a89613aca2 Mon Sep 17 00:00:00 2001 From: Scott Snyder <scott.snyder@cern.ch> Date: Thu, 11 Aug 2016 19:46:37 +0200 Subject: [PATCH] 'endreq -> endmsg.' (TileRecUtils-00-09-79) * Tagging TileRecUtils-00-09-79. * endreq -> endmsg. 2016-08-09 Siarhei Harkusha <Siarhei.Harkusha@cern.ch> * python/TileRecFlags.py: modified to add new zeroAmplitudeWithoutDigits and correctPedestalDifference properties to control TileRawChannelOF1Corrector tool; added TileDigitsContainer property to set up name of Tile digits container to be used by Tile raw channel maker algorithm * python/TileRawChannelGetter.py: modified to use new properties in TileRecFlags.py to control TileRawChannelOF1Corrector tool and Tile digits container used in Tile raw channel make algorithm * TileRecUtils/TileRawChannelOF1Corrector.h, src/TileRawChannelOF1Corrector.cxx: modified to use TileCondToolDspThreshold tool to get DSP thresholds * Tagging TileRecUtils-00-09-78 2016-07-29 Tigran Mkrtchyan <t.mkrtchyan@cern.ch> * src/TileRawChannelBuilder.cxx: added new 4th degree amplitude correction for OF1 method ... (Long ChangeLog diff - truncated) Former-commit-id: b8292058f299dfc92484efc4687c92ddfb652f11 --- .../TileRecUtils/TileRawChannelOF1Corrector.h | 13 +-- .../python/TileRawChannelGetter.py | 32 +++++-- .../TileRecUtils/python/TileRecFlags.py | 32 ++++++- .../TileRecUtils/src/TileBeamInfoProvider.cxx | 2 +- .../TileRecUtils/src/TileCellBuilder.cxx | 11 ++- .../src/TileRawChannelBuilder.cxx | 26 +++++- .../src/TileRawChannelOF1Corrector.cxx | 83 ++++++++++++------- .../src/TileRawCorrelatedNoise.cxx | 4 +- 8 files changed, 146 insertions(+), 57 deletions(-) diff --git a/TileCalorimeter/TileRecUtils/TileRecUtils/TileRawChannelOF1Corrector.h b/TileCalorimeter/TileRecUtils/TileRecUtils/TileRawChannelOF1Corrector.h index 3fe8036e1c9..a64c1ee10c9 100644 --- a/TileCalorimeter/TileRecUtils/TileRecUtils/TileRawChannelOF1Corrector.h +++ b/TileCalorimeter/TileRecUtils/TileRecUtils/TileRawChannelOF1Corrector.h @@ -14,7 +14,7 @@ // Tile includes #include "TileRecUtils/ITileRawChannelTool.h" - +#include "TileConditions/ITileCondToolDspThreshold.h" // forward declarations class TileRawChannel; @@ -25,6 +25,7 @@ class TileCondToolNoiseSample; class ITileCondToolOfc; class TileCondToolTiming; class TileCondToolEmscale; +//class ITileCondToolDspThresholds; /** @class TileRawChannelOF1Corrector @@ -43,15 +44,15 @@ class TileRawChannelOF1Corrector: public AthAlgTool, virtual public ITileRawChan static const InterfaceID& interfaceID(); /** AlgTool initialize method.*/ - virtual StatusCode initialize(); + virtual StatusCode initialize() override; /** AlgTool finalize method */ - virtual StatusCode finalize(); + virtual StatusCode finalize() override; /** Callback to handle Data-driven GeoModel initialisation */ virtual StatusCode geoInit(IOVSVC_CALLBACK_ARGS); /** Correct TileRawChannel amplitudes if pedestal changed */ - virtual StatusCode process(const TileRawChannelContainer* rawChannelContainer); + virtual StatusCode process(const TileRawChannelContainer* rawChannelContainer) override; private: @@ -62,11 +63,11 @@ class TileRawChannelOF1Corrector: public AthAlgTool, virtual public ITileRawChan ToolHandle<ITileCondToolOfc> m_tileCondToolOfc; ToolHandle<TileCondToolTiming> m_tileToolTiming; ToolHandle<TileCondToolEmscale> m_tileToolEms; + ToolHandle<ITileCondToolDspThreshold> m_tileDspThreshold; std::string m_digitsContainerName; bool m_zeroAmplitudeWithoutDigits; - float m_negativeAmplitudeThreshold; - float m_positiveAmplitudeThreshold; + bool m_correctPedestalDifference; }; #endif // TILERECUTILS_TILERAWCHANNELOF1CORRECTOR_H diff --git a/TileCalorimeter/TileRecUtils/python/TileRawChannelGetter.py b/TileCalorimeter/TileRecUtils/python/TileRawChannelGetter.py index df497722d20..7b8b043d2fa 100644 --- a/TileCalorimeter/TileRecUtils/python/TileRawChannelGetter.py +++ b/TileCalorimeter/TileRecUtils/python/TileRawChannelGetter.py @@ -8,6 +8,7 @@ from AthenaCommon.SystemOfUnits import * from AthenaCommon.Constants import * from AthenaCommon.Logging import logging from AthenaCommon.AthenaCommonFlags import athenaCommonFlags +import AthenaCommon.CfgMgr as CfgMgr from RecExConfig.Configured import Configured import traceback @@ -97,15 +98,27 @@ class TileRawChannelGetter ( Configured) : NoiseFilterTools = [] if jobproperties.TileRecFlags.noiseFilter() == 1: - if globalflags.DataSource() == 'data' and not athenaCommonFlags.isOnline(): + if globalflags.DataSource() == 'data': from TileConditions.TileInfoConfigurator import TileInfoConfigurator tileInfoConfigurator = TileInfoConfigurator() - # check if there OFC in DB for OF1 method - if tileInfoConfigurator.setupCOOLOFC(ofcType = 'OF1'): - tileInfoConfigurator.setupCOOLTIME(online = True) + # check if there are DSP thresholds in DB + if jobproperties.TileRecFlags.zeroAmplitudeWithoutDigits() and not tileInfoConfigurator.setupCOOLDspThreshold(): + jobproperties.TileRecFlags.zeroAmplitudeWithoutDigits = False + + if jobproperties.TileRecFlags.correctPedestalDifference(): + # check if offline and there are OFCs in DB for OF1 method + if athenaCommonFlags.isOnline() or not tileInfoConfigurator.setupCOOLOFC(ofcType = 'OF1'): + jobproperties.TileRecFlags.correctPedestalDifference = False + else: + tileInfoConfigurator.setupCOOLTIME(online = True) + + if jobproperties.TileRecFlags.zeroAmplitudeWithoutDigits() or jobproperties.TileRecFlags.correctPedestalDifference(): from TileRecUtils.TileRecUtilsConf import TileRawChannelOF1Corrector theTileRawChannelOF1Corrector = TileRawChannelOF1Corrector() + theTileRawChannelOF1Corrector.CorrectPedestalDifference = jobproperties.TileRecFlags.correctPedestalDifference() + theTileRawChannelOF1Corrector.ZeroAmplitudeWithoutDigits = jobproperties.TileRecFlags.zeroAmplitudeWithoutDigits() + ToolSvc += theTileRawChannelOF1Corrector NoiseFilterTools += [theTileRawChannelOF1Corrector] @@ -365,8 +378,8 @@ class TileRawChannelGetter ( Configured) : if jobproperties.TileRecFlags.OfcFromCOOL(): from TileConditions.TileInfoConfigurator import TileInfoConfigurator tileInfoConfigurator = TileInfoConfigurator() - tileInfoConfigurator.setupCOOLOFC() - theTileRawChannelBuilderOF1.TileCondToolOfc = ToolSvc.TileCondToolOfcCool + tileInfoConfigurator.setupCOOLOFC(ofcType = 'OF1') + theTileRawChannelBuilderOF1.TileCondToolOfc = ToolSvc.TileCondToolOfcCoolOF1 else: from TileConditions.TileInfoConfigurator import TileInfoConfigurator tileInfoConfigurator = TileInfoConfigurator() @@ -499,7 +512,7 @@ class TileRawChannelGetter ( Configured) : theTileRawChannelMaker.TileRawChannelBuilder += [ToolSvc.TileRawChannelBuilderOptATLAS] - jobproperties.TileRecFlags.print_JobProperties('tree&value') + # now add algorithm to topSequence # this should always come at the end @@ -519,9 +532,12 @@ class TileRawChannelGetter ( Configured) : return False #theTileRawCorrelatedNoise.UseMeanFiles = False #theTileRawCorrelatedNoise.PMTOrder = True - theTileRawChannelMaker.TileDigitsContainer = "NewDigitsContainer" + jobproperties.TileRecFlags.TileDigitsContainer = "NewDigitsContainer" topSequence += theTileRawCorrelatedNoise; + jobproperties.TileRecFlags.print_JobProperties('tree&value') + + theTileRawChannelMaker.TileDigitsContainer = jobproperties.TileRecFlags.TileDigitsContainer() topSequence += theTileRawChannelMaker; else: diff --git a/TileCalorimeter/TileRecUtils/python/TileRecFlags.py b/TileCalorimeter/TileRecUtils/python/TileRecFlags.py index ded3549ff2e..8f085d31df1 100644 --- a/TileCalorimeter/TileRecUtils/python/TileRecFlags.py +++ b/TileCalorimeter/TileRecUtils/python/TileRecFlags.py @@ -112,6 +112,15 @@ class TileRawChannelContainer(JobProperty): allowedTypes = ['str'] StoredValue = 'TileRawChannelCnt' +# +class TileDigitsContainer(JobProperty): + """ name of the container which will be used by TileRawChannelMaker + """ + statusOn = True + allowedTypes = ['str'] + StoredValue = 'TileDigitsCnt' + + # class TileRunType(JobProperty): """ declare type of all events in a run (0=unknown, 1=physics, 2=laser, 4=ped, 8=cis) @@ -215,6 +224,24 @@ class simulateTrips(JobProperty): allowedTypes = ['bool'] StoredValue = False + +class zeroAmplitudeWithoutDigits(JobProperty): + """ zero amplitude in Tile raw channel container from DSP reconstructed with OF1 method + if amplitude is above threshold but there are no corresponding digits + available in Tile digits container + """ + statusOn = True + allowedTypes = ['bool'] + StoredValue = True + +class correctPedestalDifference(JobProperty): + """ correct amplitude in Tile raw channel container from DSP reconstructed with OF1 method + if there is online pedestal difference + """ + statusOn = True + allowedTypes = ['bool'] + StoredValue = True + # Defines the container for the performance monitoring flags class TileRecFlags(JobPropertyContainer): @@ -240,6 +267,7 @@ list_jobproperties = [ doTileMF, doTileOptATLAS, TileRawChannelContainer, + TileDigitsContainer, TileRunType, noiseFilter, calibrateEnergy, @@ -253,7 +281,9 @@ list_jobproperties = [ BestPhaseFromCOOL, readDigits, doTileOverflowFit, - simulateTrips + simulateTrips, + zeroAmplitudeWithoutDigits, + correctPedestalDifference ] for i in list_jobproperties: diff --git a/TileCalorimeter/TileRecUtils/src/TileBeamInfoProvider.cxx b/TileCalorimeter/TileRecUtils/src/TileBeamInfoProvider.cxx index 8986ebb2993..46b8cb3df71 100644 --- a/TileCalorimeter/TileRecUtils/src/TileBeamInfoProvider.cxx +++ b/TileCalorimeter/TileRecUtils/src/TileBeamInfoProvider.cxx @@ -513,7 +513,7 @@ void TileBeamInfoProvider::handle(const Incident& inc) { if (msgLvl(MSG::VERBOSE)) { msg(MSG::VERBOSE) << "BCID = " << m_BCID << endmsg; msg(MSG::VERBOSE) << "digi size = " << m_digiSize << endmsg; - msg(MSG::VERBOSE) << "zero-suppressed digi container = " << m_incompleteDigits << endreq; + msg(MSG::VERBOSE) << "zero-suppressed digi container = " << m_incompleteDigits << endmsg; if (m_trigType < 0) msg(MSG::VERBOSE) << "trig type = " << m_trigType << " (Level-1 type) " << endmsg; diff --git a/TileCalorimeter/TileRecUtils/src/TileCellBuilder.cxx b/TileCalorimeter/TileRecUtils/src/TileCellBuilder.cxx index 328639eb92f..bec35af10a9 100644 --- a/TileCalorimeter/TileRecUtils/src/TileCellBuilder.cxx +++ b/TileCalorimeter/TileRecUtils/src/TileCellBuilder.cxx @@ -544,7 +544,7 @@ StatusCode TileCellBuilder::process(CaloCellContainer * theCellContainer) { //specify that a given calorimeter has been filled if (theCellContainer->hasCalo(caloNum)) { // log << MSG::WARNING << "CaloCellContainer has already been filled with TileCells (caloNum = " - // << caloNum << ")" << endreq ; + // << caloNum << ")" << endmsg ; } theCellContainer->setHasCalo(caloNum); } @@ -1098,11 +1098,10 @@ void TileCellBuilder::build(const ITERATOR & begin, const ITERATOR & end, COLLEC amp = m_tileToolEmscale->undoOnlCalib(drawerIdx, channel, gain, amp, m_RChUnit); if (amp > m_ampMinThresh) // amp cut in ADC counts amp *= TileRawChannelBuilder::correctAmp(time,m_of2); - } else if (amp > m_ampMinThresh - && (m_RChUnit == TileRawChannelUnit::ADCcounts - || m_RChUnit == TileRawChannelUnit::OnlineADCcounts)) { - - amp *= TileRawChannelBuilder::correctAmp(time,m_of2); + } else if (m_RChUnit == TileRawChannelUnit::ADCcounts + || m_RChUnit == TileRawChannelUnit::OnlineADCcounts) { + if (amp > m_ampMinThresh) + amp *= TileRawChannelBuilder::correctAmp(time,m_of2); } else { ATH_MSG_ERROR( "Units in raw channel container is " << m_RChUnit ); ATH_MSG_ERROR( "But amplitude correction works only with ADC counts " ); diff --git a/TileCalorimeter/TileRecUtils/src/TileRawChannelBuilder.cxx b/TileCalorimeter/TileRecUtils/src/TileRawChannelBuilder.cxx index 913d4081285..17a8acb292a 100644 --- a/TileCalorimeter/TileRecUtils/src/TileRawChannelBuilder.cxx +++ b/TileCalorimeter/TileRecUtils/src/TileRawChannelBuilder.cxx @@ -594,8 +594,19 @@ double TileRawChannelBuilder::correctAmp(double phase, bool of2) { */ // estimation from Vakhtang for rel 14.4.0 - double k = (phase < 0.0 ? 0.0009400 : 0.0010160); + /*double k = (phase < 0.0 ? 0.0009400 : 0.0010160); corr = (1.0 + k * phase * phase); + */ + + // Parabolic correction from Tigran + double a1,a2,b,c; + a1 = phase < 0.0 ? 0.000940774 : 0.00102111; + a2 = phase < 0.0 ? 0.000759051 : 0.000689625; + b = phase < 0.0 ? -2.0 * 7.0 * (a1 - a2) : 2.0 * 12.5 * (a1 - a2); + c = phase < 0.0 ? 1.0 - 7.0 * 7.0 * (a1-a2) : 1.0 - 12.5 * 12.5 * (a1-a2); + if (phase < 12.5 && phase > -7.0) corr = a1 * phase * phase + 1.0; + else corr = phase * ( a2 * phase + b) + c; + } else { /*double a,b,c; @@ -607,8 +618,19 @@ double TileRawChannelBuilder::correctAmp(double phase, bool of2) { corr = a + phase * ( b + c * phase); */ - double k = (phase < 0.0 ? 0.0005241 : 0.0006167); + /*double k = (phase < 0.0 ? 0.0005241 : 0.0006167); corr = (1.0 + k * phase * phase); + */ + + // 4th degree polynomial correction from Tigran + double k1 = (phase < 0.0 ? -0.0000326707:0.000380336); + double k2 = (phase < 0.0 ? -0.000560962:-0.000670487); + double k3 = (phase < 0.0 ? -0.00000807869:0.00000501773); + double k4 = (phase < 0.0 ? -0.000000145008:0.0000000584647); + + corr = 1.0 / (1.0 + (k1 + (k2 + (k3 + k4 *phase)*phase)*phase)*phase); + + } return corr; diff --git a/TileCalorimeter/TileRecUtils/src/TileRawChannelOF1Corrector.cxx b/TileCalorimeter/TileRecUtils/src/TileRawChannelOF1Corrector.cxx index 6f7d167cf80..f8b5378b75e 100644 --- a/TileCalorimeter/TileRecUtils/src/TileRawChannelOF1Corrector.cxx +++ b/TileCalorimeter/TileRecUtils/src/TileRawChannelOF1Corrector.cxx @@ -13,6 +13,7 @@ #include "TileConditions/TileCondToolOfc.h" #include "TileConditions/TileCondToolTiming.h" #include "TileConditions/TileCondToolEmscale.h" +#include "TileConditions/TileCondToolDspThreshold.h" // Atlas includes #include "AthenaKernel/errorcheck.h" @@ -34,6 +35,7 @@ TileRawChannelOF1Corrector::TileRawChannelOF1Corrector(const std::string& type, , m_tileCondToolOfc("TileCondToolOfcCool/TileCondToolOfcCoolOF1") , m_tileToolTiming("TileCondToolTiming/TileCondToolOnlineTiming") , m_tileToolEms("TileCondToolEmscale") + , m_tileDspThreshold("TileCondToolDspThreshold") { declareInterface<ITileRawChannelTool>(this); declareInterface<TileRawChannelOF1Corrector>(this); @@ -42,12 +44,11 @@ TileRawChannelOF1Corrector::TileRawChannelOF1Corrector(const std::string& type, declareProperty("TileCondToolOfc", m_tileCondToolOfc); declareProperty("TileCondToolTiming", m_tileToolTiming); declareProperty("TileCondToolEmscale", m_tileToolEms); + declareProperty("TileCondToolDspThreshold", m_tileDspThreshold); declareProperty("TileDigitsContainer", m_digitsContainerName = "TileDigitsCnt"); declareProperty("ZeroAmplitudeWithoutDigits", m_zeroAmplitudeWithoutDigits = true); - declareProperty("NegativeAmplitudeThresholdToZero", m_negativeAmplitudeThreshold = -10); - declareProperty("PositiveAmplitudeThresholdToZero", m_positiveAmplitudeThreshold = 10); - + declareProperty("CorrectPedestalDifference", m_correctPedestalDifference = true); } //======================================================== @@ -56,8 +57,6 @@ StatusCode TileRawChannelOF1Corrector::initialize() { ATH_MSG_INFO("Initializing..."); - //=== TileCondToolEmscale - if (m_zeroAmplitudeWithoutDigits) CHECK( m_tileToolEms.retrieve() ); const IGeoModelSvc* geoModel = 0; CHECK( service("GeoModelSvc", geoModel) ); @@ -83,14 +82,25 @@ StatusCode TileRawChannelOF1Corrector::geoInit(IOVSVC_CALLBACK_ARGS) { CHECK( detStore()->retrieve(m_tileHWID) ); - //=== get TileCondToolOfc - CHECK( m_tileCondToolOfc.retrieve() ); - //=== get TileCondToolNoiseSample - CHECK( m_tileToolNoiseSample.retrieve() ); + if (m_correctPedestalDifference) { + //=== get TileCondToolOfc + CHECK( m_tileCondToolOfc.retrieve() ); + + //=== get TileCondToolNoiseSample + CHECK( m_tileToolNoiseSample.retrieve() ); + + //=== get TileToolTiming + CHECK( m_tileToolTiming.retrieve() ); + } + + //=== TileCondToolEmscale + if (m_zeroAmplitudeWithoutDigits) { + CHECK( m_tileToolEms.retrieve() ); - //=== get TileToolTiming - CHECK( m_tileToolTiming.retrieve() ); + //=== get TileToolTiming + CHECK( m_tileDspThreshold.retrieve() ); + } return StatusCode::SUCCESS; } @@ -146,33 +156,44 @@ StatusCode TileRawChannelOF1Corrector::process(const TileRawChannelContainer* ra int channel = m_tileHWID->channel(adcId); int gain = m_tileHWID->adc(adcId); - float onlinePedestalDifference = m_tileToolNoiseSample->getOnlinePedestalDifference(drawerIdx, channel, gain, rawChannelUnit); - float phase = -m_tileToolTiming->getSignalPhase(drawerIdx, channel, gain); - const TileOfcWeightsStruct* weights = m_tileCondToolOfc->getOfcWeights(drawerIdx, channel, gain, phase, false); - float weightsSum(0.0); - for (int i = 0; i < weights->n_samples; ++i) weightsSum += weights->w_a[i]; - float energyCorrection = onlinePedestalDifference * weightsSum; - ATH_MSG_VERBOSE( TileCalibUtils::getDrawerString(ros, drawer) - << " ch" << channel << (gain ? " HG: " : " LG: ") - << "online pedestal difference: " << onlinePedestalDifference - << "; OFC weights (a) sum: " << weightsSum - << " => energy correction: " << energyCorrection); - - rawChannel->setAmplitude(rawChannel->amplitude() + energyCorrection); - - if (checkDigits) { + if (m_correctPedestalDifference) { + + float onlinePedestalDifference = m_tileToolNoiseSample->getOnlinePedestalDifference(drawerIdx, channel, gain, rawChannelUnit); + float phase = -m_tileToolTiming->getSignalPhase(drawerIdx, channel, gain); + const TileOfcWeightsStruct* weights = m_tileCondToolOfc->getOfcWeights(drawerIdx, channel, gain, phase, false); + float weightsSum(0.0); + for (int i = 0; i < weights->n_samples; ++i) weightsSum += weights->w_a[i]; + float energyCorrection = onlinePedestalDifference * weightsSum; + ATH_MSG_VERBOSE( TileCalibUtils::getDrawerString(ros, drawer) + << " ch" << channel << (gain ? " HG: " : " LG: ") + << "online pedestal difference: " << onlinePedestalDifference + << "; OFC weights (a) sum: " << weightsSum + << " => energy correction: " << energyCorrection); + + rawChannel->setAmplitude(rawChannel->amplitude() + energyCorrection); + + } + + if (checkDigits && noDigits[channel]) { + float amplitude = m_tileToolEms->undoOnlCalib(drawerIdx, channel, gain, rawChannel->amplitude(), rawChannelUnit); - if ((amplitude < m_negativeAmplitudeThreshold - || amplitude > m_positiveAmplitudeThreshold) - && noDigits[channel]) { + float minimuAmplitudeThreshold(-99999.0); + float maximumAmplitudeThreshold(99999.0); + m_tileDspThreshold->getAmplitudeThresholds(drawerIdx, channel, gain, minimuAmplitudeThreshold, maximumAmplitudeThreshold); + if (amplitude < minimuAmplitudeThreshold + || amplitude > maximumAmplitudeThreshold) + { ATH_MSG_VERBOSE( TileCalibUtils::getDrawerString(ros, drawer) << " ch" << channel << (gain ? " HG:" : " LG:") - << " amplitude: " << amplitude - << " [ADC] without digits => set apmlitude/time/quality: 0.0/0.0/15.0"); + << " amplitude: " << amplitude << " [ADC]" + << " outside range: " << minimuAmplitudeThreshold << ".." << maximumAmplitudeThreshold + << " without digits => set apmlitude/time/quality: 0.0/0.0/15.0"); rawChannel->insert(0.0F, 0.0F, 15.0F); + } + } } diff --git a/TileCalorimeter/TileRecUtils/src/TileRawCorrelatedNoise.cxx b/TileCalorimeter/TileRecUtils/src/TileRawCorrelatedNoise.cxx index 68fcbb233db..4b85b2eeb01 100644 --- a/TileCalorimeter/TileRecUtils/src/TileRawCorrelatedNoise.cxx +++ b/TileCalorimeter/TileRecUtils/src/TileRawCorrelatedNoise.cxx @@ -176,7 +176,7 @@ StatusCode TileRawCorrelatedNoise::initialize() { FILE* mean_file = MeanFile[Ros - 1][Drawer]; //if(fgets(buff, sizeof(buff), mean_file) != NULL) { // if (lDebug) - // log << MSG::DEBUG << "Vector is being loaded: "<< buff << endreq; + // log << MSG::DEBUG << "Vector is being loaded: "<< buff << endmsg; //} // load tokens to be searched for in a string char* word; @@ -259,7 +259,7 @@ StatusCode TileRawCorrelatedNoise::initialize() { FILE* rms_file = Sample3RMSFile[Ros - 1][Drawer]; //if(fgets(buff, sizeof(buff), rms_file) != NULL) { // if (lDebug) - // log << MSG::DEBUG << "Vector is being loaded: "<< buff << endreq; + // log << MSG::DEBUG << "Vector is being loaded: "<< buff << endmsg; //} // load tokens to be searched for in a string char* word; -- GitLab