1 //--------------------------------------------------------------------------
4 // This software is part of the EvtGen package developed jointly
5 // for the BaBar and CLEO collaborations. If you use all or part
6 // of it, please give an appropriate acknowledgement.
8 // Copyright Information: See EvtGen/COPYRIGHT
9 // Copyright (C) 1998 Caltech, UCSB
11 // Module: EvtDecayTable.cc
15 // Modification history:
17 // DJL/RYD September 25, 1996 Module created
19 //------------------------------------------------------------------------
21 #include "EvtGenBase/EvtPatches.hh"
30 #include "EvtGenBase/EvtParticle.hh"
31 #include "EvtGenBase/EvtRandom.hh"
32 #include "EvtGenBase/EvtDecayTable.hh"
33 #include "EvtGenBase/EvtPDL.hh"
34 #include "EvtGenBase/EvtSymTable.hh"
35 #include "EvtGenBase/EvtDecayBase.hh"
36 #include "EvtGenBase/EvtModel.hh"
37 #include "EvtGenBase/EvtParser.hh"
38 #include "EvtGenBase/EvtParserXml.hh"
39 #include "EvtGenBase/EvtReport.hh"
40 #include "EvtGenBase/EvtModelAlias.hh"
41 #include "EvtGenBase/EvtRadCorr.hh"
42 #include "EvtGenBase/EvtExtGeneratorCommandsTable.hh"
48 EvtDecayTable::EvtDecayTable() {
52 EvtDecayTable::~EvtDecayTable() {
56 EvtDecayTable* EvtDecayTable::getInstance() {
58 static EvtDecayTable* theDecayTable = 0;
60 if (theDecayTable == 0) {
61 theDecayTable = new EvtDecayTable();
68 int EvtDecayTable::getNMode(int ipar){
69 return _decaytable[ipar].getNMode();
72 EvtDecayBase* EvtDecayTable::getDecay(int ipar, int imode){
73 return _decaytable[ipar].getDecayModel(imode);
76 void EvtDecayTable::printSummary(){
78 for(size_t i=0;i<EvtPDL::entries();i++){
79 _decaytable[i].printSummary();
84 EvtDecayBase* EvtDecayTable::getDecayFunc(EvtParticle *p){
87 partnum=p->getId().getAlias();
89 if ( _decaytable[partnum].getNMode()==0 ) return 0;
90 return _decaytable[partnum].getDecayModel(p);
94 void EvtDecayTable::readDecayFile(const std::string dec_name, bool verbose){
96 if ( _decaytable.size() < EvtPDL::entries() ) _decaytable.resize(EvtPDL::entries());
97 EvtModel &modelist=EvtModel::instance();
98 EvtExtGeneratorCommandsTable* extGenCommands = EvtExtGeneratorCommandsTable::getInstance();
99 std::string colon(":"), equals("=");
103 report(INFO,"EvtGen") << "In readDecayFile, reading:"<<dec_name.c_str()<<endl;
107 fin.open(dec_name.c_str());
109 report(ERROR,"EvtGen") << "Could not open "<<dec_name.c_str()<<endl;
114 parser.read(dec_name);
122 for(itok=0;itok<parser.getNToken();itok++){
124 token=parser.getToken(itok);
126 if (token=="End") hasend=1;
131 report(ERROR,"EvtGen") << "Could not find an 'End' in "<<dec_name.c_str()<<endl;
132 report(ERROR,"EvtGen") << "Will terminate execution."<<endl;
138 std::string model,parent,sdaug;
143 EvtId daught[MAX_DAUG];
148 std::vector<EvtModelAlias> modelAliasList;
153 token=parser.getToken(itoken++);
155 //Easy way to turn off photos... Lange September 5, 2000
156 if (token=="noPhotos"){
157 EvtRadCorr::setNeverRadCorr();
159 report(INFO,"EvtGen")
160 << "As requested, PHOTOS will be turned off."<<endl;
162 else if (token=="yesPhotos"){
163 EvtRadCorr::setAlwaysRadCorr();
165 report(INFO,"EvtGen")
166 << "As requested, PHOTOS will be turned on for all decays."<<endl;
168 else if (token=="normalPhotos"){
169 EvtRadCorr::setNormalRadCorr();
171 report(INFO,"EvtGen")
172 << "As requested, PHOTOS will be turned on only when requested."<<endl;
174 else if (token=="Alias"){
179 newname=parser.getToken(itoken++);
180 oldname=parser.getToken(itoken++);
182 EvtId id=EvtPDL::getId(oldname);
184 if (id==EvtId(-1,-1)) {
185 report(ERROR,"EvtGen") <<"Unknown particle name:"<<oldname.c_str()
186 <<" on line "<<parser.getLineofToken(itoken)<<endl;
187 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
191 EvtPDL::alias(id,newname);
192 if ( _decaytable.size() < EvtPDL::entries() ) _decaytable.resize(EvtPDL::entries());
194 } else if (token=="ModelAlias"){
195 std::vector<std::string> modelArgList;
197 std::string aliasName=parser.getToken(itoken++);
198 std::string modelName=parser.getToken(itoken++);
200 std::string nameTemp;
202 nameTemp=parser.getToken(itoken++);
204 modelArgList.push_back(nameTemp);
206 }while(nameTemp!=";");
207 EvtModelAlias newAlias(aliasName,modelName,modelArgList);
208 modelAliasList.push_back(newAlias);
209 } else if (token=="ChargeConj"){
212 std::string abarname;
214 aname=parser.getToken(itoken++);
215 abarname=parser.getToken(itoken++);
217 EvtId a=EvtPDL::getId(aname);
218 EvtId abar=EvtPDL::getId(abarname);
220 if (a==EvtId(-1,-1)) {
221 report(ERROR,"EvtGen") <<"Unknown particle name:"<<aname.c_str()
222 <<" on line "<<parser.getLineofToken(itoken)<<endl;
223 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
227 if (abar==EvtId(-1,-1)) {
228 report(ERROR,"EvtGen") <<"Unknown particle name:"<<abarname.c_str()
229 <<" on line "<<parser.getLineofToken(itoken)<<endl;
230 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
235 EvtPDL::aliasChgConj(a,abar);
237 } else if (token == "JetSetPar") {
239 // Check if any old Pythia 6 commands are present
240 std::string pythiaCommand = parser.getToken(itoken++);
244 // The old command format is NAME(INT)=VALUE
245 int i1 = pythiaCommand.find_first_of("(");
246 int i2 = pythiaCommand.find_first_of(")");
247 int i3 = pythiaCommand.find_first_of("=");
249 std::string pythiaModule = pythiaCommand.substr(0, i1);
250 std::string pythiaParam = pythiaCommand.substr(i1+1, i2-i1-1);
251 std::string pythiaValue = pythiaCommand.substr(i3+1);
253 command["MODULE"] = pythiaModule;
254 command["PARAM"] = pythiaParam;
255 command["VALUE"] = pythiaValue;
257 command["GENERATOR"] = "Both";
258 command["VERSION"] = "PYTHIA6";
260 extGenCommands->addCommand("PYTHIA", command);
262 } else if (modelist.isCommand(token)){
266 cnfgstr=parser.getToken(itoken++);
268 modelist.storeCommand(token,cnfgstr);
270 } else if (token == "PythiaGenericParam" || token == "PythiaAliasParam" ||
271 token == "PythiaBothParam") {
273 // Read in any Pythia 8 commands, which will be of the form
274 // pythia<type>Param module:param=value, with no spaces in the parameter
275 // string! Here, <type> specifies whether the command is for generic
276 // decays, alias decays, or both.
278 // Pythia 6 commands will be defined by the old JetSetPar command
279 // name, which is handled by the modelist.isCommand() statement above.
281 std::string pythiaCommand = parser.getToken(itoken++);
282 std::string pythiaModule(""), pythiaParam(""), pythiaValue("");
284 // Separate out the string into the 3 sections using the delimiters
287 std::vector<std::string> pComVect1 = this->splitString(pythiaCommand, colon);
289 if (pComVect1.size() == 2) {
291 pythiaModule = pComVect1[0];
293 std::string pCom2 = pComVect1[1];
295 std::vector<std::string> pComVect2 = this->splitString(pCom2, equals);
297 if (pComVect2.size() == 2) {
299 pythiaParam = pComVect2[0];
300 pythiaValue = pComVect2[1];
306 // Define the Pythia 8 command and pass it to the external generator
309 if (token == "PythiaGenericParam") {
310 command["GENERATOR"] = "Generic";
311 } else if (token == "PythiaAliasParam") {
312 command["GENERATOR"] = "Alias";
314 command["GENERATOR"] = "Both";
317 command["MODULE"] = pythiaModule;
318 command["PARAM"] = pythiaParam;
319 command["VALUE"] = pythiaValue;
321 command["VERSION"] = "PYTHIA8";
322 extGenCommands->addCommand("PYTHIA", command);
324 } else if (token=="CDecay"){
328 name=parser.getToken(itoken++);
329 ipar=EvtPDL::getId(name);
331 if (ipar==EvtId(-1,-1)) {
332 report(ERROR,"EvtGen") <<"Unknown particle name:"<<name.c_str()
334 <<parser.getLineofToken(itoken-1)<<endl;
335 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
339 EvtId cipar=EvtPDL::chargeConj(ipar);
341 if (_decaytable[ipar.getAlias()].getNMode()!=0) {
343 report(DEBUG,"EvtGen") <<
344 "Redefined decay of "<<name.c_str()<<" in CDecay"<<endl;
346 _decaytable[ipar.getAlias()].removeDecay();
349 //take contents of cipar and conjugate and store in ipar
350 _decaytable[ipar.getAlias()].makeChargeConj(&_decaytable[cipar.getAlias()]);
352 } else if (token=="Define"){
356 name=parser.getToken(itoken++);
357 // value=atof(parser.getToken(itoken++).c_str());
359 EvtSymTable::define(name,parser.getToken(itoken++));
361 //New code Lange April 10, 2001 - allow the user
362 //to change particle definitions of EXISTING
363 //particles on the fly
364 } else if (token=="Particle"){
367 pname=parser.getToken(itoken++);
369 report(INFO,"EvtGen") << pname.c_str() << endl;
370 //There should be at least the mass
371 double newMass=atof(parser.getToken(itoken++).c_str());
372 EvtId thisPart = EvtPDL::getId(pname);
373 double newWidth=EvtPDL::getMeanMass(thisPart);
374 if ( parser.getNToken() > 3 ) newWidth=atof(parser.getToken(itoken++).c_str());
376 //Now make the change!
377 EvtPDL::reSetMass(thisPart, newMass);
378 EvtPDL::reSetWidth(thisPart, newWidth);
381 report(INFO,"EvtGen") << "Changing particle properties of " <<
382 pname.c_str() << " Mass=" << newMass << " Width="<<newWidth<<endl;
384 } else if ( token=="ChangeMassMin") {
386 pname=parser.getToken(itoken++);
387 double tmass=atof(parser.getToken(itoken++).c_str());
389 EvtId thisPart = EvtPDL::getId(pname);
390 EvtPDL::reSetMassMin(thisPart,tmass);
392 report(DEBUG,"EvtGen") <<"Refined minimum mass for " << EvtPDL::name(thisPart).c_str() << " to be " << tmass << endl;
394 } else if ( token=="ChangeMassMax") {
396 pname=parser.getToken(itoken++);
397 double tmass=atof(parser.getToken(itoken++).c_str());
398 EvtId thisPart = EvtPDL::getId(pname);
399 EvtPDL::reSetMassMax(thisPart,tmass);
401 report(DEBUG,"EvtGen") <<"Refined maximum mass for " << EvtPDL::name(thisPart).c_str() << " to be " << tmass << endl;
403 } else if ( token=="IncludeBirthFactor") {
405 pname=parser.getToken(itoken++);
407 if ( parser.getToken(itoken++)=="yes") yesno=true;
408 EvtId thisPart = EvtPDL::getId(pname);
409 EvtPDL::includeBirthFactor(thisPart,yesno);
411 if ( yesno ) report(DEBUG,"EvtGen") <<"Include birth factor for " << EvtPDL::name(thisPart).c_str() <<endl;
412 if ( !yesno ) report(DEBUG,"EvtGen") <<"No longer include birth factor for " << EvtPDL::name(thisPart).c_str() <<endl;
415 } else if ( token=="IncludeDecayFactor") {
417 pname=parser.getToken(itoken++);
419 if ( parser.getToken(itoken++)=="yes") yesno=true;
420 EvtId thisPart = EvtPDL::getId(pname);
421 EvtPDL::includeDecayFactor(thisPart,yesno);
423 if ( yesno ) report(DEBUG,"EvtGen") <<"Include decay factor for " << EvtPDL::name(thisPart).c_str() <<endl;
424 if ( !yesno ) report(DEBUG,"EvtGen") <<"No longer include decay factor for " << EvtPDL::name(thisPart).c_str() <<endl;
426 } else if ( token=="LSNONRELBW") {
428 pname=parser.getToken(itoken++);
429 EvtId thisPart = EvtPDL::getId(pname);
430 std::string tstr="NONRELBW";
431 EvtPDL::changeLS(thisPart,tstr);
433 report(DEBUG,"EvtGen") <<"Change lineshape to non-rel BW for " << EvtPDL::name(thisPart).c_str() <<endl;
434 } else if ( token=="LSFLAT") {
436 pname=parser.getToken(itoken++);
437 EvtId thisPart = EvtPDL::getId(pname);
438 std::string tstr="FLAT";
439 EvtPDL::changeLS(thisPart,tstr);
441 report(DEBUG,"EvtGen") <<"Change lineshape to flat for " << EvtPDL::name(thisPart).c_str() <<endl;
442 } else if ( token=="LSMANYDELTAFUNC") {
444 pname=parser.getToken(itoken++);
445 EvtId thisPart = EvtPDL::getId(pname);
446 std::string tstr="MANYDELTAFUNC";
447 EvtPDL::changeLS(thisPart,tstr);
449 report(DEBUG,"EvtGen") <<"Change lineshape to spikes for " << EvtPDL::name(thisPart).c_str() <<endl;
451 } else if ( token=="BlattWeisskopf") {
453 pname=parser.getToken(itoken++);
454 double tnum=atof(parser.getToken(itoken++).c_str());
455 EvtId thisPart = EvtPDL::getId(pname);
456 EvtPDL::reSetBlatt(thisPart,tnum);
458 report(DEBUG,"EvtGen") <<"Redefined Blatt-Weisskopf factor " << EvtPDL::name(thisPart).c_str() << " to be " << tnum << endl;
459 } else if ( token=="BlattWeisskopfBirth") {
461 pname=parser.getToken(itoken++);
462 double tnum=atof(parser.getToken(itoken++).c_str());
463 EvtId thisPart = EvtPDL::getId(pname);
464 EvtPDL::reSetBlattBirth(thisPart,tnum);
466 report(DEBUG,"EvtGen") <<"Redefined Blatt-Weisskopf birth factor " << EvtPDL::name(thisPart).c_str() << " to be " << tnum << endl;
467 } else if ( token=="SetLineshapePW") {
469 pname=parser.getToken(itoken++);
470 EvtId thisPart = EvtPDL::getId(pname);
471 std::string pnameD1=parser.getToken(itoken++);
472 EvtId thisD1 = EvtPDL::getId(pnameD1);
473 std::string pnameD2=parser.getToken(itoken++);
474 EvtId thisD2 = EvtPDL::getId(pnameD2);
475 int pw=atoi(parser.getToken(itoken++).c_str());
477 report(DEBUG,"EvtGen") <<"Redefined Partial wave for " << pname.c_str() << " to " << pnameD1.c_str() << " " << pnameD2.c_str() << " ("<<pw<<")"<<endl;
478 EvtPDL::setPWForDecay(thisPart,pw,thisD1,thisD2);
479 EvtPDL::setPWForBirthL(thisD1,pw,thisPart,thisD2);
480 EvtPDL::setPWForBirthL(thisD2,pw,thisPart,thisD1);
483 } else if (token=="Decay") {
485 std::string temp_fcn_new_model;
487 EvtDecayBase* temp_fcn_new;
493 parent=parser.getToken(itoken++);
494 ipar=EvtPDL::getId(parent);
496 if (ipar==EvtId(-1,-1)) {
497 report(ERROR,"EvtGen") <<"Unknown particle name:"<<parent.c_str()
499 <<parser.getLineofToken(itoken-1)<<endl;
500 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
504 if (_decaytable[ipar.getAlias()].getNMode()!=0) {
505 report(DEBUG,"EvtGen") <<"Redefined decay of "
506 <<parent.c_str()<<endl;
507 _decaytable[ipar.getAlias()].removeDecay();
513 token=parser.getToken(itoken++);
515 if (token!="Enddecay"){
518 while (token.c_str()[i++]!=0){
519 if (isalpha(token.c_str()[i])){
520 report(ERROR,"EvtGen") <<
521 "Expected to find a branching fraction or Enddecay "<<
522 "but found:"<<token.c_str()<<" on line "<<
523 parser.getLineofToken(itoken-1)<<endl;
524 report(ERROR,"EvtGen") << "Possibly to few arguments to model "<<
525 "on previous line!"<<endl;
526 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
531 brfr=atof(token.c_str());
533 int isname=EvtPDL::getId(parser.getToken(itoken)).getId()>=0;
534 int ismodel=modelist.isModel(parser.getToken(itoken));
536 if (!(isname||ismodel)){
537 //see if this is an aliased model
538 for(size_t iAlias=0;iAlias<modelAliasList.size();iAlias++){
539 if ( modelAliasList[iAlias].matchAlias(parser.getToken(itoken)) ) {
546 if (!(isname||ismodel)){
548 report(INFO,"EvtGen") << parser.getToken(itoken).c_str()
549 << " is neither a particle name nor "
550 << "the name of a model. "<<endl;
551 report(INFO,"EvtGen") << "It was encountered on line "<<
552 parser.getLineofToken(itoken)<<" of the decay file."<<endl;
553 report(INFO,"EvtGen") << "Please fix it. Thank you."<<endl;
554 report(INFO,"EvtGen") << "Be sure to check that the "
555 << "correct case has been used. \n";
556 report(INFO,"EvtGen") << "Terminating execution. \n";
564 while(EvtPDL::getId(parser.getToken(itoken)).getId()>=0){
565 sdaug=parser.getToken(itoken++);
566 daught[n_daugh++]=EvtPDL::getId(sdaug);
567 if (daught[n_daugh-1]==EvtId(-1,-1)) {
568 report(ERROR,"EvtGen") <<"Unknown particle name:"<<sdaug.c_str()
569 <<" on line "<<parser.getLineofToken(itoken)<<endl;
570 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
576 model=parser.getToken(itoken++);
584 if (model=="PHOTOS"){
586 model=parser.getToken(itoken++);
588 if (model=="VERBOSE"){
590 model=parser.getToken(itoken++);
592 if (model=="SUMMARY"){
594 model=parser.getToken(itoken++);
596 }while(model=="PHOTOS"||
600 //see if this is an aliased model
602 for(size_t iAlias=0;iAlias<modelAliasList.size();iAlias++){
603 if ( modelAliasList[iAlias].matchAlias(model) ) {
609 if ( foundAnAlias==-1 ) {
610 if(!modelist.isModel(model)){
611 report(ERROR,"EvtGen") <<
612 "Expected to find a model name,"<<
613 "found:"<<model.c_str()<<" on line "<<
614 parser.getLineofToken(itoken)<<endl;
615 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
620 model=modelAliasList[foundAnAlias].getName();
623 temp_fcn_new_model=model;
624 temp_fcn_new=modelist.getFcn(model);
628 temp_fcn_new->setPHOTOS();
631 temp_fcn_new->setVerbose();
634 temp_fcn_new->setSummary();
638 std::vector<std::string> temp_fcn_new_args;
643 if ( foundAnAlias==-1 ) {
645 name=parser.getToken(itoken++);
647 temp_fcn_new_args.push_back(EvtSymTable::get(name,ierr));
649 report(ERROR,"EvtGen")
650 <<"Reading arguments and found:"<<
651 name.c_str()<<" on line:"<<
652 parser.getLineofToken(itoken-1)<<endl;
653 report(ERROR,"EvtGen")
654 << "Will terminate execution!"<<endl;
658 //int isname=EvtPDL::getId(name).getId()>=0;
659 int ismodel=modelist.isModel(name);
661 report(ERROR,"EvtGen")
662 <<"Expected ';' but found:"<<
663 name.c_str()<<" on line:"<<
664 parser.getLineofToken(itoken-1)<<endl;
665 report(ERROR,"EvtGen")
666 << "Most probable error is omitted ';'."<<endl;
667 report(ERROR,"EvtGen")
668 << "Will terminate execution!"<<endl;
674 std::vector<std::string> copyMe=modelAliasList[foundAnAlias].getArgList();
675 temp_fcn_new_args=copyMe;
682 temp_fcn_new->saveDecayInfo(ipar,n_daugh,
684 temp_fcn_new_args.size(),
691 // for (i=0;i<n_daugh;i++){
692 for (i=0;i<temp_fcn_new->nRealDaughters();i++){
693 if ( EvtPDL::getMinMass(daught[i])>0.0001 ){
694 massmin+=EvtPDL::getMinMass(daught[i]);
696 massmin+=EvtPDL::getMeanMass(daught[i]);
700 _decaytable[ipar.getAlias()].addMode(temp_fcn_new,brfrsum,massmin);
704 } while(token!="Enddecay");
706 _decaytable[ipar.getAlias()].finalize();
709 // Allow copying of decays from one particle to another; useful
710 // in combination with RemoveDecay
711 else if (token=="CopyDecay") {
715 newname=parser.getToken(itoken++);
716 oldname=parser.getToken(itoken++);
718 EvtId newipar=EvtPDL::getId(newname);
719 EvtId oldipar=EvtPDL::getId(oldname);
721 if (oldipar==EvtId(-1,-1)) {
722 report(ERROR,"EvtGen") <<"Unknown particle name:"<<oldname.c_str()
723 <<" on line "<<parser.getLineofToken(itoken)<<endl;
724 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
727 if (newipar==EvtId(-1,-1)) {
728 report(ERROR,"EvtGen") <<"Unknown particle name:"<<newname.c_str()
729 <<" on line "<<parser.getLineofToken(itoken)<<endl;
730 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
733 if (_decaytable[newipar.getAlias()].getNMode()!=0) {
734 report(DEBUG,"EvtGen") <<"Redefining decay of "
736 _decaytable[newipar.getAlias()].removeDecay();
738 _decaytable[newipar.getAlias()] = _decaytable[oldipar.getAlias()];
740 // Enable decay deletion; intended primarily for aliases
741 // Peter Onyisi, March 2008
742 else if (token=="RemoveDecay") {
743 parent = parser.getToken(itoken++);
744 ipar = EvtPDL::getId(parent);
746 if (ipar==EvtId(-1,-1)) {
747 report(ERROR,"EvtGen") <<"Unknown particle name:"<<parent.c_str()
749 <<parser.getLineofToken(itoken-1)<<endl;
750 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
754 if (_decaytable[ipar.getAlias()].getNMode()==0) {
755 report(DEBUG,"EvtGen") << "No decays to delete for "
756 << parent.c_str() << endl;
758 report(DEBUG,"EvtGen") <<"Deleting selected decays of "
759 <<parent.c_str()<<endl;
763 token = parser.getToken(itoken);
765 if (token != "Enddecay") {
767 while (EvtPDL::getId(parser.getToken(itoken)).getId() >= 0) {
768 sdaug = parser.getToken(itoken++);
769 daught[n_daugh++] = EvtPDL::getId(sdaug);
770 if (daught[n_daugh-1]==EvtId(-1,-1)) {
771 report(ERROR,"EvtGen") <<"Unknown particle name:"<<sdaug.c_str()
772 <<" on line "<<parser.getLineofToken(itoken)<<endl;
773 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
777 token = parser.getToken(itoken);
779 report(ERROR,"EvtGen")
780 <<"Expected ';' but found:"<<
781 token <<" on line:"<<
782 parser.getLineofToken(itoken-1)<<endl;
783 report(ERROR,"EvtGen")
784 << "Most probable error is omitted ';'."<<endl;
785 report(ERROR,"EvtGen")
786 << "Will terminate execution!"<<endl;
789 token = parser.getToken(itoken++);
790 EvtDecayBase* temp_fcn_new = modelist.getFcn("PHSP");
791 std::vector<std::string> temp_fcn_new_args;
792 std::string temp_fcn_new_model("PHSP");
793 temp_fcn_new->saveDecayInfo(ipar, n_daugh,
799 _decaytable[ipar.getAlias()].removeMode(temp_fcn_new);
801 } while (token != "Enddecay");
804 else if (token!="End"){
806 report(ERROR,"EvtGen") << "Found unknown command:'"<<token.c_str()<<"' on line "
807 <<parser.getLineofToken(itoken)<<endl;
808 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
813 } while ((token!="End")&&itoken!=parser.getNToken());
815 //Now we may need to reset the minimum mass for some particles????
817 for (size_t ii=0; ii<EvtPDL::entries(); ii++){
819 int nModTot=getNMode(ii);
821 if ( nModTot == 0 ) continue;
823 if ( EvtPDL::getWidth(temp) < 0.0000001 ) continue;
825 double minMass=EvtPDL::getMaxMass(temp);
826 for (jj=0; jj<nModTot; jj++) {
827 double tmass=_decaytable[ii].getDecay(jj).getMassMin();
828 if ( tmass< minMass) minMass=tmass;
830 if ( minMass > EvtPDL::getMinMass(temp) ) {
832 report(INFO,"EvtGen") << "Given allowed decays, resetting minMass " << EvtPDL::name(temp).c_str() << " "
833 << EvtPDL::getMinMass(temp) << " to " << minMass << endl;
834 EvtPDL::reSetMassMin(temp,minMass);
839 void EvtDecayTable::readXMLDecayFile(const std::string dec_name, bool verbose){
840 if ( _decaytable.size() < EvtPDL::entries() ) _decaytable.resize(EvtPDL::entries());
841 EvtModel &modelist=EvtModel::instance();
842 EvtExtGeneratorCommandsTable* extGenCommands = EvtExtGeneratorCommandsTable::getInstance();
845 parser.open(dec_name);
848 std::string decayParent = "";
850 std::vector<EvtModelAlias> modelAliasList;
851 bool endReached = false;
853 while(parser.readNextTag()) {
854 //TAGS FOUND UNDER DATA
855 if(parser.getParentTagTitle() == "data") {
856 if(parser.getTagTitle() == "photos") {
857 std::string usage = parser.readAttribute("usage");
858 if(usage == "always") {
859 EvtRadCorr::setAlwaysRadCorr();
861 report(INFO,"EvtGen")
862 << "As requested, PHOTOS will be turned on for all decays."<<endl;
863 } else if(usage == "never") {
864 EvtRadCorr::setNeverRadCorr();
866 report(INFO,"EvtGen")
867 << "As requested, PHOTOS will be turned off."<<endl;
869 EvtRadCorr::setNormalRadCorr();
871 report(INFO,"EvtGen")
872 << "As requested, PHOTOS will be turned on only when requested."<<endl;
875 } else if(parser.getTagTitle() == "alias") {
876 std::string alias = parser.readAttribute("name");
877 std::string particle = parser.readAttribute("particle");
878 checkParticle(particle);
879 EvtId id=EvtPDL::getId(particle);
881 EvtPDL::alias(id,alias);
882 if ( _decaytable.size() < EvtPDL::entries() ) _decaytable.resize(EvtPDL::entries());
884 } else if(parser.getTagTitle() == "modelAlias") {
885 std::vector<std::string> modelArgList;
887 std::string alias = parser.readAttribute("name");
888 std::string model = parser.readAttribute("model");
889 std::string paramStr = parser.readAttribute("params");
890 std::istringstream paramStream(paramStr);
895 EvtDecayBase* fcn = modelist.getFcn(model);
897 std::string paramName = fcn->getParamName(0);
898 while(paramName!="") {
899 param = parser.readAttribute(paramName,fcn->getParamDefault(i));
901 modelArgList.push_back(param);
903 paramName = fcn->getParamName(i);
906 while(std::getline(paramStream, param, ' ')) {
907 modelArgList.push_back(param);
910 EvtModelAlias newAlias(alias,model,modelArgList);
911 modelAliasList.push_back(newAlias);
913 } else if(parser.getTagTitle() == "chargeConj") {
914 std::string particle = parser.readAttribute("particle");
915 std::string conjugate = parser.readAttribute("conjugate");
917 EvtId a=EvtPDL::getId(particle);
918 EvtId abar=EvtPDL::getId(conjugate);
920 checkParticle(particle);
921 checkParticle(conjugate);
923 EvtPDL::aliasChgConj(a,abar);
925 } else if(parser.getTagTitle() == "conjDecay") {
926 std::string particle = parser.readAttribute("particle");
928 EvtId a=EvtPDL::getId(particle);
929 EvtId abar=EvtPDL::chargeConj(a);
931 checkParticle(particle);
932 checkParticle(abar.getName());
934 if (_decaytable[a.getAlias()].getNMode()!=0) {
936 report(DEBUG,"EvtGen") <<
937 "Redefined decay of "<<particle.c_str()<<" in ConjDecay"<<endl;
939 _decaytable[a.getAlias()].removeDecay();
942 //take contents of abar and conjugate and store in a
943 _decaytable[a.getAlias()].makeChargeConj(&_decaytable[abar.getAlias()]);
945 } else if(parser.getTagTitle() == "define") {
946 std::string name = parser.readAttribute("name");
947 std::string value = parser.readAttribute("value");
948 EvtSymTable::define(name,value);
950 } else if(parser.getTagTitle() == "particle") {
951 std::string name = parser.readAttribute("name");
952 double mass = parser.readAttributeDouble("mass");
953 double width = parser.readAttributeDouble("width");
954 double minMass = parser.readAttributeDouble("massMin");
955 double maxMass = parser.readAttributeDouble("massMax");
956 std::string birthFactor = parser.readAttribute("includeBirthFactor");
957 std::string decayFactor = parser.readAttribute("includeDecayFactor");
958 std::string lineShape = parser.readAttribute("lineShape");
959 double blattWeisskopfD = parser.readAttributeDouble("blattWeisskopfFactor");
960 double blattWeisskopfB = parser.readAttributeDouble("blattWeisskopfBirth");
962 EvtId thisPart = EvtPDL::getId(name);
966 EvtPDL::reSetMass(thisPart, mass);
967 report(DEBUG,"EvtGen") <<"Refined mass for " << EvtPDL::name(thisPart).c_str() << " to be " << mass << endl;
970 EvtPDL::reSetWidth(thisPart, width);
971 report(DEBUG,"EvtGen") <<"Refined width for " << EvtPDL::name(thisPart).c_str() << " to be " << width << endl;
974 EvtPDL::reSetMassMin(thisPart,minMass);
975 report(DEBUG,"EvtGen") <<"Refined minimum mass for " << EvtPDL::name(thisPart).c_str() << " to be " << minMass << endl;
978 EvtPDL::reSetMassMax(thisPart,maxMass);
979 report(DEBUG,"EvtGen") <<"Refined maximum mass for " << EvtPDL::name(thisPart).c_str() << " to be " << maxMass << endl;
981 if(!birthFactor.empty()) {
982 EvtPDL::includeBirthFactor(thisPart,stringToBoolean(birthFactor));
984 if(stringToBoolean(birthFactor)) {
985 report(DEBUG,"EvtGen") <<"Include birth factor for " << EvtPDL::name(thisPart).c_str() <<endl;
987 report(DEBUG,"EvtGen") <<"No longer include birth factor for " << EvtPDL::name(thisPart).c_str() <<endl;
991 if(!decayFactor.empty()) {
992 EvtPDL::includeDecayFactor(thisPart,stringToBoolean(decayFactor));
994 if(stringToBoolean(decayFactor)) {
995 report(DEBUG,"EvtGen") <<"Include decay factor for " << EvtPDL::name(thisPart).c_str() <<endl;
997 report(DEBUG,"EvtGen") <<"No longer include decay factor for " << EvtPDL::name(thisPart).c_str() <<endl;
1001 if(!lineShape.empty()) {
1002 EvtPDL::changeLS(thisPart,lineShape);
1004 report(DEBUG,"EvtGen") <<"Change lineshape to " << lineShape << " for " << EvtPDL::name(thisPart).c_str() <<endl;
1006 if(blattWeisskopfD != -1) {
1007 EvtPDL::reSetBlatt(thisPart,blattWeisskopfD);
1009 report(DEBUG,"EvtGen") <<"Redefined Blatt-Weisskopf factor "
1010 << EvtPDL::name(thisPart).c_str() << " to be " << blattWeisskopfD << endl;
1012 if(blattWeisskopfB != -1) {
1013 EvtPDL::reSetBlattBirth(thisPart,blattWeisskopfB);
1015 report(DEBUG,"EvtGen") <<"Redefined Blatt-Weisskopf birth factor "
1016 << EvtPDL::name(thisPart).c_str() << " to be " << blattWeisskopfB << endl;
1018 } else if(parser.getTagTitle() == "lineShapePW") {
1019 std::string parent = parser.readAttribute("parent");
1020 std::string daug1 = parser.readAttribute("daug1");
1021 std::string daug2 = parser.readAttribute("daug2");
1022 int pw = parser.readAttributeInt("pw");
1024 checkParticle(parent);
1025 checkParticle(daug1);
1026 checkParticle(daug2);
1028 EvtId thisPart = EvtPDL::getId(parent);
1029 EvtId thisD1 = EvtPDL::getId(daug1);
1030 EvtId thisD2 = EvtPDL::getId(daug2);
1032 EvtPDL::setPWForDecay(thisPart,pw,thisD1,thisD2);
1033 EvtPDL::setPWForBirthL(thisD1,pw,thisPart,thisD2);
1034 EvtPDL::setPWForBirthL(thisD2,pw,thisPart,thisD1);
1036 report(DEBUG,"EvtGen") <<"Redefined Partial wave for " << parent.c_str() << " to "
1037 << daug1.c_str() << " " << daug2.c_str() << " ("<<pw<<")"<<endl;
1039 } else if(parser.getTagTitle() == "decay") { //start of a particle
1041 decayParent = parser.readAttribute("name");
1042 checkParticle(decayParent);
1043 ipar=EvtPDL::getId(decayParent);
1045 if (_decaytable[ipar.getAlias()].getNMode()!=0) {
1046 report(DEBUG,"EvtGen") <<"Redefined decay of "
1047 <<decayParent.c_str()<<endl;
1048 _decaytable[ipar.getAlias()].removeDecay();
1051 } else if(parser.getTagTitle() == "copyDecay") {
1052 std::string particle = parser.readAttribute("particle");
1053 std::string copy = parser.readAttribute("copy");
1055 EvtId newipar=EvtPDL::getId(particle);
1056 EvtId oldipar=EvtPDL::getId(copy);
1058 checkParticle(particle);
1059 checkParticle(copy);
1061 if (_decaytable[newipar.getAlias()].getNMode()!=0) {
1062 report(DEBUG,"EvtGen") <<"Redefining decay of "
1064 _decaytable[newipar.getAlias()].removeDecay();
1066 _decaytable[newipar.getAlias()] = _decaytable[oldipar.getAlias()];
1068 } else if(parser.getTagTitle() == "removeDecay") {
1069 decayParent = parser.readAttribute("particle");
1070 checkParticle(decayParent);
1071 ipar=EvtPDL::getId(decayParent);
1073 if (_decaytable[ipar.getAlias()].getNMode()==0) {
1074 report(DEBUG,"EvtGen") << "No decays to delete for "
1075 << decayParent.c_str() << endl;
1077 report(DEBUG,"EvtGen") <<"Deleting selected decays of "
1078 <<decayParent.c_str()<<endl;
1081 } else if(parser.getTagTitle() == "pythiaParam") {
1083 command["GENERATOR"] = parser.readAttribute("generator");
1084 command["MODULE"] = parser.readAttribute("module");
1085 command["PARAM"] = parser.readAttribute("param");
1086 command["VALUE"] = parser.readAttribute("value");
1087 command["VERSION"] = "PYTHIA8";
1088 extGenCommands->addCommand("PYTHIA", command);
1090 } else if(parser.getTagTitle() == "pythia6Param") {
1092 command["GENERATOR"] = parser.readAttribute("generator");
1093 command["MODULE"] = parser.readAttribute("module");
1094 command["PARAM"] = parser.readAttribute("param");
1095 command["VALUE"] = parser.readAttribute("value");
1096 command["VERSION"] = "PYTHIA6";
1097 extGenCommands->addCommand("PYTHIA", command);
1099 } else if(parser.getTagTitle() == "/data") { //end of data
1103 } else if(parser.getTagTitle() == "Title" || parser.getTagTitle() == "Details"
1104 || parser.getTagTitle() == "Author" || parser.getTagTitle() == "Version"
1105 //the above tags are expected to be in the XML decay file but are not used by EvtGen
1106 || parser.getTagTitle() == "dalitzDecay" || parser.getTagTitle() == "copyDalitz") {
1107 //the above tags are only used by EvtGenModels/EvtDalitzTable
1108 } else { report(INFO,"EvtGen") << "Unknown tag "<<parser.getTagTitle()
1109 <<" found in XML decay file near line "<<parser.getLineNumber()<<". Tag will be ignored."<<endl;
1111 //TAGS FOUND UNDER DECAY
1112 } else if(parser.getParentTagTitle() == "decay") {
1113 if(parser.getTagTitle() == "channel") { //start of a channel
1115 EvtId daughter[MAX_DAUG];
1117 EvtDecayBase* temp_fcn_new;
1118 std::string temp_fcn_new_model;
1119 std::vector<std::string> temp_fcn_new_args;
1121 double brfr = parser.readAttributeDouble("br");
1122 std::string daugStr = parser.readAttribute("daughters");
1123 std::istringstream daugStream(daugStr);
1124 std::string model = parser.readAttribute("model");
1125 std::string paramStr = parser.readAttribute("params");
1126 std::istringstream paramStream(paramStr);
1127 bool decVerbose = parser.readAttributeBool("verbose");
1128 bool decPhotos = parser.readAttributeBool("photos");
1129 bool decSummary = parser.readAttributeBool("summary");
1132 while(std::getline(daugStream, daugh, ' ')) {
1133 checkParticle(daugh);
1134 daughter[nDaughters++] = EvtPDL::getId(daugh);
1137 int modelAlias = -1;
1138 for(size_t iAlias=0;iAlias<modelAliasList.size();iAlias++){
1139 if ( modelAliasList[iAlias].matchAlias(model) ) {
1145 if ( modelAlias==-1 ) {
1146 if(!modelist.isModel(model)){
1147 report(ERROR,"EvtGen") <<
1148 "Expected to find a model name near line "<<parser.getLineNumber()<<","<<
1149 "found:"<<model.c_str()<<endl;
1150 report(ERROR,"EvtGen") << "Will terminate execution!"<<endl;
1154 model=modelAliasList[modelAlias].getName();
1157 temp_fcn_new_model = model;
1158 temp_fcn_new = modelist.getFcn(model);
1160 if(decPhotos) temp_fcn_new->setPHOTOS();
1161 if(decVerbose) temp_fcn_new->setVerbose();
1162 if(decSummary) temp_fcn_new->setSummary();
1165 if(modelAlias == -1) {
1167 if(paramStr == "") {
1169 std::string paramName = temp_fcn_new->getParamName(0);
1170 while(paramName != "") {
1171 param = parser.readAttribute(paramName,temp_fcn_new->getParamDefault(i));
1172 if(param == "") break; //params must be added in order so we can't just skip the missing ones
1173 temp_fcn_new_args.push_back(EvtSymTable::get(param,ierr));
1175 report(ERROR,"EvtGen")
1176 <<"Reading arguments near line "<<parser.getLineNumber()<<" and found:"<<
1177 param.c_str()<<endl;
1178 report(ERROR,"EvtGen")
1179 << "Will terminate execution!"<<endl;
1183 paramName = temp_fcn_new->getParamName(i);
1186 } else {//if the params are not set seperately
1187 while(std::getline(paramStream, param, ' ')) {
1188 temp_fcn_new_args.push_back(EvtSymTable::get(param,ierr));
1190 report(ERROR,"EvtGen")
1191 <<"Reading arguments near line "<<parser.getLineNumber()<<" and found:"<<
1192 param.c_str()<<endl;
1193 report(ERROR,"EvtGen")
1194 << "Will terminate execution!"<<endl;
1200 std::vector<std::string> copyMe=modelAliasList[modelAlias].getArgList();
1201 temp_fcn_new_args=copyMe;
1206 temp_fcn_new->saveDecayInfo(ipar,nDaughters,
1208 temp_fcn_new_args.size(),
1215 for (int i=0;i<temp_fcn_new->nRealDaughters();i++){
1216 if ( EvtPDL::getMinMass(daughter[i])>0.0001 ){
1217 massMin+=EvtPDL::getMinMass(daughter[i]);
1219 massMin+=EvtPDL::getMeanMass(daughter[i]);
1223 _decaytable[ipar.getAlias()].addMode(temp_fcn_new,brfrSum,massMin);
1225 } else if(parser.getTagTitle() == "/decay") { //end of a particle
1226 _decaytable[ipar.getAlias()].finalize();
1227 } else report(INFO,"EvtGen") << "Unexpected tag "<<parser.getTagTitle()
1228 <<" found in XML decay file near line "<<parser.getLineNumber()<<". Tag will be ignored."<<endl;
1229 //TAGS FOUND UNDER REMOVEDECAY
1230 } else if(parser.getParentTagTitle() == "removeDecay") {
1231 if(parser.getTagTitle() == "channel") { //start of a channel
1233 EvtId daughter[MAX_DAUG];
1235 std::string daugStr = parser.readAttribute("daughters");
1236 std::istringstream daugStream(daugStr);
1239 while(std::getline(daugStream, daugh, ' ')) {
1240 checkParticle(daugh);
1241 daughter[nDaughters++] = EvtPDL::getId(daugh);
1244 EvtDecayBase* temp_fcn_new = modelist.getFcn("PHSP");
1245 std::vector<std::string> temp_fcn_new_args;
1246 std::string temp_fcn_new_model("PHSP");
1247 temp_fcn_new->saveDecayInfo(ipar, nDaughters,
1253 _decaytable[ipar.getAlias()].removeMode(temp_fcn_new);
1254 } else if(parser.getTagTitle() != "/removeDecay") {
1255 report(INFO,"EvtGen") << "Unexpected tag "<<parser.getTagTitle()
1256 <<" found in XML decay file near line "<<parser.getLineNumber()<<". Tag will be ignored."<<endl;
1259 }//while lines in file
1262 report(INFO,"EvtGen") << "Either the decay file ended prematurely or the file is badly formed.\n"
1263 <<"Error occured near line"<<parser.getLineNumber()<<endl;
1267 //Now we may need to reset the minimum mass for some particles????
1268 for (size_t ii=0; ii<EvtPDL::entries(); ii++){
1270 int nModTot=getNMode(ii);
1272 if ( nModTot == 0 ) continue;
1274 if ( EvtPDL::getWidth(temp) < 0.0000001 ) continue;
1276 double minMass=EvtPDL::getMaxMass(temp);
1277 for (jj=0; jj<nModTot; jj++) {
1278 double tmass=_decaytable[ii].getDecay(jj).getMassMin();
1279 if ( tmass< minMass) minMass=tmass;
1281 if ( minMass > EvtPDL::getMinMass(temp) ) {
1283 report(INFO,"EvtGen") << "Given allowed decays, resetting minMass " << EvtPDL::name(temp).c_str() << " "
1284 << EvtPDL::getMinMass(temp) << " to " << minMass << endl;
1285 EvtPDL::reSetMassMin(temp,minMass);
1290 bool EvtDecayTable::stringToBoolean(std::string valStr) {
1291 return (valStr == "true" || valStr == "1" || valStr == "on" || valStr == "yes");
1294 void EvtDecayTable::checkParticle(std::string particle) {
1295 if (EvtPDL::getId(particle)==EvtId(-1,-1)) {
1296 report(ERROR,"EvtGen") <<"Unknown particle name:"<<particle.c_str()<<endl;
1297 report(ERROR,"EvtGen") <<"Will terminate execution!"<<endl;
1302 EvtDecayBase* EvtDecayTable::findDecayModel(EvtId id, int modeInt) {
1304 int aliasInt = id.getAlias();
1306 EvtDecayBase* theModel = this->findDecayModel(aliasInt, modeInt);
1312 EvtDecayBase* EvtDecayTable::findDecayModel(int aliasInt, int modeInt) {
1314 EvtDecayBase* theModel(0);
1316 if (aliasInt >= 0 && aliasInt < (int) EvtPDL::entries()) {
1318 theModel = _decaytable[aliasInt].getDecayModel(modeInt);
1326 bool EvtDecayTable::hasPythia(EvtId id) {
1328 bool hasPythia = this->hasPythia(id.getAlias());
1333 bool EvtDecayTable::hasPythia(int aliasInt) {
1335 bool hasPythia(false);
1336 if (aliasInt >= 0 && aliasInt < (int) EvtPDL::entries()) {
1338 hasPythia = _decaytable[aliasInt].isJetSet();
1346 int EvtDecayTable::getNModes(EvtId id) {
1348 int nModes = this->getNModes(id.getAlias());
1353 int EvtDecayTable::getNModes(int aliasInt) {
1357 if (aliasInt >= 0 && aliasInt < (int) EvtPDL::entries()) {
1359 nModes = _decaytable[aliasInt].getNMode();
1366 int EvtDecayTable::findChannel(EvtId parent, std::string model,
1367 int ndaug, EvtId *daugs,
1368 int narg, std::string *args){
1371 EvtId daugs_scratch[50];
1374 for(i=0;i<_decaytable[parent.getAlias()].getNMode();i++){
1378 right=right&&model==_decaytable[parent.getAlias()].
1379 getDecay(i).getDecayModel()->getModelName();
1380 right=right&&(ndaug==_decaytable[parent.getAlias()].
1381 getDecay(i).getDecayModel()->getNDaug());
1382 right=right&&(narg==_decaytable[parent.getAlias()].
1383 getDecay(i).getDecayModel()->getNArg());
1389 for(j=0;j<ndaug;j++){
1390 daugs_scratch[j]=daugs[j];
1395 for(j=0;j<_decaytable[parent.getAlias()].
1396 getDecay(i).getDecayModel()->getNDaug();j++){
1398 for(k=0;k<ndaug;k++){
1399 if (daugs_scratch[k]==_decaytable[parent.getAlias()].
1400 getDecay(i).getDecayModel()->getDaug(j)){
1401 daugs_scratch[k]=EvtId(-1,-1);
1408 right=right&&(nmatch==ndaug);
1410 for(j=0;j<_decaytable[parent.getAlias()].
1411 getDecay(i).getDecayModel()->getNArg();j++){
1412 right=right&&(args[j]==_decaytable[parent.getAlias()].
1413 getDecay(i).getDecayModel()->getArgStr(j));
1416 if (right) return i;
1421 int EvtDecayTable::inChannelList(EvtId parent, int ndaug, EvtId *daugs){
1424 EvtId daugs_scratch[MAX_DAUG];
1427 for(i=0;i<ndaug;i++){
1428 dsum+=daugs[i].getAlias();
1433 int ipar=parent.getAlias();
1435 int nmode=_decaytable[ipar].getNMode();
1437 for(i=0;i<nmode;i++){
1439 EvtDecayBase* thedecaymodel=_decaytable[ipar].getDecay(i).getDecayModel();
1441 if (thedecaymodel->getDSum()==dsum){
1443 int nd=thedecaymodel->getNDaug();
1446 for(j=0;j<ndaug;j++){
1447 daugs_scratch[j]=daugs[j];
1451 for(k=0;k<ndaug;k++){
1452 if (EvtId(daugs_scratch[k])==thedecaymodel->getDaug(j)){
1453 daugs_scratch[k]=EvtId(-1,-1);
1459 if ((nmatch==ndaug)&&
1461 ((thedecaymodel->getModelName()=="JETSET")||
1462 (thedecaymodel->getModelName()=="PYTHIA")))){
1472 std::vector<std::string> EvtDecayTable::splitString(std::string& theString,
1473 std::string& splitter) {
1475 // Code from STLplus
1476 std::vector<std::string> result;
1478 if (!theString.empty() && !splitter.empty()) {
1480 for (std::string::size_type offset = 0;;) {
1482 std::string::size_type found = theString.find(splitter, offset);
1484 if (found != std::string::npos) {
1485 std::string tmpString = theString.substr(offset, found-offset);
1486 if (tmpString.size() > 0) {result.push_back(tmpString);}
1487 offset = found + splitter.size();
1489 std::string tmpString = theString.substr(offset, theString.size()-offset);
1490 if (tmpString.size() > 0) {result.push_back(tmpString);}