Skip to content

Commit f748273

Browse files
committed
more tweaks for sigmoids
1 parent c03f2e9 commit f748273

17 files changed

Lines changed: 557 additions & 252 deletions

File tree

ostap/fitting/background.py

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,15 +1336,24 @@ def __init__ ( self ,
13361336

13371337
if isinstance ( sigmoid_type , string_types ) :
13381338
stl = str ( sigmoid_type ).lower()
1339-
if stl in ( 'logistic' , ) : sigmoid_type = Ostap.Math.Sigmoid.Logistic
1340-
elif stl in ( 'hyperbolic' , 'tanh' ) : sigmoid_type = Ostap.Math.Sigmoid.Hyperbolic
1341-
elif stl in ( 'trigonometric' , 'atan' ) : sigmoid_type = Ostap.Math.Sigmoid.Trigonometric
1342-
elif stl in ( 'error' , 'erf' ) : sigmoid_type = Ostap.Math.Sigmoid.Error
1343-
elif stl in ( 'gudermannian' , 'gd' ) : sigmoid_type = Ostap.Math.Sigmoid.Gudermannian
1339+
if stl in ( 'logistic' , ) : sigmoid_type = Ostap.Math.SigmoidType.Logistic
1340+
elif stl in ( 'hyperbolic' , 'tanh' ) : sigmoid_type = Ostap.Math.SigmoidType.Hyperbolic
1341+
elif stl in ( 'trigonometric' , 'atan' ) : sigmoid_type = Ostap.Math.SigmoidType.Trigonometric
1342+
elif stl in ( 'error' , 'erf' ) : sigmoid_type = Ostap.Math.SigmoidType.Error
1343+
elif stl in ( 'gudermannian' , 'gd' ) : sigmoid_type = Ostap.Math.SigmoidType.Gudermannian
1344+
elif stl in ( 'algebraic' , ) : sigmoid_type = Ostap.Math.SigmoidType.Algebdraic
1345+
elif stl in ( 'smooth' , ) : sigmoid_type = Ostap.Math.SigmoidType.SmoothTransition
1346+
elif stl in ( 'poly0' , 'p0' ) : sigmoid_type = Ostap.Math.SigmoidType.Polynomial_n0
1347+
elif stl in ( 'poly1' , 'p1' ) : sigmoid_type = Ostap.Math.SigmoidType.Polynomial_n1
1348+
elif stl in ( 'poly2' , 'p2' ) : sigmoid_type = Ostap.Math.SigmoidType.Polynomial_n2
1349+
elif stl in ( 'poly3' , 'p3' ) : sigmoid_type = Ostap.Math.SigmoidType.Polynomial_n3
1350+
elif stl in ( 'poly4' , 'p4' ) : sigmoid_type = Ostap.Math.SigmoidType.Polynomial_n4
1351+
elif stl in ( 'poly5' , 'p5' ) : sigmoid_type = Ostap.Math.SigmoidType.Polynomial_n5
1352+
elif stl in ( 'poly6' , 'p6' ) : sigmoid_type = Ostap.Math.SigmoidType.Polynomial_n6
13441353
else : raise TypeError ( "Invalid Sigmoid type %s" % sigmoid_type )
13451354

13461355
sigmoid_type = int ( sigmoid_type )
1347-
assert Ostap.Math.Sigmoid.First <= sigmoid_type <= Ostap.Math.Sigmoid.Last , \
1356+
assert Ostap.Math.Sigmoidtype.First <= sigmoid_type <= Ostap.Math.SigmoidType.Last , \
13481357
'Invalid Sigmoid type: %s' % sigmoid_type
13491358

13501359
no_xmin = xmin is None

ostap/fitting/fithelpers.py

Lines changed: 106 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@
3232
'NameDuplicates' , ## allow/disallow name duplicates
3333
'SETPARS' , ## context manager to keep/preserve parameters
3434
###
35-
'TailN' , ## helper mixing to define N-parameter for tail
36-
'TailNL' , ## helper mixing to define N-parameter for tail
37-
'TailNR' , ## helper mixing to define N-parameter for tail
35+
'TailN' , ## helper mixin to define N-parameter for tail
36+
'TailNL' , ## helper mixin to define N-parameter for tail
37+
'TailNR' , ## helper mixin to define N-parameter for tail
3838
##
39-
'Tail' , ## helper mixing to define power-law tail
40-
'LeftTail' , ## helper mixing to define power-law (left) tail
41-
'RightTail' , ## helper mixing to define power-law (right) tail
39+
'Tail' , ## helper mixin to define power-law tail
40+
'LeftTail' , ## helper mixin to define power-law (left) tail
41+
'RightTail' , ## helper mixin to define power-law (right) tail
4242
##
43-
'SigmaLR' , ## helper mixing to treat L/R sigmas
44-
'TwoSigmas' , ## helper mixing to treat two sigmas
43+
'SigmaLR' , ## helper mixin to treat L/R sigmas
44+
'TwoSigmas' , ## helper mixin to treat two sigmas
4545
)
4646
# =============================================================================
4747
from ostap.core.meta_info import root_info
@@ -650,6 +650,62 @@ def set_value ( var , value , ok = lambda a , b : True ) :
650650
# =========================================================================
651651
## Create some expressions with variables
652652
# =========================================================================
653+
654+
# =============================================================================
655+
## construct (on-flight) variable for the sum of many variables \f$ sum_i v_i \f$
656+
# @code
657+
# var1 = ...
658+
# var2 = ...
659+
# var2 = ...
660+
# var4 = xxx.add_variables ( var1 , var2 , var3 )
661+
# @endcode
662+
def add_variables ( self , *variables , name = '' , title = '' ) :
663+
""" Construct (on-flight) variable for var1*c1+var2*c2
664+
>>> var1 = ...
665+
>>> var2 = ...
666+
>>> var3 =
667+
>>> var4 = xxx.add_variables ( var1 , var2 , var3 )
668+
"""
669+
## the most trivial case
670+
if not variables : return ROOT.RooFit.RooConst ( 0 )
671+
672+
## collect variables
673+
vvars = []
674+
vsum = 0.0
675+
for i , v in enumerate ( variables ) :
676+
if isinstance ( v , num_types ) : vsum += float ( v )
677+
elif isinstance ( v , ROOT.RooConstVar ) : vsum += float ( v )
678+
elif isinstance ( v , ROOT.RooAbsReal ) : vvars.append ( v )
679+
else :
680+
raise TypeError ("add_variables: invalid variable[#%d] type %s" % ( i , typename ( v ) ) )
681+
682+
## no variables?
683+
if not vvars : return ROOT.RooFit.RooConst ( vsum )
684+
685+
## only one variable ?
686+
if 1 == len ( vvars ) : return self.vars_add ( vvars [ 0 ] , vsum , name = name , title = title )
687+
688+
## at least two variables
689+
vlst = ROOT.RooArgList()
690+
for v in vvars : vlst.add ( v )
691+
692+
## if constant is not zero - add it!
693+
if vsum :
694+
vsum = ROOT.RooFit.RooConst ( vsum )
695+
vlst.add ( vsum )
696+
697+
self.aux_keep.append ( vlst )
698+
699+
name = name if name else self.roo_name ( "_add_" .join ( v.name for v in vlst ) )
700+
title = title if title else ( "+" .join ( v.name for v in vlst ) )
701+
702+
## add variables
703+
result = Ostap.MoreRooFit.Addition ( name , title , vlst )
704+
self.aux_keep.append ( result )
705+
706+
return result
707+
708+
sum_variables = add_variables
653709

654710
# =========================================================================
655711
## construct (on-flight) variable for the product of
@@ -670,7 +726,9 @@ def vars_multiply ( self , var1 , var2 , name = '' , title = '' ) :
670726
>>> var4 = xxx.vars_multiply ( var1 , 2 , 'sigma2' , title = 'Scaled sigma' )
671727
>>> var3 = xxx.vars_product ( var1 , var2 )
672728
>>> var4 = xxx.vars_product ( var1 , 2 , 'sigma2' , title = 'Scaled sigma' )
673-
"""
729+
"""
730+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
731+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
674732

675733
f1 = isinstance ( var1 , num_types )
676734
f2 = isinstance ( var2 , num_types )
@@ -704,7 +762,6 @@ def vars_multiply ( self , var1 , var2 , name = '' , title = '' ) :
704762

705763
return result
706764

707-
708765
# =============================================================================
709766
## construct (on-flight) variable for the sum of
710767
# <code>var1</code> and <code>var2</code> \f$ v\equiv c_1v_1 + c_2v_2\f$
@@ -726,36 +783,34 @@ def vars_add ( self , var1 , var2 , c1 = 1 , c2 = 1 , name = '' , title = '' ) :
726783
>>> var6 = xxx.vars_sum ( var1 , 2 , 'sigma2' , title = 'Scaled sigma' )
727784
"""
728785

786+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
787+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
788+
729789
assert isinstance ( c1 , num_types ) and isinstance ( c2 , num_types ),\
730790
"vars_add: c1 and c2 must be numeric types!"
731791

732792
c1 = float ( c1 )
733793
c2 = float ( c2 )
734794

735-
if 0 == c1 and 0 == c2 :
736-
return ROOT.RooFit.RooConst ( 0 ) ## shortcut
737-
elif 0 == c1 :
738-
return self.vars_multiply ( var2 , c2 , name = name , title = title )
739-
elif 0 == c2 :
740-
return self.vars_multiply ( var1 , c1 , name = name , title = title )
795+
if 0 == c1 and 0 == c2 : return ROOT.RooFit.RooConst ( 0 ) ## shortcut
796+
elif 0 == c1 : return self.vars_multiply ( var2 , c2 , name = name , title = title )
797+
elif 0 == c2 : return self.vars_multiply ( var1 , c1 , name = name , title = title )
741798

742799
f1 = isinstance ( var1 , num_types )
743800
f2 = isinstance ( var2 , num_types )
744801

745802
if f1 and f2 :
746803
res = float ( var1 ) * float ( c1 ) + float ( var2 ) * float ( c2 )
747-
return ROOT.RooFit.RooConst ( res )
804+
return ROOT.RooFit.RooConst ( res )
748805
elif f1 :
749806
## shortcut
750-
if 0 == var1 :
751-
return self.var_multiply ( var2 , c2 , name = name , title = title ) ## SHORTCUT
807+
if 0 == var1 : return self.var_multiply ( var2 , c2 , name = name , title = title ) ## SHORTCUT
752808
#
753809
var1 = ROOT.RooFit.RooConst ( float ( var1 ) * float ( c1 ) )
754810
return self.vars_add ( var1 , var2 , name = name , title = title )
755811
elif f2 :
756812
## shortcut
757-
if 0 == var2 :
758-
return self.var_multiply ( var1 , c1 , name = name , title = title ) ## SHORTCUT
813+
if 0 == var2 : return self.var_multiply ( var1 , c1 , name = name , title = title ) ## SHORTCUT
759814
#
760815
var2 = ROOT.RooFit.RooConst ( float ( var2 ) * float ( c2 ) )
761816
return self.vars_add ( var1 , var2 , name =name , title = title )
@@ -766,10 +821,8 @@ def vars_add ( self , var1 , var2 , c1 = 1 , c2 = 1 , name = '' , title = '' ) :
766821
name = name if name else self.roo_name ( "add_%s_%s" % ( var1.name , var2.name ) )
767822
title = title if title else "(%s)+(%s)" % ( var1.name , var2.name )
768823

769-
if c1 == 1 and c2 == 1 :
770-
result = Ostap.MoreRooFit.Addition ( var1 , var2 , name , title )
771-
else :
772-
result = Ostap.MoreRooFit.Addition2 ( name , title , var1 , var2 , c1 , c2 )
824+
if c1 == 1 and c2 == 1 : result = Ostap.MoreRooFit.Addition ( var1 , var2 , name , title )
825+
else : result = Ostap.MoreRooFit.Addition2 ( name , title , var1 , var2 , c1 , c2 )
773826

774827
self.aux_keep.append ( result )
775828

@@ -796,6 +849,9 @@ def vars_subtract ( self , var1 , var2 , name = '' , title = '' ) :
796849
>>> var6 = xxx.vars_difference ( var1 , 2 , 'sigma2' , title = 'Scaled sigma' )
797850
"""
798851

852+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
853+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
854+
799855
f1 = isinstance ( var1 , num_types )
800856
f2 = isinstance ( var2 , num_types )
801857

@@ -846,6 +902,9 @@ def vars_divide ( self , var1 , var2 , name = '' , title = '' ) :
846902
>>> var6 = xxx.vars_ratio ( var1 , 2 , 'sigma2' , title = 'Scaled sigma' )
847903
"""
848904

905+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
906+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
907+
849908
f1 = isinstance ( var1 , num_types )
850909
f2 = isinstance ( var2 , num_types )
851910

@@ -886,6 +945,9 @@ def vars_fraction ( self , var1 , var2 , name = '' , title = '' ) :
886945
>>> var4 = xxx.vars_fraction ( var1 , 2 , 'sigma2' , title = 'exression' )
887946
"""
888947

948+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
949+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
950+
889951
f1 = isinstance ( var1 , num_types )
890952
f2 = isinstance ( var2 , num_types )
891953

@@ -935,6 +997,9 @@ def vars_asymmetry ( self , var1 , var2 , scale = 1 , name = '' , title = '' ) :
935997
>>> var4 = xxx.vars_reldifference ( var1 , 2 , 'sigma2' , title = 'exression' )
936998
"""
937999

1000+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
1001+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
1002+
9381003
f1 = isinstance ( var1 , num_types )
9391004
f2 = isinstance ( var2 , num_types )
9401005

@@ -981,6 +1046,10 @@ def vars_power ( self , var1 , var2 , name = '' , title = '' ) :
9811046
>>> var4 = xxx.vars_power ( var1 , 2.0 )
9821047
>>> var4 = xxx.vars_power ( 2.0 , var2 )
9831048
"""
1049+
1050+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
1051+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
1052+
9841053
f1 = isinstance ( var1 , num_types )
9851054
f2 = isinstance ( var2 , num_types )
9861055

@@ -1009,7 +1078,7 @@ def vars_power ( self , var1 , var2 , name = '' , title = '' ) :
10091078

10101079
return result
10111080

1012-
# =============================================================================
1081+
# =============================================================================
10131082
## construct (on-flight) variable for \f$ exp(ab) \f$
10141083
# <code>var1</code> and <code>var2</code>:
10151084
# @code
@@ -1027,6 +1096,10 @@ def vars_exp ( self , var1 , var2 = 1 , name = '' , title = '' ) :
10271096
>>> var4 = xxx.vars_exp ( var1 , 2.0 )
10281097
>>> var4 = xxx.vars_exp ( 2.0 , var2 )
10291098
"""
1099+
1100+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
1101+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
1102+
10301103
f1 = isinstance ( var1 , num_types )
10311104
f2 = isinstance ( var2 , num_types )
10321105

@@ -1073,6 +1146,10 @@ def vars_abs ( self , var1 , var2 = 1 , name = '' , title = '' ) :
10731146
>>> var4 = xxx.vars_abs ( var1 , 2.0 )
10741147
>>> var4 = xxx.vars_abs ( 2.0 , var2 )
10751148
"""
1149+
1150+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
1151+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
1152+
10761153
f1 = isinstance ( var1 , num_types )
10771154
f2 = isinstance ( var2 , num_types )
10781155

@@ -1109,7 +1186,6 @@ def vars_abs ( self , var1 , var2 = 1 , name = '' , title = '' ) :
11091186
vars_pow = vars_power
11101187
vars_expo = vars_exp
11111188

1112-
11131189
# =========================================================================
11141190
## helper function to create <code>RooFormulaVar</code>
11151191
# @code
@@ -1171,7 +1247,6 @@ def vars_formula ( self , formula , vars , name = '' , title = '' ) :
11711247

11721248
return rfv
11731249

1174-
11751250
# =========================================================================
11761251
## make very specific combination of variables: alpha*var1*(bets+gamma*var2)
11771252
# \f$ r = \alpha v_1 ( \beta + \gamma * v_2 ) \
@@ -1187,6 +1262,9 @@ def vars_combination ( self ,
11871262
r = alpha * v_1 ( beta + gamma * v_2 )
11881263
"""
11891264

1265+
if isinstance ( var1 , ROOT.RooConstVar ) : var1 = float ( var1 )
1266+
if isinstance ( var2 , ROOT.RooConstVar ) : var2 = float ( var2 )
1267+
11901268
f1 = isinstance ( var1 , num_types )
11911269
f2 = isinstance ( var2 , num_types )
11921270

ostap/fitting/rooreduce.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,22 @@ def _r2v_reduce ( var ) :
920920

921921
Ostap.MoreRooFit.TwoVars.__reduce__ = _r2v_reduce
922922

923+
# =============================================================================
924+
## Reduce <code>Ostap::MoreRooFit::Sigmoid</code> objects
925+
# @see Ostap::MoreRooFit.Sigmoid
926+
def _r2vsigm_reduce ( var ) :
927+
""" Reduce `Ostap.MoreRooFit.Sigmoid` objects
928+
- see Ostap.MoreRooFit.Sigmouid
929+
"""
930+
return root_store_factory , ( type ( var ) ,
931+
var.name ,
932+
var.title ,
933+
var.x() ,
934+
var.y() ,
935+
var.sigmoid_type () )
936+
937+
Ostap.MoreRooFit.Sigmoid.__reduce__ = _r2vsigm_reduce
938+
923939
# ===================================================================
924940
## Reduce <code>Ostap::MoreRooFit::Addition</code> objects
925941
# @see Ostap::MoreRooFit.Addition

0 commit comments

Comments
 (0)