Back to home page

EIC code displayed by LXR

 
 

    


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 // Checking and opening input files
0022 // ****************************************************************************
0023 bool CalibSampleParser::CheckAndOpenIO(void){
0024 
0025   //Need to check first input to get the setup...I do not think it is necessary
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 // Primary process function 
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 // Parsing routine
0127 // ****************************************************************************
0128 bool CalibSampleParser::Parse(){
0129 
0130     // initialize run number file
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     // initialize setup
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     // initialize a dummy event - it will be a tree with one branch containing one event, event contains multiple tiles
0148     event.SetRunNumber( RunNr ); // to be fixed?
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 ); // skip header
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); // tokens[0] - channel, tokens[3] - ADC, tokens[4] - TOA, tokens[5] - TOT || tokens[1] - time, tokens[2] - phase - skipping
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 ){          // correction in the channel number to remove calib channels: 37, 38
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 ) {         // check the timing - some channels are missing entries from waveforms
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 );                                                  // pushing the missing values as 0
0208           temp_toa.push_back( 0 );        
0209           temp_tot.push_back( 0 );
0210           sample_counter++;                                                         // incrementing the sample counter to account for the missing entry
0211           temp_adc.push_back( std::atoi(tokens[3].c_str()) );                       // and then the read values
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         // save the current tiles waveforms, and then push the tile to the samples vector
0217         tmpTile.SetNsample(sample_counter);
0218         tmpTile.SetCellID(cell_id);
0219         tmpTile.SetE(0);          // need to process waveform to set this
0220         tmpTile.SetTOA(0);        // need to process waveform to set this
0221         // TOT - the first non-zero value
0222         int tempTOT   = *(std::find_if(temp_tot.begin(), temp_tot.end(), [](int n){ return n!=0; }) );
0223         tmpTile.SetTOT( tempTOT );        // need to process waveform to set this - the first value that comes up 
0224         // SetIntegratedADC as max ADC 
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         // we're moving to the next tile
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 ){      // correction in the channel number to remove calib channels: 37, 38
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       // TOT - the first non-zero value
0262       int tempTOT   = *(std::find_if(temp_tot.begin(), temp_tot.end(), [](int n){ return n!=0; }) );
0263       tmpTile.SetTOT( tempTOT );        // need to process waveform to set this - the first value that comes up 
0264       // SetIntegratedADC as max ADC 
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     // fill the tree and write it out to file - should contain just one event
0286     RootOutput->cd();
0287 
0288     // setup 
0289     RootSetupWrapper rswtmp=RootSetupWrapper(setup);
0290     rsw=rswtmp;
0291     TsetupOut->Fill();
0292     TsetupOut->Write();
0293     // data
0294     tOutTree->Fill();
0295     tOutTree->Write();
0296 
0297     // close the file
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   // initialize run number file
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   // Get run info object
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     // dummy pedestal - just first ADC values from the tile:
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;} ));  // placeholders for now
0349     toa = *(std::find_if( temp_toaWaveform.begin(), temp_toaWaveform.end(), [](int val){return val>1;} ));  // placeholders for now
0350     adc = *(std::max_element( temp_adcWaveform.begin(), temp_adcWaveform.end())) - ped;                     // placeholders for now
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   // initialize setup
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   // read in calib object to modify
0415   TcalibIn->GetEntry(0);
0416   calib.SetRunNumber( RunNr );
0417 
0418   // reading in config file with calib channels in the first line, list of KCUs # + .json file in following lines
0419   // example config: config_HGCROCPedestalCalibParser.txt
0420   //          8,0,37,38,75,76,113,114,151
0421   //          0,/home/ewa/EIC/DATA/HGCROCData/PedestalRun_PairWithRun051/103_PedestalCalib_pedecalib_20251029_182545.json
0422 
0423   // important arrays in .json file: dead channels - includes the list of calibration files that need to be skipped in the channel numbering
0424   //                    pede_values - pedestal values
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   // reading in the calib channels from the config file 
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] );     // first comes the number of calib channels
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   // reading in the list of the .json files
0455   while( std::getline( jsonList, line) ){
0456     std::stringstream   s2(line);
0457     tokens.clear();
0458     while( std::getline( s2, token, ',') )  tokens.push_back( token ); // tokens[0] - KCU number, tokens[1] - path to .json file
0459     kcu = std::stoi( tokens[0] );
0460 
0461     std::ifstream tmpJson ( tokens[1] );
0462     while(std::getline( tmpJson, line ) ){
0463 
0464       // first check if the list of calib channels in the .json file matches the one given in the config
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);    // should only be one, tokens[0]
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       // now lets read in the pedestal values
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);    // should only be one, tokens[0] - pedestal value
0500             if( !IsCalibChannel( channelCounter ) ) {
0501               pedestalValues.push_back( std::stoi( tokens[0] ) );
0502             }
0503           }
0504           channelCounter++;
0505         }
0506       }
0507     }
0508   }
0509 
0510   // now we are looping over the pedestal values, with the int iterator being the HGCROC channel, to exchange the pedestal values in the calib object
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 );       // skipping not connected channels - those with cell_id = -1
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   // fill the tree and write it out to file - should contain just one event
0528   RootOutput->cd();
0529   
0530   // setup 
0531   RootSetupWrapper rswtmp=RootSetupWrapper(setup);
0532   rsw=rswtmp;
0533   TsetupOut->Fill();
0534   TsetupOut->Write();
0535 
0536   // calib
0537   TString   outputCalibTxt  = OutputFilename.ReplaceAll(".root","_calib.txt");
0538   calib.PrintCalibToFile( outputCalibTxt );
0539   TcalibOut->Fill();
0540   TcalibOut->Write();
0541 
0542   // close the file
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 }