#include "DDataBinning.h" ClassImp(DDataBinning) DDataBinning::DDataBinning(string locBinningName, const vector& locGridEdges_Primary, const vector& locBinSize_Primary, const vector >& locGridEdges_Secondary, const vector& locBinSize_Secondary) : dBinningName(locBinningName), dGridEdges_Primary(locGridEdges_Primary), dBinSize_Primary(locBinSize_Primary), dGridEdges_Secondary(locGridEdges_Secondary), dBinSize_Secondary(locBinSize_Secondary) { Generate_BinningGrid(); } DDataBinning::DDataBinning(string locBinningName, const vector& locBinEdges_Primary, const vector >& locBinEdges_Secondary) { dBinningName = locBinningName; dBinEdges_Primary = locBinEdges_Primary; dBinEdges_Secondary = locBinEdges_Secondary; } size_t DDataBinning::Get_NumPrimaryBins_InGroup(int locGroup) const { double locRange = dGridEdges_Primary[locGroup + 1] - dGridEdges_Primary[locGroup] + 0.000001; return size_t(locRange/dBinSize_Primary[locGroup]); } size_t DDataBinning::Get_NumSecondaryBins_InGroup(int locGroup) const { double locRange = dGridEdges_Secondary[locGroup].second - dGridEdges_Secondary[locGroup].first + 0.000001; return size_t(locRange/dBinSize_Secondary[locGroup]); } size_t DDataBinning::Get_NumBinsInGroup(int locGroup) const { return Get_NumPrimaryBins_InGroup(locGroup)*Get_NumSecondaryBins_InGroup(locGroup); } size_t DDataBinning::Get_NumBinGroups(void) const { if(dGridEdges_Primary.empty()) return 0; return (dGridEdges_Primary.size() - 1); } size_t DDataBinning::Get_NumPrimaryBins(void) const { if(dBinEdges_Primary.empty()) return 0; return (dBinEdges_Primary.size() - 1); } size_t DDataBinning::Get_NumSecondaryBins_InPrimaryBin(int locPrimaryBin) const { if(dBinEdges_Secondary[locPrimaryBin].empty()) return 0; return (dBinEdges_Secondary[locPrimaryBin].size() - 1); } void DDataBinning::Generate_BinningGrid(void) { for(size_t loc_i = 0; loc_i < dBinSize_Primary.size(); ++loc_i) { //primary bin edges size_t locNumFirstDimBins = Get_NumPrimaryBins_InGroup(loc_i); for(size_t loc_j = 0; loc_j < locNumFirstDimBins; ++loc_j) dBinEdges_Primary.push_back(dGridEdges_Primary[loc_i] + dBinSize_Primary[loc_i]*(double(loc_j))); //secondary bin edges size_t locNumSecondDimBins = Get_NumSecondaryBins_InGroup(loc_i); vector loc2ndDimBinEdges(locNumSecondDimBins + 1, 0.0); for(size_t loc_j = 0; loc_j < locNumSecondDimBins + 1; ++loc_j) loc2ndDimBinEdges[loc_j] = dGridEdges_Secondary[loc_i].first + dBinSize_Secondary[loc_i]*(double(loc_j)); dBinEdges_Secondary.insert(dBinEdges_Secondary.end(), locNumFirstDimBins, loc2ndDimBinEdges); } dBinEdges_Primary.push_back(dGridEdges_Primary.back()); } bool DDataBinning::Get_BinIndices(size_t locOverallBinIndex, int& locPrimaryBinIndex, int& locSecondaryBinIndex) const { locPrimaryBinIndex = -1; locSecondaryBinIndex = -1; if(!dGridEdges_Primary.empty()) return Get_BinIndices_Grid(locOverallBinIndex, locPrimaryBinIndex, locSecondaryBinIndex); else return Get_BinIndices_NonGrid(locOverallBinIndex, locPrimaryBinIndex, locSecondaryBinIndex); } bool DDataBinning::Get_BinIndices_Grid(size_t locOverallBinIndex, int& locPrimaryBinIndex, int& locSecondaryBinIndex) const { //loop over groups size_t locBaseBinIndex = 0; size_t locBaseNumPrimaryBins = 0; for(size_t loc_i = 0; loc_i < Get_NumBinGroups(); ++loc_i) { size_t locNumFirstDimBins = Get_NumPrimaryBins_InGroup(loc_i); size_t locNumBinsInGroup = Get_NumBinsInGroup(loc_i); if((locOverallBinIndex - locBaseBinIndex) >= locNumBinsInGroup) { locBaseNumPrimaryBins += locNumFirstDimBins; locBaseBinIndex += locNumBinsInGroup; continue; } size_t locNumSecondDimBins = Get_NumSecondaryBins_InGroup(loc_i); locPrimaryBinIndex = locBaseNumPrimaryBins + (locOverallBinIndex - locBaseBinIndex) / locNumSecondDimBins; locSecondaryBinIndex = (locOverallBinIndex - locBaseBinIndex) % locNumSecondDimBins; // 0 -> 4 = 0 -> 4 return true; } return false; } bool DDataBinning::Get_BinIndices_NonGrid(size_t locOverallBinIndex, int& locPrimaryBinIndex, int& locSecondaryBinIndex) const { int locTempBinIndex = locOverallBinIndex; for(size_t loc_i = 0; loc_i < dBinEdges_Secondary.size(); ++loc_i) { int locNumSecondaryBins = int(dBinEdges_Secondary[loc_i].size()) - 1; if(locNumSecondaryBins <= 0) continue; if(locTempBinIndex >= locNumSecondaryBins) { locTempBinIndex -= locNumSecondaryBins; continue; } locPrimaryBinIndex = loc_i; locSecondaryBinIndex = locTempBinIndex; return true; } return false; } size_t DDataBinning::Get_TotalNumBins(void) const { size_t locTotalNumBins = 0; if(!dGridEdges_Primary.empty()) { for(size_t loc_i = 0; loc_i < Get_NumBinGroups(); ++loc_i) locTotalNumBins += Get_NumBinsInGroup(loc_i); } else { for(size_t loc_i = 0; loc_i < dBinEdges_Secondary.size(); ++loc_i) locTotalNumBins += (dBinEdges_Secondary[loc_i].size() - 1); } return locTotalNumBins; } int DDataBinning::Get_BinGroupIndex(double locPrimaryValue) const { if(locPrimaryValue < dGridEdges_Primary[0]) return -1; for(size_t loc_i = 0; loc_i < Get_NumBinGroups(); ++loc_i) { if(locPrimaryValue >= dGridEdges_Primary[loc_i + 1]) continue; return loc_i; } return -1; } int DDataBinning::Get_BinGroupIndex(size_t locOverallBinIndex) const { for(size_t loc_i = 0; loc_i < Get_NumBinGroups(); ++loc_i) { if(locOverallBinIndex < Get_NumBinsInGroup(loc_i)) return loc_i; locOverallBinIndex -= Get_NumBinsInGroup(loc_i); } return -1; } bool DDataBinning::Get_BinIndices(double locPrimaryValue, double locSecondaryValue, int& locPrimaryBinIndex, int& locSecondaryBinIndex) const { locSecondaryBinIndex = -1; locPrimaryBinIndex = Get_PrimaryBinIndex(locPrimaryValue); if(locPrimaryBinIndex == -1) return false; //grid if(!dGridEdges_Primary.empty()) { int locBinGroupIndex = Get_BinGroupIndex(locPrimaryValue); if(locBinGroupIndex == -1) return false; double locMinSecondaryValue = dGridEdges_Secondary[locBinGroupIndex].first; if((locSecondaryValue < locMinSecondaryValue) || (locSecondaryValue > dGridEdges_Secondary[locBinGroupIndex].second)) return false; locSecondaryBinIndex = (locSecondaryValue - locMinSecondaryValue)/(dBinSize_Secondary[locBinGroupIndex]); return true; } //non-grid for(size_t loc_i = 0; loc_i < dBinEdges_Secondary[locPrimaryBinIndex].size(); ++loc_i) { if(locSecondaryValue >= dBinEdges_Secondary[locPrimaryBinIndex][loc_i]) continue; locSecondaryBinIndex = int(loc_i) - 1; break; } return (locSecondaryBinIndex != -1); } int DDataBinning::Get_PrimaryBinIndex(double locPrimaryValue) const { //grid if(!dGridEdges_Primary.empty()) { int locBinGroupIndex = Get_BinGroupIndex(locPrimaryValue); if(locBinGroupIndex == -1) return -1; int locPrimaryBinIndex = 0; for(int loc_i = 0; loc_i < locBinGroupIndex; ++loc_i) locPrimaryBinIndex += Get_NumPrimaryBins_InGroup(loc_i); locPrimaryBinIndex += (locPrimaryValue - dGridEdges_Primary[locBinGroupIndex])/(dBinSize_Primary[locBinGroupIndex]); return locPrimaryBinIndex; } //non-grid for(size_t loc_i = 0; loc_i < dBinEdges_Primary.size(); ++loc_i) { if(locPrimaryValue >= dBinEdges_Primary[loc_i]) continue; return (int(loc_i) - 1); } return -1; } double* DDataBinning::Create_PrimaryBinArray(int& locNumBins) const { locNumBins = dBinEdges_Primary.size() - 1; double* locBinArray = new double[dBinEdges_Primary.size()]; for(size_t loc_i = 0; loc_i < dBinEdges_Primary.size(); ++loc_i) locBinArray[loc_i] = dBinEdges_Primary[loc_i]; return locBinArray; }