//------------------------------------------------------------------------------ // gso_Palette class -- // (C) Piero Giubilato 2008-2010, Berkeley Lab -- //------------------------------------------------------------------------------ //______________________________________________________________________________ // {Trace} // [File name] "gso_Map2D.cpp" // [Author] "Piero Giubilato" // [Version] "0.5" // [Modified by] "Piero Giubilato" // [Last revision] "22 Jan 2009" // [Language] "C++" // [Compiler] "Visual C++ 9.x" // [Member of] "Cool SEAL" // [Project] "SEAL" // [Description] "Source for the gso_Map2D class" // [Key documentation] // "Visual C++ Reference Help" // "Root reference guide" // {Trace} //______________________________________________________________________________ // Standard component #include // Application component #include "global.h" #include "gso_Map2D.h" // CINT Preprocessor class import definition ClassImp(gso_Map2D) //______________________________________________________________________________ gso_Map2D::gso_Map2D(const TGWindow* window, const gso_Palette* pal, UInt_t width, UInt_t height) :TGFrame(window, width, height, 0) { // Default constructor. gso_Map2D provides display functionalities for 2D // data array and structures. While less powerful than the TASImage root // class, it offers maximum speed and multithreading capabilities (soon...). // // 'window' is the container window // 'pal' is the gso_Palette object necessary to the map creation // 'width' is the width of the 2D map in pixels // 'height' is the height of the 2D map in pixels // Debug dbg_Print("gso_Map2D::gso_Map2D:(default)", DBG_LVL_ZERO); // Reset data pointer data_US = 0; data_S = 0; data_UI = 0; data_I = 0; data_F = 0; data_D = 0; data_Mode = kdt_Null; // Save the data reference and sets up the frame Init(window, pal, 0, 0, width, height); } /* //______________________________________________________________________________ gso_Map2D::gso_Map2D(const TGWindow* window, const gso_Palette* pal, const UShort_t* data, UInt_t data_Width, UInt_t data_Height, UInt_t width, UInt_t height) :TGFrame(window, width, height, 0) { // UShort_t constructor. gso_Map2D provides display functionalities for 2D // data array and structures. While less powerful than the TASImage root // class, it offers maximum speed and multithreading capabilities (soon...). // // 'window' is the container window // 'pal' is the gso_Palette object necessary to the map creation // 'data' is the address of the 2D data matrix // 'data_Width' is the width of the data matrix // 'sata_Height' is the height of the data matrix // 'width' is the width of the 2D map in pixels // 'height' is the height of the 2D map in pixels // Debug dbg_Print("gso_Map2D::gso_Map2D:(UShort)", DBG_LVL_ZERO); // Save the data reference and sets up the frame data_US = data; data_Mode = kdt_UShort; Init(window, pal, data_Width, data_Height, width, height); } //______________________________________________________________________________ gso_Map2D::gso_Map2D(const TGWindow* window, const gso_Palette* pal, const Short_t* data, UInt_t data_Width, UInt_t data_Height, UInt_t width, UInt_t height) :TGFrame(window, width, height, 0) { // Short_t constructor dbg_Print("gso_Map2D::gso_Map2D:(Short)", DBG_LVL_ZERO); // Save the data reference and set up the frame data_S = data; data_Mode = kdt_Short; Init(window, pal, data_Width, data_Height, width, height); } //______________________________________________________________________________ gso_Map2D::gso_Map2D(const TGWindow* window, const gso_Palette* pal, const UInt_t* data, UInt_t data_Width, UInt_t data_Height, UInt_t width, UInt_t height) :TGFrame(window, width, height, 0) { // UInt_t constructor dbg_Print("gso_Map2D::gso_Map2D:(UInt)", DBG_LVL_ZERO); // Save the data reference and set up the frame data_UI = data; data_Mode = kdt_UInt;; Init(window, pal, data_Width, data_Height, width, height); } //______________________________________________________________________________ gso_Map2D::gso_Map2D(const TGWindow* window, const gso_Palette* pal, const Int_t* data, UInt_t data_Width, UInt_t data_Height, UInt_t width, UInt_t height) :TGFrame(window, width, height, 0) { // UInt_t constructor dbg_Print("gso_Map2D::gso_Map2D:(Int)", DBG_LVL_ZERO); // Save the data reference and set up the frame data_I = data; data_Mode = kdt_Int;; Init(window, pal, data_Width, data_Height, width, height); } //______________________________________________________________________________ gso_Map2D::gso_Map2D(const TGWindow* window, const gso_Palette* pal, const Float_t* data, UInt_t data_Width, UInt_t data_Height, UInt_t width, UInt_t height) :TGFrame(window, width, height, 0) { // UInt_t constructor dbg_Print("gso_Map2D::gso_Map2D:(Float)", DBG_LVL_ZERO); // Save the data reference and set up the frame data_F = data; data_Mode = kdt_Float;; Init(window, pal, data_Width, data_Height, width, height); } //______________________________________________________________________________ gso_Map2D::gso_Map2D(const TGWindow* window, const gso_Palette* pal, const Double_t* data, UInt_t data_Width, UInt_t data_Height, UInt_t width, UInt_t height) :TGFrame(window, width, height, 0) { // UInt_t constructor dbg_Print("gso_Map2D::gso_Map2D:(Double)", DBG_LVL_ZERO); // Save the data reference and set up the frame data_D = data; data_Mode = kdt_Double;; Init(window, pal, data_Width, data_Height, width, height); } */ //______________________________________________________________________________ gso_Map2D::~gso_Map2D() { // Default destructor dbg_Print("gso_Map2D::~gso_Map2D:()", DBG_LVL_ZERO); // Removes the frame from the container delete frame_gc_Set; // Removes the old PixMap if any if (frame_PxMap) gVirtualX->DeletePixmap(frame_PxMap); } //______________________________________________________________________________ void gso_Map2D::data_Set(const UShort_t* data, UInt_t data_Width_t, UInt_t data_Height_t) { // Debug dbg_Print("gso_Map2D::data_Set:(UShort)", DBG_LVL_MAKE); // Save the data reference and sets up the frame data_US = data; data_Mode = kdt_UShort; data_Width = data_Width_t; data_Height = data_Height_t; } //______________________________________________________________________________ void gso_Map2D::data_Set(const Short_t* data, UInt_t data_Width_t, UInt_t data_Height_t) { // Debug dbg_Print("gso_Map2D::data_Set:(Short)", DBG_LVL_MAKE); // Save the data reference and sets up the frame data_S = data; data_Mode = kdt_Short; data_Width = data_Width_t; data_Height = data_Height_t; } //______________________________________________________________________________ void gso_Map2D::data_Set(const UInt_t* data, UInt_t data_Width_t, UInt_t data_Height_t) { // Debug dbg_Print("gso_Map2D::data_Set:(UInt)", DBG_LVL_MAKE); // Save the data reference and sets up the frame data_UI = data; data_Mode = kdt_UInt; data_Width = data_Width_t; data_Height = data_Height_t; } //______________________________________________________________________________ void gso_Map2D::data_Set(const Int_t* data, UInt_t data_Width_t, UInt_t data_Height_t) { // Debug dbg_Print("gso_Map2D::data_Set:(Int)", DBG_LVL_MAKE); // Save the data reference and sets up the frame data_I = data; data_Mode = kdt_Int; data_Width = data_Width_t; data_Height = data_Height_t; } //______________________________________________________________________________ void gso_Map2D::data_Set(const Float_t* data, UInt_t data_Width_t, UInt_t data_Height_t) { // Debug dbg_Print("gso_Map2D::data_Set:(Float)", DBG_LVL_MAKE); // Save the data reference and sets up the frame data_F = data; data_Mode = kdt_Float; data_Width = data_Width_t; data_Height = data_Height_t; } //______________________________________________________________________________ void gso_Map2D::data_Set(const Double_t* data, UInt_t data_Width_t, UInt_t data_Height_t) { // Debug dbg_Print("gso_Map2D::data_Set:(Double)", DBG_LVL_MAKE); // Save the data reference and sets up the frame data_D = data; data_Mode = kdt_Double; data_Width = data_Width_t; data_Height = data_Height_t; } //______________________________________________________________________________ void gso_Map2D::Init(const TGWindow* window, const gso_Palette* pal, UInt_t data_Width_t, UInt_t data_Height_t, UInt_t width, UInt_t height) { // Creates a layer over a root button dbg_Print("gso_Map2D::Init:(default)", DBG_LVL_MAKE); // Stores data array dimensions data_Width = data_Width_t; data_Height = data_Height_t; // Save the palette reference palette = pal; pal_range_Max = 1; pal_range_Min = 0; pal_range_Auto = false; // Sets up the graphic context for the map painting frame_gc_Set = new GCValues_t(); frame_gc_Set->fMask = kGCClipMask | kGCClipXOrigin | kGCClipYOrigin; frame_gc_Set->fClipMask = kNone; frame_gc_Set->fClipXOrigin = 0; frame_gc_Set->fClipYOrigin = 0; frame_gc_Hnd = gVirtualX->CreateGC(GetId(), frame_gc_Set); // Clear the PxMap Id frame_PxMap = 0; } //______________________________________________________________________________ void gso_Map2D::Draw() { // Draws the current data set to the root frame dbg_Print("gso_Map2D::Draw:()", DBG_LVL_MAKE); // Removes the old PixMap if any if (frame_PxMap) gVirtualX->DeletePixmap(frame_PxMap); // Creates the PixMap reference char array (this array represents the pixels // which will be drawn, not the original data!) UInt_t* frame_Array = new UInt_t[GetWidth() * GetHeight()]; // Fill the char array (templatized to accept different data types) switch (data_Mode) { case kdt_Null: char_Fill(data_US, frame_Array); break; case kdt_UShort: char_Fill(data_US, frame_Array); break; case kdt_Short: char_Fill(data_S, frame_Array); break; case kdt_UInt: char_Fill(data_UI, frame_Array); break; case kdt_Int: char_Fill(data_I, frame_Array); break; case kdt_Float: char_Fill(data_F, frame_Array); break; case kdt_Double: char_Fill(data_D, frame_Array); break; default: dbg_Print("gso_Map2D::fill: unsupported data type!", DBG_LVL_PLAY); } // Create the map PxMap from the char pivot array frame_PxMap = gVirtualX->CreatePixmapFromData((UChar_t*)frame_Array, GetWidth(), GetHeight()); // Removes the pivot char array delete frame_Array; // Shows the map fClient->NeedRedraw(this); } //______________________________________________________________________________ template void gso_Map2D::char_Fill(const T* data, UInt_t* map_Array) { // Fills the character array accordingly to the palette values. The function // is a template to handle all possible different source data types. dbg_Print("gso_Map2D::char_Fill:(default)", DBG_LVL_MAKE); // Blanck map if no data if (!data) { for (UInt_t i = 0; i < GetWidth() * GetHeight(); i++) map_Array[i] = 0; return; } // SpeedUp pivots UInt_t frame_Width = GetWidth(); UInt_t frame_Height = GetHeight(); // Data auto range pre scan if (pal_range_Auto) { pal_range_Max = (Double_t)data[0]; pal_range_Min = (Double_t)data[0]; for (UInt_t i = 1; i < data_Width * data_Height; i++) { if (data[i] > pal_range_Max) pal_range_Max = (Double_t)data[i]; if (data[i] < pal_range_Min) pal_range_Min = (Double_t)data[i]; } } // Range check if (pal_range_Max == pal_range_Min) pal_range_Max = pal_range_Min + 1; // Palette and scale setup Double_t pal_Scale = 255 / (pal_range_Max - pal_range_Min); const UInt_t* pal_Front = palette->color_Front(); Double_t x_Scale = (Float_t)data_Width / (Float_t)frame_Width; Double_t y_Scale = (Float_t)data_Height / (Float_t)frame_Height; UInt_t y_data_Scaled, y_frame_Scaled; T data_Max = data[0]; T data_Min = data[0]; T data_Val; // Scans all the map pixels for (UInt_t y = 0; y < frame_Height; y++) { // To save time, computes this just at every row y_data_Scaled = (UInt_t)(y * y_Scale) * data_Width; y_frame_Scaled = y * frame_Width; // Standard columns rows loop for (UInt_t x = 0; x < frame_Width; x++) { // Relates the current pixel position with the nearest data posiiton data_Val = data[(UInt_t)(x * x_Scale) + y_data_Scaled]; // Boundary check in case of no autorange if (!pal_range_Auto) { if (data_Val > pal_range_Max) data_Val = (T)pal_range_Max; if (data_Val < pal_range_Min) data_Val = (T)pal_range_Min; } // Transfers the palette color into the PxMap array. Note how the PxMax array // wants a BGRA 4 bytes arrangement for each pixel, so the palette is made by // a 4 bytes UInt_t where the 4 bytes are stored during the palette building. map_Array[x + y_frame_Scaled] = pal_Front[(UInt_t)((data_Val - pal_range_Min) * pal_Scale)]; } } } //______________________________________________________________________________ void gso_Map2D::range_Set(Double_t max, Double_t min) { // Sets the palette range dbg_Print("gso_Map2D::range_Set:(Double, Double)", DBG_LVL_FLOW); // Sets range limits if (min <= max) {pal_range_Min = min; pal_range_Max = max;} else {pal_range_Max = min; pal_range_Min = max;} // Redraw the map Draw(); } //______________________________________________________________________________ void gso_Map2D::range_Get(const Double_t* max, const Double_t* min) const { // Returns the palette range dbg_Print("gso_Map2D::range_get:(Double, Double)", DBG_LVL_FLOW); // Sets range limits max = &pal_range_Max; min = &pal_range_Min; } //______________________________________________________________________________ Double_t gso_Map2D::range_Max() const { // Returns the palette range maximum dbg_Print("gso_Map2D::range_Max:()", DBG_LVL_FLOW); return pal_range_Max; } //______________________________________________________________________________ Double_t gso_Map2D::range_Min() const { // Returns the palette range minimum dbg_Print("gso_Map2D::range_Min:()", DBG_LVL_FLOW); return pal_range_Min; } //______________________________________________________________________________ void gso_Map2D::range_Max(Double_t max) { // sets the palette range maximum dbg_Print("gso_Map2D::range_Max:(Double)", DBG_LVL_FLOW); range_Set(max, pal_range_Min); } //______________________________________________________________________________ void gso_Map2D::range_Min(Double_t min) { // Sets the palette range minimum dbg_Print("gso_Map2D::range_Min:(Double)", DBG_LVL_FLOW); range_Set(pal_range_Max, min); } //______________________________________________________________________________ bool gso_Map2D::range_Auto() const { // Returns the palette range minimum dbg_Print("gso_Map2D::range_Auto:()", DBG_LVL_FLOW); return pal_range_Auto; } //______________________________________________________________________________ void gso_Map2D::range_Auto(bool automatic) { // Sets the palette range auto mode dbg_Print("gso_Map2D::range_Auto:(bool)", DBG_LVL_FLOW); pal_range_Auto = automatic; // Refreshes in case if (automatic) Draw(); } //______________________________________________________________________________ void gso_Map2D::Refresh() { // Reloads data dbg_Print("gso_Map2D::Refresh:()", DBG_LVL_FLOW); // Moves and resizes the map frame. Tthis will call a DoRedraw in case of need. Draw(); } //______________________________________________________________________________ void gso_Map2D::MoveResize(UInt_t left, UInt_t top, UInt_t width, UInt_t height) { // Overloaded TGFrame move and resize function. dbg_Print("gso_Map2D::MoveResize:(default)", DBG_LVL_FLOW); // Moves and resizes the map frame. Tthis will call a DoRedraw in case of need. TGFrame::MoveResize(left, top, width, height); } //______________________________________________________________________________ void gso_Map2D::DoRedraw() { // Draws the current map to the palette frame. This function // overloads the TGFrame original one. dbg_Print("gso_Map2D::DoRedraw:()", DBG_LVL_FLOW); // Redraws the map if any available if (frame_PxMap) gVirtualX->CopyArea(frame_PxMap, GetId(), frame_gc_Hnd, 0, 0, GetWidth(), GetHeight(), 0, 0); }