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

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