ANASEN_analysis/anasen_analysis_vignesh/DataDump.C
Sudarsan Balakrishnan b2242ccacd Improved SX3 calibrations, step-ladder correction to pcz.
A lot of the files are identical to old ones, but the main changes are:
1) EXFit2.C in sx3cal
	- Finds front/right gains for each strip using the known middle two pad edges, but gainmatches all backs
2) Define new 'fix' loci, arising from the step-ladder correction to A1C2 events. This is tested in scratch/sx3z_vs_pcz/testmodel.h, will be given a better name in the future.
3) Explore A1C2 and A1C3 loci in detail
4) environment variables to 'flip' and 'offset' wires during sort. All env vars are set in shell scripts that call them
5) environment variables that allow for timestamp bounds to be set and unset. Default limiting values are 0 and dbl_max so no harm done unless these specific env vars are set.
6) Some bookkeeping indicating 27Al instead of 26Al in all places.
2026-04-14 13:45:11 -04:00

640 lines
22 KiB
C

#define DataDump_cxx
#include "DataDump.h"
#include "Armory/ClassPW.h"
#include "Armory/HistPlotter.h"
#include <TH2.h>
#include <TStyle.h>
#include <TCanvas.h>
#include <TMath.h>
#include <TBranch.h>
#include "TVector3.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <map>
#include <utility>
#include <vector>
#include <utility>
#include <algorithm>
// Global instances
PW pw_contr;
PW pwinstance;
TVector3 hitPos;
long long int gcount=0;
class Event {
public:
TVector3 pos;
int ch1=-1; //ring# for QQQ, anode# for PC
int ch2=-1; //wedge# for QQQ, cathode# for PC
double Energy1=-1; //Front for QQQ, Anode for PC
double Energy2=-1; //Back for QQQ, Cathode for PC
double Time1=-1;
double Time2=-1;
Event(TVector3 p, double E1, double E2, double T1, double T2): pos(p), Energy1(E1), Energy2(E2), Time1(T1), Time2(T2) {}
};
/*
void testfunction()
{
for(auto cathode: cathodes) {
std::unordered_set<int> chans;
chans.insert(cathode.ch);
}
}
*/
// Calibration globals
const int MAX_QQQ = 4;
const int MAX_RING = 16;
const int MAX_WEDGE = 16;
double qqqGain[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{0}}};
bool qqqGainValid[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{false}}};
double qqqCalib[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{0}}};
bool qqqCalibValid[MAX_QQQ][MAX_RING][MAX_WEDGE] = {{{false}}};
// TCutg *cutQQQ;
// PC Arrays
double pcSlope[48];
double pcIntercept[48];
HistPlotter *plotter;
bool HitNonZero;
bool sx3ecut;
bool qqqEcut;
void DataDump::Begin(TTree * /*tree*/)
{
TString option = GetOption();
plotter = new HistPlotter("Analyzer_QQQ.root", "TFILE");
pw_contr.ConstructGeo();
pwinstance.ConstructGeo();
// ---------------------------------------------------------
// 1. CRITICAL FIX: Initialize PC Arrays to Default (Raw)
// ---------------------------------------------------------
for (int i = 0; i < 48; i++) {
pcSlope[i] = 1.0; // Default slope = 1 (preserves Raw energy)
pcIntercept[i] = 0.0; // Default intercept = 0
}
// Calculate Crossover Geometry ONCE
TVector3 a, c, diff;
double a2, ac, c2, adiff, cdiff, denom, alpha;
for (size_t i = 0; i < pwinstance.An.size(); i++)
{
a = pwinstance.An[i].first - pwinstance.An[i].second;
for (size_t j = 0; j < pwinstance.Ca.size(); j++)
{
c = pwinstance.Ca[j].first - pwinstance.Ca[j].second;
diff = pwinstance.An[i].first - pwinstance.Ca[j].first;
a2 = a.Dot(a);
c2 = c.Dot(c);
ac = a.Dot(c);
adiff = a.Dot(diff);
cdiff = c.Dot(diff);
denom = a2 * c2 - ac * ac;
alpha = (ac * cdiff - c2 * adiff) / denom;
Crossover[i][j][0].x = pwinstance.An[i].first.X() + alpha * a.X();
Crossover[i][j][0].y = pwinstance.An[i].first.Y() + alpha * a.Y();
Crossover[i][j][0].z = pwinstance.An[i].first.Z() + alpha * a.Z();
if (Crossover[i][j][0].z < -190 || Crossover[i][j][0].z > 190 || (i+j)%24 == 12 )
{
Crossover[i][j][0].z = 9999999;
}
Crossover[i][j][1].x = alpha;
Crossover[i][j][1].y = 0;
}
}
// Load PC Calibrations
std::ifstream inputFile("slope_intercept_results.txt");
if (inputFile.is_open())
{
std::string line;
int index;
double slope, intercept;
while (std::getline(inputFile, line))
{
std::stringstream ss(line);
ss >> index >> slope >> intercept;
if (index >= 0 && index <= 47)
{
pcSlope[index] = slope;
pcIntercept[index] = intercept;
}
}
inputFile.close();
}
else
{
std::cerr << "Error opening slope_intercept.txt" << std::endl;
}
// ... (Load QQQ Gains and Calibs - same as before) ...
{
std::string filename = "qqq_GainMatch.dat";
std::ifstream infile(filename);
if (infile.is_open())
{
int det, ring, wedge;
double gainw, gainr;
while (infile >> det >> wedge >> ring >> gainw >> gainr)
{
qqqGain[det][wedge][ring] = gainw;
qqqGainValid[det][wedge][ring] = (gainw > 0);
}
infile.close();
}
}
{
std::string filename = "qqq_Calib.dat";
std::ifstream infile(filename);
if (infile.is_open())
{
int det, ring, wedge;
double slope;
while (infile >> det >> wedge >> ring >> slope)
{
qqqCalib[det][wedge][ring] = slope;
qqqCalibValid[det][wedge][ring] = (slope > 0);
}
infile.close();
}
}
}
Bool_t DataDump::Process(Long64_t entry)
{
hitPos.Clear();
HitNonZero = false;
bool qqq1000cut = false;
b_sx3Multi->GetEntry(entry);
b_sx3ID->GetEntry(entry);
b_sx3Ch->GetEntry(entry);
b_sx3E->GetEntry(entry);
b_sx3T->GetEntry(entry);
b_qqqMulti->GetEntry(entry);
b_qqqID->GetEntry(entry);
b_qqqCh->GetEntry(entry);
b_qqqE->GetEntry(entry);
b_qqqT->GetEntry(entry);
b_pcMulti->GetEntry(entry);
b_pcID->GetEntry(entry);
b_pcCh->GetEntry(entry);
b_pcE->GetEntry(entry);
b_pcT->GetEntry(entry);
sx3.CalIndex();
qqq.CalIndex();
pc.CalIndex();
// QQQ Processing
int qqqCount = 0;
int qqqAdjCh = 0;
// REMOVE WHEN RERUNNING USING THE NEW CALIBRATION FILE
for (int i = 0; i < qqq.multi; i++)
{
if ((qqq.id[i] == 3 || qqq.id[i] == 1) && qqq.ch[i] < 16)
{
qqq.ch[i] = 16 - qqq.ch[i];
}
}
for (int i = 0; i < qqq.multi; i++)
{
if (qqq.id[i] == 0 && qqq.ch[i] >= 16)
{
qqq.ch[i] = 31 - qqq.ch[i] + 16;
}
}
std::vector<std::tuple<int,int,double,int,double>> qqqlist;
std::vector<Event> QQQ_Events, PC_Events;
std::vector<Event> QQQ_Events_Raw, PC_Events_Raw;
bool PCQQQTimeCut = false;
for (int i = 0; i < qqq.multi; i++)
{
for (int j = i + 1; j < qqq.multi; j++)
{
if (qqq.id[i] == qqq.id[j])
{
qqqCount++;
int chWedge = -1;
int chRing = -1;
double eWedge = 0.0;
double eWedgeMeV = 0.0;
double eRing = 0.0;
double eRingMeV = 0.0;
double tRing = 0.0;
double tWedge = 0.0;
if (qqq.ch[i] < 16 && qqq.ch[j] >= 16 && qqqGainValid[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16])
{
chWedge = qqq.ch[i];
eWedge = qqq.e[i] * qqqGain[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16];
chRing = qqq.ch[j] - 16;
eRing = qqq.e[j];
tRing = static_cast<double>(qqq.t[j]);
tWedge = static_cast<double>(qqq.t[i]);
}
else if (qqq.ch[j] < 16 && qqq.ch[i] >= 16 && qqqGainValid[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16])
{
chWedge = qqq.ch[j];
eWedge = qqq.e[j] * qqqGain[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16];
chRing = qqq.ch[i] - 16;
eRing = qqq.e[i];
tRing = static_cast<double>(qqq.t[i]);
tWedge = static_cast<double>(qqq.t[j]);
}
else
continue;
if (qqqCalibValid[qqq.id[i]][chWedge][chRing]) {
eWedgeMeV = eWedge * qqqCalib[qqq.id[i]][chWedge][chRing] / 1000;
eRingMeV = eRing * qqqCalib[qqq.id[i]][chWedge][chRing] / 1000;
}
else
continue;
double theta = -TMath::Pi() / 2 + 2 * TMath::Pi() / 16 / 4. * (qqq.id[i] * 16 + chWedge + 0.5);
double rho = 50. + 40. / 16. * (chRing + 0.5);
Event qqqevent(TVector3(rho*TMath::Cos(theta),rho*TMath::Sin(theta),23+75+30), eRingMeV, eWedgeMeV, tRing, tWedge);
Event qqqeventr(TVector3(rho*TMath::Cos(theta),rho*TMath::Sin(theta),23+75+30), eRing, eWedge, tRing, tWedge);
QQQ_Events.push_back(qqqevent);
QQQ_Events_Raw.push_back(qqqeventr);
qqqlist.push_back(std::tuple(qqq.id[i],chRing,eRingMeV,chWedge,eWedgeMeV));
} //end if qqq.id[i] == qqq.id[j]
}//inner qqq loop, j
}//outer qqq loop, i
// PC Gain Matching and Filling
double anodeT = -99999;
double cathodeT = 99999;
int anodeIndex = -1;
int cathodeIndex = -1;
int aID = 0;
int cID = 0;
double aE = 0;
double cE = 0;
double aESum = 0;
double cESum = 0;
double aEMax = 0;
int aIDMax = 0;
anodeHits.clear();
cathodeHits.clear();
anodeTimes.clear();
cathodeTimes.clear();
corrcatMax.clear();
corranoMax.clear();
std::array<bool,24> caths_seen{0}, anos_seen{0};
std::vector<std::tuple<int,double,double>> anodeChunks, cathodeChunks;
for (int i = 0; i < pc.multi; i++)
{
if (pc.e[i] > 4)
{
;//plotter->Fill2D("PC_Index_Vs_Energy", 48, 0, 48, 2000, 0, 30000, pc.index[i], static_cast<double>(pc.e[i]), "hRawPC");
} else
continue;
if (pc.index[i] < 48) {
pc.e[i] = pcSlope[pc.index[i]] * pc.e[i] + pcIntercept[pc.index[i]];
//plotter->Fill2D("PC_Index_VS_GainMatched_Energy", 48, 0, 48, 2000, 0, 30000, pc.index[i], pc.e[i], "hGMPC");
}
if (pc.index[i] < 24) {
anodeT = static_cast<double>(pc.t[i]);
anodeIndex = pc.index[i];
anos_seen[anodeIndex] = 1;
anodeHits.push_back(std::pair<int, double>(pc.index[i], pc.e[i]));
anodeTimes.push_back(anodeT);
anodeChunks.push_back(std::tuple<int,double,double>(pc.index[i],anodeT,pc.e[i]));
} else {
cathodeT = static_cast<double>(pc.t[i]);
cathodeIndex = pc.index[i] - 24;
caths_seen[cathodeIndex] = 1;
cathodeChunks.push_back(std::tuple<int,double,double>(pc.index[i]-24,cathodeT,pc.e[i]));
cathodeHits.push_back(std::pair<int, double>(pc.index[i] - 24, pc.e[i]));
cathodeTimes.push_back(cathodeT);
}
}//end of pc.multi loop
if(anodeHits.size() && cathodeHits.size()) {
for(size_t ii=0; ii<anodeHits.size(); ii++) {
const auto& an = anodeHits.at(ii);
const auto& at = anodeTimes.at(ii);
for(size_t jj=0; jj<cathodeHits.size(); jj++) {
const auto& ca = cathodeHits.at(jj);
const auto& ct = cathodeTimes.at(jj);
plotter->Fill2D("ach_minus_cch_vs_ach",60,-30,30,24,0,24,an.first-ca.first,an.first);
plotter->Fill2D("ach_minus_cch_vs_dt",60,-30,30,400,-1000,1000,an.first-ca.first,at-ct);
plotter->Fill2D("ach_vs_cch",24,0,24,24,0,24,an.first,ca.first);
}
}
gcount++;
}
bool all_three = anodeHits.size() > 0 && cathodeHits.size() > 0 && qqqlist.size() > 0;
if(all_three) std::cout << "---" << std::endl;
for(size_t ii=0; ii<anodeHits.size() && all_three; ii++) {
const auto& an = anodeHits.at(ii);
const auto& at = anodeTimes.at(ii);
std::cout << "an" << std::setprecision(16) << ", " << an.first << ", " << an.second << ", " << at << " ,-1, -1" << std::endl;
}
for(size_t jj=0; jj<cathodeHits.size() && all_three; jj++) {
const auto& ca = cathodeHits.at(jj);
const auto& ct = cathodeTimes.at(jj);
std::cout << "ca" << std::setprecision(16) << ", " << ca.first << ", " << ca.second << ", " << ct << " ,-1, -1" << std::endl;
}
for(size_t jj=0; jj<qqqlist.size() && all_three; jj++) {
const auto[id,chr,er,chw,ew] = qqqlist.at(jj);
std::cout << "q" << std::setprecision(16) << ", " << id << ", " << chr << ", " << er << ", " << chw << ", " << ew << std::endl;
}
if(all_three) std::cout << " --end-- " << std::endl;
if(gcount == 100)
return -1;
// std::sort(anodeChunks.begin(),anodeChunks.end(),);
if (anodeHits.size() >= 1 && cathodeHits.size() >= 1)
{
// 2. CRITICAL FIX: Define reference vector 'a'
// In Analyzer.cxx, 'a' was left over from the loop. We use the first anode wire as reference here.
// (Assuming pwinstance.An is populated and wires are generally parallel).
TVector3 refAnode = pwinstance.An[0].first - pwinstance.An[0].second;
for (const auto &anode : anodeHits)
{
aID = anode.first;
aE = anode.second;
aESum += aE;
if (aE > aEMax)
{
aEMax = aE;
aIDMax = aID;
}
}
for (const auto &cathode : cathodeHits)
{
cID = cathode.first;
cE = cathode.second;
for (int j = -4; j < 3; j++)
{
if ((aIDMax + 24 + j) % 24 == 23 - cID)
{
corrcatMax.push_back(std::pair<int, double>(cID, cE));
cESum += cE;
}
}
}
}
TVector3 anodeIntersection;
anodeIntersection.Clear();
if (corrcatMax.size() > 0)
{
double x = 0, y = 0, z = 0;
for (const auto &corr : corrcatMax)
{
if (Crossover[aIDMax][corr.first][0].z > 9000000)
continue;
if (cESum > 0)
{
x += (corr.second) / cESum * Crossover[aIDMax][corr.first][0].x;
y += (corr.second) / cESum * Crossover[aIDMax][corr.first][0].y;
z += (corr.second) / cESum * Crossover[aIDMax][corr.first][0].z;
}
}
if (x == 0 && y == 0 && z == 0)
;
// to ignore events with no valid crossover points
else
anodeIntersection = TVector3(x, y, z);
}
bool PCQQQPhiCut = false;
// flip the algorithm for cathode 1 multi anode events
if ((hitPos.Phi() > (anodeIntersection.Phi() - TMath::PiOver4())) && (hitPos.Phi() < (anodeIntersection.Phi() + TMath::PiOver4()))) {
PCQQQPhiCut = true;
}
if (anodeIntersection.Z() != 0)
{
plotter->Fill1D("PC_Z_Projection", 600, -300, 300, anodeIntersection.Z(), "hPCzQQQ");
plotter->Fill2D("Z_Proj_VsDelTime", 600, -300, 300, 200, -2000, 2000, anodeIntersection.Z(), anodeT - cathodeT, "hPCzQQQ");
plotter->Fill2D("IntPhi_vs_QQQphi", 100, -200, 200, 80, -200, 200, anodeIntersection.Phi() * 180. / TMath::Pi(), hitPos.Phi() * 180. / TMath::Pi(), "hPCQQQ");
plotter->Fill2D("Inttheta_vs_QQQtheta", 90, 0, 180, 20, 0, 45, anodeIntersection.Theta() * 180. / TMath::Pi(), hitPos.Theta() * 180. / TMath::Pi(), "hPCQQQ");
plotter->Fill2D("Inttheta_vs_QQQtheta_TC" + std::to_string(PCQQQTimeCut), 90, 0, 180, 20, 0, 45, anodeIntersection.Theta() * 180. / TMath::Pi(), hitPos.Theta() * 180. / TMath::Pi(), "hPCQQQ");
plotter->Fill2D("IntPhi_vs_QQQphi_TC" + std::to_string(PCQQQTimeCut) + "PhiC" + std::to_string(PCQQQPhiCut), 100, -200, 200, 80, -200, 200, anodeIntersection.Phi() * 180. / TMath::Pi(), hitPos.Phi() * 180. / TMath::Pi(), "hPCQQQ");
}
if (anodeIntersection.Z() != 0 && cathodeHits.size() >= 2)
plotter->Fill1D("PC_Z_Projection_TC" + std::to_string(PCQQQTimeCut) + "PhiC" + std::to_string(PCQQQPhiCut), 600, -300, 300, anodeIntersection.Z(), "hPCzQQQ");
if (anodeIntersection.Z() != 0 && cathodeHits.size() == 1)
{
plotter->Fill1D("PC_Z_proj_1C", 600, -300, 300, anodeIntersection.Z(), "hPCzQQQ");
plotter->Fill2D("IntersectionPhi_vs_AnodeZ_1C", 400, -200, 200, 600, -300, 300, anodeIntersection.Phi() * 180. / TMath::Pi(), anodeIntersection.Z(), "hPCzQQQ");
}
if (anodeIntersection.Z() != 0 && cathodeHits.size() == 2)
{
plotter->Fill1D("PC_Z_proj_2C", 600, -300, 300, anodeIntersection.Z(), "hPCzQQQ");
plotter->Fill2D("IntersectionPhi_vs_AnodeZ_2C", 400, -200, 200, 600, -300, 300, anodeIntersection.Phi() * 180. / TMath::Pi(), anodeIntersection.Z(), "hGMPC");
}
if (anodeIntersection.Z() != 0 && cathodeHits.size() > 2)
{
plotter->Fill1D("PC_Z_proj_nC", 600, -300, 300, anodeIntersection.Z(), "hPCzQQQ");
plotter->Fill2D("IntersectionPhi_vs_AnodeZ_nC", 400, -200, 200, 600, -300, 300, anodeIntersection.Phi() * 180. / TMath::Pi(), anodeIntersection.Z(), "hGMPC");
}
if (anodeHits.size() > 0 && cathodeHits.size() > 0)
plotter->Fill2D("AHits_vs_CHits", 12, 0, 11, 6, 0, 5, anodeHits.size(), cathodeHits.size(), "hRawPC");
// make another plot with nearest neighbour constraint
bool hasNeighbourAnodes = false;
bool hasNeighbourCathodes = false;
// 1. Check Anodes for neighbours (including wrap-around 0-23)
for (size_t i = 0; i < anodeHits.size(); i++)
{
for (size_t j = i + 1; j < anodeHits.size(); j++)
{
int diff = std::abs(anodeHits[i].first - anodeHits[j].first);
if (diff == 1 || diff == 23)
{ // 23 handles the cylindrical wrap
hasNeighbourAnodes = true;
break;
}
}
if (hasNeighbourAnodes)
break;
}
// 2. Check Cathodes for neighbours (including wrap-around 0-23)
for (size_t i = 0; i < cathodeHits.size(); i++)
{
for (size_t j = i + 1; j < cathodeHits.size(); j++)
{
int diff = std::abs(cathodeHits[i].first - cathodeHits[j].first);
if (diff == 1 || diff == 23)
{
hasNeighbourCathodes = true;
break;
}
}
if (hasNeighbourCathodes)
break;
}
// ---------------------------------------------------------
// FILL PLOTS
// ---------------------------------------------------------
if (anodeHits.size() > 0 && cathodeHits.size() > 0)
{
plotter->Fill2D("AHits_vs_CHits_NA" + std::to_string(hasNeighbourAnodes), 12, 0, 11, 6, 0, 5, anodeHits.size(), cathodeHits.size(), "hRawPC");
plotter->Fill2D("AHits_vs_CHits_NC" + std::to_string(hasNeighbourCathodes), 12, 0, 11, 6, 0, 5, anodeHits.size(), cathodeHits.size(), "hRawPC");
// Constraint Plot: Only fill if BOTH planes have adjacent hits
// This effectively removes events with only isolated single-wire hits (noise)
if (hasNeighbourAnodes && hasNeighbourCathodes)
{
plotter->Fill2D("AHits_vs_CHits_NN", 12, 0, 11, 6, 0, 5, anodeHits.size(), cathodeHits.size(), "hRawPC");
}
}
if (HitNonZero && anodeIntersection.Z() != 0)
{
pw_contr.CalTrack2(hitPos, anodeIntersection);
plotter->Fill1D("VertexRecon", 600, -300, 300, pw_contr.GetZ0());
plotter->Fill1D("VertexRecon_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 600, -300, 300, pw_contr.GetZ0());
if (cathodeHits.size() == 2)
plotter->Fill1D("VertexRecon_2c_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 600, -300, 300, pw_contr.GetZ0());
}
for (int i = 0; i < qqq.multi; i++)
{
if (PCQQQTimeCut)
{
plotter->Fill2D("PC_XY_Projection_QQQ_TimeCut" + std::to_string(qqq.id[i]), 400, -100, 100, 400, -100, 100, anodeIntersection.X(), anodeIntersection.Y(), "hPCQQQ");
}
plotter->Fill2D("PC_XY_Projection_QQQ" + std::to_string(qqq.id[i]), 400, -100, 100, 400, -100, 100, anodeIntersection.X(), anodeIntersection.Y(), "hPCQQQ");
for (int j = i + 1; j < qqq.multi; j++)
{
if (qqq.id[i] == qqq.id[j])
{
int chWedge = -1;
int chRing = -1;
double eWedge = 0.0;
double eWedgeMeV = 0.0;
double eRing = 0.0;
double eRingMeV = 0.0;
double tRing = 0.0;
int qqqID = -1;
if (qqq.ch[i] < 16 && qqq.ch[j] >= 16 && qqqGainValid[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16])
{
chWedge = qqq.ch[i];
eWedge = qqq.e[i] * qqqGain[qqq.id[i]][qqq.ch[i]][qqq.ch[j] - 16];
chRing = qqq.ch[j] - 16;
eRing = qqq.e[j];
tRing = static_cast<double>(qqq.t[j]);
qqqID = qqq.id[i];
}
else if (qqq.ch[j] < 16 && qqq.ch[i] >= 16 && qqqGainValid[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16])
{
chWedge = qqq.ch[j];
eWedge = qqq.e[j] * qqqGain[qqq.id[j]][qqq.ch[j]][qqq.ch[i] - 16];
chRing = qqq.ch[i] - 16;
tRing = static_cast<double>(qqq.t[i]);
eRing = qqq.e[i];
qqqID = qqq.id[i];
}
else
continue;
if (qqqCalibValid[qqq.id[i]][chRing][chWedge])
{
eWedgeMeV = eWedge * qqqCalib[qqq.id[i]][chRing][chWedge] / 1000;
eRingMeV = eRing * qqqCalib[qqq.id[i]][chRing][chWedge] / 1000;
}
else
continue;
// if (anodeIntersection.Z() != 0)
{
plotter->Fill2D("PC_Z_vs_QQQRing", 600, -300, 300, 16, 0, 16, anodeIntersection.Z(), chRing, "hPCzQQQ");
}
if (anodeIntersection.Z() != 0 && cathodeHits.size() == 2)
{
plotter->Fill2D("PC_Z_vs_QQQRing_2C", 600, -300, 300, 16, 0, 16, anodeIntersection.Z(), chRing, "hPCzQQQ");
plotter->Fill2D("PC_Z_vs_QQQRing_2C" + std::to_string(qqq.id[i]), 600, -300, 300, 16, 0, 16, anodeIntersection.Z(), chRing, "hPCzQQQ");
plotter->Fill2D("PC_Z_vs_QQQWedge_2C", 600, -300, 300, 16, 0, 16, anodeIntersection.Z(), chWedge, "hPCzQQQ");
}
plotter->Fill2D("Vertex_V_QQQRingTC" + std::to_string(PCQQQTimeCut) + "PhiC" + std::to_string(PCQQQPhiCut), 600, -300, 300, 16, 0, 16, pw_contr.GetZ0(), chRing, "hPCQQQ");
double phi = TMath::ATan2(anodeIntersection.Y(), anodeIntersection.X()) * 180. / TMath::Pi();
plotter->Fill2D("PolarAngle_Vs_QQQWedge" + std::to_string(qqqID), 360, -360, 360, 16, 0, 16, phi, chWedge, "hPCQQQ");
// plotter->Fill2D("EdE_PC_vs_QQQ_timegate_ls1000"+std::to_string())
plotter->Fill2D("PC_Z_vs_QQQRing_Det" + std::to_string(qqqID), 600, -300, 300, 16, 0, 16, anodeIntersection.Z(), chRing, "hPCQQQ");
//double theta = -TMath::Pi() / 2 + 2 * TMath::Pi() / 16 / 4. * (qqq.id[i] * 16 + chWedge + 0.5);
//double rho = 50. + 40. / 16. * (chRing + 0.5);
for (int k = 0; k < pc.multi; k++)
{
if(pc.index[k] >= 24)
continue;
double sinTheta = TMath::Sin(hitPos.Theta());
plotter->Fill2D("CalibratedQQQE_RvsPCE_TC" + std::to_string(PCQQQTimeCut) + "PhiC" + std::to_string(PCQQQPhiCut), 1000, 0, 10, 2000, 0, 30000, eRingMeV, pc.e[k]*sinTheta, "hPCQQQ");
plotter->Fill2D("CalibratedQQQE_WvsPCE_TC" + std::to_string(PCQQQTimeCut) + "PhiC" + std::to_string(PCQQQPhiCut), 1000, 0, 10, 2000, 0, 30000, eWedgeMeV, pc.e[k]*sinTheta, "hPCQQQ");
plotter->Fill2D("PCQQQ_dTimevsdPhi", 200, -2000, 2000, 80, -200, 200, tRing - static_cast<double>(pc.t[k]), (hitPos.Phi()-anodeIntersection.Phi()) * 180. / TMath::Pi(), "hTiming");
}
}
}
}
for (int i = 0; i < sx3.multi; i++)
{
// plotting sx3 strip hits vs anode phi
if (sx3.ch[i] < 8)
plotter->Fill2D("AnodePhi_vs_SX3Strip", 100, -200, 200, 8 * 24, 0, 8 * 24, anodeIntersection.Phi() * 180. / TMath::Pi(), sx3.id[i] * 8 + sx3.ch[i]);
}
if (anodeIntersection.Z() != 0 && cathodeHits.size() == 3)
{
plotter->Fill1D("PC_Z_proj_3C", 600, -300, 300, anodeIntersection.Z(), "hPCzQQQ");
}
plotter->Fill2D("AnodeMaxE_Vs_Cathode_Sum_Energy", 2000, 0, 30000, 2000, 0, 30000, aEMax, cESum, "hGMPC");
plotter->Fill1D("Correlated_Cathode_MaxAnode", 6, 0, 5, corrcatMax.size(), "hGMPC");
plotter->Fill2D("Correlated_Cathode_VS_MaxAnodeEnergy", 6, 0, 5, 2000, 0, 30000, corrcatMax.size(), aEMax, "hGMPC");
plotter->Fill1D("AnodeHits", 12, 0, 11, anodeHits.size(), "hGMPC");
plotter->Fill2D("AnodeMaxE_vs_AnodeHits", 12, 0, 11, 2000, 0, 30000, anodeHits.size(), aEMax, "hGMPC");
if (anodeHits.size() < 1)
{
plotter->Fill1D("NoAnodeHits_CathodeHits", 6, 0, 5, cathodeHits.size(), "hGMPC");
}
return kTRUE;
}
void DataDump::Terminate()
{
plotter->FlushToDisk();
}