1 #include "PionInteractionSystematic.hxx" 3 #include "GeometryManager.hxx" 11 #define JMDEBUGVERSION 1 21 PionInteractionSystematic::PionInteractionSystematic(){
35 typeInteraction = NULL;
39 InteractionTrueParticles = NULL;
43 PionInteractionSystematic::~PionInteractionSystematic(){
57 delete [] pInteraction;
61 delete [] typeInteraction;
62 typeInteraction = NULL;
69 delete [] TrueParticles;
72 if(InteractionTrueParticles)
73 delete [] InteractionTrueParticles;
74 InteractionTrueParticles = NULL;
78 delete [] stepLengths;
86 SteppingResult::SteppingResult(Float_t mcSum,
88 std::vector<Float_t> steps,
90 TLorentzVector posFinal){
92 MCSumNSigmaStepLength = mcSum;
93 DataSumNSigmaStepLength = dataSum;
121 Double_t DScattCentres(TGeoMixture* mixture){
125 Double_t* ZArray = mixture->GetZmixt();
126 Double_t* AArray = mixture->GetAmixt();
127 Double_t* WArray = mixture->GetWmixt();
128 Int_t NElts = mixture->GetNelements();
131 Double_t NA = 6.02214e23;
137 for(Int_t i = 0; i< NElts; i++){
144 result += (NA/AArray[i])*WArray[i]*((1000.0/(6.2415e21))*mixture->GetDensity());
164 Int_t GetMaterialSeries(std::string matName){
167 if (matName ==
"Air")
return 10;
169 else if (matName ==
"CO2")
return 10;
171 else if (matName ==
"Aluminum")
return 20;
173 else if (matName ==
"Steel")
return 30;
175 else if (matName ==
"AlRoha" || matName ==
"AlRoha2")
return 20;
177 else if (matName ==
"AlG10")
return 40;
179 else if (matName ==
"WaterSystem")
return 50;
181 else if (matName ==
"G10FGD1" || matName ==
"G10")
return 60;
185 else if (matName.find(
"FGDScintillator") != std::string::npos)
return 0;
187 else if (matName ==
"FGDGlue")
return 70;
189 else if (matName ==
"G10Roha")
return 80;
195 else if (matName ==
"G10FGD2")
return 60;
197 else if (matName ==
"ActiveWater")
return 10;
199 else if (matName ==
"Polypropylene")
return 0;
201 else if (matName ==
"FGDWaterModuleEpoxy")
return 70;
209 else if (matName ==
"GasMixtureTPC")
return 20;
218 Double_t GetIElement(Int_t Z){
264 Double_t GetZoverAMaterial(TGeoMixture* mat){
269 Int_t NElements = mat->GetNelements();
272 Double_t* Zmixt = mat->GetZmixt();
275 Double_t* Amixt = mat->GetAmixt();
278 Double_t* Wmixt = mat->GetWmixt();
281 for(Int_t i = 0; i < NElements; i++){
283 ZoverA += Wmixt[i]*(Zmixt[i]/Amixt[i]);
293 Double_t GetIMaterial(TGeoMixture* mat, Double_t ZoverA){
298 Int_t NElements = mat->GetNelements();
301 Double_t* Zmixt = mat->GetZmixt();
304 Double_t* Amixt = mat->GetAmixt();
307 Double_t* Wmixt = mat->GetWmixt();
310 for(Int_t i = 0; i < NElements; i++){
312 lnI += (Wmixt[i]*(Zmixt[i]/Amixt[i])*log(GetIElement((Int_t)Zmixt[i])))/ZoverA;
322 Double_t computeEkinFromMom(Double_t mom){
324 Double_t Ekin = sqrt(pow(mom,2) + pow(139.57,2)) - 139.57;
328 Double_t Interpolate(
double xsec1,
double xsec2,
double mom1,
double mom){
330 return (((mom/10.)-mom1)*(xsec2-xsec1) + xsec1);
338 std::pair<TLorentzVector,TVector3> TakeSmallStep(Int_t charge,
339 TLorentzVector initPos,
342 TGeoMaterial* material,
343 std::string materialName,
344 TGeoMixture* mixture){
347 Double_t initEkin = computeEkinFromMom(initMom.Mag());
350 TVector3 initDir = initMom*(1/initMom.Mag());
359 Double_t
K = 0.307075;
361 Double_t mec2 = 0.510998918;
362 Double_t m_pi = 139.57;
365 Double_t p_pi = initMom.Mag();
366 Double_t betagamma = p_pi/m_pi;
367 Double_t beta = p_pi/(initEkin + m_pi);
368 Double_t gamma = betagamma/beta;
369 Double_t T_max = (2*mec2*pow(betagamma,2))/(1 + 2*gamma*(mec2/m_pi) + pow(mec2/m_pi,2));
373 Double_t ZoverA = 0.53768;
374 Double_t I = 68.7E-6;
375 Double_t rho = 1.032;
379 if (materialName.find(
"FGDScintillator") == std::string::npos){
381 ZoverA = GetZoverAMaterial(mixture);
382 I = GetIMaterial(mixture,ZoverA)*(1E-6);
385 rho = (1000.0/(6.2415e21))*(material->GetDensity());
388 Double_t dEdx = K*z2*(ZoverA)*(1/pow(beta,2))*((1.0/2.0)*log(2*mec2*pow(betagamma,2)*T_max/pow(I,2)) - pow(beta,2));
394 Double_t finalEkin = initEkin - dEdx*(0.1)*stepLength*rho;
400 Double_t c = 299792458;
401 TVector3 initVelocity = beta*c*initDir;
404 TVector3
field(0.2,0.0,0.0);
408 TVector3 dpdt = charge*(1.602176e-19)*initVelocity.Cross(field);
412 Double_t dt = ((0.001*stepLength)/initVelocity.Mag());
413 TVector3 dp = dpdt*dt;
418 TVector3 pFinal = gamma*m_pi*(1.782662e-30)*initVelocity + dp;
422 TVector3 finalDir = pFinal*(1/pFinal.Mag());
428 TLorentzVector positionChange(stepLength*initDir.X(),stepLength*initDir.Y(),stepLength*initDir.Z(),(1e9)*dt);
429 TLorentzVector finalPosition = initPos + positionChange;
432 TVector3 finalMomVec;
436 TVector3 zeroVec(0.0,0.0,0.0);
437 finalMomVec = zeroVec;
442 Double_t finalMom = sqrt(pow(finalEkin + m_pi,2) - pow(m_pi,2));
443 finalMomVec = finalMom*finalDir;
446 return std::make_pair(finalPosition,finalMomVec);
452 Bool_t PionSIManager::InVOI(SubDetId_h det, Float_t* pos)
const{
454 #if JMDEBUGVERSION == 0 455 if (det == SubDetId::kFGD1 && InVOI1(pos))
return true;
456 #elif JMDEBUGVERSION == 1 458 if (InVOI1(pos) || InVOI2(pos))
return true;
459 #elif JMDEBUGVERSION == 2 461 if (InVOIext(pos))
return true;
462 #elif JMDEBUGVERSION == 3 463 if (det == SubDetId::kFGD1 && InVOI1(pos))
return true;
464 else if (det == SubDetId::kFGD2 && InVOI2(pos))
return true;
472 Bool_t PionSIManager::InVOI1(Float_t* pos)
const{
477 Bool_t xOK = -1150.0 < pos[0] && pos[0] < 1150.0;
478 Bool_t yOK = -1170.0 < pos[1] && pos[1] < 1230.0;
479 Bool_t zOK = 98.0 < pos[2] && pos[2] < 576.0;
481 return xOK && yOK && zOK;
485 Bool_t PionSIManager::InVOI2(Float_t* pos)
const{
489 Bool_t xOK = -1150.0 < pos[0] && pos[0] < 1150.0;
490 Bool_t yOK = -1170.0 < pos[1] && pos[1] < 1230.0;
491 Bool_t zOK = 1347.0 < pos[2] && pos[2] < 1934.0;
493 return xOK && yOK && zOK;
497 Bool_t PionSIManager::InVOIext(Float_t* pos)
const{
500 Bool_t xOK = -1150.0 < pos[0] && pos[0] < 1150.0;
501 Bool_t yOK = -1170.0 < pos[1] && pos[1] < 1230.0;
502 Bool_t zOK = 98.0 < pos[2] && pos[2] < 1934.0;
504 return xOK && yOK && zOK;
516 SteppingResult PionSIManager::StepBetweenPoints(SubDetId_h det, Int_t charge,
517 TLorentzVector initPos,
519 TLorentzVector finalPos,
521 TGeoManager* geom)
const{
524 std::pair<TLorentzVector,TVector3> stepResult;
527 Float_t MCSumNSigmaStepLength = 0;
528 Float_t DataSumNSigmaStepLength = 0;
533 Double_t initPointSep = (finalPos - initPos).Vect().Mag();
534 Double_t stepPointSep = 0.0;
538 TLorentzVector stepStartPos = initPos;
539 TVector3 stepStartMom = initMom;
543 Double_t totalStepLength = 0;
544 std::vector<Float_t> totalStepLengths;
547 TVector3 lastSavedMomentum = initMom;
550 TLorentzVector stepEndPos;
553 while(stepPointSep < initPointSep){
557 TGeoNode *node = geom->FindNode(stepStartPos.X(),stepStartPos.Y(),stepStartPos.Z());
558 TGeoVolume *volume = node->GetVolume();
559 TGeoMaterial *material = volume->GetMaterial();
560 std::string materialName = material->GetName();
561 TGeoMixture *mixture = (TGeoMixture*)material;
565 stepResult = TakeSmallStep(charge,stepStartPos,stepStartMom,stepLength,
566 material,materialName,mixture);
570 stepEndPos = stepResult.first;
571 stepEndMom = stepResult.second;
575 stepPointSep = (stepEndPos - initPos).Vect().Mag();
579 Double_t NDScint = ((6.02214e23)/12.011)*0.89538563*1.03552;
584 Int_t intTypes[3] = {0,1,4};
604 if (materialName.find(
"FGDScintillator") == std::string::npos){
606 Double_t scaledStepLength = stepLength;
630 Double_t NDMat = DScattCentres(mixture);
635 scaledStepLength *= (NDMat/NDScint);
644 Int_t materialSeries = GetMaterialSeries(materialName);
647 Double_t cXSecSum = 0;
648 Double_t matXSecSum = 0;
649 Double_t matMCXSecSum = 0;
651 for(Int_t ti = 0; ti < 3; ti++){
654 int momBin = int(stepStartMom.Mag()/10);
655 if (momBin>800) momBin = 800;
656 cXSecSum += Interpolate(PiXSec::xsec_data[piT + intTypes[ti]][momBin], PiXSec::xsec_data[piT + intTypes[ti]][momBin+1],momBin,stepStartMom.Mag());
657 matXSecSum += Interpolate(PiXSec::xsec_data[materialSeries + piT + intTypes[ti]][momBin], PiXSec::xsec_data[materialSeries + piT + intTypes[ti]][momBin+1],momBin,stepStartMom.Mag());
658 matMCXSecSum += Interpolate(PiXSec::xsec_MC[materialSeries + piT + intTypes[ti]][momBin], PiXSec::xsec_MC[materialSeries + piT + intTypes[ti]][momBin+1],momBin,stepStartMom.Mag());
665 scaledStepLength *= (matXSecSum/cXSecSum);
669 totalStepLength += scaledStepLength;
677 MCSumNSigmaStepLength += NDMat*(1E-27)*matMCXSecSum*(stepLength/10.0);
678 DataSumNSigmaStepLength += NDMat*(1E-27)*matXSecSum*(stepLength/10.0);
686 totalStepLength += stepLength;
689 Double_t cXSecSum = 0;
690 Double_t cMCXSecSum = 0;
691 for(Int_t ti = 0; ti < 3; ti++){
692 int momBin = int(stepStartMom.Mag()/10);
693 if (momBin>800) momBin = 800;
694 cXSecSum += Interpolate(PiXSec::xsec_data[piT + intTypes[ti]][momBin], PiXSec::xsec_data[piT + intTypes[ti]][momBin+1],momBin,stepStartMom.Mag());
695 cMCXSecSum += Interpolate(PiXSec::xsec_MC[piT + intTypes[ti]][momBin], PiXSec::xsec_MC[piT + intTypes[ti]][momBin+1],momBin,stepStartMom.Mag());
702 MCSumNSigmaStepLength += NDScint*(1E-27)*cMCXSecSum*(stepLength/10.0);
703 DataSumNSigmaStepLength += NDScint*(1E-27)*cXSecSum*(stepLength/10.0);
712 Float_t stepEndPosArray[4];
713 anaUtils::VectorToArray(stepEndPos,stepEndPosArray);
714 if(stepEndMom.Mag() == 0.0 || !InVOI(det, stepEndPosArray)){
715 totalStepLengths.push_back(totalStepLength);
719 DataSumNSigmaStepLength,
729 else if (lastSavedMomentum.Mag() - stepEndMom.Mag() >= 10.0
730 || stepPointSep >= initPointSep){
732 lastSavedMomentum = stepEndMom;
733 totalStepLengths.push_back(totalStepLength);
741 stepStartPos = stepResult.first;
742 stepStartMom = stepResult.second;
753 DataSumNSigmaStepLength,
755 lastSavedMomentum.Mag(),
770 TGeoManager* pionSIGeom = ND::hgman().GeoManager();
775 pionSIGeom = ND::hgman().GeoManager();
780 if((UInt_t) nTraj>NMAXTRUEPARTICLES) nTraj = NMAXTRUEPARTICLES;
789 std::vector<AnaTrueParticleB*> trajOfInterest;
790 for (Int_t it = 0; it < nTraj; it++){
797 trajOfInterest.push_back(track);
802 for (Int_t jt = 0; jt < nTraj; jt++){
806 trajOfInterest.push_back(track);
820 std::vector<AnaTrueParticleB*> pionTrajs;
821 std::vector<Interaction*> interactions;
823 for(UInt_t oai = 0; oai < trajOfInterest.size(); oai++){
825 if (trajOfInterest[oai]->PDG == 211 || trajOfInterest[oai]->PDG == -211){
826 if(InVOI(det, trajOfInterest[oai]->Position) )
827 pionTrajs.push_back(trajOfInterest[oai]);
831 if(trajOfInterest[oai]->ParentPDG == 211 || trajOfInterest[oai]->ParentPDG == -211){
833 AnaTrueParticleB* parent = GetParent(trajOfInterest[oai],allTrajInTPCFGD,nTraj);
834 Bool_t matchFound =
false;
835 for (UInt_t jsi = 0; jsi < interactions.size(); jsi++){
836 if (interactions[jsi]->IncludesTrajectory(trajOfInterest[oai])){
837 interactions[jsi]->AddTrajectory(trajOfInterest[oai],parent);
847 interactions.push_back(newInteraction);
858 std::vector< std::pair<AnaTrueParticleB*,Int_t> > pionTrajAndInteraction;
861 Int_t nInteractions = 0;
862 for (UInt_t p = 0; p < pionTrajs.size(); p++){
868 #if (JMDEBUGVERSION == 0) || (JMDEBUGVERSION == 2) || (JMDEBUGVERSION == 3) 869 if(InVOI(sel.GetDetectorFV(branch), pionTraj->
PositionEnd)){
874 #elif JMDEBUGVERSION == 1 879 std::vector<Interaction*> thisPionInteractions;
883 for (UInt_t i = 0; i < interactions.size(); i++){
887 if (interactions[i]->parentID == pionTraj->
ID 888 && interactions[i]->position[3] >= pionTraj->
PositionEnd[3]){
889 thisPionInteractions.push_back(interactions[i]);
912 for (UInt_t i = 0; i < thisPionInteractions.size(); i++){
914 TLorentzVector thisPos(thisPionInteractions[i]->position[0],thisPionInteractions[i]->position[1],thisPionInteractions[i]->position[2],thisPionInteractions[i]->position[3]);
917 if(posEnd == thisPos){
919 NPiPlus += thisPionInteractions[i]->NumberOfParticleType(211);
920 NPiZero += thisPionInteractions[i]->NumberOfParticleType(111)
921 + thisPionInteractions[i]->NPiZeroFromDecayProducts();
922 NPiMinus += thisPionInteractions[i]->NumberOfParticleType(-211);
923 NMuPlus += thisPionInteractions[i]->NumberOfParticleType(-13);
924 NMuMinus += thisPionInteractions[i]->NumberOfParticleType(13);
925 NExotic += thisPionInteractions[i]->CountExoticParticles();
935 NPiPlus += thisPionInteractions[i]->NumberOfParticleType(-13);
938 NPiMinus += thisPionInteractions[i]->NumberOfParticleType(13);
945 if(thisPionInteractions[i]->position[3] - pionTraj->
PositionEnd[3] < 10E-4){
949 NPiZero += thisPionInteractions[i]->NPiZeroFromDecayProducts();
953 TSPiZero += thisPionInteractions[i]->NumberOfParticleType(111);
961 TSPiZero += thisPionInteractions[i]->NumberOfParticleType(111)
962 + thisPionInteractions[i]->NPiZeroFromDecayProducts();
970 if (thisPionInteractions[i]->NumberOfParticleType(211)
972 + thisPionInteractions[i]->NumberOfParticleType(-211)
973 + thisPionInteractions[i]->CountExoticParticles() > 0){
975 if(pionTraj->
PDG == 211){
992 std::vector<Interaction*> interactions;
993 for (std::vector<Interaction*>::iterator it = interactions.begin(); it != interactions.end(); it++){
998 interactions.clear();
1004 Int_t interactionType;
1007 if((pionTraj->
PDG == 211 && NMuPlus == 1)
1008 || (pionTraj->
PDG == -211 && NMuMinus == 1)){
1010 interactionType = 3;
1015 else if(NExotic > 0){
1016 interactionType = 7;
1021 else if (NPiPlus + NPiZero + NPiMinus > 1){
1022 interactionType = 5;
1029 else if (NPiZero == 1){
1030 interactionType = 1;
1035 else if ((pionTraj->
PDG == 211 && NPiMinus == 1)
1036 || (pionTraj->
PDG == -211 && NPiPlus == 1)){
1037 interactionType = 2;
1042 else if ((pionTraj->
PDG == 211 && NPiPlus == 1)
1043 || (pionTraj->
PDG == -211 && NPiMinus == 1)){
1044 interactionType = 4;
1049 else if (NPiPlus + NPiZero + NPiMinus
1050 + NMuMinus + NMuPlus == 0){
1051 interactionType = 0;
1057 interactionType = 7;
1063 pionTrajAndInteraction.push_back(std::make_pair(pionTraj,interactionType));
1068 pionTrajAndInteraction.push_back(std::make_pair(pionTraj,8));
1074 Int_t thisIntType = pionTrajAndInteraction.back().second;
1078 if(thisIntType == 0 || thisIntType == 1 || thisIntType == 4){
1093 std::vector<Float_t> allPionSteps;
1095 Float_t AllPionsMCSumNSigmaStepLength = 0.0;
1096 Float_t AllPionsDataSumNSigmaStepLength = 0.0;
1099 Int_t nPions = (Int_t)pionTrajAndInteraction.size();
1100 Bool_t* pionType =
new Bool_t[(UInt_t)nPions];
1101 Int_t* nSteps =
new Int_t[(UInt_t)nPions];
1102 Float_t* initMom =
new Float_t[(UInt_t)nPions];
1103 Float_t* pInteraction =
new Float_t[(UInt_t)nInteractions];
1104 Int_t* typeInteraction =
new Int_t[(UInt_t)nInteractions];
1105 Int_t interactionsSoFar = 0;
1108 std::vector<Float_t> testFinalMom;
1109 std::vector<TLorentzVector> testFinalPos;
1110 std::vector<Int_t> testInteractionType;
1111 Int_t* pionID =
new Int_t[nPions];
1115 for(UInt_t ip = 0; ip < pionTrajAndInteraction.size(); ip++){
1118 Int_t intCode = pionTrajAndInteraction[ip].second;
1121 if(pionTraj->
PDG == 211){
1123 pionType[ip] =
true;
1128 pionType[ip] =
false;
1138 pionID[ip] = pionTraj->
ID;
1140 TrueParticles[ip] = pionTraj;
1154 nSteps[ip] = sr.stepLengths.size();
1156 testFinalMom.push_back(sr.finalMom);
1158 testFinalPos.push_back(sr.finalPos);
1160 testInteractionType.push_back(intCode);
1164 if(intCode == 0 || intCode == 1 || intCode == 4){
1166 pInteraction[interactionsSoFar] = sr.finalMom;
1171 TGeoNode *node = pionSIGeom->FindNode(pionTraj->
PositionEnd[0],
1175 TGeoVolume *volume = node->GetVolume();
1176 TGeoMaterial *material = volume->GetMaterial();
1177 std::string materialName = material->GetName();
1179 Int_t materialSeries = GetMaterialSeries(materialName);
1186 Int_t pionTypeSeries = 0;
1188 pionTypeSeries = 100;
1192 typeInteraction[interactionsSoFar] = intCode + materialSeries + pionTypeSeries;
1194 InteractionTrueParticles[interactionsSoFar] = pionTraj;
1198 interactionsSoFar++;
1204 for(UInt_t sIdx = 0; sIdx < sr.stepLengths.size() ; sIdx++){
1206 allPionSteps.push_back(sr.stepLengths[sIdx]);
1212 AllPionsMCSumNSigmaStepLength += sr.MCSumNSigmaStepLength;
1213 AllPionsDataSumNSigmaStepLength += sr.DataSumNSigmaStepLength;
1220 Int_t totalSteps = (Int_t)allPionSteps.size();
1223 Float_t* stepLengths =
new Float_t[totalSteps];
1225 for(UInt_t i = 0; i < allPionSteps.size(); i++){
1227 stepLengths[i] = allPionSteps[i];
1233 Float_t weightMCToData = TMath::Exp(-(AllPionsDataSumNSigmaStepLength - AllPionsMCSumNSigmaStepLength));
1236 for(Int_t ni = 0; ni < nInteractions; ni++){
1238 Int_t siType = typeInteraction[ni];
1239 Float_t siMom = pInteraction[ni];
1241 int momBin = int(siMom/10);
1242 if (momBin>800) momBin = 800;
1244 Double_t dataXSec = Interpolate(PiXSec::xsec_data[siType][momBin], PiXSec::xsec_data[siType][momBin+1],momBin,siMom);
1245 Double_t mcXSec = Interpolate(PiXSec::xsec_MC[siType][momBin], PiXSec::xsec_MC[siType][momBin+1],momBin,siMom);
1251 weightMCToData *= dataXSec/mcXSec;
1262 result->nPions = nPions;
1263 result->pionType = pionType;
1264 result->totalSteps = totalSteps;
1265 result->nSteps = nSteps;
1266 result->initMom = initMom;
1267 result->stepLengths = stepLengths;
1268 result->nInteractions = nInteractions;
1269 result->pInteraction = pInteraction;
1270 result->typeInteraction = typeInteraction;
1271 result->testFinalMom = testFinalMom;
1272 result->testFinalPos = testFinalPos;
1273 result->testInteractionType = testInteractionType;
1274 result->weightMCToData = weightMCToData;
1275 result->MCSumNSigmaStepLength = AllPionsMCSumNSigmaStepLength;
1276 result->DataSumNSigmaStepLength = AllPionsDataSumNSigmaStepLength;
1277 result->MCProbNoInt = TMath::Exp(-AllPionsMCSumNSigmaStepLength);
1278 result->DataProbNoInt = TMath::Exp(-AllPionsDataSumNSigmaStepLength);
1279 result->pionID = pionID;
1280 result->TrueParticles = TrueParticles;
1281 result->InteractionTrueParticles = InteractionTrueParticles;
1291 for (Int_t it = 0; it < nTraj; it++){
1294 if (track->
ParentID == track2->
ID)
return track2;
int GetAllTrajInBunch(const AnaEventB &event, AnaTrueParticleB *traj[])
Float_t Momentum
The initial momentum of the true particle.
Int_t ID
The ID of the trueObj, which corresponds to the ID of the TTruthParticle that created it...
Representation of a true Monte Carlo trajectory/particle.
const TVector3 field
Constants.
Int_t PDG
The PDG code of this particle.
const Double_t K
Bethe-Bloch constants.
PionInteractionSystematic * ComputePionWeightInfo(const AnaEventB &event, SubDetId_h det) const
Int_t ParentID
The ID of this particle's immediate parent, or 0 if there is no parent.
Float_t PositionEnd[4]
The end position of the true particle.
Float_t Position[4]
The initial position of the true particle.
Float_t Direction[3]
The initial direction of the true particle.
bool LoadGeometry(const std::string &file="", Int_t geomID=-1, const std::string &geomDir="")
Load the TGeoManager from the input root file. Returns true when the new geometry was loaded...