In the JSON file, users can select options to blind the fits and/or plots along the x-axis SIG window:
"REGIONS": {
"pass": {
"PROCESSES": ["SIGNAME"],
"BINNING": "default"
},
"fail": {
"PROCESSES": ["SIGNAME"],
"BINNING": "default"
}
},
"OPTIONS": {
"blindedPlots": ["pass"],
"blindedFits": ["pass"]
}
2DAlphabet creates channel masks for all regions (e.g. fail_LOW/SIG/HIGH and pass_LOW/SIG/HIGH) and then will set mask_%s_SIG=1' during the fit, where % is filled by whichever region(s) are in the blindedFits list in the JSON.
To blind the plots, 2DAlphabet checks if blindedPlots is nonzero length. If the list is populated, then it will automatically blind the SIG window in data for all regions listed. In the above JSON example for instance, data_obs_pass_SIG would be blinded (those bins in the TH2 would be set to zero).
So blinding the fits works as expected, and blinding the plots technically works - but matplotlib will see those zero bins in data and plot them with Garwood Poisson CI as error bars. This behavior makes it seem like there is data in that region, when really there should be no data points. Below is an example of postfit pass distribution with a SIG window from 3000-3800 GeV that shows data points (zero) instead of empty points:
Expected behavior:

Actual behavior:

Suggested fix:
matplotlib won't plot NaN values. The plotting class has access to the blinding requests and there should be some way of figuring out which bins these correspond to. Then, the plotter just NaNs the blinded values so that the data points are not shown in the plot.
In the JSON file, users can select options to blind the fits and/or plots along the x-axis
SIGwindow:2DAlphabet creates channel masks for all regions (e.g.
fail_LOW/SIG/HIGHandpass_LOW/SIG/HIGH) and then will setmask_%s_SIG=1'during the fit, where%is filled by whichever region(s) are in theblindedFitslist in the JSON.To blind the plots, 2DAlphabet checks if
blindedPlotsis nonzero length. If the list is populated, then it will automatically blind theSIGwindow in data for all regions listed. In the above JSON example for instance,data_obs_pass_SIGwould be blinded (those bins in the TH2 would be set to zero).So blinding the fits works as expected, and blinding the plots technically works - but matplotlib will see those zero bins in data and plot them with Garwood Poisson CI as error bars. This behavior makes it seem like there is data in that region, when really there should be no data points. Below is an example of postfit pass distribution with a
SIGwindow from 3000-3800 GeV that shows data points (zero) instead of empty points:Expected behavior:

Actual behavior:

Suggested fix:
matplotlib won't plot
NaNvalues. The plotting class has access to the blinding requests and there should be some way of figuring out which bins these correspond to. Then, the plotter justNaNs the blinded values so that the data points are not shown in the plot.