12 #include "dbclient/KM3NeTDBClient.h" 
   16 #include "JDB/JDBincludes.hh" 
   35 #include "TGraphErrors.h" 
   59     interpolator(
const double minHVdiff, 
const double minGain, 
const double maxGain, 
const double targetGain) :
 
   60       dHV(minHVdiff), gainMin(minGain), gainMax(maxGain), gainTarget(targetGain) {}
 
   70     const bool checkHV(map_t::const_reference entry1, map_t::const_reference entry2)
 const {
 
   72       return (fabs(entry1.first - entry2.first) > dHV);
 
   82     const bool checkGain(map_t::const_reference entry)
 const {
 
   84       return (entry.second.first > gainMin && entry.second.first < gainMax);
 
   95     const bool areIncreasing(map_t::const_reference entry1, map_t::const_reference entry2)
 const { 
 
   97       return ((entry1.first < entry2.first && entry1.second.first > entry2.second.first) ||
 
   98               (entry1.first > entry2.first && entry1.second.first < entry2.second.first));
 
  109     const bool areValid(map_t::const_reference entry1,
 
  110                         map_t::const_reference entry2)
 const { 
 
  112       return (checkHV      (entry1, entry2) && checkGain(entry1) &&
 
  113               areIncreasing(entry1, entry2) && checkGain(entry2));
 
  123     const pair<map_t::const_reference,
 
  124                map_t::const_reference> getPoints(
const map_t& data)
 const {
 
  126       map_t::const_iterator point0 = data.cbegin();
 
  127       map_t::const_iterator point1 = next(data.cbegin());
 
  129       for (map_t::const_iterator it = next(data.cbegin()); it != data.cend(); ++it) {
 
  131         if        (fabs(it->second.first - gainTarget) < fabs(point0->second.first - gainTarget)) {
 
  133           point1 = (areValid(*point0, *it) ? point0 : point1);
 
  136         } 
else if ((fabs(it->second.first - gainTarget) < fabs(point1->second.first - gainTarget) ||
 
  137                     !areValid(*point0, *point1)) && areValid(*point0, *it)) { 
 
  143       return pair<map_t::const_reference,
 
  144                   map_t::const_reference>(*point0, *point1);
 
  156                                             map_t::const_reference entry2)
 const {
 
  160       if (areValid(entry1, entry2)) {
 
  162         const double logHV0    = log(fabs(entry1.first));
 
  163         const double logHV1    = log(fabs(entry2.first));
 
  165         const double logG0     = log(entry1.second.first);
 
  166         const double logG1     = log(entry2.second.first);
 
  167         const double elogG0    = entry1.second.second / entry1.second.first;
 
  168         const double elogG1    = entry2.second.second / entry2.second.first;
 
  170         const double dlogG0    = log(gainTarget) - logG0;
 
  171         const double dlogG1    = log(gainTarget) - logG1;
 
  173         const double slope     = (logG1 - logG0) / (logHV1 - logHV0);
 
  174         const double logHVnom  = dlogG0 / slope + logHV0;
 
  175         const double elogHVnom = sqrt(dlogG1 * dlogG1 * elogG0 * elogG0 +
 
  176                                       dlogG0 * dlogG0 * elogG1 * elogG1) / fabs(slope * (logG1 - logG0));
 
  179         result.second =  
exp(logHVnom) * elogHVnom;
 
  194       pair<map_t::const_reference,
 
  195            map_t::const_reference> intpPoints = getPoints(data);
 
  197       return getNominalHV(intpPoints.first, intpPoints.second);
 
  202     const double gainMin;     
 
  203     const double gainMax;     
 
  204     const double gainTarget;  
 
  216 int main(
int argc, 
char **argv)
 
  236   double           HVstepMin   = 2 * 3.14;                
 
  253     JParser<> zap(
"Example program to find optimal HV-settings.");
 
  258     zap[
'f'] = 
make_field(inputFiles,   
"map of run numbers to file strings (i.e. to the output of JFitToT)");
 
  259     zap[
'a'] = 
make_field(detectorFile, 
"detector file");
 
  260     zap[
'T'] = 
make_field(testType,     
"test type")                                  = 
"HV-TUNING-SEA-GAIN-v1";
 
  262     zap[
'o'] = 
make_field(graphFile,    
"Graphical output           (root format)")   = 
"";
 
  268   catch(
const exception &error) {
 
  269     FATAL(error.what() << endl);
 
  285     NOTICE(
"Loading database tables..." << endl);
 
  295       ResultSet& rs       = 
getResultSet(getTable<JPersons>(), selector);
 
  303       const int runNr = fileIt->first;
 
  305       NOTICE(
"Extracting Gain-/HV-data for run " << runNr << endl);
 
  309         TFile fitData(fileIt->second.c_str(), 
"READ");
 
  312         ResultSet& rs       = 
getResultSet(getTable<JPMTHVRunSettings>(), selector);
 
  316           const int domID = 
detector.getModule(
JLocation(table.DUID, table.FLOORID)).getID();
 
  320           const TF1* f1 = (h1 != NULL ? h1->GetFunction(
FITTOT_FNAME.c_str()) : NULL);
 
  322           double gain      = (fabs(gainMin - gainTarget) > fabs(gainMax - gainTarget) ? gainMin : gainMax);
 
  323           double gainError = 0.0;
 
  327             const int Ngain = f1->GetParNumber(
"gain");
 
  329             gain      = f1->GetParameter(Ngain);
 
  330             gainError = f1->GetParError (Ngain);
 
  332           } 
else if (h1 == NULL && find(missingDOMs.cbegin(), missingDOMs.cend(), domID) == missingDOMs.cend()) {
 
  334             missingDOMs.push_back(domID);
 
  337           data[domID][table.PMTSERIAL][table.DUID][table.FLOORID][table.PMTINTID].insert(make_pair(table.HV_VALUE, make_pair(gain, gainError)));
 
  340           const int    index = 
distance(inputFiles.cbegin(), fileIt);
 
  342           manager[
name]->SetPoint     (index, log10(fabs(table.HV_VALUE)), log10(gain));
 
  343           manager[
name]->SetPointError(index, 0.0, gainError / gain / log(10));
 
  350   } 
catch (
const exception& error) {
 
  352     FATAL(error.what() << endl);
 
  360   NOTICE(
"Searching optimal high-voltage settings..." << endl <<
 
  361          LEFT(30) << 
"UPI" << 
CENTER(35) << 
"(identifer / location)" << 
RIGHT(35) << 
"Inter-/Extrapolated high-voltage [-]" << endl);
 
  363   for (pmtMap_t::super_const_iterator pmt = data.super_begin(); pmt != data.super_end(); ++pmt) {
 
  366     const int         domID   = pmt->first;
 
  368     const JLocation_t location(pmt->second->second->first,
 
  369                                pmt->second->second->second->first,
 
  370                                pmt->second->second->second->second->first);
 
  372     const runMap_t&   data    = pmt.getValue();
 
  374     NOTICE(
LEFT(30) << pmtUPI << 
"(a.k.a. " << domID << 
'.' << 
FILL(2,
'0') << location.
position << 
" / " << location << 
"):");    
 
  377     if (data.size() < 2 || find(missingDOMs.cbegin(), missingDOMs.cend(), domID) != missingDOMs.cend()) {
 
  379       NOTICE (setprecision(2) << right << 
FIXED(20,2) << 0.0 << 
" +/- " << 
FIXED(4,2) << 0.0 << endl);
 
  380       WARNING((data.size() < 2 ? 
"Insufficient data" : 
"Missing (dead?) DOM") << endl);
 
  387     const interpolator interpolator(HVstepMin, gainMin, gainMax, gainTarget);
 
  389     const pair<runMap_t::const_reference,
 
  390                runMap_t::const_reference> points = interpolator.getPoints(data);
 
  393     const bool valid = (interpolator.areValid(points.first, points.second) && result.first < 0.0 &&
 
  394                         ((log(fabs(result.first))        - log(fabs(points.first.first))) /
 
  395                          (log(fabs(points.second.first)) - log(fabs(points.first.first))) < 2.0));
 
  397     NOTICE(setprecision(2) << right << 
FIXED(20,2) << result.first  << 
" +/- " << 
FIXED(4,2) << result.second << endl);
 
  399     if (result.first < data.cbegin()  -> 
first ||
 
  400         result.first > data.crbegin() -> 
first) {
 
  402       WARNING(
"Nominal gain " << gainTarget << 
" lies outside of HV-scan range; " <<
 
  403               "Extrapolation " << (valid ? 
"successful." : 
"failed; Setting zero.") << endl);
 
  407       WARNING(
"Could not find optimal high-voltage; Setting zero." << endl);
 
  412                                  valid ? result.first : 0.0,
 
  416     HVcalibrations.push_back(HVcal); 
 
  420   if (! graphFile.empty()) {
 
  422     TFile out(graphFile.c_str(), 
"RECREATE");
 
  427       it->second->SetMarkerStyle(kFullDotSmall);
 
  438   js[
User_t]                  = person.LOGIN;
 
  447   ofs << setw(2) << setprecision(8);
 
Utility class to parse command line options. 
 
JMultiMap is a general purpose multidimensional map based on a type list of maps. ...
 
static const std::string Failed_t
 
std::vector< T >::difference_type distance(typename std::vector< T >::const_iterator first, typename PhysicsEvent::const_iterator< T > second)
Specialisation of STL distance. 
 
#define gmake_property(A)
macro to convert (template) parameter to JPropertiesElement object 
 
static const std::string Tests_t
 
static const JPBS_t PMT(3, 4, 2, 3)
PBS of photo-multiplier tube (PMT) 
 
static const std::string OK_t
 
static const double FITTOT_GAIN_MAX
Default maximal gain. 
 
static const double FITTOT_GAIN_MIN
Default minimal gain. 
 
Utility class to parse parameter values. 
 
T get(const JHead &header)
Get object from header. 
 
#define MAKE_CSTRING(A)
Make C-string. 
 
then for HISTOGRAM in h0 h1
 
static const std::string Location_t
 
Empty structure for specification of parser element that is initialised (i.e. does not require input)...
 
Universal product identifier (UPI). 
 
Dynamic ROOT object management. 
 
Auxiliary data structure for floating point format specification. 
 
Auxiliary class for specifying selection of database data. 
 
then set_variable FORMULA *[0] exp(-0.5 *(x-[1])*(x-[1])/([2]*[2]))*exp(-0.5 *(y-[1])*(y-[1])/([2]*[2]))" JF2 -o $WORKDIR/f2.root -F "$FORMULA" -@ "p0
 
Data structure for detector geometry and calibration. 
 
then echo The file $DIR KM3NeT_00000001_00000000 root already please rename or remove it first
 
#define MAKE_STRING(A)
Make string. 
 
static const std::string FITTOT_SUFFIX
 
Auxiliary data structure for alignment of data. 
 
JDetectorsHelper getDetector
Function object for mapping serial number to object identifier of detector and vice versa...
 
Auxiliary class to manage set of compatible ROOT objects (e.g. histograms) using unique keys...
 
I/O formatting auxiliaries. 
 
static const char FITTOT_SEPARATOR
 
Logical location of module. 
 
Auxiliary data structure for location of product in detector. 
 
#define make_field(A,...)
macro to convert parameter to JParserTemplateElement object 
 
static const std::string Test_t
 
const double NOMINAL_GAIN
Specification for normalized gain corresponding to a one photo-electron pulse. 
 
General purpose messaging. 
 
Auxiliary data structure for sequence of same character. 
 
then $JPP_DIR examples JDetector JToT o $OUTPUT_FILE n N $NPE P gain
 
int position
position in floor 
 
static const std::string EndTime_t
 
void load(const std::string &file_name, JDetector &detector)
Load detector from input file. 
 
Auxililary class to get date and time. 
 
Utility class to parse command line options. 
 
Data structure for PMT high-voltage calibration. 
 
static const std::string Type_t
 
std::string to_string(const T &value)
Convert value to string. 
 
ResultSet & getResultSet(const std::string &query)
Get result set. 
 
static const std::string StartTime_t
 
static const std::string User_t
Detector calibration key words for JSON I/O. 
 
JUPIHelper getUPI
Function object for mapping PBS and serial number to UPI. 
 
do set_variable DETECTOR_TXT $WORKDIR detector
 
Template definition for getting table specific selector. 
 
static const std::string FITTOT_FNAME
 
bool putObject(TDirectory *dir, const T &object)
Write object to ROOT directory. 
 
int main(int argc, char *argv[])