source: trunk/MagicSoft/Mars/mmovie/MMovieWrite.cc@ 9492

Last change on this file since 9492 was 9369, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 25.3 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 4/2007 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2007
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MMovieWrite
28//
29// The intention of this class is to encode movies prepard by the
30// MMoviePrepare task.
31//
32// For writing the movies the images are converted to ppm and piped through
33// ppm2y4m to mpeg2enc. The output format is a mpeg2 movie and should
34// be within the specifications of mpeg2 for DVD. Its size is 720x480,
35// which is a good compromise between resolution and file size. The frame
36// rate is fixed to 24fps.
37//
38// By changing the setup you can control the output:
39//
40// NumEvents: To make sure the file size doesn't get too large
41// (300 evts are roughly 80MB with the default seetings) you can set
42// a maximum number of events. If this number of events has been encoded
43// the eventloop is stopped.
44//
45// TargetLength: The length (in seconds) each even will be encoded to.
46// For example with the default Target Length of 5s and the fixed frame
47// rate of 24fps each event will be encoded into 24f/s*5s +1f = 121frames
48// equally distributed between the beginning of the first and the end of
49// the last frame.
50//
51// Threshold: The default threshold is 2. At 2 times median pedestal rms
52// of the pixles with area index 0 (for MAGIC: inner pixels) the color
53// palette will change from yellow to red and isolated pixels between
54// the median rms and 2 times the median of the rms will be removed from
55// the image. To switch off this behaviour you can set a threshold
56// below one.
57//
58// Filename: The output filename of the movie. If it doesn't end with ".mpg"
59// the suffix is added.
60//
61// The interpolation of the frames is done using a TSpline3. If the spline
62// would extrapolate due to the shift by the relative time calibration the
63// contents is set to zero. Unsuitable pixels are interpolated frame by
64// frame using the surrounding suitable pixels.
65//
66// A few words about file size: MPEG is a motion compensation compression,
67// which means that if a region of a past frame is shown again at the same
68// place or somewhere else this region is referenced instead of encoded again.
69// This means that in our case (almost all frames are identical!) the
70// increase of file size is far from linear with the number of encoded events!
71//
72//
73// Input:
74// MGeomCam
75// MRawRunHeader
76// MRawEvtHeader
77// MSignalCam
78// MBadPixelsCam
79// MMovieData
80// [MMcEvt]
81//
82/////////////////////////////////////////////////////////////////////////////
83#include "MMovieWrite.h"
84
85#include <errno.h>
86
87#include <TF1.h>
88#include <TStyle.h>
89#include <TColor.h>
90#include <TCanvas.h>
91#include <TSystem.h>
92#include <TASImage.h>
93#include <TStopwatch.h>
94
95#include "MString.h"
96
97#include "MParList.h"
98#include "MTaskList.h"
99
100#include "MGeomCam.h"
101#include "MGeomPix.h"
102
103#include "MMcEvt.hxx"
104
105#include "MH.h"
106#include "MHCamera.h"
107#include "MMovieData.h"
108#include "MSignalCam.h"
109#include "MRawEvtHeader.h"
110#include "MRawRunHeader.h"
111#include "MBadPixelsCam.h"
112#include "MBadPixelsPix.h"
113#include "MCalibrateData.h"
114
115#include "MLog.h"
116#include "MLogManip.h"
117
118ClassImp(MMovieWrite);
119
120using namespace std;
121
122// --------------------------------------------------------------------------
123//
124// Default constructor.
125//
126MMovieWrite::MMovieWrite(const char *name, const char *title)
127 : fPipe(0), fTargetLength(5), fThreshold(2), fNumEvents(25000), fFilename("movie.mpg")
128{
129 fName = name ? name : "MMovieWrite";
130 fTitle = title ? title : "Task to encode a movie";
131}
132
133// --------------------------------------------------------------------------
134//
135// Close pipe if still open
136//
137MMovieWrite::~MMovieWrite()
138{
139 if (fPipe)
140 gSystem->ClosePipe(fPipe);
141}
142
143// --------------------------------------------------------------------------
144//
145// Check the pipe for errors. In case of error print an error message.
146// return kFALSE in case of error, kTRUE in case of success.
147//
148Bool_t MMovieWrite::CheckPipe()
149{
150 if (!ferror(fPipe))
151 return kTRUE;
152
153 *fLog << err << "Error in pipe: " << strerror(errno) << endl;
154 return kFALSE;
155}
156
157// --------------------------------------------------------------------------
158//
159// Open pipe for encoding the movie
160//
161Bool_t MMovieWrite::OpenPipe()
162{
163 // name = "ppmtoy4m -B -S 420mpeg2 -v 0 | yuvplay";
164 // name = Form("ppmtoy4m -B -S 420jpeg -v 0 -F %d:%d | yuv2lav -v 0 -o output%03d.avi", TMath::Nint() TMath::Nint(fTargetLength*1000))
165 // name = "ppmtoy4m -B -F 3:1 -S 420jpeg -v 0 | yuv2lav -v 0 -o output.avi";
166
167 TString name;
168 name = "ppmtoy4m -B -F 24:1 -S 420jpeg -v 0 | ";
169 name += "mpeg2enc -v 0 -F 2 -I 0 -M 2 -o ";
170 name += fFilename;
171 if (!fFilename.EndsWith(".mpg"))
172 name += ".mpg";
173
174 const Int_t n = TMath::Nint(fTargetLength*24)+1;
175
176 name += " -f 9 -E 40 -r 0 -K kvcd ";
177 name += MString::Format("-g %d -G %d", n, n);
178
179 // For higher resolution add "--no-constraints"
180
181 fPipe = gSystem->OpenPipe(name, "w");
182 if (!fPipe)
183 {
184 *fLog << err;
185 *fLog << "Pipe: " << name << endl;
186 *fLog << "Couldn't open pipe... aborting." << endl;
187 CheckPipe();
188 return kFALSE;
189 }
190
191 *fLog << inf << "Setup pipe to ppmtoy4m and mpeg2enc to encode " << fFilename << "." << endl;
192
193 return kTRUE;
194
195 // 1: 37M name += "-f 9 -E 40 -H -4 1 -2 1 --dualprime-mpeg2";
196 // 2: 42M name += "-f 9";
197 // 3: 37M name += "-f 9 -E 40 -4 1 -2 1 --dualprime-mpeg2";
198 // 4: 37M name += "-f 9 -E 40 -4 1 -2 1";
199 // 5: 37M name += "-f 9 -E 40 -4 4 -2 4"; // 640x400 3 frames/slice
200 // 6: 11M name += "-f 3 -E 40 -b 750"; // 640x400 3 frames/slice
201
202 // 7: 28M name += "-f 9 -E 40 -G 50"; // 640x400 3 frames/slice
203 // 8: 24M name += "-f 9 -E 40 -G 500"; // 640x400 3 frames/slice
204
205 // 9: 17M name += "-f 9 -E 40 -G 2400"; // 640x400 24 frames/slice
206 // 10: 19M name += "-f 9 -E 40 -G 1120"; // 720x480 3 frames/slice
207 // 20: 33M name += "-f 9 -E 40 -g 28 -G 28"; // 720x480 3 frames/slice
208 // 57M name += "-f 9 -E 40 -g 28 -G 28 -q 4"; // 720x480 3 frames/slice
209
210 // 30M name += "-f 9 -E 40 -g 84 -G 84 -r 0"; // 720x480 3 frames/slice
211 // 31M name += "-f 9 -E 40 -g 56 -G 56 -r 0"; // 720x480 3 frames/slice
212 // 34M name += "-f 9 -E 40 -g 28 -G 28 -r 0"; // 720x480 3 frames/slice
213 // 24: 24M name += "-f 9 -E 40 -g 28 -G 28 -r 0 -K kvcd"; // 720x480 3 frames/slice
214 // 25: 24M name += "-f 9 -E -40 -g 28 -G 28 -r 0 -K kvcd"; // 720x480 3 frames/slice
215 // 26: 26M name += "-f 9 -E 0 -g 28 -G 28 -r 0 -K kvcd"; // 720x480 3 frames/slice
216 // 34M name += "-f 9 -E 40 -g 28 -G 28 -r 2"; // 720x480 3 frames/slice
217 // 33M name += "-f 9 -E 40 -g 28 -G 28 -r 32"; // 720x480 3 frames/slice
218
219 // name += "-f 9 -E 40 -g 121 -G 121 -r 0 -K kvcd"; // 720x480 5s 24 frames/slice
220
221 // 11: 56M name += "-f 9 -E 40 -g 217 -G 217"; // 720x480 24 frames/slice
222 // 18: 59M name += "-f 9 -E 40 -G 250"; // 720x480 24 frames/slice
223 // 62M name += "-f 9 -E 40 -G 184"; // 720x480 24 frames/slice
224
225 // 12: --- name += "-f 9 -E 40 -G 500 -q 31"; // 720x480 3frames/slice
226 // 13: 49M name += "-f 9 -E 40 -G 500 -q 4"; // 720x480 3frames/slice
227 // 14: 21M name += "-f 9 -E 40 -G 500 -q 4 -b 1500"; // 720x480 3frames/slice
228
229 // 15: 57M name += "-f 9 -E 40 -G 500 --no-constraints"; // 1280 864 3frames/slice
230
231 // 16: >80 name += "-f 9 -E 40 -G 217 --no-constraints -b 3000"; // 1280 864 24frames/slice
232 // 17: >50 name += "-f 9 -E 40 -G 682 -b 3000 --no-constraints"; // 1280 864 24frames/slice
233}
234
235// --------------------------------------------------------------------------
236//
237// Search for:
238// - MGeomCam
239// - MRawRunHeader
240// - MRawEvtHeader
241// - MSignalCam
242// - MBadPixelsCam
243// - MMovieData
244//
245// Open a pipe to write the images to. Can be either a player or
246// an encoder.
247//
248Int_t MMovieWrite::PreProcess(MParList *plist)
249{
250 fCam = (MGeomCam*)plist->FindObject("MGeomCam");
251 if (!fCam)
252 {
253 *fLog << err << "MGeomCam not found ... aborting." << endl;
254 return kFALSE;
255 }
256 fRun = (MRawRunHeader*)plist->FindObject("MRawRunHeader");
257 if (!fRun)
258 {
259 *fLog << err << "MRawRunHeader not found ... aborting." << endl;
260 return kFALSE;
261 }
262 fHead = (MRawEvtHeader*)plist->FindObject("MRawEvtHeader");
263 if (!fHead)
264 {
265 *fLog << err << "MRawEvtHeader not found ... aborting." << endl;
266 return kFALSE;
267 }
268 fSig = (MSignalCam*)plist->FindObject("MSignalCam");
269 if (!fSig)
270 {
271 *fLog << err << "MSignalCam not found ... aborting." << endl;
272 return kFALSE;
273 }
274 fBad = (MBadPixelsCam*)plist->FindObject("MBadPixelsCam");
275 if (!fBad)
276 {
277 *fLog << err << "MBadPixelsCam not found ... aborting." << endl;
278 return kFALSE;
279 }
280 fIn = (MMovieData*)plist->FindObject("MMovieData");
281 if (!fIn)
282 {
283 *fLog << err << "MMovieData not found... aborting." << endl;
284 return kFALSE;
285 }
286
287 fMC = (MMcEvt*)plist->FindObject("MMcEvt");
288
289 return OpenPipe();
290}
291
292#ifdef USE_TIMING
293TStopwatch clockT, clock1, clock2, clock3;
294#endif
295
296// --------------------------------------------------------------------------
297//
298// Close pipe if still open
299//
300Int_t MMovieWrite::PostProcess()
301{
302 if (fPipe)
303 {
304 gSystem->ClosePipe(fPipe);
305 fPipe=0;
306 }
307
308#ifdef USE_TIMING
309 *fLog << all << endl;
310 *fLog << "Snap: " << flush;
311 clock1.Print();
312 *fLog << "Writ: " << flush;
313 clock2.Print();
314 *fLog << "Prep: " << flush;
315 clock3.Print();
316 *fLog << "Totl: " << flush;
317 clockT.Print();
318 *fLog << endl;
319#endif
320
321 return kTRUE;
322}
323
324// --------------------------------------------------------------------------
325//
326// Produce a 99 color palette made such, that everything below one
327// pedestal rms is white, everything up to two pedestal rms is yellow
328// and everything above gets colors.
329//
330Int_t MMovieWrite::SetPalette(Double_t rms, const TH1 &h) const
331{
332 const Double_t min = h.GetMinimum();
333 const Double_t max = h.GetMaximum();
334
335 const Double_t f = (fThreshold*rms-min)/(max-min);
336 const Double_t w = 1-f;
337
338 // --- Produce the nice colored palette ---
339
340 // min th*rms max
341 double s[6] = {0.0, f/2, f, f+w/4, f+3*w/5, 1.0 };
342
343 double r[6] = {1.0, 1.0, 1.0, 0.85, 0.1, 0.0 };
344 double g[6] = {1.0, 1.0, 1.0, 0.15, 0.1, 0.0 };
345 double b[6] = {0.9, 0.55, 0.4, 0.15, 0.7, 0.1 };
346
347 TArrayI col(99);
348
349#if ROOT_VERSION_CODE < ROOT_VERSION(5,18,00)
350 const Int_t rc = gStyle->CreateGradientColorTable(6, s, r, g, b, col.GetSize());
351#else
352 const Int_t rc = TColor::CreateGradientColorTable(6, s, r, g, b, col.GetSize());
353#endif
354
355 // --- Overwrite the 'underflow' bin with white ---
356
357 for (int i=0; i<col.GetSize(); i++)
358 col[i] = gStyle->GetColorPalette(i);
359
360 col[0] = TColor::GetColor(0xff, 0xff, 0xff);
361
362 // --- Set Plette ---
363
364 gStyle->SetPalette(col.GetSize(), col.GetArray());
365
366 return rc;
367}
368
369// --------------------------------------------------------------------------
370//
371// The created colors are not overwritten and must be deleted manually
372// because having more than 32768 color in a palette will crash
373// gPad->PaintBox
374//
375void MMovieWrite::DeletePalette(Int_t colidx) const
376{
377 for (int i=0; i<99; i++)
378 {
379 TColor *col = gROOT->GetColor(colidx+i);
380 if (col)
381 delete col;
382 }
383}
384
385/*
386// --------------------------------------------------------------------------
387//
388// Do a snapshot from the pad via TASImage::FromPad and write the
389// image to the pipe.
390// return kFALSE in case of error, kTRUE in case of success.
391//
392Bool_t MMovieWrite::WriteImage(TVirtualPad &pad)
393{
394 clock1.Start(kFALSE);
395 TASImage img;
396 img.FromPad(&pad);
397 clock1.Stop();
398
399 clock2.Start(kFALSE);
400 const Bool_t rc = WriteImage(img);
401 clock2.Stop();
402
403 return rc;
404}
405
406#include <TVirtualPS.h>
407Bool_t MMovieWrite::WriteImage(TVirtualPad &pad)
408{
409 TVirtualPS *psave = gVirtualPS;
410
411 clock1.Start(kFALSE);
412 TImage dump("", 114);
413 dump.SetBit(BIT(11));
414 pad.Paint();
415 TASImage *itmp = (TASImage*)dump.GetStream();
416 clock1.Stop();
417
418 clock2.Start(kFALSE);
419 const Bool_t rc = WriteImage(*itmp);
420 clock2.Stop();
421
422 gVirtualPS = psave;
423
424 return rc;
425}
426*/
427
428// --------------------------------------------------------------------------
429//
430// Update the part of the idst image with the contents of the pad.
431//
432// It is a lot faster not to rerender the parts of the image which don't
433// change anyhow, because rerendering the camera is by far the slowest.
434//
435void MMovieWrite::UpdateImage(TASImage &idst, TVirtualPad &pad)
436{
437 // Get image from pad
438 TASImage isrc;
439 isrc.FromPad(&pad);
440
441 // Get position and width of destination- and source-image
442 const UInt_t wsrc = isrc.GetWidth(); // width of image
443 const UInt_t hsrc = isrc.GetHeight(); // height of image
444
445 const UInt_t usrc = pad.UtoPixel(1)*4; // width of pad (argb)
446 //const UInt_t vsrc = pad.VtoPixel(0); // height of pad
447
448 const UInt_t xsrc = pad.UtoAbsPixel(0); // offset of pad in canvas
449 const UInt_t ysrc = pad.VtoAbsPixel(1); // offset of pad in canvas
450
451 const UInt_t wdst = idst.GetWidth();
452 //const UInt_t hdst = idst.GetHeight();
453
454 // Update destination image with source image
455 const UInt_t size = wsrc*hsrc;
456
457 UInt_t *psrc = isrc.GetArgbArray();
458 UInt_t *pdst = idst.GetArgbArray();
459
460 UInt_t *src = psrc + ysrc*wsrc+xsrc;
461 UInt_t *dst = pdst + ysrc*wdst+xsrc;
462
463 while (src<psrc+size)
464 {
465 memcpy(dst, src, usrc);
466
467 src += wsrc;
468 dst += wdst;
469 }
470}
471
472// --------------------------------------------------------------------------
473//
474// Write the image as ppm (raw/P6) to the pipe.
475// return kFALSE in case of error, kTRUE in case of success.
476//
477Bool_t MMovieWrite::WriteImage(TASImage &img)
478{
479 // Write image header
480 fprintf(fPipe, "P6 %d %d 255\n", img.GetWidth(), img.GetHeight());
481 if (!CheckPipe())
482 return kFALSE;
483
484 // Write image data (remove alpha channel from argb data)
485 UInt_t *argb = img.GetArgbArray();
486 for (UInt_t *ptr=argb; ptr<argb+img.GetWidth()*img.GetHeight(); ptr++)
487 if (fwrite(ptr, 3, 1, fPipe)!=1)
488 break;
489
490 return CheckPipe();
491}
492
493// --------------------------------------------------------------------------
494//
495// Update TASImage with changing parts of the image and write image to pipe.
496// return kFALSE in case of error, kTRUE in case of success.
497//
498Bool_t MMovieWrite::WriteImage(TASImage &img, TVirtualPad &pad)
499{
500#ifdef USE_TIMING
501 clock1.Start(kFALSE);
502 UpdateImage(img, pad);
503 clock1.Stop();
504
505 clock2.Start(kFALSE);
506 const Bool_t rc = WriteImage(img);
507 clock2.Stop();
508
509 return rc;
510#else
511 UpdateImage(img, pad);
512 return WriteImage(img);
513#endif
514}
515
516// --------------------------------------------------------------------------
517//
518// Do a simple interpolation of the surrounding suitable pixels for all
519// unsuitable pixels.
520//
521void MMovieWrite::TreatBadPixels(TH1 &h) const
522{
523 const UShort_t entries = fCam->GetNumPixels();
524
525 //
526 // Loop over all pixels
527 //
528 for (UShort_t i=0; i<entries; i++)
529 {
530 //
531 // Check whether pixel with idx i is blind
532 //
533 if (!(*fBad)[i].IsUnsuitable())
534 continue;
535
536 const MGeom &gpix = (*fCam)[i];
537
538 Int_t num = 0;
539 Double_t sum = 0;
540
541 //
542 // Loop over all its neighbors
543 //
544 Int_t n = gpix.GetNumNeighbors();
545 while (n--)
546 {
547 const UShort_t nidx = gpix.GetNeighbor(n);
548
549 //
550 // Do not use blind neighbors
551 //
552 if ((*fBad)[nidx].IsUnsuitable())
553 continue;
554
555 sum += h.GetBinContent(nidx+1);
556 num++;
557 }
558
559 h.SetBinContent(i+1, sum/num);
560 }
561}
562
563// --------------------------------------------------------------------------
564//
565// Do a simple interpolation of the surrounding suitable pixels for all
566// unsuitable pixels.
567//
568void MMovieWrite::Clean(TH1 &h, Double_t rms) const
569{
570 if (fThreshold<1)
571 return;
572
573 const UShort_t entries = fCam->GetNumPixels();
574
575 //
576 // Loop over all pixels
577 //
578 for (UShort_t i=0; i<entries; i++)
579 {
580 Double_t val = h.GetBinContent(i+1);
581 if (val<rms || val>fThreshold*rms)
582 continue;
583
584 const MGeom &gpix = (*fCam)[i];
585
586 //
587 // Loop over all its neighbors
588 //
589 Int_t n = gpix.GetNumNeighbors();
590 while (n)
591 {
592 const UShort_t nidx = gpix.GetNeighbor(n-1);
593 if (h.GetBinContent(nidx+1)>=rms)
594 break;
595 n--;
596 }
597
598 if (n==0)
599 h.SetBinContent(i+1, 0);
600 }
601}
602
603// --------------------------------------------------------------------------
604//
605Bool_t MMovieWrite::Process(TH1 &h, TVirtualPad &c)
606{
607 // ---------------- Setup ------------------
608
609 const Float_t freq = fRun->GetFreqSampling()/1000.; // [GHz] Sampling frequency
610 const UInt_t slices = fIn->GetNumSlices();
611 const Float_t len = slices/freq; // [ns] length of data stream in data-time
612 //const Float_t len = (slices-2)/freq; // [ns] length of data stream in data-time
613
614 const Double_t rms = fIn->GetMedianPedestalRms();
615 const Double_t max = fIn->GetMax(); // scale the lover limit such
616 const Double_t dif = (max-rms)*99/98; // that everything below rms is
617 const Double_t min = max-dif; // displayed as white
618
619 // If the maximum is equal or less the
620 // pedestal rms something must be wrong
621 if (dif<=0)
622 return kFALSE;
623
624 h.SetMinimum(min);
625 h.SetMaximum(max);
626
627 // -----------------------------------------
628
629 // Produce starting image from canvas
630 TASImage img;
631 img.FromPad(&c);
632
633 // Set new adapted palette for further rendering
634 const Int_t colidx = SetPalette(rms, h);
635
636 // Get the pad containing the camera with the movie
637 TVirtualPad &pad = *c.GetPad(1)->GetPad(1);
638
639 // Calculate number of frames
640 const Int_t numframes = TMath::Nint(fTargetLength*24);
641
642 // Get number of pixels in camera
643 const Int_t npix = fCam->GetNumPixels();
644
645 // Loop over all frames+1 (upper edge)
646 for (Int_t i=0; i<=numframes; i++)
647 {
648 // Calculate corresponding time
649 const Float_t t = len*i/numframes;// + 0.5/freq; // Process from slice beg+0.5 to end-1.5
650
651 // Calculate histogram contents by spline interpolation
652 for (UShort_t p=0; p<npix; p++)
653 {
654 const Double_t y = (*fBad)[p].IsUnsuitable() ? 0 : fIn->CheckedEval(p, t);
655 h.SetBinContent(p+1, y);
656 }
657
658 // Interpolate unsuitable pixels
659 TreatBadPixels(h);
660
661 // Clean single pixels
662 Clean(h, rms);
663
664 // Set new name to be displayed
665 h.SetName(MString::Format("%d: %.2f/%.1fns", i+1, t*freq, t));
666
667 // Update existing image with new data and encode into pipe
668 if (!WriteImage(img, pad))
669 return kFALSE;
670 }
671
672 DeletePalette(colidx);
673
674 cout << setw(3) << GetNumExecutions() << ": " << MString::Format("%6.2f", (float)numframes/(slices-2)) << " f/sl " << slices << " " << numframes+1 << endl;
675
676 return kTRUE;
677}
678
679// --------------------------------------------------------------------------
680//
681Int_t MMovieWrite::Process()
682{
683#ifdef USE_TIMING
684 clockT.Start(kFALSE);
685
686 clock3.Start(kFALSE);
687#endif
688 // ---------------- Prepare display ------------------
689
690 Bool_t batch = gROOT->IsBatch();
691 gROOT->SetBatch();
692
693 TCanvas c;
694 //c.Iconify();
695 c.SetBorderMode(0);
696 c.SetFrameBorderMode(0);
697 c.SetFillColor(kWhite);
698 //c.SetCanvasSize(640, 400);
699 c.SetCanvasSize(720, 480);
700 //c.SetCanvasSize(960, 640);
701 //c.SetCanvasSize(1024, 688);
702 //c.SetCanvasSize(1152, 768);
703 //c.SetCanvasSize(1280, 864);
704
705 MH::SetPalette("pretty");
706
707 c.cd();
708 TPad p1("Pad2", "", 0.7, 0.66, 0.99, 0.99);
709 p1.SetNumber(2);
710 p1.SetBorderMode(0);
711 p1.SetFrameBorderMode(0);
712 p1.SetFillColor(kWhite);
713 p1.Draw();
714 p1.cd();
715
716 MHCamera hsig(*fCam, "Signal", "Calibrated Signal");
717 hsig.SetYTitle("S [phe]");
718 hsig.SetCamContent(*fSig, 99);
719 hsig.SetMinimum(0);
720 //hsig.SetContour(99);
721 hsig.Draw("nopal");
722
723 c.cd();
724 TPad p2("Pad3", "", 0.7, 0.33, 0.99, 0.65);
725 p2.SetNumber(3);
726 p2.SetBorderMode(0);
727 p2.SetFrameBorderMode(0);
728 p2.SetFillColor(kWhite);
729 p2.Draw();
730 p2.cd();
731
732 MHCamera htime(*fCam, "ArrivalTime", "Calibrated Arrival Time");
733 htime.SetYTitle("T [au]");
734 htime.SetCamContent(*fSig, 8);
735 htime.Draw("nopal");
736
737 c.cd();
738 TPad p3("Pad4", "", 0.7, 0.00, 0.99, 0.32);
739 p3.SetNumber(4);
740 p3.SetBorderMode(0);
741 p3.SetFrameBorderMode(0);
742 p3.SetFillColor(kWhite);
743 p3.Draw();
744 p3.cd();
745/*
746 TH1F htpro("TimeProj", "", slices, 0, len);
747 for (UInt_t i=0; i<htime.GetNumPixels(); i++)
748 if(htime.IsUsed(i))
749 htpro.Fill((htime.GetBinContent(i+1)-first)/freq, hsig.GetBinContent(i+1));
750 htpro.SetMinimum(0);
751 htpro.SetMaximum(100);
752 htpro.SetLineColor(kBlue);
753 htpro.Draw();
754
755 TF1 fgaus("f1", "gaus");
756 const Double_t m = (htpro.GetMaximumBin()-0.5)*len/slices;
757 fgaus.SetParameter(0, htpro.GetMaximum());
758 fgaus.SetParameter(1, m);
759 fgaus.SetParameter(2, 1.0);
760 fgaus.SetParLimits(1, m-3, m+3);
761 fgaus.SetParLimits(2, 0, 3);
762 fgaus.SetLineWidth(1);
763 fgaus.SetLineColor(kMagenta);
764 htpro.Fit(&fgaus, "NI", "", m-3, m+3);
765 fgaus.Draw("same");
766
767 g.SetMarkerStyle(kFullDotMedium);
768 g.Draw("PL");
769 //g.SetMinimum(0);
770 //g.SetMaximum(100);
771 //g.Draw("APL");
772
773 p3.Update();
774 p3.cd(1);
775 gPad->Update();
776 */
777 c.cd();
778 TPad p0("MainPad", "", 0.01, 0.01, 0.69, 0.99);
779 p0.SetNumber(1);
780 p0.SetBorderMode(0);
781 p0.SetFrameBorderMode(0);
782 p0.SetFillColor(kWhite);
783 p0.Draw();
784 p0.cd();
785 /*
786 cout << "Max=" << hsig.GetMaximum() << "/" << fIn->GetMax() << " ";
787 cout << hsig.GetMaximum()/fIn->GetMax() << endl;
788 Float_t rms0 = fPed->GetAveragedRmsPerArea(*fCam, 0, fBad)[0];
789 Float_t rms1 = fPed->GetAveragedRmsPerArea(*fCam, 1, fBad)[0];
790 cout << "RMS="<<rms0<<"/"<<rms1<<endl;
791
792 rms0 = GetMedianPedestalRms();
793
794 cout << "MED=" << rms0 << endl;
795 */
796
797 TString s = MString::Format("%d: Evt #", GetNumExecutions()+1);
798 s += fHead->GetDAQEvtNumber();
799 s += " of ";
800 s += "Run #";
801 s += fRun->GetRunNumber();
802 if (fMC)
803 s = fMC->GetDescription(s);
804
805 MHCamera h(*fCam);
806 h.SetTitle(s);
807 h.SetAllUsed();
808 h.SetYTitle("V [au]");
809 h.SetContour(99);
810
811 h.Draw("nopal");
812
813 // ---------------- Show data ------------------
814 gStyle->SetOptStat(1000000001);
815/*
816 p0.Modified();
817 p1.Modified();
818 p2.Modified();
819
820 p0.GetPad(1)->Modified();
821 p1.GetPad(1)->Modified();
822 p2.GetPad(1)->Modified();
823
824 c.Update();
825 */
826
827 // ---------------- Show data ------------------
828#ifdef USE_TIMING
829 clock3.Stop();
830#endif
831
832 // Switch off automatical adding to directory (SetName would do)
833 const Bool_t add = TH1::AddDirectoryStatus();
834 TH1::AddDirectory(kFALSE);
835
836 const Bool_t rc = Process(h, c);
837
838 // restore previous state
839 TH1::AddDirectory(add);
840
841#ifdef USE_TIMING
842 clockT.Stop();
843#endif
844
845 gROOT->SetBatch(batch);
846
847 if (!rc)
848 return kERROR;
849
850 return fNumEvents<=0 || GetNumExecutions()<fNumEvents;
851}
852
853// --------------------------------------------------------------------------
854//
855// Check for corresponding entries in resource file and setup
856//
857// Example:
858// MMovieWrite.TargetLength: 5 <seconds>
859// MMovieWrite.NumEvents: 500
860// MMovieWrite.Threshold: 2 <rms>
861// MMovieWrite.FileName: movie.mpg
862//
863Int_t MMovieWrite::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
864{
865 Bool_t rc = kFALSE;
866 if (IsEnvDefined(env, prefix, "NumEvents", print))
867 {
868 fNumEvents = GetEnvValue(env, prefix, "NumEvents", (Int_t)fNumEvents);
869 rc = kTRUE;
870 }
871 if (IsEnvDefined(env, prefix, "TargetLength", print))
872 {
873 fTargetLength = GetEnvValue(env, prefix, "TargetLength", fTargetLength);
874 rc = kTRUE;
875 }
876 if (IsEnvDefined(env, prefix, "Threshold", print))
877 {
878 fThreshold = GetEnvValue(env, prefix, "Threshold", fThreshold);
879 rc = kTRUE;
880 }
881 if (IsEnvDefined(env, prefix, "FileName", print))
882 {
883 fFilename = GetEnvValue(env, prefix, "FileName", fFilename);
884 rc = kTRUE;
885 }
886 return rc;
887}
Note: See TracBrowser for help on using the repository browser.