#!/usr/bin/env gaudirun.py 
# =============================================================================
# @file
#
# WG-production for
#
#  - B -> psi(') n*pi m*K     decays, 1<=(n+m)<= 6 
#  - B -> psi(') eta('),omega decays
#  - B -> psi(') K(K) eta('),omega decays
#  - B  -> psi C                                      (included into X )
#  - B+ -> psi (K*+ -> K+ pi0 ) for photon efficiency (included into X0) 
#  - B+ -> psi pp H
#
#  - Upsilon -> mumu
#  - chi_b   -> ( Upsilon gamma ) 
#
# Input :  DIMUON.DST
#
# Outputs :
#
#  - BandQ.PSIX.mdst
#  - BandQ.PSIX0.mdst
#  - BandQ.BOTTOM.mdst
#
# @author Vanya BELYAEV Ivan.Belyaev@itep.ru
# @date   2012-08-17
#
# @attention DataType and CondDB are not specified!
#
# For 2k+11-data:
#
# @code
#
#  gaudirun.py  $BANDQCONFIGROOT/scripts/BandQ.py $BANDQCONFIGROOT/scripts/DataType-2011.py  the_file_with_input_data.py
#
# @endcode
#
# For 2k+12-data:
#
# @code
# 
# gaudirun.py  $BANDQCONFIGROOT/scripts/BandQ.py $BANDQCONFIGROOT/scripts/DataType-2012.py  the_file_with_input_data.py
#
# @endcode
#
#                    $Revision: 150278 $
#  Last modification $Date: 2012-12-18 16:28:58 +0100 (Tue, 18 Dec 2012) $
#                 by $Author: ibelyaev $ 
# =============================================================================
"""

WG-production for

  - B -> psi(') n*pi m*K     decays, 1<=(n+m)<= 6 
  - B -> psi(') eta('),omega decays
  - B -> psi(') K(K) eta('),omega decays
  - B  -> psi C                                      (included into X )
  - B+ -> psi (K*+ -> K+ pi0 ) for photon efficiency (included into X0) 
  - B+ -> psi pp H

  - Upsilon -> mumu
  - chi_b   -> ( Upsilon gamma ) 

Input :  DIMUON.DST

Outputs :

  - BandQ.PSIX.mdst
  - BandQ.PSIX0.mdst
  - BandQ.UPSILON.mdst
    
Attention: DataType and CondDB are not specified!
> gaudirun.py  BandQ.py $BANDQCONFIGROOT/scripts/DataTypoe-2011.py   data.py
> gaudirun.py  BandQ.py $BANDQCONFIGROOT/scripts/DataTypoe-2012.py   data.py
   
"""
# =============================================================================
__author__   = "Vanya BELYAEV Ivan.Belyaev@itep.ru"
__date__     = "$Date: 2012-12-18 16:28:58 +0100 (Tue, 18 Dec 2012) $"
__version__  = "$Revision: 150278 $"
# =============================================================================
## logging
# =============================================================================
try : 
    from AnalysisPython.Logger import getLogger
    _name = __name__
    if 0 == _name.find ( '__'   ) : _name = 'WG/B&Q'
    logger = getLogger (  _name )
except:
    from Gaudi.Configuration import log as logger
    
# =============================================================================
from GaudiKernel.SystemOfUnits import GeV 

## the_year = "2012"


# =============================================================================
# 0. import basic elements
# =============================================================================
import StrippingSelections.StrippingBandQ.StrippingUpsilonExotic  as BOTTOM
import StrippingSelections.StrippingBandQ.StrippingPsiX0          as PSIX0  
import StrippingSelections.StrippingBandQ.StrippingPsiXForBandQ   as PSIX
import StrippingSelections.StrippingCharm.StrippingPromptCharm    as PC  

# =============================================================================
# 1. 
# =============================================================================
#
## location of dimuon candidates in TES:
#
jpsi_name        = 'FullDSTDiMuonJpsi2MuMuDetachedLine'
psi2_name        = 'FullDSTDiMuonPsi2MuMuDetachedLine'
ups_name         = 'FullDSTDiMuonDiMuonHighMassLine'

jpsi_line   = '/Event/Dimuon/Phys/%s/Particles' % jpsi_name 
psi2s_line  = '/Event/Dimuon/Phys/%s/Particles' % psi2_name 
ups_line    = '/Event/Dimuon/Phys/%s/Particles' %  ups_name 

bottom = BOTTOM.UpsilonExoticConf ( 'UpsilonExotica' ,
                                    config = { 'DIMUONLINE'  : ups_line                   } )
psix0  = PSIX0.PsiX0Conf          ( 'PsiX0'          ,
                                    config = { 'DIMUONLINES' : [ jpsi_line , psi2s_line ] } ) 
psix   = PSIX.PsiX_BQ_Conf        ( 'PsiX'           ,
                                    config = { 'DIMUONLINES' : [ jpsi_line , psi2s_line ] } )

# ==============================================================================
## high pt prompt J/psi line 
# ==============================================================================
jpsiPT_location  = 'FullDSTDiMuonJpsi2MuMuTOSLine' ## high pt prompt J/psi 
jpsiPT_line      = '/Event/Dimuon/Phys/%s/Particles' % jpsiPT_location 
from PhysSelPython.Wrappers import AutomaticData 
jpsi_PT_0          = AutomaticData ( jpsiPT_line )

from GaudiConfUtils.ConfigurableGenerators import FilterDesktop 
from PhysSelPython.Wrappers                import SimpleSelection
jpsi_PT = SimpleSelection (
    'promptJpsi'      ,
    FilterDesktop     ,
    [ jpsi_PT_0     ] , 
    Code = """
    in_range ( 2.990 * GeV , M , 3.110 * GeV )
    & ( VFASPF ( VCHI2 ) < 10 ) 
    & ( 3 * GeV          < PT  )
    & ( MAXTREE( 'mu+' == ID , PROBNNmu    ) > 0.25 )
    & ( MAXTREE( 'mu+' == ID , BPVIPCHI2() ) < 16   )  
    & ( BPVVDCHI2 < 50  )
    """
    )

# ==============================================================================
## B+X-selections 
# ==============================================================================
beauty  = psix.beauty    ()
pc      = PC.StrippingPromptCharmConf('PromptCharm', {
    'pT(D0)'           :  0.95 * GeV ,    ## pt-cut for  prompt   D0
    'pT(D+)'           :  0.95 * GeV ,    ## pt-cut for  prompt   D+
    'pT(Ds+)'          :  0.95 * GeV ,    ## pt-cut for  prompt   Ds+
    'pT(Lc+)'          :  0.95 * GeV ,    ## pt-cut for  prompt   Lc+
    } )

prompt  = pc.PromptCharm ()  ## prompt charm 
w       = pc.W           ()  ## W+/- 
dimu_pr = pc.DiMuon      ()  ## prompt dimuons 

# ==============================================================================
## B&W 
# ==============================================================================
from GaudiConfUtils.ConfigurableGenerators import CombineParticles
from PhysSelPython.Wrappers                import SimpleSelection
bw_sel = SimpleSelection (
    'SelB&W'                    ,
    CombineParticles            ,
    [ pc.W()  , psix.beauty() ] ,
    # 
    ## the decays to be reconstructed
    DecayDescriptors = [
    #
    # charm-anti-charm
    #
    " [ chi_b0(2P) -> B0        mu+ ]cc " ,
    " [ chi_b0(2P) -> B~0       mu+ ]cc " ,
    " [ chi_b0(2P) -> B+        mu+ ]cc " ,
    " [ chi_b0(2P) -> B-        mu+ ]cc " ,
    " [ chi_b0(2P) -> B_s0      mu+ ]cc " ,
    " [ chi_b0(2P) -> B_s0      mu- ]cc " ,
    ] ,
    ##
    ## combination cut : accept all
    CombinationCut = " AALL " ,
    ##      mother cut : accept all
    MotherCut      = "  ALL " , 
    #
    ## make the selection faster
    #
    ParticleCombiners = { '' : 'LoKi::VertexFitter:PUBLIC' } 
    #
    )

# ==============================================================================
## B&B
# ==============================================================================
from GaudiConfUtils.ConfigurableGenerators import CombineParticles
from PhysSelPython.Wrappers                import SimpleSelection
bb_sel = SimpleSelection (
    ##
    'SelB&B'          ,
    CombineParticles  , 
    [ psix.beauty() ] ,
    # 
    ## the decays to be reconstructed
    DecayDescriptors = [
    #
    # beauty+beauty
    #
    "   chi_b0(2P) -> B0        B~0       " ,
    "   chi_b0(2P) -> B+        B-        " ,
    "   chi_b0(2P) -> B_s0      B_s0      " ,
    #
    " [ chi_b0(2P) -> B0        B0    ]cc " ,
    " [ chi_b0(2P) -> B0        B+    ]cc " ,
    " [ chi_b0(2P) -> B0        B_s0  ]cc " ,
    # 
    " [ chi_b0(2P) -> B0        B-    ]cc " ,
    " [ chi_b0(2P) -> B0        B_s~0 ]cc " ,
    #
    " [ chi_b0(2P) -> B+        B+    ]cc " ,
    " [ chi_b0(2P) -> B+        B_s0  ]cc " ,
    " [ chi_b0(2P) -> B+        B_s~0 ]cc " ,
    #
    ] ,
    #
    ## combination cut : accept all
    #
    CombinationCut = " AALL " ,
    #
    ##      mother cut : accept all
    #
    MotherCut      = "  ALL " , 
    #
    ## make the selection faster
    #
    ParticleCombiners = { '' : 'LoKi::VertexFitter:PUBLIC' } 
    #
    )

# ==============================================================================
## B&C
# ==============================================================================
from GaudiConfUtils.ConfigurableGenerators import CombineParticles
from PhysSelPython.Wrappers                import SimpleSelection
bc_sel = SimpleSelection (
    'SelB&C'          ,
    CombineParticles  , 
    [ psix . beauty() , pc . PromptCharm() ] , 
    # 
    ## the decays to be reconstructed
    DecayDescriptors = [
    #
    # beauty + charm
    #
    " [ chi_b0(2P) -> B0        D0         ]cc " ,
    " [ chi_b0(2P) -> B0        D+         ]cc " ,
    " [ chi_b0(2P) -> B0        D*(2010)+  ]cc " ,
    " [ chi_b0(2P) -> B0        D_s+       ]cc " ,
    " [ chi_b0(2P) -> B0        Lambda_c+  ]cc " ,
    #
    " [ chi_b0(2P) -> B0        D~0        ]cc " ,
    " [ chi_b0(2P) -> B0        D-         ]cc " ,
    " [ chi_b0(2P) -> B0        D*(2010)-  ]cc " ,
    " [ chi_b0(2P) -> B0        D_s-       ]cc " ,
    " [ chi_b0(2P) -> B0        Lambda_c~- ]cc " ,
    #
    " [ chi_b0(2P) -> B+        D0         ]cc " ,
    " [ chi_b0(2P) -> B+        D+         ]cc " ,
    " [ chi_b0(2P) -> B+        D*(2010)+  ]cc " ,
    " [ chi_b0(2P) -> B+        D_s+       ]cc " ,
    " [ chi_b0(2P) -> B+        Lambda_c+  ]cc " ,
    #
    " [ chi_b0(2P) -> B+        D~0        ]cc " ,
    " [ chi_b0(2P) -> B+        D-         ]cc " ,
    " [ chi_b0(2P) -> B+        D*(2010)-  ]cc " ,
    " [ chi_b0(2P) -> B+        D_s-       ]cc " ,
    " [ chi_b0(2P) -> B+        Lambda_c~- ]cc " ,
    #
    #
    " [ chi_b0(2P) -> B_s0      D0         ]cc " ,
    " [ chi_b0(2P) -> B_s0      D+         ]cc " ,
    " [ chi_b0(2P) -> B_s0      D*(2010)+  ]cc " ,
    " [ chi_b0(2P) -> B_s0      D_s+       ]cc " ,
    " [ chi_b0(2P) -> B_s0      Lambda_c+  ]cc " ,
    #
    " [ chi_b0(2P) -> B_s0      D~0        ]cc " ,
    " [ chi_b0(2P) -> B_s0      D-         ]cc " ,
    " [ chi_b0(2P) -> B_s0      D*(2010)-  ]cc " ,
    " [ chi_b0(2P) -> B_s0      D_s-       ]cc " ,
    " [ chi_b0(2P) -> B_s0      Lambda_c~- ]cc " ,
    #
    ] ,
    ## combination cut : accept all
    CombinationCut = " AALL " ,
    ##      mother cut : accept all
    MotherCut      = "  ALL " , 
    #
    ## make the selection faster
    #
    ParticleCombiners = { '' : 'LoKi::VertexFitter:PUBLIC' } 
    #
    )

# ==============================================================================
## B&2mu
# ==============================================================================
from GaudiConfUtils.ConfigurableGenerators import CombineParticles
from PhysSelPython.Wrappers                import SimpleSelection
bm_sel = SimpleSelection (
    'SelB&2Mu'         ,
    CombineParticles   , 
    [ psix . beauty () , pc . DiMuon () ] ,
    #
    ## the decays to be reconstructed
    DecayDescriptors = [
    #
    # beauty+2mu
    #
    " [ chi_b0(2P) -> B0        J/psi(1S)  ]cc " ,
    " [ chi_b0(2P) -> B+        J/psi(1S)  ]cc " ,
    "   chi_b0(2P) -> B_s0      J/psi(1S)      " ,
    #
    ] ,
    ##
    ## combination cut : accept all
    CombinationCut = " AALL " ,
    ##      mother cut : accept all
    MotherCut      = "  ALL " , 
    #
    ## make the selection faster
    #
    ParticleCombiners = { '' : 'LoKi::VertexFitter:PUBLIC' } 
    #
    )

## rename particle 
from GaudiConfUtils.ConfigurableGenerators import SubstitutePID
from PhysSelPython.Wrappers                import SimpleSelection
sel_ups_Y = SimpleSelection (
    'UpsilonY'    , 
    SubstitutePID ,
    [ bottom.upsilons() ]  , 
    Code          = " DECTREE('J/psi(1S) -> mu+ mu-') & ( M > 6 * GeV ) " ,
    Substitutions = {
    'J/psi(1S) -> mu+ mu-' : "Upsilon(1S)"
    }
    )

# =============================================================================
## Y + prompt charm 
# =============================================================================
from GaudiConfUtils.ConfigurableGenerators import CombineParticles 
from PhysSelPython.Wrappers                import SimpleSelection
sel_Ycharm = SimpleSelection (
    'Y&Charm'        ,
    CombineParticles , 
    [ bottom.upsilons() , pc.PromptCharm() ] , 
    ## algorithm parameters 
    DecayDescriptors    = [
    "[ chi_b1(1P) -> J/psi(1S) D0        ]cc" ,
    "[ chi_b1(1P) -> J/psi(1S) D+        ]cc" ,
    "[ chi_b1(1P) -> J/psi(1S) D*(2010)+ ]cc" ,
    "[ chi_b1(1P) -> J/psi(1S) D_s+      ]cc" ,
    "[ chi_b1(1P) -> J/psi(1S) Lambda_c+ ]cc" ,
    ] , 
    CombinationCut     = " AALL " ,
    MotherCut          = "  ALL " , 
    ParticleCombiners  = { '' : 'LoKi::VertexFitter:PUBLIC' }
    # 
    )


# =============================================================================
## Y + prompt J/psi 
# =============================================================================
from GaudiConfUtils.ConfigurableGenerators import CombineParticles 
from PhysSelPython.Wrappers                import SimpleSelection
sel_YPsi = SimpleSelection (
    'Y&psi'          ,
    CombineParticles , 
    [ sel_ups_Y , pc.DiMuon () ] , 
    ## algorithm parameters 
    DecayDescriptor    = " chi_b1(1P) -> Upsilon(1S) J/psi(1S)" ,
    CombinationCut     = " AALL " ,
    MotherCut          = "  ALL " , 
    ParticleCombiners  = { '' : 'LoKi::VertexFitter:PUBLIC' }
    # 
    )

# =============================================================================
## Y + detached J/psi 
# =============================================================================
from GaudiConfUtils.ConfigurableGenerators import CombineParticles 
from PhysSelPython.Wrappers                import SimpleSelection
sel_YPsiB = SimpleSelection (
    'Y&psiB'         ,
    CombineParticles , 
    [ sel_ups_Y      , psix.psi () ] , 
    ## algorithm parameters 
    DecayDescriptor    = " chi_b2(1P) -> Upsilon(1S) J/psi(1S)" ,
    CombinationCut     = " AALL " ,
    MotherCut          = "  ALL " , 
    ParticleCombiners  = { '' : 'LoKi::VertexFitter:PUBLIC' }
    # 
    )

# =============================================================================
## Y + Y
# =============================================================================
from GaudiConfUtils.ConfigurableGenerators import CombineParticles 
from PhysSelPython.Wrappers                import SimpleSelection
sel_2xY = SimpleSelection (
    '2xY'            ,
    CombineParticles , 
    [ sel_ups_Y      , ] , 
    ## algorithm parameters 
    DecayDescriptor    = " chi_b0(1P) -> Upsilon(1S) Upsilon(1S)" ,
    CombinationCut     = " AALL " ,
    MotherCut          = "  ALL " , 
    ParticleCombiners  = { '' : 'LoKi::VertexFitter:PUBLIC' }
    # 
    )

# =============================================================================
## pair of detached J/psi 
# =============================================================================
from GaudiConfUtils.ConfigurableGenerators import CombineParticles 
from PhysSelPython.Wrappers                import SimpleSelection
sel_2xPsiB = SimpleSelection (
    '2xB'             ,   
    CombineParticles  ,
    [ psix.psi ()  ]  ,
    DecayDescriptor   = "chi_b0(1P) -> J/psi(1S) J/psi(1S) " ,
    CombinationCut    = "AALL" ,
    MotherCut         = " ALL" ,
    ReFitPVs          = True    
    )

# =============================================================================
## Y -> J/psi p+ p~-
# =============================================================================
from GaudiConfUtils.ConfigurableGenerators import FilterDesktop 
from PhysSelPython.Wrappers                import SimpleSelection
from StandardParticles                     import StdAllLooseANNProtons 
protons = SimpleSelection (
    'GoodProtons' ,
    FilterDesktop ,
    [ StdAllLooseANNProtons ] ,
    Code = """
    ( PT           > 250 * MeV ) & 
    ( CLONEDIST    > 5000      ) & 
    ( TRCHI2DOF    < 4         ) & 
    ( TRGHOSTPROB  < 0.5       ) & 
    in_range ( 2         , ETA , 5         ) &
    in_range ( 10 * GeV  , P   , 120 * GeV )
    &   HASRICH
    & ( PROBNNp     > 0.20 )
    & ( PROBNNpi    < 0.80 ) 
    & ( PROBNNK     < 0.80 )
    """ 
    )

from GaudiConfUtils.ConfigurableGenerators import DaVinci__N3BodyDecays
from PhysSelPython.Wrappers                import SimpleSelection
sel_psi_PP = SimpleSelection (
    'Psi&PP'   ,
    DaVinci__N3BodyDecays  ,
    [ jpsi_PT, protons ]    , 
    ## algorithm properties 
    DecayDescriptor  = "Upsilon(1S) -> J/psi(1S) p+ p~-" ,
    DaughtersCuts    = {
    'p+' : "PT>1*GeV"
    },
    Combination12Cut = """
    ( AM < 12 * GeV ) & ( ACHI2DOCA(1,2)  < 16  ) 
    """,    
    CombinationCut = """
    in_range ( 8.4 * GeV , AM , 11.6 * GeV ) &
    ( ACHI2DOCA(1,3)  < 16  ) &
    ( ACHI2DOCA(2,3)  < 16  ) 
    """,
    MotherCut  = """
    VFASPF(VCHI2PDOF) < 8    
    """
    )

from GaudiConfUtils.ConfigurableGenerators import CombineParticles 
from PhysSelPython.Wrappers                import SimpleSelection
sel_psi_P = SimpleSelection (
    'Psi&P'                ,
    CombineParticles       ,
    [ jpsi_PT , protons ]   , 
    ## algorithm properties 
    DecayDescriptor  = "[chi_b1(1P) -> J/psi(1S) p+]cc" ,
    DaughtersCuts    = {
    'p+'        : """
    ( PT>500*MeV        ) &
    ( PROBNNp     > 0.5 ) &
    ( PROBNNpi    < 0.8 ) &
    ( PROBNNK     < 0.8 ) &
    ( BPVIPCHI2() < 16  ) 
    """
    },
    CombinationCut   = """
    ( AM  - AM1 < ( 5.15 - 3.1 ) * GeV ) & 
    ( APT > 3   * GeV ) 
    """,
    MotherCut        = """
    ( PT > 3 *  GeV         ) & 
    ( M  < 5.050 * GeV      ) &
    ( VFASPF(VCHI2PDOF) < 6 )
    """    
    )

from GaudiConfUtils.ConfigurableGenerators import DaVinci__N3BodyDecays
from PhysSelPython.Wrappers                import SimpleSelection
sel_ups_PP = SimpleSelection (
    'Ups&PP'                   ,
    DaVinci__N3BodyDecays  ,
    [ bottom.upsilons() , protons ]  , 
    ## algorithm properties 
    DecayDescriptor  = "chi_b1(1P) -> J/psi(1S) p+ p~-" ,
    Combination12Cut = """
    ( AM < 15 * GeV        ) &
    ( ACHI2DOCA(1,2) < 16  ) 
    """,    
    CombinationCut = """
    ( AM - AM1  < 5 * GeV  ) &
    ( ACHI2DOCA(1,3) < 16  ) &
    ( ACHI2DOCA(2,3) < 16  ) 
    """,
    MotherCut  = """
    VFASPF(VCHI2PDOF) < 8 
    """
    )

from GaudiConfUtils.ConfigurableGenerators import DaVinci__N3BodyDecays
from PhysSelPython.Wrappers                import SimpleSelection
sel_ups_P = SimpleSelection (
    'Ups&P'             ,
    CombineParticles    ,
    [ bottom.upsilons() , protons ]  , 
    ## algorithm properties 
    DecayDescriptor  = "[chi_b1(1P) -> J/psi(1S) p+]cc" ,
    CombinationCut   = """
    ( AM        < 13 * GeV ) & 
    ( AM - AM1  < 3  * GeV )
    """,
    MotherCut        = "VFASPF(VCHI2PDOF) < 8  " 
    )


from PhysSelPython.Wrappers import MultiSelectionSequence
from PhysSelPython.Wrappers import      SelectionSequence

# =============================================================================
## PSIX0 stream 
# =============================================================================
psi_x0 = MultiSelectionSequence (
    "PSIX0",
    Sequences = [
    #
    SelectionSequence ( 'ETA'           , psix0 . b2eta       () ) ,
    SelectionSequence ( 'ETAPRIME'      , psix0 . b2etap      () ) ,
    SelectionSequence ( 'OMEGA'         , psix0 . b2omega     () ) ,
    #
    SelectionSequence ( 'KETA'          , psix0 . b2Keta      () ) ,
    SelectionSequence ( 'KETAPRIME'     , psix0 . b2Ketap     () ) ,
    SelectionSequence ( 'KOMEGA'        , psix0 . b2Komega    () ) ,
    #
    SelectionSequence ( 'KKETA'         , psix0 . b2KKeta     () ) ,
    SelectionSequence ( 'KKETAPRIME'    , psix0 . b2KKetap    () ) ,
    SelectionSequence ( 'KKOMEGA'       , psix0 . b2KKomega   () ) ,
    #
    SelectionSequence ( 'PIETA'         , psix0 . b2pieta     () ) ,
    SelectionSequence ( 'PIETAPRIME'    , psix0 . b2pietap    () ) ,
    SelectionSequence ( 'PIOMEGA'       , psix0 . b2piomega   () ) ,
    #
    SelectionSequence ( 'PIPIETA'       , psix0 . b2pipieta   () ) ,
    SelectionSequence ( 'PIPIETAPRIME'  , psix0 . b2pipietap  () ) ,
    SelectionSequence ( 'PIPIOMEGA'     , psix0 . b2pipiomega () ) ,
    #
    SelectionSequence ( 'KPIETA'        , psix0 . b2Kpieta    () ) ,
    SelectionSequence ( 'KPIETAPRIME'   , psix0 . b2Kpietap   () ) ,
    SelectionSequence ( 'KPIOMEGA'      , psix0 . b2Kpiomega  () ) ,
    #
    ] 
    )

#  -------------------------------------------------------------+------------------------------
# 
# =============================================================================
## PSIX stream 
# =============================================================================
psi_x = MultiSelectionSequence (
    "PSIX"      ,
    Sequences = [
    #
    SelectionSequence ( 'B2PsiK'    , psix . psi_K    () ) ,
    SelectionSequence ( 'B2PsiPi'   , psix . psi_pi   () ) ,
    #
    SelectionSequence ( 'B2Psi2K'   , psix . psi_2K   () ) ,
    SelectionSequence ( 'B2Psi2KPi' , psix . psi_2Kpi () ) ,
    SelectionSequence ( 'B2Psi2Pi'  , psix . psi_2pi  () ) ,
    #
    SelectionSequence ( 'B2Psi3K'   , psix . psi_3K   () ) ,
    SelectionSequence ( 'B2Psi3KPi' , psix . psi_3Kpi () ) ,
    SelectionSequence ( 'B2Psi3Pi'  , psix . psi_3pi  () ) ,
    #
    SelectionSequence ( 'B2Psi4K'   , psix . psi_4K   () ) ,
    SelectionSequence ( 'B2Psi4KPi' , psix . psi_4Kpi () ) ,
    SelectionSequence ( 'B2Psi4Pi'  , psix . psi_4pi  () ) ,
    #
    SelectionSequence ( 'B2Psi5K'   , psix . psi_5K   () ) ,
    SelectionSequence ( 'B2Psi5KPi' , psix . psi_5Kpi () ) ,
    SelectionSequence ( 'B2Psi5Pi'  , psix . psi_5pi  () ) ,
    #
    SelectionSequence ( 'B2Psi6KPi' , psix . psi_6Kpi () ) ,
    SelectionSequence ( 'B2Psi6Pi'  , psix . psi_6pi  () ) ,
    #
    SelectionSequence ( 'B2Psi7KPi' , psix . psi_7Kpi () ) ,
    SelectionSequence ( 'B2Psi7Pi'  , psix . psi_7pi  () ) ,
    #
    ## Lb
    #
    SelectionSequence ( 'Lb2PSIPK'      , psix . psi_pK      () ) ,
    SelectionSequence ( 'Lb2PSIPPi'     , psix . psi_ppi     () ) ,
    SelectionSequence ( 'Lb2PSIPKPiPi'  , psix . psi_pKpipi  () ) ,
    SelectionSequence ( 'Lb2PSIPPiPiPi' , psix . psi_ppipipi () ) ,
    SelectionSequence ( 'Xb2PSIPKK'     , psix . psi_pKK     () ) ,
    SelectionSequence ( 'Xb2PSIPKKPi'   , psix . psi_pKKpi   () ) ,
    SelectionSequence ( 'Ob2PSIPKKKPi'  , psix . psi_pKKKpi  () ) ,
    #
    # 2 protons
    #
    SelectionSequence ( 'B2PSIPP'       , psix . psi_pp       () ) ,
    SelectionSequence ( 'B2PSIPPPi'     , psix . psi_pppi     () ) ,
    SelectionSequence ( 'B2PSIPPK'      , psix . psi_ppK      () ) ,
    SelectionSequence ( 'B2PSIPPPiPi'   , psix . psi_pppipi   () ) ,
    SelectionSequence ( 'B2PSIPPKPiPi'  , psix . psi_ppKpipi  () ) ,
    SelectionSequence ( 'B2PSIPPPiPiPi' , psix . psi_pppipipi () ) ,
    #
    ## B + X
    #
    SelectionSequence ( 'B&B'           , bb_sel  )  ,    
    SelectionSequence ( 'B&C'           , bc_sel  )  ,    
    SelectionSequence ( 'B&2Mu'         , bm_sel  )  ,    
    SelectionSequence ( 'B&W'           , bw_sel  )  ,
    #
    ##  Bc -> J/psi rho+          ## new 
    # 
    SelectionSequence ( 'BC2RHO'          , psix0 . bc2rho     () ) ,
    # 
    ## for the photon efficiency: ## new 
    #
    SelectionSequence ( 'KSTARPLUS'       , psix0 . bu2Kstar   () ) ,
    ## SelectionSequence ( 'KSTARPLUSMERGED' , psix0 . bu2KstarM  () ) , 
    #
    ## channels with chic
    # 
    SelectionSequence ( 'B2CHICK'     , psix0 . b2chicK     () ) ,
    SelectionSequence ( 'B2CHICKK'    , psix0 . b2chicKK    () ) ,
    SelectionSequence ( 'B2CHICKPi'   , psix0 . b2chicKpi   () ) ,
    SelectionSequence ( 'B2CHICKPiPi' , psix0 . b2chicKpipi () ) ,
    SelectionSequence ( 'B2CHICPiPi'  , psix0 . b2chicpipi  () ) ,
    #
    SelectionSequence ( 'BC2CHICPi'   , psix0 . bc2chicpi   () ) ,
    SelectionSequence ( 'Lb2CHICPi'   , psix0 . lb2chicpK   () ) ,
    ]
    )

# =============================================================================
## UPSILON stream 
# =============================================================================
bottom = MultiSelectionSequence (
    'BOTTOM' ,
    Sequences = [
    SelectionSequence ( 'Ups'     , sel_ups_Y  ) ,
    SelectionSequence ( 'Y&C'     , sel_Ycharm ) ,
    SelectionSequence ( 'Y&Psi'   , sel_YPsi   ) ,
    SelectionSequence ( 'Y&PsiB'  , sel_YPsiB  ) ,
    SelectionSequence ( 'Y&Y'     , sel_2xY    ) ,
    SelectionSequence ( '2xPsiB'  , sel_2xPsiB ) ,
    SelectionSequence ( 'Psi&p'   , sel_psi_P  ) , 
    SelectionSequence ( 'Psi&pp'  , sel_psi_PP ) , 
    SelectionSequence ( 'Y&p'     , sel_ups_P  ) , 
    SelectionSequence ( 'Y&pp'    , sel_ups_PP ) , 
    SelectionSequence ( 'Y&KK'    , bottom.upsilon_phi       () ) ,
    SelectionSequence ( 'Y&PiPi'  , bottom.upsilon_rho       () ) ,
    SelectionSequence ( 'Y&eta'   , bottom.upsilon_eta       () ) ,
    SelectionSequence ( 'Y&etapr' , bottom.upsilon_eta_prime () ) ,
    SelectionSequence ( 'Y&omega' , bottom.upsilon_omega     () ) 
    ]
    )

# =============================================================================
## micro-DST writer
# =============================================================================
from DSTWriters.Configuration import ( SelDSTWriter            ,
                                       stripMicroDSTStreamConf ,
                                       stripMicroDSTElements   )

# Configuration of SelDSTWriter
SelDSTWriterConf     = { 'default' : stripMicroDSTStreamConf ( pack = False ) }
SelDSTWriterElements = { 'default' : stripMicroDSTElements   ( pack = False , refit = True ) }

uDstWriter = SelDSTWriter(
    "MyDSTWriter"                          ,
    StreamConf         =  SelDSTWriterConf      ,
    MicroDSTElements   =  SelDSTWriterElements  ,
    OutputFileSuffix   = 'BandQ'                ,  ## output PRE-fix! 
    SelectionSequences = [ bottom ,
                           psi_x  ,
                           psi_x0 ,
                           ]
    )

#
## Read only fired events to speed up
#
from PhysConf.Filters import LoKi_Filters
fltrs = LoKi_Filters (
    STRIP_Code = """
    HLT_PASS_RE ( 'Stripping.*DiMuonJpsi2MuMuTOS.*'      ) |
    HLT_PASS_RE ( 'Stripping.*DiMuonJpsi2MuMuDetached.*' ) |
    HLT_PASS_RE ( 'Stripping.*DiMuonPsi2MuMuDetached.*'  ) |
    HLT_PASS_RE ( 'Stripping.*DiMuonDiMuonHighMass.*'    )     
    """ 
    )

## # 
## ## protection against ``corrupted'' Stripping 17b DIMUON.DST
## #  obsolete? 
## #  also add protection against very busy events
## fltrs_0 = LoKi_Filters (
##     VOID_Code  = """
##     ( EXISTS     ( '/Event/DAQ/RawEvent' ) | EXISTS ( '/Event/Trigger/RawEvent' ) ) 
##     & EXISTS     ( '/Event/Strip/Phys/DecReports') &
##     ( RECSUMMARY (  0 , -1 )                                > 0.5 ) & 
##     ( RECSUMMARY ( 10 , -1 )                                < 500 ) & 
##     ( RECSUMMARY ( 13 , -1 )                                < 500 ) & 
##     ( CONTAINS   ( '/Event/Phys/StdLooseKaons/Particles' )  < 250 ) & 
##     ( CONTAINS   ( '/Event/Phys/StdLoosePions/Particles' )  < 250 ) 
##     """,
##     VOID_Preambulo = ["from LoKiCore.functions import * "]
##     )

# ==============================================================================
# The last step: DaVinci & DB 
# ==============================================================================

from Configurables import DaVinci 
davinci = DaVinci ( 
    #
    ## DataType        = the_year ,                ## ATTENTION !!
    #
    EventPreFilters = fltrs.filters ('Filters') , 
    InputType       = "DST"    , 
    EvtMax          =    -1    ,  
    PrintFreq       =  1000    ,
    Lumi            =  True    ,  
    )

davinci.appendToMainSequence( [ uDstWriter.sequence() ] )

## from Configurables import CondDB
## CondDB ( LatestGlobalTagByDataType = the_year )  ## ATTENTION !!
    
# =============================================================================
if '__main__' == __name__ :
    
    print 100*'*'
    print __doc__
    print 100*'*'
    print ' Author  : %s ' % __author__
    print ' Version : %s ' % __version__ 
    print ' Date    : %s ' % __date__
    print 100*'*'


# =============================================================================
# The END 
# =============================================================================

