diff --git a/Detectors/FIT/macros/CMakeLists.txt b/Detectors/FIT/macros/CMakeLists.txt index a6bf1799a5dde..8460187815e81 100644 --- a/Detectors/FIT/macros/CMakeLists.txt +++ b/Detectors/FIT/macros/CMakeLists.txt @@ -49,5 +49,27 @@ o2_add_test_root_macro(readAlignParam.C PUBLIC_LINK_LIBRARIES O2::CCDB LABELS fit) +o2_add_test_root_macro(compareLut.C + PUBLIC_LINK_LIBRARIES O2::DataFormatsFIT + LABELS fit) + +o2_add_test_root_macro(createLutFromCsv.C + PUBLIC_LINK_LIBRARIES O2::DataFormatsFIT + O2::CommonUtils + LABELS fit) + +o2_add_test_root_macro(fetchLut.C + PUBLIC_LINK_LIBRARIES O2::DataFormatsFIT + O2::CCDB + LABELS fit) + +o2_add_test_root_macro(convertLutToCsv.C + PUBLIC_LINK_LIBRARIES O2::DataFormatsFIT + LABELS fit) + +o2_add_test_root_macro(printLut.C + PUBLIC_LINK_LIBRARIES O2::DataFormatsFIT + LABELS fit) + o2_data_file(COPY readFITDCSdata.C DESTINATION Detectors/FIT/macros/) o2_data_file(COPY readFITDeadChannelMap.C DESTINATION Detectors/FIT/macros/) \ No newline at end of file diff --git a/Detectors/FIT/macros/compareLut.C b/Detectors/FIT/macros/compareLut.C new file mode 100644 index 0000000000000..9c6062c05f5bd --- /dev/null +++ b/Detectors/FIT/macros/compareLut.C @@ -0,0 +1,110 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include + +R__LOAD_LIBRARY(libO2CommonUtils) +R__LOAD_LIBRARY(libO2DataFormatsFIT) + +#include "CommonUtils/ConfigurableParamHelper.h" +#include "DataFormatsFIT/LookUpTable.h" +#include "Framework/Logger.h" +#include "CommonConstants/LHCConstants.h" +#include "lut.h" + +#endif + +namespace compare_lut +{ +std::vector readLutFromFile(const std::string filePath, const std::string objectName) +{ + TFile file(filePath.c_str(), "READ"); + if (file.IsOpen() == false) { + std::cerr << "Failed to open " << filePath << std::endl; + return {}; + } + std::cout << "Successfully opened " << std::endl + << filePath; + + std::vector* lut = nullptr; + file.GetObject>(objectName.c_str(), lut); + + if (lut == nullptr) { + std::cerr << "Failed to read object " << objectName << std::endl; + return {}; + } + std::cout << "Successfully get " << objectName << " object" << std::endl; + + std::vector lutCopy = *lut; + file.Close(); + + return std::move(lutCopy); +} +} // namespace compare_lut + +inline bool operator==(const o2::fit::EntryFEE& lhs, const o2::fit::EntryFEE& rhs) +{ + auto comparer = [](const o2::fit::EntryFEE& e) { + return std::tie( + e.mEntryCRU.mLinkID, e.mEntryCRU.mEndPointID, e.mEntryCRU.mCRUID, e.mEntryCRU.mFEEID, + e.mChannelID, e.mLocalChannelID, e.mModuleType, e.mModuleName, + e.mBoardHV, e.mChannelHV, e.mSerialNumberMCP, e.mCableHV, e.mCableSignal); + }; + return comparer(lhs) == comparer(rhs); +} + +void compareLut(const std::string fileA, const std::string fileB, const bool compareEvenForDifferentSize = false, const std::string objectName = "ccdb_object") +{ + std::vector lutA = compare_lut::readLutFromFile(fileA, objectName); + std::vector lutB = compare_lut::readLutFromFile(fileB, objectName); + if (lutA.empty() || lutB.empty()) { + return; + } + + bool lutAreSame = true; + + if (lutA.size() != lutB.size()) { + std::cerr << "Different number of entries: " << lutA.size() << " for " << fileA << " vs " << lutB.size() << " for file " << fileB.c_str() << std::endl; + lutAreSame = false; + if (compareEvenForDifferentSize == false) { + return; + } + } + + size_t size = (lutA.size() < lutB.size()) ? lutA.size() : lutB.size(); + + std::cout << "--- Comparision ---" << std::endl; + + for (size_t idx = 0; idx < size; idx++) { + if (lutA[idx] == lutB[idx]) { + continue; + } else { + std::cout << "Entry " << idx << " in " << fileA << " entry: " << lutA[idx] << std::endl; + std::cout << "Entry " << idx << " in " << fileB << " entry: " << lutB[idx] << std::endl; + lutAreSame = false; + } + } + + for (size_t idx = size; idx < lutA.size(); idx++) { + std::cout << "Extra entry " << idx << " in " << fileA << ": " << lutA[idx] << std::endl; + } + + for (size_t idx = size; idx < lutB.size(); idx++) { + std::cout << "Extra entry " << idx << " in " << fileB << ": " << lutB[idx] << std::endl; + } + + if (lutAreSame) { + std::cout << "LUTs are the same!" << std::endl; + } else { + std::cout << "LUTs are different!" << std::endl; + } +} diff --git a/Detectors/FIT/macros/convertLutToCsv.C b/Detectors/FIT/macros/convertLutToCsv.C new file mode 100644 index 0000000000000..a8fdc79bb4b09 --- /dev/null +++ b/Detectors/FIT/macros/convertLutToCsv.C @@ -0,0 +1,88 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include +#include + +R__LOAD_LIBRARY(libO2CommonUtils) +R__LOAD_LIBRARY(libO2DataFormatsFIT) + +#include "CommonUtils/ConfigurableParamHelper.h" +#include "DataFormatsFIT/LookUpTable.h" +#include "Framework/Logger.h" +#include "CommonConstants/LHCConstants.h" +#include "lut.h" + +#endif + +namespace convert_lut_to_csv +{ +std::vector readLutFromFile(const std::string filePath, const std::string objectName) +{ + TFile file(filePath.c_str(), "READ"); + if (file.IsOpen() == false) { + std::cerr << "Failed to open " << filePath << std::endl; + return {}; + } + std::cout << "Successfully opened " << std::endl + << filePath; + + std::vector* lut = nullptr; + file.GetObject>(objectName.c_str(), lut); + + if (lut == nullptr) { + std::cerr << "Failed to read object " << objectName << std::endl; + return {}; + } + std::cout << "Successfully get " << objectName << " object" << std::endl; + + std::vector lutCopy = *lut; + file.Close(); + + return std::move(lutCopy); +} +} // namespace convert_lut_to_csv + +void saveToCSV(const std::vector& lut, const std::string& path) +{ + std::ofstream ofs(path.data()); + if (!ofs.is_open()) { + std::cerr << "Cannot open file for writing: " << path << std::endl; + return; + } + ofs << "LinkID,EndPointID,CRUID,FEEID,ModuleType,LocalChannelID,channel #,Module,HV board,HV channel,MCP S/N,HV cable,signal cable\n"; + for (const auto& entry : lut) { + ofs << entry.mEntryCRU.mLinkID << "," + << entry.mEntryCRU.mEndPointID << "," + << entry.mEntryCRU.mCRUID << "," + << entry.mEntryCRU.mFEEID << "," + << entry.mModuleType << "," + << entry.mLocalChannelID << "," + << entry.mChannelID << "," + << entry.mModuleName << "," + << entry.mBoardHV << "," + << entry.mChannelHV << "," + << entry.mSerialNumberMCP << "," + << entry.mCableHV << "," + << entry.mCableSignal << "\n"; + } + ofs.close(); +} + +void convertLutToCsv(const std::string fileName, const std::string objectName, const std::string csvName) +{ + if (fileName.empty() || objectName.empty() || csvName.empty()) { + return; + } + std::vector lut = convert_lut_to_csv::readLutFromFile(fileName, objectName); + saveToCSV(lut, csvName); +} \ No newline at end of file diff --git a/Detectors/FIT/macros/createLutFromCsv.C b/Detectors/FIT/macros/createLutFromCsv.C new file mode 100644 index 0000000000000..204965efaaa18 --- /dev/null +++ b/Detectors/FIT/macros/createLutFromCsv.C @@ -0,0 +1,93 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include +#include + +R__LOAD_LIBRARY(libO2CommonUtils) +R__LOAD_LIBRARY(libO2CCDB) +R__LOAD_LIBRARY(libO2DataFormatsFIT) + +#include "DataFormatsFIT/LookUpTable.h" +#include "Framework/Logger.h" +#include "CommonConstants/LHCConstants.h" +#endif + +namespace create_lut_from_csv +{ +void saveToRoot(std::vector& lut, const std::string& path) +{ + TFile file(path.data(), "RECREATE"); + if (file.IsOpen() == false) { + std::cerr << "Failed to open file " << path << std::endl; + return; + } + + file.WriteObject(&lut, "ccdb_object"); + file.Close(); +} +} // namespace create_lut_from_csv + +void createLutFromCsv(const std::string csvFilePath, const std::string rootFilePath) +{ + std::vector lut; + std::ifstream lutCSV(csvFilePath); + if (lutCSV.is_open() == false) { + std::cerr << "Failed to open file " << csvFilePath << std::endl; + return; + } + + std::string line; + std::getline(lutCSV, line); + std::map headerMap; + + auto headersView = std::string_view(line) | std::views::split(','); + + int index = 0; + for (auto&& rng : headersView) { + std::string columnName(rng.begin(), rng.end()); + headerMap[columnName] = index++; + } + + while (std::getline(lutCSV, line)) { + if (line.size() == 0) { + return; + } + o2::fit::EntryFEE entry; + auto fieldViews = std::string_view(line) | std::views::split(','); + std::vector parsedLine; + for (auto&& view : fieldViews) { + parsedLine.emplace_back(view.begin(), view.end()); + } + if (parsedLine.size() < headerMap.size()) { + std::cerr << "Ill-formed line: " << line << std::endl; + return; + } + + entry.mEntryCRU.mLinkID = std::stoi(parsedLine[headerMap.at("LinkID")]); + entry.mEntryCRU.mEndPointID = std::stoi(parsedLine[headerMap.at("EndPointID")]); + entry.mEntryCRU.mCRUID = std::stoi(parsedLine[headerMap.at("CRUID")]); + entry.mEntryCRU.mFEEID = std::stoi(parsedLine[headerMap.at("FEEID")]); + + entry.mModuleType = parsedLine[headerMap.at("ModuleType")]; + entry.mLocalChannelID = parsedLine[headerMap.at("LocalChannelID")]; + entry.mChannelID = parsedLine[headerMap.at("channel #")]; + entry.mModuleName = parsedLine[headerMap.at("Module")]; + entry.mBoardHV = parsedLine[headerMap.at("HV board")]; + entry.mChannelHV = parsedLine[headerMap.at("HV channel")]; + entry.mSerialNumberMCP = parsedLine[headerMap.at("MCP S/N")]; + entry.mCableHV = parsedLine[headerMap.at("HV cable")]; + entry.mCableSignal = parsedLine[headerMap.at("signal cable")]; + lut.emplace_back(entry); + } + create_lut_from_csv::saveToRoot(lut, rootFilePath); +} \ No newline at end of file diff --git a/Detectors/FIT/macros/fetchLut.C b/Detectors/FIT/macros/fetchLut.C new file mode 100644 index 0000000000000..33a923308a89d --- /dev/null +++ b/Detectors/FIT/macros/fetchLut.C @@ -0,0 +1,73 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include +#include + +R__LOAD_LIBRARY(libO2CommonUtils) +R__LOAD_LIBRARY(libO2CCDB) +R__LOAD_LIBRARY(libO2DataFormatsFIT) + +#include "CommonUtils/ConfigurableParamHelper.h" +#include "DataFormatsFIT/LookUpTable.h" +#include "CCDB/CcdbApi.h" +#include "CCDB/CCDBTimeStampUtils.h" +#include "Framework/Logger.h" +#include "CommonConstants/LHCConstants.h" + +#endif + +namespace +{ +void saveToRoot(std::shared_ptr> lut, const std::string& path) +{ + TFile file(path.data(), "RECREATE"); + if (file.IsOpen() == false) { + std::cerr << "Failed to open file " << path << std::endl; + } + + file.WriteObject(lut.get(), "ccdb_object"); + file.Close(); +} + +void _fetchLut(const std::string ccdbUrl = "alice-ccdb.cern.ch", const std::string detector = "FT0", long timestamp = -1, const std::string fileName = "o2_lut.root") +{ + o2::ccdb::CcdbApi ccdbApi; + ccdbApi.init(ccdbUrl); + const std::string ccdbPath = detector + "/Config/LookupTable"; + std::map metadata; + + if (timestamp == -1) { + timestamp = o2::ccdb::getCurrentTimestamp(); + } + + std::shared_ptr> lut(ccdbApi.retrieveFromTFileAny>(ccdbPath, metadata, timestamp)); + + if (!lut) { + std::cerr << "LUT object not found in " << ccdbUrl << "/" << ccdbPath << " for timestamp " << timestamp << std::endl; + return; + } else { + std::cout << "Successfully fetched LUT for " << detector << " from " << ccdbUrl << std::endl; + } + + if (fileName.empty()) { + return; + } + + saveToRoot(lut, fileName); +} +} // namespace + +void fetchLut(const std::string ccdbUrl = "alice-ccdb.cern.ch", const std::string detector = "FT0", long timestamp = -1, const std::string fileName = "o2_lut.root") +{ + _fetchLut(ccdbUrl, detector, timestamp, fileName); +} \ No newline at end of file diff --git a/Detectors/FIT/macros/printLut.C b/Detectors/FIT/macros/printLut.C new file mode 100644 index 0000000000000..9d56a594eb910 --- /dev/null +++ b/Detectors/FIT/macros/printLut.C @@ -0,0 +1,62 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#if !defined(__CLING__) || defined(__ROOTCLING__) +#include +#include + +R__LOAD_LIBRARY(libO2CommonUtils) +R__LOAD_LIBRARY(libO2DataFormatsFIT) + +#include "CommonUtils/ConfigurableParamHelper.h" +#include "DataFormatsFIT/LookUpTable.h" +#include "Framework/Logger.h" +#include "CommonConstants/LHCConstants.h" +#endif + +namespace print_lut +{ +std::vector readLutFromFile(const std::string filePath, const std::string objectName) +{ + TFile file(filePath.c_str(), "READ"); + if (file.IsOpen() == false) { + std::cerr << "Failed to open " << filePath << std::endl; + return {}; + } + std::cout << "Successfully opened " << std::endl + << filePath; + + std::vector* lut = nullptr; + file.GetObject>(objectName.c_str(), lut); + + if (lut == nullptr) { + std::cerr << "Failed to read object " << objectName << std::endl; + return {}; + } + std::cout << "Successfully get " << objectName << " object" << std::endl; + + std::vector lutCopy = *lut; + file.Close(); + + return std::move(lutCopy); +} +} // namespace print_lut + +void printLut(const std::string fileName, const std::string objectName = "ccdb_object") +{ + std::vector lut = print_lut::readLutFromFile(fileName, objectName); + const size_t size = lut.size(); + + std::cout << "--- Lookup table ---" << std::endl; + + for (size_t idx = 0; idx < size; idx++) { + std::cout << lut[idx] << std::endl; + } +} \ No newline at end of file