/**
 * Constructs a new AdaptSRNParametersOperator.
 */
AdaptSRNParametersOperator::AdaptSRNParametersOperator(const QString &name)
	: NeuralNetworkManipulationOperator(name)
{
	mChangeProbability = new NormalizedDoubleValue(0.1, 0.0, 1.0, 0.0, 1.0);
	mGlobalSettings = new BoolValue(true);
	
	mChangeProbability->setDescription("The probability for a parameter change to occur at all.\n"
									   "If used with ApplyGlobally = false, then this probability\n"
									   "is applied to each SRN neuron separately.");
	
	mGlobalSettings->setDescription("If true, then all parameters of all SRN neurons are changed\n"
									"at once.");
	
	for(int i = 0; i < 5; ++i) {
		mProbabilities.append(new NormalizedDoubleValue(0.5, 0.0, 1.0, 0.0, 1.0));
		mDeviations.append(new NormalizedDoubleValue(0.05, 0.0, 1.0, 0.0, 1.0));
		mMins.append(new DoubleValue(0.0));
		mMaxs.append(new DoubleValue(1.0));
	}
	addParameters("Alpha", 0);
	addParameters("Beta", 1);
	addParameters("Gamma", 2);
	addParameters("Delta", 3);
	addParameters("AStar", 4);
	
	addParameter("ProbabilityForChange", mChangeProbability);
	addParameter("ApplyGlobally", mGlobalSettings);
	
	getEnableOperatorValue()->set(false);
	getHiddenValue()->set(true);

}
Пример #2
0
CTDResidualLearner::CTDResidualLearner(CRewardFunction *rewardFunction, 
                                       CGradientQFunction *qfunction, 
                                       CAgentController *agent, 
                                       CResidualFunction *residual, 
                                       CResidualGradientFunction *residualGradient, 
                                       CAbstractBetaCalculator *betaCalc,
                                       bool adaptive)

: CTDGradientLearner(rewardFunction, qfunction, agent, residual, residualGradient)

{
    adaptiveFeatures = adaptive;
    network = NULL;
    
	this->betaCalculator = betaCalc;

	residualETraces = new CGradientQETraces(qfunction);
	residualETraces->setReplacingETraces(true);

	directGradientTraces = new CGradientQETraces(qfunction);
	directGradientTraces->setReplacingETraces(true);

	residualGradientTraces = new CGradientQETraces(qfunction);
	residualGradientTraces->setReplacingETraces(true);


	addParameters(residualETraces);

	addParameters(directGradientTraces, "Gradient");
	addParameters(residualGradientTraces, "Gradient");

	addParameters(betaCalculator);

	addParameter("ScaleResidualGradient", 0.0);
}
Пример #3
0
CActorFromQFunction::CActorFromQFunction(CAbstractQFunction *qFunction) : CActor()
{
	this->qFunction = qFunction;
	eTraces = qFunction->getStandardETraces();

	addParameters(qFunction);
	addParameters(eTraces, "Actor");

}
Пример #4
0
CActorFromContinuousActionGradientPolicy::CActorFromContinuousActionGradientPolicy(CContinuousActionGradientPolicy *l_gradientPolicy)
{
	this->gradientPolicy = l_gradientPolicy;
	gradientETraces = new CGradientVETraces(NULL);
	gradientFeatureList = new CFeatureList();

	addParameters(gradientPolicy);
	addParameters(gradientETraces, "Actor");

	policyDifference = new CContinuousActionData(l_gradientPolicy->getContinuousActionProperties());
}
Пример #5
0
void CActorForMultipleAgents::addActor(CActor *actor, CAgentController *policy)
{
	actors->push_back(actor);
	actionSets->push_back(policy);
	
	numActions = numActions * policy->getActions()->size();
	
	assert(numActions <= actions->size());
	
	addParameters(actor);
	addParameters(policy);
}
Пример #6
0
void
JsonInputFileFormatter::addBlock(const std::string & name,
                                 const moosecontrib::Json::Value & block,
                                 bool toplevel)
{
  addLine("");
  if (toplevel)
    addLine("[" + name + "]");
  else
    addLine("[./" + name + "]");

  _level++;
  if (block.isMember("description") && !block["description"].asString().empty())
    addLine("", 0, block["description"].asString());

  if (block.isMember("parameters"))
    addParameters(block["parameters"]);

  if (block.isMember("actions"))
  {
    // there could be duplicate parameters across actions, last one wins
    moosecontrib::Json::Value all_params;
    auto & actions = block["actions"];
    for (auto && name : actions.getMemberNames())
    {
      auto & params = actions[name]["parameters"];
      for (auto && param_name : params.getMemberNames())
        all_params[param_name] = params[param_name];
    }
    addParameters(all_params);
  }

  if (block.isMember("star"))
    addBlock("*", block["star"]);

  addTypes("subblock_types", block);
  addTypes("types", block);

  if (block.isMember("subblocks"))
  {
    auto & subblocks = block["subblocks"];
    if (!subblocks.isNull())
      for (auto && name : subblocks.getMemberNames())
        addBlock(name, subblocks[name]);
  }

  _level--;
  if (toplevel)
    addLine("[]");
  else
    addLine("[../]");
}
Пример #7
0
CActorFromActionValue::CActorFromActionValue(CAbstractVFunction *vFunction, CAction *action1, CAction *action2) : CAgentController(new CActionSet())
{
	actions->add(action1);
	actions->add(action2);

	addParameters(vFunction);

	this->vFunction = vFunction;
	this->eTraces = vFunction->getStandardETraces();

	addParameters(eTraces, "Actor");

	setParameter("ActorLearningRate", 1000.0);
}
Пример #8
0
DxArchiverParameters::DxArchiverParameters(string command) : 
   SeekerParameterGroup(command),
   internal_(new DxArchiverParametersInternal())
{
   addParameters();
   addAllImmedCmdHelp();
}
Пример #9
0
DxArchiverParameters::DxArchiverParameters(const DxArchiverParameters& rhs):
   SeekerParameterGroup(rhs.getCommand()),
   internal_(new DxArchiverParametersInternal(*rhs.internal_))
{
   setSite(rhs.getSite());
   addParameters();
}
Пример #10
0
DxParameters::DxParameters(const DxParameters& rhs):
   SeekerParameterGroup(rhs.getCommand(), rhs.getDbTableName(), 
			rhs.getIdColNameInActsTable()),
   internal_(new DxParametersInternal(*rhs.internal_))
{
   setSite(rhs.getSite());
   addParameters();
}
Пример #11
0
CActorFromQFunctionAndPolicy::CActorFromQFunctionAndPolicy(CAbstractQFunction *qFunction, CStochasticPolicy *policy) : CActorFromQFunction(qFunction)
{
	this->policy = policy;
	
	actionValues = new double[policy->getActions()->size()];

	addParameters(policy);

	addParameter("PolicyMinimumLearningRate", 0.5);
}
Пример #12
0
CTDLearner::CTDLearner(CRewardFunction *rewardFunction, CAbstractQFunction *qFunction, CAgentController *estimationPolicy) : CSemiMDPRewardListener(rewardFunction)
{
	this->qfunction = qFunction;
    this->etraces = qFunction->getStandardETraces();
	this->estimationPolicy = estimationPolicy;

	addParameter("QLearningRate", 0.2);
	addParameter("DiscountFactor",0.95);
	addParameters(qfunction);
	addParameters(etraces);

	addParameter("ResetETracesOnWrongEstimate", 1.0);

	if (estimationPolicy)
	{
		addParameters(estimationPolicy);
	}
	this->externETraces = false;
	this->actionDataSet = new CActionDataSet(qfunction->getActions());

	lastEstimatedAction = NULL;
}
Пример #13
0
CTDGradientLearner::CTDGradientLearner(CRewardFunction *rewardFunction, CGradientQFunction *qfunction, CAgentController *agentController, CResidualFunction *residual, CResidualGradientFunction *residualGradient) : CTDLearner(rewardFunction, qfunction, new CGradientQETraces(qfunction), agentController)
{
	assert(qfunction->isType(GRADIENTQFUNCTION));
	this->gradientQFunction = qfunction;
	
	this->residual = residual;
	this->residualGradient = residualGradient;

	if (residual)
	{
		addParameters(residual);
	}
	if (residualGradient)
	{
		addParameters(residualGradient);
	}
	this->gradientQETraces = dynamic_cast<CGradientQETraces *>(etraces);
	gradientQETraces->setReplacingETraces(true);

	oldGradient = new CFeatureList();
	newGradient = new CFeatureList();
	residualGradientFeatures = new CFeatureList();
}
Пример #14
0
DxParameters& DxParameters::operator=(const DxParameters& rhs)
{
   if (this == &rhs) {
      return *this;
   }
  
   setCommand(rhs.getCommand());
   eraseParamList();
   setSite(rhs.getSite());
   delete internal_;
   internal_ = new DxParametersInternal(*rhs.internal_);
   addParameters();
   return *this;
}
Пример #15
0
DxParameters::DxParameters(string command) : 
   SeekerParameterGroup(command, DbTableName, IdColNameInActsTable),
   internal_(new DxParametersInternal())
{
   internal_->daddResolution.addChoice(1);  // 1Hz
   internal_->daddResolution.addChoice(2);  // 2HZ
   internal_->daddResolution.addChoice(4);  // 4HZ

   internal_->sendBaselines.addChoice(ChoiceOn);
   internal_->sendBaselines.addChoice(ChoiceOff);

   internal_->sendComplexAmplitudes.addChoice(ChoiceOn);
   internal_->sendComplexAmplitudes.addChoice(ChoiceOff);

   internal_->dataRequestType.addChoice(DataReqFreq);
   internal_->dataRequestType.addChoice(DataReqSubchannel);

   internal_->manualBandwidth.addChoice(ChoiceOn);
   internal_->manualBandwidth.addChoice(ChoiceOff);

   internal_->allowPulseDetection.addChoice(ChoiceOn);
   internal_->allowPulseDetection.addChoice(ChoiceOff);

   internal_->sendBaselineStatistics.addChoice(ChoiceOn);
   internal_->sendBaselineStatistics.addChoice(ChoiceOff);

   internal_->checkBaselineWarningLimits.addChoice(ChoiceOn);
   internal_->checkBaselineWarningLimits.addChoice(ChoiceOff);

   internal_->checkBaselineErrorLimits.addChoice(ChoiceOn);
   internal_->checkBaselineErrorLimits.addChoice(ChoiceOff);

   internal_->recentRfiEnable.addChoice(ChoiceOn);
   internal_->recentRfiEnable.addChoice(ChoiceOff);

   addParameters();
   addAllImmedCmdHelp();

}
Пример #16
0
CVPolicyLearner::CVPolicyLearner(CStateReward *rewardFunction, CTransitionFunction *dynModel, CTransitionFunctionInputDerivationCalculator *dynModeldInput,CAbstractVFunction *vFunction, CVFunctionInputDerivationCalculator *vFunctionInputDerivation, CContinuousActionGradientPolicy *gradientPolicy, CCAGradientPolicyInputDerivationCalculator *policydInput, std::list<CStateModifier *> *stateModifiers, int nForwardView) : CSemiMDPRewardListener(rewardFunction)
{
	this->rewardFunction = rewardFunction;
	this->vFunction = vFunction;
	this->gradientPolicy = gradientPolicy;
	this->dynModeldInput = dynModeldInput;
	this->policydInput = policydInput;
	this->vFunctionInputDerivation = vFunctionInputDerivation;
	this->dynModel = dynModel;
	this->stateModifiers = stateModifiers;


	dPolicy = new Matrix(gradientPolicy->getNumOutputs(), dynModel->getNumContinuousStates());
	dModelInput = new Matrix(dynModel->getNumContinuousStates(), gradientPolicy->getNumOutputs() + dynModel->getNumContinuousStates());
	dReward = new ColumnVector(dynModel->getNumContinuousStates());
	dVFunction = new ColumnVector(dynModel->getNumContinuousStates());
	data = new CContinuousActionData(gradientPolicy->getContinuousActionProperties());

//	states = new std::list<CState *>();

	addParameter("DiscountFactor", 0.95);
	addParameter("PolicyLearningRate", 1.0);
	addParameter("PolicyLearningFowardView", nForwardView);
	addParameter("PolicyLearningBackwardView", 0.0);

	addParameters(policydInput, "DPolicy");
	addParameters(dynModeldInput, "DModel");
	addParameters(vFunctionInputDerivation, "DVFunction");


	tempStateCol = new CStateCollectionImpl(dynModel->getStateProperties(), stateModifiers);


	stateGradient1 = new CStateGradient();

	for (unsigned int i = 0; i < dynModel->getNumContinuousStates(); i ++)
	{
		stateGradient1->push_back(new CFeatureList());
	}

	stateGradient2 = new CStateGradient();

	for (unsigned int i = 0; i < dynModel->getNumContinuousStates(); i ++)
	{
		stateGradient2->push_back(new CFeatureList());
	}

	dModelGradient = new CStateGradient();

	for (int i = 0; i < gradientPolicy->getNumOutputs(); i ++)
	{
		dModelGradient->push_back(new CFeatureList());
	}

	policyGradient = new CFeatureList();

	pastStates = new std::list<CStateCollectionImpl *>();
	pastDRewards = new std::list<ColumnVector *>();
	pastActions = new std::list<CContinuousActionData *>();

	statesResource = new std::list<CStateCollectionImpl *>();
	rewardsResource = new std::list<ColumnVector *>();
	actionsResource = new std::list<CContinuousActionData *>();
}
Пример #17
0
CParameters::CParameters(CParameters &copy)
{
	parameters = new std::map<string, double>();
	isAdaptive = new std::map<string, bool>();
	addParameters(&copy);
}
Пример #18
0
void CGradientUpdateFunction::setEtaCalculator(CAdaptiveEtaCalculator *etaCalc)
{
	addParameters(etaCalc);
	this->etaCalc = etaCalc;
}
Пример #19
0
bool ParserAlterQuery::parseImpl(Pos & pos, Pos end, ASTPtr & node, Pos & max_parsed_pos, Expected & expected)
{
    Pos begin = pos;

    ParserKeyword s_alter_table("ALTER TABLE");
    ParserKeyword s_add_column("ADD COLUMN");
    ParserKeyword s_drop_column("DROP COLUMN");
    ParserKeyword s_modify_column("MODIFY COLUMN");
    ParserKeyword s_modify_primary_key("MODIFY PRIMARY KEY");

    ParserKeyword s_attach_partition("ATTACH PARTITION");
    ParserKeyword s_detach_partition("DETACH PARTITION");
    ParserKeyword s_drop_partition("DROP PARTITION");
    ParserKeyword s_attach_part("ATTACH PART");
    ParserKeyword s_fetch_partition("FETCH PARTITION");
    ParserKeyword s_freeze_partition("FREEZE PARTITION");
    ParserKeyword s_reshard("RESHARD");
    ParserKeyword s_partition("PARTITION");

    ParserKeyword s_after("AFTER");
    ParserKeyword s_from("FROM");
    ParserKeyword s_from_partition("FROM PARTITION");
    ParserKeyword s_copy("COPY");
    ParserKeyword s_to("TO");
    ParserKeyword s_using("USING");
    ParserKeyword s_coordinate("COORDINATE");
    ParserKeyword s_with("WITH");
    ParserKeyword s_name("NAME");

    ParserString s_dot(".");
    ParserString s_comma(",");
    ParserString s_doubledot("..");

    ParserWhitespaceOrComments ws;

    ParserIdentifier table_parser;
    ParserCompoundIdentifier parser_name;
    ParserCompoundColumnDeclaration parser_col_decl;
    ParserLiteral parser_literal;
    ParserUnsignedInteger parser_uint;
    ParserStringLiteral parser_string_literal;

    ASTPtr table;
    ASTPtr database;
    String cluster_str;
    ASTPtr col_type;
    ASTPtr col_after;
    ASTPtr col_drop;

    auto query = std::make_shared<ASTAlterQuery>();

    ws.ignore(pos, end);
    if (!s_alter_table.ignore(pos, end, max_parsed_pos, expected))
        return false;

    ws.ignore(pos, end);

    if (!table_parser.parse(pos, end, database, max_parsed_pos, expected))
        return false;

    /// Parse [db].name
    if (s_dot.ignore(pos, end))
    {
        if (!table_parser.parse(pos, end, table, max_parsed_pos, expected))
            return false;

        query->table = typeid_cast<ASTIdentifier &>(*table).name;
        query->database = typeid_cast<ASTIdentifier &>(*database).name;
    }
    else
    {
        table = database;
        query->table = typeid_cast<ASTIdentifier &>(*table).name;
    }

    ws.ignore(pos, end);

    if (ParserKeyword{"ON"}.ignore(pos, end, max_parsed_pos, expected))
    {
        if (!ASTQueryWithOnCluster::parse(pos, end, cluster_str, max_parsed_pos, expected))
            return false;
    }

    bool parsing_finished = false;
    do
    {
        ASTAlterQuery::Parameters params;
        ws.ignore(pos, end);

        if (s_add_column.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!parser_col_decl.parse(pos, end, params.col_decl, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);
            if (s_after.ignore(pos, end, max_parsed_pos, expected))
            {
                ws.ignore(pos, end);

                if(!parser_name.parse(pos, end, params.column, max_parsed_pos, expected))
                    return false;
            }

            params.type = ASTAlterQuery::ADD_COLUMN;
        }
        else if (s_drop_partition.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
                return false;

            params.type = ASTAlterQuery::DROP_PARTITION;
        }
        else if (s_drop_column.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!parser_name.parse(pos, end, params.column, max_parsed_pos, expected))
                return false;

            params.type = ASTAlterQuery::DROP_COLUMN;
            params.detach = false;

            if (s_from_partition.ignore(pos, end, max_parsed_pos, expected))
            {
                ws.ignore(pos, end);

                if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
                    return false;
            }
        }
        else if (s_detach_partition.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
                return false;

            params.type = ASTAlterQuery::DROP_PARTITION;
            params.detach = true;
        }
        else if (s_attach_partition.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
                return false;

            params.type = ASTAlterQuery::ATTACH_PARTITION;
        }
        else if (s_attach_part.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
                return false;

            params.part = true;
            params.type = ASTAlterQuery::ATTACH_PARTITION;
        }
        else if (s_fetch_partition.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            if (!s_from.ignore(pos, end, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            ASTPtr ast_from;
            if (!parser_string_literal.parse(pos, end, ast_from, max_parsed_pos, expected))
                return false;

            params.from = typeid_cast<const ASTLiteral &>(*ast_from).value.get<const String &>();
            params.type = ASTAlterQuery::FETCH_PARTITION;
        }
        else if (s_freeze_partition.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!parser_literal.parse(pos, end, params.partition, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            /// WITH NAME 'name' - place local backup to directory with specified name
            if (s_with.ignore(pos, end, max_parsed_pos, expected))
            {
                ws.ignore(pos, end);

                if (!s_name.ignore(pos, end, max_parsed_pos, expected))
                    return false;

                ws.ignore(pos, end);

                ASTPtr ast_with_name;
                if (!parser_string_literal.parse(pos, end, ast_with_name, max_parsed_pos, expected))
                    return false;

                params.with_name = typeid_cast<const ASTLiteral &>(*ast_with_name).value.get<const String &>();

                ws.ignore(pos, end);
            }

            params.type = ASTAlterQuery::FREEZE_PARTITION;
        }
        else if (s_modify_column.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!parser_col_decl.parse(pos, end, params.col_decl, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            params.type = ASTAlterQuery::MODIFY_COLUMN;
        }
        else if (s_modify_primary_key.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);

            if (!ParserString("(").ignore(pos, end, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            if (!ParserNotEmptyExpressionList(false).parse(pos, end, params.primary_key, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            if (!ParserString(")").ignore(pos, end, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            params.type = ASTAlterQuery::MODIFY_PRIMARY_KEY;
        }
        else if (s_reshard.ignore(pos, end, max_parsed_pos, expected))
        {
            ParserList weighted_zookeeper_paths_p(std::make_unique<ParserWeightedZooKeeperPath>(), std::make_unique<ParserString>(","), false);
            ParserExpressionWithOptionalAlias parser_sharding_key_expr(false);
            ParserStringLiteral parser_coordinator;

            ws.ignore(pos, end);

            if (s_copy.ignore(pos, end, max_parsed_pos, expected))
                params.do_copy = true;

            ws.ignore(pos, end);

            if (s_partition.ignore(pos, end, max_parsed_pos, expected))
            {
                ws.ignore(pos, end);

                if (!parser_uint.parse(pos, end, params.partition, max_parsed_pos, expected))
                    return false;

                ws.ignore(pos, end);

                if (s_doubledot.ignore(pos, end, max_parsed_pos, expected))
                {
                    ws.ignore(pos, end);

                    if (!parser_uint.parse(pos, end, params.last_partition, max_parsed_pos, expected))
                        return false;
                }
            }

            ws.ignore(pos, end);

            if (!s_to.ignore(pos, end, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            if (!weighted_zookeeper_paths_p.parse(pos, end, params.weighted_zookeeper_paths, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            if (!s_using.ignore(pos, end, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            if (!parser_sharding_key_expr.parse(pos, end, params.sharding_key_expr, max_parsed_pos, expected))
                return false;

            ws.ignore(pos, end);

            if (s_coordinate.ignore(pos, end, max_parsed_pos, expected))
            {
                ws.ignore(pos, end);

                if (!s_with.ignore(pos, end, max_parsed_pos, expected))
                    return false;

                ws.ignore(pos, end);

                if (!parser_coordinator.parse(pos, end, params.coordinator, max_parsed_pos, expected))
                    return false;

                ws.ignore(pos, end);
            }

            params.type = ASTAlterQuery::RESHARD_PARTITION;
        }
        else
            return false;

        ws.ignore(pos, end);

        if (!s_comma.ignore(pos, end, max_parsed_pos, expected))
        {
            ws.ignore(pos, end);
            parsing_finished = true;
        }

        query->addParameters(params);
    }
    while (!parsing_finished);

    query->range = StringRange(begin, end);
    query->cluster = cluster_str;
    node = query;

    return true;
}
Пример #20
0
void fitter(
            const string workDirName="Test", // Working directory
            // Select the type of datasets to fit
            bool fitData     = true,         // Fits Data if true, otherwise fits MC
            bool fitPbPb     = true,         // Fits PbPb datasets
            bool fitPP       = true,         // Fits PP datasets
            // Select the type of object to fit
            bool incJpsi     = true,         // Includes Jpsi model
            bool incPsi2S    = true,         // Includes Psi(2S) model
            bool incBkg      = true,         // Includes Background model
            // Select the fitting options
            bool cutCtau     = false,        // Apply prompt ctau cuts
            bool doSimulFit  = false,        // Do simultaneous fit
            bool wantPureSMC = false,        // Flag to indicate if we want to fit pure signal MC
            int  numCores    = 2,            // Number of cores used for fitting
            // Select the drawing options
            bool setLogScale = true,         // Draw plot with log scale
            bool incSS       = false,        // Include Same Sign data
            bool zoomPsi     = false,        // Zoom Psi(2S) peak on extra pad
            int  nBins       = 54            // Number of bins used for plotting
            ) 
{
  // -------------------------------------------------------------------------------
  // STEP 0: INITIALIZE THE FITTER WORK ENVIROMENT
  // The work enviroment is divided as follows:
  /*
    main |-> Macros: Contain all the macros
         |-> Input   |-> <WorkDir> : Contain Input File, Bin and Parameter List for a given work directory (e.g. 20160201)
	 |-> Output  |-> <WorkDir> : Contain Output Plots and Results for a given work directory (e.g. 20160201)
	 |-> DataSet : Contain all the datasets (MC and Data)
  */

  if (!checkSettings(fitData, fitPbPb, fitPP, incJpsi, incPsi2S, incBkg, cutCtau, doSimulFit, wantPureSMC, setLogScale, zoomPsi, incSS, numCores, nBins)) { return; }

  map<string,string> DIR;
  if(!iniWorkEnv(DIR, workDirName)){ return; }
 
  // -------------------------------------------------------------------------------
  // STEP 1: CREATE/LOAD THE ROODATASETS
  /*
    Input : List of TTrees with format:  TAG <tab> FILE_NAME
    Output: Collection of RooDataSets splitted by tag name, including OS and SS dimuons.
  */
  
  const string InputTrees = DIR["input"] + "InputTrees.txt";
  map<string, vector<string> > InputFileCollection;
  if(!getInputFileNames(InputTrees, InputFileCollection)){ return; }
  
  TObjArray* aDSTAG = new TObjArray(); // Array to store the different tags in the list of trees
  aDSTAG->SetOwner(true);
  map<string, RooWorkspace> Workspace;

  for(map<string, vector<string> >::iterator FileCollection=InputFileCollection.begin(); FileCollection!=InputFileCollection.end(); ++FileCollection) {
    // Get the file tag which has the following format: DSTAG_COLL , i.e. DATA_PP 
    string FILETAG = FileCollection->first;  
    string DSTAG   = FILETAG;
    if (FILETAG.size()) {
      DSTAG.erase(DSTAG.find("_"));
    } else {
      cout << "[ERROR] FILETAG is empty!" << endl;
    }
    // Extract the filenames
    vector<string> InputFileNames = FileCollection->second; 
    string         OutputFileName;
    // If we have data, check if the user wants to fit data
    if ( (FILETAG.find("DATA")!=std::string::npos) && fitData==true ) {
      if ( (FILETAG.find("PP")!=std::string::npos)   && !fitPP   ) continue; // If we find PP, check if the user wants PP
      if ( (FILETAG.find("PbPb")!=std::string::npos) && !fitPbPb ) continue; // If we find PbPb, check if the user wants PbPb
      OutputFileName = DIR["dataset"] + "DATASET_" + FILETAG + ".root";
      if(!tree2DataSet(Workspace[DSTAG], InputFileNames, FILETAG, OutputFileName)){ return; }
      if (!aDSTAG->FindObject(DSTAG.c_str())) aDSTAG->Add(new TObjString(DSTAG.c_str()));
    }
    // If we find MC, check if the user wants to fit MC
    if ( (FILETAG.find("MC")!=std::string::npos) && fitData==false ) {
      if ( (FILETAG.find("PP")!=std::string::npos)    && !fitPP    ) continue; // If we find PP, check if the user wants PP
      if ( (FILETAG.find("PbPb")!=std::string::npos)  && !fitPbPb  ) continue; // If we find PbPb, check if the user wants PbPb
      if ( (FILETAG.find("JPSI")!=std::string::npos)  && !incJpsi  ) continue; // If we find Jpsi MC, check if the user wants to include Jpsi
      if ( (FILETAG.find("PSI2S")!=std::string::npos) && !incPsi2S ) continue; // If we find Psi2S MC, check if the user wants to include Psi2S
      OutputFileName = DIR["dataset"] + "DATASET_" + FILETAG + ".root";
      if(!tree2DataSet(Workspace[DSTAG], InputFileNames, FILETAG, OutputFileName)){ return; }
      if (!aDSTAG->FindObject(DSTAG.c_str())) aDSTAG->Add(new TObjString(DSTAG.c_str()));
      if (wantPureSMC)
      {
        OutputFileName = DIR["dataset"] + "DATASET_" + FILETAG + "_PureS" + ".root";
        if(!tree2DataSet(Workspace[Form("%s_PureS",DSTAG.c_str())], InputFileNames, FILETAG, OutputFileName)){ return; }
      }
    } 
  }
  if (Workspace.size()==0) {
    cout << "[ERROR] No onia tree files were found matching the user's input settings!" << endl; return;
  }

  // -------------------------------------------------------------------------------
  // STEP 2: LOAD THE INITIAL PARAMETERS
  /*
    Input : List of initial parameters with format PT <tab> RAP <tab> CEN <tab> iniPar ... 
    Output: two vectors with one entry per kinematic bin filled with the cuts and initial parameters
  */
  
  string InputFile;
  vector< struct KinCuts >       cutVector;
  vector< map<string, string> >  parIniVector;
 
  if (fitPbPb && incBkg) {
    // Add initial parameters for PbPb background models
    InputFile = (DIR["input"] + "InitialParam_MASS_BKG_PbPb.csv");
    if (!addParameters(InputFile, cutVector, parIniVector, true)) { return; }
  } 
  if (fitPbPb && incJpsi) {
    // Add initial parameters for PbPb jpsi models
    InputFile = (DIR["input"] + "InitialParam_MASS_JPSI_PbPb.csv");
    if (!addParameters(InputFile, cutVector, parIniVector, true)) { return; }
  } 
  if (fitPbPb && incPsi2S) {
    // Add initial parameters for PbPb psi(2S) models
    InputFile = (DIR["input"] + "InitialParam_MASS_PSI2S_PbPb.csv");
    if (!addParameters(InputFile, cutVector, parIniVector, true)) { return; }
  } 
  if (fitPP && incBkg) {
    // Add initial parameters for PP background models
    InputFile = (DIR["input"] + "InitialParam_MASS_BKG_PP.csv");
    if (!addParameters(InputFile, cutVector, parIniVector, false)) { return; }
  } 
  if (fitPP && incJpsi) {
    // Add initial parameters for PP jpsi models
    InputFile = (DIR["input"] + "InitialParam_MASS_JPSI_PP.csv");
    if (!addParameters(InputFile, cutVector, parIniVector, false)) { return; }
  } 
  if (fitPP && incPsi2S) {
    // Add initial parameters for PP psi(2S) models
    InputFile = (DIR["input"] + "InitialParam_MASS_PSI2S_PP.csv");
    if (!addParameters(InputFile, cutVector, parIniVector, false)) { return; }
  }

  // -------------------------------------------------------------------------------  
  // STEP 3: FIT THE DATASETS
  /*
    Input : 
              -> The cuts and initial parameters per kinematic bin
	      -> The workspace with the full datasets included.
    Output: 
              -> Plots (png, pdf and root format) of each fit.
	      -> The local workspace used for each fit.
  */
  
  TIter nextDSTAG(aDSTAG);
  string outputDir = DIR["output"];
  for (unsigned int i=0; i<cutVector.size(); i++) {

    nextDSTAG.Reset();
    TObjString* soDSTAG(0x0);
    while ( (soDSTAG = static_cast<TObjString*>(nextDSTAG.Next())) )
    {
      TString DSTAG   = static_cast<TString>(soDSTAG->GetString());
      
      if (Workspace.count(DSTAG.Data())>0) {
        // DATA/MC datasets were loaded
        if (doSimulFit) {
          // If do simultaneous fits, then just fits once
          if (!fitCharmonia( Workspace[DSTAG.Data()], cutVector.at(i), parIniVector.at(i), outputDir,
                             // Select the type of datasets to fit
                             DSTAG.Data(),
                             false,           // dummy flag when fitting simultaneously since both PP and PbPb are used
                             // Select the type of object to fit
                             incJpsi,         // Includes Jpsi model
                             incPsi2S,        // Includes Psi(2S) model
                             incBkg,          // Includes Background model
                             // Select the fitting options
                             cutCtau,         // Apply prompt ctau cuts
                             true,            // Do simultaneous fit
                             wantPureSMC,     // Flag to indicate if we want to fit pure signal MC
                             numCores,        // Number of cores used for fitting
                             // Select the drawing options
                             setLogScale,     // Draw plot with log scale
                             incSS,           // Include Same Sign data
                             zoomPsi,         // Zoom Psi(2S) peak on extra pad
                             nBins,           // Number of bins used for plotting
                             false            // Compute the mean PT (NEED TO FIX)
                             )
              ) { return; }
        } else {
          // If don't want simultaneous fits, then fit PbPb or PP separately
          if ( DSTAG.Contains("MCJPSI")  ) { incJpsi = true;  incPsi2S = false; }
          if ( DSTAG.Contains("MCPSI2S") ) { incJpsi = false; incPsi2S = true;  }
            
          if (fitPbPb) {
            if (!fitCharmonia( Workspace[DSTAG.Data()], cutVector.at(i), parIniVector.at(i), outputDir,
                               // Select the type of datasets to fit
                               DSTAG.Data(),
                               true,            // In this case we are fitting PbPb
                               // Select the type of object to fit
                               incJpsi,         // Includes Jpsi model
                               incPsi2S,        // Includes Psi(2S) model
                               incBkg,          // Includes Background model
                               // Select the fitting options
                               cutCtau,         // Apply prompt ctau cuts
                               false,           // Do simultaneous fit
                               false,     // Flag to indicate if we want to fit pure signal MC
                               numCores,        // Number of cores used for fitting
                               // Select the drawing options
                               setLogScale,     // Draw plot with log scale
                               incSS,           // Include Same Sign data
                               zoomPsi,         // Zoom Psi(2S) peak on extra pad
                               nBins,           // Number of bins used for plotting
                               false            // Compute the mean PT (NEED TO FIX)
                               )
                ) { return; }
            if (DSTAG.Contains("MC") && wantPureSMC)
            {
              if (!fitCharmonia( Workspace[Form("%s_PureS",DSTAG.Data())], cutVector.at(i), parIniVector.at(i), outputDir,
                                // Select the type of datasets to fit
                                DSTAG.Data(),
                                true,            // In this case we are fitting PbPb
                                // Select the type of object to fit
                                incJpsi,         // Includes Jpsi model
                                incPsi2S,        // Includes Psi(2S) model
                                incBkg,          // Includes Background model
                                // Select the fitting options
                                cutCtau,         // Apply prompt ctau cuts
                                false,           // Do simultaneous fit
                                true,            // Flag to indicate if we want to fit pure signal MC
                                numCores,        // Number of cores used for fitting
                                // Select the drawing options
                                setLogScale,     // Draw plot with log scale
                                incSS,           // Include Same Sign data
                                zoomPsi,         // Zoom Psi(2S) peak on extra pad
                                nBins,           // Number of bins used for plotting
                                false            // Compute the mean PT (NEED TO FIX)
                                )
                  ) { return; }
            }
          }
          if (fitPP) {
            if (!fitCharmonia( Workspace[DSTAG.Data()], cutVector.at(i), parIniVector.at(i), outputDir,
                               // Select the type of datasets to fit
                               DSTAG.Data(),
                               false,           // In this case we are fitting PP
                               // Select the type of object to fit
                               incJpsi,         // Includes Jpsi model
                               incPsi2S,        // Includes Psi(2S) model
                               incBkg,          // Includes Background model
                               // Select the fitting options
                               cutCtau,         // Apply prompt ctau cuts
                               false,           // Do simultaneous fit
                               false,           // Flag to indicate if we want to fit pure signal MC
                               numCores,        // Number of cores used for fitting
                               // Select the drawing options
                               setLogScale,     // Draw plot with log scale
                               incSS,           // Include Same Sign data
                               zoomPsi,         // Zoom Psi(2S) peak on extra pad
                               nBins,           // Number of bins used for plotting
                               false            // Compute the mean PT (NEED TO FIX)
                               )
                ) { return; }
            if (DSTAG.Contains("MC") && wantPureSMC)
            {
              if (!fitCharmonia( Workspace[Form("%s_PureS",DSTAG.Data())], cutVector.at(i), parIniVector.at(i), outputDir,
                                // Select the type of datasets to fit
                                DSTAG.Data(),
                                false,           // In this case we are fitting PP
                                // Select the type of object to fit
                                incJpsi,         // Includes Jpsi model
                                incPsi2S,        // Includes Psi(2S) model
                                incBkg,          // Includes Background model
                                // Select the fitting options
                                cutCtau,         // Apply prompt ctau cuts
                                false,           // Do simultaneous fit
                                true,            // Flag to indicate if we want to fit pure signal MC
                                numCores,        // Number of cores used for fitting
                                // Select the drawing options
                                setLogScale,     // Draw plot with log scale
                                incSS,           // Include Same Sign data
                                zoomPsi,         // Zoom Psi(2S) peak on extra pad
                                nBins,           // Number of bins used for plotting
                                false            // Compute the mean PT (NEED TO FIX)
                                )
                  ) { return; }
            }
          }
        }
      } else {
        cout << "[ERROR] The workspace for " << DSTAG.Data() << " was not found!" << endl; return;
      }  
    }
  }
  
  delete aDSTAG;
};