1068 const string myname =
"AdcRoiViewer::fillSumHists: ";
1075 if (
m_LogLevel >= 2 ) cout << myname <<
"Setting run data." <<
endl;
1078 if ( rdat.
run() != rdatOld.
run() ) {
1079 cout << myname <<
"Ignoring unexpected change in run number: " << rdatOld.
run()
1080 <<
" --> " << rdat.
run();
1082 }
else if ( ! rdat.
isValid() ) {
1083 if (
m_LogLevel >= 3 ) cout << myname <<
"Run data not found." <<
endl;
1086 float pulserQin = 0.0;
1089 bool haveQin =
false;
1090 if ( havePulserAmplitude ) {
1094 haveQin = pulserQin != 0.0;
1096 cout << myname <<
"WARNING: Pulser charge evaluates to zero." <<
endl;
1099 Index pulserPeriod = 0;
1100 if ( havePulserPeriod ) {
1102 if ( pulserPeriod == 0 ) {
1103 havePulserPeriod =
false;
1104 cout << myname <<
"WARNING: Pulser period is zero." <<
endl;
1109 bool haveTickOffset =
false;
1110 long tickOffset = 0;
1111 bool haveTickOffsetPulserMod =
false;
1112 Index tickOffsetPulserMod = 0;
1113 double timingPhase = 0.0;
1123 haveTickOffset =
true;
1124 tickOffset = off.
value;
1125 timingPhase = off.
rem;
1127 cout << myname <<
"Unable to retrieve tick offset for run " << tdat.
run <<
"-" << tdat.
subrun 1130 if ( haveTickOffset && havePulserPeriod ) {
1131 long toff = tickOffset;
1132 long period = pulserPeriod;
1133 toff = toff % period;
1134 if ( toff < 0 ) toff += period;
1135 tickOffsetPulserMod = toff;
1136 haveTickOffsetPulserMod =
true;
1143 const HistInfo& hin0 = ish.second;
1145 Name varx = hin0.varx;
1147 if ( varx ==
"fitHeight" ) varx =
"fitHeightNeg";
1148 if ( varx ==
"sigArea" ) varx =
"sigAreaNeg";
1150 Name vary = hin0.vary;
1152 Name fitName = hin0.fitName;
1153 Name plotNameTemplate = hin0.plotName;
1156 if ( varx ==
"sigArea" ) vals = dm.
getFloatVector(
"roiSigAreas");
1157 else if ( varx ==
"sigAreaNeg" ) vals = dm.
getFloatVector(
"roiSigAreas");
1158 else if ( varx ==
"sigWidth" ) ivals = dm.
getIntVector(
"roiNTicks");
1159 else if ( varx ==
"sigTick0" ) ivals = dm.
getIntVector(
"roiTick0s");
1160 else if ( varx ==
"sigTick0Pulser" ) ivals = dm.
getIntVector(
"roiTick0s");
1161 else if ( varx ==
"sigTickMax" ) ivals = dm.
getIntVector(
"roiTickMaxs");
1162 else if ( varx ==
"sigTickMaxPulser" ) ivals = dm.
getIntVector(
"roiTickMaxs");
1163 else if ( varx ==
"fitHeight" ) vals = dm.
getFloatVector(
"roiFitHeights");
1164 else if ( varx ==
"fitHeightNeg" ) vals = dm.
getFloatVector(
"roiFitHeights");
1165 else if ( varx ==
"fitHeightGain" ) vals = dm.
getFloatVector(
"roiFitHeights");
1166 else if ( varx ==
"fitWidth" ) vals = dm.
getFloatVector(
"roiFitWidths");
1167 else if ( varx ==
"fitPos" ) vals = dm.
getFloatVector(
"roiFitPositions");
1168 else if ( varx ==
"fitPosRem" ) vals = dm.
getFloatVector(
"roiFitPositions");
1169 else if ( varx ==
"fitPosPulser" ) vals = dm.
getFloatVector(
"roiFitPositions");
1170 else if ( varx ==
"fitToffPulser" ) vals = dm.
getFloatVector(
"roiFitPositions");
1171 else if ( varx ==
"fitToffPulserMod10" ) vals = dm.
getFloatVector(
"roiFitPositions");
1172 else if ( varx ==
"fitStat" ) ivals = dm.
getIntVector(
"roiFitStats");
1173 else if ( varx ==
"fitChiSquare" ) vals = dm.
getFloatVector(
"roiFitChiSquares");
1174 else if ( varx ==
"fitChiSquareDof" ) vals = dm.
getFloatVector(
"roiFitChiSquareDofs");
1175 else if ( varx ==
"fitCSNorm" ) vals = dm.
getFloatVector(
"roiFitChiSquares");
1176 else if ( varx ==
"fitCSNormDof" ) vals = dm.
getFloatVector(
"roiFitChiSquareDofs");
1177 else if ( varx ==
"timeSec" ) ivals = dm.
getIntVector(
"roiTimes");
1178 else if ( varx ==
"timeHour" ) ivals = dm.
getIntVector(
"roiTimes");
1179 else if ( varx ==
"timeDay" ) ivals = dm.
getIntVector(
"roiTimes");
1180 else if ( varx ==
"procEvent" ) ivals.push_back(acd.
event());
1181 else if ( varx ==
"procTimeSec" ) ivals.push_back(
int(acd.
time()) -
int(
m_StartTime));
1182 else if ( varx ==
"procTimeHour" ) ivals.push_back(
int(acd.
time()) -
int(
m_StartTime));
1183 else if ( varx ==
"procTimeDay" ) ivals.push_back(
int(acd.
time()) -
int(
m_StartTime));
1186 cout << myname <<
"ERROR: Invalid variable name: " << varx <<
endl;
1190 Name hnam0 = ph0->GetName();
1193 Name ylab = ph0->GetYaxis()->GetTitle();
1195 if ( ivals.size() && !vals.size() )
for (
int ival : ivals ) vals.push_back(ival);
1196 if ( varx ==
"fitPosRem" )
for (
float&
val : vals )
val = std::remainder(
val,1);
1197 if ( varx ==
"fitPosPulser" ) {
1198 if ( ! havePulserPeriod ) {
1199 cout << myname <<
"WARNING: Cannot evaluate " << varx <<
" without pulser period" <<
endl;
1202 for (
float&
val : vals )
val = fmod(
val, pulserPeriod);
1204 if ( varx ==
"fitToffPulser" || varx ==
"fitToffPulserMod10" ||
1205 varx ==
"sigTick0Pulser" || varx ==
"sigTickMaxPulser" ) {
1206 if ( ! haveTickOffsetPulserMod ) {
1207 cout << myname <<
"WARNING: Cannot evaluate " << varx <<
" without timing offset and pulser period" <<
endl;
1210 for (
float&
val : vals )
val = fmod(
val + pulserPeriod + tickOffsetPulserMod, pulserPeriod);
1211 if ( varx ==
"fitToffPulserMod10" ) {
1212 for (
float&
val : vals )
val = fmod(
val, 10.0);
1216 if ( varx ==
"fitHeightNeg" ) varfac = -1.0;
1217 if ( varx ==
"sigAreaNeg" ) varfac = -1.0;
1218 if ( varx ==
"fitCSNorm" || varx ==
"fitCSNormDof" ) {
1220 if ( pedrms > 0.0 ) varfac = 1.0/(pedrms*pedrms);
1223 if ( varx ==
"fitHeightGain" ) {
1225 cout << myname <<
"WARNING: Cannot evaluate " << varx <<
" without Qin" <<
endl;
1228 varfac = 1.0/pulserQin;
1230 if ( varx ==
"timeHour" || varx ==
"procTimeHour" ) varfac = 1/3600.0;
1231 if ( varx ==
"timeDay" || varx ==
"procTimeDay" ) varfac = 1/(24*3600.0);
1232 if ( varfac != 1.0 )
for (
float&
val : vals )
val *= varfac;
1236 if ( (ph ==
nullptr) || (ph->GetEntries() == 0 && vals.size()) ) {
1237 bool replacingHistogram = ph !=
nullptr;
1241 bool havePlot = plotNameTemplate.size();
1244 if ( replacingHistogram ) {
1246 iplotHist = find(plotHists.begin(), plotHists.end(), ph);
1247 if ( iplotHist == plotHists.end() ) {
1248 cout << myname <<
"ERROR: Unable to find histogram in plot name list." <<
endl;
1250 iplotHist = plotHists.end();
1252 *iplotHist =
nullptr;
1256 if (
m_LogLevel >= 2 ) cout << myname <<
"Replacing histogram " << hnam <<
endl;
1259 plotHists.push_back(
nullptr);
1260 iplotHist = plotHists.end();
1263 if (
m_LogLevel >= 2 ) cout << myname <<
"Creating histogram " << hnam <<
endl;
1265 Name httl0 = ph0->GetTitle();
1267 int nbin = ph0->GetNbinsX();
1268 float xmin = ph0->GetXaxis()->GetXmin();
1269 float xmax = ph0->GetXaxis()->GetXmax();
1272 if ( vals.size() && xmin > xmax && xmin > 0.0 ) {
1274 std::sort(tmpvals.begin(), tmpvals.end());
1275 Index nval = tmpvals.size();
1276 if (
m_LogLevel >= 3 ) cout << myname <<
" Centering histogram on median of " 1277 << nval <<
" value" << (nval==1 ?
"" :
"s") << endl;
1278 float xmed = 0.5*(tmpvals[(nval-1)/2] + tmpvals[nval/2]);
1280 xmin = xmed - 0.5*width;
1281 bool roundXmin = xmax > 0.0;
1287 xmin = rfac*
int(xmin/rfac + (xmin > 0.0 ? 0.5 : -0.5));
1289 xmax = xmin + width;
1291 }
else if ( xmin >= xmax ) {
1295 }
else if ( xmin < 0.0 ) {
1303 cout << myname <<
" Name: " << hnam <<
endl;
1304 cout << myname <<
" Title: " << httl <<
endl;
1305 cout << myname <<
" nbin: " << nbin <<
endl;
1306 cout << myname <<
" xmin: " << xmin <<
endl;
1307 cout << myname <<
" xmax: " << xmax <<
endl;
1308 cout << myname <<
" fit: " << fitName <<
endl;
1310 bool isTH2 =
dynamic_cast<TH2*
>(ph0);
1312 ph =
new TH1F(hnam.c_str(), httl.c_str(), nbin, xmin, xmax);
1314 int nbiny = ph0->GetNbinsY();
1315 float ymin = ph0->GetYaxis()->GetXmin();
1316 float ymax = ph0->GetYaxis()->GetXmax();
1317 ph =
new TH2F(hnam.c_str(), httl.c_str(), nbin, xmin, xmax, nbiny, ymin, ymax);
1319 ph->SetDirectory(
nullptr);
1322 ph->SetLineWidth(2);
1323 ph->GetXaxis()->SetTitle(xlab.c_str());
1324 ph->GetYaxis()->SetTitle(ylab.c_str());
1325 if ( ph0->GetListOfFunctions()->GetEntries() ) {
1326 TF1* pf =
dynamic_cast<TF1*
>(ph0->GetListOfFunctions()->At(0)->Clone());
1327 ph->GetListOfFunctions()->AddLast(pf);
1328 ph->GetListOfFunctions()->SetOwner(kTRUE);
1333 if ( plotNameTemplate.size() ) {
1335 if ( havePlot ) *iplotHist = ph;
1336 if ( ! replacingHistogram ) {
1342 if (
m_LogLevel >= 3 ) cout << myname <<
"Filling summary histogram " << hnam
1343 <<
". Fill count is " << vals.size() <<
endl;
1346 bool checkFit = varx.substr(0,3) ==
"fit";
1347 if ( csds.size() == 0 || fstats.size() == 0 ) checkFit =
false;
1348 double chiSquareDofMax = 0.0;
1350 if ( csds.size() != vals.size() ) {
1351 cout <<
"ERROR: Variable and chi-square/DF vectors have different sizes." <<
endl;
1354 if ( fstats.size() != vals.size() ) {
1355 cout <<
"ERROR: Variable and fit status vectors have different sizes: " 1356 << vals.size() <<
" != " << fstats.size() <<
endl;
1362 bool logerr =
m_LogLevel >= 3 && nhstGood == 0;
1363 for (
Index ival=0; ival<vals.size(); ++ival ) {
1366 int fstat = fstats[ival];
1367 float csd = csds[ival];
1369 if ( logerr) cout << myname <<
"WARNING: Skipping entry with fit status " << fstat
1370 <<
" (chi-square/DOF = " << csd <<
")" <<
endl;
1373 }
else if ( chiSquareDofMax > 0.0 && csd > chiSquareDofMax ) {
1374 if ( logerr) cout << myname <<
"WARNING: Skipping entry with chi-square/DOF = " << csd <<
endl;
1379 float val = vals[ival];
1381 if ( vary ==
"timingPhase" ) valy = timingPhase;
1382 if ( vary ==
"event" ) valy = acd.
event();
1386 ph->Fill(val, valy);
1391 cout << myname <<
"WARNING: Skipped " << nvalSkip <<
" of " << nval
1392 <<
" entries due to bad fit for histogram " << hnam <<
"." <<
endl;
1396 if ( nhstGood != nhst ) {
1397 cout << myname <<
"WARNING: Only filled " << nhstGood <<
" of " << nhst <<
" histograms." <<
endl;
const TimeOffsetTool * m_pTickOffsetTool
bool havePulserPeriod() const
const AdcChannelStringTool * m_adcStringBuilder
HistInfoMap sumHistTemplates
Index pulserAmplitude() const
bool havePulserSource() const
const RunDataTool * m_pRunDataTool
IndexByNameMap sumHistChannels
ChannelGroupService::Name Name
const IntVector & getIntVector(Name name) const
const FloatVector & getFloatVector(Name name) const
TH1 * getSumHist(Name hnam)
std::vector< TH1 * > HistVector
Index pulserPeriod() const
HistVectorMap sumPlotHists
std::vector< int > IntVector
Dft::FloatVector FloatVector
AdcLongIndex triggerClock() const
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
QTextStream & endl(QTextStream &s)
bool havePulserAmplitude() const