File indexing completed on 2026-01-07 09:25:15
0001 #include "CalibSampleParser.h"
0002 #include <vector>
0003 #include <algorithm>
0004 #include <sstream>
0005 #include <string>
0006 #include <cstdlib>
0007 #include "TROOT.h"
0008 #include "TPaletteAxis.h"
0009 #include "TProfile.h"
0010 #include "TChain.h"
0011 #include "TileSpectra.h"
0012 #include "PlotHelper.h"
0013 #include "CommonHelperFunctions.h"
0014
0015 #include "waveform_fitting/waveform_fit_base.h"
0016 #include "waveform_fitting/crystal_ball_fit.h"
0017 #include "waveform_fitting/max_sample_fit.h"
0018
0019
0020
0021
0022
0023 bool CalibSampleParser::CheckAndOpenIO(void){
0024
0025
0026 std::cout<<"Input file set to: '"<<inputFilePath.Data() <<std::endl;
0027 if(inputFilePath.IsNull()){
0028 std::cout<<"An input file is required, aborting"<<std::endl;
0029 return false;
0030 }
0031 if( inputFilePath.Contains(".csv") ){
0032 std::cout << "Reading in .csv file with calibration output, and parsing it into .root file" << std::endl;
0033 } else if( inputFilePath.Contains(".txt") ){
0034 std::cout << "Reading in config file with list of dead channels, and .json files with respective KCUs. " << std::endl;
0035 std::cout << "Additional .root file with calib object is required to run in this mode." << std::endl;
0036 SwitchPedestalCalib();
0037 if( doPlotting ) {
0038 std::cout << "Plotting not available in the current mode, no plots will be produced" << std::endl;
0039 }
0040 }
0041
0042 if( !MapInputName.IsNull() ){
0043 MapInput.open( MapInputName.Data(), std::ios::in);
0044 if( !MapInput.is_open() ){
0045 std::cout << "Could not open mapping file: " << MapInputName << std::endl;
0046 return false;
0047 }
0048 } else {
0049 std::cout << "A mapping file is required, aborting" << std::endl;
0050 return false;
0051 }
0052
0053 if(!OutputFilename.IsNull() ){
0054 std::cout << "Output root filename set to " << OutputFilename << std::endl;
0055 } else {
0056 if( optParse == 1 ){
0057 OutputFilename = calibInputFile;
0058 OutputFilename = OutputFilename.ReplaceAll(".root","overwrittenPedestal.root");
0059 } else {
0060 OutputFilename = inputFilePath;
0061 OutputFilename = OutputFilename.ReplaceAll(".csv",".root");
0062 }
0063 std::cout << "Output root filename set by default to " << OutputFilename << std::endl;
0064 }
0065
0066 OutputHistFilename = OutputFilename;
0067 OutputHistFilename = OutputHistFilename.ReplaceAll(".root","_hist.root");
0068
0069 RootOutput = new TFile(OutputFilename.Data(), "RECREATE");
0070
0071 if( optParse == 0 ){
0072 tOutTree = new TTree("CalibSample","CalibSample");
0073 tOutTree->Branch("event",&event);
0074 tOutTree->SetDirectory(RootOutput);
0075 } else if ( optParse == 1 ){
0076 std::cout << "Reading a calib object from the file " << calibInputFile.Data() << std::endl;
0077 RootCalibInput = new TFile( calibInputFile.Data(), "READ" );
0078 if( RootCalibInput->IsZombie() ){
0079 std::cout << "Error opening " << calibInputFile.Data() <<", does the file exist?" << std::endl;
0080 return false;
0081 }
0082 TcalibIn = (TTree*) RootCalibInput->Get("Calib");
0083 if( !TcalibIn ){
0084 std::cout << "Could not retrieve Calib, aborting" <<std::endl;
0085 return false;
0086 } else {
0087 int matchingbranch = TcalibIn->SetBranchAddress("calib",&calibptr);
0088 if( matchingbranch < 0 ){
0089 std::cout<<"Error retrieving calibration info form the tree"<<std::endl;
0090 return false;
0091 }
0092 }
0093 }
0094
0095 TsetupOut = new TTree("Setup","Setup");
0096 setup=Setup::GetInstance();
0097 TsetupOut->Branch("setup",&rsw);
0098 TsetupOut->SetDirectory( RootOutput );
0099 TcalibOut = new TTree("Calib","Calib");
0100 TcalibOut->Branch("calib",&calib);
0101 TcalibOut->SetDirectory( RootOutput );
0102
0103 std::cout <<"=============================================================" << std::endl;
0104 std::cout <<" Basic setup complete" << std::endl;
0105 std::cout <<"=============================================================" << std::endl;
0106 return true;
0107 }
0108
0109
0110
0111
0112
0113 bool CalibSampleParser::Process(void){
0114 bool status;
0115 if( optParse == 0 ){
0116 status = Parse();
0117 if( doPlotting ) status = ProcessAndPlotWaveforms();
0118 } else if ( optParse == 1 ) {
0119 status = ParsePedestalCalib();
0120 }
0121 return status;
0122 }
0123
0124
0125
0126
0127
0128 bool CalibSampleParser::Parse(){
0129
0130
0131 if (RunListInputName.CompareTo("")== 0) {
0132 std::cerr << "ERROR: No run list file has been provided, please make sure you do so! Aborting!" << std::endl;
0133 return false;
0134 }
0135 std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
0136
0137
0138 if (MapInputName.CompareTo("")== 0) {
0139 std::cerr << "ERROR: No mapping file has been provided, please make sure you do so! Aborting!" << std::endl;
0140 return false;
0141 }
0142 if( debug > 2) std::cout << "Setup max row " << setup->GetNMaxRow() << "\t max col " << setup->GetNMaxColumn() << "\t max layer " << setup->GetNMaxLayer() << "\t max module " << setup->GetNMaxModule() << std::endl;
0143
0144 std::cout << "Creating mapping " << std::endl;
0145 setup->Initialize(MapInputName.Data(),debug);
0146
0147
0148 event.SetRunNumber( RunNr );
0149 event.SetROtype(ReadOut::Type::Hgcroc);
0150 event.SetBeamName( "dummy" );
0151 event.SetBeamID( 0 );
0152 event.SetBeamEnergy( 0 );
0153
0154 Int_t temp_channel = -1;
0155 int cell_id = -1;
0156 int counter = 1;
0157 int sample_counter = 1;
0158
0159 std::vector<Hgcroc> samples;
0160 samples.clear();
0161 Hgcroc tmpTile;
0162
0163 std::vector<int> temp_adc;
0164 std::vector<int> temp_toa;
0165 std::vector<int> temp_tot;
0166 temp_adc.clear();
0167 temp_toa.clear();
0168 temp_tot.clear();
0169
0170 std::ifstream calibSampleCsv( inputFilePath.Data() );
0171 std::string line;
0172 std::getline( calibSampleCsv, line );
0173 while (std::getline( calibSampleCsv, line )){
0174 std::stringstream ss(line);
0175 std::string token;
0176 std::vector<std::string> tokens;
0177 while(std::getline(ss,token,',')){
0178 tokens.push_back(token);
0179 }
0180 int channel = std::stoi(tokens[0]);
0181 int asic = 0;
0182
0183 if(temp_channel == -1) {
0184 temp_channel = channel;
0185 if( channel%76 < 37 ){
0186 channel = 72*(channel/76) + channel%76;
0187 } else if( channel%76 == 37 || channel%76 == 38){
0188 continue;
0189 } else {
0190 channel = 72*(channel/76) + (channel-2);
0191 }
0192 asic = (channel/72);
0193 cell_id = setup->GetCellID(asic, channel % 72);
0194 temp_adc.push_back( std::atoi(tokens[3].c_str()) );
0195 temp_toa.push_back( std::atoi(tokens[5].c_str()) );
0196 temp_tot.push_back( std::atoi(tokens[4].c_str()) );
0197 } else if( temp_channel == channel){
0198 sample_counter++;
0199 if( std::atof( tokens[1].c_str() ) == (sample_counter-1)*1.5625 ) {
0200 temp_adc.push_back( std::atoi(tokens[3].c_str()) );
0201 temp_toa.push_back( std::atoi(tokens[5].c_str()) );
0202 temp_tot.push_back( std::atoi(tokens[4].c_str()) );
0203 } else {
0204 if( debug > 3){
0205 std::cout << "missing entry, channel: " << channel << "\t time " << std::atof( tokens[1].c_str() ) << "\t target value: " << (sample_counter-1)*1.5625 << std::endl;
0206 }
0207 temp_adc.push_back( 0 );
0208 temp_toa.push_back( 0 );
0209 temp_tot.push_back( 0 );
0210 sample_counter++;
0211 temp_adc.push_back( std::atoi(tokens[3].c_str()) );
0212 temp_toa.push_back( std::atoi(tokens[5].c_str()) );
0213 temp_tot.push_back( std::atoi(tokens[4].c_str()) );
0214 }
0215 } else if( temp_channel != channel){
0216
0217 tmpTile.SetNsample(sample_counter);
0218 tmpTile.SetCellID(cell_id);
0219 tmpTile.SetE(0);
0220 tmpTile.SetTOA(0);
0221
0222 int tempTOT = *(std::find_if(temp_tot.begin(), temp_tot.end(), [](int n){ return n!=0; }) );
0223 tmpTile.SetTOT( tempTOT );
0224
0225 int tempIntADC = *(std::max_element( temp_adc.begin(), temp_adc.end() ));
0226 tmpTile.SetIntegratedADC( tempIntADC );
0227 tmpTile.SetADCWaveform( temp_adc );
0228 tmpTile.SetTOAWaveform( temp_toa );
0229 tmpTile.SetTOTWaveform( temp_tot );
0230 samples.push_back( tmpTile );
0231 if(debug > 1) std::cout << "Channel: " << temp_channel << "\t Cell ID: " << cell_id << "\t NSamples: " << sample_counter << "\t ADC: " << tempIntADC << "\t ToT: " << tempTOT << std::endl;
0232
0233
0234 temp_adc.clear();
0235 temp_toa.clear();
0236 temp_tot.clear();
0237 sample_counter = 1;
0238 temp_channel = channel;
0239 if( channel%76 < 37 ){
0240 channel = 72*(channel/76) + channel%76;
0241 } else if( channel%76 == 37 || channel%76 == 38){
0242 continue;
0243 } else {
0244 channel = 72*(channel/76) + (channel-2);
0245 }
0246 asic = (channel/72);
0247 cell_id = setup->GetCellID(asic, channel % 72);
0248 if(debug > 1 ) std::cout << "layer " << setup->GetLayer(cell_id) << "\t module " << setup->GetModule(cell_id) << "\t column " << setup->GetColumn(cell_id) << "\t row " << setup->GetRow(cell_id) << std::endl;
0249 counter++;
0250 temp_adc.push_back( std::atoi(tokens[3].c_str()) );
0251 temp_toa.push_back( std::atoi(tokens[4].c_str()) );
0252 temp_tot.push_back( std::atoi(tokens[5].c_str()) );
0253 }
0254 }
0255
0256 if( cell_id != (*samples.end()).GetCellID() ){
0257 tmpTile.SetNsample(sample_counter);
0258 tmpTile.SetCellID(cell_id);
0259 tmpTile.SetE(0);
0260 tmpTile.SetTOA(0);
0261
0262 int tempTOT = *(std::find_if(temp_tot.begin(), temp_tot.end(), [](int n){ return n!=0; }) );
0263 tmpTile.SetTOT( tempTOT );
0264
0265 int tempIntADC = *(std::max_element( temp_adc.begin(), temp_adc.end() ));
0266 tmpTile.SetIntegratedADC( tempIntADC );
0267 tmpTile.SetADCWaveform( temp_adc );
0268 tmpTile.SetTOAWaveform( temp_toa );
0269 tmpTile.SetTOTWaveform( temp_tot );
0270 samples.push_back(tmpTile);
0271 if(debug > 1) std::cout << "Channel: " << temp_channel << "\t Cell ID: " << cell_id << "\t NSamples: " << sample_counter << "\t ADC: " << tempIntADC << "\t ToT: " << tempTOT << std::endl;
0272 }
0273 if( debug > 1) std::cout << "Total number of parsed samples: " << counter << std::endl;
0274
0275 if( debug > 1) std::cout << "Samples saved in the event class: " << std::endl;
0276 int counter2 = 0;
0277 for(auto it = samples.begin(); it!= samples.end(); ++it){
0278 if( debug > 1 ) {
0279 std::cout << "Sample: " << counter2 << "\t CellID:" << (*it).GetCellID() << std::endl;
0280 }
0281 counter2++;
0282 event.AddTile( new Hgcroc(*it) );
0283 }
0284
0285
0286 RootOutput->cd();
0287
0288
0289 RootSetupWrapper rswtmp=RootSetupWrapper(setup);
0290 rsw=rswtmp;
0291 TsetupOut->Fill();
0292 TsetupOut->Write();
0293
0294 tOutTree->Fill();
0295 tOutTree->Write();
0296
0297
0298 RootOutput->Close();
0299
0300 std::cout <<"=============================================================" << std::endl;
0301 std::cout <<" Parsing complete" << std::endl;
0302 std::cout <<" Output saved to " << OutputFilename.Data() << std::endl;
0303 std::cout <<"=============================================================" << std::endl;
0304
0305
0306 return true;
0307 }
0308
0309 bool CalibSampleParser::ProcessAndPlotWaveforms(){
0310
0311
0312 if (RunListInputName.CompareTo("")== 0) {
0313 std::cerr << "ERROR: No run list file has been provided, please make sure you do so! Aborting!" << std::endl;
0314 return false;
0315 }
0316 std::map<int,RunInfo> ri=readRunInfosFromFile(RunListInputName.Data(),debug,0);
0317
0318
0319 std::map<int,RunInfo>::iterator it=ri.find( RunNr );
0320
0321 RootOutputHist = new TFile(OutputHistFilename.Data(), "RECREATE");
0322 RootOutputHist->mkdir("IndividualCells");
0323 RootOutput->cd();
0324
0325 waveform_fit_base *waveform_builder = nullptr;
0326 waveform_builder = new max_sample_fit();
0327
0328 std::map<int,TileSpectra> hSpectra;
0329 std::map<int,TileSpectra>::iterator ithSpectra;
0330
0331
0332 for(int j=0; j<event.GetNTiles(); j++){
0333 Hgcroc* aTile = (Hgcroc*)event.GetTile(j);
0334 ithSpectra = hSpectra.find(aTile->GetCellID());
0335
0336 double adc = 0;
0337 double tot = 0;
0338 double toa = 0;
0339
0340
0341 double ped = (aTile->GetADCWaveform()).at(0);
0342 if(debug > 3) std::cout << "CellID " << aTile->GetCellID() << "\t (dummy) Pedestal " << ped << std::endl;
0343
0344 std::vector<int> temp_totWaveform = aTile->GetTOTWaveform();
0345 std::vector<int> temp_toaWaveform = aTile->GetTOAWaveform();
0346 std::vector<int> temp_adcWaveform = aTile->GetADCWaveform();
0347
0348 tot = *(std::find_if( temp_totWaveform.begin(), temp_totWaveform.end(), [](int val){return val>1;} ));
0349 toa = *(std::find_if( temp_toaWaveform.begin(), temp_toaWaveform.end(), [](int val){return val>1;} ));
0350 adc = *(std::max_element( temp_adcWaveform.begin(), temp_adcWaveform.end())) - ped;
0351
0352 if(debug > 5) std::cout << "tot: " << tot << "\t toa " << toa << "\t adc " << adc << std::endl;
0353
0354 waveform_builder->set_waveform( aTile->GetADCWaveform() );
0355 waveform_builder->fit_with_average_ped(ped);
0356
0357 aTile->SetIntegratedADC(waveform_builder->get_E());
0358 aTile->SetPedestal(waveform_builder->get_pedestal());
0359
0360 if(ithSpectra!=hSpectra.end()){
0361 ithSpectra->second.FillExtHGCROC(adc, 0., tot, 0);
0362 ithSpectra->second.FillWaveformVsTimeParser(aTile->GetADCWaveform(),ped);
0363 } else {
0364 RootOutputHist->cd("IndividualCells");
0365 hSpectra[aTile->GetCellID()]=TileSpectra("ped",3,aTile->GetCellID(),nullptr,event.GetROtype(),debug);
0366 hSpectra[aTile->GetCellID()].FillExtHGCROC(adc, 0., tot, 0);
0367 hSpectra[aTile->GetCellID()].FillWaveformVsTimeParser(aTile->GetADCWaveform(),ped);
0368 hSpectra[aTile->GetCellID()].WriteExt(false);
0369 RootOutput->cd();
0370 }
0371 }
0372
0373 int t_max = ((Hgcroc*)event.GetTile(0))->GetNsample() * 1562.5;
0374
0375 Int_t textSizePixel = 30;
0376
0377 TCanvas* canvas8PanelProf;
0378 TPad* pad8PanelProf[8];
0379 Double_t topRCornerXProf[8];
0380 Double_t topRCornerYProf[8];
0381 Double_t relSize8PProf[8];
0382 CreateCanvasAndPadsFor8PannelTBPlot(canvas8PanelProf, pad8PanelProf, topRCornerXProf, topRCornerYProf, relSize8PProf, textSizePixel, 0.045, "Prof", false);
0383
0384 for(int l=0; l < setup->GetNMaxLayer()+1; l++){
0385 for(int m=0; m < setup->GetNMaxModule()+1; m++ ){
0386 if (l%10 == 0 && l > 0 && debug > 0) std::cout << "============================== layer " << l << " / " << setup->GetNMaxLayer() << " layers" << std::endl;
0387
0388 PlotCorr2D8MLayer(canvas8PanelProf, pad8PanelProf, topRCornerXProf, topRCornerYProf, relSize8PProf, textSizePixel,
0389 hSpectra, 1, 0, t_max, 1024, l, m,
0390 Form("%s/Waveform_Mod%02d_Layer%02d.%s" ,outputDirPlots.Data(), m, l, "pdf"), it->second, 1);
0391 }
0392 }
0393
0394 std::cout <<"=============================================================" << std::endl;
0395 std::cout <<" Plots saved to " << outputDirPlots.Data() << std::endl;
0396 std::cout <<"=============================================================" << std::endl;
0397
0398
0399
0400 return true;
0401 }
0402
0403 bool CalibSampleParser::ParsePedestalCalib(){
0404
0405
0406 if (MapInputName.CompareTo("")== 0) {
0407 std::cerr << "ERROR: No mapping file has been provided, please make sure you do so! Aborting!" << std::endl;
0408 return false;
0409 }
0410 if( debug > 2) std::cout << "Setup max row " << setup->GetNMaxRow() << "\t max col " << setup->GetNMaxColumn() << "\t max layer " << setup->GetNMaxLayer() << "\t max module " << setup->GetNMaxModule() << std::endl;
0411 std::cout << "Creating mapping " << std::endl;
0412 setup->Initialize(MapInputName.Data(),debug);
0413
0414
0415 TcalibIn->GetEntry(0);
0416 calib.SetRunNumber( RunNr );
0417
0418
0419
0420
0421
0422
0423
0424
0425 std::ifstream jsonList ( inputFilePath.Data() );
0426 std::string line;
0427
0428 std::vector<int> cellIDs;
0429 std::string deadChannelsJson = " \"dead_channels\": [";
0430 std::string pedestalValJson = " \"pede_values\": [";
0431
0432 int NChannels = 0;
0433 std::vector<int> calibChannelsJson;
0434 std::vector<int> pedestalValues;
0435 int channelCounter = 0;
0436
0437
0438 std::getline( jsonList, line );
0439 std::stringstream ss(line);
0440 std::string token;
0441 std::vector<std::string> tokens;
0442 while( std::getline( ss, token, ',') ) tokens.push_back(token);
0443 NChannels = std::stoi( tokens[0] );
0444 for(int i = 1; i < tokens.size(); i++){
0445 calibChannelsSet.push_back( std::stoi( tokens[i] ) );
0446 }
0447 if( calibChannelsSet.size() != NChannels ){
0448 std::cout << "Given number of calib channels " << NChannels << " doesn't match the number of listed calib channels " << calibChannelsSet.size() << std::endl;
0449 std::cout << "Check config file... Aborting" << std::endl;
0450 return false;
0451 }
0452 tokens.clear();
0453
0454
0455 while( std::getline( jsonList, line) ){
0456 std::stringstream s2(line);
0457 tokens.clear();
0458 while( std::getline( s2, token, ',') ) tokens.push_back( token );
0459 kcu = std::stoi( tokens[0] );
0460
0461 std::ifstream tmpJson ( tokens[1] );
0462 while(std::getline( tmpJson, line ) ){
0463
0464
0465 if( line.compare(deadChannelsJson) == 0 ){
0466 std::cout << "Checking if the calib channels in .json file match the set-up calib channels" << std::endl;
0467 while( std::getline( tmpJson, line) ){
0468 if( line.compare(" ],") == 0 ) break;
0469 else {
0470 std::stringstream s4(line);
0471 tokens.clear();
0472 while( std::getline(s4,token,',') ) tokens.push_back(token);
0473 calibChannelsJson.push_back( std::stoi( tokens[0] ) );
0474 }
0475 }
0476 if( calibChannelsJson.size() != NChannels ) {
0477 std::cout << "Unexpected length of the read-in calib channels array... Aborting" << std::endl;
0478 return false;
0479 }
0480
0481 for(int i=0; i< (int)calibChannelsJson.size(); i++){
0482 if( calibChannelsJson.at(i) != calibChannelsSet.at(i) ){
0483 std::cout << "Read-in calib channels " << calibChannelsJson.at(i) << " different from known calib channel " << calibChannelsSet.at(i) << std::endl;
0484 std::cout << "Modify the config file... Aborting" << std::endl;
0485 return false;
0486 }
0487 if( debug > 5) std::cout << "Read-in calib channel " << calibChannelsJson.at(i) << ", set-up calib channel " << calibChannelsSet.at(i) << std::endl;
0488 }
0489 }
0490
0491
0492 if( line.compare(pedestalValJson) == 0 ){
0493 std::cout << "Calib channels checked, now time to read the pedestal values " << std::endl;
0494 while( std::getline( tmpJson, line) ){
0495 if( line.compare(" ],") == 0 ) break;
0496 else {
0497 std::stringstream s4(line);
0498 tokens.clear();
0499 while( std::getline(s4,token,',') ) tokens.push_back(token);
0500 if( !IsCalibChannel( channelCounter ) ) {
0501 pedestalValues.push_back( std::stoi( tokens[0] ) );
0502 }
0503 }
0504 channelCounter++;
0505 }
0506 }
0507 }
0508 }
0509
0510
0511 for(int i=0; i<pedestalValues.size(); i++){
0512 if( debug > 5) std::cout << "channel: " << i << ", pedestal value " << pedestalValues.at(i) << std::endl;
0513
0514 int channel = i;
0515 int asic = kcu * 2 + (i/72);
0516 int cell_id = setup->GetCellID( asic, channel%72 );
0517 if( cell_id != -1 ) cellIDs.push_back( cell_id );
0518 if( debug > 10) std::cout << "Channel " << i << ", kcu " << kcu << ", asic " << asic << ", cellID " << cell_id << std::endl;
0519
0520 TileCalib* tileCalib = calib.GetTileCalib( cell_id );
0521 if( debug > 5 ) std::cout << "Setting pedestal for tile " << cell_id << " from " << tileCalib->PedestalMeanH << " to " << pedestalValues.at(i) << std::endl;
0522 tileCalib->PedestalMeanH = pedestalValues.at(i);
0523 }
0524
0525 std::cout << "Pedestal values overwritten, and the calib object will be saved in " << OutputFilename.Data() << std::endl;
0526
0527
0528 RootOutput->cd();
0529
0530
0531 RootSetupWrapper rswtmp=RootSetupWrapper(setup);
0532 rsw=rswtmp;
0533 TsetupOut->Fill();
0534 TsetupOut->Write();
0535
0536
0537 TString outputCalibTxt = OutputFilename.ReplaceAll(".root","_calib.txt");
0538 calib.PrintCalibToFile( outputCalibTxt );
0539 TcalibOut->Fill();
0540 TcalibOut->Write();
0541
0542
0543 RootOutput->Close();
0544 std::cout <<"=============================================================" << std::endl;
0545 std::cout <<" Parsing of pedestal calib complete" << std::endl;
0546 std::cout <<" Output saved to " << OutputFilename.Data() << std::endl;
0547 std::cout <<"=============================================================" << std::endl;
0548
0549 return true;
0550 }