FEDRA emulsion software from the OPERA Collaboration
emhts2raw.cpp File Reference
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdint>
#include "EdbRun.h"
#include "EdbView.h"
#include "EdbSegment.h"
Include dependency graph for emhts2raw.cpp:

Classes

struct  DataPoint
 
struct  HTSView
 

Functions

void calculate_HTSView_Parameters (HTSView &view)
 
void CheckNewView (const DataPoint &point, const DataPoint &last_point, HTSView &current_view, EdbRun &run, int line_number)
 
void ConvertViewToEdbView (HTSView &view, EdbRun &run)
 
void decodeShotID (long long shotid, uint32_t &ViewID, uint32_t &ImagerID, int16_t &col, int16_t &row)
 
int main (int argc, char *argv[])
 
int readDataPoint (const std::string &line, DataPoint &point)
 
int readHTSFileTGZ (const std::string &filename, EdbRun &run)
 

Function Documentation

◆ calculate_HTSView_Parameters()

void calculate_HTSView_Parameters ( HTSView view)
70 {
71  if (view.segments.empty())
72  return;
73 
74  float xsum = 0.0f, ysum = 0.0f, zsum = 0.0f, z1sum = 0.0f, z2sum = 0.0f;
75  float xmin = view.segments[0].x, xmax = view.segments[0].x;
76  float ymin = view.segments[0].y, ymax = view.segments[0].y;
77  view.plate = view.segments[0].pos / 10;
78  view.side = view.segments[0].pos % 10;
79  view.col = view.segments[0].id0;
80  view.row = view.segments[0].id1;
81 
82  for (const auto &dp : view.segments)
83  {
84  xsum += dp.x;
85  ysum += dp.y;
86  zsum += dp.z;
87  z1sum += dp.z1;
88  z2sum += dp.z2;
89 
90  if (dp.x < xmin)
91  xmin = dp.x;
92  if (dp.x > xmax)
93  xmax = dp.x;
94  if (dp.y < ymin)
95  ymin = dp.y;
96  if (dp.y > ymax)
97  ymax = dp.y;
98  }
99 
100  int n = view.segments.size();
101  view.nsegments = n;
102  view.x0 = xsum / n;
103  view.y0 = ysum / n;
104  view.z0 = zsum / n;
105  view.z1 = z1sum / n;
106  view.z2 = z2sum / n;
107 
108  view.xmin = xmin;
109  view.xmax = xmax;
110  view.ymin = ymin;
111  view.ymax = ymax;
112  view.zmin = min(view.z1, view.z2);
113  view.zmax = max(view.z1, view.z2);
114 }
float min(TClonesArray *t)
Definition: bitview.cxx:275
int max
Definition: check_shower.C:41
float xmin
Definition: emthickness.cpp:61
float ymin
Definition: emthickness.cpp:63
float xmax
Definition: emthickness.cpp:61
float ymax
Definition: emthickness.cpp:63
std::vector< DataPoint > segments
Definition: emhts2raw.cpp:48
float z0
Definition: emhts2raw.cpp:46
float z2
Definition: emhts2raw.cpp:46
float xmax
Definition: emhts2raw.cpp:47
float z1
Definition: emhts2raw.cpp:46
float ymin
Definition: emhts2raw.cpp:47
int nsegments
Definition: emhts2raw.cpp:41
float zmin
Definition: emhts2raw.cpp:47
float y0
Definition: emhts2raw.cpp:46
int plate
Definition: emhts2raw.cpp:42
int row
Definition: emhts2raw.cpp:45
float x0
Definition: emhts2raw.cpp:46
float ymax
Definition: emhts2raw.cpp:47
float xmin
Definition: emhts2raw.cpp:47
float zmax
Definition: emhts2raw.cpp:47
int side
Definition: emhts2raw.cpp:43
int col
Definition: emhts2raw.cpp:44

◆ CheckNewView()

void CheckNewView ( const DataPoint point,
const DataPoint last_point,
HTSView current_view,
EdbRun run,
int  line_number 
)
170 {
171  if (last_point.isg == -1)
172  return; // First point, nothing to compare
173 
174  if (point.id0 != last_point.id0 || point.id1 != last_point.id1)
175  {
176  // New view detected
177  std::cout << "line=" << line_number
178  << " last_isg/isg =" << last_point.isg << " / " << point.isg
179  << " last_id0/id0 = " << last_point.id0 << " / " << point.id0
180  << " last_id1/id1 = " << last_point.id1 << " / " << point.id1 << std::endl;
181  if (current_view.nsegments > 0)
182  {
183  std::cout << "View " << current_view.view_id << " has " << current_view.nsegments << " segments." << std::endl;
184  ConvertViewToEdbView(current_view, run);
185  current_view.view_id++;
186  current_view.nsegments = 0;
187  current_view.segments.clear();
188  }
189  }
190 }
void ConvertViewToEdbView(HTSView &view, EdbRun &run)
Definition: emhts2raw.cpp:116
EdbRun * run
Definition: check_raw.C:38
int isg
Definition: emhts2raw.cpp:22
int id0
Definition: emhts2raw.cpp:33
int id1
Definition: emhts2raw.cpp:34
int view_id
Definition: emhts2raw.cpp:40

◆ ConvertViewToEdbView()

void ConvertViewToEdbView ( HTSView view,
EdbRun run 
)
117 {
118  // Here you would convert the HTSView to an EdbView and add it to the EdbRun
119  // This is a placeholder function
120  std::cout << "Converting View " << view.view_id << " with " << view.nsegments << " segments to EdbView." << std::endl;
121 
123 
124  float zbase = (view.side == 1) ? view.zmax : view.zmin;
125  EdbView *edbView = run.GetView();
126  edbView->GetHeader()->SetViewID(view.view_id);
127  edbView->GetHeader()->SetCoordXY(view.x0, view.y0);
128  EdbAffine2D aa(*(edbView->GetHeader()->GetAffine()));
129  edbView->GetHeader()->SetAffine(aa.A11(), aa.A12(), aa.A21(), aa.A22(), view.x0, view.y0);
130  if (view.side == 2)
131  { // top
132  edbView->GetHeader()->SetCoordZ(view.zmax, view.zmin, 0, 0);
133  edbView->GetHeader()->SetNframes(16, 0); // assuming 16 frames for top
134  }
135  else
136  { // bottom
137  edbView->GetHeader()->SetCoordZ(0, 0, view.zmax, view.zmin);
138  edbView->GetHeader()->SetNframes(0, 16); // assuming 16 frames for bottom
139  }
140  edbView->GetHeader()->SetColRow(view.col, view.row);
141 
142  int cnt = 0;
143  EdbSegment seg;
144  for (const auto &dp : view.segments)
145  {
146  float x = dp.x - view.x0 + (zbase - dp.z) * dp.tx; // propagate to zbase
147  float y = dp.y - view.y0 + (zbase - dp.z) * dp.ty; // propagate to zbase
148  seg.Set(x, y, zbase, dp.tx, dp.ty, dp.z2 - dp.z1, view.side, dp.ph, dp.isg);
149  edbView->AddSegment(&seg);
150  cnt++;
151  }
152  run.AddView(edbView);
153 }
Definition: EdbAffine.h:17
void AddView()
Definition: EdbRun.cxx:332
EdbView * GetView() const
Definition: EdbRun.h:109
Definition: EdbSegment.h:61
void Set(float x, float y, float z, float tx, float ty, float dz=0, int side=0, int puls=0, int id=0)
Definition: EdbSegment.cxx:92
void SetViewID(int id)
Definition: EdbView.h:99
Definition: EdbView.h:134
EdbViewHeader * GetHeader() const
Definition: EdbView.h:163
void calculate_HTSView_Parameters(HTSView &view)
Definition: emhts2raw.cpp:69

◆ decodeShotID()

void decodeShotID ( long long  shotid,
uint32_t &  ViewID,
uint32_t &  ImagerID,
int16_t &  col,
int16_t &  row 
)
52 {
53  // Convert to uint32_t (assuming shotid stores the uint32_t value)
54  uint32_t shotid_uint32 = static_cast<uint32_t>(shotid);
55 
56  // Extract col and row
57  col = static_cast<int16_t>(shotid_uint32 & 0x0000FFFF);
58  row = static_cast<int16_t>((shotid_uint32 & 0xFFFF0000) >> 16);
59 
60  // Reconstruct ShotID from col and row
61  uint32_t reconstructed_shotid = ((uint32_t)(uint16_t)row << 16) | ((uint32_t)(uint16_t)col);
62 
63  // Decode ViewID and ImagerID
64  const uint32_t NumberOfImager = 72;
65  ViewID = reconstructed_shotid / NumberOfImager;
66  ImagerID = reconstructed_shotid % NumberOfImager;
67 }

◆ main()

int main ( int  argc,
char *  argv[] 
)
331 {
332  std::vector<std::string> input_files;
333  std::string output_file;
334 
335  // Parse command line arguments
336  for (int i = 1; i < argc; i++)
337  {
338  std::string arg = argv[i];
339 
340  if (arg == "-o" || arg == "--output")
341  {
342  if (i + 1 < argc)
343  {
344  output_file = argv[++i];
345  }
346  else
347  {
348  std::cerr << "Error: -o option requires an output filename" << std::endl;
349  return 1;
350  }
351  }
352  else if (arg == "-h" || arg == "--help")
353  {
354  std::cerr << "Usage: " << argv[0] << " [options] <input_files...>" << std::endl;
355  std::cerr << "Options:" << std::endl;
356  std::cerr << " -o, --output <file> Specify output ROOT file (default: auto-generated)" << std::endl;
357  std::cerr << " -h, --help Show this help message" << std::endl;
358  std::cerr << std::endl;
359  std::cerr << "Examples:" << std::endl;
360  std::cerr << " " << argv[0] << " side1.tgz side2.tgz -o output.root" << std::endl;
361  std::cerr << " " << argv[0] << " data1.gz data2.gz data3.gz" << std::endl;
362  std::cerr << " " << argv[0] << " *.tgz -o combined.root" << std::endl;
363  return 0;
364  }
365  else if (arg[0] == '-')
366  {
367  std::cerr << "Error: Unknown option " << arg << std::endl;
368  return 1;
369  }
370  else
371  {
372  // It's an input file
373  input_files.push_back(arg);
374  }
375  }
376 
377  // Check if we have at least one input file
378  if (input_files.empty())
379  {
380  std::cerr << "Error: No input files specified" << std::endl;
381  std::cerr << "Usage: " << argv[0] << " [options] <input_files...>" << std::endl;
382  std::cerr << "Use " << argv[0] << " -h for more help" << std::endl;
383  return 1;
384  }
385 
386  // Generate output filename if not specified
387  if (output_file.empty())
388  {
389  if (input_files.size() == 1)
390  {
391  // Single input file: use its base name
392  std::string infile = input_files[0];
393  auto pos = infile.find_last_of("/");
394  std::string base = (pos == std::string::npos) ? infile : infile.substr(pos + 1);
395 
396  // Remove extension
397  auto dot = base.find_last_of('.');
398  while (dot != std::string::npos &&
399  (base.substr(dot) == ".tgz" ||
400  base.substr(dot) == ".gz" ||
401  base.substr(dot) == ".tar.gz" ||
402  base.substr(dot) == ".txt"))
403  {
404  base = base.substr(0, dot);
405  dot = base.find_last_of('.');
406  }
407 
408  output_file = base + ".raw.root";
409  }
410  else
411  {
412  // Multiple input files: use generic name
413  output_file = "combined.raw.root";
414  }
415  }
416 
417  // Optional: Check if output file has .root extension
418  if (output_file.size() < 5 || output_file.substr(output_file.size() - 5) != ".root")
419  {
420  std::cout << "Note: Output filename doesn't end with .root, adding it" << std::endl;
421  output_file += ".root";
422  }
423 
424  std::cout << "Processing " << input_files.size() << " input file(s):" << std::endl;
425  for (size_t i = 0; i < input_files.size(); i++)
426  {
427  std::cout << " [" << i + 1 << "] " << input_files[i] << std::endl;
428  }
429  std::cout << "Output file: " << output_file << std::endl;
430 
431  // Create ROOT run object
432  EdbRun run(output_file.c_str(), "RECREATE");
433 
434  try
435  {
436  int total_records = 0;
437 
438  // Process all input files
439  for (size_t i = 0; i < input_files.size(); i++)
440  {
441  std::cout << "\n=== Processing file " << i + 1 << "/" << input_files.size()
442  << ": " << input_files[i] << " ===" << std::endl;
443 
444  int numRecords = readHTSFileTGZ(input_files[i], run);
445  std::cout << "Successfully read " << numRecords << " records from "
446  << input_files[i] << std::endl;
447 
448  total_records += numRecords;
449  }
450 
451  std::cout << "\n=== Summary ===" << std::endl;
452  std::cout << "Total records processed: " << total_records << std::endl;
453  std::cout << "Output saved to: " << output_file << std::endl;
454  }
455  catch (const std::exception &e)
456  {
457  std::cerr << "Error: " << e.what() << std::endl;
458  run.Close();
459  return 1;
460  }
461 
462  run.Close();
463 
464  return 0;
465 }
T dot(const SVector< T, D > &lhs, const SVector< T, D > &rhs)
Definition: Functions.hh:132
Definition: EdbRun.h:74
void Close()
Definition: EdbRun.cxx:466
int readHTSFileTGZ(const std::string &filename, EdbRun &run)
Definition: emhts2raw.cpp:192

◆ readDataPoint()

int readDataPoint ( const std::string &  line,
DataPoint point 
)
156 {
157  std::istringstream iss(line);
158  iss >> point.pos >> point.zone >> point.shotid >> point.isg >> point.ph >>
159  point.tx >> point.ty >> point.x >> point.y >> point.z >> point.z1 >> point.z2 >>
160  point.px >> point.py >> point.id0 >> point.id1 >> point.id2;
161  if (!iss)
162  {
163  return -1; // Error in parsing
164  }
165  point.z = (point.z1 + point.z2) / 2; // mt x,y corresponds to 8-th layer z
166  return 0; // Success
167 }
float px
Definition: emhts2raw.cpp:31
float x
Definition: emhts2raw.cpp:26
int zone
Definition: emhts2raw.cpp:20
int ph
Definition: emhts2raw.cpp:23
int pos
Definition: emhts2raw.cpp:19
float py
Definition: emhts2raw.cpp:32
long long shotid
Definition: emhts2raw.cpp:21
float z1
Definition: emhts2raw.cpp:29
float y
Definition: emhts2raw.cpp:27
int id2
Definition: emhts2raw.cpp:35
float z2
Definition: emhts2raw.cpp:30
float z
Definition: emhts2raw.cpp:28
float tx
Definition: emhts2raw.cpp:24
float ty
Definition: emhts2raw.cpp:25

◆ readHTSFileTGZ()

int readHTSFileTGZ ( const std::string &  filename,
EdbRun run 
)
193 {
194  FILE *input_stream = nullptr;
195  bool is_pipe = false;
196 
197  // Determine input source
198  if (filename.find(".tgz") != std::string::npos ||
199  filename.find(".tar.gz") != std::string::npos)
200  {
201  // For .tgz files: use pipe
202  std::string command = "tar -xzOf '" + filename + "' 2>/dev/null";
203  input_stream = popen(command.c_str(), "r");
204  is_pipe = true;
205  if (!input_stream)
206  {
207  throw std::runtime_error("Failed to open pipe for: " + filename);
208  }
209  }
210  else if (filename.find(".gz") != std::string::npos)
211  {
212  // For .gz files: use pipe
213  std::string command = "gunzip -c '" + filename + "' 2>/dev/null";
214  input_stream = popen(command.c_str(), "r");
215  is_pipe = true;
216  if (!input_stream)
217  {
218  throw std::runtime_error("Failed to open pipe for: " + filename);
219  }
220  }
221  else
222  {
223  // For uncompressed files: use regular FILE*
224  input_stream = fopen(filename.c_str(), "r");
225  if (!input_stream)
226  {
227  throw std::runtime_error("Cannot open file: " + filename);
228  }
229  }
230 
231  // Now read from the stream (pipe or regular file)
232  char *line_buffer = nullptr;
233  size_t buffer_size = 0;
234  ssize_t bytes_read;
235  int total_lines = 0;
236 
237  HTSView current_view;
238  DataPoint last_point;
239  last_point.isg = -1;
240  last_point.id0 = 12345678;
241  last_point.id1 = 12345678;
242 
243  try
244  {
245  while ((bytes_read = getline(&line_buffer, &buffer_size, input_stream)) != -1)
246  {
247  std::string line(line_buffer);
248 
249  // Remove trailing newline if present
250  if (!line.empty() && line.back() == '\n')
251  {
252  line.pop_back();
253  }
254 
255  // Remove trailing carriage return if present
256  if (!line.empty() && line.back() == '\r')
257  {
258  line.pop_back();
259  }
260 
261  total_lines++;
262  if (line.empty())
263  continue;
264 
265  DataPoint point;
266  if (readDataPoint(line, point) != 0)
267  {
268  std::cerr << "Warning: could not parse line " << total_lines
269  << " in file " << filename
270  << ": " << line << std::endl;
271  continue;
272  }
273 
274  CheckNewView(point, last_point, current_view, run, total_lines);
275 
276  last_point = point;
277  current_view.nsegments++;
278  current_view.segments.push_back(point);
279  }
280 
281  // Check for read errors
282  if (ferror(input_stream))
283  {
284  throw std::runtime_error("Error reading from " + filename);
285  }
286  }
287  catch (...)
288  {
289  free(line_buffer);
290  if (is_pipe)
291  {
292  pclose(input_stream);
293  }
294  else
295  {
296  fclose(input_stream);
297  }
298  throw;
299  }
300 
301  free(line_buffer);
302 
303  // Finalize last view
304  if (current_view.nsegments > 0)
305  {
306  std::cout << "View " << current_view.view_id << " has "
307  << current_view.nsegments << " segments." << std::endl;
308  ConvertViewToEdbView(current_view, run);
309  }
310 
311  // Close the input stream properly
312  int status = 0;
313  if (is_pipe)
314  {
315  status = pclose(input_stream);
316  if (status != 0)
317  {
318  std::cerr << "Warning: decompression command exited with status "
319  << status << " for file: " << filename << std::endl;
320  }
321  }
322  else
323  {
324  fclose(input_stream);
325  }
326 
327  return total_lines;
328 }
void CheckNewView(const DataPoint &point, const DataPoint &last_point, HTSView &current_view, EdbRun &run, int line_number)
Definition: emhts2raw.cpp:169
int readDataPoint(const std::string &line, DataPoint &point)
Definition: emhts2raw.cpp:155
string filename
Definition: emthickness.cpp:34
fclose(pFile)
Definition: emhts2raw.cpp:18
Definition: emhts2raw.cpp:39