Skip to content

Commit 6141ea5

Browse files
author
Wiktor Pierozak
committed
FIT: created macros to save LUT to CSV, convert back to ROOT and compare LUTs in ROOT format
1 parent 87b9775 commit 6141ea5

File tree

4 files changed

+315
-0
lines changed

4 files changed

+315
-0
lines changed

Detectors/FIT/macros/CMakeLists.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,5 +49,21 @@ o2_add_test_root_macro(readAlignParam.C
4949
PUBLIC_LINK_LIBRARIES O2::CCDB
5050
LABELS fit)
5151

52+
o2_add_test_root_macro(compareLUT.C
53+
PUBLIC_LINK_LIBRARIES O2::DataFormatsFIT
54+
O2::CCDB
55+
LABELS fit)
56+
57+
o2_add_test_root_macro(convertLUTCSVtoROOT.C
58+
PUBLIC_LINK_LIBRARIES O2::DataFormatsFIT
59+
O2::CCDB
60+
O2::CommonUtils
61+
LABELS fit)
62+
63+
o2_add_test_root_macro(fetchLUT.C
64+
PUBLIC_LINK_LIBRARIES O2::DataFormatsFIT
65+
O2::CCDB
66+
LABELS fit)
67+
5268
o2_data_file(COPY readFITDCSdata.C DESTINATION Detectors/FIT/macros/)
5369
o2_data_file(COPY readFITDeadChannelMap.C DESTINATION Detectors/FIT/macros/)

Detectors/FIT/macros/compareLUT.C

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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+
#if !defined(__CLING__) || defined(__ROOTCLING__)
12+
#include <iostream>
13+
#include <array>
14+
#endif
15+
16+
17+
R__LOAD_LIBRARY(libO2CommonUtils)
18+
R__LOAD_LIBRARY(libO2DataFormatsFIT)
19+
20+
#include "CommonUtils/ConfigurableParamHelper.h"
21+
#include "DataFormatsFIT/LookUpTable.h"
22+
#include "Framework/Logger.h"
23+
#include "CommonConstants/LHCConstants.h"
24+
25+
std::vector<o2::fit::EntryFEE> readLUTFromFile(const std::string filePath, const std::string objectName)
26+
{
27+
TFile file(filePath.c_str(), "READ");
28+
if(file.IsOpen() == false) {
29+
LOGP(fatal, "Failed to open {}", filePath);
30+
}
31+
LOGP(info, "Successfully opened {}", filePath);
32+
33+
std::vector<o2::fit::EntryFEE>* lut = nullptr;
34+
file.GetObject<std::vector<o2::fit::EntryFEE>>(objectName.c_str(), lut);
35+
36+
if(lut == nullptr) {
37+
LOGP(fatal, "Failed to read object {}", objectName);
38+
}
39+
LOGP(info, "Successfully get {} object", objectName);
40+
41+
std::vector<o2::fit::EntryFEE> lutCopy = *lut;
42+
file.Close();
43+
44+
return std::move(lutCopy);
45+
}
46+
47+
inline bool operator==(const o2::fit::EntryFEE& lhs, const o2::fit::EntryFEE& rhs)
48+
{
49+
auto comparer = [](const o2::fit::EntryFEE& e) {
50+
return std::tie(
51+
e.mEntryCRU.mLinkID, e.mEntryCRU.mEndPointID, e.mEntryCRU.mCRUID, e.mEntryCRU.mFEEID,
52+
e.mChannelID, e.mLocalChannelID, e.mModuleType, e.mModuleName,
53+
e.mBoardHV, e.mChannelHV, e.mSerialNumberMCP, e.mCableHV, e.mCableSignal
54+
);
55+
};
56+
return comparer(lhs) == comparer(rhs);
57+
}
58+
59+
60+
void compareLUT(const std::string fileA, const std::string fileB, bool compareEvenForDifferentSize = false, const std::string objectName = "LookupTable")
61+
{
62+
std::vector<o2::fit::EntryFEE> lutA = readLUTFromFile(fileA, objectName);
63+
std::vector<o2::fit::EntryFEE> lutB = readLUTFromFile(fileB, objectName);
64+
65+
bool lutAreSame = true;
66+
67+
if(lutA.size() != lutB.size()) {
68+
LOGP(error, "The LUT vary in size: {} for {} vs {} for {}", lutA.size(), fileA, lutB.size(), fileB);
69+
lutAreSame = false;
70+
if(compareEvenForDifferentSize == false) {
71+
return;
72+
}
73+
}
74+
75+
size_t size = (lutA.size() < lutB.size()) ? lutA.size() : lutB.size();
76+
77+
std::cout << "--- Comparision ---" << std::endl;
78+
79+
for(size_t idx = 0; idx < size; idx++) {
80+
if(lutA[idx] == lutB[idx]) {
81+
continue;
82+
} else {
83+
std::cout << "Entry " << idx << " in " << fileA << " entry: " << lutA[idx] << std::endl;
84+
std::cout << "Entry " << idx << " in " << fileB << " entry: " << lutB[idx] << std::endl;
85+
lutAreSame = false;
86+
}
87+
}
88+
89+
for(size_t idx = size; idx < lutA.size(); idx++) {
90+
std::cout << "Extra entry " << idx << " in " << fileA << ": " << lutA[idx] << std::endl;
91+
}
92+
93+
for(size_t idx = size; idx < lutB.size(); idx++) {
94+
std::cout << "Extra entry " << idx << " in " << fileB << ": " << lutB[idx] << std::endl;
95+
}
96+
97+
if(lutAreSame) {
98+
std::cout << "LUTs are the same!" << std::endl;
99+
} else {
100+
std::cout << "LUTs are different!" << std::endl;
101+
}
102+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
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+
#if !defined(__CLING__) || defined(__ROOTCLING__)
12+
#include <iostream>
13+
#include <array>
14+
#include <ranges>
15+
16+
17+
R__LOAD_LIBRARY(libO2CommonUtils)
18+
R__LOAD_LIBRARY(libO2CCDB)
19+
R__LOAD_LIBRARY(libO2DataFormatsFIT)
20+
21+
#include "DataFormatsFIT/LookUpTable.h"
22+
#include "Framework/Logger.h"
23+
#include "CommonConstants/LHCConstants.h"
24+
25+
#endif
26+
27+
void saveToRoot(std::vector<o2::fit::EntryFEE>& lut, string_view path);
28+
29+
void convertLUTCSVtoROOT(const std::string csvFilePath, const std::string rootFilePath)
30+
{
31+
std::vector<o2::fit::EntryFEE> lut;
32+
std::ifstream lutCSV(csvFilePath);
33+
if(lutCSV.is_open() == false){
34+
LOGP(error, "Failed to open {}", csvFilePath);
35+
return;
36+
}
37+
38+
std::string line;
39+
std::getline(lutCSV, line);
40+
std::map<std::string, int> headerMap;
41+
42+
auto headersView = std::string_view(line) | std::views::split(',');
43+
44+
int index = 0;
45+
for (auto&& rng : headersView) {
46+
std::string columnName(rng.begin(), rng.end());
47+
headerMap[columnName] = index++;
48+
}
49+
50+
while(std::getline(lutCSV, line)) {
51+
if(line.size() == 0) {
52+
return;
53+
}
54+
o2::fit::EntryFEE entry;
55+
auto fieldViews = std::string_view(line) | std::views::split(',');
56+
std::vector<std::string> parsedLine;
57+
for(auto&& view: fieldViews) {
58+
parsedLine.emplace_back(view.begin(), view.end());
59+
}
60+
if (parsedLine.size() < headerMap.size()) {
61+
LOGP(error, "Ill-formed line: {}", line);
62+
return;
63+
}
64+
65+
entry.mEntryCRU.mLinkID = std::stoi(parsedLine[headerMap.at("LinkID")]);
66+
entry.mEntryCRU.mEndPointID = std::stoi(parsedLine[headerMap.at("EndPointID")]);
67+
entry.mEntryCRU.mCRUID = std::stoi(parsedLine[headerMap.at("CRUID")]);
68+
entry.mEntryCRU.mFEEID = std::stoi(parsedLine[headerMap.at("FEEID")]);
69+
70+
entry.mModuleType = parsedLine[headerMap.at("ModuleType")];
71+
entry.mLocalChannelID = parsedLine[headerMap.at("LocalChannelID")];
72+
entry.mChannelID = parsedLine[headerMap.at("channel #")];
73+
entry.mModuleName = parsedLine[headerMap.at("Module")];
74+
entry.mBoardHV = parsedLine[headerMap.at("HV board")];
75+
entry.mChannelHV = parsedLine[headerMap.at("HV channel")];
76+
entry.mSerialNumberMCP = parsedLine[headerMap.at("MCP S/N")];
77+
entry.mCableHV = parsedLine[headerMap.at("HV cable")];
78+
entry.mCableSignal = parsedLine[headerMap.at("signal cable")];
79+
lut.emplace_back(entry);
80+
}
81+
saveToRoot(lut, rootFilePath);
82+
}
83+
84+
void saveToRoot(std::vector<o2::fit::EntryFEE>& lut, string_view path)
85+
{
86+
TFile file(path.data(), "RECREATE");
87+
if(file.IsOpen() == false) {
88+
LOGP(fatal, "Failed to open file {}", path.data());
89+
}
90+
91+
file.WriteObject(&lut, "LookupTable");
92+
file.Close();
93+
}

Detectors/FIT/macros/fetchLUT.C

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
#if !defined(__CLING__) || defined(__ROOTCLING__)
12+
#include <iostream>
13+
#include <array>
14+
#include <ranges>
15+
#endif
16+
17+
18+
R__LOAD_LIBRARY(libO2CommonUtils)
19+
R__LOAD_LIBRARY(libO2CCDB)
20+
R__LOAD_LIBRARY(libO2DataFormatsFIT)
21+
22+
#include "CommonUtils/ConfigurableParamHelper.h"
23+
#include "DataFormatsFIT/LookUpTable.h"
24+
#include "CCDB/CcdbApi.h"
25+
#include "CCDB/CCDBTimeStampUtils.h"
26+
#include "Framework/Logger.h"
27+
#include "CommonConstants/LHCConstants.h"
28+
29+
void saveToCSV(const std::vector<o2::fit::EntryFEE>& lut, string_view path);
30+
void saveToRoot(std::shared_ptr<std::vector<o2::fit::EntryFEE>> lut, string_view path);
31+
32+
void fetchLUT(const std::string ccdbUrl, const std::string detector, long timestamp = -1, const std::string fileName = "", bool asCsv = true)
33+
{
34+
o2::ccdb::CcdbApi ccdbApi;
35+
ccdbApi.init(ccdbUrl);
36+
const std::string ccdbPath = detector + "/Config/LookupTable";
37+
std::map<std::string, std::string> metadata;
38+
39+
if(timestamp == -1){
40+
timestamp = o2::ccdb::getCurrentTimestamp();
41+
}
42+
43+
std::shared_ptr<std::vector<o2::fit::EntryFEE>> lut(ccdbApi.retrieveFromTFileAny<std::vector<o2::fit::EntryFEE>>(ccdbPath, metadata, timestamp));
44+
45+
if (!lut) {
46+
LOGP(error, "LUT object not found in {}/{} for timestamp {}.", ccdbUrl, ccdbPath, timestamp);
47+
return;
48+
} else {
49+
LOGP(info, "Successfully fetched LUT for {} from {}", detector, ccdbUrl);
50+
}
51+
52+
std::cout << detector << " lookup table: " << std::endl;
53+
for(const auto& entry: (*lut)) {
54+
std::cout << entry << std::endl;
55+
}
56+
57+
if(fileName.empty()) {
58+
return;
59+
}
60+
61+
if(asCsv) {
62+
saveToCSV(*lut, fileName);
63+
} else {
64+
saveToRoot(lut, fileName);
65+
}
66+
}
67+
68+
69+
void saveToCSV(const std::vector<o2::fit::EntryFEE>& lut, string_view path)
70+
{
71+
std::ofstream ofs(path.data());
72+
if (!ofs.is_open()) {
73+
LOGP(error, "Cannot open file for writing: {}", path);
74+
return;
75+
}
76+
ofs << "LinkID,EndPointID,CRUID,FEEID,ModuleType,LocalChannelID,channel #,Module,HV board,HV channel,MCP S/N,HV cable,signal cable\n";
77+
for (const auto& entry : lut) {
78+
ofs << entry.mEntryCRU.mLinkID << ","
79+
<< entry.mEntryCRU.mEndPointID << ","
80+
<< entry.mEntryCRU.mCRUID << ","
81+
<< entry.mEntryCRU.mFEEID << ","
82+
<< entry.mModuleType << ","
83+
<< entry.mLocalChannelID << ","
84+
<< entry.mChannelID << ","
85+
<< entry.mModuleName << ","
86+
<< entry.mBoardHV << ","
87+
<< entry.mChannelHV << ","
88+
<< entry.mSerialNumberMCP << ","
89+
<< entry.mCableHV << ","
90+
<< entry.mCableSignal << "\n";
91+
}
92+
ofs.close();
93+
}
94+
95+
void saveToRoot(std::shared_ptr<std::vector<o2::fit::EntryFEE>> lut, string_view path)
96+
{
97+
TFile file(path.data(), "RECREATE");
98+
if(file.IsOpen() == false) {
99+
LOGP(fatal, "Failed to open file {}", path.data());
100+
}
101+
102+
file.WriteObject(lut.get(), "LookupTable");
103+
file.Close();
104+
}

0 commit comments

Comments
 (0)