#ifndef ANALYSIS_HH_INCLUDED #define ANALYSIS_HH_INCLUDED #include "Flux.hh" #include "Astro.hh" #include "Evt.hh" #include "Det.hh" #include "io_util.hh" #include #include #include #include #include using namespace std; #include "TCanvas.h" #include "Computable.hh" #include "Histogram.hh" #include "foreach.hh" #include "stringutil.hh" #include "EventFile.hh" #include "HistSet.hh" #include "RunSet.hh" #include "../search/definitions.hh" using namespace analysis; /*! An analysis is little more than a set of periods */ struct Analysis { string name; RunSet runset; vector< HistSet > histsets; Analysis( string name ) : name(name) {} Analysis() {} void init_histset(TFile* outfile, string period, string flavor, string cfg){ HistSet h; h.name = name; h.period = period; h.flavor = flavor; h.batch = -1; h.analysis = this; h.outputfile = outfile; h.read_config(cfg); histsets.push_back( h ) ; } /*! return all names, across all histsets, of all observables/selections/variants */ vector all_names( string what = "observables" ) { vector r; for( auto& h : histsets ) { add( r, h.names_of(what) ); } set s( r.begin(), r.end() ); return vector( r.begin(), r.end() ); } vector all_flavors() { return runset.all_flavors(); } /* flag all runs in the given run-range as belonging to period */ int flag_period( string period_name, string description, int first_run, int last_run ) { return runset.flag_period( period_name, description, first_run, last_run ); } struct Job { int id; string flavor; string period; int batch; int nevents; ClassDef(Job, 1); }; /* make a vector of jobs, based on the batches */ vector jobs() { vector allflavs = runset.all_flavors(); vector allbatches = runset.all_batches(); vector r; for( auto& flav : allflavs ) for( auto& batch : allbatches ) { Job j; j.id = r.size() + 1000; j.flavor = flav; j.batch = batch; j.period = runset.get_period_of_batch( batch ); j.nevents = runset.total_nevents_of_batch( batch, flav ); r.push_back( j ); } return r; } HistSet& get_histset( Job& job ) { return get_histset( job.flavor, job.batch ); } /*! find a histset, or clone one for the current batch */ HistSet& get_histset( string flavor, int batch ) { vector flavmatches; vector matches; for( auto& hs : histsets ) { if ( hs.flavor != flavor ) continue; flavmatches.push_back( &hs ); if ( hs.batch == batch ) { matches.push_back( &hs ); } } if ( matches.size() > 1 ) { fatal("Error: two histsets for the same batch!"); } if ( matches.size() == 1 ) { return *matches[0]; } if ( flavmatches.size() > 0 ) { // clone a Histset of the same flavor HistSet& src = *flavmatches[0]; HistSet dst = src; // copy dst.batch = batch; dst.period = runset.get_period_of_batch( batch ); dst.histograms.clear(); histsets.push_back( dst ); return *histsets.rbegin(); } else { static auto empty = HistSet(); return empty; } } void run_job( int jobnum ) { for (auto j : jobs() ) { print( "have job ", j.id ); if (j.id != jobnum ) continue; auto& hset = get_histset( j ); RunSet myruns = runset; myruns.filter( [&](Run& run) { return j.batch == run.batch; }); hset.init_config(); hset.run( myruns ); } print("done with run_job"); } Table job_table() { Table T("jobnum","flavor","period","batch","nevents"); for(auto& j : jobs() ) T << j.id << j.flavor << j.period << j.batch << j.nevents; return T; } Table histset_table() { Table T("name","flavor","period","batch","nhistograms","selections","weights","observables"); for(auto& h : histsets ) T << h.name << h.flavor << h.period << h.batch << h.histograms.size() << h.selections.size() << h.weights.size() << h.observables.size(); return T; } void merge_histsets() { // todo: check that we have all expected jobs/batches!! map M; for( auto& h : histsets ) { if ( h.batch == -1 ) { h.name = "_deleteme"; continue; } string key = h.flavor+"@"+h.period; if (!contains( keys(M), key )) { M[key] = &h; } else { M[key]->merge( h ); h.name = "_deleteme"; } } print ( histset_table() ); remove_element_if( histsets, [](const HistSet& h) { return h.batch == -1 || h.name == "_deleteme"; } ); } void set_output_file( TFile* outfile ) { for( auto& h : histsets ) h.set_output_file( outfile ); } ClassDef(Analysis, 1); }; #endif