00001 #include <vector> 00002 #include <list> 00003 #include "PH_HEPEVT_Interface.h" 00004 #include "PhotosParticle.h" 00005 #include "PhotosBranch.h" 00006 #include "Photos.h" 00007 #include "Log.h" 00008 using std::vector; 00009 using std::list; 00010 using std::endl; 00011 00012 namespace Photospp 00013 { 00014 00015 PhotosBranch::PhotosBranch(PhotosParticle* p) 00016 { 00017 daughters = p->getDaughters(); 00018 00019 //Suppress if somehow got stable particle 00020 if(daughters.size()==0) 00021 { 00022 Log::Debug(1)<<"Stable particle."<<endl; 00023 suppression = 1; 00024 forcing = 0; 00025 particle = NULL; 00026 return; 00027 } 00028 else if(daughters.at(0)->getMothers().size()==1) 00029 { 00030 // Regular case - one mother 00031 Log::Debug(1)<<"Regular case."<<endl; 00032 particle = p; 00033 mothers = p->findProductionMothers(); 00034 } 00035 else 00036 { 00037 // Advanced case - branch with multiple mothers - no mid-particle 00038 Log::Debug(1)<<"Advanced case."<<endl; 00039 particle = NULL; 00040 mothers = daughters.at(0)->getMothers(); 00041 } 00042 forcing = checkForcingLevel(); 00043 if(!forcing) suppression = checkSuppressionLevel(); 00044 else suppression = 0; 00045 00046 // Even if forced or passed suppression check, we still have to check few things 00047 if(!suppression) 00048 { 00049 // Check momentum conservation 00050 suppression=!checkMomentumConservation(); 00051 if(suppression) Log::Warning()<<"Branching ignored due to 4-momentum non conservation"<<endl; 00052 00053 // Check if advanced case has only one daughter 00054 if(!particle && daughters.size()==1) suppression=-1; 00055 00056 // If any of special cases is true, we're not forcing this branch 00057 if(suppression) forcing=0; 00058 } 00059 } 00060 00061 void PhotosBranch::process() 00062 { 00063 Log::Debug(703)<<" Processing barcode: "<<( (particle) ? particle->getBarcode() : ( (mothers.size()) ? mothers.at(0)->getBarcode() : -1) )<<endl; 00064 /* 00065 cout<<"Particles send to photos (with barcodes in brackets):"<<endl; 00066 vector<PhotosParticle *> get = getParticles(); 00067 for(int i=0;i<(int)get.size();i++) cout<<"ID: "<<get.at(i)->getPdgID()<<" ("<<get.at(i)->getBarcode()<<"), "; cout<<endl; 00068 */ 00069 int index = PH_HEPEVT_Interface::set(this); 00070 PH_HEPEVT_Interface::prepare(); 00071 photos_make_c_(&index); 00072 PH_HEPEVT_Interface::complete(); 00073 PH_HEPEVT_Interface::get(); 00074 checkMomentumConservation(); 00075 } 00076 00077 vector<PhotosParticle *> PhotosBranch::getParticles() 00078 { 00079 vector<PhotosParticle *> ret = mothers; 00080 if(particle) ret.push_back(particle); 00081 ret.insert(ret.end(),daughters.begin(),daughters.end()); 00082 return ret; 00083 } 00084 00085 bool PhotosBranch::checkMomentumConservation() 00086 { 00087 if(particle) return particle->checkMomentumConservation(); 00088 if(mothers.size()>0) return mothers.at(0)->checkMomentumConservation(); 00089 return true; 00090 } 00091 00092 vector<PhotosBranch *> PhotosBranch::createBranches(vector<PhotosParticle *> particles) 00093 { 00094 Log::Debug(700)<<"PhotosBranch::createBranches - filtering started"<<endl; 00095 list<PhotosParticle *> list(particles.begin(),particles.end()); 00096 vector<PhotosBranch *> branches; 00097 00098 // First - add all forced decays 00099 if(Photos::forceBremList) 00100 { 00101 std::list<PhotosParticle *>::iterator it; 00102 for(it=list.begin();it!=list.end();it++) 00103 { 00104 PhotosBranch *branch = new PhotosBranch(*it); 00105 int forcing = branch->getForcingStatus(); 00106 if(forcing) 00107 { 00108 Log::Debug(701)<<" Forced: "<<(*it)->getPdgID()<<" (barcode: "<<(*it)->getBarcode()<<") with forcing status= "<<forcing<<endl; 00109 branches.push_back(branch); 00110 it = list.erase(it); 00111 --it; 00112 // If forcing consecutive decays 00113 if(forcing==2) 00114 { 00115 PhotosParticle *p = branch->getDecayingParticle(); 00116 if(!p) 00117 if(branch->getMothers().size()>0) p = branch->getMothers().at(0); 00118 else continue; 00119 vector<PhotosParticle *> tree = p->getDecayTree(); 00120 //Add branches for all particles from the list - max O(n*m) 00121 std::list<PhotosParticle *>::iterator it2; 00122 for(it2=list.begin();it2!=list.end();it2++) 00123 { 00124 for(int i=0;i<(int)tree.size();i++) 00125 { 00126 if(tree.at(i)->getBarcode()==(*it2)->getBarcode()) 00127 { 00128 PhotosBranch *b = new PhotosBranch(*it2); 00129 branches.push_back(b); 00130 // If we were to delete our next particle in line 00131 if(it==it2) --it; 00132 it2 = list.erase(it2); 00133 --it2; 00134 break; 00135 } 00136 } 00137 } 00138 } 00139 } 00140 else delete branch; 00141 } 00142 } 00143 // Quit if we're suppressing everything 00144 if(Photos::isSuppressed) return branches; 00145 // Now - check if remaining decays are suppressed 00146 while(!list.empty()) 00147 { 00148 PhotosParticle *particle = list.front(); 00149 list.pop_front(); 00150 if(!particle) continue; 00151 00152 PhotosBranch *branch = new PhotosBranch(particle); 00153 int suppression = branch->getSuppressionStatus(); 00154 if(!suppression) branches.push_back(branch); 00155 else 00156 { 00157 Log::Debug(702)<<" Suppressed: "<<particle->getPdgID()<<" (barcode: "<<particle->getBarcode()<<") with suppression status= "<<suppression<<endl; 00158 //If suppressing consecutive decays 00159 if(suppression==2) 00160 { 00161 PhotosParticle *p = branch->getDecayingParticle(); 00162 if(!p) 00163 if(branch->getMothers().size()>0) p = branch->getMothers().at(0); 00164 else continue; 00165 vector<PhotosParticle *> tree = p->getDecayTree(); 00166 //Remove all particles from the list - max O(n*m) 00167 std::list<PhotosParticle *>::iterator it; 00168 for(it=list.begin();it!=list.end();it++) 00169 { 00170 for(int i=0;i<(int)tree.size();i++) 00171 { 00172 if(tree.at(i)->getBarcode()==(*it)->getBarcode()) 00173 { 00174 it = list.erase(it); 00175 --it; 00176 break; 00177 } 00178 } 00179 } 00180 } 00181 delete branch; 00182 continue; 00183 } 00184 00185 //In case we don't have mid-particle erase rest of the mothers from list 00186 if(!branch->getDecayingParticle()) 00187 { 00188 vector<PhotosParticle *> mothers = branch->getMothers(); 00189 for(int i=0;i<(int)mothers.size();i++) 00190 { 00191 PhotosParticle *m = mothers.at(i); 00192 if(m->getBarcode()==particle->getBarcode()) continue; 00193 std::list<PhotosParticle *>::iterator it; 00194 for(it=list.begin();it!=list.end();it++) 00195 if(m->getBarcode()==(*it)->getBarcode()) 00196 { 00197 it = list.erase(it); 00198 break; 00199 } 00200 } 00201 } 00202 } 00203 return branches; 00204 } 00205 00206 int PhotosBranch::checkList(bool forceOrSuppress) 00207 { 00208 vector< vector<int>* > *list = (forceOrSuppress) ? Photos::forceBremList : Photos::supBremList; 00209 if(!list) return 0; 00210 00211 // Can't check without pdgid 00212 int motherID; 00213 if(particle) motherID = particle->getPdgID(); 00214 else 00215 { 00216 if(mothers.size()==0) return 0; 00217 motherID = mothers.at(0)->getPdgID(); 00218 } 00219 00220 // Create list of daughters 00221 vector<int> dID; 00222 for(int j=0;j<(int)daughters.size();j++) dID.push_back(daughters[j]->getPdgID()); 00223 00224 vector< vector<int> *> &patternList = *list; 00225 00226 // Check if the mother and list of daughters matches any of the declared patterns 00227 for(int j=0; j<(int)patternList.size();j++) 00228 { 00229 // Skip patterns that don't have our mother 00230 if(motherID!=(*patternList[j])[0]) continue; 00231 00232 // Compare decay daughters with pattern - max O(n*m) 00233 vector<int> &pattern = *patternList[j]; 00234 bool fullMatch=true; 00235 for(int k = 1; k<(int)pattern.size()-1; k++) 00236 { 00237 bool oneMatch=false; 00238 for(int l=0;l<(int)dID.size(); l++) 00239 if(pattern[k]==dID[l]) { oneMatch=true; break; } 00240 if(!oneMatch) { fullMatch=false; break; } 00241 } 00242 // Check if the matching pattern is set for consecutive suppression 00243 /* 00244 Currently minimal matching is used. 00245 If e.g. 25 -> -15 is suppressed, then 25 -> 15,-15 and 25 -> 15,-15,22 etc. is suppressed too 00246 For exact matching (then suppress 25 -> 15,-15 ; 25 -> 15,-15,22 etc. must be done separately) uncoment line ...: 00247 */ 00248 // if(pattern.size()<=2 || (fullMatch && dID.size()==pattern.size()-2) ) 00249 // ...and comment out line: 00250 if(pattern.size()<=2 || fullMatch) 00251 return (pattern.back()==1) ? 2 : 1; 00252 } 00253 return 0; 00254 } 00255 00256 } // namespace Photospp