#include "CreateFile_EPW.h"

//References:
//Shuttleworth, J. W. (1993). Evaporation. In D. R. Maidment (Ed.), Handbook of Hydrology (pp. 4.1-4.5.3). New York: McGraw-Hill.

//Create_EPW_file function initalizes ....
void CreateFile_EPW::Create_EPW_file(Inputs* input)
{
    //Note: Consider refactor header4 LeapYear and OpaqueSkyCover_MissingCode_99_tenths, SnowDepthOnGround_cm from Weather.csv
    //Note: Consider refactor header7 values timestepsperhour, start and stop data from HydroPlusConfig.xml and Weather.csv

    //outputDirectory = input->SimulationStringParams["OutputFolder_Path"]
    string outputDirectory = input->SimulationStringParams["OutputFolder_Path"];
    string path_EPW_Outputfile = outputDirectory + "/iTreeWeatherRadiation.epw";
    ofstream outputFile(path_EPW_Outputfile);

    if (!outputFile.is_open()) {
        cout << "Error: Cannot open output file " << path_EPW_Outputfile << ".\n" << endl;
        return;
    }
    //Month_DataRecord_Count dimensionalized as vector of 12 integers, set to 0
    vector<int> Month_DataRecord_Count(12, 0);
    //MonthlyAvgTair_C sized to 12 double values
    input->MonthlyAvgTair_C.resize(12, 0.0);

    string Place_Location = input->CoolBuildingStringParams["Place_Location"];
    string State_Location = input->CoolBuildingStringParams["State_Location"];
    string Country_Location = input->CoolBuildingStringParams["Country_Location"];
    string Latitude_Location = input->CoolBuildingStringParams["Latitude_Location"];
    string Longitude_Location = input->CoolBuildingStringParams["Longitude_Location"];
    string TimeZoneOffset_Location = input->CoolBuildingStringParams["TimeZoneOffset_Location"];
    string Elevation_Location = input->CoolBuildingStringParams["Elevation_Location"];
    string Prior_Fields = "PriorFields_City_State_Country";
    string Next_Fields = "NextFields_Latitude_DD_Longitude_DD_TimeZoneOffset_Hr_Elevation_m";
    // Header strings
    string header0 = "LOCATION," + Place_Location + "," + State_Location + "," + Country_Location + "," + Prior_Fields + "," + Next_Fields + "," + Latitude_Location + "," + Longitude_Location + "," + TimeZoneOffset_Location + "," + Elevation_Location;
    string header1 = "DESIGN CONDITIONS,0";
    string header2 = "TYPICAL/EXTREME PERIODS,0";
    string header3 = "GROUND TEMPERATURES,0";
    string header4 = "HOLIDAYS/DAYLIGHT SAVING,No,0,0,0";
    string header5 = "COMMENTS 1,HOLIDAYS/DAYLIGHT SAVING No vs Yes for designates if time series contains February 29 and is a Leap Year,DaylightSavingStartDate,DaylightSavingStopDate,NumberHolidays";
    string header6 = "COMMENTS 2, Year,Month,Day,Hour,Minute,DataSourceandUncertaintyFlags,DryBulbTemperature_°C,DewPointTemperature_°C,RelativeHumidity_%,AtmosphericStationPressure_Pa,ExtraterrestrialHorizontalRadiation_Wh/m²,ExtraterrestrialDirectNormalRadiation_Wh/m²,HorizontalInfraredRadiationIntensityfromSky_Wh/m²,GlobalHorizontalRadiation_Wh/m²,DirectNormalRadiation_Wh/m²,DiffuseHorizontalRadiation_Wh/m²,GlobalHorizontalIlluminance_lux,DirectNormalIlluminance_lux,DiffuseHorizontalIlluminance_lux,ZenithLuminance_Cd/m²,WindDirection_°,WindSpeed_m/s,TotalSkyCover_tenths,OpaqueSkyCover_tenths,Visibility_km,CeilingHeight_m,PresentWeatherObservation,PresentWeatherCodes,PrecipitableWater_mm,AerosolOpticalDepth_thousandths,SnowDepth_cm,DaysSinceLastSnowfall_days,Albedo_unitless,LiquidPrecipitationDepth_mm,LiquidPrecipitationQuantityPeriod_hr";
    string header7 = "DATA PERIODS,1,1,PriorFields_DataSets_TimeStepsPerHour_Comments2ContainsHeaderForDataColumnsBelow_NextFields_FirstDayOfWeek_StartDate_StopDate,Sunday,1/1,12/31";

    outputFile << header0 << '\n' << header1 << '\n' << header2 << '\n' << header3 << '\n' << header4 << '\n'
        << header5 << '\n' << header6 << '\n' << header7 << '\n';

    //DataSourceAndUncertaintyFlags_EPW_str defined using standard E+
    string DataSourceAndUncertaintyFlags_EPW_str = "A7A7A7A7*0?0?0?0?0?0?0?0A7A7A7A7A7A7F8F8A7E7";
    //ExtraterrestrialHorizontalRadiation_Wh/m² missing value 9999
    int ExtraterrestrialHorizontalRadiation_MissingCode_9999_Wh_p_m2 = 9999;
    //ExtraterrestrialDirectNormalRadiation_Wh/m² missing value 9999
    int ExtraterrestrialDirectNormalRadiation_MissingCode_9999_Wh_p_m2 = 9999;
    //HorizontalInfraredRadiationIntensityfromSky_Wh/m² missing value 9999
    int HorizontalInfraredRadiationIntensityfromSky_MissingCode_9999_Wh_p_m2 = 9999;
    //GlobalHorizontalRadiation_Wh/m² missing value 9999
    int GlobalHorizontalRadiation_MissingCode_9999_Wh_p_m2 = 9999;
    //GlobalHorizontalIlluminance_lux missing value 999999
    int GlobalHorizontalIlluminance_MissingCode_999999_lux = 999999;
    //DirectNormalIlluminance_lux missing value 999999
    int DirectNormalIlluminance_MissingCode_999999_lux = 999999;
    //DiffuseHorizontalIlluminance_lux missing value 999999
    int DiffuseHorizontalIlluminance_MissingCode_999999_lux = 999999;
    //ZenithLuminance_Cd/m² missing value 9999
    int ZenithLuminance_MissingCode_9999_Cd_p_m2 = 9999;
    //OpaqueSkyCover_tenths missing value 99
    //Note: Consider refactor to obtain from WeatherPrep
    int OpaqueSkyCover_MissingCode_99_tenths = 99;
    //Visibility_km missing value 9999
    int Visibility_MissingCode_9999_km = 9999;
    //CeilingHeight_m missing value 99999
    int CeilingHeight_MissingCode_99999_m = 99999;
    //PrecipitableWater_mm missing value 999 (Not used by E+)
    int PrecipitableWater_MissingCode_999_mm = 999;
    //AerosolOpticalDepth_thousandths missing value 0.999 (Not used by E+)
    double AerosolOpticalDepth_MissingCode_0pt999_thousandths = 0.999;
    //DaysSinceLastSnowfall_days missing value 99 (Not used by E+)
    int epw_LastSnow = 99;
    //Albedo_unitless missing value 0 (Not used by E+)
    int Albedo_MissingCode_0_unitless = 0;
    //LiquidPrecipitationDepth_mm missing value 9999
    int LiquidPrecipitationDepth_MissingCode_0_mm = 0;
    //LiquidPrecipitationQuantityPeriod_hr (Not used by E+)
    int LiquidPrecipitationQuantityPeriod_MissingCode_0_hr = 0;

    // Loop through all data rows
    for (size_t data_i = 0; data_i < input->Tair_C.size(); ++data_i) {
        //YYYYMMDD is input->SimulationDate_GDH[data_i]
        int YYYYMMDD = input->SimulationDate_GDH[data_i];
        //HH_MM_SS is input->SimulationTime_HMS[data_i]
        string HH_MM_SS = input->SimulationTime_HMS[data_i];

        //Year_YYYY extracted from YYYYMMDD, first 4 spaces
        int Year_YYYY = stoi(to_string(YYYYMMDD).substr(0, 4));
        //Month_0_Julian_or_1_to_12_MM extracted from YYYYMMDD, next 2 spaces
        int Month_MM = stoi(to_string(YYYYMMDD).substr(4, 2));
        //Day_of_Month_or_Julian_if_Month_0_DD extracted from YYYYMMDD, next 2 spaces
        int Day_DD = stoi(to_string(YYYYMMDD).substr(6, 2));
        //Hour_HH extracted from HH_MM_SS; values must be 1 to 24
        int Hour_HH = stoi(HH_MM_SS.substr(0, 2)) + 1;
        //Minute_Mn extracted from HH_MM_SS
        int Minute_Mn = stoi(HH_MM_SS.substr(3, 2));
        //Tair_C (C) is input->Tair_C[data_i] 
        double Tair_C = input->Tair_C[data_i];

        //MonthlyAvgTair_C[Month_MM-1] sums Tair_C (C), changing vector ID for each month, and will divide to get average
        input->MonthlyAvgTair_C[Month_MM-1] += Tair_C;
        //Month_DataRecord_Count[Month_MM-1] updates to count data records in month
        Month_DataRecord_Count[Month_MM-1] = Month_DataRecord_Count[Month_MM-1] + 1;

        //Tdew_C is input->Tdew_C[data_i]
        double Tdew_C = input->Tdew_C[data_i];
        double WindSpeed_mps = input->WindSpd_mps[data_i];
        double WindDirection_deg = input->WindDir_deg[data_i];
        double AtmPress_Pa = input->AtmPres_kPa[data_i] * 1000.0;

        //PresentWeatherObservation_MissingCode_9, 0 = observation, 9 = no observation, initialized to 9
        int PresentWeatherObservation_MissingCode_9 = 9;
        //PresentWeatherCodes_MissingCode_999999999_tmy2 initialized to 999999999
        PresentWeatherCodes_MissingCode_999999999_tmy2 = "999999999";
        double PrecipitationDepth_mm = 9999;

        //PrecipitationDepth_mm is obtained as value or 9999 when missing
        //Note: Values of 0 are converted by EnergyPlus into 1.5 mm
        if (input->Precip_mpdt[data_i] > 0) {
            PrecipitationDepth_mm = input->Precip_mpdt[data_i] * 1000.0;
            PresentWeatherObservation_MissingCode_9 = 0;
            //PresentWeatherCodes_MissingCode_999999999_tmy2 redefined in CreateFile_EPW::EPW_PresentWeatherCode_string
            CreateFile_EPW::EPW_PresentWeatherCode_string(Tair_C, PrecipitationDepth_mm);
        }
        else {
            //9999 is no precipitation
            PrecipitationDepth_mm = 9999;
        }
        //SnowDepthOnGround_cm set to 0
        //Note: Consider refactor to obtain value from Weather.csv
        double SnowDepthOnGround_cm = 0;

        double RadiationDirect_Wpm2 = input->Radiation_Shortwave_Direct_Wpm2[data_i];
        double RadiationDiffuse_Wpm2 = input->Radiation_Shortwave_Diffuse_Wpm2[data_i];
        double RadiationLongwaveDown_Wpm2 = input->Radiation_Longwave_Downwelling_Wpm2[data_i];

        //VaporPressure_Saturated_kPa (kPa) as Tetens' formula in Eq 4.2.2 Shuttleworth (1993), e_kPa=0.6108*exp[(17.27*T_C)/(237.3+T_C)]
        double VaporPressure_Saturated_kPa = 0.6108 * exp((17.27 * Tair_C) / (237.3 + Tair_C));
        //VaporPressure_Actual_kPa (kPa) as Tetens' formula in Eq 4.2.2 Shuttleworth (1993), e_kPa=0.6108*exp[(17.27*T_C)/(237.3+T_C)]
        double VaporPressure_Actual_kPa = 0.6108 * exp((17.27 * Tdew_C) / (237.3 + Tdew_C));
        //RelativeHumidity_percent computed as VaporPressure_Actual_kPa / VaporPressure_Saturated_kPa * 100
        double RelativeHumidity_percent = VaporPressure_Actual_kPa / VaporPressure_Saturated_kPa * 100;

        // Output data to file
        outputFile << 
            // Year: This is the Year of the data. Not used in E+.
            Year_YYYY << "," <<
            // Month: This is the month (1-12) for the data. Cannot be missing.
            Month_MM << "," <<
            // Day: This is the day (dependent on month) for the data. Cannot be missing.
            Day_DD << "," <<
            // Hour: This is the hour of the data. (1 - 24). Hour 1 is 00:01 to 01:00. Cannot be missing.
            Hour_HH << "," <<
            // Minute: This is the minute field. (1..60)
            Minute_Mn << "," <<
            // DataSourceandUncertaintyFlags: The data source and uncertainty flags from various formats are consolidated in the E/E+ EPW format.
            DataSourceAndUncertaintyFlags_EPW_str << "," <<
            // DryBulbTemperature: This is the dry bulb temperature in °C at the time indicated. Valid values range from -70 °C to 70 °C. Missing value is 99.9.
            Tair_C << "," <<
            // DewPointTemperature: This is the dew point temperature in °C at the time indicated. Valid values range from -70 °C to 70 °C. Missing value is 99.9.
            Tdew_C << "," <<
            // RelativeHumidity: This is the Relative Humidity in percent at the time indicated. Valid values range from 0% to 110%. Missing value is 999.
            RelativeHumidity_percent << "," <<
            // AtmosphericStationPressure: This is the station pressure in Pa at the time indicated. Valid values range from 31,000 to 120,000. Missing value is 999999.
            AtmPress_Pa << "," <<
            // ExtraterrestrialHorizontalRadiation: This is the Extraterrestrial Horizontal Radiation in Wh/m². Minimum value is 0; missing value is 9999.
            ExtraterrestrialHorizontalRadiation_MissingCode_9999_Wh_p_m2 << "," <<
            // ExtraterrestrialDirectNormalRadiation: This is the Extraterrestrial Direct Normal Radiation in Wh/m². Minimum value is 0; missing value is 9999.
            ExtraterrestrialDirectNormalRadiation_MissingCode_9999_Wh_p_m2 << "," <<
            // HorizontalInfraredRadiationIntensity: This is the Horizontal Infrared Radiation Intensity in Wh/m². Missing value is 9999.
            HorizontalInfraredRadiationIntensityfromSky_MissingCode_9999_Wh_p_m2 << "," <<
            // GlobalHorizontalRadiation: This is the Global Horizontal Radiation in Wh/m². Minimum value is 0; missing value is 9999.
            GlobalHorizontalRadiation_MissingCode_9999_Wh_p_m2 << "," <<
            // DirectNormalRadiation: This is the Direct Normal Radiation in Wh/m². Missing values are set to 0. Counts of such missing values are totaled at the end of the run period.
            RadiationDirect_Wpm2 << "," <<
            // DiffuseHorizontalRadiation: This is the Diffuse Horizontal Radiation in Wh/m². Missing values are set to 0. Counts of such missing values are totaled at the end of the run period.
            RadiationDiffuse_Wpm2 << "," <<
            // GlobalHorizontalIlluminance: This is the Global Horizontal Illuminance in lux. Minimum value is 0; missing value is 999999.
            GlobalHorizontalIlluminance_MissingCode_999999_lux << "," <<
            // DirectNormalIlluminance: This is the Direct Normal Illuminance in lux. Minimum value is 0; missing value is 999999.
            DirectNormalIlluminance_MissingCode_999999_lux << "," <<
            // DiffuseHorizontalIlluminance: This is the Diffuse Horizontal Illuminance in lux. Minimum value is 0; missing value is 999999.
            DiffuseHorizontalIlluminance_MissingCode_999999_lux << "," <<
            // ZenithLuminance: This is the Zenith Illuminance in Cd/m². Minimum value is 0; missing value is 9999.
            ZenithLuminance_MissingCode_9999_Cd_p_m2 << "," <<
            // WindDirection: This is the Wind Direction in degrees (0 to 360). Missing value is 999.
            WindDirection_deg << "," <<
            // WindSpeed: This is the wind speed in m/sec. Values can range from 0 to 40. Missing value is 999.
            //fixed << setprecision(1) << WindSpeed_mps << "," << defaultfloat <<
            WindSpeed_mps << "," << 
            // TotalSkyCover: This is the value for total sky cover (tenths of coverage). Minimum value is 0; maximum value is 10; missing value is 99.
            OpaqueSkyCover_MissingCode_99_tenths << "," <<
            // OpaqueSkyCover: This is the value for opaque sky cover (tenths of coverage). Minimum value is 0; maximum value is 10; missing value is 99.
            OpaqueSkyCover_MissingCode_99_tenths << "," <<
            // Visibility: This is the value for visibility in km. Missing value is 9999.
            Visibility_MissingCode_9999_km << "," <<
            // CeilingHeight: This is the value for ceiling height in m. Missing value is 99999.
            CeilingHeight_MissingCode_99999_m << "," <<
            // PresentWeatherObservation: If 0, observed weather codes are taken from the next field. If 9, "missing" weather is assumed.
            PresentWeatherObservation_MissingCode_9 << "," <<
            // PresentWeatherCodes: See detailed interpretation below.
            PresentWeatherCodes_MissingCode_999999999_tmy2 << "," <<
            // PrecipitableWater: This is the value for Precipitable Water in mm. Missing value is 999.
            PrecipitableWater_MissingCode_999_mm << "," <<
            // AerosolOpticalDepth: This is the value for Aerosol Optical Depth in thousandths. Missing value is .999.
            AerosolOpticalDepth_MissingCode_0pt999_thousandths << "," <<
            // SnowDepth: This is the value for Snow Depth in cm. Missing value is 999.
            SnowDepthOnGround_cm << "," <<
            // DaysSinceLastSnowfall: This is the value for Days Since Last Snowfall. Missing value is 99.
            epw_LastSnow << "," <<
            // Albedo: The ratio (unitless) of reflected solar irradiance to global horizontal irradiance.
            Albedo_MissingCode_0_unitless << "," <<
            // LiquidPrecipitationDepth: Amount of liquid precipitation (mm) observed at the indicated time. Overrides "precipitation" flag as rainfall. Missing or zero is set to 1.5 mm.
            PrecipitationDepth_mm << "," <<
            // LiquidPrecipitationQuantity: Period of accumulation (hr) for the liquid precipitation depth field.
            LiquidPrecipitationQuantityPeriod_MissingCode_0_hr << 
            "\n";
    }
    //outputFile closed
    outputFile.close();
    cout << "CoolBuilding EPW file written successfully!" << endl;


    //For loop of month in year to compute monthly average air temperature
    for (int month_ID = 0; month_ID < 12; ++month_ID) {
        double groundTemp_C = 0;
        double groundMinTemp_C = 15;
        double groundMaxTemp_C = 25;
        //defaultTemp_C is average of min and max
        double defaultTemp_C = (groundMinTemp_C + groundMaxTemp_C) / 2.0; 
        //If Month_DataRecord_Count[month_ID] > 0 then data exist, enter for division
        if (Month_DataRecord_Count[month_ID] > 0) {
            //realAvgTemp_C is input->MonthlyAvgTair_C[month_ID] / Month_DataRecord_Count[month_ID]
            double realAvgTemp_C = input->MonthlyAvgTair_C[month_ID] / Month_DataRecord_Count[month_ID];
            //If realAvgTemp_C >= groundMinTemp_C && <= groundMaxTemp_C then use it
            if (realAvgTemp_C >= groundMinTemp_C && realAvgTemp_C <= groundMaxTemp_C) {
                input->MonthlyAvgTair_C[month_ID] = realAvgTemp_C; 
            }
            else if (realAvgTemp_C > groundMaxTemp_C) {
                input->MonthlyAvgTair_C[month_ID] = groundMaxTemp_C; 
            }
            else {
                input->MonthlyAvgTair_C[month_ID] = groundMinTemp_C;
            }
        }
        //Else MonthlyAvgTair_C set to defaultTemp_C for use in IDF
        else {
            input->MonthlyAvgTair_C[month_ID] = defaultTemp_C;
        }
    }
}

//EPW_PresentWeatherCode_string is a string function to populate the EPW variable PresentWeather
void CreateFile_EPW::EPW_PresentWeatherCode_string(double Tair_C, double PrecipitationDepth_mm) {
    // PresentWeatherCodes Interpretation:
    // Column 1: Occurrences of Thunderstorm, Tornado, or Squall
    //   0 = Thunderstorm, 1 = Heavy thunderstorm, 2 = Tornado, 4 = Moderate squall
    //   6 = Waterspout, 7 = Funnel cloud, 8 = Tornado (beginning 1984), 9 = None/Unknown
    string epw_PresentWeatherCode_col_1 = "9";
    // Column 2: Occurrences of Rain, Rain Showers, or Freezing Rain
    //   0 = Light rain (<=2.5 mm/hr), 1 = Moderate rain (>2.5 <=0.75 mm/hr), 2 = Heavy rain (>0.75 mm/hr), 3 = Light rain showers
    //   4 = Moderate rain showers, 5 = Heavy rain showers, 6 = Light freezing rain
    //   7 = Moderate freezing rain, 8 = Heavy freezing rain, 9 = None/Unknown
    //   Light = up to 0.25 cm per hour Moderate = 0.28 to 0.76 cm per hour Heavy = greater than 0.76 cm per hour
    string epw_PresentWeatherCode_col_2 = "9";
    // Column 3: Occurrences of Rain Squalls, Drizzle, or Freezing Drizzle
    //   0 = Light rain squalls, 1 = Moderate rain squalls, 3 = Light drizzle (<=0.25 mm/hr)
    //   4 = Moderate drizzle (>0.25 <=0.5 mm/hr), 5 = Heavy drizzle (>0.5 mm/hr), 6 = Light freezing drizzle
    //   7 = Moderate freezing drizzle, 8 = Heavy freezing drizzle, 9 = None/Unknown
    //   Light = up to 0.025 cm per hour Moderate = 0.025 to 0.051 cm per hour Heavy = greater than 0.051 cm
    string epw_PresentWeatherCode_col_3 = "9";
    // Column 4: Occurrences of Snow, Snow Pellets, or Ice Crystals
    //   0 = Light snow (<=2.5 mm/hr), 1 = Moderate snow (>2.5 <=0.75 mm/hr), 2 = Heavy snow (>0.75 mm/hr), 3 = Light snow pellets
    //   4 = Moderate snow pellets, 5 = Heavy snow pellets, 6 = Light ice crystals
    //   7 = Moderate ice crystals, 8 = Heavy ice crystals, 9 = None/Unknown
    string epw_PresentWeatherCode_col_4 = "9";
    // Column 5: Occurrences of Snow Showers, Snow Squalls, or Snow Grains
    //   0 = Light snow, 1 = Moderate snow showers, 2 = Heavy snow showers
    //   3 = Light snow squall, 4 = Moderate snow squall, 5 = Heavy snow squall
    //   6 = Light snow grains, 7 = Moderate snow grains, 9 = None/Unknown
    string epw_PresentWeatherCode_col_5 = "9";
    // Column 6: Occurrences of Sleet, Sleet Showers, or Hail
    //   0 = Light ice pellet showers, 1 = Moderate ice pellet showers, 2 = Heavy ice pellet showers
    //   4 = Hail, 9 = None/Unknown
    string epw_PresentWeatherCode_col_6 = "9";
    // Column 7: Occurrences of Fog, Blowing Dust, or Blowing Sand
    //   0 = Fog, 1 = Ice fog, 2 = Ground fog, 3 = Blowing dust, 4 = Blowing sand
    //   5 = Heavy fog, 6 = Glaze (beginning 1984), 7 = Heavy ice fog, 8 = Heavy ground fog, 9 = None/Unknown
    string epw_PresentWeatherCode_col_7 = "9";
    // Column 8: Occurrences of Smoke, Haze, Smoke and Haze, Blowing Snow, or Dust
    //   0 = Smoke, 1 = Haze, 2 = Smoke and haze, 3 = Dust, 4 = Blowing snow
    //   5 = Blowing spray, 6 = Dust storm (beginning 1984), 7 = Volcanic ash, 9 = None/Unknown
    string epw_PresentWeatherCode_col_8 = "9";
    // Column 9: Occurrences of Ice Pellets
    //   0 = Light ice pellets, 1 = Moderate ice pellets, 2 = Heavy ice pellets, 9 = None/Unknown
    string epw_PresentWeatherCode_col_9 = "9";

    //If Tair_C not freezing then define precipitation as drizzle or rain of given intensity
    // Evaluate based on temperature and precipitation
    if (Tair_C > 0) {
        if (PrecipitationDepth_mm < 0.25) {
            epw_PresentWeatherCode_col_3 = "3";
        }
        else if (PrecipitationDepth_mm <= 0.5) {
            epw_PresentWeatherCode_col_3 = "4";
        }
        else if (PrecipitationDepth_mm < 1.0) {
            epw_PresentWeatherCode_col_3 = "5";
        }
        else if (PrecipitationDepth_mm <= 2.5) {
            epw_PresentWeatherCode_col_2 = "0";
        }
        else if (PrecipitationDepth_mm <= 7.5) {
            epw_PresentWeatherCode_col_2 = "1";
        }
        else {
            epw_PresentWeatherCode_col_2 = "2";
        }
    }
    else if (Tair_C <= 0) {
        if (PrecipitationDepth_mm <= 2.5) {
            epw_PresentWeatherCode_col_4 = "0";
        }
        else if (PrecipitationDepth_mm <= 7.5) {
            epw_PresentWeatherCode_col_4 = "1";
        }
        else {
            epw_PresentWeatherCode_col_4 = "2";
        }
    }

    PresentWeatherCodes_MissingCode_999999999_tmy2 = epw_PresentWeatherCode_col_1 + epw_PresentWeatherCode_col_2 + epw_PresentWeatherCode_col_3 + epw_PresentWeatherCode_col_4 + epw_PresentWeatherCode_col_5 + epw_PresentWeatherCode_col_6 + epw_PresentWeatherCode_col_7 + epw_PresentWeatherCode_col_8 + epw_PresentWeatherCode_col_9;
}

