diff --git a/Armory/ANASEN_model.C b/Armory/ANASEN_model.C index e21d4c6..72bc262 100644 --- a/Armory/ANASEN_model.C +++ b/Armory/ANASEN_model.C @@ -42,7 +42,7 @@ void ANASEN_model(int anodeID1 = -1, int anodeID2 = -1, int cathodeID1 = -1, int //--- making ANASEN const int nWire = 24; const int wireShift = 3; - const int zLen = 300; //mm + const int zLen = 350; //mm const int radiusA = 38; const int radiusC = 43; diff --git a/Armory/ClassPW.h b/Armory/ClassPW.h old mode 100644 new mode 100755 index 92e015c..81ae0be --- a/Armory/ClassPW.h +++ b/Armory/ClassPW.h @@ -2,6 +2,7 @@ #define ClassPW_h #include +#include #include #include #include @@ -61,6 +62,14 @@ public: double GetTrackPhi() const { return trackVec.Phi(); } double GetZ0(); + inline std::tuple, double, double, double> GetPseudoWire(const std::vector>& cluster, std::string type); + + inline std::tuple + FindCrossoverProperties(const std::vector>& a_cluster, const std::vector>& c_cluster); + + inline std::vector>> + Make_Clusters(std::unordered_map> wireEvents); + int GetNumWire() const { return nWire; } double GetDeltaAngle() const { return dAngle; } double GetAnodeLength() const { return anodeLength; } @@ -105,7 +114,8 @@ private: const int nWire = 24; const int wireShift = 3; - const float zLen = 380; // mm + // const float zLen = 380; // mm + const float zLen = 348.6; // mm const float radiusA = 37; const float radiusC = 43; @@ -171,7 +181,160 @@ inline void PW::ConstructGeo() dAngle = wireShift * TMath::TwoPi() / nWire; anodeLength = TMath::Sqrt(zLen * zLen + TMath::Power(2 * radiusA * TMath::Sin(dAngle / 2), 2)); - cathodeLength = TMath::Sqrt(zLen * zLen + TMath::Power(2 * radiusC * TMath::Sin(dAngle / 2), 2)); + cathodeLength = TMath::Sqrt(zLen * zLen + TMath::Power(2 * radiusC * TMath::Sin(dAngle / 2), 2)); //chord length subtending an angle alpha is 2rsin(alpha/2) +} + +inline std::vector>> +PW::Make_Clusters(std::unordered_map> wireEvents) { + std::vector>> wireClusters; + std::vector> wireCluster; + //TODO: Write a macro once, call it twice + int wirecount=0; + while(wirecount < 24) { + if(wireEvents.find(wirecount)==wireEvents.end()) { + wirecount++; + continue; + } + wireCluster.clear(); + int ctr2=wirecount; + do { + wireCluster.emplace_back(wireEvents[ctr2]); + ctr2+=1; + if(ctr2==24 || ctr2-wirecount == 7) break; //loose logic, needs to be looked at. + } while(wireEvents.find(ctr2)!=wireEvents.end()); + wireClusters.push_back(std::move(wireCluster)); + wirecount = ctr2; //we already dealt with wires until the last value of ctr2 + } + + if(wireClusters.size() > 1) { //Deal with wraparound if required + auto first_cluster = wireClusters.front(); //front and back provide references to the elements themselves. less copy, can modify etc + auto last_cluster = wireClusters.back(); + if(std::get<0>(last_cluster.back())==23 && std::get<0>(first_cluster.front())==0) { + last_cluster.insert(last_cluster.end(),first_cluster.begin(),first_cluster.end()); + } + wireClusters.erase(wireClusters.begin()); //canonically, erase() needs an iterator, hence begin() not front() + //TODO: Can also deal with 'gaps' of missing wires similarly. end of one segment and beginning of another segment will be separated by missing wire --> combine the two + //TODO: Also needs some development regarding the time-correlation. Don't put wires in the same cluster if they aren't time coincident + } + return wireClusters; + + /*if(aClusters.size()>1 || cClusters.size() > 1) { + std::cout << " ============== " << std::endl; + } + if(aClusters.size()>1 && cClusters.size() >=1) { + std::cout << aClusters.size() << " new anode clusters ----> " << std::endl; + int cc=1; + for(auto ac : aClusters) { + std::cout << " Cluster " << cc << std::endl; + double first_ts = std::get<2>(ac.at(0)); + for(auto item : ac) { + std::cout << " \t" << std::get<0>(item) << " " << std::get<1>(item) << " " << std::get<2>(item)-first_ts << std::endl; + } + std::cout << " ------" << std::endl; + cc++; + } + } + + if(cClusters.size()>=1 ) { + std::cout << cClusters.size() << " new cathode clusters ----> " << std::endl; + int cc=1; + for(auto ac : cClusters) { + std::cout << " Cluster " << cc << std::endl; + double first_ts = std::get<2>(ac.at(0)); + for(auto item : ac) { + std::cout << " \t" << std::get<0>(item) << " " << std::get<1>(item) << " " << std::get<2>(item)-first_ts << std::endl; + } + std::cout << " ------" << std::endl; + cc++; + } + } */ +} + +inline std::tuple, double, double, double> +PW::GetPseudoWire(const std::vector>& cluster, std::string type) { + std::pair avgvec = std::pair(TVector3(0,0,0),TVector3(0,0,0)); + double sumEnergy = 0; + double maxEnergy = 0; + double tsMaxEnergy = 0; + if(type=="ANODE") { + //if(cluster.size()>1) std::cout << " -------anodes" << std::endl; + for( auto wire : cluster) { + avgvec.first += std::get<1>(wire)*TVector3(An.at(std::get<0>(wire)).first.X(), An.at(std::get<0>(wire)).first.Y(), 0) ; + avgvec.second += std::get<1>(wire)*TVector3(An.at(std::get<0>(wire)).second.X(), An.at(std::get<0>(wire)).second.Y(), 0); + sumEnergy += std::get<1>(wire); + if(std::get<1>(wire) > maxEnergy) { + maxEnergy = std::get<1>(wire); + tsMaxEnergy = std::get<2>(wire); + } + /*if(cluster.size()>1) { + std::cout << "\t\t ch:" << std::get<0>(wire) << " " << std::get<1>(wire) << " " << std::get<2>(wire) << std::endl; + std::cout << "\t\t w1(r,phi,z):" << An.at(std::get<0>(wire)).first.Perp() << " " << An.at(std::get<0>(wire)).first.Phi()*180/M_PI << " " << An.at(std::get<0>(wire)).first.Z() << std::endl; + std::cout << "\t\t w2(r,phi,z):" << An.at(std::get<0>(wire)).second.Perp() << " " << An.at(std::get<0>(wire)).second.Phi()*180/M_PI << " " << An.at(std::get<0>(wire)).second.Z() << std::endl; + }*/ + } + avgvec.first = avgvec.first*(1.0/sumEnergy); + avgvec.second = avgvec.second*(1.0/sumEnergy); + double phi1 = avgvec.first.Phi(); + double phi2 = avgvec.second.Phi(); + avgvec.first.SetXYZ(radiusA*TMath::Cos(phi1), radiusA*TMath::Sin(phi1), zLen/2); + avgvec.second.SetXYZ(radiusA*TMath::Cos(phi2), radiusA*TMath::Sin(phi2), -zLen/2); + /*if(cluster.size()>1) { + std::cout << "\t\t avg1(r,phi,z):" << avgvec.first.Perp() << " " << avgvec.first.Phi()*180/M_PI << " " << avgvec.first.Z() << std::endl; + std::cout << "\t\t avg2(r,phi,z):" << avgvec.second.Perp() << " " << avgvec.second.Phi()*180/M_PI << " " << avgvec.second.Z() << std::endl; + }*/ + } else if(type =="CATHODE") { + for( auto wire : cluster) { + avgvec.first += std::get<1>(wire)*TVector3(Ca.at(std::get<0>(wire)).first.X(), Ca.at(std::get<0>(wire)).first.Y(), 0) ; + avgvec.second += std::get<1>(wire)*TVector3(Ca.at(std::get<0>(wire)).second.X(), Ca.at(std::get<0>(wire)).second.Y(), 0); + sumEnergy += std::get<1>(wire); + if(std::get<1>(wire) > maxEnergy) { + maxEnergy = std::get<1>(wire); + tsMaxEnergy = std::get<2>(wire); + } + } + avgvec.first = avgvec.first*(1.0/sumEnergy); + avgvec.second = avgvec.second*(1.0/sumEnergy); + double phi1 = avgvec.first.Phi(); + double phi2 = avgvec.second.Phi(); + avgvec.first.SetXYZ(radiusC*TMath::Cos(phi1), radiusC*TMath::Sin(phi1), zLen/2); + avgvec.second.SetXYZ(radiusC*TMath::Cos(phi2), radiusC*TMath::Sin(phi2), -zLen/2); + } + return std::tuple(avgvec, sumEnergy, maxEnergy, tsMaxEnergy); +} + +inline std::tuple PW::FindCrossoverProperties(const std::vector>& a_cluster, + const std::vector>& c_cluster) { + //std::pair apwire = GetPseudoWire(a_cluster,"ANODE",anodeSumE); + //std::pair cpwire = GetPseudoWire(c_cluster,"CATHODE",cathodeSumE); + auto [apwire, apSumE, apMaxE, apTSMaxE] = GetPseudoWire(a_cluster,"ANODE"); + auto [cpwire, cpSumE, cpMaxE, cpTSMaxE] = GetPseudoWire(c_cluster,"CATHODE"); + + TVector3 crossover; + crossover.Clear(); + TVector3 a, c, diff; + double a2, ac, c2, adiff, cdiff, denom, alpha=0; + + if(apSumE && cpSumE) { + a = apwire.first - apwire.second; + c = cpwire.first - cpwire.second; + diff = apwire.first - cpwire.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 = apwire.first + alpha*a; + if(crossover.z() < -190 || crossover.Z() > 190 ) { + alpha = 9999999; + apSumE=-1; cpSumE=-1; + apMaxE=-1; cpMaxE=-1; + apTSMaxE=-1; cpTSMaxE=-1; + } + } + //std::cout << apSumE << " " << cpSumE << " " << " " << crossover.Perp() << std::endl; + return std::tuple(crossover,alpha,apSumE,cpSumE,apMaxE,cpMaxE,apTSMaxE,cpTSMaxE); } inline void PW::FindWireID(TVector3 pos, TVector3 direction, bool verbose) @@ -301,6 +464,18 @@ inline void PW::CalTrack2(TVector3 siPos, TVector3 anodeInt, bool verbose) printf("X slope = %f and Y slope = %f \n", mx, my); } +/*inline TVector3 PW::CalTrack3(TVector3 siPos, TVector3 anodeInt, bool verbose) +{ + + TVector3 v = anodeInt-siPos; + double t_minimum = -1.0*(siPos.X()*v.X()+siPos.Y()*v.Y())/(v.X()*v.X()+v.Y()*v.Y()); + TVector3 vector_closest_to_z = siPos + t_minimum*v; + + return vector_closest_to_z; + if (verbose) + printf("X slope = %f and Y slope = %f \n", mx, my); +}*/ + inline double PW::GetZ0() { @@ -312,4 +487,4 @@ inline double PW::GetZ0() return trackVec.Z(); } -#endif \ No newline at end of file +#endif diff --git a/MakeVertex.C b/MakeVertex.C old mode 100644 new mode 100755 index c1a18b4..a8d4ab1 --- a/MakeVertex.C +++ b/MakeVertex.C @@ -24,14 +24,28 @@ PW pwinstance; TVector3 hitPos; double qqqenergy, qqqtimestamp; -struct Event { - TVector3 pos; - double Energy1=-1; //Front for QQQ, Anode for PC - double Energy2=-1; //Back for QQQ, Cathode for PC - double Time1=-1; - double Time2=-1; +class Event +{ +public: + Event(TVector3 p, double e1, double e2, double t1, double t2) : pos(p), Energy1(e1), Energy2(e2), Time1(t1), Time2(t2) {} + Event(TVector3 p, double e1, double e2, double t1, double t2, int c1, int c2) : pos(p), Energy1(e1), Energy2(e2), Time1(t1), Time2(t2), ch2(c1), ch1(c1) {} + + TVector3 pos; + int ch1 = -1; // int(ch1/16) gives qqq id, ch1%16 gives ring# + int ch2 = -1; // int(ch2/16) gives qqq id, ch2%16 gives wedge# + double Energy1 = -1; // Front for QQQ, Anode for PC + double Energy2 = -1; // Back for QQQ, Cathode for PC + double Time1 = -1; + double Time2 = -1; }; +/*std::vector +Make_QQQClusters(const std::unordered_map& qqqvec) { + std::vector qqqevents; //input events, but combine NN energies + + +}*/ + // Calibration globals const int MAX_QQQ = 4; const int MAX_RING = 16; @@ -93,7 +107,7 @@ void MakeVertex::Begin(TTree * /*tree*/) 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) + if (Crossover[i][j][0].z < -190 || Crossover[i][j][0].z > 190 || (i + j) % 24 == 12) { Crossover[i][j][0].z = 9999999; } @@ -185,7 +199,7 @@ Bool_t MakeVertex::Process(Long64_t entry) { hitPos.Clear(); qqqenergy = -1; - qqqtimestamp=-1; + qqqtimestamp = -1; HitNonZero = false; bool qqq1000cut = false; b_sx3Multi->GetEntry(entry); @@ -208,35 +222,63 @@ Bool_t MakeVertex::Process(Long64_t entry) qqq.CalIndex(); pc.CalIndex(); + // if(sx3.multi>1) { + // std::cout << "-----" << std::endl; + // for(int i=0; i= 16) - { - qqq.ch[i] = 31 - qqq.ch[i] + 16; - } - } + // for (int i = 0; i < qqq.multi; i++) + // { + // //if ((qqq.id[i] == 3 || qqq.id[i] == 1) && qqq.ch[i] < 16) + // if (qqq.id[i] == 1 && qqq.ch[i] < 16) //for run 12, 26Al + // { + // 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 QQQ_Events, PC_Events; std::vector QQQ_Events_Raw, PC_Events_Raw; + std::unordered_map> qvecr[4], qvecw[4]; + if (qqq.multi > 1) + { + // std::cout << "------" << std::endl; + for (int i = 0; i < qqq.multi; i++) + { + // std::cout << std::setprecision(16) << "qqq"<< qqq.id[i] << " " << std::string(qqq.ch[i]/16?"ring":"wedge") << qqq.ch[i]%16 << " " << qqq.e[i] << " " << qqq.t[i] - qqq.t[0] << std::endl; + if (qqq.ch[i] / 16) + { + if (qvecr[qqq.id[i]].find(qqq.ch[i]) != qvecr[qqq.id[i]].end()) + std::cout << "mayday!" << std::endl; + qvecr[qqq.id[i]][qqq.ch[i]] = std::tuple(qqq.id[i], qqq.ch[i], qqq.e[i], qqq.t[i]); + } + else + { + if (qvecw[qqq.id[i]].find(qqq.ch[i]) != qvecw[qqq.id[i]].end()) + std::cout << "mayday!" << std::endl; + qvecw[qqq.id[i]][qqq.ch[i]] = std::tuple(qqq.id[i], qqq.ch[i], qqq.e[i], qqq.t[i]); + } + } + } + // Now, qvecr[i] has all ring events of qqq#i, qvecw[i] has all wedge events of bool PCQQQTimeCut = false; for (int i = 0; i < qqq.multi; i++) { - plotter->Fill2D("QQQ_Index_Vs_Energy", 16 * 8, 0, 16 * 8, 2000, 0, 16000, qqq.index[i], qqq.e[i], "hRawQQQ"); for (int j = 0; j < qqq.multi; j++) @@ -303,11 +345,30 @@ Bool_t MakeVertex::Process(Long64_t entry) { eWedgeMeV = eWedge * qqqCalib[qqq.id[i]][chWedge][chRing] / 1000; eRingMeV = eRing * qqqCalib[qqq.id[i]][chWedge][chRing] / 1000; + + if (eRingMeV / eWedgeMeV > 3.0 || eRingMeV / eWedgeMeV < 1.0 / 3.0) + continue; + // if(eRingMeV<4.0 || eWedgeMeV<4.0) continue; + + double theta = -TMath::Pi() / 2 + 2 * TMath::Pi() / 16 / 4. * (qqq.id[i] * 16 + chWedge + 0.5); + double rho = 50. + (50. / 16.) * (chRing + 0.5); //"?" + + Event qqqevent(TVector3(rho * TMath::Cos(theta), rho * TMath::Sin(theta), 100), eRingMeV, eWedgeMeV, tRing, tWedge, chRing + qqq.id[i] * 16, chWedge + qqq.id[i] * 16); + Event qqqeventr(TVector3(rho * TMath::Cos(theta), rho * TMath::Sin(theta),100), eRing, eWedge, tRing, tWedge, chRing + qqq.id[i] * 16, chWedge + qqq.id[i] * 16); + QQQ_Events.push_back(qqqevent); + QQQ_Events_Raw.push_back(qqqeventr); + plotter->Fill2D("QQQCartesianPlot", 200, -100, 100, 200, -100, 100, rho * TMath::Cos(theta), rho * TMath::Sin(theta), "hCalQQQ"); + plotter->Fill2D("QQQCartesianPlot" + std::to_string(qqq.id[i]), 200, -100, 100, 200, -100, 100, rho * TMath::Cos(theta), rho * TMath::Sin(theta), "hCalQQQ"); + if (PCQQQTimeCut) + { + plotter->Fill2D("PC_XY_Projection_QQQ_TimeCut" + std::to_string(qqq.id[i]), 400, -100, 100, 400, -100, 100, rho * TMath::Cos(theta), rho * TMath::Sin(theta), "hPCQQQ"); + } + plotter->Fill2D("PC_XY_Projection_QQQ" + std::to_string(qqq.id[i]), 400, -100, 100, 400, -100, 100, rho * TMath::Cos(theta), rho * TMath::Sin(theta), "hPCQQQ"); } else continue; + plotter->Fill2D("WedgeE_Vs_RingECal", 1000, 0, 10, 1000, 0, 10, eWedgeMeV, eRingMeV, "hCalQQQ"); - if(eRingMeV/eWedgeMeV > 3.0 || eRingMeV/eWedgeMeV<1.0/3.0) continue; plotter->Fill2D("WedgeE_Vs_RingECal_selected", 1000, 0, 10, 1000, 0, 10, eWedgeMeV, eRingMeV, "hCalQQQ"); for (int k = 0; k < pc.multi; k++) @@ -320,68 +381,53 @@ Bool_t MakeVertex::Process(Long64_t entry) if (pc.index[k] < 24 && pc.e[k] > 50) { - // plotter->Fill2D("QQQ_CalibW_Vs_PC_Energy", 1000, 0, 16, 2000, 0, 30000, eWedgeMeV, pc.e[k], "hCalQQQ"); - // plotter->Fill2D("QQQ_CalibR_Vs_PC_Energy", 1000, 0, 16, 2000, 0, 30000, eRingMeV, pc.e[k], "hCalQQQ"); - - // if (tRing - static_cast(pc.t[k]) < 0 && tRing - static_cast(pc.t[k]) > -600) - // // { - // // plotter->Fill2D("QQQ_CalibW_Vs_PC_Energy_Tight", 1000, 0, 16, 2000, 0, 30000, eWedgeMeV, pc.e[k], "hCalQQQ"); - // // plotter->Fill2D("QQQ_CalibR_Vs_PC_Energy_Tight", 1000, 0, 16, 2000, 0, 30000, eRingMeV, pc.e[k], "hCalQQQ"); - // // } - // // else - // // { - // // plotter->Fill2D("QQQ_CalibW_Vs_PC_Energy_OffTime", 1000, 0, 16, 2000, 0, 30000, eWedgeMeV, pc.e[k], "hCalQQQ"); - // // plotter->Fill2D("QQQ_CalibR_Vs_PC_Energy_OffTime", 1000, 0, 16, 2000, 0, 30000, eRingMeV, pc.e[k], "hCalQQQ"); - // // } plotter->Fill2D("Timing_Difference_QQQ_PC", 500, -2000, 2000, 16, 0, 16, tRing - static_cast(pc.t[k]), chRing, "hTiming"); plotter->Fill2D("DelT_Vs_QQQRingECal", 500, -2000, 2000, 1000, 0, 10, tRing - static_cast(pc.t[k]), eRingMeV, "hTiming"); - plotter->Fill2D("CalibratedQQQEvsPCE_R", 1000, 0, 10, 2000, 0, 30000, eRingMeV, pc.e[k], "hPCQQQ"); - plotter->Fill2D("CalibratedQQQEvsPCE_W", 1000, 0, 10, 2000, 0, 30000, eWedgeMeV, pc.e[k], "hPCQQQ"); + plotter->Fill2D("CalibratedQQQEvsPCE_R", 1000, 0, 10, 2000, 0, 200, eRingMeV, pc.e[k]/ 151.461, "hPCQQQ"); // division by 151.5 for rough conversion of PC energy to keV from the slope on teh Source data + plotter->Fill2D("CalibratedQQQEvsPCE_W", 1000, 0, 10, 2000, 0, 200, eWedgeMeV, pc.e[k]/ 151.461, "hPCQQQ");// division by 151.5 for rough conversion of PC energy to keV from the slope on teh Source data if (tRing - static_cast(pc.t[k]) < -150) // proton tests, 27Al - - //if (tRing - static_cast(pc.t[k]) < -150 && tRing - static_cast(pc.t[k]) > -450) // 27Al - //if (tRing - static_cast(pc.t[k]) < -70 && tRing - static_cast(pc.t[k]) > -150) // 17F + // if (tRing - static_cast(pc.t[k]) < -150 && tRing - static_cast(pc.t[k]) > -450) // 27Al + // if (tRing - static_cast(pc.t[k]) < -70 && tRing - static_cast(pc.t[k]) > -150) // 17F { PCQQQTimeCut = true; } } - if (pc.index[k] >= 24 && pc.e[k] > 50) { + if (pc.index[k] >= 24 && pc.e[k] > 50) + { plotter->Fill2D("Timing_Difference_QQQ_PC_Cathode", 500, -2000, 2000, 16, 0, 16, tRing - static_cast(pc.t[k]), chRing, "hTiming"); } - } //end of pc loop - - double theta = -TMath::Pi() / 2 + 2 * TMath::Pi() / 16 / 4. * (qqq.id[i] * 16 + chWedge + 0.5); - double rho = 50. + (50. / 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); - plotter->Fill2D("QQQPolarPlot", 16 * 4, -TMath::Pi(), TMath::Pi(), 32, 40, 100, theta, rho, "hCalQQQ"); - plotter->Fill2D("QQQCartesianPlot", 200, -100, 100, 200, -100, 100, rho * TMath::Cos(theta), rho * TMath::Sin(theta), "hCalQQQ"); - plotter->Fill2D("QQQCartesianPlot" + std::to_string(qqq.id[i]), 200, -100, 100, 200, -100, 100, rho * TMath::Cos(theta), rho * TMath::Sin(theta), "hCalQQQ"); - if (PCQQQTimeCut) - { - plotter->Fill2D("PC_XY_Projection_QQQ_TimeCut" + std::to_string(qqq.id[i]), 400, -100, 100, 400, -100, 100, rho * TMath::Cos(theta), rho * TMath::Sin(theta), "hPCQQQ"); - } - plotter->Fill2D("PC_XY_Projection_QQQ" + std::to_string(qqq.id[i]), 400, -100, 100, 400, -100, 100, rho * TMath::Cos(theta), rho * TMath::Sin(theta), "hPCQQQ"); + } // end of pc k loop if (!HitNonZero) { + double theta = -TMath::Pi() / 2 + 2 * TMath::Pi() / 16 / 4. * (qqq.id[i] * 16 + chWedge + 0.5); + double rho = 50. + (50. / 16.) * (chRing + 0.5); //"?" double x = rho * TMath::Cos(theta); double y = rho * TMath::Sin(theta); - hitPos.SetXYZ(x, y, (23 + 75 + 30)); + hitPos.SetXYZ(x, y, 100); qqqenergy = eRingMeV; qqqtimestamp = tRing; HitNonZero = true; } - } - } - } + } // if j==i + } // j loop end + } // i loop end plotter->Fill1D("QQQ_Multiplicity", 10, 0, 10, qqqCount, "hRawQQQ"); + /*if(QQQ_Events.size()>=1) { + std::cout<< " ---->" << std::endl; + for(auto qe: QQQ_Events) { + std::cout << qe.ch1/16 << " " <> WireEvent; // this stores nearest neighbour wire events, or a 'cluster' + WireEvent aWireEvents, cWireEvents; // naming for book keeping + aWireEvents.clear(); + aWireEvents.reserve(24); + // PC Gain Matching and Filling double anodeT = -99999; double cathodeT = 99999; @@ -392,8 +438,10 @@ Bool_t MakeVertex::Process(Long64_t entry) if (pc.e[i] > 50) { plotter->Fill2D("PC_Index_Vs_Energy", 48, 0, 48, 2000, 0, 30000, pc.index[i], static_cast(pc.e[i]), "hRawPC"); - } else { - continue; + } + else + { + continue; } if (pc.index[i] < 48) @@ -406,11 +454,13 @@ Bool_t MakeVertex::Process(Long64_t entry) { anodeT = static_cast(pc.t[i]); anodeIndex = pc.index[i]; + aWireEvents[pc.index[i]] = std::tuple(pc.index[i], pc.e[i], static_cast(pc.t[i])); } else { cathodeT = static_cast(pc.t[i]); cathodeIndex = pc.index[i] - 24; + cWireEvents[pc.index[i] - 24] = std::tuple(pc.index[i] - 24, pc.e[i], static_cast(pc.t[i])); } if (anodeT != -99999 && cathodeT != 99999) @@ -453,59 +503,75 @@ Bool_t MakeVertex::Process(Long64_t entry) double aEMax = 0; int aIDMax = 0; - typedef std::unordered_map> WireEvent; //this stores nearest neighbour wire events, or a 'cluster' - WireEvent aWireEvents, cWireEvents, aWireEvent, cWireEvent; //naming for book keeping - std::vector aClusters, cClusters; //all clusters that fire toghther. aClusters.at(0).size() gives 'how many wires in cluster-0', aClusters.size() gives 'how many clusters' - - std::set awirelist, cwirelist; for (int i = 0; i < pc.multi; i++) { // if (pc.e[i] > 100) { - if (pc.index[i] < 24) { + if (pc.index[i] < 24) + { anodeHits.push_back(std::pair(pc.index[i], pc.e[i])); - //aWireEvents.push_back(std::tuple(pc.index[i],pc.t[i],pc.e[i])); - //awirelist.insert(pc.index[i]); } - else if (pc.index[i] >= 24) { + else if (pc.index[i] >= 24) + { cathodeHits.push_back(std::pair(pc.index[i] - 24, pc.e[i])); - //cxWireEvents.push_back(std::tuple(pc.index[i]-24,pc.t[i],pc.e[i])); - //cwirelist.insert(pc.index[i]-24); } } } - std::sort(anodeHits.begin(),anodeHits.end(),[](std::pair a, std::pair b){ return a.first < b.first;}); - std::sort(cathodeHits.begin(),cathodeHits.end(),[](std::pair a, std::pair b){ return a.first < b.first;}); + std::sort(anodeHits.begin(), anodeHits.end(), [](std::pair a, std::pair b) + { return a.first < b.first; }); + std::sort(cathodeHits.begin(), cathodeHits.end(), [](std::pair a, std::pair b) + { return a.first < b.first; }); - //std::sort(cWireEvents.begin(),cWireEvents.end(),[](std::tuple a, std::tuple b){return std::get<0>(a) < std::get<0>(b);}); - //std::sort(aWireEvents.begin(),aWireEvents.end(),[](std::tuple a, std::tuple b){return std::get<0>(a) < std::get<0>(b);}); -/* + std::vector>> aClusters = pwinstance.Make_Clusters(aWireEvents); + std::vector>> cClusters = pwinstance.Make_Clusters(cWireEvents); - for(int i=0; i<24; i++) { - if(std::find_if(awireEvents.begin(),aWireEvents.end(),[&](std::tuple a){return std::get<0>(a)==i;})) { - aClusters. - } - } + std::vector> sumE_AC; + for (auto aCluster : aClusters) + { + for (auto cCluster : cClusters) + { + if(aCluster.size()<=1 && cCluster.size()<=1) continue; + auto [crossover, alpha, apSumE, cpSumE, apMaxE, cpMaxE, apTSMaxE, cpTSMaxE] = pwinstance.FindCrossoverProperties(aCluster, cCluster); + if (alpha != 9999999 && apSumE != -1) + { + // Event PCEvent(crossover,apMaxE,cpMaxE,apTSMaxE,cpTSMaxE); + // Event PCEvent(crossover,apSumE,cpSumE,apTSMaxE,cpTSMaxE); + Event PCEvent(crossover, apSumE, cpMaxE, apTSMaxE, cpTSMaxE); // run12 shows cathode-max and anode-sum provide best dE signals. + // std::cout << apSumE << " " << crossover.Perp() << " " << apMaxE << " " << apTSMaxE << std::endl; + PC_Events.push_back(PCEvent); + sumE_AC.push_back(std::pair(apSumE, cpSumE)); + } + } + } + if (QQQ_Events.size() && PC_Events.size()) + plotter->Fill2D("PCEv_vs_QQQEv", 20, 0, 20, 20, 0, 20, QQQ_Events.size(), PC_Events.size()); - std::vector>> aWires, cWires; - std::set acs, bcs; - - for(size_t i=0; iFill1D("dt_pcA_qqqR", 640, -2000, 2000, qqqevent.Time1 - pcevent.Time1); + plotter->Fill1D("dt_pcC_qqqW", 640, -2000, 2000, qqqevent.Time2 - pcevent.Time2); + plotter->Fill2D("dE_E_AnodeQQQR", 400, 0, 10, 800, 0, 40000, qqqevent.Energy1, pcevent.Energy1); + plotter->Fill2D("dE_E_CathodeQQQR", 400, 0, 10, 800, 0, 10000, qqqevent.Energy2, pcevent.Energy2); + double sinTheta = TMath::Sin((qqqevent.pos - TVector3(0, 0, 90)).Theta()); /// TMath::Sin((TVector3(51.5,0,128.) - TVector3(0,0,90)).Theta()); + plotter->Fill2D("dE2_E_AnodeQQQR", 400, 0, 10, 800, 0, 40000, qqqevent.Energy1, pcevent.Energy1 * sinTheta); + plotter->Fill2D("dE2_E_CathodeQQQR", 400, 0, 10, 800, 0, 10000, qqqevent.Energy2, pcevent.Energy2 * sinTheta); + + if (qqqevent.pos.Phi() <= pcevent.pos.Phi() + TMath::Pi() / 4. && qqqevent.pos.Phi() >= pcevent.pos.Phi() - TMath::Pi() / 4. && qqqevent.Time1 - pcevent.Time1 < -150 && qqqevent.Time2 - pcevent.Time2 < -300) + { + plotter->Fill1D("PCZ", 800, -200, 200, pcevent.pos.Z(), "phicut"); + double pcz_guess = 37.0 / TMath::Tan((qqqevent.pos - TVector3(0, 0, 90)).Theta()) + 90; // this is ideally kept to be all QQQ+userinput for calibration of pcz + plotter->Fill2D("pczguess_vs_pc", 300, 0, 200, 150, 0, 200, pcz_guess, pcevent.pos.Z(), "phicut"); + plotter->Fill2D("pczguess_vs_pc_phi=" + std::to_string(qqqevent.pos.Phi() * 180. / M_PI), 100, 0, 200, 150, 0, 200, pcz_guess, pcevent.pos.Z(), "phicut"); + // plotter->Fill1D("PCZ",800,-200,200,pcevent.pos.Z(),"phicut"); + } + } + } + // HALFTIME! Can stop here in future versions + // return kTRUE; - if (anodeHits.size() >= 1 && cathodeHits.size() >= 1) { // 2. CRITICAL FIX: Define reference vector 'a' @@ -546,7 +612,7 @@ Bool_t MakeVertex::Process(Long64_t entry) } } - TVector3 anodeIntersection,vector_closest_to_z; + TVector3 anodeIntersection, vector_closest_to_z; anodeIntersection.Clear(); vector_closest_to_z.Clear(); if (corrcatMax.size() > 0) @@ -572,26 +638,28 @@ Bool_t MakeVertex::Process(Long64_t entry) } 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()))) { + if ((hitPos.Phi() > (anodeIntersection.Phi() - TMath::PiOver4())) && (hitPos.Phi() < (anodeIntersection.Phi() + TMath::PiOver4()))) + { PCQQQPhiCut = true; } for (double Tz = 60; Tz <= 100; Tz += 1.0) { - TVector3 TargetPos(0, 0, Tz); - if(PCQQQPhiCut && anodeIntersection.Perp()>0 && anodeIntersection.Z()!=0 && cathodeHits.size()>=2) { - plotter->Fill2D("Inttheta_vs_QQQtheta_TC" + std::to_string(PCQQQTimeCut) + "_TZ" + std::to_string(Tz), 400, 0, 180, 90, 0, 90, (anodeIntersection - TargetPos).Theta() * 180. / TMath::Pi(), (hitPos - TargetPos).Theta() * 180. / TMath::Pi(), "TPosVariation"); - //plotter->Fill2D("R_ratio_to_Z_ratio" + std::to_string(PCQQQTimeCut) + "_TZ" + std::to_string(Tz), 100, -2, 2, 100, -2, 2, (anodeIntersection - TargetPos).Z()/(hitPos-TargetPos).Z(), ((anodeIntersection - TargetPos).Perp()+2.5)/(hitPos-TargetPos).Perp(), "TPosVariation"); - } + TVector3 TargetPos(0, 0, Tz); + if (PCQQQPhiCut && anodeIntersection.Perp() > 0 && anodeIntersection.Z() != 0 && cathodeHits.size() >= 2) + { + plotter->Fill2D("Inttheta_vs_QQQtheta_TC" + std::to_string(PCQQQTimeCut) + "_TZ" + std::to_string(Tz), 400, 0, 180, 90, 0, 90, (anodeIntersection - TargetPos).Theta() * 180. / TMath::Pi(), (hitPos - TargetPos).Theta() * 180. / TMath::Pi(), "TPosVariation"); + // plotter->Fill2D("R_ratio_to_Z_ratio" + std::to_string(PCQQQTimeCut) + "_TZ" + std::to_string(Tz), 100, -2, 2, 100, -2, 2, (anodeIntersection - TargetPos).Z()/(hitPos-TargetPos).Z(), ((anodeIntersection - TargetPos).Perp()+2.5)/(hitPos-TargetPos).Perp(), "TPosVariation"); + } } - if (anodeIntersection.Z() != 0 && anodeIntersection.Perp()>0 && HitNonZero) + if (anodeIntersection.Z() != 0 && anodeIntersection.Perp() > 0 && HitNonZero) { 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)+ "_PC"+std::to_string(PCQQQPhiCut), 90, 0, 180, 20, 0, 45, anodeIntersection.Theta() * 180. / TMath::Pi(), hitPos.Theta() * 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)+ "_PC"+std::to_string(PCQQQPhiCut), 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) @@ -672,42 +740,46 @@ Bool_t MakeVertex::Process(Long64_t entry) { pw_contr.CalTrack2(hitPos, anodeIntersection); plotter->Fill1D("VertexRecon", 600, -1300, 1300, pw_contr.GetZ0()); - plotter->Fill1D("VertexRecon_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 600, -1300, 1300, pw_contr.GetZ0()); + plotter->Fill1D("VertexRecon_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 600, -1300, 1300, pw_contr.GetZ0()); if (cathodeHits.size() == 2) - plotter->Fill1D("VertexRecon_2c_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 600, -1300, 1300, pw_contr.GetZ0()); + plotter->Fill1D("VertexRecon_2c_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 600, -1300, 1300, pw_contr.GetZ0()); TVector3 x2(anodeIntersection), x1(hitPos); - TVector3 v = x2-x1; - double t_minimum = -1.0*(x1.X()*v.X()+x1.Y()*v.Y())/(v.X()*v.X()+v.Y()*v.Y()); - vector_closest_to_z = x1 + t_minimum*v; - - plotter->Fill1D("VertexRecon_Z_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 600, -1300, 1300, vector_closest_to_z.Z() ,"customVertex"); - if(vector_closest_to_z.Perp() < 20) { - plotter->Fill1D("VertexRecon_RadialCut_Z_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 600, -1300, 1300, vector_closest_to_z.Z() ,"customVertex"); - } - - plotter->Fill2D("VertexRecon_XY_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 100, -100, 100, 100,-100,100, vector_closest_to_z.X(), vector_closest_to_z.Y() ,"customVertex"); - if(cathodeHits.size()==2) { - plotter->Fill1D("VertexRecon2C_Z_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 600, -1300, 1300, vector_closest_to_z.Z() ,"customVertex"); - if(vector_closest_to_z.Perp() < 20) { - plotter->Fill1D("VertexRecon2C_RadialCut_Z_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 600, -1300, 1300, vector_closest_to_z.Z() ,"customVertex"); - } - plotter->Fill2D("VertexRecon2C_XY_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 100, -100, 100, 100,-100,100, vector_closest_to_z.X(), vector_closest_to_z.Y() ,"customVertex"); - plotter->Fill2D("VertexRecon2C_RhoZ_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 100, -100, 100, 600,-1300,1300, vector_closest_to_z.Perp(), vector_closest_to_z.Z() ,"customVertex"); - plotter->Fill2D("VertexRecon2C_Z_vs_QQQE_TC"+std::to_string(PCQQQTimeCut)+"_PhiC"+std::to_string(PCQQQPhiCut), 600, -1300, 1300, 800,0,20000, vector_closest_to_z.Z(), qqqenergy ,"customVertex"); - } - + TVector3 v = x2 - x1; + double t_minimum = -1.0 * (x1.X() * v.X() + x1.Y() * v.Y()) / (v.X() * v.X() + v.Y() * v.Y()); + vector_closest_to_z = x1 + t_minimum * v; + + plotter->Fill1D("VertexRecon_Z_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 600, -1300, 1300, vector_closest_to_z.Z(), "customVertex"); + if (vector_closest_to_z.Perp() < 20) + { + plotter->Fill1D("VertexRecon_RadialCut_Z_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 600, -1300, 1300, vector_closest_to_z.Z(), "customVertex"); + } + + plotter->Fill2D("VertexRecon_XY_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 100, -100, 100, 100, -100, 100, vector_closest_to_z.X(), vector_closest_to_z.Y(), "customVertex"); + if (cathodeHits.size() == 2) + { + plotter->Fill1D("VertexRecon2C_Z_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 600, -1300, 1300, vector_closest_to_z.Z(), "customVertex"); + if (vector_closest_to_z.Perp() < 20) + { + plotter->Fill1D("VertexRecon2C_RadialCut_Z_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 600, -1300, 1300, vector_closest_to_z.Z(), "customVertex"); + } + plotter->Fill2D("VertexRecon2C_XY_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 100, -100, 100, 100, -100, 100, vector_closest_to_z.X(), vector_closest_to_z.Y(), "customVertex"); + plotter->Fill2D("VertexRecon2C_RhoZ_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 100, -100, 100, 600, -1300, 1300, vector_closest_to_z.Perp(), vector_closest_to_z.Z(), "customVertex"); + plotter->Fill2D("VertexRecon2C_Z_vs_QQQE_TC" + std::to_string(PCQQQTimeCut) + "_PhiC" + std::to_string(PCQQQPhiCut), 600, -1300, 1300, 800, 0, 20000, vector_closest_to_z.Z(), qqqenergy, "customVertex"); + } } for (int i = 0; i < qqq.multi; i++) { - if(anodeIntersection.Perp() > 0) { //suppress x,y=0,0 events - 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"); + if (anodeIntersection.Perp() > 0) + { // suppress x,y=0,0 events + 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++) { @@ -767,45 +839,52 @@ Bool_t MakeVertex::Process(Long64_t entry) // 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); + // 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) + if (pc.index[k] >= 24) continue; + -// double sinTheta = TMath::Sin((hitPos-vector_closest_to_z).Theta()); - double sinTheta = TMath::Sin((anodeIntersection-TVector3(0,0,90.0)).Theta()); -// double sinTheta = TMath::Sin((hitPos-TVector3(0,0,30.0)).Theta()); -// double sinTheta = TMath::Sin(hitPos.Theta()); + // double sinTheta = TMath::Sin((hitPos-vector_closest_to_z).Theta()); + // double sinTheta = TMath::Sin((anodeIntersection-TVector3(0,0,90.0)).Theta()); + double sinTheta = TMath::Sin((anodeIntersection - vector_closest_to_z).Theta()); + // double sinTheta = TMath::Sin((hitPos-TVector3(0,0,30.0)).Theta()); + // double sinTheta = TMath::Sin(hitPos.Theta()); - if(cathodeHits.size()==2 && PCQQQPhiCut) { - plotter->Fill2D("CalibratedQQQE_RvsCPCE_TC" + std::to_string(PCQQQTimeCut) , 400, 0, 10, 400, 0, 30000, eRingMeV, pc.e[k]*sinTheta, "hPCQQQ"); - plotter->Fill2D("CalibratedQQQE_WvsCPCE_TC" + std::to_string(PCQQQTimeCut) , 400, 0, 10, 400, 0, 30000, eWedgeMeV, pc.e[k]*sinTheta, "hPCQQQ"); - plotter->Fill2D("CalibratedQQQE_RvsPCE_TC" + std::to_string(PCQQQTimeCut) , 400, 0, 10, 400, 0, 30000, eRingMeV, pc.e[k], "hPCQQQ"); - plotter->Fill2D("CalibratedQQQE_WvsPCE_TC" + std::to_string(PCQQQTimeCut) , 400, 0, 10, 400, 0, 30000, eWedgeMeV, pc.e[k], "hPCQQQ"); - plotter->Fill2D("PCQQQ_dTimevsdPhi", 200, -2000, 2000, 80, -200, 200, tRing - static_cast(pc.t[k]), (hitPos.Phi()-anodeIntersection.Phi()) * 180. / TMath::Pi(), "hTiming"); + // if(cathodeHits.size()==2 && PCQQQPhiCut) { + { + plotter->Fill2D("CalibratedQQQE_RvsCPCE_TC" + std::to_string(PCQQQTimeCut) + std::to_string(pw_contr.GetZ0() < -150), 400, 0, 10, 400, 0, 30000, eRingMeV, pc.e[k] * sinTheta, "hPCQQQ"); + plotter->Fill2D("CalibratedQQQE_RvsCPCE_Cal_TC" + std::to_string(PCQQQTimeCut) + std::to_string(pw_contr.GetZ0() < -150), 400, 0, 10, 400, 0, 200, eRingMeV, pc.e[k] * sinTheta / 151.461, "hPCQQQ"); // division by 151.5 for rough conversion of PC energy to keV from the slope on teh Source data + plotter->Fill2D("CalibratedQQQE_WvsCPCE_TC" + std::to_string(PCQQQTimeCut), 400, 0, 10, 400, 0, 30000, eWedgeMeV, pc.e[k] * sinTheta, "hPCQQQ"); + plotter->Fill2D("CalibratedQQQE_RvsPCE_TC" + std::to_string(PCQQQTimeCut) + std::to_string(pw_contr.GetZ0() < -150), 400, 0, 10, 400, 0, 30000, eRingMeV, pc.e[k], "hPCQQQ"); + plotter->Fill2D("CalibratedQQQE_RvsPCE_Cal_TC" + std::to_string(PCQQQTimeCut) + std::to_string(pw_contr.GetZ0() < -150), 400, 0, 10, 400, 0, 200, eRingMeV, pc.e[k] / 151.461, "hPCQQQ"); // division by 151.5 for rough conversion of PC energy to keV from the slope on teh Source data + plotter->Fill2D("CalibratedQQQE_WvsPCE_TC" + std::to_string(PCQQQTimeCut), 400, 0, 10, 400, 0, 30000, eWedgeMeV, pc.e[k], "hPCQQQ"); + plotter->Fill2D("PCQQQ_dTimevsdPhi", 200, -2000, 2000, 80, -200, 200, tRing - static_cast(pc.t[k]), (hitPos.Phi() - anodeIntersection.Phi()) * 180. / TMath::Pi(), "hTiming"); } - } - }///qqq i==j case end - } //j loop end + } /// qqq i==j case end + } // j loop end } // qqq i loop end - TVector3 guessVertex(0,0,90.); //for run12, subtract anodeIntersection.Z() by ~74.0 seems to work - //rho=40.0 mm is halfway between the cathodes(rho=42) and anodes(rho=37) - double pcz_guess = 42.0/TMath::Tan((hitPos-guessVertex).Theta()) + guessVertex.Z(); //this is ideally kept to be all QQQ+userinput for calibration of pcz - if(PCQQQTimeCut && PCQQQPhiCut && hitPos.Perp()>0 && anodeIntersection.Perp()>0 && cathodeHits.size()>=2) { - plotter->Fill2D("pczguess_vs_qqqE_rad="+std::to_string(hitPos.Perp()),100,0,200,800,0,20,pcz_guess,qqqenergy,"pczguess"); - plotter->Fill2D("pczguess_vs_pcz_rad="+std::to_string(hitPos.Perp()),100,0,200,150,0,200,pcz_guess,anodeIntersection.Z(),"pczguess"); //entirely qqq-derived position vs entirely PC derived position - plotter->Fill2D("pczguess_vs_pcz_phi="+std::to_string(hitPos.Phi()*180./M_PI),100,0,200,150,0,200,pcz_guess,anodeIntersection.Z()/0.8,"pczguess"); //entirely qqq-derived position vs entirely PC derived position - plotter->Fill2D("pczguess_vs_pcz",100,0,200,150,0,200,pcz_guess,anodeIntersection.Z()/0.8); - plotter->Fill2D("pcz_vs_pcPhi_rad="+std::to_string(hitPos.Perp()),360,0,360,150,0,200,anodeIntersection.Phi()*180./M_PI,anodeIntersection.Z(),"pczguess"); + + TVector3 guessVertex(0, 0, 90.); // for run12, subtract anodeIntersection.Z() by ~74.0 seems to work + // rho=40.0 mm is halfway between the cathodes(rho=42) and anodes(rho=37) + double pcz_guess = 42.0 / TMath::Tan((hitPos - guessVertex).Theta()) + guessVertex.Z(); // this is ideally kept to be all QQQ+userinput for calibration of pcz + if (PCQQQTimeCut && PCQQQPhiCut && hitPos.Perp() > 0 && anodeIntersection.Perp() > 0 && cathodeHits.size() >= 2) + { + plotter->Fill2D("pczguess_vs_qqqE", 100, 0, 200, 800, 0, 20, pcz_guess, qqqenergy, "pczguess"); + // double pczoffset = 30.0; + // plotter->Fill2D("pczguess_vs_pcz_rad="+std::to_string(hitPos.Perp()),100,0,200,150,0,200,pcz_guess,anodeIntersection.Z(),"pczguess"); //entirely qqq-derived position vs entirely PC derived position + plotter->Fill2D("pczguess_vs_pcz_phi=" + std::to_string(hitPos.Phi() * 180. / M_PI), 100, 0, 200, 150, 0, 200, pcz_guess, anodeIntersection.Z() , "pczguess"); // entirely qqq-derived position vs entirely PC derived position + plotter->Fill2D("pczguess_vs_pcz", 300, 0, 200, 150, 0, 200, pcz_guess, anodeIntersection.Z() ,"pczguess"); //entirely qqq-derived position vs entirely PC derived position + plotter->Fill2D("pcz_vs_pcPhi_rad=" + std::to_string(hitPos.Perp()), 360, 0, 360, 150, 0, 200, anodeIntersection.Phi() * 180. / M_PI, anodeIntersection.Z() , "pczguess"); } for (int i = 0; i < sx3.multi; i++) { // plotting sx3 strip hits vs anode phi - if (sx3.ch[i] < 8 && anodeIntersection.Perp()>0) + if (sx3.ch[i] < 8 && anodeIntersection.Perp() > 0) plotter->Fill2D("PCPhi_vs_SX3Strip", 100, -200, 200, 8 * 24, 0, 8 * 24, anodeIntersection.Phi() * 180. / TMath::Pi(), sx3.id[i] * 8 + sx3.ch[i]); } diff --git a/TrackRecon.C b/TrackRecon.C index 11fa897..c28d03f 100644 --- a/TrackRecon.C +++ b/TrackRecon.C @@ -301,6 +301,8 @@ Bool_t TrackRecon::Process(Long64_t entry) continue; plotter->Fill2D("WedgeE_Vs_RingECal", 1000, 0, 10, 1000, 0, 10, eWedgeMeV, eRingMeV, "hCalQQQ"); + if(qqq.multi>2 ) plotter->Fill2D("WedgeE_Vs_RingECal_mulit>2", 1000, 0, 10, 1000, 0, 10, eWedgeMeV, eRingMeV, "hCalQQQ"); + if(qqq.multi==2 ) plotter->Fill2D("WedgeE_Vs_RingECal_mulit=2", 1000, 0, 10, 1000, 0, 10, eWedgeMeV, eRingMeV, "hCalQQQ"); for (int k = 0; k < pc.multi; k++) { @@ -420,7 +422,8 @@ Bool_t TrackRecon::Process(Long64_t entry) for (int j = i + 1; j < pc.multi; j++) { // plotter->Fill2D("PC_Coincidence_Matrix_anodeMinusCathode_lt_-200_" + std::to_string(anodeT - cathodeT < -200), 48, 0, 48, 48, 0, 48, pc.index[i], pc.index[j], "hRawPC"); - plotter->Fill2D("Anode_V_Anode", 24, 0, 24, 24, 0, 24, pc.index[i], pc.index[j], "hGMPC"); + if(pc.e[i]>50 && pc.e[j]>50) + plotter->Fill2D("Anode_V_Anode", 24, 0, 24, 24, 0, 24, pc.index[i], pc.index[j], "hRawPC"); } }