#####################################################################
##                                                                 ##
##                  Here starts the USER's block                   ##
##                                                                 ##
##    USER has to go through the lines bellow and include the      ##
##    input root files and variables to be plotted, as well as     ##
##    their X and Y axis ranges, labels, legends and colors.       ##
##                                                                 ##
##    USERS can also define the bin edges to compute the number    ##
##    of entries per bin per input file per variable.              ##
##                                                                 ##
#####################################################################

import os
import subprocess

# Set width and height of canvas.
# NOTE: It is safer to not touch in the canvas settup, unless you
#       know what you are doing.
canvas_ratio = 0.29 # right side percent of the pad not covered
wCanvas = 750  # width
hCanvas = 600  # height

# Would you like to apply a linear (0) or a log scale (1) to Y axis?
linear_log_scale = 1

# Would you like to only pop up the plots, or to only save them, or to do both?
# In case of USER running in batch mode ('root -b' option), this code
# will automatically save plots in ".png" format.
# What do you like to do?
#   - Pop up only -> 0
#   - Save only -> 1
#   - Both (pop up and save) -> 2
pop_save = 1

# If USER wants to save plots, tell what format:
# pdf? png? eps? root?
output_file_format = ["png", "pdf", "root"]

# If USER wants to save plots, provide a commom name.
output_file_name = "distribution_TP_ID_v5"

# Would you like to get the entries per bin per input file per variable?
# If "NO"  -> output_entries_per_bin = 0  || (macro will create plots only)
# If "YES" -> output_entries_per_bin = 1  || (macro will get entries only)
# If "YES" -> output_entries_per_bin > 1  || (macro will do both things: create plots and get entries)
output_entries_per_bin = 0

# Would you like to scale MC samples from normalization in Z peak based on data / MC ration?
# If "NO"  -> 0
# If "YES" -> 1
normalize = 0

# Distance between label and Y axis.
# NOTE: It is safer to not touch in the canvas settup, unless you
#       know what you are doing.
y_title_offset = 1.40

# Set legend position
xMinLegend = 0.72 ## minimum x position of the legend
yMinLegend = 0.35 ## minimum y position of the legend
xMaxLegend = 0.99 ## maximum x position of the legend
yMaxLegend = 0.9  ## maximum y position of the legend


# Write the binning for each variable:
pt_bins = [45., 50., 55., 60., 65., 70., 75., 80., 85., 90., 140., 300., 500.]
eta_bins = [-2.4, -2.1, -1.6, -1.2, -0.9, -0.6, -0.3, -0.2, 0.2, 0.3, 0.6, 0.9, 1.2, 1.6, 2.1, 2.4]
phi_bins = [-3.0, -2.5, -2.0, -1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]
mass_bins = [60, 120, 200, 500, 800, 1000, 1500, 2000, 3000]
vertex_bins = [0.5, 2.5, 4.5, 6.5, 8.5, 10.5, 12.5, 14.5, 16.5, 18.5, 20.5, 22.5, 24.5, 26.5, 28.5, 30.5]
deltaR_bins = [0.0, 0.5, 0.75, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0]
probeIso_bins = [0.0, 0.005, 0.01, 0.015, 0.02, 0.025, 0.03, 0.035, 0.04, 0.045, 0.05, 0.055, 0.06, 0.065, 0.07, 0.075, 0.08, 0.085, 0.09, 0.095, 0.1, 0.105, 0.11]
combRelIsoPF04dBeta_bins = [0.0, 0.005, 0.01]
tag_combRelIsoPF04dBeta_bins = [0.0, 0.005, 0.01]
innertkSigmaPtOverPt_bins = [0.0, 0.005, 0.0]
tag_innertrackPtRelError_bins = [0.0, 0.005, 0.01]
NewTuneP_eta_bins = [0.0, 0.005, 0.01]
tag_NewTuneP_eta_bins = [0.0, 0.005, 0.01]
NewTuneP_phi_bins = [0.0, 0.005, 0.01]
tag_NewTuneP_phi_bins = [0.0, 0.005, 0.01]
NewTuneP_pt_bins = [0.0, 0.005, 0.01]
tag_NewTuneP_pt_bins = [0.0, 0.005, 0.01]
tag_MET_bins = [0.0, 0.005, 0.01]
pair_collinearity1_bins = [0.0, 0.005, 0.01]
pair_DimuonVtxProbePtAtTheVtx_bins = [0.0, 0.005, 0.01]
pair_DimuonVtxTagPtAtTheVtx_bins = [0.0, 0.005, 0.01]
pair_DimuonVtxProbePtBefore_bins = [0.0, 0.005, 0.01]
pair_DimuonVtxTagPtBefore_bins = [0.0, 0.005, 0.01]
pair_DimuonVtxZcoordinate_bins = [0.0, 0.005, 0.01]
pair_DimuonVtxRdistance_bins = [0.0, 0.005, 0.01]
pair_DimuonVtxRdistanceFromBS_bins = [0.0, 0.005, 0.01]
pair_DimuonVtxFitNormQui2_bins = [0.0, 0.005, 0.01]
pair_dz_bins = [0.0, 0.005, 0.01]

# Write the list of variables inside an array.
variables_settings = [
    ("pair_newTuneP_probe_pt",        100,   0., 1000.,    50.,  10000000., "p_{T} #left[GeV/c#right]",          "Events", "", pt_bins),
    ("eta",                            50, -2.5,   2.5,  1000.,    500000., "#eta",                              "Events", "", eta_bins),
    ("phi",                            34, -3.4,   3.4, 10000.,    500000., "#phi [rad]",                        "Events", "", phi_bins),
    ("pair_newTuneP_mass",            100,   0., 3000.,    50.,    100000., "m_{#mu#mu} #left[GeV/c^{2}#right]", "Events", "", mass_bins),
    ("tag_nVertices",                  60,   0.,   60.,  0.005,     20000., "Number of Vertices",                "Events", "", vertex_bins),
    ("pair_deltaR",                   100,   0.,    6.,    0.5, 500000000., "#Delta R (#mu,#mu)",                "Events", "", deltaR_bins),
    ("tkIso/pair_newTuneP_probe_pt",  100,   0.,    1.,   500., 200000000., "IsolationR03 SumPt/pt",             "Events", "", probeIso_bins),
    ("combRelIsoPF04dBeta",           100,   0.,   0.5,  1000.,  10000000., "combRelIsoPF04dBeta",               "Events", "", combRelIsoPF04dBeta_bins),
    ("tag_combRelIsoPF04dBeta",       100,   0.,  0.15,  1000., 100000000., "tag_combRelIsoPF04dBeta",           "Events", "", tag_combRelIsoPF04dBeta_bins),
    ("innertkSigmaPtOverPt",          100,   0.,    1.,   100.,  10000000., "innertkSigmaPtOverPt",              "Events", "", innertkSigmaPtOverPt_bins),
    ("tag_innertrackPtRelError",      100,   0.,  0.12,   0.05, 200000000., "tag_innertrackPtRelError",          "Events", "", tag_innertrackPtRelError_bins),
    ("NewTuneP_eta",                   50, -2.5,   2.5,  1000.,    500000., "NewTuneP_eta",                      "Events", "", NewTuneP_eta_bins),
    ("tag_NewTuneP_eta",               50, -2.5,   2.5,  1000.,    500000., "tag_NewTuneP_eta",                  "Events", "", tag_NewTuneP_eta_bins),
    ("NewTuneP_phi",                   34, -3.4,   3.4, 10000.,    500000., "NewTuneP_phi",                      "Events", "", NewTuneP_phi_bins),
    ("tag_NewTuneP_phi",               34, -3.4,   3.4, 10000.,    500000., "tag_NewTuneP_phi",                  "Events", "", tag_NewTuneP_phi_bins),
    ("NewTuneP_pt",                   100,   0., 1000.,   100., 200000000., "NewTuneP_pt",                       "Events", "", NewTuneP_pt_bins),
    ("tag_NewTuneP_pt",               100,   0., 1000.,    0.5,    500000., "tag_NewTuneP_pt",                   "Events", "", tag_NewTuneP_pt_bins),
    ("tag_MET",                       100,   0.,  500.,    0.5,    500000., "tag_MET",                           "Events", "", tag_MET_bins),
    ("pair_collinearity1",            350,   0.,   3.5, 10000., 500000000., "pair_collinearity1",                "Events", "", pair_collinearity1_bins),
    ("pair_DimuonVtxProbePtAtTheVtx", 100,   0.,  500.,    0.5,    500000., "pair_DimuonVtxProbePtAtTheVtx",     "Events", "", pair_DimuonVtxProbePtAtTheVtx_bins),
    ("pair_DimuonVtxTagPtAtTheVtx",   100,   0.,  500.,    0.5,    500000., "pair_DimuonVtxTagPtAtTheVtx",       "Events", "", pair_DimuonVtxTagPtAtTheVtx_bins),
    ("pair_DimuonVtxProbePtBefore",   100,   0.,  500.,    0.5,    500000., "pair_DimuonVtxProbePtBefore",       "Events", "", pair_DimuonVtxProbePtBefore_bins),
    ("pair_DimuonVtxTagPtBefore",     100,   0.,  500.,    0.5,    500000., "pair_DimuonVtxTagPtBefore",         "Events", "", pair_DimuonVtxTagPtBefore_bins),
    ("pair_DimuonVtxZcoordinate",     100, -50.,   50.,    0.5,    500000., "pair_DimuonVtxZcoordinate",         "Events", "", pair_DimuonVtxZcoordinate_bins),
    ("pair_DimuonVtxRdistance",       100,   0.,    1.,   100.,    500000., "pair_DimuonVtxRdistance",           "Events", "", pair_DimuonVtxRdistance_bins),
    ("pair_DimuonVtxRdistanceFromBS", 100,   0.,    1.,  0.001,   5000000., "pair_DimuonVtxRdistanceFromBS",     "Events", "", pair_DimuonVtxRdistanceFromBS_bins),
    ("pair_DimuonVtxFitNormQui2",     100,   0.,  100.,     1.,    500000., "pair_DimuonVtxFitNormQui2",         "Events", "", pair_DimuonVtxFitNormQui2_bins),
    ("pair_dz",                       100,  -1.,    1.,    0.1, 200000000., "pair_dz",                           "Events", "", pair_dz_bins),
    ]


# USER has to tell what is the variable name related to the mass.
mass_variable = "pair_newTuneP_mass"

# Include bellow as many lines as you need to add ROOT files.
# First input ROOT file must have DATA events (root file 0).
# The code will create histogrms in stacks following the order
# of the input root files as they appear here: the histogram
# on the top corresponds to the input root file 1, while the
# histogram on the bottom corresponds to the last input root
# file entry bellow.
input_files = [
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/tnpZ_SingleMuRun2012C_22Jan2013_v1.root",       # root file 0 (Data)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/tnpZ_M_20_withNVtxWeights.root",                # root file 1 (DY->MuMu M 20)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/tnpZ_M_120_withNVtxWeights.root",               # root file 2 (DY->MuMu M 120)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/tnpZ_M_200_withNVtxWeights.root",               # root file 3 (DY->MuMu M 200)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/tnpZ_M_500_withNVtxWeights.root",               # root file 4 (DY->MuMu M 500)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/tnpZ_M_800_withNVtxWeights.root",               # root file 5 (DY->MuMu M 800)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/tnpZ_M_1000_withNVtxWeights.root",              # root file 6 (DY->MuMu M 1000)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/tnpZ_M_1500_withNVtxWeights.root",              # root file 7 (DY->MuMu M 1500)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/tnpZ_M_2000_withNVtxWeights.root",              # root file 8 (DY->MuMu M 2000)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/DYToTauTau_M_20_withNVtxWeights.root",          # root file 9 (DY->TauTau M 20)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/ttbar_withNVtxWeights.root",                    # root file 10 (ttbar)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/T_tW_withNVtxWeights.root",                     # root file 11 (tW)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/Tbar_tW_withNVtxWeights.root",                  # root file 12 (tbarW)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/WW_withNVtxWeights.root",                       # root file 13 (WW)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/WZ_withNVtxWeights.root",                       # root file 14 (WZ)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/ZZ_withNVtxWeights.root",                       # root file 15 (ZZ)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/WJetsToLNu_withNVtxWeights.root",               # root file 16 (W+Jets->lnu)
    "dcap://osg-se.sprace.org.br:/pnfs/sprace.org.br/data/cms/store/user/adesouza/MuonPOG/HighMassDimuonEff_WithVertexReweighting_Dec_26_2013/QCD_Pt_20_MuEnrichedPt_15_withNVtxWeights.root",# root file 17 (Inclusive QCD)
    ]


# Write the selections on the mass with respect to each input ROOT file.
mass_selection = [
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass < 3000.0)",  # root file 0  (Data)
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass <  120.0)",  # root file 1  (DY->MuMu M 20)
    "(pair_newTuneP_mass >=  120.0) && (pair_newTuneP_mass <  200.0)", # root file 2  (DY->MuMu M 120)
    "(pair_newTuneP_mass >=  200.0) && (pair_newTuneP_mass <  500.0)", # root file 3  (DY->MuMu M 200)
    "(pair_newTuneP_mass >=  500.0) && (pair_newTuneP_mass <  800.0)", # root file 4  (DY->MuMu M 500)
    "(pair_newTuneP_mass >=  800.0) && (pair_newTuneP_mass < 1000.0)", # root file 5  (DY->MuMu M 800)
    "(pair_newTuneP_mass >= 1000.0) && (pair_newTuneP_mass < 1500.0)", # root file 6  (DY->MuMu M 1000)
    "(pair_newTuneP_mass >= 1500.0) && (pair_newTuneP_mass < 2000.0)", # root file 7  (DY->MuMu M 1500)
    "(pair_newTuneP_mass >= 2000.0)",                                  # root file 8  (DY->MuMu M 2000)
    "(pair_newTuneP_mass >=  20.0) && (pair_newTuneP_mass < 3000.0)",  # root file 9  (DY->TauTau M 20)
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass < 3000.0)",  # root file 10 (ttbar)
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass < 3000.0)",  # root file 11 (tW)
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass < 3000.0)",  # root file 12 (tbarW)
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass < 3000.0)",  # root file 13 (WW)
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass < 3000.0)",  # root file 14 (WZ)
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass < 3000.0)",  # root file 15 (ZZ)
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass < 3000.0)",  # root file 16 (W+Jets->lnu)
    "(pair_newTuneP_mass >=   0.0) && (pair_newTuneP_mass < 3000.0)",  # root file 17 (Inclusive QCD)
    ]

# Write the default event selections (with exception of mass).
default_selection = "(eta >= -2.4) && (eta <= 2.4) && (charge != tag_charge) && (tag_NewTuneP_pt > 45.) && (pair_collinearity1 > 0.02) && (pair_dz >= -0.2) && (pair_dz <= 0.2) && (pair_DimuonVtxFitNormQui2 < 10.)"

# Provide label of histograms concerning each input ROOT file
label_of_histogram = [
    "Data-RunC, 7.05 fb^{-1}",                        # root file 0  (Data)
    "DY #rightarrow #mu#mu, 20 < M(#mu#mu) <  120",   # root file 1  (DY->MuMu M 20)
    "DY #rightarrow #mu#mu, 120 < M(#mu#mu) <  200",  # root file 2  (DY->MuMu M 120)
    "DY #rightarrow #mu#mu, 200 < M(#mu#mu) <  500",  # root file 3  (DY->MuMu M 200)
    "DY #rightarrow #mu#mu, 500 < M(#mu#mu) <  800",  # root file 4  (DY->MuMu M 500)
    "DY #rightarrow #mu#mu, 800 < M(#mu#mu) < 1000",  # root file 5  (DY->MuMu M 800)
    "DY #rightarrow #mu#mu, 1000 < M(#mu#mu) < 1500", # root file 6  (DY->MuMu M 1000)
    "DY #rightarrow #mu#mu, 1500 < M(#mu#mu) < 2000", # root file 7  (DY->MuMu M 1500)
    "DY #rightarrow #mu#mu, M(#mu#mu) > 2000",        # root file 8  (DY->MuMu M 2000)
    "DY #rightarrow #tau#tau",                        # root file 9  (DY->TauTau M 20)
    "t#bar{t}",                                       # root file 10 (ttbar)
    "tW",                                             # root file 11 (tW)
    "#bar{t}W",                                       # root file 12 (tbarW)
    "WW",                                             # root file 13 (WW)
    "WZ",                                             # root file 14 (WZ)
    "ZZ",                                             # root file 15 (ZZ)
    "W+Jets #rightarrow l#nu",                        # root file 16 (W+Jets->lnu)
    "Inclusive QCD",                                  # root file 17 (Inclusive QCD)
    ]

# Write the weight of each input ROOT file.
# Of course, weight of DATA is "1.0".
weight = [
          1.0,#              // input file 0  (DATA)
    4.0989119,#    2.5756,   // input file 1  (DY->MuMu M 20)
    0.8787172,#    0.5522,   // input file 2  (DY->MuMu M 120)
    0.1097428,#    0.0690,   // input file 3  (DY->MuMu M 200)
    0.0032626,#    0.0021,   // input file 4  (DY->MuMu M 500)
    0.0004058,#    0.0003,   // input file 5  (DY->MuMu M 800)
    0.0001327,#    0.00008,  // input file 6  (DY->MuMu M 1000)
    0.0000126,#    0.000008, // input file 7  (DY->MuMu M 1500)
    0.0000016,#    0.000001, // input file 8  (DY->MuMu M 2000)
    4.0970485,#    2.5745,   // input file 9  (DY->TauTau M 20)
    0.0761073,#    0.0478,   // input file 10 (ttbar)
    0.1572465,#    0.0988,   // input file 11 (tW)
    0.1585843,#    0.0996,   // input file 12 (tbarW)
    0.0386323,#    0.0243,   // input file 13 (WW)
    0.0234053,#    0.0147,   // input file 14 (WZ)
    0.0126613,#    0.0080,   // input file 15 (ZZ)
    13.897167,#    8.7325,   // input file 16 (W+Jets->lnu)
    44.194163, #    27.7702   // input file 17 (Inclusive QCD)
#    0.4290,    # input file 18 (DY+Jets->LL M 50)
    ]


# The first color number will be the color of the histograms correspondent to the first
# input ROOT file, while the last color number will be assigned to the last input file.
color_of_histogram = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]


#######################################################################################
##                                                                                   ##
##               !!! Users do not need to modify the lines bellow !!!                ##
##                                                                                   ##
#######################################################################################

#######################################################################################
# This function writes the general settings into an output file.
def General_Settings(output):
    output.write("/////////////////////////////////////////////////////////////////////\n")
    output.write("//                                                                 //\n")
    output.write("//                  Here starts the USER's block                   //\n")
    output.write("//    USER has to go through the lines bellow and include input    //\n")
    output.write("//    root files, variables to be read and plotted, as well as     //\n")
    output.write("//    their X and Y axis ranges, labels, legends and colors.       //\n")
    output.write("//                                                                 //\n")
    output.write("//    USERS can also define the bin edges to compute the number    //\n")
    output.write("//    of entries per bin per input file per variable.              //\n")
    output.write("//                                                                 //\n")
    output.write("/////////////////////////////////////////////////////////////////////\n\n")
    
    output.write("// Set width and height of canvas.\n")
    output.write("// NOTE: It is safer to not touch in the canvas settup, unless you\n")
    output.write("//       know what you are doing.\n")
    output.write("Float_t canvas_ratio = "+str(canvas_ratio)+"; // right side percent of the pad not covered\n")
    output.write("Int_t wCanvas = "+str(wCanvas)+";  // width\n")
    output.write("Int_t hCanvas = "+str(hCanvas)+";  // height\n\n")
    
    output.write("// Would you like to apply a linear (0) or a log scale (1) to Y axis?\n")
    output.write("Int_t linear_log_scale = "+str(linear_log_scale)+";\n\n")
    
    output.write("// Would you like to only pop up the plots, or to only save them, or to do both?\n")
    output.write("// In case of USER running in batch mode ('root -b' option), this code\n")
    output.write("// will automatically save plots in \".png\" format.\n")
    output.write("// What do you like to do?\n")
    output.write("//   - Pop up only -> 0\n")
    output.write("//   - Save only -> 1\n")
    output.write("//   - Both (pop up and save) -> 2\n")
    output.write("Int_t pop_save = "+str(pop_save)+";\n\n")
    
    output.write("// If USER wants to save plots, tell what format:\n")
    output.write("// pdf? png? eps? root?\n")
    output.write("string output_file_format[] = {")
    for i in range(len(output_file_format)):
        if i == (len(output_file_format) - 1):
            output.write("\""+output_file_format[i]+"\"};\n\n")
        else:
            output.write("\""+output_file_format[i]+"\", ")

    output.write("// If USER wants to save plots, provide a commom name.\n")
    output.write("string output_file_name = \""+output_file_name+"\";\n\n")
    
    output.write("// Would you like to get the entries per bin per input file per variable?\n")
    output.write("// If \"NO\"  -> output_entries_per_bin = 0  || (macro will create plots only)\n")
    output.write("// If \"YES\" -> output_entries_per_bin = 1  || (macro will get entries only)\n")
    output.write("// If \"YES\" -> output_entries_per_bin > 1  || (macro will do both things: create plots and get entries)\n")
    output.write("Int_t output_entries_per_bin = "+str(output_entries_per_bin)+";\n\n")

    output.write("// Would you like to scale MC samples from normalization in Z peak based on data / MC ration?\n")
    output.write("// If \"NO\"  -> 0\n")
    output.write("// If \"YES\" -> 1\n")
    output.write("Int_t normalize = "+str(normalize)+";\n\n")

    output.write("// Distance between label and Y axis.\n")
    output.write("// NOTE: It is safer to not touch in the canvas settup, unless you\n")
    output.write("//       know what you are doing.\n")
    output.write("Float_t y_title_offset = "+str(y_title_offset)+";\n\n")

    output.write("// Set legend position\n")
    output.write("double xMinLegend = "+str(xMinLegend)+"; // minimum x position of the legend\n")
    output.write("double yMinLegend = "+str(yMinLegend)+";  // minimum y position of the legend\n")
    output.write("double xMaxLegend = "+str(xMaxLegend)+"; // maximum x position of the legend\n")
    output.write("double yMaxLegend = "+str(yMaxLegend)+";  // maximum y position of the legend\n\n")

    output.write("// Include bellow as many lines as you need to add ROOT files.\n")
    output.write("// First input ROOT file must have DATA events (root file 0).\n")
    output.write("// The code will create histogrms in stacks following the order\n")
    output.write("// of the input root files as they appear here: the histogram\n")
    output.write("// on the top corresponds to the input root file 1, while the\n")
    output.write("// histogram on the bottom corresponds to the last input root\n")
    output.write("// file entry bellow.\n")
    output.write("string input_files[] = {\n")
    for i in range(len(input_files)):
        if i == (len(input_files) - 1):
            output.write("\""+input_files[i]+"\"\n")
        else:
            output.write("\""+input_files[i]+"\",\n")
    output.write("};\n\n")

    output.write("// Provide label of histograms concerning each input ROOT file\n")
    output.write("string label_of_histogram[] = {\n")
    for i in range(len(label_of_histogram)):
        if i == (len(label_of_histogram) - 1):
            output.write("\""+label_of_histogram[i]+"\"\n")
        else:
            output.write("\""+label_of_histogram[i]+"\",\n")
    output.write("};\n\n")

    output.write("// Write the weight of each input ROOT file.\n")
    output.write("// Of course, weight of DATA is \"1.0\".\n")
    output.write("double weight[] = {\n")
    for i in range(len(weight)):
        if i == (len(weight) - 1):
            output.write(str(weight[i])+"\n")
        else:
            output.write(str(weight[i])+",\n")
    output.write("};\n\n")

    output.write("// The first color number will be the color of the histograms correspondent to the first\n")
    output.write("// input ROOT file, while the last color number will be assigned to the last input file.\n")
    output.write("int color_of_histogram[] = {"+", ".join(str(i) for i in color_of_histogram)+"};\n")

    output.write("// USER has to tell what is the variable name related to the mass.\n")
    output.write("string mass_variable = \""+mass_variable+"\";\n\n")

    output.write("// Write the selections on the mass with respect to each input ROOT file.\n")
    output.write("string mass_selection[] = {\n")
    for i in range(len(mass_selection)):
        if i == (len(mass_selection) - 1):
            output.write("\""+mass_selection[i]+"\"\n")
        else:
            output.write("\""+mass_selection[i]+"\",\n")
    output.write("};\n\n")

    output.write("// Write the default event selections (with exception of mass).\n")
    output.write("string default_selection = \""+default_selection+"\";\n\n")


#########################################################################################################
# This function runs over several variables defined by the User and write them into an output file.
def Loop_Over_Variables(output, i):

    output.write("// Write the list of variables inside an array.\n")
    output.write("string list_of_variables[] = {")
#    for i in range(len(variables_settings)):
#        if i == (len(variables_settings) - 1):
    output.write("\""+variables_settings[i][0]+"\"")
#        else:
#            output.write("\""+variables_settings[i][0]+"\",\n")
    output.write("};\n\n")

    output.write("// Number of bins, Y and X axis ranges and stylistic definitions from USER.\n")
    output.write("// If you want, you can also provide the histogram title and the Y and X\n")
    output.write("// axis labels for each variable. Labels are giving to each histogram\n")
    output.write("// corresponding to each input root file.\n")
    output.write("// Give also a different color to each histogram corresponding to each input\n")
    output.write("// root file.\n")
    output.write("// Order of numbers bellow has to follow order of the list of variables provided above.\n")
    output.write("int number_of_bins[] = {")
#    for i in range(len(variables_settings)):
#        if i == (len(variables_settings) - 1):
    output.write(str(variables_settings[i][1])+"};\n\n")
#        else:
#            output.write(str(variables_settings[i][1])+", ")

    output.write("double x_minimum[] = {")
#    for i in range(len(variables_settings)):
#        if i == (len(variables_settings) - 1):
    output.write(str(variables_settings[i][2])+"};\n\n")
#        else:
#            output.write(str(variables_settings[i][2])+", ")

    output.write("double x_maximum[] = {")
#    for i in range(len(variables_settings)):
#        if i == (len(variables_settings) - 1):
    output.write(str(variables_settings[i][3])+"};\n\n")
#        else:
#            output.write(str(variables_settings[i][3])+", ")

    output.write("double y_minimum[] = {")
#    for i in range(len(variables_settings)):
#        if i == (len(variables_settings) - 1):
    output.write(str(variables_settings[i][4])+"};\n\n")
#        else:
#            output.write(str(variables_settings[i][4])+", ")

    output.write("double y_maximum[] = {")
#    for i in range(len(variables_settings)):
#        if i == (len(variables_settings) - 1):
    output.write(str(variables_settings[i][5])+"};\n\n")
#        else:
#            output.write(str(variables_settings[i][5])+", ")

    output.write("// Provide label of X axis.\n")
    output.write("string x_axis_label[] = {")
#    for i in range(len(variables_settings)):
#        if i == (len(variables_settings) - 1):
    output.write("\""+str(variables_settings[i][6])+"\"};\n\n")
#        else:
#            output.write("\""+str(variables_settings[i][6])+"\", ")

    output.write("// Provide label of Y axis.\n")
    output.write("string y_axis_label[] = {")
#    for i in range(len(variables_settings)):
#        if i == (len(variables_settings) - 1):
    output.write("\""+str(variables_settings[i][7])+"\"};\n\n")
#        else:
#            output.write("\""+str(variables_settings[i][7])+"\", ")

    output.write("// Provide titles\n")
    output.write("string title_of_histogram[] = {")
#    for i in range(len(variables_settings)):
#        if i == (len(variables_settings) - 1):
    output.write("\""+str(variables_settings[i][8])+"\"};\n\n")
#        else:
#            output.write("\""+str(variables_settings[i][8])+"\", ")

    output.write("// Write the binning for each variable\n")
    output.write("double "+variables_settings[i][0].replace("/", "_")+"_bins[] = {")
    output.write( ", ".join(str(j) for j in variables_settings[i][9]) )
    output.write("};\n\n")

    output.write("////////////////////////////////////////////////////////////////////\n")
    output.write("//         Loop bellow corresponds to the variable above.         //\n")
    output.write("////////////////////////////////////////////////////////////////////\n")
    output.write("void fill_bins (vector <vector <double> > &bin_edges) {\n")
    output.write("  Int_t total_number_of_variables = (sizeof(list_of_variables) / sizeof(string));\n")
    output.write("  bin_edges.resize(total_number_of_variables + 1);\n\n")
    output.write("  for ( Int_t i = 0; i < (sizeof("+variables_settings[i][0].replace("/", "_")+"_bins) / sizeof(double)); i++ )\n")
    output.write("    bin_edges[0].push_back( "+variables_settings[i][0]+"_bins[i] );\n")
    output.write("\n")
    output.write("}\n")


#######################################################################################
# This function enable to run bash commands via Python and read its results pop up
# on screen in real time.
def bash_via_python(command_line):

    p2 = subprocess.Popen(command_line, shell=True, stderr=subprocess.PIPE)
    while True:
        out = p2.stderr.read(1)
        if out == '' and p2.poll() != None:
            break
        if out != '':
            sys.stdout.write(out)
            sys.stdout.flush()


#######################################################################################
# User provides a directory name through this function. If such directory does not
# exists yet, it will be created.
def create_new_directory(directory):

    from_bash = os.path.isdir(directory)
    if from_bash == True:
        print "\n-->\t WARNING: File <", directory, "> already exists. Please, provide other name! \n"
        exit()
    else:
        bash_via_python("mkdir "+directory)
        print "\n-->\t File <", directory, "> has been successfully created.\n"


#######################################################################################
# Here the main function is defined, creating an output file where all general and
# specific variable settings will be written down.
def main():

    print "A new directory will be created here."
    directory = raw_input("Please, provide the name of the directory: ")
    from_bash = os.path.isdir(directory)
    if from_bash == True:
        print "\n-->\t WARNING: File <", directory, "> already exists. Please, provide other name! \n"
        exit()
    else:
        bash_via_python("mkdir "+directory)
        print "\n-->\t File <", directory, "> has been successfully created.\n"

#    bash_via_python("cp TagAndProbe_stacks_V12.cpp \
#                        Setting_Variables2.h "+directory+"/.")

#    os.chdir(directory)
#    bash_via_python("ls -all")
#    os.chdir("..")


    bash_via_python("cp  TagAndProbe_stacks_V12.cpp  TagAndProbe.sh  TagAndProbe_for_condor.submit \
                     submit_TagAndProbe_to_condor.sh  Common_Settings.py  "+directory+"/.")

    os.chdir(directory)

    for i in range(len(variables_settings)):
        outputFile = open("General_Settings"+str(i)+".h", "w")
        General_Settings(outputFile)
        Loop_Over_Variables(outputFile, i)
        outputFile.close()

        bash_via_python("mkdir Plot_"+variables_settings[i][0].replace("/",""))
        bash_via_python("cp TagAndProbe_stacks_V12.cpp  TagAndProbe.sh  TagAndProbe_for_condor.submit \
                         submit_TagAndProbe_to_condor.sh  "+outputFile.name+" \
                         Plot_"+variables_settings[i][0].replace("/","")+"/.")

        os.chdir("Plot_"+variables_settings[i][0].replace("/",""))

        bash_via_python("sed -i 's/Setting_Variables.h/"+outputFile.name+"/g' TagAndProbe.sh")
        bash_via_python("sed -i 's/Setting_Variables.h/"+outputFile.name+"/g' TagAndProbe_stacks_V12.cpp")
        bash_via_python("sed -i 's/Setting_Variables.h/"+outputFile.name+"/g' submit_TagAndProbe_to_condor.sh")

        bash_via_python("./submit_TagAndProbe_to_condor.sh  Plots")
        os.chdir("..")

    bash_via_python("ls -all")

#######################################################################################
# Here starts the main funtion
main()