41#include "TDirectory.h"
61 std::string
a = ctime(&t);
63 for (
unsigned i=0 ; i<
a.size()-1 ; i++ ) b+=
a[i];
70 return stat(
file.c_str(),&buff)==0;
76std::ostream*
outp = &std::cout;
85std::string
algorithm =
"HLT_Histogram_Not_Empty&GatherData";
91std::string
description =
"https://twiki.cern.ch/twiki/bin/view/Atlas/HltTrackingDataQualityMonitoring#Tier0";
95std::map<std::string, std::string>
remap;
102std::map<std::string, int>
dirs;
108std::ostream&
operator<<( std::ostream& s,
const std::vector<T>& v ) {
109 if ( v.empty() )
return s;
110 for (
size_t i=0 ; i<v.size() ; i++ ) s << v[i] <<
"\n";
114bool contains(
const std::string& s,
const std::string& regx ) {
return s.find(regx)!=std::string::npos; }
119std::ostream&
operator<<( std::ostream& s,
const std::vector<T*>& v ) {
120 if ( v.empty() )
return s;
121 for (
int i=0 ; i<v.size() ; i++ ) s << *v[i] <<
"\n";
131 TObject*
a = tobj->ReadObj()->Clone();
132 static_cast<TH1*
>(
a)->SetDirectory(0);
133 return static_cast<T*
>(
a);
138std::string
find(
const std::string& s ) {
139 std::map<std::string, std::string>::const_iterator itr =
remap.find(s);
140 if ( itr!=
remap.end() )
return itr->second;
146int count( std::string s,
const std::string& regx ) {
147 size_t p = s.find( regx );
149 while ( p!=std::string::npos ) {
161std::string
chop(std::string& s1,
const std::string& s2)
163 std::string::size_type pos = s1.find(s2);
165 if ( pos == std::string::npos ) {
167 s1.erase(0, s1.size());
170 s3 = s1.substr(0, pos);
171 s1.erase(0, pos+s2.size());
177std::vector<std::string>
split(
const std::string& s,
const std::string& t=
":" ) {
180 size_t pos = s2.find(t);
182 std::vector<std::string>
tags;
184 while ( pos!=std::string::npos ) {
189 tags.push_back(std::move(s2));
197std::string
chopex(std::string& s1,
const std::string& s2)
199 std::string::size_type pos = s1.find(s2);
201 if ( pos == std::string::npos ) {
206 s3 = s1.substr(0, pos);
207 s1.erase(0, pos+s2.size());
214std::string
chomp(std::string& s1,
const std::string& s2)
216 std::string::size_type pos = s1.find(s2);
218 if ( pos == std::string::npos ) {
223 s3 = s1.substr(pos+s2.size(),s1.size());
224 s1.erase(pos,s1.size());
233std::string
choptoken(std::string& s1,
const std::string& s2)
236 std::string::size_type pos = s1.find(s2);
237 if ( pos != std::string::npos ) {
238 s3 = s1.substr(0, pos+s2.size());
239 s1.erase(0, pos+s2.size());
247std::string
chomptoken(std::string& s1,
const std::string& s2)
250 std::string::size_type pos = s1.find(s2);
251 if ( pos != std::string::npos ) {
252 s3 = s1.substr(pos, s1.size());
253 s1.erase(pos, s1.size());
260std::string
chopfirst(std::string& s1,
const std::string& s2)
263 std::string::size_type pos = s1.find_first_not_of(s2);
264 if ( pos != std::string::npos ) {
265 s3 = s1.substr(0, pos);
276std::string
choplast(std::string& s1,
const std::string& s2)
279 std::string::size_type pos = s1.find_last_not_of(s2);
280 if ( pos != std::string::npos ) {
281 s3 = s1.substr(pos+1, s1.size());
282 s1.erase(pos+1, s1.size());
290std::string
chopends(std::string& s1,
const std::string& s2)
302 std::string::size_type pos;
303 while ( (pos = s.find(s2))!=std::string::npos ) {
304 s.erase(pos, s2.size());
310std::string
replace( std::string s,
const std::string& s2,
const std::string& s3) {
311 std::string::size_type pos;
314 while ( (pos = s.find(s2))!=std::string::npos ) {
315 s.replace(pos, s2.size(), s3);
325 std::string::size_type pos;
326 while ( (pos = s.find(regex))!=std::string::npos ) {
327 s.erase(pos, regex.size());
333std::vector<std::string>
maphist(
const std::vector<std::string>& v ) {
335 for (
unsigned i=0 ; i<v.size() ; i++ ) {
337 std::string tmp = v[i];
338 std::string path =
chop( tmp,
"Expert/" );
340 tmp =
replace( tmp,
"/",
"__" );
342 mapped.push_back( std::move(path) );
357bool match( std::string s1, std::string s2 ) {
359 int i1 = std::count( s1.begin(), s1.end(),
'/' );
360 int i2 = std::count( s2.begin(), s2.end(),
'/' );
362 int i = ( i1<i2 ? i1 : i2 );
366 for ( i++ ; i-- ; ) {
367 size_t p1 = s1.find(
'/');
368 size_t p2 = s2.find(
'/');
370 std::string ss1 = s1.substr( 0, p1 );
371 std::string ss2 = s2.substr( 0, p2 );
378 if ( ss1!=ss2 )
return false;
391 bool matched =
false;
393 std::map<std::string,int>::const_iterator itr =
dirs.begin();
394 while ( itr!=
dirs.end() ) {
395 if (
match( s, itr->first) ) matched =
true;
397 if ( matched )
return true;
404 if (
dirs.size()==0 )
return true;
405 std::map<std::string,int>::const_iterator itr =
dirs.begin();
406 while ( itr!=
dirs.end() ) {
407 if ( s.find(itr->first)!=std::string::npos )
return true;
416 if (
dirs.size()==0 )
return "";
417 std::map<std::string,int>::const_iterator itr =
dirs.begin();
418 while ( itr!=
dirs.end() ) {
419 if ( s.find(itr->first)!=std::string::npos )
return itr->first;
426std::map<std::string,int>::const_iterator
matchcwditr(
const std::string& s ) {
427 if (
dirs.size()==0 )
return dirs.end();
428 std::map<std::string,int>::const_iterator itr =
dirs.begin();
429 while ( itr!=
dirs.end() ) {
430 if ( s.find(itr->first)!=std::string::npos )
return itr;
442 reference(
const std::string& n,
const std::string& f ) :
447 std::cerr <<
"opening file " << f << std::endl;
449 TFile*
r = TFile::Open(f.c_str());
451 std::cerr <<
"cannot open root file " << f << std::endl;
457 TList* tl = gDirectory->GetListOfKeys();
461 for (
int i=0 ; i<tl->GetSize() ; i++ ) {
463 TKey* tobj = (TKey*)tl->At(i);
465 if ( std::string(tobj->GetClassName()).find(
"TDirectory")!=std::string::npos ) {
468 TDirectory* tnd = (TDirectory*)tobj->ReadObj();
470 std::string dir = tnd->GetName();
473 dir.erase( 0, std::string(
"run_").size() );
474 m_run = std::atoi( dir.c_str() );
506 static bool first =
true;
508 s <<
"##########################\n";
509 s <<
"# References\n";
510 s <<
"##########################\n\n";
513 s <<
"reference " <<
r.name() <<
" {\n";
514 s <<
"\t\tfile = " <<
r.file() <<
"\n";
515 s <<
"\t\tpath = run_" <<
r.run() <<
"\n";
516 s <<
"\t\tname = same_name" <<
"\n";
533 std::string user = std::getenv(
"USER");
535 (*outp) <<
"######################################################################\n";
536 (*outp) <<
"# $Id: collisions_run.config " <<
date() <<
" " << user <<
" $\n";
537 (*outp) <<
"######################################################################\n";
540 (*outp) <<
"#######################\n";
541 (*outp) <<
"# HLTidtrk\n";
542 (*outp) <<
"#######################\n";
559 (*outp) <<
"#######################\n";
560 (*outp) <<
"# Output\n";
561 (*outp) <<
"#######################\n\n\n";
568 void makemenu(
node& n,
const std::string& space=
"", std::string path=
"", std::string rawpath=
"",
bool found=
false ) {
572 if ( n.name()==
base ) found =
true;
575 if ( n.name()==
"top_level" )
print =
true;
591 std::string newspacer = space;
595 std::string output_name =
find(n.name());
599 if ( path==
"" ) path += output_name;
600 else path +=
"/" + output_name;
601 if ( rawpath==
"" ) rawpath += n.name();
602 else rawpath +=
"/" + n.name();
609 if (
print ) (*outp) << space <<
"output " << output_name <<
" {" <<
"\n";
611 for (
unsigned i=0 ; i<n.size() ; i++ ) {
615 if (
print ) (*outp) << space <<
"}\n";
633 (*outp) <<
"#######################\n";
634 (*outp) <<
"# Histogram Assessments\n";
635 (*outp) <<
"#######################\n\n";
640 void makeass(
node& n,
const std::string& space=
"", std::string path=
"", std::string rawpath=
"",
bool found=
false ) {
642 static std::string savedir =
"";
646 if ( n.name()==
base ) found =
true;
655 std::string newspacer = space;
666 std::string output_name =
find(n.name());
669 if ( path==
"" ) path += output_name;
670 else path +=
"/" + output_name;
671 if ( rawpath==
"" ) rawpath += n.name();
672 else rawpath +=
"/" + n.name();
677 if (
print ) (*outp) << space <<
"dir " << n.name() <<
" {" <<
"\n";
679 bool first_hists =
true;
681 for (
unsigned i=0 ; i<n.size() ; i++ ) {
686 (*outp) << space <<
"\t" <<
"hist .* {\n";
687 (*outp) << space <<
"\t\t" <<
"regex \t= 1\n";
688 (*outp) << space <<
"\t\t" <<
"algorithm \t= " <<
algorithm <<
"\n";
689 (*outp) << space <<
"\t\t" <<
"description \t= " <<
description <<
"\n";
690 (*outp) << space <<
"\t\t" <<
"output \t= " << path <<
"\n";
691 (*outp) << space <<
"\t\t" <<
"display \t= StatBox\n";
693 for (
unsigned it=0 ; it<
tags.size() ; it++ ) (*
outp) << space <<
"\t\t" <<
replace(
tags[it],
"=",
"\t=") <<
"\n";
694 (*outp) << space <<
"\t" <<
"}\n";
699 (*outp) << space <<
"\t" <<
"hist " << n[i]->name() <<
" {\n";
700 (*outp) << space <<
"\t\t" <<
"algorithm \t= " <<
algorithm <<
"\n";
701 (*outp) << space <<
"\t\t" <<
"description \t= " <<
description <<
"\n";
702 (*outp) << space <<
"\t\t" <<
"output \t= " << path <<
"\n";
703 (*outp) << space <<
"\t\t" <<
"display \t= StatBox\n";
705 for (
unsigned it=0 ; it<
tags.size() ; it++ ) (*
outp) << space <<
"\t\t" <<
replace(
tags[it],
"=",
"\t=") <<
"\n";
706 (*outp) << space <<
"\t" <<
"}\n";
716 if (
print ) (*outp) << space <<
"}\n";
739void search( TDirectory* td,
const std::string& s, std::string
cwd,
node* n ) {
744 if ( std::string(td->GetName()).find(
"_LB")!=std::string::npos )
return;
745 if ( std::string(td->GetName()).find(
"lb_")!=std::string::npos )
return;
756 std::cerr <<
"search() WARNING too many levels of directories (max 10) !!!\n";
761 TDirectory* here = gDirectory;
767 if (
cwd!=
"" )
cwd +=
"/";
768 cwd += td->GetName();
772 std::string fulldir = td->GetName();
775 bool first_found =
false;
780 if ( (
cwd+
"/").
find( ase+
"/" )!=std::string::npos ) {
785 std::cerr <<
"matched dirs " <<
cwd <<
" " <<
matchdir(
cwd ) << std::endl;
788 std::map<std::string,int>::const_iterator fitr =
matchcwditr(
cwd );
790 if ( fitr!=
dirs.end() ) {
792 if ( fitr->second>0 ) {
794 std::vector<std::string> subpath;
796 std::string
sp = fitr->first;
798 while(
sp.size() ) subpath.push_back(
chop(
sp,
"/") );
800 for (
unsigned ip=0 ; ip<subpath.size()-1 ; ip++ ) {
823 TList* tl = gDirectory->GetListOfKeys();
831 for (
int i=0 ; i<tl->GetSize() ; i++ ) {
833 TKey* tobj = (TKey*)tl->At(i);
835 if ( tobj==0 )
continue;
841 if ( std::string(tobj->GetClassName()).find(
"TDirectory")!=std::string::npos ) {
844 TDirectory* tnd = (TDirectory*)tobj->ReadObj();
856 if ( std::string(tobj->GetClassName()).find(
"TH1")!=std::string::npos ||
857 std::string(tobj->GetClassName()).find(
"TH2")!=std::string::npos ||
858 std::string(tobj->GetClassName()).find(
"TProfile")!=std::string::npos ) {
868 std::string subdir =
cwd;
872 savedhistos.push_back( subdir+
"/"+tobj->GetName() );
875 if ( std::string(tobj->GetName())==
"Chain" ) {
880 std::cout <<
"\t" << subdir <<
"\t" << N << std::endl;
882 node* p = np->parent();
883 if ( p && p->name()!=
"Shifter" ) {
885 p->addrate( p->name(), N );
887 node* p2 = p->parent();
888 if ( p2 ) p2->addrate( p->name(), N );
922int cost( std::vector<std::string>&
files,
node& n,
const std::string& directory=
"",
bool deleteref=
false,
bool relocate=
false ) {
924 std::cerr <<
"processing ..." << std::endl;
931 for (
unsigned i=0 ; i<
files.size() ; i++ ) {
935 std::cerr <<
"opening " <<
currentfile << std::endl;
938 std::cerr <<
"file " <<
files[i] <<
" does not exist" << std::endl;
943 fptr[i] = TFile::Open(
files[i].c_str() );
945 if (
fptr[i]==0 ||
fptr[i]->IsZombie() ) {
946 std::cerr <<
"file " <<
files[i] <<
" cannot be opened" << std::endl;
952 if ( directory!=
"" )
fptr[i]->cd(directory.c_str());
954 TDirectory* here = gDirectory;
963 search( gDirectory,
"",
"", &n );
971 if ( deleteref || relocate ) {
973 std::cerr <<
"remapping" << std::endl;
977 if ( relocate && !deleteref ) std::cerr <<
"saving histograms to file .newhist.root ... " << std::endl;
980 TFile* fnew =
new TFile(
outref.c_str(),
"recreate" );
983 TDirectory*
base = gDirectory;
987 for (
unsigned ih=0 ; ih<
savedhistos.size() ; ih++ ) {
991 for (
unsigned jh=0 ; jh<
dirs.size()-1 ; jh++ ) {
993 TDirectory* renedir = gDirectory->GetDirectory(
dirs[jh].c_str() );
994 if ( renedir==0 ) gDirectory->mkdir(
dirs[jh].c_str() );
995 gDirectory->cd(
dirs[jh].c_str() );
1001 href->Write(
dirs.back().c_str() );
1010 std::cerr <<
"closing files" << std::endl;
1017 if (
outref==
".newhist.root" ) {
1018 std::cerr <<
"replacing histogram file" << std::endl;
1019 std::string cmd = std::string(
"mv ") +
files[i] +
" " +
files[i] +
".bak";
1020 std::system( cmd.c_str() );
1021 cmd = std::string(
"mv .newhist.root ") +
files[i];
1022 std::system( cmd.c_str() );
1035int usage(std::ostream& s,
int ,
char** argv,
int status=-1) {
1036 s <<
"Usage: " << argv[0] <<
" [OPTIONS] input1.root ... inputN.root\n\n";
1037 s <<
" -o FILENAME \tname of output (filename required)\n";
1038 s <<
" -b, --base DIR \tuse directory DIR as the base for the han config\n";
1039 s <<
" -d, --dir DIR \tonly directories below DIR where DIR is a structure such as HLT/TRIDT etc\n";
1040 s <<
" -x, DIR \texclude directory DIR\n";
1041 s <<
" -r SRC DST \tremap directory SRC to directory DST\n";
1042 s <<
" -ds, --desc DESCRIP \tuse DESCRIP as the description\n";
1043 s <<
" -t, --tag VALUE \tadd the VALUE to the list of command per histogram\n";
1044 s <<
" -a, --algorithm VALUE \tuse VALUE as the execution algorithm for each histogram\n";
1045 s <<
" -wc, --wildcard \tprint use hist * rather than a separate entry for each histogram\n";
1046 s <<
" -dr, --deleteref \tdelete unselected histograms\n";
1047 s <<
" -or, --outref FILENAME \tdelete file to write reduced output to (overwrites input otherwise) \n";
1048 s <<
" -rh, --relocate \trelocate selected histograms\n";
1049 s <<
" -ref, --reference TAG FILE \tadd FILE as a reference file with tag TAG\n";
1050 s <<
" -rc, --refconf FILE \tadd FILE to the config as a reference block\n";
1051 s <<
" -v, --verbose \tprint verbose output\n";
1052 s <<
" -h, --help \tdisplay this help\n";
1061 std::ifstream strm(
file.c_str());
1062 for ( std::string line ; getline( strm, line ); )
refblock.push_back( line );
1074 gStyle->SetPadRightMargin(0.05);
1075 gStyle->SetPadTopMargin(0.075);
1078 TCanvas* tg =
new TCanvas(
"tg",
"tg", 700, 600 );
1081 gStyle->SetStatY(0.4);
1083 gStyle->SetStatX(0.89);
1085 gStyle->SetStatW(0.25);
1087 gStyle->SetStatH(0.16);
1091 if ( argc<2 )
return usage( std::cerr, argc, argv );
1094 for (
int i=1 ; i<argc ; i++ ) {
1095 if ( std::string(argv[i])==
"-h" || std::string(argv[i])==
"--help" )
return usage( *
outp, argc, argv, 0 );
1098 std::string dir =
"";
1100 std::vector<std::string> subdirs;
1103 bool deleteref =
false;
1104 bool relocate =
false;
1106 std::string outfile =
"";
1111 for (
int i=1 ; i<argc ; i++ ) {
1112 if ( std::string(argv[i])==
"-v" || std::string(argv[i])==
"--verbose" )
verbose =
true;
1113 else if ( std::string(argv[i])==
"-o" ) {
1115 if ( i<argc-offset ) outfile = argv[i];
1116 else return usage( std::cerr, argc, argv );
1118 else if ( std::string(argv[i])==
"-or" || std::string(argv[i])==
"--outrefr" ) {
1120 if ( i<argc-offset )
outref = argv[i];
1121 else return usage( std::cerr, argc, argv );
1123 else if ( std::string(argv[i])==
"-ref" || std::string(argv[i])==
"--reference" ) {
1125 std::string reffile;
1127 if ( i<argc-offset ) reftag = argv[i];
1128 else return usage( std::cerr, argc, argv );
1130 if ( i<argc-offset ) reffile = argv[i];
1131 else return usage( std::cerr, argc, argv );
1135 else if ( std::string(argv[i])==
"-rc" || std::string(argv[i])==
"-refconf" ) {
1138 else return usage( std::cerr, argc, argv );
1140 else if ( std::string(argv[i])==
"-dr" || std::string(argv[i])==
"--deleteref" ) deleteref =
true;
1141 else if ( std::string(argv[i])==
"-rh" || std::string(argv[i])==
"--relocate" ) relocate =
true;
1142 else if ( std::string(argv[i])==
"-wc" || std::string(argv[i])==
"--wildcard" )
allhists =
false;
1143 else if ( std::string(argv[i])==
"-d" || std::string(argv[i])==
"--dir" ) {
1146 if ( i<argc-offset ) {
1147 std::string stringdir(argv[i]);
1148 dirs.insert( std::map<std::string,int>::value_type( stringdir, std::count( stringdir.begin(), stringdir.end(),
'/' ) ) );
1150 std::string tdir = argv[i];
1155 subdirs.push_back(
chop( tdir,
"/" ) );
1158 while ( tdir.size() );
1160 else return usage( std::cerr, argc, argv );
1162 else if ( std::string(argv[i])==
"-x" ) {
1164 if ( i<argc-offset )
exclude.insert( argv[i] );
1165 else return usage( std::cerr, argc, argv );
1167 else if ( std::string(argv[i])==
"-ds" || std::string(argv[i]).
find(
"--desc")==0 ) {
1170 else return usage( std::cerr, argc, argv );
1172 else if ( std::string(argv[i])==
"-b" || std::string(argv[i])==
"--base" ) {
1174 if ( i<argc-offset )
base = argv[i] ;
1175 else return usage( std::cerr, argc, argv );
1177 else if ( std::string(argv[i])==
"-a" || std::string(argv[i])==
"--algorithm" ) {
1179 if ( i<argc-offset )
algorithm = argv[i] ;
1180 else return usage( std::cerr, argc, argv );
1187 else if ( std::string(argv[i])==
"-t" || std::string(argv[i])==
"--tag" ) {
1189 if ( i<argc-offset )
tags.push_back( argv[i] );
1190 else return usage( std::cerr, argc, argv );
1192 else if ( std::string(argv[i])==
"-r" ) {
1195 if ( i<argc+2-offset ) {
1198 remap.insert( std::map<std::string,std::string>::value_type( src, dest ) );
1199 }
else return usage( std::cerr, argc, argv );
1203 files.push_back(argv[i]);
1208 if (
base ==
"" )
base = std::move(dir);
1213 if (
files.size()<1 )
return usage( std::cerr, argc, argv );
1218 if (
verbose ) std::cerr <<
"timing" << std::endl;
1225 n.name(
"top_level" );
1227 int status =
cost(
files, n,
"", deleteref, relocate );
1231 if ( status )
return status;
1233 if ( outfile!=
"" )
outp =
new std::ofstream(outfile.c_str());
1248 (*outp) << std::endl;
1252 if ( t>1000 ) std::cerr <<
"total time " << t*0.001 <<
" s" << std::endl;
1253 else std::cerr <<
"total time " << t <<
" ms" << std::endl;
struct timeval simpletimer_start(void)
double simpletimer_stop(const struct timeval &start_time)
void print(char *figname, TCanvas *c1)
TGraphErrors * GetEntries(TH2F *histo)
node * addnode(node *np, const std::string &name, TObject *td, node::TYPE t)
add a submode with a specific name, or return the existing node if one already exists
Define macros for attributes used to control the static checker.
#define ATLAS_NO_CHECK_FILE_THREAD_SAFETY
Header file for AthHistogramAlgorithm.
make the histogram assessment part of the config
void makeass(node &n, const std::string &space="", std::string path="", std::string rawpath="", bool found=false)
ass(node &n, bool ah=true)
const std::string & name() const
const std::string & file() const
reference(const reference &r)
reference(const std::string &n, const std::string &f)
T * Get(TFile &f, const std::string &n, const std::string &dir="", const chainmap_t *chainmap=0, std::vector< std::string > *saved=0)
get a histogram given a path, and an optional initial directory if histogram is not found,...
int ir
counter of the current depth
bool matchcwd(const std::string &s)
std::vector< TFile * > fptr
bool matchdir(const std::string &s)
see whether this directory matches any of the directories we are explicitly being asked to match
std::string description
glabal timer - how long have I taken so far?
std::ostream & operator<<(std::ostream &s, const std::vector< T > &v)
std::vector< std::string > maphist(const std::vector< std::string > &v)
std::vector< std::string > files
file names and file pointers
std::string chopex(std::string &s1, const std::string &s2)
std::vector< std::string > savedhistos
std::string date()
sadly, includes a return at the end
void depunctuate(std::string &s, const std::string ®ex=":")
std::vector< std::string > tags
std::string replace(std::string s, const std::string &s2, const std::string &s3)
std::vector< std::string > mapped
std::map< std::string, int >::const_iterator matchcwditr(const std::string &s)
void referenceblock(const std::string &file)
std::string choptoken(std::string &s1, const std::string &s2)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles
std::vector< reference > references
std::ostream * outp
send output to here ...
int cost(std::vector< std::string > &files, node &n, const std::string &directory="", bool deleteref=false, bool relocate=false)
bool contains(const std::string &s, const std::string ®x)
does a string contain the substring
bool file_exists(const std::string &file)
std::string chopends(std::string &s1, const std::string &s2)
std::string chomp(std::string &s1, const std::string &s2)
void removespace(std::string &s, const std::string &s2)
std::string find(const std::string &s)
return a remapped string
int count(std::string s, const std::string ®x)
count how many occurances of a regx are in a string
std::set< std::string > exclude
list of directories to be excluded
std::string chopfirst(std::string &s1, const std::string &s2)
std::map< std::string, std::string > remap
list of directories to be explicitly remapped
std::string choplast(std::string &s1, const std::string &s2)
std::map< std::string, int > dirs
list of directories to be explicitly included, together with corresponding depths of subdirectories
std::string matchcwdstr(const std::string &s)
std::vector< std::string > split(const std::string &s, const std::string &t=":")
std::vector< std::string > refblock
std::string chomptoken(std::string &s1, const std::string &s2)
std::string chop(std::string &s1, const std::string &s2)
bool match(std::string s1, std::string s2)
match the individual directories of two strings