void Convolution::Construct(){ if (!fFunction || !fHasAxes) throw LogicError("Convolution::Construct() : Tried to construct convolution without axes or function, or both!!"); if(!fCachedCompatibleBins) CacheCompatibleBins(); size_t nBins = fPdfMapping.GetNBins(); size_t nDims = fPdfMapping.GetAxes().GetNDimensions(); const AxisCollection& axes = fPdfMapping.GetAxes(); std::vector<size_t> relativeIndices = fDataRep.GetRelativeIndices(fPdfDataRep); // Work out the transition probabilitites within this sub set of the bins std::vector<double> binCentres(fSysAxes.GetNDimensions()); std::vector<double> lowEdges(fSysAxes.GetNDimensions()); std::vector<double> highEdges(fSysAxes.GetNDimensions()); PdfMapping subMap; subMap.SetAxes(fSysAxes); for (size_t origBin = 0; origBin < fSysAxes.GetNBins(); origBin++){ // get the centre of the bin. Need to offset by this for a convolution fSysAxes.GetBinCentres(origBin, binCentres); // loop over the bins it can be smeared into for(size_t destBin = 0; destBin < fSysAxes.GetNBins(); destBin++){ fSysAxes.GetBinLowEdges(destBin, lowEdges); fSysAxes.GetBinHighEdges(destBin, highEdges); for(size_t i = 0; i < fSysAxes.GetNDimensions(); i++){ lowEdges[i] -= binCentres.at(i); highEdges[i] -= binCentres.at(i); } subMap.SetComponent(destBin, origBin, fFunction -> Integral(lowEdges, highEdges)); } } // Now expand to the full size matrix. Elements are zero by default // compatible bins are cached, values must match the smaller matrix above size_t destBin = -1; std::vector<unsigned> nonZeroRowIndices; std::vector<unsigned> nonZeroColIndices; std::vector<double> values; nonZeroRowIndices.reserve(fCompatibleBins.at(0).size()); nonZeroColIndices.reserve(fCompatibleBins.at(0).size()); for(size_t origBin = 0; origBin < axes.GetNBins(); origBin++){ for(size_t i = 0; i < fCompatibleBins.at(origBin).size(); i++){ destBin = fCompatibleBins.at(origBin).at(i); nonZeroRowIndices.push_back(origBin); nonZeroColIndices.push_back(destBin); values.push_back( subMap.GetComponent(fSysBins.at(origBin), fSysBins.at(destBin))); } } fPdfMapping.SetComponents(nonZeroRowIndices, nonZeroColIndices, values); }
BinAxis BinnedEDShrinker::ShrinkAxis(const BinAxis& axis_, const unsigned lowerBuff_, const unsigned upperBuff_) const{ // no buffer no problem if (!lowerBuff_ && !upperBuff_) return axis_; if ((lowerBuff_ + upperBuff_) >= axis_.GetNBins()) throw ValueError(Formatter() << "BinnedEDShrinker::Buffersize (" << lowerBuff_ << ", " << upperBuff_ << ")" << " exceeds number of bins (" << axis_.GetNBins() << ")"); const size_t oldBinCount = axis_.GetNBins(); const size_t newBinCount = oldBinCount - upperBuff_ - lowerBuff_; std::vector<double> lowEdges(newBinCount, 0); std::vector<double> highEdges(newBinCount, 0); // fill the vectors of the new edges using a simple offset for(size_t i = 0; i < newBinCount; i++){ size_t equivilentOldBin = lowerBuff_ + i; lowEdges[i] = axis_.GetBinLowEdge(equivilentOldBin); highEdges[i] = axis_.GetBinHighEdge(equivilentOldBin); } return BinAxis(axis_.GetName(), lowEdges, highEdges, axis_.GetLatexName()); }
void Convolution::Construct(){ if (!fPdf || !fHasAxes) throw InitialisationError("Tried to construct convolution without axes and pdf!"); if(!fCachedCompatibleBins) CacheCompatibleBins(); Reset(); size_t nBins = fPdfMapping.GetNBins(); size_t nDims = fPdfMapping.GetAxes().GetNDimensions(); const AxisCollection& axes = fPdfMapping.GetAxes(); std::vector<size_t> relativeIndicies = fDataRep.GetRelativeIndicies(fPdfDataRep); std::vector<double> binCentre(relativeIndicies.size()); std::vector<double> lowEdges(relativeIndicies.size()); std::vector<double> highEdges(relativeIndicies.size()); for(size_t i = 0; i < nBins; i++){ for(size_t k = 0; k < relativeIndicies.size(); k++) binCentre[k] = axes.GetBinCentre(i, relativeIndicies.at(k)); // Loop over compatible bins and integrate over bin j to work out the response from i -> j // others are zero from reset for(size_t j = 0; j < fCompatibleBins.at(i).size(); j++){ size_t mappedBin = fCompatibleBins.at(i).at(j); for(size_t k = 0; k < relativeIndicies.size(); k++){ lowEdges[k] = axes.GetBinLowEdge(mappedBin, relativeIndicies.at(k)); highEdges[k] = axes.GetBinHighEdge(mappedBin, relativeIndicies.at(k)); } // Move the pdf origin to the centre of bin i for(size_t k = 0; k < lowEdges.size(); k++){ lowEdges[k] -= binCentre[k]; highEdges[k] -= binCentre[k]; } double Rij = fPdf -> Integral(lowEdges, highEdges); fPdfMapping.SetComponent(mappedBin, i, Rij); } } }