0% found this document useful (0 votes)
5 views3 pages

Timeanalysis

The document contains C++ code for analyzing waveform data from ROOT files, focusing on computing the time of arrival (TOA) for voltage signals. It includes functions to validate data, compute a baseline, identify rising edges, and fit the data to determine TOA. Additionally, it processes multiple ROOT files to generate a histogram of time differences between two channels' TOA values.

Uploaded by

Om
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views3 pages

Timeanalysis

The document contains C++ code for analyzing waveform data from ROOT files, focusing on computing the time of arrival (TOA) for voltage signals. It includes functions to validate data, compute a baseline, identify rising edges, and fit the data to determine TOA. Additionally, it processes multiple ROOT files to generate a histogram of time differences between two channels' TOA values.

Uploaded by

Om
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 3

#include <iostream>

#include <vector>
#include <TH1D.h>
#include <TFile.h>
#include <TTree.h>
#include <TGraph.h>
#include <TF1.h>

using namespace std;

// Function to check if a value is valid (not NaN or Inf)


bool isValidValue(double value) {
return !isnan(value) && isfinite(value);
}

// Function to compute baseline level (average of first N samples)


double computeBaseline(const vector<double>& voltage, int numBaselineSamples = 10)
{
double baseline = 0.0;
int count = 0;
for (int i = 0; i < min(numBaselineSamples, (int)voltage.size()); i++) {
if (isValidValue(voltage[i])) {
baseline += voltage[i];
count++;
}
}
return (count > 0) ? baseline / count : 0.0;
}

// Function to find the rising edge region for fitting


pair<int, int> findRisingEdge(const vector<double>& voltage, double baseline,
double riseThreshold = 0.02) {
int startIndex = -1, endIndex = -1;

for (size_t i = 0; i < voltage.size(); i++) {


if (startIndex == -1 && voltage[i] >= baseline + riseThreshold) {
startIndex = i; // Start fitting region
}
if (startIndex != -1 && voltage[i] >= baseline + 0.3) {
endIndex = i; // End fitting region
break;
}
}

if (startIndex == -1 || endIndex == -1) {


return {0, voltage.size() - 1}; // Default to full waveform if edge is
unclear
}
return {startIndex, endIndex};
}

// Function to fit rising edge and compute TOA at the baseline level
double computeTOA(const vector<double>& voltage, const vector<double>& time) {
double baseline = computeBaseline(voltage);
auto [start, end] = findRisingEdge(voltage, baseline);

if (end <= start) return -1; // Invalid fit range

TGraph graph;
for (int i = start; i < end; i++) {
graph.SetPoint(graph.GetN(), time[i], voltage[i]);
}

TF1* fitFunc = new TF1("fitFunc", "pol1", time[start], time[end]);


graph.Fit(fitFunc, "Q");

double a = fitFunc->GetParameter(0); // Intercept


double b = fitFunc->GetParameter(1); // Slope
delete fitFunc;

return (baseline - a) / b; // Time at which the fit crosses the baseline level
}

// Function to compute time difference histogram


void computeTimeDifference(const vector<string>& rootFiles, TH1D* histTimeDiff) {
if (rootFiles.empty()) {
cerr << "❌ Error: No ROOT files provided for time analysis!" << endl;
return;
}

for (const auto& fileName : rootFiles) {


TFile* file = TFile::Open(fileName.c_str(), "READ");
if (!file || file->IsZombie()) {
cerr << "❌ Error: Could not open ROOT file: " << fileName << endl;
continue;
}

TTree* tree = (TTree*)file->Get("WaveformTree");


if (!tree) {
cerr << "❌ Error: Could not find waveform tree in " << fileName <<
endl;
file->Close();
continue;
}

double time;
vector<double> channel1, channel2;

tree->SetBranchAddress("Time", &time);
tree->SetBranchAddress("CH1", &channel1);
tree->SetBranchAddress("CH2", &channel2);

vector<double> timeValues, ch1Waveform, ch2Waveform;

for (int i = 0; i < tree->GetEntries(); i++) {


tree->GetEntry(i);
timeValues.push_back(time);

if (isValidValue(channel1[i])) ch1Waveform.push_back(channel1[i]);
if (isValidValue(channel2[i])) ch2Waveform.push_back(channel2[i]);
}

file->Close();

if (ch1Waveform.empty() || ch2Waveform.empty()) {
cerr << "❌ Skipping file due to empty waveform data!" << endl;
continue;
}
double toaCh1 = computeTOA(ch1Waveform, timeValues);
double toaCh2 = computeTOA(ch2Waveform, timeValues);

if (toaCh1 >= 0 && toaCh2 >= 0) {


double timeDifference = toaCh2 - toaCh1;
histTimeDiff->Fill(timeDifference);
}
}

cout << "✅ Time difference histogram computed successfully!" << endl;
}

You might also like