~maddevelopers/mg5amcnlo/new_clustering

« back to all changes in this revision

Viewing changes to models/usermod.py

  • Committer: Rikkert Frederix
  • Date: 2021-09-09 15:51:40 UTC
  • mfrom: (78.75.502 3.2.1)
  • Revision ID: frederix@physik.uzh.ch-20210909155140-rg6umfq68h6h47cf
merge with 3.2.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
    different part of the model. Check of consistency of the model are performed.
18
18
    This produce a new valid UFO model in output.
19
19
"""
 
20
from __future__ import absolute_import
20
21
import copy
21
22
import glob
22
23
import logging
31
32
import models.import_ufo as import_ufo
32
33
import models.check_param_card as check_param_card
33
34
from madgraph import MG5DIR
 
35
import six
 
36
from six.moves import range
34
37
 
35
38
pjoin =os.path.join
36
39
logger = logging.getLogger('madgraph.model')
55
58
        model = ufomodels.load_model(modelpath)
56
59
        # Check the validity of the model. Too old UFO (before UFO 1.0)
57
60
        if not hasattr(model, 'all_orders'):
58
 
            raise USRMODERROR, 'Base Model doesn\'t follows UFO convention (no couplings_order information)\n' +\
59
 
                               'MG5 is able to load such model but NOT to the add model feature.'
60
 
        if isinstance(model.all_particles[0].mass, basestring):
61
 
            raise USRMODERROR, 'Base Model doesn\'t follows UFO convention (Mass/Width of particles are string name, not object)\n' +\
62
 
                               'MG5 is able to load such model but NOT to the add model feature.' 
 
61
            raise USRMODERROR('Base Model doesn\'t follows UFO convention (no couplings_order information)\n' +\
 
62
                               'MG5 is able to load such model but NOT to the add model feature.')
 
63
        if isinstance(model.all_particles[0].mass, six.string_types):
 
64
            raise USRMODERROR('Base Model doesn\'t follows UFO convention (Mass/Width of particles are string name, not object)\n' +\
 
65
                               'MG5 is able to load such model but NOT to the add model feature.') 
63
66
                                 
64
67
        old_particles = [id(p) for p in model.all_particles]
65
68
        self.particles = [copy.copy(p) for p in model.all_particles]
66
69
        if any(hasattr(p, 'loop_particles') for p in self.particles):
67
 
            raise USRMODERROR, 'Base Model doesn\'t follows UFO convention '
 
70
            raise USRMODERROR('Base Model doesn\'t follows UFO convention ')
68
71
        self.vertices = list(model.all_vertices)
69
72
        # ensure that the particles are correctly listed
70
73
        for v in self.vertices:
212
215
        """convert param to string in order to have it written correctly for the 
213
216
        UFO file"""
214
217
 
215
 
        if isinstance(param, basestring): 
 
218
        if isinstance(param, six.string_types): 
216
219
            return "'%s'" % param.replace("\\", "\\\\").replace('\'', '\\\'').replace('\"', '\\\"')
217
220
        elif isinstance(param, int) or isinstance(param, float) or \
218
221
                                                       isinstance(param, complex):
219
222
            return "%s" % param
220
 
        elif isinstance(param, long):
 
223
        elif isinstance(param, int):
221
224
            return ("%s" % param).replace('L','')
222
225
        elif isinstance(param, list):
223
226
            return '[%s]' % ', '.join(self.format_param(p) for p in param)
239
242
        elif param is None:
240
243
            return 'None'
241
244
        else:
242
 
            raise Exception, '%s unknow type for writting UFO' % param.__class__.__name__
 
245
            raise Exception('%s unknow type for writting UFO' % param.__class__.__name__)
243
246
 
244
247
 
245
248
 
292
295
            other_attr = [name for name in obj.get_all().keys() 
293
296
                                                  if name not in args]
294
297
        else:
295
 
            other_attr = obj.__dict__.keys()
 
298
            other_attr = list(obj.__dict__.keys())
296
299
        
297
300
        if str(obj.__class__.__name__) == 'CTParameter' and 'nature' in other_attr:
298
301
            logger.critical('UFO model is outdated (including some bugs). Please update object_library.py to latest version')
445
448
        """ """
446
449
        text = """
447
450
# This file was automatically created by The UFO_usermod        
448
 
 
449
451
from object_library import all_orders, CouplingOrder
450
452
"""
451
453
 
476
478
        
477
479
        text = """
478
480
# This file was automatically created by The UFO_usermod   
 
481
 
479
482
from object_library import all_propagators, Propagator
480
483
"""
481
484
 
540
543
            if part.name == name:
541
544
                return part
542
545
        
543
 
        raise USRMODERROR, 'no particle %s in the model' % name
 
546
        raise USRMODERROR('no particle %s in the model' % name)
544
547
 
545
548
    def add_parameter(self, parameter, identify_pid={}):
546
549
        """wrapper to call the correct function"""
576
579
                return self.check_mass_width_of_particle(old_part, particle)
577
580
            elif identify:
578
581
                if particle.spin != old_part.spin:
579
 
                    raise USRMODERROR, "identify particles should have the same spin"
 
582
                    raise USRMODERROR("identify particles should have the same spin")
580
583
                elif particle.color != old_part.color:
581
 
                    raise USRMODERROR, "identify particles should have the same color"
 
584
                    raise USRMODERROR("identify particles should have the same color")
582
585
                particle.replace = old_part
583
586
                return self.check_mass_width_of_particle(old_part, particle)
584
587
            else:
585
588
                logger.warning('The particle name \'%s\' is present in both model with different pdg code' % name)
586
589
                logger.warning('The particle coming from the plug-in model will be rename to \'%s%s\'' % (name, self.addon))
587
590
                particle.name = '%s%s' % (name, self.addon)
 
591
                particle.antiname = '%s%s' % (particle.antiname, self.addon)
588
592
                self.particles.append(particle)
589
593
                return
590
594
        elif identify:
591
 
            raise USRMODERROR, "Particle %s is not in the model" % identify
 
595
            raise USRMODERROR("Particle %s is not in the model" % identify)
592
596
 
593
597
        pdg = particle.pdg_code
594
598
        if pdg in self.particle_dict:
606
610
            #different name but actually  the same
607
611
            if p_plugin.mass.name in self.old_new:
608
612
                if self.old_new[p_plugin.mass.name] != p_base.mass.name:
609
 
                    raise USRMODERROR, 'Some inconsistency in the mass assignment in the model: equivalent of %s is %s != %s ' % ( p_plugin.mass.name, self.old_new[p_plugin.mass.name], p_base.mass.name)
 
613
                    raise USRMODERROR('Some inconsistency in the mass assignment in the model: equivalent of %s is %s != %s ' % ( p_plugin.mass.name, self.old_new[p_plugin.mass.name], p_base.mass.name))
610
614
            elif  p_base.mass.name.lower() == 'zero':
611
615
                p_base.mass = p_plugin.mass
612
616
            elif  p_plugin.mass.name.lower() == 'zero':
615
619
                misc.sprint(p_base.mass.value, p_plugin.mass.value, dir(p_base.mass))
616
620
                misc.sprint(p_base.mass.nature, p_plugin.mass.nature)
617
621
                misc.sprint(self.old_new)
618
 
                raise USRMODERROR, 'Some inconsistency in the mass assignment in the model\n' + \
 
622
                raise USRMODERROR('Some inconsistency in the mass assignment in the model\n' + \
619
623
             '     Mass: %s and %s\n' %(p_base.mass.name, p_plugin.mass.name) + \
620
624
             '     conflict name %s\n' % self.old_new + \
621
 
             '     pdg_code: %s %s' % (p_base.pdg_code, p_plugin.pdg_code)
 
625
             '     pdg_code: %s %s' % (p_base.pdg_code, p_plugin.pdg_code))
622
626
        # Check the width
623
627
        if p_base.width.name != p_plugin.width.name:
624
628
            #different name but actually  the same
625
629
            if p_plugin.width.name in self.old_new:
626
630
                if self.old_new[p_plugin.width.name] != p_base.width.name:
627
 
                    raise USRMODERROR, 'Some inconsistency in the mass assignment in the model'
 
631
                    raise USRMODERROR('Some inconsistency in the mass assignment in the model')
628
632
            elif  p_base.width.name.lower() == 'zero':
629
633
                p_base.width = p_plugin.width
630
634
            elif  p_plugin.width.name.lower() == 'zero':
631
635
                pass
632
636
            else:
633
 
                raise USRMODERROR, 'Some inconsistency in the mass assignment in the model'        
 
637
                raise USRMODERROR('Some inconsistency in the mass assignment in the model')        
634
638
        
635
639
        return
636
640
 
676
680
            logger.info('The two model defines the block \'%s\' with id \'%s\' with different parameter name \'%s\', \'%s\'\n'\
677
681
                      %  (old_param.lhablock, old_param.lhacode, parameter.name, old_param.name) + \
678
682
            '     We will merge those two parameters in a single one')
679
 
            if parameter.name in self.old_new.values():
 
683
            if parameter.name in list(self.old_new.values()):
680
684
                key = [k for k in self.old_new if self.old_new[k] == parameter.name][0]
681
685
                self.old_new[key] = old_param.name
682
686
                self.old_new[parameter.name] = old_param.name
700
704
                logger.info('The two model defines the parameter for  block \'%s\' with id \'%s\' with different parameter name \'%s\', \'%s\'\n'\
701
705
                      %  (parameter.lhablock.lower(), lhacode[0], parameter.name, old_param.name) + \
702
706
                '     We will merge those two parameters in a single one')
703
 
                if parameter.name in self.old_new.values():
 
707
                if parameter.name in list(self.old_new.values()):
704
708
                    key = [k for k in self.old_new if self.old_new[k] == parameter.name][0]
705
709
                    self.old_new[key] = old_param.name
706
710
                    self.old_new[parameter.name] = old_param.name
723
727
                return #Nothing to do!
724
728
            else:
725
729
                if self.old_new:
726
 
                    pattern = re.compile(r'\b(%s)\b' % '|'.join(self.old_new.keys()))
 
730
                    pattern = re.compile(r'\b(%s)\b' % '|'.join(list(self.old_new.keys())))
727
731
                    def replace(matchobj):
728
732
                        return self.old_new[matchobj.group(0)]
729
733
                    parameter.value = pattern.sub(replace, parameter.value)
735
739
        
736
740
        # No name conflict:
737
741
        if self.old_new:
738
 
            pattern = re.compile(r'\b(%s)\b' % '|'.join(self.old_new.keys()))
 
742
            pattern = re.compile(r'\b(%s)\b' % '|'.join(list(self.old_new.keys())))
739
743
            def replace(matchobj):
740
744
                return self.old_new[matchobj.group(0)]
741
745
            parameter.value = pattern.sub(replace, parameter.value)
755
759
            coupling.name = '%s%s' % (coupling.name, self.addon)
756
760
        
757
761
        if self.old_new:  
758
 
            pattern = re.compile(r'\b(%s)\b' % '|'.join(self.old_new.keys()))
 
762
            pattern = re.compile(r'\b(%s)\b' % '|'.join(list(self.old_new.keys())))
759
763
            def replace(matchobj):
760
764
                return self.old_new[matchobj.group(0)]
761
765
            coupling.value = pattern.sub(replace, coupling.value)
801
805
            lorentz.name = '%s%s' % (lorentz.name, self.addon)
802
806
        
803
807
        if self.old_new:     
804
 
            pattern = re.compile(r'\b(%s)\b' % '|'.join(self.old_new.keys()))
 
808
            pattern = re.compile(r'\b(%s)\b' % '|'.join(list(self.old_new.keys())))
805
809
            def replace(matchobj):
806
810
                return self.old_new[matchobj.group(0)]
807
811
            lorentz.structure = pattern.sub(replace, lorentz.structure)
851
855
        iden_vertex = [v for v in self.vertices if get_pdg(v) == id_part]
852
856
        iden = False
853
857
        nb_coupling = len(interaction.couplings)
854
 
        keys = interaction.couplings.keys() # to have a fixed order!
 
858
        keys = list(interaction.couplings.keys()) # to have a fixed order!
855
859
        
856
860
        get_lor_and_color =  lambda i: (interaction.lorentz[keys[i][1]].structure,
857
861
                       interaction.color[keys[i][0]])
940
944
            model = ufomodels.load_model(path) 
941
945
                
942
946
        if not model:
943
 
            raise USRMODERROR, 'Need a valid Model'
 
947
            raise USRMODERROR('Need a valid Model')
944
948
        else:
945
949
            path = model.__path__[0]
946
950
        # Check the validity of the model. Too old UFO (before UFO 1.0)
947
951
        if not hasattr(model, 'all_orders'):
948
 
            raise USRMODERROR, 'Add-on Model doesn\'t follows UFO convention (no couplings_order information)\n' +\
949
 
                               'MG5 is able to load such model but NOT to the add model feature.'
950
 
        if isinstance(model.all_particles[0].mass, basestring):
951
 
            raise USRMODERROR, 'Add-on Model doesn\'t follows UFO convention (Mass/Width of particles are string name, not object)\n' +\
952
 
                               'MG5 is able to load such model but NOT to the add model feature.' 
 
952
            raise USRMODERROR('Add-on Model doesn\'t follows UFO convention (no couplings_order information)\n' +\
 
953
                               'MG5 is able to load such model but NOT to the add model feature.')
 
954
        if isinstance(model.all_particles[0].mass, six.string_types):
 
955
            raise USRMODERROR('Add-on Model doesn\'t follows UFO convention (Mass/Width of particles are string name, not object)\n' +\
 
956
                               'MG5 is able to load such model but NOT to the add model feature.') 
953
957
    
954
958
        for order in model.all_orders:
955
959
            if hasattr(order, 'perturbative_expansion') and order.perturbative_expansion:
956
 
                raise USRMODERROR, 'Add-on model can not be loop model.' 
 
960
                raise USRMODERROR('Add-on model can not be loop model.') 
957
961
                              
958
962
        for order in model.all_orders:
959
963
            self.add_coupling_order(order)
997
1001
                # end for the case security
998
1002
                identify_pid[new_part.pdg_code] = old_part.pdg_code   
999
1003
                if new_part is None:
1000
 
                    raise USRMODERROR, "particle %s not in added model" % new
 
1004
                    raise USRMODERROR("particle %s not in added model" % new)
1001
1005
                if old_part is None:
1002
 
                    raise USRMODERROR, "particle %s not in original model" % old
 
1006
                    raise USRMODERROR("particle %s not in original model" % old)
1003
1007
                if new_part.antiname not in identify_particles:
1004
1008
                    new_anti = new_part.antiname
1005
1009
                    old_anti = old_part.antiname
1006
1010
                    if old_anti == old:
1007
 
                        raise USRMODERROR, "failed identification (one particle is self-conjugate and not the other)"
 
1011
                        raise USRMODERROR("failed identification (one particle is self-conjugate and not the other)")
1008
1012
                    logger.info("adding identification for anti-particle: %s=%s" % (new_anti, old_anti))
1009
1013
                    identify_particles[new_anti] = old_anti
1010
1014