source: trunk/MagicSoft/Mars/mjtrain/MJTrainDisp.cc@ 8708

Last change on this file since 8708 was 8704, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 18.6 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz 11/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2005-2007
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MJTrainDisp
28//
29//
30// Example:
31// --------
32//
33// // SequencesOn are used for training, SequencesOff for Testing
34// MDataSet set("mctesttrain.txt");
35// set.SetNumAnalysis(1); // Must have a number
36// MJTrainDisp opt;
37// //opt.SetDebug();
38// opt.AddParameter("MHillas.fLength");
39// opt.AddParameter("MHillas.fWidth");
40// MStatusDisplay *d = new MStatusDisplay;
41// opt.SetDisplay(d);
42// opt.AddPreCut("MHillasSrc.fDCA*MGeomCam.fConvMm2Deg<0.3");
43// opt.Train("rf-disp.root", set, 30000); // Number of train events
44//
45//
46// Random Numbers:
47// ---------------
48// Use:
49// if(gRandom)
50// delete gRandom;
51// gRandom = new TRandom3();
52// in advance to change the random number generator.
53//
54////////////////////////////////////////////////////////////////////////////
55#include "MJTrainDisp.h"
56
57#include <TLine.h>
58#include <TCanvas.h>
59
60#include "MHMatrix.h"
61
62#include "MLog.h"
63#include "MLogManip.h"
64
65// tools
66#include "MDataSet.h"
67#include "MTFillMatrix.h"
68#include "MChisqEval.h"
69#include "MStatusDisplay.h"
70
71// eventloop
72#include "MParList.h"
73#include "MTaskList.h"
74#include "MEvtLoop.h"
75
76// tasks
77#include "MReadMarsFile.h"
78#include "MContinue.h"
79#include "MFillH.h"
80#include "MRanForestCalc.h"
81#include "MParameterCalc.h"
82
83// container
84#include "MParameters.h"
85
86// histograms
87#include "MBinning.h"
88#include "MH3.h"
89#include "MHn.h"
90#include "MHThetaSq.h"
91
92// filter
93#include "MFilterList.h"
94
95ClassImp(MJTrainDisp);
96
97using namespace std;
98
99const TString MJTrainDisp::fgTrainParameter = "MHillasSrc.fDist*MGeomCam.fConvMm2Deg";
100
101// --------------------------------------------------------------------------
102//
103// Display a result histogram either vs. size or energy
104// FIXME: Could be moved into a new histogram class.
105//
106void MJTrainDisp::DisplayHist(TCanvas &c, Int_t i, MH3 &mh3) const
107{
108 MH::SetPalette("pretty");
109
110 TH1 &hist = *(TH1*)mh3.GetHist().Clone();
111 hist.SetBit(TH1::kNoStats);
112 hist.SetDirectory(0);
113
114 TLine line;
115 line.SetLineStyle(kDashed);
116 line.SetLineWidth(1);
117
118 c.cd(i+4);
119 gPad->SetBorderMode(0);
120 gPad->SetFrameBorderMode(0);
121 //gPad->SetFillColor(kWhite);
122 gPad->SetLogx();
123 gPad->SetGridx();
124 gPad->SetGridy();
125 //gPad->SetLeftMargin(0.12);
126 //gPad->SetRightMargin(0.12);
127
128 const Float_t cutval = hist.GetYaxis()->GetBinLowEdge(4);
129
130 TH1D heff;
131 heff.SetName(Form("Eff%s", hist.GetName()));
132 heff.SetTitle(Form("Cut efficiency vs. %s for \\vartheta<%.3f", hist.GetName(), TMath::Sqrt(cutval)));
133 heff.SetDirectory(0);
134 heff.SetXTitle(hist.GetXaxis()->GetTitle());
135 heff.SetYTitle("Efficiency");
136
137 MH::SetBinning(&heff, hist.GetXaxis());
138
139
140 for (int x=0; x<=hist.GetNbinsX()+1; x++)
141 {
142 const Double_t n0 = hist.Integral(x, x, -1, -1);
143 if (n0>0)
144 heff.SetBinContent(x, hist.Integral(x, x, -1, 3)/n0);
145 }
146
147 heff.SetMinimum(0);
148 heff.SetMaximum(1);
149 heff.DrawCopy();
150
151 line.DrawLine(10, 0.5, 31623, 0.5);
152
153 c.cd(i+0);
154 gPad->SetBorderMode(0);
155 gPad->SetFrameBorderMode(0);
156 //gPad->SetFillColor(kWhite);
157 gPad->SetLogx();
158 gPad->SetGridx();
159 gPad->SetGridy();
160 //gPad->SetLeftMargin(0.12);
161 //gPad->SetRightMargin(0.12);
162
163 for (int x=0; x<=hist.GetNbinsX(); x++)
164 {
165 Float_t n = 0;
166 for (int y=1; y<=2; y++)
167 n += hist.GetBinContent(x,y);
168
169 if (n==0)
170 continue;
171
172 for (int y=0; y<=hist.GetNbinsY(); y++)
173 hist.SetBinContent(x, y, 200*hist.GetBinContent(x,y)/n);
174 }
175
176 hist.SetMaximum(100);
177 hist.DrawCopy("colz");
178
179 line.DrawLine(10, 0.04, 31623, 0.04);
180
181 c.cd(i+2);
182 gPad->SetBorderMode(0);
183 gPad->SetFrameBorderMode(0);
184 //gPad->SetFillColor(kWhite);
185 gPad->SetLogx();
186 gPad->SetGridx();
187 gPad->SetGridy();
188 //gPad->SetLeftMargin(0.12);
189 //gPad->SetRightMargin(0.12);
190
191 for (int x=0; x<=hist.GetNbinsX(); x++)
192 {
193 Float_t n = 0;
194 for (int y=0; y<=hist.GetNbinsY(); y++)
195 n += hist.GetBinContent(x,y);
196
197 if (n==0)
198 continue;
199
200 for (int y=0; y<=hist.GetNbinsY(); y++)
201 hist.SetBinContent(x, y, 100*hist.GetBinContent(x,y)/n);
202 }
203
204 hist.SetMaximum(25);
205 hist.DrawCopy("colz");
206
207 line.DrawLine(10, 0.04, 31623, 0.04);
208}
209
210// --------------------------------------------------------------------------
211//
212// Display the result histograms in a new tab.
213//
214void MJTrainDisp::DisplayResult(MH3 &hsize, MH3 &henergy)
215{
216 TCanvas &c = fDisplay->AddTab("Disp");
217 c.Divide(2,3);
218
219 DisplayHist(c, 1, hsize);
220 DisplayHist(c, 2, henergy);
221}
222
223// --------------------------------------------------------------------------
224//
225// Run Disp optimization
226//
227Bool_t MJTrainDisp::Train(const char *out, const MDataSet &set, Int_t num)
228{
229 SetTitle(Form("TrainDisp: %s", out));
230
231 if (fDisplay)
232 fDisplay->SetTitle(fTitle);
233
234 if (!set.IsValid())
235 {
236 *fLog << err << "ERROR - DataSet invalid!" << endl;
237 return kFALSE;
238 }
239
240 if (!HasWritePermission(out))
241 return kFALSE;
242
243 *fLog << inf;
244 fLog->Separator(GetDescriptor());
245
246 // --------------------- Setup files --------------------
247 MReadMarsFile readtrn("Events");
248 MReadMarsFile readtst("Events");
249 readtrn.DisableAutoScheme();
250 readtst.DisableAutoScheme();
251
252 if (!set.AddFilesOn(readtrn))
253 {
254 *fLog << err << "ERROR - Adding SequencesOn." << endl;
255 return kFALSE;
256 }
257 if (!set.AddFilesOff(readtst))
258 {
259 *fLog << err << "ERROR - Adding SequencesOff." << endl;
260 return kFALSE;
261 }
262
263 // ----------------------- Setup Matrix ------------------
264 MHMatrix train("Train");
265 train.AddColumns(fRules);
266 if (fEnableWeights)
267 train.AddColumn("MWeight.fVal");
268 train.AddColumn(fTrainParameter);
269
270 // ----------------------- Fill Matrix RF ----------------------
271 MTFillMatrix fill(fTitle);
272 fill.SetDisplay(fDisplay);
273 fill.SetLogStream(fLog);
274 fill.SetDestMatrix1(&train, num);
275 fill.SetReader(&readtrn);
276 fill.AddPreCuts(fPreCuts);
277 fill.AddPreCuts(fTrainCuts);
278 fill.AddPreTasks(fPreTasks);
279 fill.AddPostTasks(fPostTasks);
280 if (!fill.Process())
281 return kFALSE;
282
283 // ------------------------ Train RF --------------------------
284 MRanForestCalc rf("TrainDisp", fTitle);
285 rf.SetNumTrees(fNumTrees);
286 rf.SetNdSize(fNdSize);
287 rf.SetNumTry(fNumTry);
288 rf.SetNumObsoleteVariables(1);
289 rf.SetLastDataColumnHasWeights(fEnableWeights);
290 rf.SetDisplay(fDisplay);
291 rf.SetLogStream(fLog);
292 rf.SetFileName(out);
293 rf.SetDebug(fDebug>1);
294 rf.SetNameOutput("Disp");
295
296 /*
297 MBinning b(32, 10, 100000, "BinningEnergyEst", "log");
298
299 if (!rf.TrainMultiRF(train, b.GetEdgesD())) // classification with one tree per bin
300 return;
301
302 if (!rf.TrainSingleRF(train, b.GetEdgesD())) // classification into different bins
303 return;
304 */
305 if (!rf.TrainRegression(train)) // regression (best choice)
306 return kFALSE;
307
308 // --------------------- Display result ----------------------
309
310 gLog.Separator("Test");
311
312 MH::SetPalette("pretty");
313
314 MParList plist;
315 MTaskList tlist;
316 plist.AddToList(this);
317 plist.AddToList(&tlist);
318 //plist.AddToList(&b);
319
320 MParameterD par("ThetaSquaredCut");
321 par.SetVal(0.215*0.215);
322 plist.AddToList(&par);
323
324 MAlphaFitter fit;
325 fit.SetPolynomOrder(0);
326 fit.SetSignalFitMax(0.8);
327 fit.EnableBackgroundFit(kFALSE);
328 fit.SetSignalFunction(MAlphaFitter::kThetaSq);
329 fit.SetMinimizationStrategy(MAlphaFitter::kGaussSigma);
330 plist.AddToList(&fit);
331
332 MFilterList list;
333 if (!list.AddToList(fPreCuts))
334 *fLog << err << "ERROR - Calling MFilterList::AddToList for fPreCuts failed!" << endl;
335 if (!list.AddToList(fTestCuts))
336 *fLog << err << "ERROR - Calling MFilterList::AddToList for fTestCuts failed!" << endl;
337
338 MContinue cont(&list);
339 cont.SetInverted();
340
341 const char *rule = "(MHillasSrc.fDist*MGeomCam.fConvMm2Deg)^2 + (Disp.fVal)^2 - (2*MHillasSrc.fDist*MGeomCam.fConvMm2Deg*Disp.fVal*cos(MHillasSrc.fAlpha*kDeg2Rad))";
342
343 MParameterCalc calcthetasq(rule, "MThetaSqCalc");
344 calcthetasq.SetNameParameter("ThetaSquared");
345
346 MChisqEval eval;
347 eval.SetY1("sqrt(ThetaSquared.fVal)");
348
349 // ----------- Setup binnings ----------------
350 MBinning binsS(50, 10, 100000, "BinningSize", "log");
351 MBinning binsE(70, 10, 31623, "BinningEnergy", "log");
352 MBinning binsG(50, -10, 10, "BinningSlope", "lin");
353 MBinning binsX(50, -1, 1, "BinningResidualDist", "lin");
354 MBinning binsL(50, 0, 0.3, "BinningLeakage", "lin");
355 MBinning binsT(51, -0.005, 0.505, "BinningTheta", "asin");
356 MBinning binsC(50, 1e-2, 1, "BinningConc", "log");
357 MBinning binsW(50, 0, 0.5, "BinningLength", "lin");
358 MBinning binsM(50, 0, 0.3, "BinningWidth", "lin");
359 MBinning binsV(75, 0, par.GetVal()*25, "BinningThetaSq", "lin");
360
361 plist.AddToList(&binsG);
362 plist.AddToList(&binsS);
363 plist.AddToList(&binsX);
364 plist.AddToList(&binsE);
365 plist.AddToList(&binsL);
366 plist.AddToList(&binsT);
367 plist.AddToList(&binsC);
368 plist.AddToList(&binsV);
369 plist.AddToList(&binsW);
370 plist.AddToList(&binsM);
371
372 // ----------- Setup some histograms ----------------
373
374 MHThetaSq hist;
375 hist.SkipHistTime();
376 hist.SkipHistTheta();
377 hist.SkipHistEnergy();
378
379 // To speed it up we could precalculate it.
380 const char *res = "Disp.fVal-MHillasSrc.fDist*3.37e-3";
381
382 MHn hres1("Disp1", "Xi Residual (Dist/Disp)");
383 hres1.AddHist("MHillas.fSize", res);
384 hres1.InitName("ResSize;Size;ResidualDist");
385 hres1.InitTitle(";S [phe];Disp-Dist [\\circ];");
386 hres1.SetDrawOption("colz profx");
387 hres1.AddHist("MHillasExt.fSlopeLong*sign(MHillasSrc.fCosDeltaAlpha)/3.37e-3", res);
388 hres1.InitName("ResSlope;Slope;ResidualDist");
389 hres1.InitTitle(";Slope;Disp-Dist [\\circ];");
390 hres1.SetDrawOption("colz profx");
391 hres1.AddHist("MNewImagePar.fLeakage1", res);
392 hres1.InitName("ResLeak;Leakage;ResidualDist");
393 hres1.InitTitle(";Leak;Disp-Dist [\\circ];");
394 hres1.SetDrawOption("colz profx");
395 hres1.AddHist("MPointingPos.fZd", res);
396 hres1.InitName("ResTheta;Theta;ResidualDist");
397 hres1.InitTitle(";Zd [\\circ];Disp-Dist [\\circ];");
398 hres1.SetDrawOption("colz profx");
399
400 MHn hres2("Disp2", "Dist Residual (Disp-Dist)");
401 hres2.AddHist("MHillas.fLength*3.37e-3", res);
402 hres2.InitName("ResLength;Length;ResidualDist");
403 hres2.InitTitle(";L [\\circ];Disp-Dist [\\circ];");
404 hres2.SetDrawOption("colz profx");
405 hres2.AddHist("MNewImagePar.fConc1", res);
406 hres2.InitName("ResConc1;Conc;ResidualDist");
407 hres2.InitTitle(";C;Disp-Dist [\\circ];");
408 hres2.SetDrawOption("colz profx");
409 hres2.AddHist("MHillas.fWidth*3.37e-3", res);
410 hres2.InitName("ResWidth;Width;ResidualDist");
411 hres2.InitTitle(";W [\\circ];Disp-Dist [\\circ];");
412 hres2.SetDrawOption("colz profx");
413 hres2.AddHist("MMcEvt.fEnergy", res);
414 hres2.InitName("ResEmc;Energy;ResidualDist");
415 hres2.InitTitle(";E_{mc} [GeV];Disp-Dist [\\circ];");
416 hres2.SetDrawOption("colz profx");
417
418 MH3 hdisp1("MHillas.fSize", "ThetaSquared.fVal");
419 MH3 hdisp2("MMcEvt.fEnergy", "ThetaSquared.fVal");
420 hdisp1.SetName("Size;Size;ThetaSq");
421 hdisp2.SetName("Energy;Energy;ThetaSq");
422 hdisp1.SetTitle("\\vartheta distribution vs. Size:Size [phe]:\\vartheta^2 [\\circ]");
423 hdisp2.SetTitle("\\vartheta distribution vs. Energy:Energy [GeV]:\\vartheta^2 [\\circ]");
424
425 // -------------- Setup fill tasks ----------------
426
427 MFillH fillh(&hist, "", "FillThetaSq");
428 MFillH fillh2a(&hres1, "", "FillResiduals1");
429 MFillH fillh2b(&hres2, "", "FillResiduals2");
430 MFillH fillh2c(&hdisp1, "", "FillSize");
431 MFillH fillh2d(&hdisp2, "", "FillEnergy");
432 fillh2c.SetBit(MFillH::kDoNotDisplay);
433 fillh2d.SetBit(MFillH::kDoNotDisplay);
434
435 // --------------- Setup weighting -------------------
436
437 if (fEnableWeights)
438 {
439 fillh.SetWeight();
440 fillh2a.SetWeight();
441 fillh2b.SetWeight();
442 fillh2c.SetWeight();
443 fillh2d.SetWeight();
444 eval.SetNameWeight();
445 }
446
447 // --------------- Setup tasklist -------------------
448
449 tlist.AddToList(&readtst);
450 tlist.AddToList(fPreTasks);
451 tlist.AddToList(&cont);
452 tlist.AddToList(&rf);
453 tlist.AddToList(&calcthetasq);
454 tlist.AddToList(fPostTasks);
455 tlist.AddToList(&fillh);
456 tlist.AddToList(&fillh2a);
457 tlist.AddToList(&fillh2b);
458 tlist.AddToList(&fillh2c);
459 tlist.AddToList(&fillh2d);
460 tlist.AddToList(fTestTasks);
461 tlist.AddToList(&eval);
462
463 // ------------- Setup/run eventloop -----------------
464
465 MEvtLoop loop(fTitle);
466 loop.SetLogStream(fLog);
467 loop.SetDisplay(fDisplay);
468 loop.SetParList(&plist);
469 //if (!SetupEnv(loop))
470 // return kFALSE;
471
472 if (!loop.Eventloop())
473 return kFALSE;
474
475 // ---------------- Prepare result -------------------
476
477 // Print the result
478 *fLog << inf;
479 *fLog << "Rule: " << rule << endl;
480 *fLog << "Disp: " << fTrainParameter << endl;
481 hist.GetAlphaFitter().Print("result");
482
483 // The user has closed the display
484 if (!fDisplay)
485 return kTRUE;
486
487 DisplayResult(hdisp1, hdisp2);
488
489 SetPathOut(out);
490 return WriteDisplay(0, "UPDATE");
491}
492
493/*
494#include "MParameterCalc.h"
495#include "MHillasCalc.h"
496#include "../mpointing/MSrcPosRndm.h"
497
498Bool_t MJTrainDisp::TrainGhostbuster(const char *out, const MDataSet &set, Int_t num)
499{
500 SetTitle(Form("TrainGhostbuster: %s", out));
501
502 if (fDisplay)
503 fDisplay->SetTitle(fTitle);
504
505 if (!set.IsValid())
506 {
507 *fLog << err << "ERROR - DataSet invalid!" << endl;
508 return kFALSE;
509 }
510
511 if (!HasWritePermission(out))
512 return kFALSE;
513
514 *fLog << inf;
515 fLog->Separator(GetDescriptor());
516
517 // --------------------- Setup files --------------------
518 MReadMarsFile readtrn("Events");
519 MReadMarsFile readtst("Events");
520 readtrn.DisableAutoScheme();
521 readtst.DisableAutoScheme();
522
523 if (!set.AddFilesOn(readtrn))
524 return kFALSE;
525 if (!set.AddFilesOff(readtst))
526 return kFALSE;
527
528 // ----------------------- Setup Matrix ------------------
529 MHMatrix train("Train");
530 train.AddColumns(fRules);
531 if (fEnableWeights)
532 train.AddColumn("MWeight.fVal");
533 train.AddColumn("sign(MHillasSrc.fCosDeltaAlpha)==sign(SignStore.fVal)");
534
535 MParameterCalc calc("MHillasSrc.fCosDeltaAlpha", "SignStore");
536 calc.SetNameParameter("SignStore");
537
538 MSrcPosRndm rndm;
539 rndm.SetRule(fTrainParameter);
540 //rndm.SetDistOfSource(120*3.37e-3);
541
542 MHillasCalc hcalc;
543 hcalc.SetFlags(MHillasCalc::kCalcHillasSrc);
544
545 // ----------------------- Fill Matrix RF ----------------------
546 MTFillMatrix fill(fTitle);
547 fill.SetDisplay(fDisplay);
548 fill.SetLogStream(fLog);
549 fill.SetDestMatrix1(&train, num);
550 fill.SetReader(&readtrn);
551 fill.AddPreCuts(fPreCuts);
552 fill.AddPreCuts(fTrainCuts);
553 fill.AddPreTasks(fPreTasks);
554 fill.AddPostTasks(fPostTasks);
555 fill.AddPostTask(&calc);
556 fill.AddPostTask(&rndm);
557 fill.AddPostTask(&hcalc);
558 if (!fill.Process())
559 return kFALSE;
560
561 // ------------------------ Train RF --------------------------
562 MRanForestCalc rf("TrainGhostbuster", fTitle);
563 rf.SetNumTrees(fNumTrees);
564 rf.SetNdSize(fNdSize);
565 rf.SetNumTry(fNumTry);
566 rf.SetNumObsoleteVariables(1);
567 rf.SetLastDataColumnHasWeights(fEnableWeights);
568 rf.SetDisplay(fDisplay);
569 rf.SetLogStream(fLog);
570 rf.SetFileName(out);
571 rf.SetDebug(fDebug>1);
572 rf.SetNameOutput("Sign");
573
574 if (!rf.TrainRegression(train)) // regression (best choice)
575 return kFALSE;
576
577 // --------------------- Display result ----------------------
578
579 gLog.Separator("Test");
580
581 MH::SetPalette("pretty");
582
583 MParList plist;
584 MTaskList tlist;
585 plist.AddToList(this);
586 plist.AddToList(&tlist);
587 //plist.AddToList(&b);
588
589 MFilterList list;
590 if (!list.AddToList(fPreCuts))
591 *fLog << err << "ERROR - Calling MFilterList::AddToList for fPreCuts failed!" << endl;
592 if (!list.AddToList(fTestCuts))
593 *fLog << err << "ERROR - Calling MFilterList::AddToList for fTestCuts failed!" << endl;
594
595 MContinue cont(&list);
596 cont.SetInverted();
597
598 const char *rule = "abs(Sign.fVal-(sign(MHillasSrc.fCosDeltaAlpha)==sign(SignStore.fVal)))";
599
600 //MChisqEval eval;
601 //eval.SetY1("sqrt(ThetaSquared.fVal)");
602
603 MH3 hsign1("MHillas.fSize", rule);
604 MH3 hsign2("MMcEvt.fEnergy", rule);
605 hsign1.SetTitle("Was ist das? vs. Size:Size [phe]:XXX");
606 hsign2.SetTitle("Was ist das? vs. Energy:Enerhy [GeV]:XXXX");
607
608 MBinning binsx( 70, 10, 31623, "BinningMH3X", "log");
609 MBinning binsy( 51, 0, 1, "BinningMH3Y", "lin");
610
611 plist.AddToList(&binsx);
612 plist.AddToList(&binsy);
613
614 MFillH fillh2a(&hsign1, "", "FillSize");
615 MFillH fillh2b(&hsign2, "", "FillEnergy");
616 fillh2a.SetDrawOption("profx colz");
617 fillh2b.SetDrawOption("profx colz");
618 fillh2a.SetNameTab("Size");
619 fillh2b.SetNameTab("Energy");
620
621 tlist.AddToList(&readtst);
622 tlist.AddToList(&cont);
623 tlist.AddToList(&calc);
624 tlist.AddToList(&rndm);
625 tlist.AddToList(&hcalc);
626 tlist.AddToList(&rf);
627 tlist.AddToList(&fillh2a);
628 tlist.AddToList(&fillh2b);
629 //tlist.AddToList(&eval);
630
631 MEvtLoop loop(fTitle);
632 loop.SetLogStream(fLog);
633 loop.SetDisplay(fDisplay);
634 loop.SetParList(&plist);
635 //if (!SetupEnv(loop))
636 // return kFALSE;
637
638 if (!loop.Eventloop())
639 return kFALSE;
640
641 // Print the result
642 *fLog << inf << "Rule: " << rule << endl;
643
644 //DisplayResult(hdisp1, hdisp2);
645
646 SetPathOut(out);
647 if (!WriteDisplay(0, "UPDATE"))
648 return kFALSE;
649
650 return kTRUE;
651}
652*/
Note: See TracBrowser for help on using the repository browser.