@@ -204,6 +204,13 @@ void CheckResidSpec::run(ProcessingContext& pc)
204204 quit = true ;
205205 }
206206 if (quit) {
207+ if (mPostProcOnly && o2::checkresid::CheckResidConfig::Instance ().savePostprocessed ) {
208+ for (const auto & hm : mHManV ) {
209+ if (hm) {
210+ hm->write ();
211+ }
212+ }
213+ }
207214 pc.services ().get <ControlService>().endOfStream ();
208215 pc.services ().get <ControlService>().readyToQuit (QuitRequest::Me);
209216 return ;
@@ -874,6 +881,9 @@ void CheckResidSpec::postProcessHistos()
874881 TObjArray arr;
875882 for (int ihm = 0 ; ihm < maxH; ihm++) {
876883 auto * histm = mHManV [ihm].get ();
884+ if (!histm) {
885+ continue ;
886+ }
877887 auto fitSlices = [&](int id) {
878888 auto h2 = histm->getHisto2F (id);
879889 if (!h2 || h2->GetEntries () < params.minHistoStat2Fit ) {
@@ -927,7 +937,7 @@ void CheckResidSpec::postProcessHistos()
927937void CheckResidSpec::drawHistos ()
928938{
929939 // gROOT->SetBatch(true);
930- gStyle ->SetTitleX (0.2 );
940+ gStyle ->SetTitleX (0.3 );
931941 gStyle ->SetTitleY (0.88 );
932942 gStyle ->SetTitleW (0.25 );
933943 gStyle ->SetOptStat (0 );
@@ -1191,9 +1201,12 @@ void CheckResidSpec::drawHistos()
11911201 czlpar.Print (mainPdf.c_str ());
11921202
11931203 auto getHMinMax = [this ](int id, float marginFrac, float maxDev, int roundToMicrons) -> std::tuple<float , float , float > {
1194- float maxV = std::numeric_limits<float >::min (), minV = std::numeric_limits<float >::max ();
1204+ float maxV = std::numeric_limits<float >::lowest (), minV = std::numeric_limits<float >::max ();
11951205 const int nh = this ->mHManV .size ();
11961206 for (int j = 0 ; j < nh; j++) {
1207+ if (!this ->mHManV [j]) {
1208+ continue ;
1209+ }
11971210 if (auto histo = this ->mHManV [j]->getHisto (id); histo != nullptr ) {
11981211 const int nb = histo->GetNbinsX ();
11991212 for (int ib = 1 ; ib <= nb; ib++) {
@@ -1229,54 +1242,92 @@ void CheckResidSpec::drawHistos()
12291242 hout->SetMarkerStyle (hin->GetMarkerStyle ());
12301243 };
12311244 int nh = this ->mHManV .size ();
1232- // draws the per-chip dy/dz mean+sigma pages (standard idOffset=0, or IOB idOffset=100000) into pdfName
1245+ // Draw per-chip residual/pull means and sigmas, and their half-barrel and full-layer spreads.
12331246 auto drawChipPages = [&](const std::string& pdfName, int idOffset) {
12341247 for (int il = 1 ; il < 8 ; ++il) {
1235- for (int ib = 0 ; ib < 2 ; ib++) {
1236- cchip.Clear ();
1237- cchip.Divide (1 , 4 );
1238- for (int iyz = 0 ; iyz < 2 ; iyz++) {
1239- for (int iv = 0 ; iv < 2 ; iv++) { // mean or sigma
1240- const float yRange = (iyz == 0 ? params.resMMLrY [il] : params.resMMLrZ [il]) * (idOffset ? params.IOBScaleFactor : 1 .f );
1241- bool drawn = false ;
1242- const int id = idOffset + 15000 + iyz * 10 + (2 * il + ib) * 100 + 1 + iv;
1243- auto [minV, maxV, absMax] = getHMinMax (id, 0.15 , (iv == 0 ? 2 : 8 ) * yRange, 10 );
1244- TH1 * firstAuto = nullptr ;
1245- float maxAuto = 0 .f ;
1246- for (int j = 0 ; j < nh; j++) {
1247- auto hman = this ->mHManV [j].get ();
1248- auto histo = hman->getHisto (id);
1249- if (histo) {
1250- histo->SetMaximum (absMax);
1251- histo->SetMinimum (iv ? 0 : -absMax);
1252- if (il > 3 ) {
1253- histo->SetMarkerSize (0.3 );
1254- histo->SetLineStyle (3 );
1248+ for (int iht = 0 ; iht < 2 ; iht++) { // residual or pull
1249+ for (int ib = 0 ; ib < 3 ; ib++) { // two half-barrels, then the full layer
1250+ if (iht == 1 && ib < 2 ) {
1251+ continue ; // Draw pulls only for the full layer.
1252+ }
1253+ for (int iyz = 0 ; iyz < 2 ; iyz++) {
1254+ cchip.Clear ();
1255+ cchip.Divide (1 , ib == 2 ? 2 : 4 );
1256+ bool havePage = false ;
1257+ for (int iv = 0 ; iv < 2 ; iv++) { // mean or sigma
1258+ const float yRange = (iyz == 0 ? params.resMMLrY [il] : params.resMMLrZ [il]) * (idOffset ? params.IOBScaleFactor : 1 .f );
1259+ const int baseID = idOffset + 15000 + iyz * 10 + 2 * il * 100 + iht * 5 + 1 + iv;
1260+ // Use common spread axes for both half-barrels and their full-layer sum.
1261+ auto [minV, maxV, absMax] = getHMinMax (baseID, 0.15 , (iv == 0 ? 2 : 8 ) * yRange, 10 );
1262+ auto [minV1, maxV1, absMax1] = getHMinMax (baseID + 100 , 0.15 , (iv == 0 ? 2 : 8 ) * yRange, 10 );
1263+ minV = std::min (minV, minV1);
1264+ maxV = std::max (maxV, maxV1);
1265+ absMax = std::max (absMax, absMax1);
1266+ if (iht == 1 ) {
1267+ minV = iv ? 0 .f : -params.maxPull ;
1268+ maxV = absMax = params.maxPull ;
1269+ }
1270+ bool drawn = false ;
1271+ TH1 * firstAuto = nullptr ;
1272+ float maxAuto = 0 .f ;
1273+ for (int j = 0 ; j < nh; j++) {
1274+ auto hman = this ->mHManV [j].get ();
1275+ if (!hman) {
1276+ continue ;
12551277 }
1256- cchip.cd (2 * iv + 1 );
1257- histo->Draw (drawn ? " same" : " " );
1258- if (!drawn) {
1259- gPad ->SetGrid ();
1278+ TH1 * hmeans = nullptr ;
1279+ for (int hb = ib == 2 ? 0 : ib; hb < (ib == 2 ? 2 : ib + 1 ); hb++) {
1280+ const int id = baseID + hb * 100 ;
1281+ auto histo = hman->getHisto (id);
1282+ if (!histo) {
1283+ continue ;
1284+ }
1285+ if (!hmeans) {
1286+ if (ib == 2 ) {
1287+ hmeans = new TH1F (Form (" %s_layer_spread" , histo->GetName ()), Form (" Lr%d %s %s spread" , il - 1 , chipTitles[2 * iyz + iht], iv ? " sigma" : " mean" ), params.nBinsRes , iv == 0 ? minV : std::max (0 .f , minV), maxV);
1288+ hman->addHisto (hmeans, idOffset + 25000 + il * 100 + iyz * 10 + iht * 5 + iv);
1289+ } else {
1290+ hmeans = new TH1F (Form (" %s_spread" , histo->GetName ()), Form (" %s spread;#<Delta>" , histo->GetTitle ()), params.nBinsRes , iv == 0 ? minV : std::max (0 .f , minV), maxV);
1291+ hman->addHisto (hmeans, id + 2 );
1292+ }
1293+ }
1294+ if (iht == 0 ) {
1295+ hmeans->SetXTitle (iv ? " <#sigma>, cm" : " <#Delta>, cm" );
1296+ }
1297+ collectSpread (histo, hmeans);
1298+ if (ib < 2 ) {
1299+ histo->SetMaximum (absMax);
1300+ histo->SetMinimum (iv ? 0 : -absMax);
1301+ if (il > 3 ) {
1302+ histo->SetMarkerSize (0.3 );
1303+ histo->SetLineStyle (3 );
1304+ }
1305+ cchip.cd (2 * iv + 1 );
1306+ histo->Draw (drawn ? " same" : " " );
1307+ gPad ->SetGrid ();
1308+ }
1309+ }
1310+ if (!hmeans) {
1311+ continue ;
12601312 }
1261- auto hmeans = new TH1F (Form (" %s_spread" , histo->GetName ()), Form (" %s spread" , histo->GetTitle ()), params.nBinsRes , iv == 0 ? minV : std::max (0 .f , minV), maxV);
1262- collectSpread (histo, hmeans);
1263- hman->addHisto (hmeans, id + 2 );
1264- cchip.cd (2 * iv + 2 );
1313+ cchip.cd (ib == 2 ? iv + 1 : 2 * iv + 2 );
12651314 if (!drawn) {
12661315 firstAuto = hmeans;
12671316 }
12681317 maxAuto = std::max (maxAuto, (float )hmeans->GetMaximum ());
12691318 hmeans->Draw (drawn ? " same" : " " );
1270- drawn = true ;
1319+ drawn = havePage = true ;
1320+ }
1321+ if (firstAuto) {
1322+ firstAuto->SetMaximum (maxAuto * 1.25 );
1323+ gPad ->SetGrid ();
1324+ gPad ->Modified ();
12711325 }
12721326 }
1273- if (firstAuto) {
1274- firstAuto->SetMaximum (maxAuto * 1.25 );
1275- gPad ->SetGrid ();
1276- gPad ->Modified ();
1327+ if (havePage) {
1328+ cchip.Print (pdfName.c_str ());
12771329 }
12781330 }
1279- cchip.Print (pdfName.c_str ());
12801331 }
12811332 }
12821333 }
@@ -1310,7 +1361,7 @@ void CheckResidSpec::endOfStream(EndOfStreamContext& ec)
13101361 if (mDraw ) {
13111362 drawHistos ();
13121363 }
1313- if (auto nh = mHManV .size (); nh > 0 ) {
1364+ if (auto nh = mHManV .size (); nh > 0 && ! mPostProcOnly ) {
13141365 for (int ihm = 0 ; ihm < nh; ihm++) {
13151366 if (mHManV [ihm]) {
13161367 mHManV [ihm].get ()->write ();
0 commit comments