source: branches/Mars_McMismatchStudy/fact/analysis/mc/callisto.C@ 19921

Last change on this file since 19921 was 17964, checked in by dneise, 10 years ago
debugged a crazy #include
File size: 18.8 KB
Line 
1#include <sstream>
2#include <iostream>
3
4#include "MLog.h"
5#include "MLogManip.h"
6
7#if !defined(__CINT__) || defined(__MAKECINT__)
8
9#include "TH1F.h"
10#include "TFile.h"
11#include "TStyle.h"
12#include "TGraph.h"
13#include "TLine.h"
14
15#include "DrsCalib.h"
16#include "MDrsCalibration.h"
17#include "MExtralgoSpline.h"
18#include "MSequence.h"
19#include "MStatusArray.h"
20#include "MHCamera.h"
21#include "MJob.h"
22#include "MWriteRootFile.h"
23#include "MHCamera.h"
24#include "MBadPixelsCam.h"
25#include "MBadPixelsPix.h"
26#include "MDirIter.h"
27#include "MTaskList.h"
28#include "MFDataPhrase.h"
29#include "MArrayF.h"
30#include "MBadPixelsTreat.h"
31#include "MCalibrateDrsTimes.h"
32#include "MHSectorVsTime.h"
33#include "MHCamEvent.h"
34#include "MExtractFACT.h"
35#include "MFillH.h"
36#include "MDrsCalibApply.h"
37#include "MGeomApply.h"
38#include "MContinue.h"
39#include "MRawFitsRead.h"
40#include "MReadMarsFile.h"
41#include "MEvtLoop.h"
42#include "MParList.h"
43#include "MStatusDisplay.h"
44#include "MDrsCalibrationTime.h"
45#include "MH3.h"
46#include "MGeomCamFACT.h"
47#include "MCalibrateFact.h"
48#include "MParameters.h"
49#include "MWriteAsciiFile.h"
50#include "MFilterData.h"
51#include "MTreatSaturation.h"
52
53#endif
54
55using namespace std;
56
57/* Maybe you wanna use this macro like this:
58 *
59 * 0.) ---- call root ----
60 * root -b
61 *
62 * 1.) ---- compile the stuff ----
63 * .L fact/analysis/callisto_buildable_no_sequence_file.C++
64 * <read a lot of warnings>
65 *
66 * 2.) ---- you can call it then ----
67 * Therefore you need to specify all the paths ... see below.
68 *
69 * When you wanna call the stuff directly from the bash make sure to
70 * escape the bracets and quotes correctly.
71 *
72 * your can do:
73 * root -b -q callisto_buildable_no_sequence_file.C++'("path1","path2",...)'
74 * or:
75 * root -b -q callisto_buildable_no_sequence_file.C++(\"path1\",\"$HOME\",...)
76 * using bash enviroment variables like $HOME is not possible in the upper variant.
77 */
78
79int callisto(const TString drsfile="test300samples2.drs.fits.gz",
80 const TString pedfile="00000001.001_P_MonteCarlo000_Events.fits",
81 const TString datfile="00000003.387_D_MonteCarlo010_Events.fits",
82 TString outpath = "",
83 TString displayfile = "", TString displaytitle = "")
84{
85
86 // ======================================================
87
88 if (displaytitle.IsNull())
89 displaytitle = gSystem->BaseName(datfile);
90
91 FileStat_t fstat;
92 int rc = gSystem->GetPathInfo(outpath, fstat);
93 bool isdir = !rc || R_ISDIR(fstat.fMode);
94
95 TString filename = datfile + "_callisto.root";
96 filename.Replace(0, filename.Last('/')+1, "");
97 const char *buf = gSystem->ConcatFileName(outpath, filename);
98 TString outfile = buf;
99 delete [] buf;
100
101 if (displayfile.IsNull())
102 {
103 displayfile = outfile;
104 displayfile.Insert(displayfile.Last('.'), "-display");
105 }
106 else
107 {
108 if (isdir && gSystem->DirName(displayfile)==TString("."))
109 {
110 buf = gSystem->ConcatFileName(outfile, displayfile);
111 displayfile = buf;
112 delete [] buf;
113 }
114 }
115
116 // ======================================================
117
118 // true: Display correctly mapped pixels in the camera displays
119 // but the value-vs-index plot is in software/spiral indices
120 // false: Display pixels in hardware/linear indices,
121 // but the order is the camera display is distorted
122 bool usemap = true;
123
124 // map file to use (get that from La Palma!)
125 const char *pmap = usemap ? "/home/isdc/toscanos/FACT/Mars_svn/resources/FACTmap111030.txt" : NULL;
126
127 // ------------------------------------------------------
128
129 MStatusDisplay *d = new MStatusDisplay;
130
131 MBadPixelsCam badpixels;
132 badpixels.InitSize(1440);
133 badpixels[ 424].SetUnsuitable(MBadPixelsPix::kUnsuitable);
134 badpixels[ 583].SetUnsuitable(MBadPixelsPix::kUnsuitable);
135 badpixels[ 830].SetUnsuitable(MBadPixelsPix::kUnsuitable);
136 badpixels[ 923].SetUnsuitable(MBadPixelsPix::kUnsuitable);
137 badpixels[1208].SetUnsuitable(MBadPixelsPix::kUnsuitable);
138 badpixels[1399].SetUnsuitable(MBadPixelsPix::kUnsuitable);
139 // Twin pixel
140 // 113
141 // 115
142 // 354
143 // 423
144 // 1195
145 // 1393
146
147 // ------------------------------------------------------
148
149 // Calib: 51 / 90 / 197 (20% TH)
150 // Data: 52 / 64 / 104 (20% TH)
151
152 // Extraction range in slices. It will always(!) contain the full range
153 // of integration
154 const int first_slice = 25; // 10ns
155 const int last_slice = 225; // 125ns
156
157 Long_t max = 0; // All
158 Long_t max3 = max; // Pedestal Rndm
159 Long_t max4 = max; // Pedestal Ext
160
161 // ======================================================
162
163 //double scale = 0.1;
164 double scale = 0.1024;
165
166 // ======================================================
167
168 if (pmap && gSystem->AccessPathName(pmap, kFileExists))
169 {
170 gLog << err << "ERROR - Cannot access mapping file '" << pmap << "'" << endl;
171 return 1;
172 }
173
174 gLog.Separator("Callisto");
175 gLog << all;
176 gLog << "Data File: " << datfile << '\n';
177 gLog << "DRS calib 300: " << drsfile << endl;;
178
179 MDrsCalibration drscalib300;
180 if (!drscalib300.ReadFits(drsfile.Data())) {
181 gLog << err << "ERROR - Cannot access drscallib300 file '" << drsfile << "'" << endl;
182 return 5;
183 }
184 gLog << all;
185 gLog << "Pedestal file: " << pedfile << '\n';
186 gLog << "Output file: " << outfile << '\n';
187 gLog << "Display file: " << displayfile << '\n';
188 gLog << "Display title: " << displaytitle << endl;
189
190 // ------------------------------------------------------
191/*
192 MStatusArray arrt, arrp;
193
194 TFile ft(lp_template);
195 if (arrt.Read()<=0)
196 {
197 gLog << err << "ERROR - Reading LP template from " << lp_template << endl;
198 return 100;
199 }
200
201 MHCamera *lpref = (MHCamera*)arrt.FindObjectInCanvas("ExtCalSig;avg", "MHCamera", "Cam");
202 if (!lpref)
203 {
204 gLog << err << "ERROR - LP Template not found in " << lp_template << endl;
205 return 101;
206 }
207 lpref->SetDirectory(0);
208
209 MHCamera *gain = (MHCamera*)arrt.FindObjectInCanvas("gain", "MHCamera", "Gain");
210 if (!gain)
211 {
212 gLog << err << "ERROR - Gain not found in " << lp_template << endl;
213 return 101;
214 }
215 gain->SetDirectory(0);
216
217 TFile fp(pulse_template);
218 if (arrp.Read()<=0)
219 {
220 gLog << err << "ERROR - Reading Pulse template from " << pulse_template << endl;
221 return 102;
222 }
223
224 TH1F *hpulse = (TH1F*)arrp.FindObjectInCanvas("hPixelEdgeMean0_0", "TH1F", "cgpPixelPulses0");
225 if (!hpulse)
226 {
227 gLog << err << "ERROR - Pulse Template not found in " << pulse_template << endl;
228 return 103;
229 }
230 hpulse->SetDirectory(0);
231 */
232 // ======================================================
233
234 MDrsCalibrationTime timecam;
235
236 // Plot the trigger pattern rates vs. run-number
237 MH3 hrate("MRawRunHeader.GetFileID", "MRawEvtHeader.GetTriggerID&0xff00");
238 hrate.SetWeight("1./TMath::Max(MRawRunHeader.GetRunLength,1)");
239 hrate.SetName("Rate");
240 hrate.SetTitle("Event rate [Hz];File Id;Trigger Type;");
241 hrate.InitLabels(MH3::kLabelsXY);
242 hrate.DefineLabelY( 0, "Data"); // What if TriggerID==0 already???
243 hrate.DefineLabelY(0x100, "Cal");
244 hrate.DefineLabelY(0x400, "Ped");
245 // hrate.DefaultLabelY("ERROR");
246 gStyle->SetOptFit(kTRUE);
247
248
249 // ========================= Result ==================================
250/*
251 //~ Double_t avgS = evt1f.GetHist()->GetMean();
252 //~ Double_t medS = evt1f.GetHist()->GetMedian();
253 //~ Double_t rmsS = evt1f.GetHist()->GetRMS();
254 //~ Double_t maxS = evt1f.GetHist()->GetMaximum();
255
256 MArrayF der1(hpulse->GetNbinsX());
257 MArrayF der2(hpulse->GetNbinsX());
258
259 MExtralgoSpline spline(hpulse->GetArray()+1, hpulse->GetNbinsX(),
260 der1.GetArray(), der2.GetArray());
261 spline.SetRiseFallTime(rise_time_dat, fall_time_dat);
262 spline.SetExtractionType(type);
263 spline.SetHeightTm(heighttm);
264
265 spline.Extract(hpulse->GetMaximumBin()-1);
266
267 // The pulser signal is most probably around 400mV/9.5mV
268 // IntegraFixed 2/48 corresponds to roughly 215mV*50slices
269 Double_t scale = 1./spline.GetSignal();
270
271 MArrayD calib(1440);
272 for (int i=0; i<1440; i++)
273 calib[i] =1.;
274
275 gROOT->SetSelectedPad(0);
276 d->AddTab("PulseTemp");
277 gPad->SetGrid();
278 hpulse->SetNameTitle("Pulse", "Single p.e. pulse template");
279 hpulse->SetDirectory(0);
280 hpulse->SetLineColor(kBlack);
281 hpulse->DrawCopy();
282
283 TAxis *ax = hpulse->GetXaxis();
284
285 Double_t w = hpulse->GetBinWidth(1);
286 Double_t T = w*(spline.GetTime()+0.5) +ax->GetXmin();
287 //~ Double_t H = w*(hpulse->GetMaximumBin()+0.5)+ax->GetXmin();
288
289 TLine line;
290 line.SetLineColor(kRed);
291 line.DrawLine(T-rise_time_dat*w, spline.GetHeight(),
292 T+fall_time_dat*w, spline.GetHeight());
293 line.DrawLine(T, spline.GetHeight()/4, T, 3*spline.GetHeight()/4);
294 line.DrawLine(T-rise_time_dat*w, 0,
295 T-rise_time_dat*w, spline.GetHeight());
296 line.DrawLine(T+fall_time_dat*w, 0,
297 T+fall_time_dat*w, spline.GetHeight());
298
299 TGraph gg;
300 for (int ix=1; ix<=hpulse->GetNbinsX(); ix++)
301 for (int i=0; i<10; i++)
302 {
303 Double_t x = hpulse->GetBinLowEdge(ix)+i*hpulse->GetBinWidth(ix)/10.;
304 gg.SetPoint(gg.GetN(), x+w/2, spline.EvalAt(ix-1+i/10.));
305 }
306
307 gg.SetLineColor(kBlue);
308 gg.SetMarkerColor(kBlue);
309 gg.SetMarkerStyle(kFullDotMedium);
310 gg.DrawClone("L");
311
312 gROOT->SetSelectedPad(0);
313 d->AddTab("CalConst");
314 MGeomCamFACT fact;
315 MHCamera hcalco(fact);
316 hcalco.SetName("CalConst");
317 hcalco.SetTitle(Form("Relative calibration constant [%.0f/pe]", 1./scale));
318 hcalco.SetCamContent(calib);
319 hcalco.SetAllUsed();
320 //hcalco.Scale(scale);
321 hcalco.DrawCopy();
322*/
323 // ======================================================
324
325 gLog << endl;
326 gLog.Separator("Extracting random pedestal");
327
328 MTaskList tlist3;
329
330 MParList plist3;
331 plist3.AddToList(&tlist3);
332 plist3.AddToList(&drscalib300);
333 plist3.AddToList(&badpixels);
334 plist3.AddToList(&timecam);
335
336 MEvtLoop loop3("DetermineRndmPed");
337 loop3.SetDisplay(d);
338 loop3.SetParList(&plist3);
339
340 // ------------------ Setup the tasks ---------------
341
342 MRawFitsRead read3;
343 read3.LoadMap(pmap);
344 read3.AddFile(pedfile);
345
346 MFillH fill3a(&hrate);
347
348 MContinue cont3("(MRawEvtHeader.GetTriggerID&0xff00)!=0x400", "SelectPed");
349
350 MGeomApply apply3;
351
352 MDrsCalibApply drsapply3;
353
354 MFilterData filterdata3;
355
356 //---
357
358 MExtractFACT extractor3;
359 extractor3.SetRange(first_slice, last_slice);
360 extractor3.SetNoiseCalculation(kTRUE);
361
362 MCalibrateFact conv3;
363 conv3.SetScale(scale);
364 //conv3.SetCalibConst(calib);
365
366 MBadPixelsTreat treat3;
367 treat3.SetProcessPedestalRun(kFALSE);
368 treat3.SetProcessPedestalEvt(kFALSE);
369 treat3.SetProcessTimes(kFALSE);
370
371 MHCamEvent evt3b(0, "PedRdm","Interpolated random pedestal;;Signal [~phe]");
372 //evt2b.SetErrorSpread(kFALSE);
373
374 MFillH fill3b(&evt3b, "MSignalCam", "FillPedRdm");
375 fill3b.SetDrawOption("gaus");
376
377 // ------------------ Setup eventloop and run analysis ---------------
378
379 tlist3.AddToList(&read3);
380 tlist3.AddToList(&apply3);
381 tlist3.AddToList(&drsapply3);
382 tlist3.AddToList(&cont3);
383 tlist3.AddToList(&filterdata3);
384 tlist3.AddToList(&extractor3);
385// tlist3.AddToList(&fill3a);
386 tlist3.AddToList(&conv3);
387 tlist3.AddToList(&treat3);
388 tlist3.AddToList(&fill3b);
389
390 if (!loop3.Eventloop(max3))
391 return 14;
392
393 if (!loop3.GetDisplay())
394 return 15;
395
396 // ======================================================
397
398 gLog << endl;
399 gLog.Separator("Extracting pedestal");
400
401 MTaskList tlist4;
402
403 MParList plist4;
404 plist4.AddToList(&tlist4);
405 plist4.AddToList(&drscalib300);
406 plist4.AddToList(&badpixels);
407 plist4.AddToList(&timecam);
408
409 MEvtLoop loop4("DetermineExtractedPed");
410 loop4.SetDisplay(d);
411 loop4.SetParList(&plist4);
412
413 // ------------------ Setup the tasks ---------------
414
415 MRawFitsRead read4;
416 read4.LoadMap(pmap);
417 read4.AddFile(pedfile);
418
419 MContinue cont4("(MRawEvtHeader.GetTriggerID&0xff00)!=0x400", "SelectPed");
420
421 MGeomApply apply4;
422
423 MDrsCalibApply drsapply4;
424
425 MFilterData filterdata4;
426
427 MExtractFACT extractor4;
428 extractor4.SetRange(first_slice, last_slice);
429 extractor4.SetNoiseCalculation(kFALSE);
430
431 MCalibrateFact conv4;
432 conv4.SetScale(scale);
433 //conv4.SetCalibConst(calib);
434
435 MBadPixelsTreat treat4;
436 treat4.SetProcessPedestalRun(kFALSE);
437 treat4.SetProcessPedestalEvt(kFALSE);
438
439 MHCamEvent evt4b(0, "PedExt","Interpolated extracted pedestal;;Signal [~phe]");
440 //evt4b.SetErrorSpread(kFALSE);
441
442 MFillH fill4b(&evt4b, "MSignalCam", "FillPedExt");
443 fill4b.SetDrawOption("gaus");
444
445 // ------------------ Setup eventloop and run analysis ---------------
446
447 tlist4.AddToList(&read4);
448 tlist4.AddToList(&apply4);
449 tlist4.AddToList(&drsapply4);
450 tlist4.AddToList(&cont4);
451 tlist4.AddToList(&filterdata4);
452 tlist4.AddToList(&extractor4);
453 tlist4.AddToList(&conv4);
454 tlist4.AddToList(&treat4);
455 tlist4.AddToList(&fill4b);
456
457 if (!loop4.Eventloop(max4))
458 return 15;
459
460 if (!loop4.GetDisplay())
461 return 16;
462
463 // ===================================================================
464
465 gLog << endl;
466 gLog.Separator("Extracting and calibration data");
467
468 MTaskList tlist5;
469
470 MParList plist5;
471 plist5.AddToList(&tlist5);
472 plist5.AddToList(&drscalib300);
473 plist5.AddToList(&badpixels);
474 plist5.AddToList(&timecam);
475
476 MEvtLoop loop5("CalibratingData");
477 loop5.SetDisplay(d);
478 loop5.SetParList(&plist5);
479
480 // ------------------ Setup the tasks ---------------
481
482 MRawFitsRead read5a;
483 MReadMarsFile read5b("Events");
484 read5a.LoadMap(pmap);
485 read5a.AddFile(datfile);
486 read5b.DisableAutoScheme();
487 read5b.AddFile(datfile);
488
489 MRead &read5 = datfile.EndsWith(".root") ? static_cast<MRead&>(read5b) : static_cast<MRead&>(read5a);
490
491 MFillH fill5a(&hrate);
492
493 MGeomApply apply5;
494
495 MDrsCalibApply drsapply5;
496
497 MTreatSaturation treatsat5;
498
499 MFilterData filterdata5;
500
501 MFDataPhrase filterdat("(MRawEvtHeader.GetTriggerID&0xff00)==0", "SelectDat");
502 MFDataPhrase filtercal("(MRawEvtHeader.GetTriggerID&0xff00)==0x100", "SelectCal");
503 MFDataPhrase filterped("(MRawEvtHeader.GetTriggerID&0xff00)==0x400", "SelectPed");
504 MFDataPhrase filterncl("(MRawEvtHeader.GetTriggerID&0xff00)!=0x100", "SelectNonCal");
505
506 //MContinue cont4("MRawEvtHeader.GetTriggerID!=4", "SelectData");
507
508 // ---
509
510 MExtractFACT extractor5dat;
511 extractor5dat.SetRange(first_slice, last_slice);
512 extractor5dat.SetNoiseCalculation(kFALSE);
513
514 MExtractFACT extractor5cal;
515 extractor5cal.SetRange(first_slice, last_slice);
516 extractor5cal.SetNoiseCalculation(kFALSE);
517
518 MExtractFACT extractor5tm("ExtractTM");
519 extractor5tm.SetRange(last_slice, 294);
520 extractor5tm.SetNoiseCalculation(kFALSE);
521 extractor5tm.SetNameSignalCam("TimeMarkerAmplitude");
522 extractor5tm.SetNameTimeCam("TimeMarkerTime");
523
524 extractor5dat.SetFilter(&filterncl);
525 extractor5cal.SetFilter(&filtercal);
526 //extractor4tm.SetFilter(&filtercal);
527
528 // ---
529 MCalibrateFact conv5;
530 conv5.SetScale(scale);
531 //conv5.SetCalibConst(calib);
532
533 MCalibrateDrsTimes calctm5;
534 calctm5.SetNameUncalibrated("UncalibratedTimes");
535
536 MCalibrateDrsTimes calctm5tm("CalibrateTimeMarker");
537 calctm5tm.SetNameArrivalTime("TimeMarkerTime");
538 calctm5tm.SetNameUncalibrated("UncalTimeMarker");
539 calctm5tm.SetNameCalibrated("TimeMarker");
540 calctm5tm.SetTimeMarker();
541 //calctm4tm.SetFilter(&filtercal);
542
543 MBadPixelsTreat treat5;
544 treat5.SetProcessPedestalRun(kFALSE);
545 treat5.SetProcessPedestalEvt(kFALSE);
546
547 MHCamEvent evt5b(0, "ExtSig", "Extracted signal;;S [mV·sl]");
548 MHCamEvent evt5c(0, "CalSig", "Calibrated and interpolated signal;;S [~phe]");
549 MHCamEvent evt5d(4, "ExtSigTm", "Extracted time;;T [sl]");
550 MHCamEvent evt5e(6, "CalSigTm", "Calibrated and interpolated time;;T [ns]");
551
552 MFillH fill5b(&evt5b, "MExtractedSignalCam", "FillExtSig");
553 MFillH fill5c(&evt5c, "MSignalCam", "FillCalSig");
554 MFillH fill5d(&evt5d, "MArrivalTimeCam", "FillExtTm");
555 MFillH fill5e(&evt5e, "MSignalCam", "FillCalTm");
556
557 fill5c.SetDrawOption("gaus");
558 fill5d.SetDrawOption("gaus");
559 fill5e.SetDrawOption("gaus");
560
561 /*
562 fill4b.SetFilter(&filterdat);
563 fill4c.SetFilter(&filterdat);
564 fill4d.SetFilter(&filterdat);
565 fill4e.SetFilter(&filterdat);
566 */
567
568 //MFSoftwareTrigger swtrig;
569 //MContinue contsw(&swtrig, "FilterSwTrigger", "Software trigger");
570 //contsw.SetInverted();
571
572 // The second rule is for the case reading raw-files!
573
574 MWriteRootFile write5(outfile, "RECREATE", "Calibrated Data", 2);
575 write5.AddContainer("MRawRunHeader", "RunHeaders");
576 write5.AddContainer("MGeomCam", "RunHeaders");
577 write5.AddContainer("MMcCorsikaRunHeader", "RunHeaders", kFALSE);
578 write5.AddContainer("MCorsikaRunHeader", "RunHeaders", kFALSE);
579 write5.AddContainer("MMcRunHeader", "RunHeaders", kFALSE);
580
581 // Common events
582 write5.AddContainer("MCorsikaEvtHeader", "Events", kFALSE);
583 write5.AddContainer("MMcEvt", "Events", kFALSE);
584 write5.AddContainer("IncidentAngle", "Events", kFALSE);
585 write5.AddContainer("MPointingPos", "Events", kFALSE);
586 write5.AddContainer("MSignalCam", "Events");
587 write5.AddContainer("MTime", "Events", kFALSE);
588 write5.AddContainer("MRawEvtHeader", "Events");
589 //write.AddContainer("MTriggerPattern", "Events");
590
591 // ------------------ Setup histograms and fill tasks ----------------
592
593 MContinue test;
594 test.SetFilter(&filterncl);
595
596 MTaskList tlist5tm;
597 tlist5tm.AddToList(&extractor5tm);
598 tlist5tm.AddToList(&calctm5tm);
599 tlist5tm.SetFilter(&filtercal);
600
601 MTaskList tlist5dat;
602 tlist5dat.AddToList(&fill5b);
603 tlist5dat.AddToList(&fill5c);
604 tlist5dat.AddToList(&fill5d);
605 tlist5dat.AddToList(&fill5e);
606 tlist5dat.SetFilter(&filterdat);
607
608 tlist5.AddToList(&read5);
609 tlist5.AddToList(&apply5);
610 tlist5.AddToList(&drsapply5);
611 tlist5.AddToList(&filterncl);
612 //tlist5.AddToList(&test);
613 tlist5.AddToList(&filterdat);
614 tlist5.AddToList(&filtercal);
615 tlist5.AddToList(&filterped);
616 tlist5.AddToList(&fill5a);
617 tlist5.AddToList(&treatsat5);
618 tlist5.AddToList(&filterdata5);
619 tlist5.AddToList(&extractor5dat);
620 tlist5.AddToList(&extractor5cal);
621 tlist5.AddToList(&calctm5);
622 tlist5.AddToList(&tlist5tm);
623 tlist5.AddToList(&conv5);
624 tlist5.AddToList(&treat5);
625 tlist5.AddToList(&tlist5dat);
626 tlist5.AddToList(&write5);
627
628 if (!loop5.Eventloop(max4))
629 return 18;
630
631 if (!loop5.GetDisplay())
632 return 19;
633
634 d->SetTitle(displaytitle, kFALSE);
635 d->SaveAs(displayfile);
636
637 return 0;
638}
Note: See TracBrowser for help on using the repository browser.