function [NetCost] = main(c1Index)

    clc, close all
    cd('/home/atizawa/apps/Cost-Analysis-Model')
    delete(gcp('nocreate'))   % Always start a new pool
    %system('pgrep dmtcp | xargs kill -9');
    %ldLibs = strsplit(getenv('LD_LIBRARY_PATH'),':'); 
    %newPath = strjoin(['/usr/lib/x86_64-linux-gnu',ldLibs(3:end)],':');
    %setenv('LD_LIBRARY_PATH',newPath); % MATLAB uses old Linux libraries; update them.
    %delete(gcp('nocreate'))
    %pctconfig('hostname','redr.eng.hawaii.edu')

    addpath('/home/atizawa/apps/psopt')
    addpath('/home/atizawa/apps/mlep/MLE+/core')
    addpath('/home/atizawa/apps/mlep/MLE+')

    %% Main
    set(0,'DefaultFigureVisible','on')
    %[~,Tset] = genEPTset();  % Make a bunch of random points.
    %[date, cost] = importLambda();   % Import lambda for price data
    
    if nargin < 1
        error('Penalty factor not cited. Control this through the SLURM script on a per job basis.')
    end 
    
    %% OPTIONS
    % MODES
    %----------------------
    % 0 - Single run of Tset (usually for graphing)
    % 1 - Per-hour / daily optimization with PSO
    % 2 - Lumped dimension / multi-day optimization with PSO

    MODE = 2;  
    CALIB = 0;        % Do C1 calibration for this day? (Sets C1 = 1 w/ schedule override)
    numMultiDays = 7; % For MODE = 2: How many days to do? Change IDF to reflect this (Corbin mode)
                      % These days are always counted towards NetCost.
    testMODE2 = 0;    % Single Tset solution testing of MODE 2.
    
    c1Cell = {'1.7','1.9','2.1','2.3','2.5','2.7','2.9','3.2','5','10','20','30','40'};
    c1Cell = strcat(c1Cell,'e-3');
    %c1Str = '2.8e-3';
    c1Str = c1Cell{c1Index};
    
    month = 8; day = 1; year = 2012;
    baseIDF = 'RefBldgLargeOfficeNew2004_Chicago';
    nameIDF = ['RefBldgLargeOfficeNew2004_Chicago','_',c1Str];
    IDFdir = '/home/atizawa/lus/RefLargeOfficeBuilding/';
    histDir = '/home/atizawa/lus/Window_Shifting_Logs';

    DOSWEEP = 1;     % Do iteration?
    SWEEPMIN = 1;   SWEEPMAX = 31;  % Length of days after [month,day] to do
    TIMELIMIT = 2;  % Timelimit in HOURS to do each PSO
    DOY = 213;      % Pick this day of the year for lambdas (242: prechill) 312
    searchDir = '/home/atizawa/lus/Window_Shifting_Logs/';
    searchFile = ['TsetHistory_01-Aug-2012_to_31-Aug-2012_C1-',c1Str,'.csv']; % EXACT filename to restart with
    restartSimulation = 0; % Restart with searchname (yes/no)

    %----------------
    searchname = [searchDir,'/',searchFile];
    dateObj = datenum(year,month,day);

    if MODE ~= 2, testMODE2 = 0; end 
    if CALIB == 1, SWEEPMAX = 5; SWEEPMIN = 1; end % Requires exactly 5 iterations

    if restartSimulation == 0 % Create a new file.
        TsetHistory = 35*ones(1,14); 
        TsetHistory(9:13) = convtemp(75,'F','C')*ones(1,5);
        TsetHistory = repmat(TsetHistory,1,7);  
        %TsetHistory = kron([1:8],10.*ones(1,14));
        searchname = createTsetHistory(numMultiDays, TsetHistory,dateObj,c1Str,SWEEPMAX-1,DOY,historyDir); % First creation of log
    else
        if exist(searchname,'file') == 2 
            myCSV = read_mixed_csv(searchname,',');
            DOY = str2double(myCSV{end,end-2})+1;   % read the latest entries
            startDOY = str2double(myCSV{2,end-2});
            SWEEPMIN = 1; SWEEPMAX = SWEEPMAX - (DOY-startDOY);
            dateObj = addtodate(datenum(myCSV(end,1)),1,'day');  % Do the day AFTER
            disp(['SUCCESSFUL IMPORT: Restarting ' searchname ])
            disp(['Starting with [date,DOY] = [', datestr(dateObj), ',' num2str(DOY),'] (',num2str(SWEEPMAX),' iterations remaining)'])
            if SWEEPMAX == 0, disp('0 iterations left; terminating.'); return; end    
        else
            error(['FAILED IMPORT: File ' searchname ' does not exist, terminating.'])
        end
    end

    for iterator = SWEEPMIN:SWEEPMAX
    % =============================================
    % Declare Tset (MODE = 0 or MODE = 1)
    % =============================================

       % Format:
       % -----------
       % 1:8            - 12-8am, same setpoints for all zones
       % 9+11n:19+11n   - 9am-7pm, each of 5 zones gets a set. Occupied period.
       % end            - Remainder of unoccupied period. 

       Tset = [35*ones(1,8), convtemp(75,'F','C')*ones(1,11*5), 35];
   
    % =============================================
   
    if MODE == 2
    % =============================================
    % Declare Tset (MODE = 2)
    % =============================================
       % Format:
       % -----------
       % 1+14n:14+14n
       % For non-negative integer n: every set of 14 corresponds to one day's
       % worth of schedules. I intend to schedule 1 week of setpoints, so this
       % is 14*7 = 98 entries. First 12 are for the first 12 hours of the day;
       % 13 is the remainder of the occupied period, and 14 is the remainder of
       % the unoccipied period. 
        
        dateFormat = 'dd-mmm-yyyy';
        incrementEPfile(dateObj,numMultiDays,dateFormat,nameIDF,IDFdir,baseIDF)        % 1) Setup IDF file
    
        Tset = 35*ones(1,14); 
        Tset(9:13) = convtemp(72.5,'F','C')*ones(1,5);
       
        if iterator == SWEEPMIN
           % Seed PSO population
           %------------------------
           fprintf('Seeding PSO with pre-determined Tset policies.\n')
           initPSOpop(1,:) = Tset;                            % Default, "dumb"
           initPSOpop(2,:) = [Tset(1:3),20,19,Tset(6:end)];   % 3-5am chill
           initPSOpop(3,:) = [Tset(1:6),20,19,Tset(9:end)];   % 6-8am chill

           initPSOpop = repmat(initPSOpop,1,numMultiDays);    
           [Tset_Heu] = getHeuristic(Tset,DOY,numMultiDays);  % Extra heuristics
           initPSOpop = [initPSOpop;Tset_Heu];
           %------------------------
        end 
        Tset = repmat(Tset,1,numMultiDays);  % Replicate actual after replicating entire initial PSO population
       
        % Specify 120D solution below
        % Tset = initPSOpop(end-1,:)
        
        % Pull from CSV file of choice?
        % DayN = iterator; 
        % sheet = csvread([searchDir,'/',searchFile],1,1);
        %Tset = repmat(sheet(DayN+numMultiDays,1:14),1,numMultiDays);       
             
    % =============================================         
            

    end 
        
    dim = length(Tset); 
       
    %% Optimization
    % TolX: Temperature sensitivity. Next Tset vector must be all within 0.5C.
    % TolFun: Objective function tolerance. Must be within $2.00 to stop.
    % Default for both of these is 1e-4, and both must be satisifed.
                              
        if MODE == 1
             lb = 16.*ones(64,1); 
             ub = 32.*ones(64,1);
             ub(9:end-1) = 26*ones(1,55); % Upper bound: 24C
             lb(9:end-1) = 19*ones(1,55); % Lower bound: 22C       

             initPSOpop(1,:) = [35*ones(1,8), convtemp(75,'F','C')*ones(1,11*5), 35];  
             initPSOpop(2,:) = [35*ones(1,3),[20,19,35,35,35], convtemp(75,'F','C')*ones(1,11*5), 35]; 
             initPSOpop(3,:) = [35*ones(1,3),[35,35,35,20,19] convtemp(75,'F','C')*ones(1,11*5), 35]; 

             options = psooptimset('TolCon',0.5,'TolFun',0.5,'PopulationSize',40,'TimeLimit',3600*TIMELIMIT, ...
                              'UseParallel', 'always','Vectorized', 'off', 'PlotFcns',{@psoplotbestf}, ...
                              'CognitiveAttraction', 0.5, 'SocialAttraction', 1, 'StallGenLimit',25,...
                              'ConstrBoundary','reflect','InitialPopulation',initPSOpop); % reflect or penalize
             fclose('all');
             mainEPHandle = @(x)mainEP(x,1,0,DOY,numMultiDays,testMODE2,c1Str,searchname,dateObj,nameIDF); % MODE = 1 (do PSO) and no calibration. 
           %  [NetCost] = mainEP(Tset,MODE,CALIB,DOY,numMultiDays)
             [minTset, minCost,exitflag,output,population,scores] = pso(mainEPHandle,dim,[],[],[],[],lb,ub,[],options);
        elseif MODE == 2
            % First 12 correspond to first 12 hours of the day (midnight to noon).
            % 13 corresponds to the remainder of the occupied period (noon to 8pm).
            % 14 corresponds to the remainder of day 8pm to midnight).
            
            lowOccTemp = 19; highOccTemp = 27;  % OUR BOUNDS
            %lowOccTemp = 22; highOccTemp = 24;   % HIS BOUNDS
            
             lb = [16.*ones(14,1)]; 
             ub = [32.*ones(14,1)];
             ub(9:13) = highOccTemp*ones(5,1); % 8-noon + 6 lumped
             lb(9:13) = lowOccTemp*ones(5,1);   
             
             lb = repmat(lb,numMultiDays,1); % Replicate for all planned days
             ub = repmat(ub,numMultiDays,1);
             dim = 14*numMultiDays;

             if testMODE2 == 1;
                 [minCost,PelecTOTAL,PdiscTOTAL,WattTOTAL] = mainEP(Tset,2,CALIB,DOY,numMultiDays,testMODE2,c1Str,searchname,dateObj,nameIDF); 
                 appendNewDay(searchname,dateObj,dateFormat,Tset,PelecTOTAL,PdiscTOTAL,minCost,WattTOTAL,DOY)
             else
               % OLD PSO
               %-----------
               options = psooptimset('TolCon',0.5,'TolFun',1,'PopulationSize', 45,'TimeLimit',3600*TIMELIMIT, ... 
                              'UseParallel', 'always','Vectorized', 'off', 'PlotFcns',{@psoplotbestf}, ...
                              'CognitiveAttraction', 0.7, 'SocialAttraction', 1.2,'StallGenLimit',15, ...
                              'ConstrBoundary','reflect','InitialPopulation',initPSOpop); % reflect or penalize   
                fclose('all');
                mainEPHandle = @(x)mainEP(x,2,0,DOY,numMultiDays,testMODE2,c1Str,searchname,dateObj,nameIDF); % MODE = 1 (do PSO) and no calibration. 
                %[minTset, ~,exitflag,output,population,scores] = pso(mainEPHandle,dim,[],[],[],[],lb,ub,[],options);
                minTset = Tset; 
                % NEW PSO
                %------------
    %             mypool = parpool;
    %             newoptions = optimoptions('particleswarm','SelfAdjustment',0.7,'SocialAdjustment',1.2, ... 
    %                          'UseParallel',1,'TolFun',1,'MaxTime',3600*TIMELIMIT,'SwarmSize',50, ... 
    %                          'StallIterLimit',25,'InitialSwarm',initPSOpop);
    %             [minTset,fval,exitflag,output] = particleswarm(mainEPHandle,dim,lb,ub,newoptions);
    % 
                delete(gcp('nocreate'))  % Needs to be killed in order to restart EnergyPlus (recall the finite number of allowed repeats). 
                pause(5)
                
                % Call mainEP with the minTset, as if we were testing. Return
                % all parameters to write with. We should be reading the same
                % historical schedule, as we haven't written anything new yet.
                clearvars -global  % Clear iterations so we buffer the schedule again.
                system('pgrep energy | xargs kill -9');
                fclose('all'); 
                disp('Resimulating with the minimized Tset policy:')
                [minCost,PelecTOTAL,PdiscTOTAL,WattTOTAL] = mainEP(minTset,2,0,DOY,numMultiDays,1,c1Str, ...
                                                            searchname,dateObj,nameIDF); 

                % Append results; file writing
               appendNewDay(searchname,dateObj,dateFormat,minTset,PelecTOTAL,PdiscTOTAL,minCost,WattTOTAL,DOY)
               clearvars -global  % Need to totally clear out for a new PSO
               system('pgrep energy | xargs kill -9');
               fclose('all'); 
             end
             
            % Time to change the date -- increment in log AND in energyplus
            dateObj = addtodate(dateObj,1,'day');
            DOY = DOY +1;
            disp(['Finished writing new results to file at' searchname])                
        end 

        if MODE == 0
            [NetCost] = mainEP(Tset,MODE,CALIB,DOY,numMultiDays,c1Str,searchname,dateObj,nameIDF)
        end 
        
        if DOSWEEP ~= 1 || testMODE2 == 1 || MODE == 0
            fprintf('Breaking.\n'),break
        end  % Get outta here if we're not sweeping
        close all
    end  

    %% END
    clear iterator

    % Note FATAL ERROR results: ending before # of repeats as specified in IDF
    % gives a fatal error, but is intentional.

    set(0,'DefaultFigureVisible','on')          % Restore figure settings. 
    fclose('all'); 
    fprintf('Done with simulation. Optimization converged properly.\n')

    % Send me a text message
    %if MODE == 1 || (MODE == 2 && testMODE2 == 0)
      %  send_text_message('','att', ...
      %  'Tset PSO Completed',['Finished on REDR at ', datestr(clock)])
    %end 


end 
