/* ======================================================================== *\ ! ! * ! * 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): Abelardo Moralejo 1/2005 ! ! ! Copyright: MAGIC Software Development, 2000-2003 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////////// // // macro RanForestDISP.C // // Version of Random Forest macro, intended to run on real data without assuming // any particular source position in the camera FOV. So we do not use the DIST // parameter, but rather (one version of) DISP method. We do not use either the // sign of the third longitudinal moment with respect to the center of the camera // (since the source can be somewhere else like in the case of wobble mode). // ////////////////////////////////////////////////////////////////////////////////// #include "MMcEvt.hxx" void RanForestDISP(Int_t minsize=1000) { Int_t mincorepixels = 6; // minimum number of core pixels. // Int_t mincorepixels = 0; TString skipevents; // skipevents = "(MMcEvt.fImpact>15000.)"; // skipevents = "(MNewImagePar.fLeakage1>0.001)"; // skipevents = "(MHillas.fSize>1000)"; // Skip calibration events, leaking events and flash events: skipevents = "(MNewImagePar.fLeakage1>0.1) || ({1.5+log10(MNewImagePar.fConc)*2.33333}-{6.5-log10(MHillas.fSize)}>0.)"; // // Create a empty Parameter List and an empty Task List // The tasklist is identified in the eventloop by its name // MParList plist; MTaskList tlist; plist.AddToList(&tlist); MReadMarsFile read("Events", "/data1/magic/mc_data/root/Period021_0.73_mirror/FixedWindowPeakSearch/WOBBLE_Calib_6slices/tc_3.84_2.56/star_gamma_train_new.root"); Float_t numgammas = read.GetEntries(); read.AddFile("star_train_20050110_CrabNebulaW1.root"); Float_t numhadrons = read.GetEntries() - numgammas; // Fraction of gammas to be used in training: // Float_t gamma_frac = 1.5*(numhadrons / numgammas); Float_t gamma_frac = 1.; // Total hadron number to be processed in training: // If you run RF over different data runs, using always the same # of training gammas, // you should also use always a fixed number of hadrons for training (although the data // runs may be of different duration). Otherwise the meaning of the output hadronness // would be different for the different subsamples, since its absolute values depend on // the statistics of the training sample. The number set here is the number BEFORE the // "a priori cuts" set above through "skipevents". Float_t select_n_hadrons = 37000.; Float_t hadron_frac = select_n_hadrons / numhadrons; read.DisableAutoScheme(); tlist.AddToList(&read); MFParticleId fgamma("MMcEvt", '=', MMcEvt::kGAMMA); tlist.AddToList(&fgamma); MFParticleId fhadrons("MMcEvt", '!', MMcEvt::kGAMMA); tlist.AddToList(&fhadrons); MHMatrix matrixg("MatrixGammas"); // TEST TEST TEST // matrixg.AddColumn("MMcEvt.fImpact"); // matrixg.AddColumn("MMcEvt.fMuonCphFraction"); // matrixg.AddColumn("MNewImagePar.fLeakage1"); // matrixg.AddColumn("floor(0.5+(cos(MMcEvt.fTelescopeTheta)/0.01))"); // matrixg.AddColumn("MMcEvt.fTelescopePhi"); // matrixg.AddColumn("MSigmabar.fSigmabar"); matrixg.AddColumn("MHillas.fSize"); // We do not use DIST, since it depends on knowing the source position on camera. // In wobble mode the position changes with time. Besides, we intend to do a 2-d map // with the DISP method, and so we cannot use DIST in the cuts (since it would amde the // camera center a "provoleged" position). matrixg.AddColumn("(1.-(MHillas.fWidth/MHillas.fLength))*(0.9776+(0.101062*log10(MHillas.fSize)))"); // matrixg.AddColumn("MHillas.fWidth"); // matrixg.AddColumn("MHillas.fLength"); // Scaling from real data? // matrixg.AddColumn("MHillas.fWidth/(-8.37847+(9.58826*log10(MHillas.fSize)))"); // matrixg.AddColumn("MHillas.fLength/(-40.1409+(29.3044*log10(MHillas.fSize)))"); // Scaling from MC: matrixg.AddColumn("(MHillas.fWidth*3.37e-3)/(-0.028235+(0.03231*log10(MHillas.fSize)))"); matrixg.AddColumn("(MHillas.fLength*3.37e-3)/(-0.13527+(0.09876*log10(MHillas.fSize)))"); matrixg.AddColumn("MNewImagePar.fConc"); // TEST TEST TEST TEST // matrixg.AddColumn("MConcentration.Conc7"); // matrixg.AddColumn("MNewImagePar.fConc1"); // matrixg.AddColumn("MNewImagePar.fAsym"); // matrixg.AddColumn("MHillasExt.fM3Trans"); // matrixg.AddColumn("abs(MHillasSrc.fHeadTail)"); // We cannot use the 3rd moment with a sign referred to the nominal source position, if we // assume we do not know it a priori. We cannot use either the sign as referred to the // reconstructed source position through the DISP method, since that method uses precisely // fM3Long to solve the "head-tail" asimetry and hence all showers would be "gamma-like" from // that point of view. We add however the 3rd moment with no sign to the separation parameters. matrixg.AddColumn("abs(MHillasExt.fM3Long)"); // matrixg.AddColumn("MHillasSrc.fAlpha"); TString dummy("(MHillas.fSize<"); dummy += minsize; // AM TEST dummy += ") || (MNewImagePar.fNumCorePixels<"; dummy += mincorepixels; // AM, useful FOR High Energy only: // dummy += ") || (MImagePar.fNumSatPixelsLG>0"; dummy += ")"; MContinue SizeCut(dummy); tlist.AddToList(&SizeCut); if (skipevents != "") { MContinue SCut(skipevents); tlist.AddToList(&SCut); } plist.AddToList(&matrixg); MHMatrix matrixh("MatrixHadrons"); matrixh.AddColumns(matrixg.GetColumns()); plist.AddToList(&matrixh); MFEventSelector reduce_training_hadrons; reduce_training_hadrons.SetSelectionRatio(hadron_frac); MFilterList hadfilter; hadfilter.AddToList(&reduce_training_hadrons); hadfilter.AddToList(&fhadrons); tlist.AddToList(&hadfilter); MFillH fillmath("MatrixHadrons"); fillmath.SetFilter(&hadfilter); tlist.AddToList(&fillmath); MContinue skiphad(&fhadrons); tlist.AddToList(&skiphad); MFEventSelector reduce_training_gammas; reduce_training_gammas.SetSelectionRatio(gamma_frac); tlist.AddToList(&reduce_training_gammas); MFillH fillmatg("MatrixGammas"); fillmatg.SetFilter(&reduce_training_gammas); tlist.AddToList(&fillmatg); // // Create and setup the eventloop // MEvtLoop evtloop; evtloop.SetParList(&plist); MProgressBar *bar = new MProgressBar; evtloop.SetProgressBar(bar); // // Execute your analysis // if (!evtloop.Eventloop()) return; tlist.PrintStatistics(); // --------------------------------------------------------------- // --------------------------------------------------------------- // second event loop: the trees of the random forest are grown, // the event loop is now actually a tree loop (loop of training // process) // --------------------------------------------------------------- // --------------------------------------------------------------- MTaskList tlist2; plist.Replace(&tlist2); // // matrixh.ShuffleRows(9999); // matrixg.ShuffleRows(1111); // MRanForestGrow rfgrow2; rfgrow2.SetNumTrees(100); rfgrow2.SetNumTry(3); rfgrow2.SetNdSize(10); MWriteRootFile rfwrite2("RF.root"); rfwrite2.AddContainer("MRanTree","Tree"); //save all trees MFillH fillh2("MHRanForestGini"); tlist2.AddToList(&rfgrow2); tlist2.AddToList(&rfwrite2); tlist2.AddToList(&fillh2); // gRandom is accessed from MRanForest (-> bootstrap aggregating) // and MRanTree (-> random split selection) and should be initialized // here if you want to set a certain random number generator if(gRandom) delete gRandom; // gRandom = new TRandom3(0); // Takes seed from the computer clock gRandom = new TRandom3(); // Uses always same seed // // Execute tree growing (now the eventloop is actually a treeloop) // evtloop.SetProgressBar(bar); if (!evtloop.Eventloop()) return; tlist2.PrintStatistics(); plist.FindObject("MHRanForestGini")->DrawClone(); // --------------------------------------------------------------- // --------------------------------------------------------------- // third event loop: the control sample (star2.root) is processed // through the previously grown random forest, // // the histograms MHHadronness (quality of g/h-separation) and // MHRanForest are created and displayed. // MHRanForest shows the convergence of the classification error // as function of the number of grown (and combined) trees // and tells the user how many trees are actually needed in later // classification tasks. // --------------------------------------------------------------- // --------------------------------------------------------------- MTaskList tlist3; plist.Replace(&tlist3); MReadMarsFile read3("Events", "star_20050110_CrabNebulaW1.root"); // MReadMarsFile read3("Events", "/data1/magic/mc_data/root/Period021_0.73_mirror/FixedWindowPeakSearch/WOBBLE_Calib_6slices/tc_3.84_2.56/star_gamma_test.root"); read3.DisableAutoScheme(); tlist3.AddToList(&read3); tlist3.AddToList(&SizeCut); if (skipevents != "") tlist3.AddToList(&SCut); MRanForestCalc calc; tlist3.AddToList(&calc); TString outfname = "star_S"; outfname += minsize; outfname += "_20050110_CrabNebulaW1.root"; // outfname += "_mcgammas.root"; // parameter containers you want to save // MWriteRootFile write(outfname, "recreate"); // write.AddContainer("MSigmabar", "Events"); write.AddContainer("MRawEvtHeader", "Events"); write.AddContainer("MMcEvt", "Events", kFALSE); write.AddContainer("MHillas", "Events"); write.AddContainer("MHillasExt", "Events"); write.AddContainer("MImagePar", "Events"); write.AddContainer("MNewImagePar", "Events"); write.AddContainer("MHillasSrc", "Events"); write.AddContainer("MHadronness", "Events"); write.AddContainer("MPointingPos", "Events"); write.AddContainer("MTime", "Events", kFALSE); write.AddContainer("MConcentration", "Events", kFALSE); tlist3.AddToList(&write); evtloop.SetProgressBar(bar); // // Execute your analysis // if (!evtloop.Eventloop()) return; tlist3.PrintStatistics(); // bar->DestroyWindow(); return; }