def main(args):
    # isdata = False
    # isfastsim = False
    if "False" in args.isData:
        isdata = False
    else:
        isdata = True
    if "False" in args.isFastSim:
        isfastsim = False
    else:
        isfastsim = True

    mods = [
        eleMiniCutID(),
        Stop0lObjectsProducer(args.era),
        DeepTopProducer(args.era),
        Stop0lBaselineProducer(args.era, isData=isdata, isFastSim=isfastsim),
        UpdateGenWeight(isdata, args.crossSection, args.nEvents)
    ]
    if args.era == "2018":
        mods.append(UpdateJetID(args.era))


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ For MC ~~~~~
    if not isdata:
        pufile = "%s/src/PhysicsTools/NanoSUSYTools/data/pileup/%s" % (
            os.environ['CMSSW_BASE'], DataDepInputs[args.era]["pileup"])
        mods += [
            lepSFProducer(args.era),
            puWeightProducer("auto", pufile, "pu_mc", "pileup", verbose=False)
        ]

    files = []
    lines = open(args.inputfile).readlines()
    for line in lines:
        files.append(line.strip())

    p = PostProcessor(args.outputfile,
                      files,
                      cut=None,
                      branchsel=None,
                      outputbranchsel="keep_and_drop.txt",
                      modules=mods,
                      provenance=False)
    p.run()
def main(args):
    isdata = len(args.dataEra) > 0
    isfastsim = args.isFastSim
    isSUSY = args.sampleName.startswith("SMS_")

    if isdata and isfastsim:
        print "ERROR: It is impossible to have a dataset that is both data and fastsim"
        exit(0)

    if isdata:
        dataType = "Data"
        if not args.era + args.dataEra in DataDepInputs[dataType].keys():
            print "ERROR: Era \"" + args.era + "\" not recognized"
            exit(0)
    elif isfastsim:
        dataType = "FASTSIM"
        if not args.era + args.dataEra in DataDepInputs[dataType].keys():
            print "ERROR: Era \"" + args.era + "\" not recognized"
            exit(0)
    else:
        dataType = "MC"
        if not args.era in DataDepInputs[dataType].keys():
            print "ERROR: Era \"" + args.era + "\" not recognized"
            exit(0)

    mods = []

    #~~~~~ Different modules for Data and MC ~~~~~
    # These modules must be run first in order to update JEC and MET approperiately for future modules
    # The MET update module must also be run before the JEC update modules
    if args.era == "2017":
        # EE noise mitigation in PF MET
        # https://hypernews.cern.ch/HyperNews/CMS/get/JetMET/1865.html
        mods.append(UpdateMETProducer("METFixEE2017"))
    if args.era == "2018":
        # The 2018 JetID came after our production
        mods.append(UpdateJetID(args.era))

    if isdata:
        # Apply resediual JEC on Data
        if DataDepInputs[dataType][args.era + args.dataEra]["redoJEC"]:
            mods.append(
                jetRecalib(DataDepInputs[dataType][args.era +
                                                   args.dataEra]["JEC"]))
    else:
        # JetMET uncertainty ?
        mods += [
            jetmetUncertaintiesProducer(
                args.era,
                DataDepInputs[dataType][args.era]["JECMC"],
                jerTag=DataDepInputs[dataType][args.era]["JERMC"],
                redoJEC=DataDepInputs[dataType][args.era]["redoJEC"],
                doSmearing=False,
                doL2L3=not isfastsim)
        ]

    #~~~~~ Common modules for Data and MC ~~~~~
    mods += [
        eleMiniCutID(),
        Stop0lObjectsProducer(args.era),
        TopTaggerProducer(recalculateFromRawInputs=True,
                          topDiscCut=DeepResovledDiscCut,
                          cfgWD=os.environ["CMSSW_BASE"] +
                          "/src/PhysicsTools/NanoSUSYTools/python/processors"),
        DeepTopProducer(args.era),
        Stop0lBaselineProducer(args.era, isData=isdata, isFastSim=isfastsim),
        Stop0l_trigger(args.era),
        UpdateEvtWeight(isdata, args.crossSection, args.nEvents,
                        args.sampleName)
    ]

    #~~~~~ Modules for MC Only ~~~~~
    if not isdata:
        pufile_data = "%s/src/PhysicsTools/NanoSUSYTools/data/pileup/%s" % (
            os.environ['CMSSW_BASE'],
            DataDepInputs[dataType][args.era]["pileup_Data"])
        pufile_mc = "%s/src/PhysicsTools/NanoSUSYTools/data/pileup/%s" % (
            os.environ['CMSSW_BASE'],
            DataDepInputs[dataType][args.era]["pileup_MC"])
        ## TODO: ZW don't understand this part, So this is for fullsim?
        ## Isn't jetmetUncertaintiesProducer included jecUncertProducer
        if not isfastsim:
            mods += [
                jecUncertProducer(DataDepInputs[dataType][args.era]["JECMC"]),
            ]
        ## Major modules for MC
        mods += [
            TopTaggerProducer(
                recalculateFromRawInputs=True,
                suffix="JESUp",
                AK4JetInputs=("Jet_pt_jesTotalUp", "Jet_eta", "Jet_phi",
                              "Jet_mass_jesTotalUp"),
                topDiscCut=DeepResovledDiscCut,
                cfgWD=os.environ["CMSSW_BASE"] +
                "/src/PhysicsTools/NanoSUSYTools/python/processors"),
            TopTaggerProducer(
                recalculateFromRawInputs=True,
                suffix="JESDown",
                AK4JetInputs=("Jet_pt_jesTotalDown", "Jet_eta", "Jet_phi",
                              "Jet_mass_jesTotalDown"),
                topDiscCut=DeepResovledDiscCut,
                cfgWD=os.environ["CMSSW_BASE"] +
                "/src/PhysicsTools/NanoSUSYTools/python/processors"),
            DeepTopProducer(args.era, "JESUp"),
            DeepTopProducer(args.era, "JESDown"),
            Stop0lObjectsProducer(args.era, "JESUp"),
            Stop0lObjectsProducer(args.era, "JESDown"),
            Stop0lObjectsProducer(args.era, "METUnClustUp"),
            Stop0lObjectsProducer(args.era, "METUnClustDown"),
            Stop0lBaselineProducer(args.era,
                                   isData=isdata,
                                   isFastSim=isfastsim,
                                   applyUncert="JESUp"),
            Stop0lBaselineProducer(args.era,
                                   isData=isdata,
                                   isFastSim=isfastsim,
                                   applyUncert="JESDown"),
            Stop0lBaselineProducer(args.era,
                                   isData=isdata,
                                   isFastSim=isfastsim,
                                   applyUncert="METUnClustUp"),
            Stop0lBaselineProducer(args.era,
                                   isData=isdata,
                                   isFastSim=isfastsim,
                                   applyUncert="METUnClustDown"),
            PDFUncertiantyProducer(isdata, isSUSY),
            lepSFProducer(args.era),
            lepSFProducer(args.era,
                          muonSelectionTag="Medium",
                          electronSelectionTag="Medium",
                          photonSelectionTag="Medium"),
            puWeightProducer(pufile_mc, pufile_data, args.sampleName,
                             "pileup"),
            btagSFProducer(era=args.era, algo="deepcsv"),
            BtagSFWeightProducer("allInOne_bTagEff_deepCSVb_med.root",
                                 args.sampleName, DeepCSVMediumWP[args.era]),
            # statusFlag 0x2100 corresponds to "isLastCopy and fromHardProcess"
            # statusFlag 0x2080 corresponds to "IsLastCopy and isHardProcess"
            GenPartFilter(statusFlags=[0x2100, 0x2080, 0x2000],
                          pdgIds=[0, 0, 22],
                          statuses=[0, 0, 1]),
            # TODO: first implemtation, need double check
            ISRSFWeightProducer(args.era, isSUSY, "allInOne_ISRWeight.root",
                                args.sampleName),
        ]
        # Special PU reweighting for 2017 separately
        if args.era == "2017":
            pufile_dataBtoE = "%s/src/PhysicsTools/NanoSUSYTools/data/pileup/Collisions17_BtoE.root" % os.environ[
                'CMSSW_BASE']
            pufile_dataF = "%s/src/PhysicsTools/NanoSUSYTools/data/pileup/Collisions17_F.root" % os.environ[
                'CMSSW_BASE']
            mods += [
                puWeightProducer(pufile_mc,
                                 pufile_dataBtoE,
                                 args.sampleName,
                                 "pileup",
                                 name="17BtoEpuWeight"),
                puWeightProducer(pufile_mc,
                                 pufile_dataF,
                                 args.sampleName,
                                 "pileup",
                                 name="17FpuWeight")
            ]
        # 2016 and 2017 L1 ECal prefiring reweighting
        if args.era == "2016" or args.era == "2017":
            mods.append(PrefCorr(args.era))

    #============================================================================#
    #-------------------------     Run PostProcessor     ------------------------#
    #============================================================================#
    files = []
    if len(args.inputfile) > 5 and args.inputfile[0:5] == "file:":
        #This is just a single test input file
        files.append(args.inputfile[5:])
    else:
        #this is a file list
        with open(args.inputfile) as f:
            files = [line.strip() for line in f]

    p = PostProcessor(args.outputfile,
                      files,
                      cut=None,
                      branchsel=None,
                      outputbranchsel="keep_and_drop.txt",
                      modules=mods,
                      provenance=False,
                      maxEvents=args.maxEvents)
    p.run()
     DeepTopProducer(args.era, "JESUp"),
     DeepTopProducer(args.era, "JESDown"),
     FastsimVarProducer(isfastsim, "JESUp"),
     FastsimVarProducer(isfastsim, "JESDown"),
     FastsimVarProducer(isfastsim, "METUnClustUp"),
     FastsimVarProducer(isfastsim, "METUnClustDown"),
     Stop0lObjectsProducer(args.era, "JESUp"),
     Stop0lObjectsProducer(args.era, "JESDown"),
     Stop0lObjectsProducer(args.era, "METUnClustUp"),
     Stop0lObjectsProducer(args.era, "METUnClustDown"),
     Stop0lBaselineProducer(args.era, isData=isdata, isFastSim=isfastsim, applyUncert="JESUp"),
     Stop0lBaselineProducer(args.era, isData=isdata, isFastSim=isfastsim, applyUncert="JESDown"),
     Stop0lBaselineProducer(args.era, isData=isdata, isFastSim=isfastsim, applyUncert="METUnClustUp"),
     Stop0lBaselineProducer(args.era, isData=isdata, isFastSim=isfastsim, applyUncert="METUnClustDown"),
     PDFUncertiantyProducer(isdata, isSUSY),
     lepSFProducer(args.era),
     lepSFProducer(args.era, muonSelectionTag="Medium",
                   electronSelectionTag="Medium",
                   photonSelectionTag="Medium", 
                   tauSelectionTag="Tight"),
     puWeightProducer(pufile_mc, pufile_data, args.sampleName,"pileup"),
     btagSFProducer(era=args.era, algo="deepcsv"),
     BtagSFWeightProducer("allInOne_bTagEff_deepCSVb_med.root", args.sampleName, DeepCSVMediumWP[args.era]),
     # statusFlag 0x2100 corresponds to "isLastCopy and fromHardProcess"
     # statusFlag 0x2080 corresponds to "IsLastCopy and isHardProcess"
     GenPartFilter(statusFlags = [0x2100, 0x2080, 0x2000], pdgIds = [0, 0, 22], statuses = [0, 0, 1]),
     # TODO: first implemtation, need double check
     ISRSFWeightProducer(args.era, isSUSY, "allInOne_ISRWeight.root", args.sampleName), 
     ]
 # Special PU reweighting for 2017 separately
 if args.era == "2017":