/* ======================================================================== *\ ! ! * ! * 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): Thomas Bretz 05/2002 ! Author(s): Harald Kornmayer 1/2001 ! ! Copyright: MAGIC Software Development, 2000-2002 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MCamDisplay // // Camera Display. The Pixels are displayed in // contents/area [somthing/mm^2] // //////////////////////////////////////////////////////////////////////////// #include "MCamDisplay.h" #include #include #include #include #include #include #include #include #include "MH.h" #include "MHexagon.h" #include "MGeomCam.h" #include "MCerPhotPix.h" #include "MCerPhotEvt.h" #include "MPedestalPix.h" #include "MPedestalCam.h" #include "MImgCleanStd.h" #define kItemsLegend 50 // see SetPalette(1,0) ClassImp(MCamDisplay); // ------------------------------------------------------------------------ // // Default Constructor. To be used by the root system ONLY. // MCamDisplay::MCamDisplay() : fGeomCam(NULL), fAutoScale(kTRUE), fW(0), fH(0) { fNumPixels = 0; fRange = 0; fPixels = NULL; fLegend = NULL; fLegText = NULL; fArrowX = NULL; fArrowY = NULL; fLegRadius = NULL; fLegDegree = NULL; } // ------------------------------------------------------------------------ // // Constructor. Makes a clone of MGeomCam. // MCamDisplay::MCamDisplay(MGeomCam *geom) : fGeomCam(NULL), fAutoScale(kTRUE), fW(0), fH(0) { fGeomCam = (MGeomCam*)geom->Clone(); // // create the hexagons of the display // fNumPixels = fGeomCam->GetNumPixels(); fRange = fGeomCam->GetMaxRadius(); // root 3.02 // * base/inc/TObject.h: // register BIT(8) as kNoContextMenu. If an object has this bit set it will // not get an automatic context menu when clicked with the right mouse button. // // Construct all hexagons. Use new-operator with placement // fPixels = new TClonesArray("MHexagon", fNumPixels); for (UInt_t i=0; i ROOT_VERSION(3,01,06) pix.SetBit(/*kNoContextMenu|*/kCannotPick); #endif pix.SetFillColor(16); } // // set up the Legend // const Float_t H = 0.9*fRange; const Float_t h = 2./kItemsLegend; const Float_t w = fRange/sqrt(fNumPixels); fLegend = new TClonesArray("TBox", kItemsLegend); fLegText = new TClonesArray("TText", kItemsLegend); for (Int_t i = 0; i ROOT_VERSION(3,01,06) newbox.SetBit(/*kNoContextMenu|*/kCannotPick); #endif newtxt.SetTextSize(0.025); newtxt.SetTextAlign(12); newtxt.SetX(fRange+1.5*w); newtxt.SetY(H*((i+0.5)*h - 1.)); #if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06) newtxt.SetBit(/*kNoContextMenu|*/kCannotPick); #endif } fArrowX = new TArrow(-fRange*.9, -fRange*.9, -fRange*.6, -fRange*.9, 0.025); fArrowY = new TArrow(-fRange*.9, -fRange*.9, -fRange*.9, -fRange*.6, 0.025); TString text; text += (int)(fRange*.3); text += "mm"; fLegRadius = new TText(-fRange*.85, -fRange*.85, text); text = ""; text += (float)((int)(fRange*.3*fGeomCam->GetConvMm2Deg()*10))/10; text += "\\circ"; text = text.Strip(TString::kLeading); fLegDegree = new TLatex(-fRange*.85, -fRange*.75, text); fLegRadius->SetTextSize(0.04); fLegDegree->SetTextSize(0.04); #if ROOT_VERSION_CODE < ROOT_VERSION(3,01,06) SetPalette(1, 0); #else SetPalette(51, 0); #endif } // ------------------------------------------------------------------------ // // Destructor. Deletes TClonesArrays for hexagons and legend elements. // MCamDisplay::~MCamDisplay() { fPixels->Delete(); fLegend->Delete(); fLegText->Delete(); delete fPixels; delete fLegend; delete fLegText; delete fArrowX; delete fArrowY; delete fLegRadius; delete fLegDegree; delete fGeomCam; } inline void MCamDisplay::SetPixColor(const MCerPhotPix &pix, const UInt_t i, Float_t min, Float_t max) { if (i>=fNumPixels) return; // // Fixme: Use absolute value per mm^2. Needs another scaling algorithm. // const Float_t ratio = fGeomCam->GetPixRatio(i); const Float_t pnum = ratio*pix.GetNumPhotons(); (*this)[pix.GetPixId()].SetFillColor(GetColor(pnum, min, max)); } inline void MCamDisplay::SetPixColorPedestal(const MPedestalPix &pix, const UInt_t i, Float_t min, Float_t max) { if (i>=fNumPixels) return; // // Fixme: Use absolute value per mm^2. Needs another scaling algorithm. // const Float_t ratio = fGeomCam->GetPixRatio(i); const Float_t pnum = ratio*pix.GetMean(); (*this)[i].SetFillColor(GetColor(pnum, min, max)); } inline void MCamDisplay::SetPixColorError(const MCerPhotPix &pix, const UInt_t i, Float_t min, Float_t max) { if (i>=fNumPixels) return; // // Fixme: Use absolute value per mm^2. Needs another scaling algorithm. // const Float_t ratio = fGeomCam->GetPixRatio(i); const Float_t pnum = sqrt(ratio)*pix.GetErrorPhot(); (*this)[pix.GetPixId()].SetFillColor(GetColor(pnum, min, max)); } inline void MCamDisplay::SetPixColorRatio(const MCerPhotPix &pix, Float_t min, Float_t max) { // // Fixme: Use absolute value per mm^2. Needs another scaling algorithm. // const Float_t pnum = pix.GetNumPhotons()/pix.GetErrorPhot(); (*this)[pix.GetPixId()].SetFillColor(GetColor(pnum, min, max)); } inline void MCamDisplay::SetPixColorLevel(const MCerPhotPix &pix, Float_t lvl1, Float_t lvl2) { const Int_t maxcolidx = kItemsLegend-1; MHexagon &hex = (*this)[pix.GetPixId()]; const Float_t r = pix.GetNumPhotons()/pix.GetErrorPhot(); if (r>lvl1) hex.SetFillColor(fColors[4*maxcolidx/5]); else if (r>lvl2) hex.SetFillColor(fColors[maxcolidx/2]); else hex.SetFillColor(fColors[maxcolidx/5]); } // ------------------------------------------------------------------------ // // Call this function to draw the camera layout into your canvas. // Setup a drawing canvas. Add this object and all child objects // (hexagons, etc) to the current pad. If no pad exists a new one is // created. // void MCamDisplay::Draw(Option_t *option) { // root 3.02: // gPad->SetFixedAspectRatio() TVirtualPad *pad = gPad ? gPad : MH::MakeDefCanvas("CamDisplay", "Mars Camera Display", 750, 600); pad->SetBorderMode(0); pad->SetFillColor(16); AppendPad(""); } void MCamDisplay::SetRange() { // // Maintain aspect ratio // const float ratio = 1.15; const float w = gPad->GetWw(); const float h = gPad->GetWh()*ratio; gPad->Range(-fRange, -fRange, (2*ratio-1)*fRange, fRange); if (hSetPad((1.-h/w)/2, 0, (h/w+1)/2, 0.9999999); else gPad->SetPad(0, (1.-w/h)/2, 1, (w/h+1)/2); } // ------------------------------------------------------------------------ // // This is called at any time the canvas should get repainted. // Here we maintain an aspect ratio of 1.15. This makes sure, // that the camera image doesn't get distorted by resizing the canvas. // void MCamDisplay::Paint(Option_t *opt) { if (!fPixels) return; // // Maintain aspect ratio // SetRange(); // // Maintain colors // SetPalette(); // // Paint primitives // for (UInt_t i=0; iPaint(); GetText(i)->Paint(); } fArrowX->Paint(">"); fArrowY->Paint(">"); fLegRadius->Paint(); fLegDegree->Paint(); } // ------------------------------------------------------------------------ // // With this function you can change the color palette. For more // information see TStyle::SetPalette. Only palettes with 50 colors // are allowed. // In addition you can use SetPalette(52, 0) to create an inverse // deep blue sea palette // void MCamDisplay::SetPalette(Int_t ncolors, Int_t *colors) { // // If not enough colors are specified skip this. // if (ncolors>1 && ncolors<50) { cout << "MCamDisplay::SetPalette: Only default palettes with 50 colors are allowed... ignored." << endl; return; } // // If ncolors==52 create a reversed deep blue sea palette // if (ncolors==52) { gStyle->SetPalette(51, NULL); Int_t c[50]; for (int i=0; i<50; i++) c[49-i] = gStyle->GetColorPalette(i); gStyle->SetPalette(50, c); } else gStyle->SetPalette(ncolors, colors); // // Change the colors of the pixels // for (unsigned int i=0; iGetColorPalette(idx)); } // // Store the color palette used for a leter reverse lookup // for (int i=0; iGetColorPalette(i); GetBox(i)->SetFillColor(fColors[i]); } } void MCamDisplay::SetPrettyPalette() { SetPalette(1, 0); } void MCamDisplay::SetDeepBlueSeaPalette() { SetPalette(51, 0); } void MCamDisplay::SetInvDeepBlueSeaPalette() { SetPalette(52, 0); } void MCamDisplay::SetPalette() { for (int i=0; iSetFillColor(fColors[i]); } void MCamDisplay::DrawPixelNumbers() { for (int i=0; iSetTextSize(0.3*h.GetD()/fGeomCam->GetMaxRadius()); } } // ------------------------------------------------------------------------ // // Call this function to fill the number of photo electron into the // camera. // void MCamDisplay::FillPhotNum(const MCerPhotEvt &event) { // // Reset pixel colors to default value // Reset(); // // if the autoscale is true, set the values for the range for // each event // Float_t min = 0; Float_t max = 50; if (fAutoScale) { min = event.GetNumPhotonsMin(fGeomCam); max = event.GetNumPhotonsMax(fGeomCam); if (max==min) max = min +1; UpdateLegend(min, max); } // // update the colors in the picture // const Int_t entries = event.GetNumPixels(); for (Int_t i=0; iSetPalette(1,0) // for the display. So we have to convert the value "wert" into // a color index that fits the color palette. // The range of the color palette is defined by the values fMinPhe // and fMaxRange. Between this values we have 50 color index, starting // with 0 up to 49. // Int_t MCamDisplay::GetColor(Float_t val, Float_t min, Float_t max) { // // first treat the over- and under-flows // const Int_t maxcolidx = kItemsLegend-1; if (val >= max) return fColors[maxcolidx]; if (val <= min) return fColors[0]; // // calculate the color index // const Float_t ratio = (val-min) / (max-min); const Int_t colidx = (Int_t)(ratio*maxcolidx + .5); return fColors[colidx]; } // ------------------------------------------------------------------------ // // Change the text on the legend according to the range of the Display // void MCamDisplay::UpdateLegend(Float_t minphe, Float_t maxphe) { for (Int_t i=0; iClassSaved(TCanvas::Class())) fDrawingPad->SavePrimitive(out, opt); out << " " << fDrawingPad->GetName() << "->SetWindowSize("; out << fDrawingPad->GetWw() << "," << fDrawingPad->GetWh() << ");" << endl; */ } // ------------------------------------------------------------------------ // // compute the distance of a point (px,py) to the Camera // this functions needed for graphical primitives, that // means without this function you are not able to interact // with the graphical primitive with the mouse!!! // // All calcutations are running in pixel coordinates // Int_t MCamDisplay::DistancetoPrimitive(Int_t px, Int_t py) { Int_t dist = 999999; for (UInt_t i=0; iDistancetoPrimitive(px, py); if (dDistancetoPrimitive(px, py)>0) continue; sprintf(info, "Pixel Id: %d", i); return info; } return TObject::GetObjectInfo(px, py); }