// @(#)root/tmva $Id$ // Author: Dominik Dannheim, Alexander Voigt /********************************************************************************** * Project: TMVA - a Root-integrated toolkit for multivariate data analysis * * Package: TMVA * * Classes: PDEFoamKernelLinN * * Web : http://tmva.sourceforge.net * * * * Description: * * Implementation of linear neighbors PDEFoam kernel * * * * Authors (alphabetical): * * S. Jadach - Institute of Nuclear Physics, Cracow, Poland * * Tancredi Carli - CERN, Switzerland * * Dominik Dannheim - CERN, Switzerland * * Alexander Voigt - TU Dresden, Germany * * * * Copyright (c) 2008, 2010: * * CERN, Switzerland * * MPI-K Heidelberg, Germany * * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted according to the terms listed in LICENSE * * (http://tmva.sourceforge.net/LICENSE) * **********************************************************************************/ //_____________________________________________________________________ // // PDEFoamKernelLinN // // This PDEFoam kernel estimates a cell value for a given event by // weighting with cell values of the nearest neighbor cells. // _____________________________________________________________________ #ifndef ROOT_TMVA_PDEFoamKernelLinN #include "TMVA/PDEFoamKernelLinN.h" #endif ClassImp(TMVA::PDEFoamKernelLinN) //_____________________________________________________________________ TMVA::PDEFoamKernelLinN::PDEFoamKernelLinN() : PDEFoamKernelBase() { // Default constructor for streamer } //_____________________________________________________________________ TMVA::PDEFoamKernelLinN::PDEFoamKernelLinN(const PDEFoamKernelLinN &other) : PDEFoamKernelBase(other) { // Copy constructor } //_____________________________________________________________________ Float_t TMVA::PDEFoamKernelLinN::Estimate(PDEFoam *foam, std::vector &txvec, ECellValue cv) { // Linear neighbors kernel estimator. It returns the cell value // 'cv', corresponding to the event vector 'txvec' (in foam // coordinates) linear weighted by the cell values of the neighbor // cells. // // Parameters: // // - foam - the pdefoam to search in // // - txvec - event vector in foam coordinates [0,1] // // - cv - cell value to estimate if (foam == NULL) Log() << kFATAL << ": PDEFoam not set!" << Endl; return WeightLinNeighbors(foam, txvec, cv, kTRUE); } //_____________________________________________________________________ Float_t TMVA::PDEFoamKernelLinN::WeightLinNeighbors(PDEFoam *foam, std::vector &txvec, ECellValue cv, Bool_t treatEmptyCells) { // Returns the cell value, corresponding to 'txvec' (foam // coordinates [0,1]), weighted by the neighbor cells via a linear // function. // // Parameters: // - foam - the foam to search in // // - txvec - event vector, transformed into foam coordinates [0,1] // // - cv - cell value to be weighted // // - treatEmptyCells - if this option is set to false (default), // it is not checked, wether the cell value or neighbor cell // values are undefined (using foam->CellValueIsUndefined()). // If this option is set to true, than only non-empty neighbor // cells are taken into account for weighting. If the cell // value of the cell, which contains txvec, is empty, than its // value is estimated by the average value of the non-empty // neighbor cells (using GetAverageNeighborsValue()). Float_t result = 0.; UInt_t norm = 0; const Float_t xoffset = 1.e-6; if (txvec.size() != UInt_t(foam->GetTotDim())) Log() << kFATAL << "Wrong dimension of event variable!" << Endl; // find cell, which contains txvec PDEFoamCell *cell = foam->FindCell(txvec); PDEFoamVect cellSize(foam->GetTotDim()); PDEFoamVect cellPosi(foam->GetTotDim()); cell->GetHcub(cellPosi, cellSize); // calc value of cell, which contains txvec Float_t cellval = 0; if (!(treatEmptyCells && foam->CellValueIsUndefined(cell))) // cell is not empty -> get cell value cellval = foam->GetCellValue(cell, cv); else // cell is empty -> get average value of non-empty neighbor // cells cellval = GetAverageNeighborsValue(foam, txvec, cv); // loop over all dimensions to find neighbor cells for (Int_t dim = 0; dim < foam->GetTotDim(); dim++) { std::vector ntxvec(txvec); Float_t mindist; PDEFoamCell *mindistcell = 0; // cell with minimal distance to txvec // calc minimal distance to neighbor cell mindist = (txvec[dim] - cellPosi[dim]) / cellSize[dim]; if (mindist < 0.5) { // left neighbour ntxvec[dim] = cellPosi[dim] - xoffset; mindistcell = foam->FindCell(ntxvec); // left neighbor cell } else { // right neighbour mindist = 1 - mindist; ntxvec[dim] = cellPosi[dim] + cellSize[dim] + xoffset; mindistcell = foam->FindCell(ntxvec); // right neighbor cell } // get cell value of cell, which contains ntxvec Float_t mindistcellval = foam->GetCellValue(mindistcell, cv); // if treatment of empty neighbor cells is deactivated, do // normal weighting if (!(treatEmptyCells && foam->CellValueIsUndefined(mindistcell))) { result += cellval * (0.5 + mindist); result += mindistcellval * (0.5 - mindist); norm++; } } if (norm == 0) return cellval; // all nearest neighbors were empty else return result / norm; // normalisation } //_____________________________________________________________________ Float_t TMVA::PDEFoamKernelLinN::GetAverageNeighborsValue(PDEFoam *foam, std::vector &txvec, ECellValue cv) { // This function returns the average value 'cv' of only nearest // neighbor cells. It is used in cases when a cell value is // undefined and the cell value shall be estimated by the // (well-defined) cell values of the neighbor cells. // // Parameters: // - foam - the foam to search in // - txvec - event vector, transformed into foam coordinates [0, 1] // - cv - cell value, see definition of ECellValue const Float_t xoffset = 1.e-6; Float_t norm = 0; // normalisation Float_t result = 0; // return value PDEFoamCell *cell = foam->FindCell(txvec); // find cooresponding cell PDEFoamVect cellSize(foam->GetTotDim()); PDEFoamVect cellPosi(foam->GetTotDim()); cell->GetHcub(cellPosi, cellSize); // get cell coordinates // loop over all dimensions and find neighbor cells for (Int_t dim = 0; dim < foam->GetTotDim(); dim++) { std::vector ntxvec(txvec); PDEFoamCell* left_cell = 0; // left cell PDEFoamCell* right_cell = 0; // right cell // get left cell ntxvec[dim] = cellPosi[dim] - xoffset; left_cell = foam->FindCell(ntxvec); if (!foam->CellValueIsUndefined(left_cell)) { // if left cell is not empty, take its value result += foam->GetCellValue(left_cell, cv); norm++; } // get right cell ntxvec[dim] = cellPosi[dim] + cellSize[dim] + xoffset; right_cell = foam->FindCell(ntxvec); if (!foam->CellValueIsUndefined(right_cell)) { // if right cell is not empty, take its value result += foam->GetCellValue(right_cell, cv); norm++; } } if (norm > 0) result /= norm; // calc average target else result = 0; // return null if all neighbors are empty return result; }