Project
Loading...
Searching...
No Matches
Screenshot.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16
21#include <Rtypes.h>
22#include "TROOT.h"
23#include <filesystem>
24#include <sstream>
25#include <fairlogger/Logger.h>
26
27namespace o2
28{
29namespace event_visualisation
30{
31
32bool Screenshot::CopyImage(TASImage* dst, TASImage* src, Int_t x_dst, Int_t y_dst, Int_t x_src, Int_t y_src,
33 UInt_t w_src, UInt_t h_src)
34{
35 if (!dst) {
36 return false;
37 }
38 if (!src) {
39 return false;
40 }
41
42 int x = 0;
43 int y = 0;
44 int idx_src = 0;
45 int idx_dst = 0;
46 x_src = x_src < 0 ? 0 : x_src;
47 y_src = y_src < 0 ? 0 : y_src;
48
49 if ((x_src >= (int)src->GetWidth()) || (y_src >= (int)src->GetHeight())) {
50 return false;
51 }
52
53 w_src = x_src + w_src > src->GetWidth() ? src->GetWidth() - x_src : w_src;
54 h_src = y_src + h_src > src->GetHeight() ? src->GetHeight() - y_src : h_src;
55 UInt_t yy = (y_src + y) * src->GetWidth();
56
57 src->BeginPaint(false);
58 dst->BeginPaint(false);
59
60 UInt_t* dst_image_array = dst->GetArgbArray();
61 UInt_t* src_image_array = src->GetArgbArray();
62
63 if (!dst_image_array || !src_image_array) {
64 return false;
65 }
66
67 for (y = 0; y < (int)h_src; y++) {
68 for (x = 0; x < (int)w_src; x++) {
69
70 idx_src = yy + x + x_src;
71 idx_dst = (y_dst + y) * dst->GetWidth() + x + x_dst;
72
73 if ((x + x_dst < 0) || (y_dst + y < 0) ||
74 (x + x_dst >= (int)dst->GetWidth()) || (y + y_dst >= (int)dst->GetHeight())) {
75 continue;
76 }
77
78 dst_image_array[idx_dst] = src_image_array[idx_src];
79 }
80 yy += src->GetWidth();
81 }
82
83 return true;
84}
85
86TASImage*
87 Screenshot::ScaleImage(TASImage* image, UInt_t desiredWidth, UInt_t desiredHeight, const std::string& backgroundColor)
88{
89 if (!image) {
90 return nullptr;
91 }
92 if (desiredWidth == 0 || desiredHeight == 0) {
93 return nullptr;
94 }
95
96 UInt_t scaleWidth = desiredWidth;
97 UInt_t scaleHeight = desiredHeight;
98 UInt_t offsetWidth = 0;
99 UInt_t offsetHeight = 0;
100
101 float aspectRatio = (float)image->GetWidth() / (float)image->GetHeight();
102
103 if (desiredWidth >= aspectRatio * desiredHeight) {
104 scaleWidth = (UInt_t)(aspectRatio * desiredHeight);
105 offsetWidth = (desiredWidth - scaleWidth) / 2.0f;
106 } else {
107 scaleHeight = (UInt_t)((1.0f / aspectRatio) * desiredWidth);
108 offsetHeight = (desiredHeight - scaleHeight) / 2.0f;
109 }
110
111 TASImage* scaledImage = new TASImage(desiredWidth, desiredHeight);
112 scaledImage->FillRectangle(backgroundColor.c_str(), 0, 0, desiredWidth, desiredHeight);
113
114 image->Scale(scaleWidth, scaleHeight);
115
116 CopyImage(scaledImage, image, offsetWidth, offsetHeight, 0, 0, scaleWidth, scaleHeight);
117
118 return scaledImage;
119}
120
121std::string
122 Screenshot::perform(const char* prefix, std::string fileName, o2::detectors::DetID::mask_t detectorsMask, int runNumber,
123 int firstTFOrbit, const std::string& collisionTime)
124{
125 auto start = std::chrono::high_resolution_clock::now();
128 int backgroundColor = ConfigurationManager::getBackgroundColor(); // black
129 std::string backgroundColorHex = "#000000"; // "#19324b";
130 TColor* col = gROOT->GetColor(backgroundColor);
131 if (col) {
132 backgroundColorHex = col->AsHexString();
133 }
134
135 auto image = new TASImage(width, height);
136
137 image->FillRectangle(backgroundColorHex.c_str(), 0, 0, width, height);
138
139 auto pixel_object_scale_3d = ConfigurationManager::getScreenshotPixelObjectScale3d(prefix);
140 auto pixel_object_scale_rphi = ConfigurationManager::getScreenshotPixelObjectScaleRphi(prefix);
141 auto pixel_object_scale_zy = ConfigurationManager::getScreenshotPixelObjectScaleZY(prefix);
142
143 const auto annotationStateTop = MultiView::getInstance()->getAnnotationTop()->GetState();
144 const auto annotationStateBottom = MultiView::getInstance()->getAnnotationBottom()->GetState();
145 MultiView::getInstance()->getAnnotationTop()->SetState(TGLOverlayElement::kInvisible);
146 MultiView::getInstance()->getAnnotationBottom()->SetState(TGLOverlayElement::kInvisible);
147 TImage* view3dImage = MultiView::getInstance()->getView(MultiView::EViews::View3d)->GetGLViewer()->GetPictureUsingFBO(width * 0.65, height * 0.95, pixel_object_scale_3d);
148 MultiView::getInstance()->getAnnotationTop()->SetState(annotationStateTop);
149 MultiView::getInstance()->getAnnotationBottom()->SetState(annotationStateBottom);
150 CopyImage(image, (TASImage*)view3dImage, width * 0.015, height * 0.025, 0, 0, view3dImage->GetWidth(),
151 view3dImage->GetHeight());
152 delete view3dImage;
153
154 TImage* viewRphiImage = MultiView::getInstance()->getView(
156 ->GetGLViewer()
157 ->GetPictureUsingFBO(width * 0.3, height * 0.45,
158 pixel_object_scale_rphi);
159 CopyImage(image, (TASImage*)viewRphiImage, width * 0.68, height * 0.025, 0, 0, viewRphiImage->GetWidth(),
160 viewRphiImage->GetHeight());
161 delete viewRphiImage;
162
163 TImage* viewZYImage = MultiView::getInstance()->getView(MultiView::EViews::ViewZY)->GetGLViewer()->GetPictureUsingFBO(width * 0.3, height * 0.45, pixel_object_scale_zy);
164 CopyImage(image, (TASImage*)viewZYImage, width * 0.68, height * 0.525, 0, 0, viewZYImage->GetWidth(),
165 viewZYImage->GetHeight());
166 delete viewZYImage;
167
168 static std::map<std::string, TASImage*> aliceLogos;
169 TASImage* aliceLogo = nullptr;
170 if (aliceLogos.find(prefix) != aliceLogos.end()) {
171 aliceLogo = aliceLogos.find(prefix)->second;
172 }
173
174 if (aliceLogo == nullptr) {
175 aliceLogo = new TASImage(ConfigurationManager::getScreenshotLogoAlice());
176 if (aliceLogo->IsValid()) {
177 double ratio = (double)(aliceLogo->GetWidth()) / (double)(aliceLogo->GetHeight());
178 aliceLogo->Scale(0.08 * width, 0.08 * width / ratio);
179 aliceLogos[prefix] = aliceLogo;
180 }
181 }
182 if (aliceLogo != nullptr) {
183 if (aliceLogo->IsValid()) {
184 image->Merge(aliceLogo, "alphablend", 0.01 * width, 0.01 * width);
185 }
186 }
187 // delete aliceLogo; /// avoiding reload the same resource
188
189 int o2LogoMarginX = 0.01 * width;
190 int o2LogoMarginY = 0.01 * width;
191 int o2LogoSize = 0.04 * width;
192
193 static std::map<std::string, TASImage*> o2Logos;
194 TASImage* o2Logo = nullptr;
195 if (o2Logos.find(prefix) != o2Logos.end()) {
196 o2Logo = o2Logos.find(prefix)->second;
197 }
198
199 if (o2Logo == nullptr) {
200 o2Logo = new TASImage(ConfigurationManager::getScreenshotLogoO2());
201 if (o2Logo->IsValid()) {
202 double ratio = (double)(o2Logo->GetWidth()) / (double)(o2Logo->GetHeight());
203 o2Logo->Scale(o2LogoSize, o2LogoSize / ratio);
204 o2Logos[prefix] = o2Logo;
205 }
206 }
207
208 if (o2Logo != nullptr) {
209 if (o2Logo->IsValid()) {
210 double ratio = (double)(o2Logo->GetWidth()) / (double)(o2Logo->GetHeight());
211 image->Merge(o2Logo, "alphablend", o2LogoMarginX, height - o2LogoSize / ratio - o2LogoMarginY);
212 }
213 }
214
215 int textX = o2LogoMarginX + o2LogoSize + o2LogoMarginX;
216 int textY = height - o2LogoSize - o2LogoMarginY;
217
218 auto detectorsString = detectors::DetID::getNames(detectorsMask);
219
220 std::vector<std::string> lines;
221 if (!collisionTime.empty()) {
222 lines.push_back(
223 (std::string)ConfigurationManager::getInstance().getSettings().GetValue("screenshot.message.line.0",
224 TString::Format("Run number: %d",
225 runNumber)));
226 lines.push_back(
227 (std::string)ConfigurationManager::getInstance().getSettings().GetValue("screenshot.message.line.1",
228 TString::Format("First TF orbit: %d",
229 firstTFOrbit)));
230 lines.push_back(
231 (std::string)ConfigurationManager::getInstance().getSettings().GetValue("screenshot.message.line.2",
232 TString::Format("Date: %s",
233 collisionTime.c_str())));
234 lines.push_back(
235 (std::string)ConfigurationManager::getInstance().getSettings().GetValue("screenshot.message.line.3",
236 TString::Format("Detectors: %s",
237 detectorsString.c_str())));
238 }
239
240 image->BeginPaint();
241 int fontSize = 0.015 * height;
242 int textLineHeight = 0.015 * height;
243
244 for (int i = 0; i < 4; i++) {
245 lines.push_back(""); // guard for empty collision time
246 image->DrawText(textX, textY + i * textLineHeight, lines[i].c_str(), fontSize, "#BBBBBB", "FreeSansBold.otf");
247 }
248 image->EndPaint();
249
250 image->WriteImage(fileName.c_str(), TImage::kPng);
251 delete image;
252
253 auto stop = std::chrono::high_resolution_clock::now();
254 auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
255 return fileName; // saved screenshod file name
256}
257
258} // namespace event_visualisation
259} // namespace o2
int32_t i
uint32_t col
Definition RawData.h:4
Screenshot functionality.
static std::string getNames(mask_t mask, char delimiter=',')
Definition DetID.cxx:74
static UInt_t getScreenshotHeight(const char *prefix)
static ConfigurationManager & getInstance()
Returns an instance of ConfigurationManager.
static UInt_t getScreenshotPixelObjectScale3d(const char *prefix)
static UInt_t getScreenshotPixelObjectScaleZY(const char *prefix)
static UInt_t getScreenshotWidth(const char *prefix)
static UInt_t getScreenshotPixelObjectScaleRphi(const char *prefix)
static MultiView * getInstance()
Returns an instance of the MultiView.
TEveViewer * getView(EViews view)
Returns pointer to specific view.
Definition MultiView.h:70
TGLAnnotation * getAnnotationTop()
Get annotation pointer.
Definition MultiView.h:99
TGLAnnotation * getAnnotationBottom()
Definition MultiView.h:100
static std::string perform(const char *prefix, std::string fileName, o2::detectors::DetID::mask_t detectorsMask, int runNumber, int firstTFOrbit, const std::string &collisionTime)
GLeglImageOES image
Definition glcorearb.h:4021
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum src
Definition glcorearb.h:1767
GLint GLsizei GLsizei height
Definition glcorearb.h:270
GLint GLsizei width
Definition glcorearb.h:270
GLint y
Definition glcorearb.h:270
GLenum GLenum dst
Definition glcorearb.h:1767
GLenum GLsizeiptr fontSize
Definition glcorearb.h:5519
GLuint start
Definition glcorearb.h:469
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...