/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Thomas Bretz, 5/2002 ! Author(s): Rudy Bock, 5/2002 ! ! Copyright: MAGIC Software Development, 2000-2002 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MMultiDimDistCalc // // Calculated a multidimensional distance. It calculates the distance to // all vectors in a given matrix describing Gammas and another one // describing Hadrons (non gammas). The shortest distances are avaraged. // How many distances are used for avaraging can be specified in the // constructor. // // * If you want to use the nearest neighbor function for calculation use: // MMultiDimDistCalc::SetUseKernelMethod(kFALSE); // * If you want to use the kernel function for calculation use: // MMultiDimDistCalc::SetUseKernelMethod(kTRUE); // * To use only the n next neighbors for your calculation use: // MMultiDimDistCalc::SetUseNumRows(n); // * To use all reference events set the number to 0 // //////////////////////////////////////////////////////////////////////////// #include "MMultiDimDistCalc.h" #include #include "MHMatrix.h" // must be before MLogManip.h #include "MLog.h" #include "MLogManip.h" #include "MParList.h" #include "MDataChain.h" #include "MDataArray.h" #include "MHadronness.h" ClassImp(MMultiDimDistCalc); using namespace std; static const TString gsDefName = "MMultiDimDistCalc"; static const TString gsDefTitle = "Calculate Hadronness with Nearest Neighbor/Kernel Method"; // -------------------------------------------------------------------------- // // Setup histograms and the number of distances which are used for // avaraging in CalcDist // MMultiDimDistCalc::MMultiDimDistCalc(const char *name, const char *title) : fNum(0), fUseKernel(kTRUE), fHadronnessName("MHadronness"), fData(NULL) { // // set the name and title of this object // fName = name ? name : gsDefName.Data(); fTitle = title ? title : gsDefTitle.Data(); /* fData = new TList; fData->SetOwner(); */ } // -------------------------------------------------------------------------- // // Delete the data chains // MMultiDimDistCalc::~MMultiDimDistCalc() { // delete fData; } // -------------------------------------------------------------------------- // // Needs: // - MatrixGammas [MHMatrix] // - MatrixHadrons {MHMatrix] // - MHadroness // - all data containers used to build the matrixes // // The matrix object can be filles using MFillH. And must be of the same // number of columns (with the same meaning). // Int_t MMultiDimDistCalc::PreProcess(MParList *plist) { fMGammas = (MHMatrix*)plist->FindObject("MatrixGammas", "MHMatrix"); if (!fMGammas) { *fLog << err << dbginf << "MatrixGammas [MHMatrix] not found... aborting." << endl; return kFALSE; } fMHadrons = (MHMatrix*)plist->FindObject("MatrixHadrons", "MHMatrix"); if (!fMHadrons) { *fLog << err << dbginf << "MatrixHadrons [MHMatrix] not found... aborting." << endl; return kFALSE; } if (fMGammas->GetM().GetNcols() != fMHadrons->GetM().GetNcols()) { *fLog << err << dbginf << "Error matrices have different numbers of columns... aborting." << endl; return kFALSE; } /* TIter Next(fMGammas->GetRules()); TObject *data=NULL; while ((data=Next())) { MDataChain *chain = new MDataChain(data->GetName()); if (!chain->PreProcess(plist)) { delete chain; return kFALSE; } fData->Add(chain); } */ fData = fMGammas->GetColumns(); if (!fData) { *fLog << err << dbginf << "Error matrix doesn't contain columns... aborting." << endl; return kFALSE; } if (!fData->PreProcess(plist)) { *fLog << err << dbginf << "PreProcessing of the MDataArray failed for the columns failed... aborting." << endl; return kFALSE; } fHadronness = (MHadronness*)plist->FindCreateObj("MHadronness", fHadronnessName); if (!fHadronness) return kFALSE; return kTRUE; } // -------------------------------------------------------------------------- // // Evaluates the avarage over the fNum shortest distances in a // multidimensional space to a matrix (set of vectors) describing // gammas and hadrons. // The hadroness of the event is defines as the avarage distance to the // set of gammas (dg) divided by the avarage distance to the set of // hadrons (dh). Because this value is in teh range [0, inf] it is // transformed into [0,1] by: // H = exp(-dh/dg); // Int_t MMultiDimDistCalc::Process() { // first copy the data from the data array to a vector event TVector event; *fData >> event; Int_t numg = fNum; Int_t numh = fNum; if (fNum==0) { numg = fMGammas->GetM().GetNrows(); numh = fMHadrons->GetM().GetNrows(); } if (fUseKernel) { numg = -numg; numh = -numh; } const Double_t dg = fMGammas->CalcDist(event, numg); const Double_t dh = fMHadrons->CalcDist(event, numh); if (dg<0 || dh<0) { *fLog << err << "MHMatrix::CalcDist failed (dg=" << dg << ", dh=" << dh << ")... aborting" << endl; return kERROR; } fHadronness->SetHadronness(dg==0 ? 0 : exp(-dh/dg)); fHadronness->SetReadyToSave(); return kTRUE; } void MMultiDimDistCalc::StreamPrimitive(ofstream &out) const { out << " MMultiDimDist " << GetUniqueName(); if (fName!=gsDefName || fTitle!=gsDefTitle) { out << "(\"" << fName << "\""; if (fTitle!=gsDefTitle) out << ", \"" << fTitle << "\")"; } out << ";" << endl; if (fHadronnessName!="MHadronness") out << " " << GetUniqueName() << ".SetHadronnessName(\"" << fHadronnessName << "\");" << endl; if (fNum!=0) out << " " << GetUniqueName() << ".SetUseNumRows(" << fNum << ");" << endl; if (fUseKernel) out << " " << GetUniqueName() << ".SetUseKernelMethod();" << endl; }