@@ -39,7 +39,7 @@ def __init__(self):
3939 self .default_benchmark = None
4040 self .morpher = None
4141 self .export_morphing = False
42- self .systematics = None
42+ self .systematics = OrderedDict ()
4343
4444 def add_parameter (
4545 self ,
@@ -368,57 +368,75 @@ def set_morphing(
368368 morpher .n_components - n_predefined_benchmarks ,
369369 )
370370
371- def set_systematics (self , scale_variation = None , scales = "together" , pdf_variation = None ):
371+ def reset_systematics (self ):
372+ self .systematics = OrderedDict ()
373+
374+ def add_systematics (
375+ self ,
376+ effect ,
377+ systematic_name = None ,
378+ norm_variation = 1.1 ,
379+ scale = "mu" ,
380+ scale_variations = (0.5 , 1.0 , 2.0 ),
381+ pdf_variation = "CT10" ,
382+ ):
372383 """
373- Prepares the simulation of the effect of different nuisance parameters, including scale variations and PDF
374- changes.
375384
376385 Parameters
377386 ----------
378- scale_variation : None or tuple of float, optional
379- If not None, the regularization and / or factorization scales are varied. A tuple like (0.5,1.,2.)
380- specifies the factors with which they are varied. Default value: None.
381-
382- scales : {"together", "independent", "mur", "muf"}, optional
383- Whether only the regularization scale ("mur"), only the factorization scale ("muf"), both simultanously
384- ("together") or both independently ("independent") are varied. Default value: "together".
385-
386- pdf_variation : None or str, optional
387- If not None, the PDFs are varied. The option is passed along to the `--pdf` option
387+ effect : {"norm", "scale", "pdf"}
388+ Type of the nuisance parameter. If "norm", it will affect the overall normalization of one or multiple
389+ samples in the process. If "scale", the nuisance parameter effect will be determined by varying
390+ factorization or regularization scales (depending on scale_variation and scales). If "pdf", the effect
391+ of the nuisance parameters will be determined by varying the PDF used.
392+
393+ systematic_name : None or str, optional
394+
395+ scale : {"mu", "mur", "muf"}, optional
396+ If type is "scale", this sets whether only the regularization scale ("mur"), only the factorization scale
397+ ("muf"), or both simulatenously ("mu") are varied. Default value:
398+ "mu".
399+
400+ norm_variation : float, optional
401+ If type is "norm", this sets the relative effect of the nuisance parameter on the cross section at the
402+ "plus 1 sigma" variation. 1.1 corresponds to a 10% increase, 0.9 to a 10% decrease relative to the nominal
403+ cross section. Default value: 1.1.
404+
405+ scale_variations : tuple of float, optional
406+ If type is "scale", this sets how the regularization and / or factorization scales are varied. A tuple
407+ like (0.5,1.,2.) specifies the factors with which they are varied. Default value: (0.5,1.,2.0).
408+
409+ pdf_variation : str, optional
410+ If type is "pdf", defines the PDF set for the variation. The option is passed along to the `--pdf` option
388411 of MadGraph's systematics module. See https://cp3.irmp.ucl.ac.be/projects/madgraph/wiki/Systematics for a
389- list. The option "CT10" would, as an example, run over all the eigenvectors of the CTEQ10 set.
412+ list. The option "CT10" would, as an example, run over all the eigenvectors of the CTEQ10 set. Default
413+ value: "CT10".
390414
391415 Returns
392416 -------
393417 None
394418
395419 """
396420
397- # Check input
398- if scales not in ["together" , "independent" , "mur" , "muf" ]:
399- raise ValueError ("Unknown value {} for argument scales" .format (scales ))
400-
401- # Save systematics setup
402- self .systematics = OrderedDict ()
403-
404- if scale_variation is not None :
405- scale_variation_string = "," .join ([str (factor ) for factor in scale_variation ])
406-
407- if scales == "together" :
408- self .systematics ["mu" ] = scale_variation_string
409- elif scales == "independent" :
410- self .systematics ["muf" ] = scale_variation_string
411- self .systematics ["mur" ] = scale_variation_string
412- elif scales == "mur" :
413- self .systematics ["mur" ] = scale_variation_string
414- elif scales == "muf" :
415- self .systematics ["muf" ] = scale_variation_string
416-
417- if pdf_variation is not None :
418- self .systematics ["pdf" ] = pdf_variation
419-
420- if len (self .systematics ) == 0 :
421- self .systematics = None
421+ # Default name
422+ if systematic_name is None :
423+ i = 0
424+ while "{}_{}" .format (effect , i ) in list (six .iterkeys (self .systematics )):
425+ i += 1
426+ systematic_name = "{}_{}" .format (type , i )
427+ systematic_name = systematic_name .replace (" " , "_" )
428+ systematic_name = systematic_name .replace ("-" , "_" )
429+
430+ if effect == "pdf" :
431+ self .systematics [systematic_name ] = ("pdf" , pdf_variation )
432+ elif effect == "scale" :
433+ scale_variation_string = "," .join ([str (factor ) for factor in scale_variations ])
434+ assert scale in ["mu" , "mur" , "muf" ]
435+ self .systematics [systematic_name ] = ("scale" , scale , scale_variation_string )
436+ elif effect == "norm" :
437+ self .systematics [systematic_name ] = ("norm" , norm_variation )
438+ else :
439+ raise ValueError ("Unknown systematic type {}, has to be one of 'norm', 'scale', or 'pdf'!" .format (type ))
422440
423441 def load (self , filename , disable_morphing = False ):
424442 """
@@ -489,13 +507,13 @@ def load(self, filename, disable_morphing=False):
489507 logger .info ("Did not find morphing setup." )
490508
491509 # Systematics setup
492- if self .systematics is None :
510+ if len ( self .systematics ) == 0 :
493511 logger .info ("Did not find systematics setup." )
494512 else :
495513 logger .info ("Found systematics setup with %s nuisance parameter groups" , len (self .systematics ))
496514
497515 for key , value in six .iteritems (self .systematics ):
498- logger .debug (" %s: %s" , key , value )
516+ logger .debug (" %s: %s" , key , " / " . join ( str ( x ) for x in value ) )
499517
500518 def save (self , filename ):
501519 """
@@ -635,6 +653,7 @@ def run(
635653 temp_directory = None ,
636654 initial_command = None ,
637655 python2_override = False ,
656+ systematics = None ,
638657 ):
639658
640659 """
@@ -713,6 +732,9 @@ def run(
713732 Python 2.6 or Python 2.7. If you use systematics, make sure that the python interface of LHAPDF was compiled
714733 with the Python version you are using. Default: False.
715734
735+ systematics : None or list of str, optional
736+ If list of str, defines which systematics are used for this run.
737+
716738 Returns
717739 -------
718740 None
@@ -737,6 +759,7 @@ def run(
737759 temp_directory = temp_directory ,
738760 initial_command = initial_command ,
739761 python2_override = python2_override ,
762+ systematics = systematics ,
740763 )
741764
742765 def run_multiple (
@@ -755,6 +778,7 @@ def run_multiple(
755778 temp_directory = None ,
756779 initial_command = None ,
757780 python2_override = False ,
781+ systematics = None ,
758782 ):
759783
760784 """
@@ -825,6 +849,9 @@ def run_multiple(
825849 Python 2.6 or Python 2.7. If you use systematics, make sure that the python interface of LHAPDF was compiled
826850 with the Python version you are using. Default: False.
827851
852+ systematics : None or list of str, optional
853+ If list of str, defines which systematics are used for these runs.
854+
828855 Returns
829856 -------
830857 None
@@ -867,6 +894,14 @@ def run_multiple(
867894 ]
868895 )
869896
897+ # Systematics
898+ if systematics is None :
899+ systematics_used = self .systematics
900+ else :
901+ systematics_used = OrderedDict ()
902+ for key in systematics :
903+ systematics_used [key ] = self .systematics [key ]
904+
870905 # Loop over settings
871906 i = 0
872907 mg_scripts = []
@@ -898,9 +933,9 @@ def run_multiple(
898933 logger .info (" Log file: %s" , log_file_run )
899934
900935 # Check input
901- if run_card_file is None and self .systematics is not None :
936+ if run_card_file is None and self ._check_pdf_or_scale_variation ( systematics_used ) :
902937 logger .warning (
903- "Warning: No run card given, but systematics set up. The correct systematics"
938+ "Warning: No run card given, but PDF or scale variation set up. The correct systematics"
904939 " settings are not set automatically. Make sure to set them correctly!"
905940 )
906941
@@ -918,7 +953,7 @@ def run_multiple(
918953 export_run_card (
919954 template_filename = run_card_file ,
920955 run_card_filename = mg_process_directory + "/" + new_run_card_file ,
921- systematics = self . systematics ,
956+ systematics = systematics_used ,
922957 )
923958
924959 # Copy Pythia card
@@ -983,3 +1018,9 @@ def run_multiple(
9831018 "folders:\n \n %s\n \n " ,
9841019 expected_event_files ,
9851020 )
1021+
1022+ def _check_pdf_or_scale_variation (self , systematics ):
1023+ for value in six .itervalues (systematics ):
1024+ if value [0 ] in ["pdf" , "scale" ]:
1025+ return True
1026+ return False
0 commit comments