21#include <fairlogger/Logger.h>
26const std::map<std::string, std::string>
CTPInput::run2DetToRun3Det = {{
"T",
"FT0"}, {
"V",
"FV0"}, {
"U",
"FDD"}, {
"E",
"EMC"}, {
"D",
"EMC"}, {
"H",
"TRD"}, {
"O",
"TOF"}, {
"P",
"PHS"}, {
"Z",
"ZDC"}};
27const std::map<std::string, std::string>
CTPConfiguration::detName2LTG = {{
"FV0",
"1"}, {
"FT0",
"2"}, {
"FDD",
"3"}, {
"ITS",
"4"}, {
"TOF",
"5"}, {
"MFT",
"6"}, {
"TPC",
"7"}, {
"MCH",
"8"}, {
"MID",
"9"}, {
"TST",
"10"}, {
"TRD",
"13"}, {
"HMP",
"14"}, {
"ZDC",
"15"}, {
"PHS",
"16"}, {
"EMC",
"17"}, {
"CPV",
"18"}};
31 bool isdet = det.getID() >= det.getNDetectors();
32 isdet |= det.getID() < 0;
34 LOG(error) <<
" Detector does not exist: " << det.getID();
47 return !s.empty() && std::find_if(s.begin(),
48 s.end(), [](
unsigned char c) { return !std::isdigit(c); }) == s.end();
55 bool coded = tokens[2].find(
"L") != std::string::npos;
56 coded |= tokens[2].find(
"H") != std::string::npos;
57 std::cout <<
"coded:" << coded << std::endl;
60 std::string bcmaskstr = tokens[2];
64 while (bccur < 3564) {
66 size_t posH = bcmaskstr.find(
'H',
pos);
67 size_t posL = bcmaskstr.find(
'L',
pos);
75 std::string bcsub = bcmaskstr.substr(
pos, posnext -
pos);
79 bcrange = std::stoull(bcsub);
81 LOG(warning) <<
"problem in bcmask decoding H:" << posH <<
" posL:" << posL <<
" bcsub:" << bcsub;
85 for (
int bc = bccur;
bc < bccur + bcrange;
bc++) {
89 LOG(warning) <<
"BC mask decoding to big bc:" <<
bc;
99 for (uint32_t
i = 2;
i < tokens.size();
i++) {
102 bc = std::stoull(tokens[
i]);
104 LOG(info) <<
"mask syntax:" <<
i <<
":" << tokens[
i];
115 stream <<
" # of active BC:" <<
BCmask.count() << std::endl;
118const std::set<std::string>
CTPGenerator::Generators = {
"bcd1m",
"bcd2m",
"bcd10",
"bcd20",
"rnd1m",
"rnd2m",
"rnd10",
"rnd20"};
132 this->name = std::string(
name);
150 for (
const auto& inp :
inputs) {
151 mask |= inp->inputMask;
157 stream <<
"CTP Descriptor:" <<
name <<
" Inputs:";
158 for (
const auto& inp :
inputs) {
159 stream << inp->name <<
" ";
183 stream << bcm->name <<
" ";
197 LOG(info) <<
"adding input:" << inp;
199 std::string sinp = inp;
202 sinp = inp.substr(1, inp.size() - 1);
208 }
else if (inp[0] ==
'r') {
212 int index = std::stoi(sinp);
216 if (ctpinp.
neg == 0) {
222 ctpinp.
level = sinp[0];
227 for (uint32_t
i = 0;
i < mInputs.size();
i++) {
229 LOG(info) <<
"input found at:" <<
i;
230 descInputsIndex[clsindex].push_back(
i);
234 mInputs.push_back(ctpinp);
235 descInputsIndex[clsindex].push_back(mInputs.size() - 1);
236 LOG(info) <<
"input inderted at:" << mInputs.size() - 1;
241 LOG(info) <<
"Loading CTP configuration.";
242 std::map<int, std::vector<int>> clsDescIndex;
244 mConfigString = ctpconfiguration;
245 std::istringstream iss(ctpconfiguration);
251 while (std::getline(iss, line)) {
253 if (line.size() == 0) {
256 if (line.at(0) ==
'#') {
260 if (line.find(
"ver") != std::string::npos) {
262 LOG(info) <<
"CTP Config vesrion:" << line;
264 LOG(info) <<
"CTP Config version: 0";
269 ret = processConfigurationLineRun3(line,
level, clsDescIndex);
271 ret = processConfigurationLineRun3v2(line,
level, clsDescIndex);
278 for (
auto& cls : mCTPClasses) {
279 cls.cluster = &mClusters[cls.clusterIndex];
280 if (cls.descriptorIndex != 0xff) {
281 cls.descriptor = &mDescriptors[cls.descriptorIndex];
282 if (cls.getIndex() != 0xff) {
283 for (
auto const& inp : clsDescIndex[cls.getIndex()]) {
284 mDescriptors.at(cls.descriptorIndex).inputs.push_back(&mInputs.at(inp));
291 for (
auto& cls : mCTPClasses) {
292 cls.cluster = &mClusters[cls.clusterIndex];
297int CTPConfiguration::processConfigurationLineRun3(std::string& line,
int&
level, std::map<
int, std::vector<int>>& descInputsIndex)
299 LOG(info) <<
"Processing line";
300 LOG(info) <<
"line:" << line <<
" lev:" <<
level;
303 size_t ntokens = tokens.size();
305 LOG(warning) <<
"# of tokens zero in line:" << line;
309 if (((
first = line.find(
"run")) != std::string::npos) && (
level ==
START)) {
311 }
else if ((line.find(
"inp") != std::string::npos) && ((
level ==
RUN) || (
level ==
INPUTS))) {
317 }
else if ((
first =
line.find(
"LTG")) != std::string::npos) {
319 }
else if ((
first =
line.find(
"cluster")) != std::string::npos) {
323 if (knownlevels ==
false) {
331 mRunNumber = std::stoul(tokens[1]);
333 LOG(error) <<
"RUN:" << tokens[1] << std::endl;
340 if (tokens.size() < 3) {
341 LOG(error) <<
"Wrong input line:" <<
line;
345 ctpinp.
name = tokens[1];
346 ctpinp.
level = tokens[1][0];
347 std::string run2Name{tokens[1][1]};
349 uint32_t
index = std::stoul(tokens[2]);
351 mInputs.push_back(ctpinp);
352 LOG(info) <<
"Input:" << ctpinp.
name <<
" index:" <<
index;
357 if (tokens.size() < 3) {
358 LOG(error) <<
"Wrong bc mask:" <<
line;
361 bcmask.
name = tokens[1];
362 bool coded = tokens[2].find(
"L") != std::string::npos;
363 coded |= tokens[2].find(
"H") != std::string::npos;
369 for (uint32_t
i = 2;
i < ntokens;
i++) {
372 bc = std::stoull(tokens[
i]);
374 LOG(info) <<
"mask syntax:" <<
i <<
":" << tokens[
i];
380 mBCMasks.push_back(bcmask);
381 LOG(info) <<
"BC mask added:" << bcmask.
name;
387 gen.frequency = tokens[1];
388 LOG(info) <<
"Gen added:" <<
line;
393 std::string detname = tokens[1];
397 ctpdet.
detID = det.getID();
398 LOG(info) <<
"Detector found:" << det.getID() <<
" " << detname;
400 LOG(info) <<
"Unknown detectors:" <<
line;
402 mDetectors.push_back(ctpdet);
408 mDetectors.back().mode = tokens[0];
410 LOG(info) <<
"LTGitem:" <<
line;
416 cluster.
hwMask = std::stoull(tokens[0]);
418 LOG(info) <<
"Cluster syntax error:" <<
line;
421 LOG(info) <<
"Cluster:" <<
line;
422 cluster.
name = tokens[2];
424 for (uint32_t item = 3; item < ntokens; item++) {
425 std::string detname = tokens[item];
430 mask |= det.getMask();
433 mClusters.push_back(cluster);
440 if (tokens.size() < 3) {
441 LOG(error) <<
"CTPClass: less than 3 items in class:" <<
line;
446 index = std::stoull(tokens[0]);
448 LOG(info) <<
"Class syntax error:" <<
line;
454 cls.
name = tokens[1];
459 for (uint32_t
i = 2;
i < tokens.size();
i++) {
460 std::string token = tokens[
i];
461 bool isGenerator = 0;
463 if (token.find(
gen) != std::string::npos) {
470 LOG(info) <<
"Class generator found:" << desc.
name;
471 }
else if (token.find(
"~") != std::string::npos) {
478 }
else if (token.find(
"0x") != std::string::npos) {
480 cls.
downScale = std::stoul(token,
nullptr, 16);
481 }
else if (token.find(
"bcm") != std::string::npos) {
484 for (
auto const& bcm : mBCMasks) {
485 if (bcm.name == token) {
487 LOG(info) <<
"Class BCMask found:" << token;
492 if (
i == mBCMasks.size()) {
493 LOG(error) <<
"Class BCMask NOT found:" << token <<
" assuming input";
499 mDescriptors.push_back(desc);
502 mCTPClasses.push_back(cls);
506 LOG(info) <<
"unknown line:" <<
line;
511int CTPConfiguration::processConfigurationLineRun3v2(std::string& line,
int&
level, std::map<
int, std::vector<int>>& descInputsIndex)
517 size_t ntokens = tokens.size();
519 LOG(warning) <<
"# of tokens zero in line:" <<
line;
530 }
else if ((
line.find(
"INPUTS") != std::string::npos) && (
level ==
RUN)) {
533 }
else if ((
line.find(
"inp") != std::string::npos) && (
level ==
INPUTS)) {
540 }
else if (
line.find(
"GENS") != std::string::npos) {
545 }
else if (
line.find(
"DESCRIPTORS") != std::string::npos) {
550 }
else if ((
first =
line.find(
"LTG")) != std::string::npos) {
552 }
else if ((
first =
line.find(
"cluster")) != std::string::npos) {
556 if (knownlevels ==
false) {
567 mRunNumber = std::stoul(tokens[1]);
569 LOG(error) <<
"RUN line:" <<
line;
576 if (tokens.size() != 3) {
577 LOG(error) <<
"Wrong input line:" <<
line;
581 ctpinp.
name = tokens[1];
582 ctpinp.
level = tokens[1][0];
583 std::string run2Name{tokens[1][1]};
585 uint32_t
index = std::stoul(tokens[2]);
587 mInputs.push_back(ctpinp);
593 if (tokens.size() < 3) {
594 LOG(error) <<
"Wrong bc mask:" <<
line;
598 mBCMasks.push_back(bcmask);
605 gen.frequency = tokens[1];
606 mGenerators.push_back(
gen);
611 if ((tokens.size() < 2)) {
612 if (
line.find(
"TRUE") != std::string::npos) {
614 desc.
name = tokens[0];
615 mDescriptors.push_back(desc);
618 LOG(warning) <<
"Unexpected Descriptor:" <<
line;
623 desc.
name = tokens[0];
624 for (uint32_t
i = 1;
i < tokens.size();
i++) {
626 if (inp !=
nullptr) {
627 desc.
inputs.push_back(inp);
630 mDescriptors.push_back(desc);
635 std::string detname = tokens[1];
639 ctpdet.
detID = det.getID();
640 LOG(
debug) <<
"Detector found:" << det.getID() <<
" " << detname;
642 LOG(error) <<
"Unknown detectors:" <<
line;
644 mDetectors.push_back(ctpdet);
650 mDetectors.back().mode = tokens[0];
658 cluster.
hwMask = std::stoull(tokens[0]);
660 LOG(error) <<
"Cluster syntax error:" <<
line;
664 cluster.
name = tokens[2];
666 for (uint32_t item = 3; item < ntokens; item++) {
667 std::string detname = tokens[item];
672 mask |= det.getMask();
675 mClusters.push_back(cluster);
682 if (tokens.size() < 6) {
683 LOG(error) <<
"CTPClass items < 6" <<
line;
688 index = std::stoull(tokens[1]);
690 LOG(error) <<
"Class syntax error:" <<
line;
696 cls.
name = tokens[0];
698 std::string descname = tokens[2];
700 if (descname.find(
"DTRUE") != std::string::npos) {
704 if (desc !=
nullptr) {
710 std::string bcmask = tokens[5];
711 bcmask = bcmask.substr(1, bcmask.size() - 2);
714 if (bcm !=
nullptr) {
719 if (tokens.size() > 6) {
720 cls.
downScale = std::stoul(tokens[6],
nullptr, 16);
722 mCTPClasses.push_back(cls);
726 LOG(warning) <<
"unknown line:" <<
line;
733 stream <<
"Configuration:" << mName <<
" Version:" << mVersion << std::endl;
734 stream <<
"Run:" << mRunNumber <<
" cfg name:" << mName << std::endl;
735 stream <<
"CTP BC masks:" << std::endl;
736 for (
const auto&
i : mBCMasks) {
739 stream <<
"CTP inputs:" << mInputs.size() << std::endl;
740 for (
const auto&
i : mInputs) {
743 stream <<
"CTP generators:" << std::endl;
744 for (
const auto&
i : mGenerators) {
747 stream <<
"CTP descriptors:" << mDescriptors.size() << std::endl;
748 for (
const auto&
i : mDescriptors) {
751 stream <<
"CTP detectors:" << mDetectors.size() << std::endl;
752 for (
const auto&
i : mDetectors) {
755 stream <<
"CTP clusters:" << std::endl;
756 for (
const auto&
i : mClusters) {
759 stream <<
"CTP classes:" << std::endl;
760 for (
const auto&
i : mCTPClasses) {
766 for (
auto const& inp : mInputs) {
777 if (inp !=
nullptr) {
785 for (
auto& cls : mCTPClasses) {
790 std::string ret =
"not found";
796 for (
auto const& cls : mCTPClasses) {
806 for (
auto const& inp : mInputs) {
815 for (
auto& bcm : mBCMasks) {
816 if (bcm.
name == maskname) {
824 for (
const auto& bcm : mBCMasks) {
825 if (bcm.
name == maskname) {
826 LOG(info) <<
"isBCMaskInConfigP found:" << maskname;
830 LOG(info) <<
"isBCMaskInConfigP NOT found:" << maskname;
835 for (
const auto& inp : mInputs) {
836 if (inp.
name == inpname) {
837 LOG(info) <<
"isInputInConfig found:" << inpname;
841 LOG(info) <<
"isInputInConfig NOT found:" << inpname;
846 for (
const auto& inp : mInputs) {
849 LOG(info) <<
"Found input:" << inp.
name <<
" index:" << inp.
getIndex();
858 for (
const auto& desc : mDescriptors) {
859 if (desc.
name == descname) {
860 LOG(info) <<
"isDescriptorInConfig found:" << descname;
865 LOG(info) <<
"isDescriptorInConfig NOT found:" << descname;
871 LOG(info) <<
"Creating Inputs";
872 for (
auto& des : mDescriptors) {
875 uint32_t
index = std::stoul(des.name);
880 LOG(info) <<
"Desc index:" <<
index;
883 des.inputs.push_back(inp);
885 LOG(warning) <<
"Descriptor not found:" << des.name;
888 LOG(info) <<
"Input is not a number:" << des.name;
894 std::map<o2::detectors::DetID::ID, std::vector<CTPInput>> det2inp;
895 for (
auto const& inp : mInputs) {
896 det2inp[inp.
detID].push_back(inp);
902 uint64_t clsmask = 0;
903 for (
auto const& cls : mCTPClasses) {
910 uint64_t clsmask = 0;
911 for (
auto const& cls : mCTPClasses) {
912 if (cls.
name.find(
"TRUE") != std::string::npos) {
921 uint64_t clsmask = 0;
922 for (
auto const& cls : mCTPClasses) {
923 bool exclude = cls.
name.find(
"TRUE") != std::string::npos;
924 exclude += cls.
name.find(
"EMC") != std::string::npos;
925 exclude += cls.
name.find(
"TRD") != std::string::npos;
926 exclude += cls.
name.find(
"HMP") != std::string::npos;
936 std::vector<int> classlist;
937 for (
int i = 0;
i < 64;
i++) {
938 if ((1ull <<
i) & clsmask) {
939 classlist.push_back(
i);
946 std::vector<std::string> detlist;
947 for (
auto const& det : mDetectors) {
948 std::string sdet(det.getName());
949 detlist.push_back(sdet);
956 for (
auto const& det : mDetectors) {
957 mask |= det.getMask();
965 uint64_t clsmask = 0;
966 for (
auto const& cls : mCTPClasses) {
979 for (
auto& cls : mCTPClasses) {
986 LOG(info) <<
"Checking consistency run:" << mRunNumber;
990 std::map<std::string, int> inputs;
991 for (
auto const& inp : mInputs) {
992 inputs[inp.
name] = 0;
996 std::map<std::string, int> descs;
997 for (
auto const& desc : mDescriptors) {
998 descs[desc.
name] = 0;
1000 for (
auto const inp : desc.
inputs) {
1001 inputs[inp->
name] += 1;
1004 std::cout <<
"desc1:" << descs.size() << std::endl;
1006 for (
const auto& cls : mCTPClasses) {
1008 std::cout <<
"ERROR class:" << cls.
name <<
" NO CLASS MASK" << std::endl;
1012 std::cout <<
"ERROR class:" << cls.
name <<
" NO CLUSTER" << std::endl;
1016 std::cout <<
"ERROR class:" << cls.
name <<
" NO CLUSTER INDEX" << std::endl;
1020 std::cout <<
"ERROR class:" << cls.
name <<
" NO DESCRIPTOR" << std::endl;
1027 std::cout <<
"ERROR class:" << cls.
name <<
" NO DESCRIPTOR INDEX" << std::endl;
1034 for (
auto const& inp : inputs) {
1035 if (inp.second == 0) {
1037 std::cout <<
"WARNING inputs:";
1039 std::cout << inp.first <<
" " << inp.second << std::endl;
1041 std::cout <<
"Descriptors check:" << descs.size() << std::endl;
1042 for (
auto const& desc : descs) {
1043 if (desc.second == 0) {
1045 std::cout <<
"WARNING descriptors:";
1048 std::cout << (desc.first) <<
" " << desc.second << std::endl;
1050 std::cout <<
"CTP Config consistency checked. WARNINGS:" << iw <<
" ERRORS:" << ret << std::endl;
1055 std::cout << mConfigString << std::endl;
1062 if (inpcfg.is_open()) {
1064 while (std::getline(inpcfg, line)) {
1066 if (line.size() == 0) {
1069 if (line[0] ==
'#') {
1073 size_t ntokens = tokens.size();
1075 LOG(warning) <<
"# of tokens < 6 in line:" << ntokens <<
":" << line;
1081 index = std::stoi(tokens[0]);
1083 LOG(warning) << line;
1087 std::string det = tokens[1];
1089 std::string
name = tokens[2];
1115 CTPInput(
"MT0A",
"FT0", 1),
CTPInput(
"MT0C",
"FT0", 2),
CTPInput(
"MTVX",
"FT0", 3),
CTPInput(
"MTSC",
"FT0", 4),
CTPInput(
"MTCE",
"FT0", 5),
1116 CTPInput(
"MVBA",
"FV0", 6),
CTPInput(
"MVOR",
"FV0", 7),
CTPInput(
"MVIR",
"FV0", 8),
CTPInput(
"MVNC",
"FV0", 9),
CTPInput(
"MVCH",
"FV0", 10),
1117 CTPInput(
"0UCE",
"FDD", 13),
CTPInput(
"0USC",
"FDD", 15),
CTPInput(
"0UVX",
"FDD", 16),
CTPInput(
"0U0C",
"FDD", 17),
CTPInput(
"0U0A",
"FDD", 18),
1118 CTPInput(
"0DMC",
"EMC", 14),
CTPInput(
"0DJ1",
"EMC", 41),
CTPInput(
"0DG1",
"EMC", 42),
CTPInput(
"0DJ2",
"EMC", 43),
CTPInput(
"0DG2",
"EMC", 44),
1119 CTPInput(
"0EMC",
"EMC", 21),
CTPInput(
"0EJ1",
"EMC", 37),
CTPInput(
"0EG1",
"EMC", 38),
CTPInput(
"0EJ2",
"EMC", 39),
CTPInput(
"0EG2",
"EMC", 40),
1120 CTPInput(
"0PH0",
"PHS", 22),
CTPInput(
"1PHL",
"PHS", 27),
CTPInput(
"1PHH",
"PHS", 28),
CTPInput(
"1PHL",
"PHM", 29),
1130 uint32_t indexcor =
index;
1132 indexcor =
index - 100;
1143 LOG(info) <<
"Input with index:" <<
index <<
" not in deafult input config";
1150 if (
index > o2::ctp::CTP_NINPUTS) {
1151 LOG(warn) <<
"getInputNameFRomIndex: index too big:" <<
index;
1160 LOG(info) <<
"Input with index:" <<
index <<
" not in deafult input config";
1165 std::string namecorr =
name;
1166 if ((
name[0] ==
'0') || (
name[0] ==
'M') || (
name[0] ==
'1')) {
1167 namecorr = namecorr.substr(1, namecorr.size() - 1);
1169 LOG(warn) <<
"Input name without level:" <<
name;
1172 if (inp.
name.find(namecorr) != std::string::npos) {
1176 LOG(warn) <<
"Input with name:" <<
name <<
" not in default input config";
1183 std::ifstream ctpcfg(
file);
1184 if (ctpcfg.is_open()) {
1186 while (std::getline(ctpcfg, line)) {
1188 if (line.size() == 0) {
1191 if (line[0] ==
'#') {
1195 size_t ntokens = tokens.size();
1197 LOG(warn) <<
"Not enough tokens";
1200 if (tokens[0].find(
"TForbits") != std::string::npos) {
1201 TFOrbits = std::atol(tokens[1].c_str());
1202 }
else if (tokens[0].find(
"ccdb") != std::string::npos) {
1203 ccdb = std::atoi(tokens[1].c_str());
1204 }
else if (tokens[0].find(
"orbitshift") != std::string::npos) {
1206 }
else if (tokens[0].find(
"ir_inputs") != std::string::npos) {
1210 LOG(warn) <<
" Token not found:" << tokens[0];
1213 LOG(warn) <<
"Open file success:" <<
file;
1215 LOG(warn) <<
"Can not open file:" <<
file;
default_random_engine gen(dev())
std::vector< std::string > getDetectorList() const
std::vector< int > getTriggerClassList() const
static bool isNumber(const std::string &s)
uint64_t getInputMask(const std::string &name) const
uint64_t getTriggerClassMaskWInputsNoTrgDets() const
uint64_t getTriggerClassMask() const
void createInputsInDecriptorsFromNames()
const CTPInput * isInputInConfig(const std::string inpname) const
std::string getClassNameFromHWIndex(int index)
const BCMask * isBCMaskInConfigP(const std::string bcmask) const
bool isBCMaskInConfig(const std::string maskname) const
int addInput(std::string &inp, int clsindex, std::map< int, std::vector< int > > &descInputsIndex)
int getInputIndex(const std::string &name) const
o2::detectors::DetID::mask_t getDetectorMask() const
static void capitaliseString(std::string &str)
uint64_t getClassMaskForInputMask(uint64_t inputMask) const
const CTPDescriptor * isDescriptorInConfig(const std::string descname, int &index) const
void printStream(std::ostream &stream) const
int loadConfigurationRun3(const std::string &ctpconfiguartion)
const CTPClass * getCTPClassFromHWIndex(const int index) const
uint64_t getTriggerClassMaskWInputs() const
int checkConfigConsistency() const
std::map< o2::detectors::DetID::ID, std::vector< CTPInput > > getDet2InputMap()
bool isMaskInInputs(const uint64_t &mask) const
bool isDetector(const o2::detectors::DetID &det)
static const std::map< std::string, std::string > detName2LTG
Static class with identifiers, bitmasks and names for ALICE detectors.
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLsizei const GLchar *const * path
std::ostream & operator<<(std::ostream &in, const CTPConfiguration &conf)
int32_t const char int32_t line
std::bitset< o2::constants::lhc::LHCMaxBunches > BCmask
int setBCmask(std::vector< std::string > &tokens)
void printStream(std::ostream &stream) const
Class = Mask+Descriptor+Cluster.
std::vector< BCMask const * > BCClassMask
void printStream(std::ostream &strem) const
CTPCluster const * cluster
CTPDescriptor const * descriptor
o2::detectors::DetID::mask_t maskCluster
std::string getClusterDetNames() const
void printStream(std::ostream &strem) const
Descriptor = Generator or List of [negated] inputs.
std::vector< CTPInput const * > inputs
std::uint64_t getInputsMask() const
void printStream(std::ostream &strem) const
The main part is Local Trigger Generator (LTG)
void printStream(std::ostream &stream) const
const char * getName() const
o2::detectors::DetID::ID detID
CTP internal generator: 4 for L0 and 4 for LM levels.
void printStream(std::ostream &stream) const
static const std::set< std::string > Generators
int readAndSave(std::string &path)
static void trim(std::string &s)
static std::vector< std::string > tokenize(const std::string &src, char delim, bool trimToken=true, bool skipEmpty=true)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"