コード例 #1
0
ファイル: generateWeights.cpp プロジェクト: soulish/NCAA_C
int main(int argc,char *argv[]) {
    int c;
    bool writeOutput = false;
    std::string outFileName = "";
    std::vector<std::string> years;
    std::string inYears = "";
    int numIterations = 1;
    int outYear = 0;
    bool useSeededValues = false;
    std::string seededLocation = "";
    bool zeroSRS = false;
    /*____________________________Parse Command Line___________________________*/
    while ((c = getopt(argc, argv, "y:Y:o:i:S:zh")) != -1) {
        switch (c) {
            case 'y':
                inYears.assign(optarg);
                boost::split(years, inYears, boost::is_any_of(","));
                break;
            case 'Y':
                outYear = atoi(optarg);
                break;
            case 'o':
                outFileName.assign(optarg);
                writeOutput = true;
                break;
            case 'i':
                numIterations = atoi(optarg);
                break;
            case 'S':
                useSeededValues = true;
                seededLocation.assign(optarg);
                break;
            case 'z':
                zeroSRS = true;
                break;
            case 'h':
                printOptions();
                return 0;
            default:
                // not an option
                break;
        }
    }

    //ensure years and outYear are set
    if (years.empty()) {
        std::cout << "You must set the input years using the -y switch and a comma-separated list of years" <<
        std::endl;
        printOptions();
        return 0;
    }
    if (outYear == 0) {
        std::cout << "You must set the output year using the -Y switch" << std::endl;
        printOptions();
        return 0;
    }

    char *homePath, path[256];
    homePath = getenv("HOME");

    //read in the necessary constants
    sprintf(path, "%s/cpp/NCAA_C/constants/waverage_standard_deviations.d", homePath);
    ConstantStandardDeviations *stdDevs = ConstantStandardDeviations::Instance();
    stdDevs->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/season_info.d", homePath);
    ConstantSeasonInfo *seasonInfo = ConstantSeasonInfo::Instance();
    seasonInfo->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/waverage_functions.d", homePath);
    ConstantWAverageFunctions *functions = ConstantWAverageFunctions::Instance();
    functions->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/team_neutral_ratios.d", homePath);
    ConstantTeamNeutralRatios *ratios = ConstantTeamNeutralRatios::Instance();
    ratios->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/srs_additions.d", homePath);
    ConstantSRSadditions *additions = ConstantSRSadditions::Instance();
    additions->initialize(path);

    //read in the game and waverage info
    for (std::string &year : years) {
        sprintf(path, "%s/cpp/NCAA_C/teams/%s/", homePath, year.c_str());
        std::cout << "Reading in games and waverages for " << year << std::endl;
        readTeamsFromDir(path);
        readTeamsFromDir(path, "waverages");
    }

    std::unordered_map<std::string, Team*> teams = Team::getTeams();
    std::unordered_map<std::string, TeamGame*> games;
    Team *opp;
    TeamWAverage *wa1, *wa2;
    int totalGames = 0;

    for (auto &team : teams) {
        games = team.second->getGamesByDate();
        for (auto &game : games) {
            if (team.first < game.second->getOpp()) continue; //look at each game only once
            opp = Team::findTeam(game.second->getOpp());
            if (!opp) continue;
            if (game.second->getDate() >= seasonInfo->get(team.second->getYear(), "tournament start")) continue;
            if (game.second->getDate().month().as_number() == 11) continue;

            totalGames++;

            wa1 = team.second->WAverageOnDate(game.second->getDate());
            wa2 = opp->WAverageOnDate(game.second->getDate());

            std::string loc = game.second->getLoc();
            std::string oppLoc = game.second->getOppLoc();

            std::unordered_map<std::string, double> predictions1 = functions->predictStats(wa1, wa2, outYear);
            std::unordered_map<std::string, double> predictions2 = functions->predictStats(wa2, wa1, outYear);

            win.push_back(game.second->getWin());
            oor.push_back((predictions1["oor.p"] * wa1->getValue("oor.p") / ratios->get(outYear,loc,"oor.p") -
                           predictions2["oor.p"] * wa2->getValue("oor.p") / ratios->get(outYear,oppLoc,"oor.p")) /
                          stdDevs->get(outYear,"oor.p"));

            oefg.push_back((predictions1["oefg.p"] * wa1->getValue("oefg.p") / ratios->get(outYear,loc,"oefg.p") -
                            predictions2["oefg.p"] * wa2->getValue("oefg.p") / ratios->get(outYear,oppLoc,"oefg.p")) /
                           stdDevs->get(outYear,"oefg.p"));

            oftmr.push_back((predictions1["oftmr.p"] * wa1->getValue("oftmr.p") / ratios->get(outYear,loc,"oftmr.p") -
                             predictions2["oftmr.p"] * wa2->getValue("oftmr.p") / ratios->get(outYear,oppLoc,"oftmr.p")) /
                            stdDevs->get(outYear,"oftmr.p"));

            //This guy is reversed because turnovers are bad.
            oto.push_back((-predictions1["oto.p"] * wa1->getValue("oto.p") / ratios->get(outYear,loc,"oto.p") +
                           predictions2["oto.p"] * wa2->getValue("oto.p") / ratios->get(outYear,oppLoc,"oto.p")) /
                          stdDevs->get(outYear,"oto.p"));

            srs.push_back((wa1->getSrs() - wa2->getSrs()) / stdDevs->get(outYear,"srs")); //removed additions
        }
    }

    std::cout << "Total number of games to analyze: " << totalGames << std::endl;

    std::vector<double> temp_ary, temp_ary2;
    std::vector<double> fcn_mins;
    std::vector< std::vector<double>*> params_ary;

    if (!useSeededValues) {
        //random number generator, using Mersenne Twister method
        //the 0 means we use a unique seed each time
        TRandom3 rand(0);

        for (int i = 0; i < numIterations; i++) {
            double randoms[5];
            rand.RndmArray(5, randoms);

            if (zeroSRS)
                temp_ary = run_fit(randoms[0], randoms[1], randoms[2], randoms[3], 0);
            else
                temp_ary = run_fit(randoms[0], randoms[1], randoms[2], randoms[3], randoms[4]);

            double temp_fcn_min = temp_ary.back();
            double temp_fcn_min2;

            double temp_norm = 0;
            int num_times_through = 0;
            for (int k = 0; k < 100; k++) {
                num_times_through++;
                temp_ary2 = run_fit(temp_ary[0], temp_ary[1], temp_ary[2], temp_ary[3], temp_ary[4]);
                temp_fcn_min2 = temp_ary2.back();
                if (temp_fcn_min2 == temp_fcn_min && temp_ary == temp_ary2) break;

                temp_ary = temp_ary2;
                temp_fcn_min = temp_fcn_min2;
            }

            fcn_mins.push_back(temp_fcn_min);
            params_ary.push_back(new std::vector<double>());
            for (int ii = 0; ii < temp_ary.size(); ii++)
                params_ary.back()->push_back(temp_ary[ii]);

            int indexOfMin = indexOfVectorMin(fcn_mins);
            std::cout << "  " << i << "\t" << doubleFormatter(fcn_mins.back(), 4) << "\t" <<
            doubleFormatter(fcn_mins[indexOfMin], 4) << "\t" << indexOfMin << "\r";
            fflush(stdout);
//            std::cout << "  \t\t" << i << "\t" << doubleFormatter(fcn_mins.back(), 4) << "\t" <<
//                  doubleFormatter(fcn_mins[indexOfMin], 4) << "\t" << indexOfMin << std::endl;
//            temp_norm = 0;
//            for (int ii = 0; ii < 5; ii++)
//                temp_norm += fabs(temp_ary[ii]);
//            for (int ii = 0; ii < 5; ii++){
//                std::cout << "  " << ii << "\t" << doubleFormatter(temp_ary[ii],4) << std::endl;
//            }
        }
    }
    else{
        sprintf(path, "%s/cpp/NCAA_C/%s", homePath, seededLocation.c_str());
        ConstantGameFunction *gameFunction = ConstantGameFunction::Instance();
        gameFunction->initialize(path);

        std::vector<int> keys = gameFunction->getKeys();
        for (int &year : keys){
            std::vector<double> initialValuesVec = gameFunction->getWeights(year);

            temp_ary = run_fit(initialValuesVec[0],initialValuesVec[1],initialValuesVec[2],
                               initialValuesVec[3],initialValuesVec[4]);

            double temp_fcn_min = temp_ary.back();
            double temp_fcn_min2;

            double temp_norm = 0;
            int num_times_through = 0;
            for (int k = 0; k < 100; k++) {
                num_times_through++;
                temp_ary2 = run_fit(temp_ary[0], temp_ary[1], temp_ary[2], temp_ary[3], temp_ary[4]);
                temp_fcn_min2 = temp_ary2.back();
                if (temp_fcn_min2 == temp_fcn_min && temp_ary == temp_ary2) break;

                temp_ary = temp_ary2;
                temp_fcn_min = temp_fcn_min2;
            }

            fcn_mins.push_back(temp_fcn_min);
            params_ary.push_back(new std::vector<double>());
            for (int ii = 0; ii < temp_ary.size(); ii++)
                params_ary.back()->push_back(temp_ary[ii]);

            int indexOfMin = indexOfVectorMin(fcn_mins);
            std::cout << "  " << year << "\t" << doubleFormatter(fcn_mins.back(), 4) << "\t" <<
            doubleFormatter(fcn_mins[indexOfMin], 4) << "\t" << indexOfMin << std::endl;
        }
    }

    std::cout << "\n\n\nFinal Results";
    int indexOfMin = indexOfVectorMin(fcn_mins);
    double norm = 0;
    for (int i = 0; i < 5; i++)
        norm += fabs(params_ary[indexOfMin]->at(i));

    std::cout << "Minimum = " << doubleFormatter(fcn_mins[indexOfMin],4) << std::endl;
    for (int i = 0; i < 5; i++)
        std::cout << i << "\t" << doubleFormatter(params_ary[indexOfMin]->at(i) / norm, 4) << std::endl;

    if (writeOutput) {
        sprintf(path, "%s/cpp/NCAA_C/constants/%s", homePath, outFileName.c_str());
        std::ofstream outFile(path, std::ios::app);
        outFile << outYear;
        for (int i = 0; i < 5; i++)
            outFile << "," << doubleFormatter(params_ary[indexOfMin]->at(i) / norm, 4);
        outFile << "," << doubleFormatter(params_ary[indexOfMin]->at(5), 4);
        outFile << std::endl;
        outFile.close();
    }

    return 0;
}
コード例 #2
0
int main(int argc,char *argv[]) {
    int c;
    std::vector<std::string> years;
    std::string inYears = "";
    int numIterations = 1;
    std::string outFileName = "";
    bool writeOutput = false;
    int outYear = 0;

    /*____________________________Parse Command Line___________________________*/
    while ((c = getopt(argc, argv, "y:Y:i:o:h")) != -1) {
        switch (c) {
            case 'y':
                inYears.assign(optarg);
                boost::split(years, inYears, boost::is_any_of(","));
                break;
            case 'Y':
                outYear = atoi(optarg);
                break;
            case 'i':
                numIterations = atoi(optarg);
                break;
            case 'o':
                outFileName.assign(optarg);
                writeOutput = true;
                break;
            case 'h':
                printOptions();
                return 0;
            default:
                // not an option
                break;
        }
    }

    //ensure years and outYear are set
    if (years.empty()) {
        std::cout << "You must set the input years using the -y switch and a comma-separated list of years" <<
        std::endl;
        printOptions();
        return 0;
    }
    if (outYear == 0) {
        std::cout << "You must set the output year using the -Y switch" << std::endl;
        printOptions();
        return 0;
    }

    char *homePath, path[256];
    homePath = getenv("HOME");

    //read in the necessary constants
    sprintf(path, "%s/cpp/NCAA_C/constants/season_info.d", homePath);
    ConstantSeasonInfo *seasonInfo = ConstantSeasonInfo::Instance();
    seasonInfo->initialize(path);

    //read in the game and waverage info
    for (std::string &year : years) {
        sprintf(path, "%s/cpp/NCAA_C/teams/%s/", homePath, year.c_str());
        std::cout << "Reading in games and waverages for " << year << std::endl;
        readTeamsFromDir(path);
        readTeamsFromDir(path, "waverages");
    }

    std::unordered_map<std::string, Team*> teams = Team::getTeams();
    std::unordered_map<std::string, TeamGame*> games;
    Team *opp;
    TeamWAverage *wa1, *wa2;
    int totalGames = 0;

    std::cout << "Processing Games" << std::endl;
    for (auto &team : teams) {
        games = team.second->getGamesByDate();
        for (auto &game : games) {
            if (team.first < game.second->getOpp()) continue; //look at each game only once
            opp = Team::findTeam(game.second->getOpp());
            if (!opp) continue;
            if (game.second->getDate() >= seasonInfo->get(team.second->getYear(), "tournament start")) continue;
            if (game.second->getDate().month().as_number() == 11) continue;

            totalGames++;

            wa1 = team.second->WAverageOnDate(game.second->getDate());
            wa2 = opp->WAverageOnDate(game.second->getDate());

            int loc = 0;
            if (game.second->getLoc() == "home") loc = 1;
            else if (game.second->getLoc() == "away") loc = -1;

            win.push_back(game.second->getWin());
            location.push_back(loc);
            srs.push_back((wa1->getSrs() - wa2->getSrs()));
        }
    }

    std::cout << "Total number of games to analyze: " << totalGames << std::endl;

    std::vector<double> temp_ary, temp_ary2;
    std::vector<double> fcn_min;
    std::vector< std::vector<double>*> params_ary;

    //random number generator, using Mersenne Twister method
    //the 0 means we use a unique seed each time
    TRandom3 rand(0);

    for (int i = 0; i < numIterations; i++){
        temp_ary = run_fit(rand.Rndm()*40 - 20);//random number between -20 and 20

        double temp_fcn_min = temp_ary.back();
        double temp_fcn_min2;

        int num_times_through = 0;
        for (int k = 0; k < 100; k++){
            num_times_through++;
            temp_ary2 = run_fit(temp_ary[0]);
            temp_fcn_min2 = temp_ary2.back();
            if (temp_fcn_min2 == temp_fcn_min && temp_ary == temp_ary2) break;

            temp_ary = temp_ary2;
            temp_fcn_min = temp_fcn_min2;
        }

        fcn_min.push_back(temp_fcn_min);
        params_ary.push_back(new std::vector<double>());
        for (int ii = 0; ii < temp_ary.size(); ii++)
            params_ary.back()->push_back(temp_ary[ii]);

        int indexOfMin = indexOfVectorMin(fcn_min);
        std::cout << "  " << i << "\t" << doubleFormatter(fcn_min.back(), 4) << "\t" <<
        doubleFormatter(fcn_min[indexOfMin], 4) << "\t" << indexOfMin << "\r";
        fflush(stdout);
    }

    int indexOfMin = indexOfVectorMin(fcn_min);
    std::cout << indexOfMin << "\t" << fcn_min[indexOfMin] << "\t" <<
            params_ary[indexOfMin]->at(0) << std::endl;

    if (writeOutput) {
        sprintf(path, "%s/cpp/NCAA_C/constants/%s", homePath, outFileName.c_str());
        std::ofstream outFile(path, std::ios::app);
        outFile << outYear << "," << doubleFormatter(params_ary[indexOfMin]->at(0), 2) << "," <<
                doubleFormatter(params_ary[indexOfMin]->at(1), 4) << std::endl;
        outFile.close();
    }

    return 0;
}
コード例 #3
0
int main(int argc,char *argv[]) {
    int c;
    std::string outFileName = "";
    std::vector<std::string> years;
    std::string inYears = "";
    std::string srsValue = "free";
    /*____________________________Parse Command Line___________________________*/
    while ((c = getopt(argc, argv, "y:o:s:h")) != -1) {
        switch (c) {
            case 'y':
                inYears.assign(optarg);
                boost::split(years, inYears, boost::is_any_of(","));
                break;
            case 'o':
                outFileName.assign(optarg);
                break;
            case 's':
                srsValue.assign(optarg);
                break;
            case 'h':
                printOptions();
                return 0;
            default:
                // not an option
                break;
        }
    }

    //ensure years and outYear are set
    if (years.empty()) {
        std::cout << "You must set the input years using the -y switch and a comma-separated list of years" <<
        std::endl;
        printOptions();
        return 0;
    }
    if (outFileName == ""){
        std::cout << "You must set the output file name using the -o switch" << std::endl;
        printOptions();
        return 0;
    }

    char *homePath, path[256];
    homePath = getenv("HOME");

    //read in the necessary constants
    sprintf(path, "%s/cpp/NCAA_C/constants/waverage_standard_deviations.d", homePath);
    ConstantStandardDeviations *stdDevs = ConstantStandardDeviations::Instance();
    stdDevs->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/season_info.d", homePath);
    ConstantSeasonInfo *seasonInfo = ConstantSeasonInfo::Instance();
    seasonInfo->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/waverage_functions.d", homePath);
    ConstantWAverageFunctions *functions = ConstantWAverageFunctions::Instance();
    functions->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/team_neutral_ratios.d", homePath);
    ConstantTeamNeutralRatios *ratios = ConstantTeamNeutralRatios::Instance();
    ratios->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/srs_additions.d", homePath);
    ConstantSRSadditions *additions = ConstantSRSadditions::Instance();
    additions->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/game_function_weights.%s.d", homePath,srsValue.c_str());
    ConstantGameFunction *gameFunction = ConstantGameFunction::Instance();
    gameFunction->initialize(path);

    //read in the game and waverage info
    for (std::string &year : years) {
        sprintf(path, "%s/cpp/NCAA_C/teams/%s/", homePath, year.c_str());
        std::cout << "Reading in games and waverages for " << year << std::endl;
        readTeamsFromDir(path);
        readTeamsFromDir(path, "waverages");
    }

    std::unordered_map<std::string, Team *> teams = Team::getTeams();
    std::unordered_map<std::string, TeamGame *> games;
    Team *opp;
    TeamWAverage *wa1, *wa2;

    TFile file(("rootFiles/"+outFileName).c_str(),"RECREATE");

    std::unordered_map<int, TH1F*> hists_gameScore_wins, hists_gameScore_losses;
    for (int year = 2007; year <= 2016; year++) {
        sprintf(path,"hist_gameScore_wins_%d",year);
        hists_gameScore_wins.emplace(year, new TH1F(path,"",200,-3,3));
        sprintf(path,"hist_gameScore_losses_%d",year);
        hists_gameScore_losses.emplace(year, new TH1F(path,"",200,-3,3));
    }

    for (auto &team : teams) {
        games = team.second->getGamesByDate();
        for (auto &game : games) {
            if (team.first < game.second->getOpp()) continue; //look at each game only once
            opp = Team::findTeam(game.second->getOpp());
            if (!opp) continue;
            if (game.second->getDate() >= seasonInfo->get(team.second->getYear(), "tournament start")) continue;
            if (game.second->getDate().month().as_number() == 11) continue;

            bool win = game.second->getWin() == 1;
            int gameYear = team.second->getYear();

            wa1 = team.second->WAverageOnDate(game.second->getDate());
            wa2 = opp->WAverageOnDate(game.second->getDate());

            std::string loc = game.second->getLoc();
            std::string oppLoc = game.second->getOppLoc();

            std::unordered_map<int, double> gameScoreByYear;

            switch (gameYear){
                case 2005:
                    for (int y = 2007; y <= 2010; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2006:
                    for (int y = 2007; y <= 2011; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2007:
                    for (int y = 2008; y <= 2012; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2008:
                    for (int y = 2009; y <= 2013; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2009:
                    for (int y = 2010; y <= 2014; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2010:
                    for (int y = 2011; y <= 2015; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2011:
                    for (int y = 2012; y <= 2016; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2012:
                    for (int y = 2013; y <= 2016; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2013:
                    for (int y = 2014; y <= 2016; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2014:
                    for (int y = 2015; y <= 2016; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
                case 2015:
                    for (int y = 2016; y <= 2016; y++)
                        gameScoreByYear.emplace(y, gameFunction->predictGame(wa1,wa2,y,loc,oppLoc));
                    break;
            }
            if (win){
                for (int y = 2007; y <= 2016; y++){
                    if (gameScoreByYear.find(y) == gameScoreByYear.end()) continue;
                    hists_gameScore_wins[y]->Fill(gameScoreByYear[y]);
                    hists_gameScore_losses[y]->Fill(-gameScoreByYear[y]);
                }
            }
            else{
                for (int y = 2007; y <= 2016; y++){
                    if (gameScoreByYear.find(y) == gameScoreByYear.end()) continue;
                    hists_gameScore_wins[y]->Fill(-gameScoreByYear[y]);
                    hists_gameScore_losses[y]->Fill(gameScoreByYear[y]);
                }
            }
        }
    }

    TF1 *fnWins = new TF1("fnWins","gaus");
    TF1 *fnLosses = new TF1("fnLosses","gaus");

    std::unordered_map<int, TH1F*> hists_probs;
    std::unordered_map<int, TH1F*> hists_probs_err;

    for (int y = 2007; y <= 2016; y++){
        if (hists_gameScore_wins[y]->Integral() == 0) continue;
        hists_gameScore_wins[y]->Fit(fnWins,"q");
        hists_gameScore_losses[y]->Fit(fnLosses,"q");

        sprintf(path,"probs_by_year_%d",y);
        hists_probs.emplace(y, new TH1F(path,"",1600,-3,3));
        sprintf(path,"probs_err_by_year_%d",y);
        hists_probs_err.emplace(y, new TH1F(path,"",1600,-3,3));

        for (int i = 1; i < 1600; i++){
            double w = fnWins->Eval(-3+i*6/1600.0);
            double l = fnLosses->Eval(-3+i*6/1600.0);
            double p = 0;
            double e = 0;
            if (w != 0 && l != 0){
                p = w / (double)(w+l);
                e = sqrt(p*(1-p) / (w+l));
            }
            else if (w != 0 && l == 0){
                p = 1;
                e = 0.01;
            }
            else if (w == 0){
                p = 0;
                e = 0.01;
            }

            hists_probs[y]->SetBinContent(i,p);
            hists_probs_err[y]->SetBinContent(i,e);
        }
    }

    file.Write();
    file.Close();

    return 0;
}
コード例 #4
0
int main(int argc,char *argv[]) {
    int c;
    bool writeOutput = false;
    std::vector<std::string> years;
    std::string inYears = "";
    bool useHistogramsFile = false;
    std::string srsValue = "free";
    std::string outFileName = "";
    double sigmas = 3;
    int nbins = 33;
    std::string predictionDay = "";
    std::string endRangeDay = "";
    /*____________________________Parse Command Line___________________________*/
    while ((c = getopt(argc, argv, "y:HS:o:s:n:d:D:h")) != -1) {
        switch (c) {
            case 'y':
                inYears.assign(optarg);
                boost::split(years, inYears, boost::is_any_of(","));
                break;
            case 's':
                srsValue.assign(optarg);
                break;
            case 'H':
                useHistogramsFile = true;
                break;
            case 'o':
                outFileName = optarg;
                break;
            case 'S':
                sigmas = atof(optarg);
                break;
            case 'n':
                nbins = atoi(optarg);
                break;
            case 'd':
                predictionDay.assign(optarg);
                break;
            case 'D':
                endRangeDay.assign(optarg);
                break;
            case 'h':
                printOptions();
                return 0;
            default:
                // not an option
                break;
        }
    }

    //ensure years and outYear are set
    if (years.empty()) {
        std::cout << "You must set the input years using the -y switch and a comma-separated list of years" <<
        std::endl;
        printOptions();
        return 0;
    }

    boost::gregorian::date predictionDate;
    if (predictionDay != "")
        predictionDate = boost::gregorian::date(boost::gregorian::from_string(predictionDay));

    boost::gregorian::date endRangeDate;
    if (endRangeDay != ""){
        endRangeDate = boost::gregorian::date(boost::gregorian::from_string(endRangeDay));
        if (predictionDay == ""){
            std::cout << "If you enter an end date, you must also specify a start date" << std::endl;
            return 0;
        }
    }

    char *homePath, path[256];
    homePath = getenv("HOME");

    //read in the necessary constants
    sprintf(path, "%s/cpp/NCAA_C/constants/waverage_standard_deviations.d", homePath);
    ConstantStandardDeviations *stdDevs = ConstantStandardDeviations::Instance();
    stdDevs->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/season_info.d", homePath);
    ConstantSeasonInfo *seasonInfo = ConstantSeasonInfo::Instance();
    seasonInfo->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/waverage_functions.d", homePath);
    ConstantWAverageFunctions *functions = ConstantWAverageFunctions::Instance();
    functions->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/team_neutral_ratios.d", homePath);
    ConstantTeamNeutralRatios *ratios = ConstantTeamNeutralRatios::Instance();
    ratios->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/srs_additions.d", homePath);
    ConstantSRSadditions *additions = ConstantSRSadditions::Instance();
    additions->initialize(path);

    sprintf(path, "%s/cpp/NCAA_C/constants/game_function_weights.%s.d", homePath,srsValue.c_str());
    ConstantGameFunction *gameFunction = ConstantGameFunction::Instance();
    gameFunction->initialize(path);

    //read in the game and waverage info
    for (std::string &year : years) {
        sprintf(path, "%s/cpp/NCAA_C/teams/%s/", homePath, year.c_str());
        std::cout << "Reading in games and waverages for " << year << std::endl;
        readTeamsFromDir(path);
        readTeamsFromDir(path, "waverages");
    }

    TFile *histsFile;
    std::unordered_map<int, TH1F*> probs_by_year, probs_err_by_year;
    if (useHistogramsFile){
        sprintf(path, "%s/cpp/NCAA_C/rootFiles/gameFunctionHistograms.%s.root", homePath, srsValue.c_str());
        histsFile = new TFile(path);

        for (int y = 2007; y <= 2016; y++){
            sprintf(path, "probs_by_year_%d", y);
            probs_by_year.emplace(y, (TH1F*)gROOT->FindObject(path));
            sprintf(path, "probs_err_by_year_%d", y);
            probs_err_by_year.emplace(y, (TH1F*)gROOT->FindObject(path));
        }
    }

    std::unordered_map<std::string, Team *> teams = Team::getTeams();
    std::unordered_map<std::string, TeamGame *> games;
    Team *opp;
    TeamWAverage *wa1, *wa2;

    int gameScoreWins = 0, gameScoreTotal = 0;
    int gameScoreWinsSpread = 0, gameScoreTotalSpread = 0;
    int vegasWinsSpread = 0, vegasTotalSpread = 0;
    int adjGameScoreWins = 0, adjGameScoreTotal = 0;
    int unadjustedSrsWins = 0, unadjustedSrsTotal = 0;
    int srsWins = 0, srsTotal = 0;
    int srsWinsSpread = 0, srsTotalSpread = 0;

    int srsGameScoreWins = 0, srsGameScoreTotal = 0;
    int srsGameScoreWinsSpread = 0, srsGameScoreTotalSpread = 0;

    TFile *outFile;
    if (outFileName != "") {
        sprintf(path, "%s/cpp/NCAA_C/rootFiles/%s",homePath,outFileName.c_str());
        outFile = new TFile(path, "RECREATE");
    }

    TH1F *h_wins = new TH1F("h_wins","",nbins,0,1);
    TH1F *h_total = new TH1F("h_total","",nbins,0,1);
    TH2F *spread_vs_spread = new TH2F("spread_vs_spread","",80,-20,20,80,-20,20);
    TH2F *myspread_vs_pct = new TH2F("myspread_vs_pct","",100,0,1,80,-20,20);
    TH2F *myPct_vs_VegasPct = new TH2F("myPct_vs_VegasPct","",nbins,0,1,nbins,0,1);

    for (auto &team : teams) {
        games = team.second->getGamesByDate();
        for (auto &game : games) {
            //look only at games within a certain range
            if (predictionDay != ""){
                if (endRangeDay == ""){
                    if (predictionDate != game.second->getDate()) continue;
                }
                else{
                    if (game.second->getDate() < predictionDate || game.second->getDate() > endRangeDate) continue;
                }
            }
            else{
                if (game.second->getDate() >= seasonInfo->get(team.second->getYear(), "tournament start")) continue;
                if (game.second->getDate().month().as_number() == 11) continue;
            }
            if (team.first < game.second->getOpp()) continue; //look at each game only once
            opp = Team::findTeam(game.second->getOpp());
            if (!opp) continue;

            TeamGame *oppgame = opp->GameOnDate(game.second->getDate(),team.second->getName());

            bool win = game.second->getWin() == 1;
            double spread = game.second->getSpread();
            double mySpread;

            wa1 = team.second->WAverageOnDate(game.second->getDate());
            wa2 = opp->WAverageOnDate(game.second->getDate());

            std::string loc = game.second->getLoc();
            std::string oppLoc = game.second->getOppLoc();

            double gameScore = gameFunction->predictGame(wa1,wa2,team.second->getYear(),loc,oppLoc);
            if (gameScore >= 0 && win) gameScoreWins++;
            if (gameScore < 0 && !win) gameScoreWins++;
            gameScoreTotal++;

            double gameScorePct = -1;
            double gameScorePct_err = -1;

            double unadjustedSrsVal = wa1->getSrs() - wa2->getSrs();
            if (win && unadjustedSrsVal >= 0) unadjustedSrsWins++;
            if (!win && unadjustedSrsVal < 0) unadjustedSrsWins++;
            unadjustedSrsTotal++;

            double srsVal = wa1->getSrs() - wa2->getSrs() + additions->get(team.second->getYear(),loc);
            if (win && srsVal >= 0) srsWins++;
            if (!win && srsVal < 0) srsWins++;
            srsTotal++;

            if (gameScore >= 0 && srsVal >= 0){
                if (win) srsGameScoreWins++;
                srsGameScoreTotal++;
            }
            if (gameScore < 0 && srsVal < 0){
                if (!win) srsGameScoreWins++;
                srsGameScoreTotal++;
            }

            if (useHistogramsFile){
                if (gameScore >= 3){
                    gameScorePct = 1;
                    gameScorePct_err = 1;
                }
                else if (gameScore <= -3){
                    gameScorePct = 0;
                    gameScorePct_err = 1;
                }
                else{
                    gameScorePct = probs_by_year[team.second->getYear()]->GetBinContent((gameScore+3)*1600/6.0);
                    gameScorePct_err = probs_err_by_year[team.second->getYear()]->GetBinContent((gameScore+3)*1600/6.0);
                }

                if (gameScorePct >= 0.5 && gameScorePct - sigmas*gameScorePct_err >= 0.5 && win) adjGameScoreWins++;
                if (gameScorePct < 0.5 && gameScorePct + sigmas*gameScorePct_err < 0.5 && !win) adjGameScoreWins++;
                if ((gameScorePct >= 0.5 && gameScorePct - sigmas*gameScorePct_err >= 0.5) ||
                    (gameScorePct < 0.5 && gameScorePct + sigmas*gameScorePct_err < 0.5)) adjGameScoreTotal++;

                if (win) h_wins->Fill(gameScorePct);
                h_total->Fill(gameScorePct);

                if (spread != 0 && spread == -1*oppgame->getSpread()){
                    mySpread = pctToSpread(gameScorePct);
                    myspread_vs_pct->Fill(gameScorePct,mySpread);
                    spread_vs_spread->Fill(spread, mySpread);
                    myPct_vs_VegasPct->Fill(spreadToPct(spread),gameScorePct);
                }
            }

            if (spread != -1*oppgame->getSpread()) continue; //if the spreads are somehow messed up

            if (spread != 0){
                gameScoreTotalSpread++;
                if (gameScore > 0 && win) gameScoreWinsSpread++;
                if (gameScore < 0 && !win) gameScoreWinsSpread++;

                srsTotalSpread++;
                if (win && srsVal >= 0) srsWinsSpread++;
                if (!win && srsVal < 0) srsWinsSpread++;

                if (gameScore >= 0 && srsVal >= 0){
                    if (win) srsGameScoreWinsSpread++;
                    srsGameScoreTotalSpread++;
                }
                if (gameScore < 0 && srsVal < 0){
                    if (!win) srsGameScoreWinsSpread++;
                    srsGameScoreTotalSpread++;
                }

                vegasTotalSpread++;
                if (spread < 0 && win) vegasWinsSpread++;
                if (spread > 0 && !win) vegasWinsSpread++;
            }
        }
    }

    std::cout << "All Games" << std::endl;
    std::cout << "gameScore:\t\t" << gameScoreWins << " / " << gameScoreTotal << " = " <<
    doubleFormatter(gameScoreWins / (double) gameScoreTotal, 3) << std::endl;

    if (useHistogramsFile) {
        std::cout << "Games above sigma:\t" << adjGameScoreWins << " / " << adjGameScoreTotal << " = " <<
        doubleFormatter(adjGameScoreWins / (double) adjGameScoreTotal, 3) << std::endl;
    }

    std::cout << "Unadjusted SRS:\t\t" << unadjustedSrsWins << " / " << unadjustedSrsTotal << " = " <<
    doubleFormatter(unadjustedSrsWins / (double) unadjustedSrsTotal, 3) << std::endl;

    std::cout << "Adjusted SRS:\t\t" << srsWins << " / " << srsTotal << " = " <<
    doubleFormatter(srsWins / (double) srsTotal, 3) << std::endl;

    std::cout << "SRS, GameScore agree :\t" << srsGameScoreWins << " / " << srsGameScoreTotal << " = " <<
    doubleFormatter(srsGameScoreWins / (double) srsGameScoreTotal, 3) << std::endl;

    std::cout << std::endl;

    std::cout << "Games with a spread" << std::endl;
    std::cout << "Vegas:\t\t\t" << vegasWinsSpread << " / " << vegasTotalSpread << " = " <<
    doubleFormatter(vegasWinsSpread / (double) vegasTotalSpread,3) << std::endl;

    std::cout << "gameScore:\t\t" << gameScoreWinsSpread << " / " << gameScoreTotalSpread << " = " <<
    doubleFormatter(gameScoreWinsSpread / (double) gameScoreTotalSpread, 3) << std::endl;

    std::cout << "SRS:\t\t\t" << srsWinsSpread << " / " << srsTotalSpread << " = " <<
    doubleFormatter(srsWinsSpread / (double) srsTotalSpread, 3) << std::endl;

    std::cout << "SRS, GameScore agree :\t" << srsGameScoreWinsSpread << " / " << srsGameScoreTotalSpread << " = " <<
    doubleFormatter(srsGameScoreWinsSpread / (double) srsGameScoreTotalSpread, 3) << std::endl;

    if (outFileName != "") {
        outFile->Write();
        outFile->Close();
    }

    return 0;
}