//************************************************************************// // // // Copyright 2013 Bertram Kopf (bertram@ep1.rub.de) // // Julian Pychy (julian@ep1.rub.de) // // - Ruhr-Universität Bochum // // // // This file is part of Pawian. // // // // Pawian is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // (at your option) any later version. // // // // Pawian is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with Pawian. If not, see <http://www.gnu.org/licenses/>. // // // //************************************************************************// // IsobarTensorDecay class definition file. -*- C++ -*- // Copyright 2012 Bertram Kopf #include <getopt.h> #include <fstream> #include <algorithm> #include "PwaUtils/IsobarTensorDecay.hh" #include "PwaUtils/AbsEnv.hh" #include "qft++/relativistic-quantum-mechanics/Utils.hh" #include "ErrLogger/ErrLogger.hh" #include "Particle/Particle.hh" #include "Utils/PawianCollectionUtils.hh" #include "Utils/FunctionUtils.hh" #include "PwaUtils/KinUtils.hh" #include "PwaUtils/EvtDataBaseList.hh" IsobarTensorDecay::IsobarTensorDecay(Particle* mother, Particle* daughter1, Particle* daughter2, AbsEnv* theEnv) : IsobarLSDecay(mother, daughter1, daughter2, theEnv) ,_polMother(PolVector(_motherIGJPCPtr->J)) ,_polDaughter1(PolVector(_daughter1IGJPCPtr->J)) ,_polDaughter2(PolVector(_daughter2IGJPCPtr->J)) ,_lctTensor(LeviCivitaTensor()) , _metricTensor(MetricTensor()) { } IsobarTensorDecay::IsobarTensorDecay(std::shared_ptr<const IGJPC> motherIGJPCPtr, Particle* daughter1, Particle* daughter2, AbsEnv* theEnv, std::string motherName) : IsobarLSDecay(motherIGJPCPtr, daughter1, daughter2, theEnv, motherName) ,_polMother(PolVector(_motherIGJPCPtr->J)) ,_polDaughter1(PolVector(_daughter1IGJPCPtr->J)) ,_polDaughter2(PolVector(_daughter2IGJPCPtr->J)) ,_lctTensor(LeviCivitaTensor()) ,_metricTensor(MetricTensor()) { } IsobarTensorDecay::~IsobarTensorDecay(){ } void IsobarTensorDecay::print(std::ostream& os) const{ os << "\nJPCLS tensor amplitudes for decay\t" << _name << ":\n"; os << "suffix for fit parameter name:\t" << _fitParamSuffix << "\n"; std::vector< std::shared_ptr<const JPCLS> >::const_iterator it; for (it = _JPCLSDecAmps.begin(); it!= _JPCLSDecAmps.end(); ++it){ (*it)->print(os); os << "\n"; } AbsDecay::print(os); os << "\n"; } void IsobarTensorDecay::fillWignerDs(std::map<std::string, Vector4<double> >& fsMap, EvtData* evtData){ int evtNo=evtData->evtNo; std::map<int, bool>::const_iterator it = _alreadyFilledMap.find(evtNo); if(it!=_alreadyFilledMap.end() && it->second) return; //already filled if (!_daughter1IsStable) _absDecDaughter1->fillWignerDs(fsMap, evtData); if (!_daughter2IsStable) _absDecDaughter2->fillWignerDs(fsMap, evtData); Vector4<double> all4Vec(0.,0.,0.,0.); //fill all4Vec std::map<std::string , Vector4<double> >::iterator itMap; for(itMap=fsMap.begin(); itMap!=fsMap.end(); ++itMap){ all4Vec+=itMap->second; } //fill daughter1 and daughter2 4Vec Vector4<double> daughter1_4Vec(0.,0.,0.,0.); std::vector<Particle*> finalStatePart1; if(0!=_absDecDaughter1) finalStatePart1=_absDecDaughter1->finalStateParticles(); else finalStatePart1.push_back(_daughter1); std::vector<Particle*>::iterator itParticle; for (itParticle= finalStatePart1.begin(); itParticle != finalStatePart1.end(); ++itParticle){ itMap=fsMap.find( (*itParticle)->name() ); daughter1_4Vec+=itMap->second; } // DebugMsg << "daughter1_4Vec:\t" << _daughter1->name() << "\t" << daughter1_4Vec << endmsg; Vector4<double> daughter2_4Vec(0.,0.,0.,0.); std::vector<Particle*> finalStatePart2; if(0!=_absDecDaughter2) finalStatePart2=_absDecDaughter2->finalStateParticles(); else finalStatePart2.push_back(_daughter2); for (itParticle= finalStatePart2.begin(); itParticle != finalStatePart2.end(); ++itParticle){ itMap=fsMap.find( (*itParticle)->name() ); daughter2_4Vec+=itMap->second; } // DebugMsg << "daughter2_4Vec:\t" << _daughter2->name() << "\t" << daughter2_4Vec << endmsg; Vector4<double> mother_4Vec=daughter1_4Vec+daughter2_4Vec; Spin spinMother=_motherIGJPCPtr->J; Spin spinDaughter1=_daughter1IGJPCPtr->J; Spin spinDaughter2=_daughter2IGJPCPtr->J; _polMother.SetP4(mother_4Vec,mother_4Vec.M()); // _polMother.SetP4(mother_4Vec,mother_4Vec.M()); // DebugMsg << "_polMother:\t" << _polMother << endmsg; _polDaughter1.SetP4(daughter1_4Vec, daughter1_4Vec.M()); _polDaughter2.SetP4(daughter2_4Vec, daughter2_4Vec.M()); Spin lam12Max=spinDaughter1+spinDaughter2; if(lam12Max>spinMother) lam12Max=spinMother; Spin lamMotherMax=spinMother; if (!_hasMotherPart && spinMother>1) lamMotherMax=1; //attention: this is only valid for pbar p or e+ e- reactions; must be moved to individual specific classes std::vector< std::shared_ptr<const JPCLS> > theJPCLSAmps=JPCLSAmps(); DebugMsg << name() << endmsg; std::vector< std::shared_ptr<const JPCLS> >::iterator itJPCLS; for(itJPCLS=theJPCLSAmps.begin(); itJPCLS!=theJPCLSAmps.end(); ++itJPCLS){ // (*itJPCLS)->print(std::cout); // std::cout << std::endl; Spin L=(*itJPCLS)->L; Spin S=(*itJPCLS)->S; int s1s2S=spinDaughter1+spinDaughter2+(*itJPCLS)->S; Tensor<complex<double> > leviPssTensor; bool add_lctForChi=true; if( s1s2S%2 ==0 ) { //odd add_lctForChi=false; leviPssTensor(0)=complex<double>(1.,0.); } else{ leviPssTensor=_lctTensor*mother_4Vec; } DebugMsg << "leviPssTensor: " << leviPssTensor << endmsg; int SLms1=(*itJPCLS)->S+(*itJPCLS)->L+_motherIGJPCPtr->J; Tensor<complex<double> > leviPlsTensor; bool add_lctForTensor=true; if( SLms1%2 ==0 ){ //odd add_lctForTensor=false; leviPlsTensor=complex<double>(1.,0.); } else{ leviPlsTensor=_lctTensor*mother_4Vec; } DebugMsg << "leviPlsTensor: " << leviPlsTensor << endmsg; OrbitalTensor orbTensor(L); orbTensor.SetP4(daughter1_4Vec, daughter2_4Vec); DebugMsg << "orbTensor:\t" << orbTensor << endmsg; for (Spin lamMother=-lamMotherMax; lamMother<=lamMotherMax; ++lamMother){ DebugMsg << "lamMother:\t" << lamMother << endmsg; Tensor<complex<double> > epsilonMotherProject = _polMother(lamMother); DebugMsg << "epsilonMotherProject:\t" << epsilonMotherProject << endmsg; // //calculate ls part; // Tensor<complex<double> > lsPartTensor; // if(add_lctForTensor){ // if(epsilonMotherProject.Rank() >= orbTensor.Rank()){ // lsPartTensor= epsilonMotherProject*leviPlsTensor; // lsPartTensor.Permute(1,lsPartTensor.Rank()); // lsPartTensor=lsPartTensor|orbTensor; // } // else{ // lsPartTensor= orbTensor*leviPlsTensor; // lsPartTensor.Permute(1,lsPartTensor.Rank()); // lsPartTensor=lsPartTensor|epsilonMotherProject; // } // } // for !add_lctForTensor calculation will be done in heli loops //calculate chi Tensor<complex<double> > chi12; Tensor<complex<double> > s12SpinProjector; PolVector part12PolVec(S); part12PolVec.SetP4(mother_4Vec,mother_4Vec.M()); s12SpinProjector=part12PolVec.Projector(); DebugMsg << "s12SpinProjector:\t" << s12SpinProjector << endmsg; for (Spin lamDaughter1=-spinDaughter1; lamDaughter1 <= spinDaughter1; ++lamDaughter1){ DebugMsg << "lamDaughter1:\t" << lamDaughter1 << endmsg; Tensor<complex<double> > epsilonDaughter1Project = _polDaughter1(lamDaughter1); DebugMsg << "epsilonDaughter1Project:\t" << epsilonDaughter1Project << endmsg; for (Spin lamDaughter2=-spinDaughter2; lamDaughter2<=spinDaughter2; ++lamDaughter2){ DebugMsg << "lamDaughter2:\t" << lamDaughter2 << endmsg; Tensor<complex<double> > epsilonDaughter2Project=_polDaughter2(lamDaughter2); DebugMsg << "epsilonDaughter2Project:\t" << epsilonDaughter2Project << endmsg; Tensor<complex<double> > chiPart; if(add_lctForChi){ chiPart=(conj(epsilonDaughter1Project)*leviPssTensor)*conj(epsilonDaughter2Project); } else{ chiPart=conj(epsilonDaughter1Project)%conj(epsilonDaughter2Project); } DebugMsg << "chiPart:\t" << chiPart << endmsg; chi12=s12SpinProjector|chiPart; DebugMsg << "chi12:\t" << chi12 << endmsg; //calculate ls part; Tensor<complex<double> > lsPartTensor; if(add_lctForTensor){ if(epsilonMotherProject.Rank() >= orbTensor.Rank()){ lsPartTensor= epsilonMotherProject*leviPlsTensor; lsPartTensor.Permute(1,lsPartTensor.Rank()); lsPartTensor=lsPartTensor|orbTensor; } else{ lsPartTensor= orbTensor*leviPlsTensor; lsPartTensor.Permute(1,lsPartTensor.Rank()); lsPartTensor=lsPartTensor|epsilonMotherProject; } } if(!add_lctForTensor){ if (chi12.Rank()==fabs(epsilonMotherProject.Rank()-orbTensor.Rank())) lsPartTensor= epsilonMotherProject|orbTensor; else if (chi12.Rank()==(epsilonMotherProject.Rank()+orbTensor.Rank())) lsPartTensor= epsilonMotherProject%orbTensor; else if (epsilonMotherProject.Rank()==orbTensor.Rank()){ int noOfContractions=int((epsilonMotherProject.Rank()+orbTensor.Rank()-chi12.Rank())/2); if (noOfContractions<=epsilonMotherProject.Rank() && noOfContractions>0) lsPartTensor= epsilonMotherProject.Contract(orbTensor, noOfContractions); } else{ Alert << "wrong ranks chi12.Rank()=" << chi12.Rank() << "\tepsilonMotherProject.Rank()=" << epsilonMotherProject.Rank() << "\torbTensor.Rank()=" << orbTensor.Rank() << endmsg; exit(0); } } DebugMsg << "lsPartTensor:\t" << lsPartTensor << endmsg; Tensor<complex<double> > result=lsPartTensor|chi12; DebugMsg << "result:\t" << result << endmsg; if(result.Rank()>0){ Alert << "result.Rank()=" << result.Rank() << " > 0" << endmsg; exit(0); } evtData->ComplexDouble5SpinString[_name][L][S][lamMother][lamDaughter1][lamDaughter2]=result(0); } } } } }