diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bb9eacf7713affc03f3f02ab2dd92c2473c98ca..941dc0a2de8649cc6046d168ebb3c3d1dafe57ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.15) -project(Vetra VERSION 2.0 +project(Vetra VERSION 4.5 LANGUAGES CXX) # Definition of path for ut diff --git a/UTEmuAlgorithms/CMakeLists.txt b/UTEmuAlgorithms/CMakeLists.txt index 12c3ac170734f16b9c7ee1cebdc1bc61058d3e9f..a3c65cd521b2b4bc9258f6c94516d79a661d3dcf 100644 --- a/UTEmuAlgorithms/CMakeLists.txt +++ b/UTEmuAlgorithms/CMakeLists.txt @@ -16,12 +16,15 @@ VP/VPEmu gaudi_add_library(UTEmuLib SOURCES src/UTEmuRawDataMonitorAlgorithm.cpp + src/UTEmuStepMonitorAlgorithm.cpp src/UTEmuTrimDAC.cpp src/UTEmuPedestalCalculator.cpp + src/UTEmuPedestalCalculatorStep.cpp src/UTEmuPedestalSubtractor.cpp src/UTEmuPedestalCalculatorDataMonitorAlgorithm.cpp src/UTEmuPedestalSubtractorDataMonitorAlgorithm.cpp - src/UTEmuCommonModeSubtractor.cpp + src/UTEmuCommonModeSubtractor.cpp + src/UTEmuPulseShape.cpp LINK PUBLIC Gaudi::GaudiKernel diff --git a/UTEmuAlgorithms/include/UTEmu/UTEmuPedestalCalculator.h b/UTEmuAlgorithms/include/UTEmu/UTEmuPedestalCalculator.h index 924a9b4713634bd8e5acc02d6d60a9dc3e01159c..e527165987179d6e174f8ba4879e1a26ca624488 100644 --- a/UTEmuAlgorithms/include/UTEmu/UTEmuPedestalCalculator.h +++ b/UTEmuAlgorithms/include/UTEmu/UTEmuPedestalCalculator.h @@ -61,6 +61,7 @@ namespace UTEmu { void calculatePedestals(); void findBadChannels(); void saveThresholdsToCsv(); + void saveDisabledToCsv(); // properties Gaudi::Property<std::string> m_runNumber{ this, "RunNumber", "00000000" }; @@ -70,7 +71,7 @@ namespace UTEmu { mutable std::map<std::string, int> Pedestal_Max; mutable std::map<std::string, Gaudi::Accumulators::SigmaCounter<>> SigmaNoiseAv; mutable std::map<std::string, Gaudi::Accumulators::SigmaCounter<>> PedestalAv; - + mutable std::vector<std::string> disabledASICs; mutable std::map<unsigned int, bool> BadChannels; diff --git a/UTEmuAlgorithms/include/UTEmu/UTEmuPedestalCalculatorStep.h b/UTEmuAlgorithms/include/UTEmu/UTEmuPedestalCalculatorStep.h new file mode 100644 index 0000000000000000000000000000000000000000..50672c1bb09080f36865d593c353e4ac26f227f5 --- /dev/null +++ b/UTEmuAlgorithms/include/UTEmu/UTEmuPedestalCalculatorStep.h @@ -0,0 +1,79 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ + +/* + * UTEmuPedestalCalculatorStep.h + * + * Created on: August, 2023 + * Author: Wojciech Krupa (wokrupa@cern.ch) + */ + +#pragma once +#include "Event/ODIN.h" +#include "Event/UTDigit.h" +#include "Kernel/IEventCounter.h" +#include "Kernel/IUTReadoutTool.h" +#include "Kernel/UTDAQBoard.h" +#include "Kernel/UTDAQDefinitions.h" +#include "Kernel/UTDAQID.h" +#include "LHCbAlgs/Consumer.h" +#include "UTDAQ/UTADCWord.h" +#include "UTDAQ/UTCoordinatesMap.h" +#include "UTDAQ/UTHeaderWord.h" +#include "UTEmu/UTEmuVetraHelper.h" +#include "TCanvas.h" +#include "TFile.h" +#include "TH1D.h" +#include "TH2D.h" +#include "TKey.h" +#include <fstream> +#include <map> +#include <math.h> + +using namespace LHCb; + +namespace UTEmu { + + class PedestalCalculatorStep : public LHCb::Algorithm::Consumer<void( const LHCb::ODIN& ), + LHCb::DetDesc::usesBaseAndConditions<GaudiHistoAlg>> { + public: + PedestalCalculatorStep( const std::string& name, // algorithm instance name + ISvcLocator* pSvcLocator ) // service locator + : Consumer{ name, + pSvcLocator, + { { "ODINLocation", LHCb::ODINLocation::Default } } } {} + + StatusCode initialize() override; + StatusCode finalize() override; + void operator()( const LHCb::ODIN& ) const override; + + void savePedestalsToCsv(); + void saveBadChannelsToCsv(); + void saveSigmaNoiseToCsv(); + void calculatePedestals(); + void findBadChannels(); + void saveThresholdsToCsv(); + + // properties + Gaudi::Property<std::string> m_runNumber{ this, "RunNumber", "00000000" }; + mutable std::map<std::string, Gaudi::Accumulators::Histogram<2>> m_2d_ADCCounter; + mutable std::map<unsigned int, float> Pedestal; + mutable std::map<unsigned int, float> SigmaNoise; + mutable std::map<std::string, int> Pedestal_Max; + mutable std::map<std::string, Gaudi::Accumulators::SigmaCounter<>> SigmaNoiseAv; + mutable std::map<std::string, Gaudi::Accumulators::SigmaCounter<>> PedestalAv; + + mutable std::map<unsigned int, bool> BadChannels; + UTCoordinatesMap UTMap; + + private: + }; +} // namespace UTEmu \ No newline at end of file diff --git a/UTEmuAlgorithms/include/UTEmu/UTEmuPulseShape.h b/UTEmuAlgorithms/include/UTEmu/UTEmuPulseShape.h new file mode 100644 index 0000000000000000000000000000000000000000..0dcc352728ca793aed78a7912530f83d5cba95a9 --- /dev/null +++ b/UTEmuAlgorithms/include/UTEmu/UTEmuPulseShape.h @@ -0,0 +1,61 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ + +/* + * UTEmuPulseShape.h + * + * Created on: August, 2023 + * Author: Wojciech Krupa (wokrupa@cern.ch) + */ + +#pragma once + +#include "Event/ODIN.h" +#include "Event/UTDigit.h" +#include "GaudiAlg/GaudiTupleAlg.h" +#include "GaudiKernel/IEventProcessor.h" +#include "Kernel/IEventCounter.h" +#include "Kernel/IUTReadoutTool.h" +#include "Kernel/UTDAQID.h" +#include "LHCbAlgs/Consumer.h" +#include "UTDAQ/UTCoordinatesMap.h" +#include "UTDet/DeUTDetector.h" +#include "UTEmu/UTEmuVetraHelper.h" + +using namespace LHCb; + +namespace UTEmu { + + class PulseShape + : public LHCb::Algorithm::Consumer<void( UTDigits const&, const LHCb::ODIN&, DeUTDetector const& ), + LHCb::DetDesc::usesBaseAndConditions<GaudiHistoAlg, DeUTDetector>> { + public: + /// constructer + PulseShape( const std::string& name, ISvcLocator* svcloc ) + : Consumer{ name, + svcloc, + { { "DigitLocation", UTEmu::UTDigitLocation::UTDigits }, + { "ODINLocation", LHCb::ODINLocation::Default }, + { "UTLocation", DeUTDetLocation::location() } } } {} + + StatusCode initialize() override; + void operator()( const UTDigits&, const LHCb::ODIN&, DeUTDetector const& ) const override; + + mutable UTCoordinatesMap UTMap; + + mutable std::map<std::string, Gaudi::Accumulators::Histogram<2>> m_2d_ch; + + Gaudi::Property<unsigned int> m_layer{ this, "Layer", 0 }; + + private: + void fillHistograms( const LHCb::UTDigit*, DeUTDetector const&, const LHCb::ODIN& ) const; + }; +} // namespace UTEmu \ No newline at end of file diff --git a/UTEmuAlgorithms/include/UTEmu/UTEmuStepMonitorAlgorithm.h b/UTEmuAlgorithms/include/UTEmu/UTEmuStepMonitorAlgorithm.h new file mode 100644 index 0000000000000000000000000000000000000000..5c80c6425973f7f2028a7a369c9bddfefa6db3da --- /dev/null +++ b/UTEmuAlgorithms/include/UTEmu/UTEmuStepMonitorAlgorithm.h @@ -0,0 +1,65 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ + +/* + * UTEmuStepMonitorAlgorithm.h + * + * Created on: October, 2024 + * Author: Wojciech Krupa (wokrupa@cern.ch) + */ + +#pragma once + +#include "Event/ODIN.h" +#include "Event/UTDigit.h" +#include "GaudiAlg/GaudiTupleAlg.h" +#include "GaudiKernel/IEventProcessor.h" +#include "Kernel/IEventCounter.h" +#include "Kernel/IUTReadoutTool.h" +#include "Kernel/UTDAQID.h" +#include "LHCbAlgs/Consumer.h" +#include "UTDAQ/UTCoordinatesMap.h" +#include "UTDet/DeUTDetector.h" +#include "UTEmu/UTEmuVetraHelper.h" + +using namespace LHCb; + +namespace UTEmu { + + class StepMonitorAlgorithm + : public LHCb::Algorithm::Consumer<void( UTDigits const&, const LHCb::ODIN&, + std::vector<std::pair<unsigned int, int>> const&, DeUTDetector const& ), + LHCb::DetDesc::usesBaseAndConditions<GaudiHistoAlg, DeUTDetector>> { + public: + /// constructer + StepMonitorAlgorithm( const std::string& name, ISvcLocator* svcloc ) + : Consumer{ name, + svcloc, + { { "DigitLocation", UTEmu::UTDigitLocation::UTDigits }, + { "ODINLocation", LHCb::ODINLocation::Default }, + { "InputBankData", UTEmu::UTDigitLocation::UTBanks }, + { "UTLocation", DeUTDetLocation::location() } } } {} + + ToolHandle<IUTReadoutTool> readoutTool{ this, "ReadoutTool", "UTReadoutTool" }; + Gaudi::Property<float> m_events{ this, "Events", 100 }; + Gaudi::Property<float> m_steps{ this, "Steps", 100 }; + + StatusCode initialize() override; + void operator()( const UTDigits&, const LHCb::ODIN&, const std::vector<std::pair<unsigned int, int>>&, + DeUTDetector const& ) const override; + + mutable UTCoordinatesMap UTMap; + + mutable std::map<std::string, Gaudi::Accumulators::Histogram<2>> m_2d_ADCCounter; + private: + void fillHistograms( const LHCb::UTDigit*, DeUTDetector const&, const LHCb::ODIN& ) const; + }; +} // namespace UTEmu \ No newline at end of file diff --git a/UTEmuAlgorithms/src/UTEmuCommonModeSubtractor.cpp b/UTEmuAlgorithms/src/UTEmuCommonModeSubtractor.cpp index 8f3da68fc2dcc0aead2dc4422c1da0e338b58bad..8014a4c3372548bfc7b33eae9fe82a0e4f2cb47a 100644 --- a/UTEmuAlgorithms/src/UTEmuCommonModeSubtractor.cpp +++ b/UTEmuAlgorithms/src/UTEmuCommonModeSubtractor.cpp @@ -60,7 +60,7 @@ void CommonModeSubtractor::makeCMSNoisePlots() const { auto module_y = std::get<1>( tuple ); std::string module_name = std::get<4>( tuple ); std::string type = std::get<5>( tuple ); - if ( type == "D" ) type = "C"; + if ( type == "D" ) type = "C"; //C & D goes together // CMSNoise 1D plots mean auto title_CMSNoise = "CMSNoiseMean_" + UTEmu::UT_layers[channelID.layer()] + "_" + module_name; diff --git a/UTEmuAlgorithms/src/UTEmuPedestalCalculator.cpp b/UTEmuAlgorithms/src/UTEmuPedestalCalculator.cpp index c4ef9fe5ee5a0f006d01fa80c0135294577e67aa..61a5f003dc8f42b10e5edfec0bc7800fdc07abf0 100644 --- a/UTEmuAlgorithms/src/UTEmuPedestalCalculator.cpp +++ b/UTEmuAlgorithms/src/UTEmuPedestalCalculator.cpp @@ -45,10 +45,19 @@ void PedestalCalculator::calculatePedestals() { // Description of method: read 2D histogram and after removing outliers from the projection for each bin (channel) get // the mu. + for ( const auto& module : UTMap.getModulesNames() ) { TH2D* hist2D = dynamic_cast<TH2D*>( f2->Get( module.c_str() ) ); if ( hist2D ) { + + for ( int asic = 0; asic < UTEmu::UTNumbers::nASICs; ++asic ) { + int start_bin = asic * UTEmu::UTNumbers::nStripsPerASIC + 1; // ROOT bins start at 1 + int end_bin = ( asic + 1 ) * UTEmu::UTNumbers::nStripsPerASIC; + + TH1D* projection = hist2D->ProjectionY( "Projection", start_bin, end_bin, "" ); + if ( projection->GetEntries() == 0 ) { disabledASICs.push_back( module + ".Chip" + std::to_string( asic ) ); } + } for ( unsigned int bin = 1; bin <= hist2D->GetNbinsX(); bin++ ) { TH1D* projection = hist2D->ProjectionY( "Projection", bin, bin, "" ); @@ -78,7 +87,6 @@ void PedestalCalculator::calculatePedestals() { delete projection; } - } else { info() << "Very serious Problem" << endmsg; } @@ -129,14 +137,23 @@ void PedestalCalculator::saveThresholdsToCsv() { fout.open( input_path.c_str(), std::ios::out | std::ios::trunc ); for ( const auto& sigmaNoise : SigmaNoiseAv ) { - float zs_th = std::ceil( 5 * sigmaNoise.second.mean() ); - if ( zs_th == 3 ) zs_th = 4; // this is very temporary + float zs_th = std::ceil( 5 * sigmaNoise.second.mean() ) - 1; // Tomasz optimistic version fout << sigmaNoise.first << ", " << zs_th << "\n"; } - info() << "Saving zs_threshold file" << endmsg; }; +void PedestalCalculator::saveDisabledToCsv() { + + std::fstream fout; + + std::string input_path = std::string( UTEMU_PATH ) + "/disabled_" + m_runNumber + ".csv"; + fout.open( input_path.c_str(), std::ios::out | std::ios::trunc ); + + for ( const auto& asic : disabledASICs ) { fout << asic << "\n"; } + info() << "Saving disabled asics file" << endmsg; +}; + void PedestalCalculator::savePedestalsToCsv() { // file pointer @@ -157,7 +174,9 @@ void PedestalCalculator::saveSigmaNoiseToCsv() { std::string input_path = std::string( UTEMU_PATH ) + "/sigmaNoise_" + m_runNumber + ".csv"; fout.open( input_path.c_str(), std::ios::out | std::ios::trunc ); - for ( const auto& sigmaNoise : SigmaNoise ) { fout << sigmaNoise.first << ", " << sigmaNoise.second << "\n"; } + for ( const auto& sigmaNoise : SigmaNoise ) { + fout << sigmaNoise.first << ", " << Pedestal[sigmaNoise.first] << ", " << sigmaNoise.second << "\n"; + } info() << "Saving sigma of sigmaNoise file" << endmsg; }; @@ -170,5 +189,7 @@ StatusCode PedestalCalculator::finalize() { findBadChannels(); saveBadChannelsToCsv(); saveThresholdsToCsv(); + saveDisabledToCsv(); + return StatusCode::SUCCESS; } diff --git a/UTEmuAlgorithms/src/UTEmuPedestalCalculatorDataMonitorAlgorithm.cpp b/UTEmuAlgorithms/src/UTEmuPedestalCalculatorDataMonitorAlgorithm.cpp index c291ea3a31d30505e79967085c82aa586d40286f..c9e6ef6ac07f4a43a3041404f9224597bc1db6d7 100644 --- a/UTEmuAlgorithms/src/UTEmuPedestalCalculatorDataMonitorAlgorithm.cpp +++ b/UTEmuAlgorithms/src/UTEmuPedestalCalculatorDataMonitorAlgorithm.cpp @@ -45,8 +45,8 @@ StatusCode PedestalCalculatorDataMonitorAlgorithm::makePedestalsPlots() { if ( type == "D" ) type = "C"; // Pedestal 1D plots - auto title_pedestal = "Pedestals_" + UTEmu::UT_layers[channelID.layer()] + "_" + module_name; - auto title_pedestal_ = "Pedestals_" + UTEmu::UT_layers[channelID.layer()] + "_" + module_name + ";Channel;ADC"; + auto title_pedestal = "MeanADC_" + UTEmu::UT_layers[channelID.layer()] + "_" + module_name; + auto title_pedestal_ = "MeanADC_" + UTEmu::UT_layers[channelID.layer()] + "_" + module_name + ";Channel;ADC"; plot1D( channelID.strip(), title_pedestal, title_pedestal_, 0, UTEmu::UTNumbers::nStrips, UTEmu::UTNumbers::nStrips, pedestal.second ); @@ -56,10 +56,10 @@ StatusCode PedestalCalculatorDataMonitorAlgorithm::makePedestalsPlots() { Pedestal_Av.at( current_asic_name ) += pedestal.second; - plot1D( pedestal.second, "Projection_Pedestal", "Projection_Pedestal", -31, 31, 62 ); - if(type == "A") plot1D( pedestal.second, "Projection_Pedestal_A", "Projection_Pedestal_A", -31, 31, 62 ); - if(type == "B") plot1D( pedestal.second, "Projection_Pedestal_B", "Projection_Pedestal_B", -31, 31, 62 ); - if(type == "C") plot1D( pedestal.second, "Projection_Pedestal_C", "Projection_Pedestal_C", -31, 31, 62 ); + plot1D( pedestal.second, "Projection_MeanADC", "Projection_MeanADC", -31, 31, 62 ); + if(type == "A") plot1D( pedestal.second, "Projection_MeanADC_A", "Projection_MeanADC_A", -31, 31, 62 ); + if(type == "B") plot1D( pedestal.second, "Projection_MeanADC_B", "Projection_MeanADC_B", -31, 31, 62 ); + if(type == "C") plot1D( pedestal.second, "Projection_MeanADC_C", "Projection_MeanADC_C", -31, 31, 62 ); }; @@ -82,7 +82,7 @@ StatusCode PedestalCalculatorDataMonitorAlgorithm::makePedestalsPlots() { if ( type == "D" ) type = "C"; - auto title_layer = "PedestalAverage_" + UTEmu::UT_layers[channelID.layer()]; + auto title_layer = "MeanADCAverage_" + UTEmu::UT_layers[channelID.layer()]; // Let's include mirroring! Probably it could be done better if ( ( channelID.face() == 1 && y < 0 && x < 0 ) || ( channelID.face() == 0 && y > 0 && x < 0 ) || @@ -245,7 +245,7 @@ StatusCode PedestalCalculatorDataMonitorAlgorithm::initialize() { for ( unsigned int i = 0; i < UTEmu::UTNumbers::nASICs; i++ ) { auto chip_name = module + "_" + std::to_string( i ); - auto title = "PedestalAv_" + chip_name; + auto title = "MeanADCAv_" + chip_name; vector_emplace( Pedestal_Av, chip_name, this, title ); title = "SigmaNoiseAv_" + chip_name; vector_emplace( SigmaNoise_Av, chip_name, this, title ); @@ -291,6 +291,8 @@ StatusCode PedestalCalculatorDataMonitorAlgorithm::getSigmaNoise() { unsigned int channelID = atof( line.substr( 0, line.find( delimiter ) ).c_str() ); line.erase( 0, line.find( delimiter ) + 1 ); + auto pedestal = atof( line.c_str() ); + line.erase( 0, line.find( delimiter ) + 1 ); auto noise_sigma = atof( line.c_str() ); SigmaNoise[channelID] = noise_sigma; } diff --git a/UTEmuAlgorithms/src/UTEmuPedestalCalculatorStep.cpp b/UTEmuAlgorithms/src/UTEmuPedestalCalculatorStep.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b0391d55773e95725264149d24f21c66b1cccedd --- /dev/null +++ b/UTEmuAlgorithms/src/UTEmuPedestalCalculatorStep.cpp @@ -0,0 +1,183 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ + +/* + * UTEmuPedestalCalculatorStep.cpp + * + * Created on: August, 2023 + * Author: Wojciech Krupa (wokrupa@cern.ch) + */ + +#include "UTEmu/UTEmuPedestalCalculatorStep.h" + +using namespace LHCb; +using namespace UTEmu; + +StatusCode PedestalCalculatorStep::initialize() { return StatusCode::SUCCESS; } + +void PedestalCalculatorStep::operator()( const LHCb::ODIN& odin ) const {} + +void PedestalCalculatorStep::calculatePedestals() { + + TFile* f1 = + TFile::Open( ( std::string( UTEMU_PATH ) + "/ut_step_nzs_" + std::string( m_runNumber ) + ".root" ).c_str() ); + + if ( !f1 ) { + std::cerr << "Error: ut_step_nzs.root file does not exist." << std::endl; + exit( -1 ); + } + static TString classname_th2( "TH2D" ); + + TDirectory* f2 = (TDirectory*)f1->Get( "UTStepMonitor" ); + + if ( f2 == nullptr ) { + std::cerr << "Error: UTStepMonitor directory not found in the file." << std::endl; + exit( -1 ); + } + + // Description of method: read 2D histogram and after removing outliers from the projection for each bin (channel) get + // the mu. + for ( const auto& module : UTMap.getModulesNames() ) { + for ( unsigned int step = 0; step < 100; step++ ) { + TH2D* hist2D = dynamic_cast<TH2D*>( f2->Get( ( module + ".Step" + std::to_string( step ) ).c_str() ) ); + if ( hist2D ) { + debug() << module << " " << std::to_string( step ) << endmsg; + + for ( unsigned int bin = 1; bin <= hist2D->GetNbinsX(); bin++ ) { + + TH1D* projection = hist2D->ProjectionY( "Projection", bin, bin, "" ); + float mean = projection->GetMean(); + float rms = projection->GetRMS(); + + // Filter out outliers + for ( Int_t bin = 1; bin <= projection->GetNbinsX(); ++bin ) { + if ( TMath::Abs( projection->GetBinCenter( bin ) - mean ) > 3 * rms ) { + projection->SetBinContent( bin, 0 ); + } + } + + int channel = UTMap.getChannel( module ) + ( bin - 1 ); + + if ( step == 0 ) { + Pedestal[channel] = projection->GetMean(); + SigmaNoise[channel] = projection->GetRMS(); + } + + // Detector::UT::ChannelID channelID( UTMap.getChannel( module ) + ( bin - 1 ) ); + // This code finds maximum pedestal in the direction of pulse + if ( ( ( module.find( "W" ) != std::string::npos ) ) || ( ( module.find( "E" ) != std::string::npos ) ) ) { + if ( Pedestal[channel] < projection->GetMean() ) Pedestal[channel] = projection->GetMean(); + if ( SigmaNoise[channel] < projection->GetRMS() ) SigmaNoise[channel] = projection->GetRMS(); + } else { + if ( Pedestal[channel] > projection->GetMean() ) Pedestal[channel] = projection->GetMean(); + if ( SigmaNoise[channel] > projection->GetRMS() ) SigmaNoise[channel] = projection->GetRMS(); + } + + delete projection; + } + + } else { + // info() << "Very serious Problem" << endmsg; + } + delete hist2D; + } + } +} + +void PedestalCalculatorStep::findBadChannels() { + + // bad channels + for ( const auto& ped : Pedestal ) { + + Detector::UT::ChannelID channelID( ped.first ); + + auto tuple = + UTMap.getTuple( channelID.module(), channelID.face(), channelID.stave(), channelID.side(), channelID.sector() ); + + std::string module_name = std::get<4>( tuple ); + + std::string current_asic_name = UTEmu::UT_layers[channelID.layer()] + "_" + module_name + "_" + + std::to_string( int( channelID.strip() / UTEmu::UTNumbers::nStripsPerASIC ) ); + + float zs_th = std::ceil( 4.5 * SigmaNoiseAv[current_asic_name].mean() ); + if ( std::round( std::abs( ped.second ) ) > zs_th ) + BadChannels[ped.first] = 1; + else + BadChannels[ped.first] = 0; + } +} + +void PedestalCalculatorStep::saveBadChannelsToCsv() { + + // file pointer + std::fstream fout; + + // opens an existing csv file or creates a new file. + std::string input_path = std::string( UTEMU_PATH ) + "/above_thresholds_" + m_runNumber + ".csv"; + fout.open( input_path.c_str(), std::ios::out | std::ios::trunc ); + + for ( const auto& channel : BadChannels ) { fout << channel.first << ", " << channel.second << "\n"; }; + info() << "Saving channels above threshold file" << endmsg; +} + +void PedestalCalculatorStep::saveThresholdsToCsv() { + + std::fstream fout; + + std::string input_path = std::string( UTEMU_PATH ) + "/zs_th_mcms_" + m_runNumber + ".csv"; + fout.open( input_path.c_str(), std::ios::out | std::ios::trunc ); + + for ( const auto& sigmaNoise : SigmaNoiseAv ) { + float zs_th = std::ceil( 5 * sigmaNoise.second.mean() ) - 1; // Tomasz optimistic version + fout << sigmaNoise.first << ", " << zs_th << "\n"; + } + info() << "Saving zs_threshold file" << endmsg; +}; + + +void PedestalCalculatorStep::savePedestalsToCsv() { + + // file pointer + std::fstream fout; + + // opens an existing csv file or creates a new file. + std::string input_path = std::string( UTEMU_PATH ) + "/pedestals_" + m_runNumber + ".csv"; + fout.open( input_path.c_str(), std::ios::out | std::ios::trunc ); + + for ( const auto& ped : Pedestal ) { fout << ped.first << ", " << std::round( ped.second ) << "\n"; }; + info() << "Saving pedestal file" << endmsg; +} + +void PedestalCalculatorStep::saveSigmaNoiseToCsv() { + + std::fstream fout; + + std::string input_path = std::string( UTEMU_PATH ) + "/sigmaNoise_" + m_runNumber + ".csv"; + fout.open( input_path.c_str(), std::ios::out | std::ios::trunc ); + + for ( const auto& sigmaNoise : SigmaNoise ) { + fout << sigmaNoise.first << ", " << Pedestal[sigmaNoise.first] << ", " << sigmaNoise.second << "\n"; + } + + info() << "Saving sigma of sigmaNoise file" << endmsg; +}; + +StatusCode PedestalCalculatorStep::finalize() { + + calculatePedestals(); + savePedestalsToCsv(); + saveSigmaNoiseToCsv(); + findBadChannels(); + saveBadChannelsToCsv(); + saveThresholdsToCsv(); + + return StatusCode::SUCCESS; +} diff --git a/UTEmuAlgorithms/src/UTEmuPulseShape.cpp b/UTEmuAlgorithms/src/UTEmuPulseShape.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a71a9bdc5faa78d11327a3371dd0bb9d5a5ebdf9 --- /dev/null +++ b/UTEmuAlgorithms/src/UTEmuPulseShape.cpp @@ -0,0 +1,61 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ + +/* + * UTEmuPulseShape.cpp + * + * Created on: August, 2023 + * Author: Wojciech Krupa (wokrupa@cern.ch) + */ + +#include "UTEmu/UTEmuPulseShape.h" + +using namespace LHCb; +using namespace UTEmu; + +StatusCode PulseShape::initialize() { + return Consumer::initialize().andThen( [&] { + for ( const auto& module : UTMap.getModulesNames() ) { + for ( unsigned int i = 0; i < 512; i++ ) { + auto title = module + ".Chip" + std::to_string( i / 128 ) + ".Ch" + std::to_string( i % 128 ); + if ( title.find( UTEmu::UT_layers[m_layer] ) != std::string::npos ) { + Utility::map_emplace( m_2d_ch, title, 0, this, title, { 128, 0, 128 }, { 64, -32.5, 31.5 } ); + } + } + } + return StatusCode::SUCCESS; + } ); +} + +void PulseShape::operator()( const UTDigits& digitsCont, const LHCb::ODIN& odin, DeUTDetector const& det ) const { + + // fill histos for each digit + for ( const auto& d : digitsCont ) fillHistograms( d, det, odin ); +} + +void PulseShape::fillHistograms( const LHCb::UTDigit* aDigit, DeUTDetector const&, const LHCb::ODIN& odin ) const { + + auto tuple = UTMap.getTuple( aDigit->module(), aDigit->face(), aDigit->stave(), aDigit->side(), aDigit->sector() ); + + auto x = std::get<0>( tuple ); + auto y = std::get<1>( tuple ); + std::string module_name = std::get<4>( tuple ); + std::string type = std::get<5>( tuple ); + if ( type == "D" ) type = "C"; + + Detector::UT::ChannelID channelID = aDigit->channelID(); + + auto title_charge = UTEmu::UT_layers[aDigit->layer()] + "_" + module_name + ".Chip" + + std::to_string( aDigit->strip() / 128 ) + ".Ch" + std::to_string( aDigit->strip() % 128 ); + if ( title_charge.find( UTEmu::UT_layers[m_layer] ) != std::string::npos ) { + ++m_2d_ch.at( title_charge )[{ odin.calibrationStep(), aDigit->depositedCharge() }]; + } +} diff --git a/UTEmuAlgorithms/src/UTEmuStepMonitorAlgorithm.cpp b/UTEmuAlgorithms/src/UTEmuStepMonitorAlgorithm.cpp new file mode 100644 index 0000000000000000000000000000000000000000..196bc6c4e9dc97ae4c1d868e818d86b039355265 --- /dev/null +++ b/UTEmuAlgorithms/src/UTEmuStepMonitorAlgorithm.cpp @@ -0,0 +1,83 @@ +/*****************************************************************************\ +* (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration * +* * +* This software is distributed under the terms of the GNU General Public * +* Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". * +* * +* In applying this licence, 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. * +\*****************************************************************************/ + +/* + * UTEmuStepMonitorAlgorithm.cpp + * + * Created on: October, 2024 + * Author: Wojciech Krupa (wokrupa@cern.ch) + */ + +#include "UTEmu/UTEmuStepMonitorAlgorithm.h" + +using namespace LHCb; +using namespace UTEmu; + +StatusCode StepMonitorAlgorithm::initialize() { + + return Consumer::initialize().andThen( [&] { + for ( const auto& module : UTMap.getModulesNames() ) { + for ( unsigned int i = 0; i < m_steps; i++ ) { + auto title = module + ".Step" + std::to_string( i ); + Utility::map_emplace( m_2d_ADCCounter, title, 0, this, title, { 512, 0, 512 }, { 64, -32.5, 31.5 } ); + } + } + return StatusCode::SUCCESS; + } ); +} + +void StepMonitorAlgorithm::operator()( const UTDigits& digitsCont, const LHCb::ODIN& odin, + const std::vector<std::pair<unsigned int, int>>& bank_types, + DeUTDetector const& det ) const { + + // fill histos for each digit + for ( const auto& d : digitsCont ) fillHistograms( d, det, odin ); +} + +void StepMonitorAlgorithm::fillHistograms( const LHCb::UTDigit* aDigit, DeUTDetector const&, + const LHCb::ODIN& odin ) const { + + // aDigit (channelID) .stave() / module() = software side + + // Let's see where we are + auto tuple = UTMap.getTuple( aDigit->module(), aDigit->face(), aDigit->stave(), aDigit->side(), aDigit->sector() ); + auto x = std::get<0>( tuple ); + auto y = std::get<1>( tuple ); + std::string module_name = std::get<4>( tuple ); + std::string type = std::get<5>( tuple ); + if ( type == "D" ) type = "C"; + + unsigned int asic = aDigit->asic() % UTEmu::UTNumbers::nASICs; + + Detector::UT::ChannelID channelID = aDigit->channelID(); + UTDAQID daqID = readoutTool->channelIDToDAQID( channelID ); + auto board_ID = daqID.board(); + + // Digits occupancy plots + if ( aDigit->strip() == 0 ) { + debug() << " Stave: " << aDigit->stave() << " Side: " << aDigit->side() << " Module: " << aDigit->module() + << " Sector: " << aDigit->sector() << " Face: " << aDigit->face() << " Module name: " << module_name << " " + << "Type: " << type << " Stave_x: " << x << " Module_y: " << y << endmsg; + } + + auto title_layer = "Occupancy_" + UTEmu::UT_layers[aDigit->layer()]; + + // Let's include mirroring! Probably it could be done better + if ( ( aDigit->face() == 1 && y < 0 && x < 0 ) || ( aDigit->face() == 0 && y > 0 && x < 0 ) || + ( aDigit->face() == 0 && y < 0 && x > 0 ) || ( aDigit->face() == 1 && y > 0 && x > 0 ) ) + asic = ( 3 - asic ) % 4; + + // Raw ADC vs channel + auto title_charge = UTEmu::UT_layers[aDigit->layer()] + "_" + module_name + ".Step" + std::to_string( odin.calibrationStep() ); + auto title_charge_ = UTEmu::UT_layers[aDigit->layer()] + "_" + module_name + ".Step" + std::to_string( odin.calibrationStep() ); ";Channel;ADC"; + + ++m_2d_ADCCounter.at( title_charge )[{ aDigit->strip(), aDigit->depositedCharge() }]; +} diff --git a/UTEmuAlgorithms/src/modules.cpp b/UTEmuAlgorithms/src/modules.cpp index d085d4f614d09957db9fc4332bc9f09d467f9283..ed963f70767e298b69b3942af75c3fdda8b3632f 100644 --- a/UTEmuAlgorithms/src/modules.cpp +++ b/UTEmuAlgorithms/src/modules.cpp @@ -11,16 +11,22 @@ #include <UTEmu/UTEmuCommonModeSubtractor.h> #include <UTEmu/UTEmuPedestalCalculator.h> +#include <UTEmu/UTEmuPedestalCalculatorStep.h> #include <UTEmu/UTEmuPedestalCalculatorDataMonitorAlgorithm.h> #include <UTEmu/UTEmuPedestalSubtractor.h> #include <UTEmu/UTEmuPedestalSubtractorDataMonitorAlgorithm.h> #include <UTEmu/UTEmuRawDataMonitorAlgorithm.h> +#include <UTEmu/UTEmuStepMonitorAlgorithm.h> #include <UTEmu/UTEmuTrimDAC.h> +#include <UTEmu/UTEmuPulseShape.h> DECLARE_COMPONENT( UTEmu::RawDataMonitorAlgorithm ) +DECLARE_COMPONENT( UTEmu::StepMonitorAlgorithm ) DECLARE_COMPONENT( UTEmu::TrimDACAlgorithm ) DECLARE_COMPONENT( UTEmu::PedestalCalculator ) +DECLARE_COMPONENT( UTEmu::PedestalCalculatorStep ) DECLARE_COMPONENT( UTEmu::PedestalSubtractor ) DECLARE_COMPONENT( UTEmu::PedestalCalculatorDataMonitorAlgorithm ) DECLARE_COMPONENT( UTEmu::PedestalSubtractorDataMonitorAlgorithm ) DECLARE_COMPONENT( UTEmu::CommonModeSubtractor ) +DECLARE_COMPONENT( UTEmu::PulseShape ) diff --git a/UTEmuOptions/options/UT_Emulation_NoiseComponents.py b/UTEmuOptions/options/UT_Emulation_NoiseComponents.py index 861b0802989a0c10cb753e1b576a9f1c38899508..f95cabbd0dd97345ab2c1f3d312c565484167a2d 100644 --- a/UTEmuOptions/options/UT_Emulation_NoiseComponents.py +++ b/UTEmuOptions/options/UT_Emulation_NoiseComponents.py @@ -58,8 +58,7 @@ EventSelector().PrintFreq = 100 # ------------------------------------------------------------------------------- # Setup input ------------------------------------------------------------- - -run_number = "0000297288" +run_number = "0000310462" input_path = '/hlt2/objects/UT/' + run_number + '/' data = [] @@ -76,7 +75,7 @@ IOHelper("MDF").inputFiles(data) # Multithreading ------------------------------------------------------------- # ------------------------------------------------------------------------------- -evtslots = 12 +evtslots = 12 threads = 10 # Event Loop Manager ----------------------------------------------------------- diff --git a/UTEmuOptions/options/UT_PedestalCalculation.py b/UTEmuOptions/options/UT_PedestalCalculation.py index 48369a3f34aef8f11db339d4d3608cfd01554916..e03adfbc3748f239ee2b243def449d65d392e5e8 100644 --- a/UTEmuOptions/options/UT_PedestalCalculation.py +++ b/UTEmuOptions/options/UT_PedestalCalculation.py @@ -58,9 +58,8 @@ EventSelector().PrintFreq = 1 # ------------------------------------------------------------------------------- # Setup input ------------------------------------------------------------- -run_number = "0000297288" +run_number = "0000310465" input_path = '/hlt2/objects/UT/' + run_number + '/' - # Algorithms ---------------------------------------------------------- # Declare the algorithms we want to run. We set the output level to INFO @@ -76,7 +75,7 @@ unpacker = LHCb__UnpackRawEvent( odin = createODIN(RawBanks="DAQ/RawBanks/ODIN") pedestals = UTEmu__PedestalCalculator( - 'UTDigitsToPedestals', OutputLevel=DEBUG, RunNumber = run_number) + 'UTDigitsToPedestals', OutputLevel=INFO, RunNumber = run_number) monSeq.Members = [unpacker, odin, iovProd, pedestals] diff --git a/UTEmuOptions/options/UT_PedestalCalculationStep.py b/UTEmuOptions/options/UT_PedestalCalculationStep.py new file mode 100644 index 0000000000000000000000000000000000000000..0f29f655efbcef9e576d75a7695840fe47e03673 --- /dev/null +++ b/UTEmuOptions/options/UT_PedestalCalculationStep.py @@ -0,0 +1,105 @@ +############################################################################### +# (c) Copyright 2020 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organizatiodn # +# or submit itself to any jurisdiction. # +############################################################################### + +import sys, os, glob +from Gaudi.Configuration import MessageSvc, VERBOSE, DEBUG, INFO, ERROR, WARNING +from Gaudi.Configuration import ApplicationMgr +from Configurables import LHCbApp,GaudiSequencer +from Configurables import LoKiSvc +from Configurables import AlgResourcePool, CPUCrunchSvc, HiveSlimEventLoopMgr, HiveWhiteBoard, AvalancheSchedulerSvc +from Configurables import UTRawBankToUTNZSDigitsAlg, UTEmu__PedestalCalculatorStep, UTEmu__PedestalCalculatorDataMonitorAlgorithm +from Configurables import Gaudi__Histograming__Sink__Root as RootHistoSink +from Configurables import Gaudi__Monitoring__MessageSvcSink as MessageSvcSink +from Configurables import LHCb__Det__LbDD4hep__IOVProducer as IOVProducer +from Configurables import createODIN, LHCb__UnpackRawEvent, EventSelector +from Configurables import LHCbTimingAuditor, LHCbSequencerTimerTool, TimingAuditor, AuditorSvc, SequencerTimerTool +from GaudiConf import IOHelper +from DDDB.CheckDD4Hep import UseDD4Hep + +# ------------------------------------------------------------------------------- +app = LHCbApp() +app.DataType = "Upgrade" +app.Simulation = False +app.EvtMax = 1 + +# ------------------------------------------------------------------------------- +# DD4hep ------------------------------------------------------------- + +if UseDD4Hep: + # Prepare detector description + from Configurables import LHCb__Det__LbDD4hep__DD4hepSvc as DD4hepSvc + dd4hepsvc = DD4hepSvc() + dd4hepsvc.VerboseLevel = 1 + dd4hepsvc.GeometryLocation = "${DETECTOR_PROJECT_ROOT}/compact" + dd4hepsvc.GeometryVersion = "run3/trunk" + dd4hepsvc.GeometryMain = "LHCb.xml" + dd4hepsvc.DetectorList = ["/world", "UT"] + iovProd = IOVProducer("ReserveIOVDD4hep", ODIN='DAQ/ODIN') + +else: + # DetDesc case + LHCbApp().DataType = "Upgrade" + LHCbApp().DDDBtag = 'upgrade/UTv4r2-newUTID' + LHCbApp().CondDBtag = "master" + LHCbApp().Simulation = False + iovProd = IOVProducer() + +LoKiSvc().Welcome = False +MessageSvc().OutputLevel = INFO +EventSelector().PrintFreq = 1 + +# ------------------------------------------------------------------------------- +# Setup input ------------------------------------------------------------- +run_number = "0000309677" +input_path = '/hlt2/objects/UT/' + run_number + '/' +# Algorithms ---------------------------------------------------------- +# Declare the algorithms we want to run. We set the output level to INFO + +monSeq = GaudiSequencer("UTSequence") +monSeq.IgnoreFilterPassed = True + +unpacker = LHCb__UnpackRawEvent( + 'UnpackRawEvent', + BankTypes=['ODIN'], + RawBankLocations=['/Event/DAQ/RawBanks/ODIN' + ]) + +odin = createODIN(RawBanks="DAQ/RawBanks/ODIN") + +pedestals = UTEmu__PedestalCalculatorStep( + 'UTDigitsToPedestals', OutputLevel=INFO, RunNumber = run_number) + +monSeq.Members = [unpacker, odin, iovProd, pedestals] + +# Application Manager ---------------------------------------------------------- +# We put everything together and change the type of message service + +appMgr = ApplicationMgr( + EvtMax=-1, + TopAlg=[monSeq], + ExtSvc=[ + MessageSvcSink(), + #RootHistoSink(FileName="./Vetra/ut_data_pedestals_"+run_number+".root"), + ], +) + +# Some extra stuff for timing table +ApplicationMgr().ExtSvc += ['ToolSvc', 'AuditorSvc'] +ApplicationMgr().AuditAlgorithms = True +AuditorSvc().Auditors += ['TimingAuditor'] +SequencerTimerTool().OutputLevel = 4 + +# No error messages when reading MDF +#IODataManager().DisablePFNWarning = True + + + + diff --git a/UTEmuOptions/options/UT_PedestalMonitoring.py b/UTEmuOptions/options/UT_PedestalMonitoring.py index 12da0a59a705ab999d65a8a079171af9df96fd3c..cadbdd9b4422bf42edeb9588946851b0c00b7672 100644 --- a/UTEmuOptions/options/UT_PedestalMonitoring.py +++ b/UTEmuOptions/options/UT_PedestalMonitoring.py @@ -59,7 +59,7 @@ EventSelector().PrintFreq = 100 # ------------------------------------------------------------------------------- # Setup input ------------------------------------------------------------- -run_number = "0000297288" +run_number = "0000310462" input_path = '/hlt2/objects/UT/' + run_number + '/' data = [] @@ -117,7 +117,7 @@ odin = createODIN(RawBanks="DAQ/RawBanks/ODIN") decoder = UTRawBankToUTNZSDigitsAlg("UTRawToDigits", OutputLevel=INFO, Type="", OutputDigitData = '/Event/UT/Digits', OutputBankData = '/Event/UT/Banks') -pedestal_monitor = UTEmu__PedestalCalculatorDataMonitorAlgorithm('UTPedestalMonitor', RunNumber = run_number, OutputLevel=INFO) +pedestal_monitor = UTEmu__PedestalCalculatorDataMonitorAlgorithm('UTMeanADCMonitor', RunNumber = run_number, OutputLevel=INFO) monSeq.Members = [unpacker, odin, iovProd, decoder, pedestal_monitor] diff --git a/UTEmuOptions/options/UT_PedestalSubtraction.py b/UTEmuOptions/options/UT_PedestalSubtraction.py index d0166f7c775d4b5b04ffea7b46c1ede88494d292..134a8482378ec21bd04a982ecd9e7b6c282f9723 100644 --- a/UTEmuOptions/options/UT_PedestalSubtraction.py +++ b/UTEmuOptions/options/UT_PedestalSubtraction.py @@ -60,7 +60,7 @@ EventSelector().PrintFreq = 100 # ------------------------------------------------------------------------------- # Setup input ------------------------------------------------------------- -run_number = "0000297288" +run_number = "0000310462" input_path = '/hlt2/objects/UT/' + run_number + '/' data = [] diff --git a/UTEmuOptions/options/UT_PulseShape.py b/UTEmuOptions/options/UT_PulseShape.py new file mode 100644 index 0000000000000000000000000000000000000000..1fc2992e7da1a66b2350642897cac6e6f0810ef9 --- /dev/null +++ b/UTEmuOptions/options/UT_PulseShape.py @@ -0,0 +1,149 @@ +############################################################################### +# (c) Copyright 2020 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organizatiodn # +# or submit itself to any jurisdiction. # +############################################################################### + + +import sys, os, glob +from Gaudi.Configuration import MessageSvc, VERBOSE, DEBUG, INFO, ERROR, WARNING +from Gaudi.Configuration import ApplicationMgr +from Configurables import LHCbApp,GaudiSequencer +from Configurables import LoKiSvc +from Configurables import AlgResourcePool, CPUCrunchSvc, HiveSlimEventLoopMgr, HiveWhiteBoard, AvalancheSchedulerSvc +from Configurables import UTEmu__PulseShape, UTRawBankToUTNZSDigitsAlg +from Configurables import Gaudi__Histograming__Sink__Root as RootHistoSink +from Configurables import Gaudi__Monitoring__MessageSvcSink as MessageSvcSink +from Configurables import LHCb__Det__LbDD4hep__IOVProducer as IOVProducer +from Configurables import createODIN, LHCb__UnpackRawEvent, EventSelector +from Configurables import LHCbTimingAuditor, LHCbSequencerTimerTool, TimingAuditor, AuditorSvc, SequencerTimerTool +from GaudiConf import IOHelper +from DDDB.CheckDD4Hep import UseDD4Hep + +# ------------------------------------------------------------------------------- +app = LHCbApp() +app.DataType = "Upgrade" +app.Simulation = False +app.EvtMax = -1 +# ----------------------------------------------------------------------------- +# DD4hep ------------------------------------------------------------- + +if UseDD4Hep: + # Prepare detector description + from Configurables import LHCb__Det__LbDD4hep__DD4hepSvc as DD4hepSvc + dd4hepsvc = DD4hepSvc() + dd4hepsvc.VerboseLevel = 1 + dd4hepsvc.GeometryLocation = "${DETECTOR_PROJECT_ROOT}/compact" + dd4hepsvc.GeometryVersion = "run3/trunk" + dd4hepsvc.GeometryMain = "LHCb.xml" + dd4hepsvc.DetectorList = ["/world", "UT"] + iovProd = IOVProducer("ReserveIOVDD4hep", ODIN='DAQ/ODIN') + +else: + # DetDesc case + LHCbApp().DataType = "Upgrade" + LHCbApp().DDDBtag = 'upgrade/UTv4r2-newUTID' + LHCbApp().CondDBtag = "master" + LHCbApp().Simulation = False + iovProd = IOVProducer() + +LoKiSvc().Welcome = False +MessageSvc().OutputLevel = INFO +EventSelector().PrintFreq = 100 + +# ------------------------------------------------------------------------------- +# Setup input ------------------------------------------------------------- +run_number = "0000307556" +input_path = '/swdev/wokrupa/DATA/CalibRuns/' + run_number + '/' + + +data = [] +if os.path.exists(input_path): + data = glob.glob('/' + input_path + '*.mdf') +else: + print("Input directory doesn't exist!") + sys.exit() +if data == []: + print("Input data doesn't exist!") + sys.exit() + +IOHelper("MDF").inputFiles(data) + +# Multithreading ------------------------------------------------------------- +# ----------------------------------------------------------------------------- +evtslots = 7 +threads = 6 + +# Event Loop Manager ----------------------------------------------------------- +# It's called slim since it has less functionalities overall than the good-old +# event loop manager. Here we just set its outputlevel to DEBUG. + +whiteboard = HiveWhiteBoard("EventDataSvc", EventSlots=evtslots) +slimeventloopmgr = HiveSlimEventLoopMgr( + SchedulerName="AvalancheSchedulerSvc", OutputLevel=INFO +) + +# ForwardScheduler ------------------------------------------------------------- +# We just decide how many algorithms in flight we want to have and how many +# threads in the pool. The default value is -1, which is for TBB equivalent +# to take over the whole machine. + +scheduler = AvalancheSchedulerSvc(ThreadPoolSize=threads, OutputLevel=INFO) + +# Algo Resource Pool ----------------------------------------------------------- +# Nothing special here, we just set the debug level. +AlgResourcePool(OutputLevel=INFO) + +CPUCrunchSvc(shortCalib=True) + +# Algorithms ---------------------------------------------------------- +# Declare the algorithms we want to run. We set the output level to INFO + +monSeq = GaudiSequencer("UTSequence") +monSeq.IgnoreFilterPassed = True + +unpacker = LHCb__UnpackRawEvent( + 'UnpackRawEvent', + BankTypes=['ODIN'], + RawBankLocations=['/Event/DAQ/RawBanks/ODIN' + ]) + +odin = createODIN(RawBanks="DAQ/RawBanks/ODIN") + +decoder = UTRawBankToUTNZSDigitsAlg("UTRawToDigits", OutputLevel=INFO, Type="", OutputDigitData = '/Event/UT/Digits', OutputBankData = '/Event/UT/Banks') + +#0-4 +layer = 3 +pulse = UTEmu__PulseShape( + "UTPulseShape", OutputLevel=INFO, Layer = layer) + +monSeq.Members = [unpacker, odin, iovProd, decoder, pulse] + +# Application Manager ---------------------------------------------------------- +# We put everything together and change the type of message service + +appMgr = ApplicationMgr( + EvtMax=-1, + TopAlg=[monSeq], + HistogramPersistency="ROOT", + EventLoop=slimeventloopmgr, + ExtSvc=[ + MessageSvcSink(), + whiteboard, + RootHistoSink(FileName="./Vetra/ut_data_pulse_"+run_number+"_Layer"+str(layer)+".root"), + ], +) + +# Some extra stuff for timing table +ApplicationMgr().ExtSvc += ['ToolSvc', 'AuditorSvc'] +ApplicationMgr().AuditAlgorithms = True +AuditorSvc().Auditors += ['TimingAuditor'] +SequencerTimerTool().OutputLevel = 4 + +# No error messages when reading MDF +#IODataManager().DisablePFNWarning = True diff --git a/UTEmuOptions/options/UT_RawADC_Run.py b/UTEmuOptions/options/UT_RawADC_Run.py index 9005cfc38fe579fe8bc0415faf82ee699ff6b772..82b7c37d0a202cb9478e2f939cdf42b75c725979 100644 --- a/UTEmuOptions/options/UT_RawADC_Run.py +++ b/UTEmuOptions/options/UT_RawADC_Run.py @@ -26,11 +26,11 @@ from GaudiConf import IOHelper from DDDB.CheckDD4Hep import UseDD4Hep # ------------------------------------------------------------------------------- -app = LHCbApp() +app = LHCbApp() app.DataType = "Upgrade" app.Simulation = False -app.EvtMax = 1000 -# ------------------------------------------------------------------------------- +app.EvtMax = 10000 +# ----------------------------------------------------------------------------- # DD4hep ------------------------------------------------------------- if UseDD4Hep: @@ -58,8 +58,8 @@ EventSelector().PrintFreq = 100 # ------------------------------------------------------------------------------- # Setup input ------------------------------------------------------------- -run_number = "0000299973" -input_path = '/group/ut/ONLINE/DATA/' + run_number + '/' +run_number = "0000310465" +input_path = '/hlt2/objects/UT/' + run_number + '/' data = [] if os.path.exists(input_path): @@ -114,10 +114,10 @@ unpacker = LHCb__UnpackRawEvent( odin = createODIN(RawBanks="DAQ/RawBanks/ODIN") -decoder = UTRawBankToUTNZSDigitsAlg("UTRawToDigits", OutputLevel=INFO, Type="", OutputDigitData = '/Event/UT/Digits', OutputBankData = '/Event/UT/Banks') +decoder = UTRawBankToUTNZSDigitsAlg("UTRawToDigits", OutputLevel=ERROR, Type="", OutputDigitData = '/Event/UT/Digits', OutputBankData = '/Event/UT/Banks') monitor = UTEmu__RawDataMonitorAlgorithm( - "UTDigitMonitor", OutputLevel=INFO, Events = app.EvtMax) + "UTDigitMonitor", OutputLevel=ERROR, Events = app.EvtMax) monSeq.Members = [unpacker, odin, iovProd, decoder, monitor] diff --git a/UTEmuOptions/options/UT_Step_Run.py b/UTEmuOptions/options/UT_Step_Run.py new file mode 100644 index 0000000000000000000000000000000000000000..a898b477c2df92e3bcc1a0eefe59b144df937c2c --- /dev/null +++ b/UTEmuOptions/options/UT_Step_Run.py @@ -0,0 +1,146 @@ +############################################################################### +# (c) Copyright 2020 CERN for the benefit of the LHCb Collaboration # +# # +# This software is distributed under the terms of the GNU General Public # +# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". # +# # +# In applying this licence, CERN does not waive the privileges and immunities # +# granted to it by virtue of its status as an Intergovernmental Organizatiodn # +# or submit itself to any jurisdiction. # +############################################################################### + + +import sys, os, glob +from Gaudi.Configuration import MessageSvc, VERBOSE, DEBUG, INFO, ERROR, WARNING +from Gaudi.Configuration import ApplicationMgr +from Configurables import LHCbApp,GaudiSequencer +from Configurables import LoKiSvc +from Configurables import AlgResourcePool, CPUCrunchSvc, HiveSlimEventLoopMgr, HiveWhiteBoard, AvalancheSchedulerSvc +from Configurables import UTEmu__StepMonitorAlgorithm, UTRawBankToUTNZSDigitsAlg +from Configurables import Gaudi__Histograming__Sink__Root as RootHistoSink +from Configurables import Gaudi__Monitoring__MessageSvcSink as MessageSvcSink +from Configurables import LHCb__Det__LbDD4hep__IOVProducer as IOVProducer +from Configurables import createODIN, LHCb__UnpackRawEvent, EventSelector +from Configurables import LHCbTimingAuditor, LHCbSequencerTimerTool, TimingAuditor, AuditorSvc, SequencerTimerTool +from GaudiConf import IOHelper +from DDDB.CheckDD4Hep import UseDD4Hep + +# ------------------------------------------------------------------------------- +app = LHCbApp() +app.DataType = "Upgrade" +app.Simulation = False +app.EvtMax = 10000 +# ----------------------------------------------------------------------------- +# DD4hep ------------------------------------------------------------- + +if UseDD4Hep: + # Prepare detector description + from Configurables import LHCb__Det__LbDD4hep__DD4hepSvc as DD4hepSvc + dd4hepsvc = DD4hepSvc() + dd4hepsvc.VerboseLevel = 1 + dd4hepsvc.GeometryLocation = "${DETECTOR_PROJECT_ROOT}/compact" + dd4hepsvc.GeometryVersion = "run3/trunk" + dd4hepsvc.GeometryMain = "LHCb.xml" + dd4hepsvc.DetectorList = ["/world", "UT"] + iovProd = IOVProducer("ReserveIOVDD4hep", ODIN='DAQ/ODIN') + +else: + # DetDesc case + LHCbApp().DataType = "Upgrade" + LHCbApp().DDDBtag = 'upgrade/UTv4r2-newUTID' + LHCbApp().CondDBtag = "master" + LHCbApp().Simulation = False + iovProd = IOVProducer() + +LoKiSvc().Welcome = False +MessageSvc().OutputLevel = INFO +EventSelector().PrintFreq = 100 + +# ------------------------------------------------------------------------------- +# Setup input ------------------------------------------------------------- +run_number = "0000310472" +input_path = '/hlt2/objects/UT/' + run_number + '/' + +data = [] +if os.path.exists(input_path): + data = glob.glob('/' + input_path + '*.mdf') +else: + print("Input directory doesn't exist!") + sys.exit() +if data == []: + print("Input data doesn't exist!") + sys.exit() + +IOHelper("MDF").inputFiles(data) + +# Multithreading ------------------------------------------------------------- +# ----------------------------------------------------------------------------- +evtslots = 6 +threads = 5 + +# Event Loop Manager ----------------------------------------------------------- +# It's called slim since it has less functionalities overall than the good-old +# event loop manager. Here we just set its outputlevel to DEBUG. + +whiteboard = HiveWhiteBoard("EventDataSvc", EventSlots=evtslots) +slimeventloopmgr = HiveSlimEventLoopMgr( + SchedulerName="AvalancheSchedulerSvc", OutputLevel=INFO +) + +# ForwardScheduler ------------------------------------------------------------- +# We just decide how many algorithms in flight we want to have and how many +# threads in the pool. The default value is -1, which is for TBB equivalent +# to take over the whole machine. + +scheduler = AvalancheSchedulerSvc(ThreadPoolSize=threads, OutputLevel=INFO) + +# Algo Resource Pool ----------------------------------------------------------- +# Nothing special here, we just set the debug level. +AlgResourcePool(OutputLevel=INFO) + +CPUCrunchSvc(shortCalib=True) + +# Algorithms ---------------------------------------------------------- +# Declare the algorithms we want to run. We set the output level to INFO + +monSeq = GaudiSequencer("UTSequence") +monSeq.IgnoreFilterPassed = True + +unpacker = LHCb__UnpackRawEvent( + 'UnpackRawEvent', + BankTypes=['ODIN'], + RawBankLocations=['/Event/DAQ/RawBanks/ODIN' + ]) + +odin = createODIN(RawBanks="DAQ/RawBanks/ODIN") + +decoder = UTRawBankToUTNZSDigitsAlg("UTRawToDigits", OutputLevel=ERROR, Type="", OutputDigitData = '/Event/UT/Digits', OutputBankData = '/Event/UT/Banks') + +monitor = UTEmu__StepMonitorAlgorithm( + "UTStepMonitor", OutputLevel=ERROR, Steps = 100, Events = app.EvtMax) + +monSeq.Members = [unpacker, odin, iovProd, decoder, monitor] + +# Application Manager ---------------------------------------------------------- +# We put everything together and change the type of message service + +appMgr = ApplicationMgr( + EvtMax=-1, + TopAlg=[monSeq], + HistogramPersistency="ROOT", + EventLoop=slimeventloopmgr, + ExtSvc=[ + MessageSvcSink(), + whiteboard, + RootHistoSink(FileName="./Vetra/ut_step_nzs_"+run_number+".root"), + ], +) + +# Some extra stuff for timing table +ApplicationMgr().ExtSvc += ['ToolSvc', 'AuditorSvc'] +ApplicationMgr().AuditAlgorithms = True +AuditorSvc().Auditors += ['TimingAuditor'] +SequencerTimerTool().OutputLevel = 4 + +# No error messages when reading MDF +#IODataManager().DisablePFNWarning = True diff --git a/UTEmuOptions/options/UT_trimDAC.py b/UTEmuOptions/options/UT_TrimDAC.py similarity index 100% rename from UTEmuOptions/options/UT_trimDAC.py rename to UTEmuOptions/options/UT_TrimDAC.py diff --git a/UTScripts/BadChannels/UTBadChannels.py b/UTScripts/BadChannels/UTBadChannels.py index ab2478d8341834e73238242ff5bc62b599733d00..0d81c5f607586642d60c45359a71a5c949f966c1 100644 --- a/UTScripts/BadChannels/UTBadChannels.py +++ b/UTScripts/BadChannels/UTBadChannels.py @@ -5,7 +5,7 @@ import re import yaml from collections import OrderedDict -run = "0000294135" +run = "0000307299" # Code to convert channelID to online name + channel strip_mask = 0x1ff @@ -27,6 +27,9 @@ max_side_number = 1 side_names = ("C", "A") layer_names = ("aX", "aU", "bV", "bX") +def remove_duplicates_from_list(lst): + return list(set(lst)) + def get_online_name(aChan): det_type, side, layer, stave, face, module, sector, _ = extract_bits(aChan) assert det_type == det_type_ut @@ -96,77 +99,73 @@ def get_last(t): return t[-1] # import data -data = pd.read_csv("/swdev/wokrupa/stack2/Vetra/CMS_noise_" + run + ".csv") +data = pd.read_csv("/swdev/wokrupa/stack3/Vetra/CMS_noise_" + run + ".csv") columns_name = ['channel_ID', 'mean', 'sigma', 'N'] data.columns = columns_name -data = data[data['N'] > 50] - -# get online name and channel +# Extract online name and channel data['name'] = data['channel_ID'].apply(get_online_name) -m = data['channel_ID'].apply(extract_bits) - -df = pd.DataFrame(m) - -# Calculate last_value from channel_ID -df['last_value'] = df['channel_ID'].apply(get_last) -data['channel'] = df['last_value'] +data['channel'] = data['channel_ID'].apply(extract_bits).apply(get_last) data['chip'] = (data['channel'] // 128).astype(int) -# Compute the mean and std of the noise (sigma) of each chip without outliers -mean_noise = data.groupby(['name', 'chip'])['sigma'].apply( - mean_wo_outliers).reset_index() -std_noise = data.groupby(['name', 'chip'])[ - 'sigma'].apply(compute_ci).reset_index() +# Compute the mean and std of noise (sigma) for each chip without outliers +mean_noise = data.groupby(['name', 'chip'])['sigma'].apply(mean_wo_outliers).reset_index() +std_noise = data.groupby(['name', 'chip'])['sigma'].apply(compute_ci).reset_index() -# Merge dataframes -merged_df2 = pd.merge(data, mean_noise, on=[ - 'name', 'chip'], how='inner', suffixes=('', '_mean')) -merged_df2 = pd.merge(merged_df2, std_noise, on=[ - 'name', 'chip'], how='inner', suffixes=('', '_std')) +# Merge dataframes - calculate mean and std of sigma per chip +merged_df = pd.merge(data, mean_noise, on=['name', 'chip'], suffixes=('', '_mean')) +merged_df = pd.merge(merged_df, std_noise, on=['name', 'chip'], suffixes=('', '_std')) + +#Save all +merged_df.to_csv('all_' + run + '.csv', index=False) # Select noisy channels -condition = (merged_df2['sigma'] > - merged_df2['sigma_mean'] + 10 * merged_df2['sigma_std']) -condition_n = ( - merged_df2['sigma'] < merged_df2['sigma_mean'] - 10 * merged_df2['sigma_std']) -condition0 = (merged_df2['mean'] > 2.5 * merged_df2['sigma']) -condition0_n = (merged_df2['mean'] < -2.5 * merged_df2['sigma']) - -result_df2 = merged_df2.loc[condition | condition_n | - condition0 | condition0_n, ['channel', 'name']] - -# selection of bad channels -condition2 = merged_df2['sigma'] > 2*merged_df2['sigma_mean'] -condition20 = merged_df2['sigma'] < 0.5*merged_df2['sigma_mean'] -result_df = pd.DataFrame({ - 'channel': merged_df2.loc[condition2 | condition20, 'channel'], - 'name': merged_df2.loc[condition2 | condition20, 'name'] -}) - -# Convert the list in the correct format +condition = (merged_df['sigma'] > merged_df['sigma_mean'] + 10 * merged_df['sigma_std']) | \ + (merged_df['sigma'] < merged_df['sigma_mean'] - 10 * merged_df['sigma_std']) | \ + (merged_df['mean'] > 2.5 * merged_df['sigma']) | \ + (merged_df['mean'] < -2.5 * merged_df['sigma']) + +result_df = merged_df.loc[condition, ['channel', 'name']] + +# Select bad channels based on sigma thresholds +condition_high = merged_df['sigma'] > 2 * merged_df['sigma_mean'] +condition_low = merged_df['sigma'] < 0.5 * merged_df['sigma_mean'] + +result_df2 = merged_df.loc[condition_high | condition_low, ['channel', 'name']] + +# Convert the list in the correct format result_df['chip'] = result_df['channel'] // 128 result_df['chip'] = result_df['chip'].astype(int) +# Convert the list in the correct format +result_df2['chip'] = result_df2['channel'] // 128 +result_df2['chip'] = result_df2['chip'].astype(int) + # Group by name and chip, aggregate channels as lists -tot = result_df.groupby(['name', 'chip'])['channel'].agg(list).reset_index() -tot['nBadC'] = tot['channel'].apply(lambda x: [(i % 128) for i in x]) +combined_df = pd.concat([result_df, result_df2], ignore_index=True) -# Print noisy channels -print("Noisy channels") -print(tot) +tot_n = combined_df.groupby(['name', 'chip'])['channel'].agg(list).reset_index() + +tot_n['nBadC'] = tot_n['channel'].apply(lambda x: [(i % 128) for i in x]) # Calculate positions -tot['pos'] = tot['nBadC'].apply(lambda x: [num // 8 for num in x]) +tot_n['pos'] = tot_n['nBadC'].apply(lambda x: [num // 8 for num in x]) +# Verify the lengths are the same +assert all(tot_n['nBadC'].apply(len) == tot_n['pos'].apply(len)), "Mismatch in lengths of 'nBadC' and 'pos'" +# Print noisy channels -# Open a file for writing -file = open('bad_ch_list_' + run + '.txt', 'w') +# Apply the function to the relevant columns +tot_n['nBadC'] = tot_n['nBadC'].apply(remove_duplicates_from_list) +tot_n['pos'] = tot_n['pos'].apply(remove_duplicates_from_list) +tot_n['channel'] = tot_n['channel'].apply(remove_duplicates_from_list) + +print("CMS_based") +print(tot_n) # Tag saturation with pedestal value # Import pedestals -ped = pd.read_csv("/swdev/wokrupa/stack2/Vetra/pedestals_" + run + ".csv") -columns_name_ped = ['channel_ID', 'pedestal'] -ped.columns = columns_name_ped +ped = pd.read_csv("/swdev/wokrupa/stack3/Vetra/pedestals_" + run + ".csv") +ped.columns = ['channel_ID', 'pedestal'] ped['name'] = ped['channel_ID'].apply(get_online_name) m_ped = ped['channel_ID'].apply(extract_bits) @@ -175,69 +174,148 @@ df_ped['last_value'] = df_ped['channel_ID'].apply(lambda x: get_last(x)) ped['channel'] = df_ped['last_value'] ped['chip'] = (ped['channel'] // 128).astype(int) -merged_df_p = pd.merge(merged_df2, ped, on=[ - 'name', 'chip', 'channel_ID', 'channel'], how='inner', suffixes=('', '')) +# Select bad channels based on saturation condition +condition_p = np.abs(ped['pedestal']) > 25 +result_df_p = ped.loc[condition_p, ['channel', 'name']] -# selection of bad channels due to saturation -condition_p = np.abs(merged_df_p['pedestal']) > 25 +# Calculate chip numbers +result_df_p['chip'] = (result_df_p['channel'] // 128).astype(int) -result_df_p = pd.DataFrame({ - 'channel': merged_df_p.loc[condition_p, 'channel'], - 'name': merged_df_p.loc[condition_p, 'name'] -}) +# Group channels by name and chip +tot_p = result_df_p.groupby(['name', 'chip'])['channel'].agg(list).reset_index() -result_df_p['chip'] = result_df_p['channel']/128 -result_df_p['chip'] = result_df_p['chip'].astype(int) - -tot_p = result_df_p.groupby(['name', 'chip'])[ - 'channel'].agg(list).reset_index() +# Calculate positions tot_p['nBadC'] = tot_p['channel'].apply(lambda x: [(i % 128) for i in x]) tot_p['pos'] = tot_p['nBadC'].apply(lambda x: [num // 8 for num in x]) -print("Pedestal") + +# Verify equal lengths +assert all(tot_p['nBadC'].apply(len) == tot_p['pos'].apply(len)), "Mismatch in lengths of 'nBadC' and 'pos'" + +# Apply the function to the relevant columns +tot_p['nBadC'] = tot_p['nBadC'].apply(remove_duplicates_from_list) +tot_p['pos'] = tot_p['pos'].apply(remove_duplicates_from_list) +tot_p['channel'] = tot_p['channel'].apply(remove_duplicates_from_list) + +print("Pedestal_based") print(tot_p) +# Tag disabled channels +# Import total noise not biased by CMS + +# import data +data = pd.read_csv("/swdev/wokrupa/stack3/Vetra/sigmaNoise_" + run + ".csv") +columns_name = ['channel_ID', 'mean', 'sigma'] +data.columns = columns_name + +# Extract online name and channel +data['name'] = data['channel_ID'].apply(get_online_name) +data['channel'] = data['channel_ID'].apply(extract_bits).apply(get_last) +data['chip'] = (data['channel'] // 128).astype(int) + +# Compute the mean and std of noise (sigma) for each chip without outliers +mean_noise = data.groupby(['name', 'chip'])['sigma'].apply(mean_wo_outliers).reset_index() +std_noise = data.groupby(['name', 'chip'])['sigma'].apply(compute_ci).reset_index() + +# Merge dataframes - calculate mean and std of sigma per chip +merged_df = pd.merge(data, mean_noise, on=['name', 'chip'], suffixes=('', '_mean')) +merged_df = pd.merge(merged_df, std_noise, on=['name', 'chip'], suffixes=('', '_std')) + +#Save all +merged_df.to_csv('all2_' + run + '.csv', index=False) + +# Select noisy channels +condition = (merged_df['sigma_mean'] > 0 ) +condition2 = (merged_df['sigma'] == 0 ) + +result_df = merged_df.loc[condition & condition2, ['channel', 'name']] + +# Convert the list in the correct format +result_df['chip'] = result_df['channel'] // 128 +result_df['chip'] = result_df['chip'].astype(int) + +tot_s = result_df.groupby(['name', 'chip'])['channel'].agg(list).reset_index() +tot_s['nBadC'] = tot_s['channel'].apply(lambda x: [(i % 128) for i in x]) + +# Calculate positions +tot_s['pos'] = tot_s['nBadC'].apply(lambda x: [num // 8 for num in x]) + +# Verify the lengths are the same +assert all(tot_s['nBadC'].apply(len) == tot_s['pos'].apply(len)), "Mismatch in lengths of 'nBadC' and 'pos'" + +# Apply the function to the relevant columns +tot_s['nBadC'] = tot_s['nBadC'].apply(remove_duplicates_from_list) +tot_s['pos'] = tot_s['pos'].apply(remove_duplicates_from_list) +tot_s['channel'] = tot_s['channel'].apply(remove_duplicates_from_list) + +print("TotSig_based") +print(tot_s) + # merging bad channels from noise and from pedestal distributions -all_bad_ch = pd.concat([tot, tot_p]) +all_bad_ch = pd.concat([tot_n, tot_p, tot_s]) # Define a function to merge lists def merge_lists(series): - return list(set(x for sublist in series for x in sublist)) - -# Group by 'channel' and 'name' and apply the merge_lists function -result1 = all_bad_ch.groupby(['chip', 'name'])[ - 'nBadC'].agg(merge_lists).reset_index() -result2 = all_bad_ch.groupby(['chip', 'name'])[ - 'pos'].agg(merge_lists).reset_index() -result3 = all_bad_ch.groupby(['chip', 'name'])[ - 'channel'].agg(merge_lists).reset_index() - -final_list = pd.merge(result1, result2, on=['chip', 'name'], how='inner') -final_list = pd.merge(final_list, result3, on=['chip', 'name'], how='inner') + return [x for sublist in series for x in sublist] + +# Group by 'chip' and 'name' and apply the merge_lists function +result1 = all_bad_ch.groupby(['chip', 'name'])['nBadC'].agg(merge_lists).reset_index() +result2 = all_bad_ch.groupby(['chip', 'name'])['pos'].agg(merge_lists).reset_index() +result3 = all_bad_ch.groupby(['chip', 'name'])['channel'].agg(merge_lists).reset_index() + +# Merge the results +final_list = pd.merge(result1, result2, on=['chip', 'name'], how='inner') +final_list = pd.merge(final_list, result3, on=['chip', 'name'], how='inner') + +# Apply the function to the relevant columns +final_list['nBadC'] = final_list['nBadC'].apply(remove_duplicates_from_list) +final_list['channel'] = final_list['channel'].apply(remove_duplicates_from_list) + +#trick to have repetition but only when needed! +final_list['pos'] = final_list['nBadC'].apply(lambda x: [num // 8 for num in x]) + + tot = final_list +print("Total") +print(tot) +tot.to_csv('total_list_1_' + run + '.txt', index=False) + +# Open a file for writing +file = open('bad_ch_list_' + run + '.txt', 'w') + +exclusions = ["UTbV_1AT_S1E.Chip3.Ch104", "UTaU_2AT_M2.Chip3.Ch18", "UTbV_9CT_S3.Chip0.Ch90",] # write the bad channels in the correct format for i in range(len(tot)): - + exc = 1 mask_list = ['0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00'] sum_dict = {} prova = [] mask_dict = {} for val1, val2 in zip(tot.iloc[i]['nBadC'], tot.iloc[i]['pos']): + name = tot.iloc[i]['name'] + ".Chip" + str(tot.iloc[i]['chip']) + ".Ch" + str(val1) + print(name) + if name in exclusions: + exc = 0 + print("Exclusion! ", name) + continue if val2 not in mask_dict: mask_dict[val2] = 0 mask_dict[val2] |= (1 << val1 % 8) - mask_list2 = list(mask_dict.values()) mask = [hex(0x00 | element) for element in mask_list2] - no_rep_pos = list(set(tot.iloc[i]['pos'])) no_rep_pos.sort() - - if tot.iloc[i]['nBadC']: - for jj in range(len(no_rep_pos)): - mask_list[no_rep_pos[jj]] = mask[jj] - line = '--- {}.{} {}\n'.format(tot.iloc[i] - ['name'], tot.iloc[i]['chip'], mask_list) - file.write(line) - + if(exc): + if tot.iloc[i]['nBadC']: + for jj in range(len(no_rep_pos)): + mask_list[no_rep_pos[jj]] = mask[jj] + line = '--- {}.{} {}\n'.format(tot.iloc[i] + ['name'], tot.iloc[i]['chip'], mask_list) + file.write(line) + +# extra stuff for extra studies + +tot_p.to_csv('bad_ch_list_1_' + run + '.txt', index=False) +tot_n.to_csv('bad_ch_list_2_' + run + '.txt', index=False) +tot_s.to_csv('bad_ch_list_3_' + run + '.txt', index=False) diff --git a/UTScripts/BadChannels/UTBadChannels_Wojtek.py b/UTScripts/BadChannels/UTBadChannels_Wojtek.py deleted file mode 100644 index 19d514afa1732efa32a5b334ad6f0d5fb261e1e2..0000000000000000000000000000000000000000 --- a/UTScripts/BadChannels/UTBadChannels_Wojtek.py +++ /dev/null @@ -1,241 +0,0 @@ -import pandas as pd -import numpy as np -import matplotlib.pyplot as plt -import re -import yaml -from collections import OrderedDict - -run = "0000294165" - -# Code to convert channelID to online name + channel -strip_mask = 0x1ff -sector_mask = 0x200 -module_mask = 0x1c00 -face_mask = 0x2000 -stave_mask = 0x3c000 -layer_mask = 0xc0000 -side_mask = 0x100000 -det_type_mask = 0x600000 -det_type_ut = 2 -max_strip_number = 511 -max_sector_number = 1 -max_module_number = 7 -max_face_number = 1 -max_stave_number = 8 -max_layer_number = 3 -max_side_number = 1 -side_names = ("C", "A") -layer_names = ("aX", "aU", "bV", "bX") - -def get_online_name(aChan): - det_type, side, layer, stave, face, module, sector, _ = extract_bits(aChan) - assert det_type == det_type_ut - side_str = side_names[side] - layer_str = layer_names[layer] - stave_str = str(stave + 1) # Convert stave to string - - # Determine module_str - if stave == 0: - if face == 0: - module_str = f"B_S{4 - module}" if module < 4 else f"T_M{module - 3}" - elif face == 1: - module_str = f"B_M{4 - module}" if module < 4 else f"T_S{module - 3}" - else: - if face == 0: - module_str = f"B_S{3 - module}" if module < 4 else f"T_M{module - 3}" - elif face == 1: - module_str = f"B_M{4 - module}" if module < 4 else f"T_S{module - 4}" - - # Determine sector_str - if stave < 2 and face == 0 and 2 <= module < 5: - sector_str = "W" if sector == 0 else "E" - elif stave < 2 and face == 1 and 2 < module <= 5: - sector_str = "W" if sector == 0 else "E" - else: - assert sector == 0 - sector_str = "" - - name = f"UT{layer_str}_{stave_str}{side_str}{module_str}{sector_str}" - return name - -def extract_bits(aChan): - binary_aChan = bin(aChan)[2:] # Convert to binary string - strip = int(binary_aChan, 2) & strip_mask - sector = (int(binary_aChan, 2) & sector_mask) >> 9 - module = (int(binary_aChan, 2) & module_mask) >> 10 - face = (int(binary_aChan, 2) & face_mask) >> 13 - stave = (int(binary_aChan, 2) & stave_mask) >> 14 - layer = (int(binary_aChan, 2) & layer_mask) >> 18 - side = (int(binary_aChan, 2) & side_mask) >> 20 - det_type = (int(binary_aChan, 2) & det_type_mask) >> 21 - return det_type, side, layer, stave, face, module, sector, strip - -def compute_ci(x, confidence=0.68): - intervallo = np.percentile( - x, [100*(1-confidence)/2, 100*(1-(1-confidence)/2)]) - return (intervallo[1] - intervallo[0]) / 2 - - -def compute_min(x, confidence): - intervallo = np.percentile( - x, [100*(1-confidence)/2, 100*(1-(1-confidence)/2)]) - return intervallo[0] - -def compute_max(x, confidence): - intervallo = np.percentile( - x, [100*(1-confidence)/2, 100*(1-(1-confidence)/2)]) - return intervallo[1] - -def mean_wo_outliers(x): - minimo = compute_min(x, 0.98) - maximo = compute_max(x, 0.98) - a_sel = np.array(x)[(x > minimo) & (x < maximo)] - return np.mean(a_sel) - -def get_last(t): - return t[-1] - -# import data -data = pd.read_csv("/swdev/wokrupa/stack2/Vetra/total_noise_" + run + ".csv") -columns_name = ['channel_ID', 'mean', 'sigma'] -data.columns = columns_name - -# get online name and channel -data['name'] = data['channel_ID'].apply(get_online_name) -m = data['channel_ID'].apply(extract_bits) - -df = pd.DataFrame(m) - -# Calculate last_value from channel_ID -df['last_value'] = df['channel_ID'].apply(get_last) -data['channel'] = df['last_value'] -data['chip'] = (data['channel'] // 128).astype(int) - -# Compute the mean and std of the noise (sigma) of each chip without outliers -mean_noise = data.groupby(['name', 'chip'])['sigma'].apply( - mean_wo_outliers).reset_index() -std_noise = data.groupby(['name', 'chip'])[ - 'sigma'].apply(compute_ci).reset_index() - -# Merge dataframes -merged_df2 = pd.merge(data, mean_noise, on=[ - 'name', 'chip'], how='inner', suffixes=('', '_mean')) -merged_df2 = pd.merge(merged_df2, std_noise, on=[ - 'name', 'chip'], how='inner', suffixes=('', '_std')) - -# Select noisy channels -condition = (merged_df2['sigma'] > - merged_df2['sigma_mean'] + 10 * merged_df2['sigma_std']) -condition_n = ( - merged_df2['sigma'] < merged_df2['sigma_mean'] - 10 * merged_df2['sigma_std']) -condition0 = (merged_df2['mean'] > 2.5 * merged_df2['sigma']) -condition0_n = (merged_df2['mean'] < -2.5 * merged_df2['sigma']) - -result_df2 = merged_df2.loc[condition - condition0 | condition0_n, ['channel', 'name']] - -# selection of bad channels -condition2 = merged_df2['sigma'] > 2*merged_df2['sigma_mean'] -condition20 = merged_df2['sigma'] < 0.5*merged_df2['sigma_mean'] -result_df = pd.DataFrame({ - 'channel': merged_df2.loc[condition2 | condition20, 'channel'], - 'name': merged_df2.loc[condition2 | condition20, 'name'] -}) - -# Convert the list in the correct format -result_df['chip'] = result_df['channel'] // 128 -result_df['chip'] = result_df['chip'].astype(int) - -# Group by name and chip, aggregate channels as lists -tot = result_df.groupby(['name', 'chip'])['channel'].agg(list).reset_index() -tot['nBadC'] = tot['channel'].apply(lambda x: [(i % 128) for i in x]) - -print("Noisy channels") -with pd.option_context("display.max_rows", None, "display.max_columns", None): - print(tot) - -# Calculate positions -tot['pos'] = tot['nBadC'].apply(lambda x: [num // 8 for num in x]) - -# Open a file for writing -file = open('bad_ch_list_' + run + '.txt', 'w') - -# Tag saturation with pedestal value -# Import pedestals -ped = pd.read_csv("/swdev/wokrupa/stack2/Vetra/pedestals_" + run + ".csv") -columns_name_ped = ['channel_ID', 'pedestal'] -ped.columns = columns_name_ped -ped['name'] = ped['channel_ID'].apply(get_online_name) -m_ped = ped['channel_ID'].apply(extract_bits) - -df_ped = pd.DataFrame(m_ped) -df_ped['last_value'] = df_ped['channel_ID'].apply(lambda x: get_last(x)) -ped['channel'] = df_ped['last_value'] -ped['chip'] = (ped['channel'] // 128).astype(int) - -merged_df_p = pd.merge(merged_df2, ped, on=[ - 'name', 'chip', 'channel_ID', 'channel'], how='inner', suffixes=('', '')) - -# selection of bad channels due to saturation -condition_p = np.abs(merged_df_p['pedestal']) > 25 - -result_df_p = pd.DataFrame({ - 'channel': merged_df_p.loc[condition_p, 'channel'], - 'name': merged_df_p.loc[condition_p, 'name'] -}) - -result_df_p['chip'] = result_df_p['channel']/128 -result_df_p['chip'] = result_df_p['chip'].astype(int) - -tot_p = result_df_p.groupby(['name', 'chip'])[ - 'channel'].agg(list).reset_index() -tot_p['nBadC'] = tot_p['channel'].apply(lambda x: [(i % 128) for i in x]) -tot_p['pos'] = tot_p['nBadC'].apply(lambda x: [num // 8 for num in x]) -print("Pedestal") -print(tot_p) - -# merging bad channels from noise and from pedestal distributions -all_bad_ch = pd.concat([tot, tot_p]) - -# Define a function to merge lists -def merge_lists(series): - return list(set(x for sublist in series for x in sublist)) - -# Group by 'channel' and 'name' and apply the merge_lists function -result1 = all_bad_ch.groupby(['chip', 'name'])[ - 'nBadC'].agg(merge_lists).reset_index() -result2 = all_bad_ch.groupby(['chip', 'name'])[ - 'pos'].agg(merge_lists).reset_index() -result3 = all_bad_ch.groupby(['chip', 'name'])[ - 'channel'].agg(merge_lists).reset_index() - -final_list = pd.merge(result1, result2, on=['chip', 'name'], how='inner') -final_list = pd.merge(final_list, result3, on=['chip', 'name'], how='inner') -tot = final_list - -# write the bad channels in the correct format -for i in range(len(tot)): - - mask_list = ['0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', - '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00', '0x00'] - sum_dict = {} - prova = [] - mask_dict = {} - for val1, val2 in zip(tot.iloc[i]['nBadC'], tot.iloc[i]['pos']): - if val2 not in mask_dict: - mask_dict[val2] = 0 - mask_dict[val2] |= (1 << val1 % 8) - - mask_list2 = list(mask_dict.values()) - mask = [hex(0x00 | element) for element in mask_list2] - - no_rep_pos = list(set(tot.iloc[i]['pos'])) - no_rep_pos.sort() - - if tot.iloc[i]['nBadC']: - for jj in range(len(no_rep_pos)): - mask_list[no_rep_pos[jj]] = mask[jj] - line = '--- {}.{} {}\n'.format(tot.iloc[i] - ['name'], tot.iloc[i]['chip'], mask_list) - file.write(line) - diff --git a/UTScripts/BadChannels/UTBadChannels_Basem.py b/UTScripts/BadChannels/UTBadChannels_alt.py similarity index 100% rename from UTScripts/BadChannels/UTBadChannels_Basem.py rename to UTScripts/BadChannels/UTBadChannels_alt.py diff --git a/UTScripts/NoisyChannels/UTNoisyASICs.py b/UTScripts/NoisyChannels/UTNoisyASICs.py new file mode 100644 index 0000000000000000000000000000000000000000..b9321173fc345dbe5bcb2386c69534cbf64158d0 --- /dev/null +++ b/UTScripts/NoisyChannels/UTNoisyASICs.py @@ -0,0 +1,55 @@ +import os +import sys +import importlib +import ROOT # Assuming you have ROOT installed + +class UTSEUCheck: + def __init__(self, hist_path): + self.hist_name = ["UTOnlineBSMonitor/Average_hitRate_UCaU", "UTOnlineBSMonitor/Average_hitRate_UCaX", + "UTOnlineBSMonitor/Average_hitRate_UCbX", "UTOnlineBSMonitor/Average_hitRate_UCbV", + "UTOnlineBSMonitor/Average_hitRate_UAaU", "UTOnlineBSMonitor/Average_hitRate_UAaX", + "UTOnlineBSMonitor/Average_hitRate_UAbX", "UTOnlineBSMonitor/Average_hitRate_UAbV" + ] + self.hist_path = hist_path + self.root_file = ROOT.TFile.Open(hist_path) + self.hists = {} + noisy = {} + + if os.path.exists('/hist/Reference/UTZSMon'): + sys.path.append('/hist/Reference/UTZSMon') + try: + importlib.import_module('ut_dict') + print(f"UT Module 'ut_dict' imported successfully!") + from ut_dict import UT_dict + except ImportError: + print(f"UT Error: Module 'ut_dict' not found.") + else: + print(f"UT Error: Directory '/hist/Reference/UTZSMon' not found.") + + # Open the output text file + with open("noisy_chips.txt", "w") as output_file: + for hist_name in self.hist_name: + self.hists[hist_name] = self.root_file.Get(hist_name) + + for hist_name, hist in self.hists.items(): + print(f"UT - found {hist_name}") + try: + bins = hist.GetXaxis().GetNbins() + except AttributeError: + continue + + for checkedBin in range(1, bins + 1): + binContent = hist.GetBinContent(checkedBin) + if binContent > 0.1: + ch = checkedBin - 1 + hist.GetBinLowEdge(1) + 0.5 + output_line = f"{UT_dict[ch]} Hitrate: {binContent}\n" + + # Save to the text file + output_file.write(f"{UT_dict[ch]}\n") + + # Also print to console + print(output_line.strip()) + +if __name__ == "__main__": + hist_path = "/hist/Savesets/2024/UT/UTBSMon/11/07/UTBSMon-310209-20241107T174311.root" + UTSEUCheck(hist_path) diff --git a/UTScripts/NoisyChannels/UTNoisyChannels.py b/UTScripts/NoisyChannels/UTNoisyChannels.py new file mode 100644 index 0000000000000000000000000000000000000000..8fbc976d70285d756ab5729ef047c2dd8bb94c05 --- /dev/null +++ b/UTScripts/NoisyChannels/UTNoisyChannels.py @@ -0,0 +1,48 @@ +import os +import sys +import importlib +import ROOT # Assuming you have ROOT installed + +class UTSEUCheck: + def __init__(self, hist_path): + self.hist_name = ["UTOnlineBSMonitor/hitRateChannels_UA", "UTOnlineBSMonitor/hitRateChannels_UC"] + self.hist_path = hist_path + self.root_file = ROOT.TFile.Open(hist_path) + self.hists = {} + noisy = {} + + if os.path.exists('/hist/Reference/UTZSMon'): + sys.path.append('/hist/Reference/UTZSMon') + try: + importlib.import_module('ut_dict') + print(f"UT Module 'ut_dict' imported successfully!") + from ut_dict import UT_dict + except ImportError: + print(f"UT Error: Module 'ut_dict' not found.") + else: + print(f"UT Error: Directory '/hist/Reference/UTZSMon' not found.") + + for hist_name in self.hist_name: + self.hists[hist_name] = self.root_file.Get(hist_name) + + for hist_name, hist in self.hists.items(): + print(f"UT - found {hist_name}") + try: + bins = hist.GetXaxis().GetNbins() + except AttributeError: + continue + + for checkedBin in range(1, bins + 1): + binContent = hist.GetBinContent(checkedBin) + if binContent > 0.05: + if hist_name == "UTOnlineBSMonitor/hitRateChannels_UC": + ch=checkedBin+268288-1 + print(UT_dict[int(ch/128)]+".Ch"+str(ch%128), "Hitrate: ", binContent) + else: + ch=checkedBin-1 + print(UT_dict[int(ch/128)]+".Ch"+str(ch%128), "Hitrate: ", binContent) + +if __name__ == "__main__": + hist_path = "/hist/Savesets/2024/UT/UTBSMon/11/07/UTBSMon-310205-20241107T173911-EOR.root" + UTSEUCheck(hist_path) + diff --git a/UTScripts/References/overlay_center_natural_asic_UTaU.root b/UTScripts/References/overlay_center_natural_asic_UTaU.root index 2e7753fd05a67c651444d406932ec2b2b8962469..754447cc9b873963444fdaa459d928ba6d135286 100644 Binary files a/UTScripts/References/overlay_center_natural_asic_UTaU.root and b/UTScripts/References/overlay_center_natural_asic_UTaU.root differ diff --git a/UTScripts/References/overlay_center_natural_asic_UTaX.root b/UTScripts/References/overlay_center_natural_asic_UTaX.root index 59f8d8b66c2d0624091cdb7f9d93eb0f3d0d6e6f..d0cc0704a1dc8be461726c481006678d9fcdec64 100644 Binary files a/UTScripts/References/overlay_center_natural_asic_UTaX.root and b/UTScripts/References/overlay_center_natural_asic_UTaX.root differ diff --git a/UTScripts/References/overlay_center_natural_asic_UTbV.root b/UTScripts/References/overlay_center_natural_asic_UTbV.root index 7631d8e0a9dd091d33513d4a49bb100311e300c0..018971551ae90ea5f5f16101520e8a87da996b05 100644 Binary files a/UTScripts/References/overlay_center_natural_asic_UTbV.root and b/UTScripts/References/overlay_center_natural_asic_UTbV.root differ diff --git a/UTScripts/References/overlay_center_natural_asic_UTbX.root b/UTScripts/References/overlay_center_natural_asic_UTbX.root index feebcdbefe632e8392cee2c3c8fc2e71d62bd0f8..6339d142deee73634808235ad95d6edb05cebdb6 100644 Binary files a/UTScripts/References/overlay_center_natural_asic_UTbX.root and b/UTScripts/References/overlay_center_natural_asic_UTbX.root differ diff --git a/UTScripts/References/overlay_tell40A0.root b/UTScripts/References/overlay_tell40A0.root index 8b0e84e18a41ae474fc61a8cbd57455518a7c54a..f2baa7ca694c0be77ac3c23fb5cf3bc8ffe1ecd3 100644 Binary files a/UTScripts/References/overlay_tell40A0.root and b/UTScripts/References/overlay_tell40A0.root differ diff --git a/UTScripts/References/overlay_tell40A1.root b/UTScripts/References/overlay_tell40A1.root index ddae94730798c8d1d05d68e5032192d470ce1c61..99afb0c1a692b2bd5df2460824eaea709025482e 100644 Binary files a/UTScripts/References/overlay_tell40A1.root and b/UTScripts/References/overlay_tell40A1.root differ diff --git a/UTScripts/References/overlay_tell40C0.root b/UTScripts/References/overlay_tell40C0.root index fa1e7265cb95771f1eb8a3664e6d72f62c83da2e..374014fddb050ea1f042579a48f3bdb8c32f137d 100644 Binary files a/UTScripts/References/overlay_tell40C0.root and b/UTScripts/References/overlay_tell40C0.root differ diff --git a/UTScripts/References/overlay_tell40C1.root b/UTScripts/References/overlay_tell40C1.root index e511cee8713f661a62c1703bf416e3ef45c619c8..56222ba9ab8bfab13418470b8fab3696f80f7b99 100644 Binary files a/UTScripts/References/overlay_tell40C1.root and b/UTScripts/References/overlay_tell40C1.root differ diff --git a/UTScripts/Subtract_MCM.py b/UTScripts/Subtract_MCM.py new file mode 100644 index 0000000000000000000000000000000000000000..15019986c55d6beb37aa7565af159952bfa8b13d --- /dev/null +++ b/UTScripts/Subtract_MCM.py @@ -0,0 +1,34 @@ +import pandas as pd + +#This simple script allows to subtract MCM from pedestal file. + +# Read the input CSV file (adjust the filename as needed) +input_filename = '/swdev/wokrupa/stack3/Vetra/pedestals_0000309677_test_3.csv' +df = pd.read_csv(input_filename, header=None, names=['channel', 'value']) + +# Calculate the average for each group of channels (128 channels in your case) +group_size = 128 +num_groups = len(df) // group_size + +for group_num in range(num_groups): + start_idx = group_num * group_size + end_idx = (group_num + 1) * group_size + group_values = df.loc[start_idx:end_idx - 1, 'value'] + + # Initial average calculation + initial_avg = group_values.mean() + + # Identify non-outliers (values within the ±5 range of initial average) + non_outliers = group_values[abs(group_values - initial_avg) <= 5] + + # Recalculate average excluding outliers + adjusted_avg = int(non_outliers.mean()) + + # Adjust only the non-outliers + df.loc[non_outliers.index, 'value'] -= adjusted_avg + +# Save the modified data to a new CSV file +output_filename = '/swdev/wokrupa/stack3/Vetra/pedestals_0000309677_test_4.csv' +df.to_csv(output_filename, index=False) + +print(f"Modified data saved to {output_filename}") diff --git a/UTScripts/Vetra_Plotter_EmuNoiseComponents.cpp b/UTScripts/Vetra_Plotter_EmuNoiseComponents.cpp index 1ee53a12211fff3949352c2dc93091fe08f9b8e5..6fc7b8200c776691d212606f44fdff588ba14786 100644 --- a/UTScripts/Vetra_Plotter_EmuNoiseComponents.cpp +++ b/UTScripts/Vetra_Plotter_EmuNoiseComponents.cpp @@ -449,7 +449,7 @@ void plot_histos_noise_stave( TDirectory* f3, TDirectory* f4, unsigned int layer void Vetra_Plotter_EmuNoiseComponents() { ///////////////////////////////// - const char* number = "0000297288"; + const char* number = "0000310462"; ///////////////////////////////// std::string number_str( number ); @@ -480,7 +480,7 @@ void Vetra_Plotter_EmuNoiseComponents() { std::cerr << "Error: Failed to open file './Vetra/ut_data_pedestals_" << number << ".root'\n"; exit( -1 ); } - TDirectory* f4 = (TDirectory*)f0->Get( "UTPedestalMonitor" ); + TDirectory* f4 = (TDirectory*)f0->Get( "UTMeanADCMonitor" ); if ( f3 == nullptr ) { std::cerr << "Error: UTIncNoiseDigitMonitor directory not found in the file." << std::endl; @@ -488,7 +488,7 @@ void Vetra_Plotter_EmuNoiseComponents() { } if ( f4 == nullptr ) { - std::cerr << "Error: UTPedestalMonitor directory not found in the file." << std::endl; + std::cerr << "Error: UTMeanADCMonitor directory not found in the file." << std::endl; exit( -1 ); } diff --git a/UTScripts/Vetra_Plotter_Pedestals.cpp b/UTScripts/Vetra_Plotter_MeanADC.cpp similarity index 90% rename from UTScripts/Vetra_Plotter_Pedestals.cpp rename to UTScripts/Vetra_Plotter_MeanADC.cpp index 095cc18523c536c5c85cf5981d9a9c425e202730..99b41ca8f3a4a6aef4cdb23dd7a1cf8373ef6eb4 100644 --- a/UTScripts/Vetra_Plotter_Pedestals.cpp +++ b/UTScripts/Vetra_Plotter_MeanADC.cpp @@ -10,7 +10,7 @@ \*****************************************************************************/ /* - * Vetra_Plotter_Pedestals.cpp + * Vetra_Plotter_MeanADCs.cpp * * Created on: September, 2023 * Author: Wojciech Krupa (wokrupa@cern.ch) @@ -108,7 +108,7 @@ void plot2D( TDirectory* f2, std::string parameter, bool invertPalette, float ma gStyle->SetPalette( 57 ); hist->SetFillStyle( 3001 ); hist->SetStats( 0 ); - hist->GetZaxis()->SetRangeUser( 0, max ); + hist->GetZaxis()->SetRangeUser( 0, 6 ); std::string title = hist->GetTitle(); title = title.substr( 0, title.size()); @@ -249,7 +249,7 @@ void plot_histos_stave( TDirectory* f2, std::string parameter, unsigned int laye hist->SetFillStyle( 3001 ); hist->GetXaxis()->SetTitle( "Strip" ); hist->GetYaxis()->SetTitle( "ADC" ); - if ( parameter == "Pedestals_" ) + if ( parameter == "MeanADC_" ) hist->GetYaxis()->SetRangeUser( -31, 31 ); else hist->GetYaxis()->SetRangeUser( 0, 3 ); @@ -262,12 +262,12 @@ void plot_histos_stave( TDirectory* f2, std::string parameter, unsigned int laye c_pedsub->SaveAs( path.c_str() ); } -// To run: root -l -b Vetra/Ut/UTScripts/Vetra_Plotter_Pedestals.cpp +// To run: root -l -b Vetra/Ut/UTScripts/Vetra_Plotter_MeanADC.cpp -void Vetra_Plotter_Pedestals() { +void Vetra_Plotter_MeanADC() { ///////////////////////////////// - const char* number = "0000297288"; + const char* number = "0000310281"; ///////////////////////////////// std::string number_str( number ); @@ -283,21 +283,21 @@ void Vetra_Plotter_Pedestals() { if ( stat( dir_name.c_str(), &st ) == -1 ) { mkdir( dir_name.c_str(), 0755 ); } - TFile* f1 = TFile::Open( ( parentDir + '/' + "ut_data_pedestals_" + std::string( number ) + ".root" ).c_str() ); + TFile* f1 = TFile::Open( ( parentDir + '/' + "ut_data_meanADC_" + std::string( number ) + ".root" ).c_str() ); if ( !f1 ) exit( -1 ); - TDirectory* f3 = (TDirectory*)f1->Get( "UTPedestalMonitor" ); + TDirectory* f3 = (TDirectory*)f1->Get( "UTMeanADCMonitor" ); for ( unsigned int layer = 0; layer < 4; layer++ ) for ( unsigned int side = 0; side < 2; side++ ) for ( unsigned int stave = 1; stave <= 9; stave++ ) { - plot_histos_stave( f3, "Pedestals_", layer, side, stave, number_str, parentDir ); - plot_histos_stave( f3, "SigmaNoise_", layer, side, stave, number_str, parentDir ); + //plot_histos_stave( f3, "MeanADC_", layer, side, stave, number_str, parentDir ); + //plot_histos_stave( f3, "SigmaNoise_", layer, side, stave, number_str, parentDir ); } - plot2D( f3, "PedestalAverage", 1, 4, number_str, parentDir ); + plot2D( f3, "MeanADCAverage", 1, 4, number_str, parentDir ); plot2D( f3, "SigmaNoiseAverage", 1, 2, number_str, parentDir ); - plot2D( f3, "ZS_th", 1, 5, number_str, parentDir ); + plot2D( f3, "ZS_th", 1, 4, number_str, parentDir ); TCanvas* c_proj = new TCanvas( "Projections_SigmaNoise", "Projections_SigmaNoise", 1400, 1200 ); @@ -342,32 +342,32 @@ void Vetra_Plotter_Pedestals() { c_proj->SaveAs( ( parentDir + '/' + std::string( number_str ) + "/Projections_SigmaNoise.png" ).c_str() ); - TCanvas* c_proj2 = new TCanvas( "Projections_Pedestals", "Projections_Pedestals", 1400, 1200 ); + TCanvas* c_proj2 = new TCanvas( "Projections_MeanADC", "Projections_MeanADC", 1400, 1200 ); // Plotting projections c_proj2->Divide( 2, 2 ); - TH1F* h5 = (TH1F*)f3->Get( "Projection_Pedestal" ); + TH1F* h5 = (TH1F*)f3->Get( "Projection_MeanADC" ); if ( !h5 ) { - std::cerr << "Failed to get histogram Projection_Pedestal\n"; + std::cerr << "Failed to get histogram Projection_MeanADC\n"; return; } - TH1F* h6 = (TH1F*)f3->Get( "Projection_Pedestal_A" ); + TH1F* h6 = (TH1F*)f3->Get( "Projection_MeanADC_A" ); if ( !h6 ) { - std::cerr << "Failed to get histogram Projection_Pedestal_A\n"; + std::cerr << "Failed to get histogram Projection_MeanADC_A\n"; return; } - TH1F* h7 = (TH1F*)f3->Get( "Projection_Pedestal_B" ); + TH1F* h7 = (TH1F*)f3->Get( "Projection_MeanADC_B" ); if ( !h7 ) { - std::cerr << "Failed to get histogram Projection_Pedestal_B\n"; + std::cerr << "Failed to get histogram Projection_MeanADC_B\n"; return; } - TH1F* h8 = (TH1F*)f3->Get( "Projection_Pedestal_C" ); + TH1F* h8 = (TH1F*)f3->Get( "Projection_MeanADC_C" ); if ( !h8 ) { - std::cerr << "Failed to get histogram Projection_Pedestal_C\n"; + std::cerr << "Failed to get histogram Projection_MeanADC_C\n"; return; } @@ -383,7 +383,7 @@ void Vetra_Plotter_Pedestals() { c_proj2->cd( 4 ); h8->Draw(); - c_proj2->SaveAs( ( parentDir + '/' + std::string( number_str ) + "/Projections_Pedestal.png" ).c_str() ); + c_proj2->SaveAs( ( parentDir + '/' + std::string( number_str ) + "/Projections_MeanADC.png" ).c_str() ); gPad->SetLogy(); c_proj2->cd( 1 ); @@ -401,7 +401,7 @@ void Vetra_Plotter_Pedestals() { c_proj2->cd( 4 ); h8->Draw(); - c_proj2->SaveAs( ( parentDir + '/' + std::string( number_str ) + "/Projections_PedestalLog.png" ).c_str() ); + c_proj2->SaveAs( ( parentDir + '/' + std::string( number_str ) + "/Projections_MeanADCLog.png" ).c_str() ); gSystem->Exit( 0 ); } diff --git a/UTScripts/Vetra_Plotter_PedSub.cpp b/UTScripts/Vetra_Plotter_PedSub.cpp index 64b8b6cd4409231edd0961827f7172cd40552c8b..4aa41c2bbdaad88a1eeeb49ee59f1f4f65ec80f0 100644 --- a/UTScripts/Vetra_Plotter_PedSub.cpp +++ b/UTScripts/Vetra_Plotter_PedSub.cpp @@ -1,4 +1,4 @@ -/*****************************************************************************\ + /*****************************************************************************\ * (c) Copyright 2000-2023 CERN for the benefit of the LHCb Collaboration * * * * This software is distributed under the terms of the GNU General Public * @@ -139,7 +139,7 @@ void plot_histos_stave( TDirectory* f2, unsigned int layer, unsigned int side, u void Vetra_Plotter_PedSub() { ///////////////////////////////// - const char* number = "0000297288"; + const char* number = "0000307299"; ///////////////////////////////// std::string number_str( number ); @@ -152,7 +152,7 @@ void Vetra_Plotter_PedSub() { // Setting up the directory std::string dir_name = parentDir + std::string( number ); - struct stat st = { 0 }; + struct stat st = { 0 }; if ( stat( dir_name.c_str(), &st ) == -1 ) { mkdir( dir_name.c_str(), 0755 ); } diff --git a/UTScripts/Vetra_Plotter_PedestalRun.cpp b/UTScripts/Vetra_Plotter_PedestalRun.cpp index 0290084f305db34187e8e15e543ca397306b5e84..93b373a06086c34ab26a53120fc3fee06948f5a0 100644 --- a/UTScripts/Vetra_Plotter_PedestalRun.cpp +++ b/UTScripts/Vetra_Plotter_PedestalRun.cpp @@ -492,12 +492,13 @@ void plot_histos_noise_stave( TDirectory* f3, unsigned int layer, unsigned side, } } -// To run: root -l -b Vetra/Ut/UTScripts/Vetra_Plotter_PedestalRun.cpp +// To run: root -l -b Vetra/Ut/UTScripts/Vetra_Plotter_ +Run.cpp void Vetra_Plotter_PedestalRun() { ///////////////////////////////// - const char* number = "0000294162"; + const char* number = "0000301203"; ///////////////////////////////// std::string number_str( number ); diff --git a/UTScripts/Vetra_Plotter_RawADC.cpp b/UTScripts/Vetra_Plotter_RawADC.cpp index 7f1aad1a0041984b665ffb8cc8822e69f1e8afd0..357a4e0688c64843055925f95f7e607c0da20b73 100644 --- a/UTScripts/Vetra_Plotter_RawADC.cpp +++ b/UTScripts/Vetra_Plotter_RawADC.cpp @@ -316,7 +316,7 @@ void plot_histos_stave( TDirectory* f2, unsigned int layer, unsigned int side, u void Vetra_Plotter_RawADC() { ///////////////////////////////// - const char* number = "0000297288"; + const char* number = "0000310462"; ///////////////////////////////// std::string number_str( number ); @@ -349,7 +349,7 @@ void Vetra_Plotter_RawADC() { for ( unsigned int layer = 0; layer < NUM_LAYERS; layer++ ) for ( unsigned int side = 0; side < NUM_SIDES; side++ ) for ( unsigned int stave = 1; stave <= NUM_STAVES; stave++ ) { - // plot_histos_stave( f2, layer, side, stave, number_str, parentDir ); + plot_histos_stave( f2, layer, side, stave, number_str, parentDir ); } // MCMS diff --git a/release.notes b/release.notes index db843952b02c92759df9372ef3af856144455713..199b8209b44a526347ed8c5a9e29fe82f9ff9853 100644 --- a/release.notes +++ b/release.notes @@ -4,6 +4,11 @@ ! Purpose : Calibration and offline monitoring of the UT !----------------------------------------------------------------------------- +!============================ UTEmu v4r5 2024-11 =========================== +! 2024-06-7 - Wojciech Krupa + - Improving algorithms logic + - Adding new pedestal calculator (step) + !============================ UTEmu v4r4 2024-03 =========================== ! 2024-06-7 - Wojciech Krupa - Simplifying code @@ -39,7 +44,6 @@ - Script for initialisation of DB xml file - Migration to Vetra repository - !============================ UTEmu v2r1 2020-04 =========================== ! 202-04 - Wojciech Krupa