// *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* // ** Copyright UCAR (c) 1990 - 2016 // ** University Corporation for Atmospheric Research (UCAR) // ** National Center for Atmospheric Research (NCAR) // ** Boulder, Colorado, USA // ** BSD licence applies - redistribution and use in source and binary // ** forms, with or without modification, are permitted provided that // ** the following conditions are met: // ** 1) If the software is modified to produce derivative works, // ** such modified software should be clearly marked, so as not // ** to confuse it with the version available from UCAR. // ** 2) Redistributions of source code must retain the above copyright // ** notice, this list of conditions and the following disclaimer. // ** 3) Redistributions in binary form must reproduce the above copyright // ** notice, this list of conditions and the following disclaimer in the // ** documentation and/or other materials provided with the distribution. // ** 4) Neither the name of UCAR nor the names of its contributors, // ** if any, may be used to endorse or promote products derived from // ** this software without specific prior written permission. // ** DISCLAIMER: THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS // ** OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED // ** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=* //============================================================================= // // RAP, NCAR, P.O.Box 3000, Boulder, CO, 80307-3000, USA // // File: $RCSfile: ChecktimeReport.cc,v $ // Version: $Revision: 1.5 $ Dated: $Date: 2017/12/14 15:59:24 $ // //============================================================================= // /** * @file ChecktimeReport.cc * * Data format for deicing fluid checktimes generated by the CheckTimeDisp program * * @date September 2011 */ #include using namespace std; // // Default constructor ///////////////////////// ChecktimeReport::ChecktimeReport() { _lat = 0; _lon = 0; _alt = 0; _time = 0; clearFluids(); } // // Alternate constructor ///////////////////////// ChecktimeReport::ChecktimeReport(fl32 lat, fl32 lon, fl32 alt, ui32 time) { _lat = lat; _lon = lon; _alt = alt; _time = time; clearFluids(); } // // Destructor ///////////////////////// ChecktimeReport::~ChecktimeReport() { } // // Clear all fluid checktimes from the fluid list ///////////////////////// void ChecktimeReport::clearFluids() { _fluids.clear(); } // // Add a fluid checktime to the fluid checktime list ///////////////////////// void ChecktimeReport::addFluid(const checktime_fluid_t &fluid) { _fluids.push_back(fluid); } // // Get the checktime of a particular fluid/dilution combo ///////////////////////// ChecktimeReport::checktime_fluid_t *ChecktimeReport::getFluid(int fluid_id, int dilution) { for (size_t i=0;i<_fluids.size();i++) { if ((int) _fluids.at(i).fluid_id == fluid_id && (int) _fluids.at(i).fluid_dilution == dilution) { return &_fluids.at(i); } } return NULL; } // // Assemble the object into a byte array ///////////////////////// bool ChecktimeReport::assemble() { // Initialize the buffer _memBuf.free(); // load the header checktime_hdr_t hdr; MEM_zero(hdr); hdr.gauge_lat = _lat; hdr.gauge_lon = _lon; hdr.gauge_alt = _alt; hdr.time = _time; hdr.num_fluids = _fluids.size(); hdr.buf_len = sizeof(checktime_hdr_t) + sizeof(checktime_fluid_t)*_fluids.size(); BE_from_array_32(&hdr, sizeof(checktime_hdr_t)); _memBuf.add(&hdr, sizeof(checktime_hdr_t)); // load the fluids for (size_t i=0;i<_fluids.size(); i++) { checktime_fluid_t out = _fluids.at(i); BE_from_array_32(&out, sizeof(checktime_fluid_t)); _memBuf.add(&out, sizeof(checktime_fluid_t)); } return true; } // // Disassemble a report from a byte array ///////////////////////// bool ChecktimeReport::disassemble(const void *buf, int len) { clearFluids(); // check header length if (len < (int)sizeof(checktime_hdr_t)) { return false; } _memBuf.free(); _memBuf.add(buf, len); checktime_hdr_t *hdr = (checktime_hdr_t *)_memBuf.getPtr(); BE_to_array_32(hdr, sizeof(checktime_hdr_t)); _lat = hdr->gauge_lat; _lon = hdr->gauge_lon; _alt = hdr->gauge_alt; _time = hdr->time; // buffer length is wrong if (len != (int) hdr->buf_len) { return false; } checktime_fluid_t *ptr = (checktime_fluid_t *)((char *)_memBuf.getPtr() + sizeof(checktime_hdr_t)); for (size_t i = 0; i < hdr->num_fluids; i++) { BE_to_array_32(ptr, sizeof(checktime_fluid_t)); _fluids.push_back(*ptr); ptr++; } return true; } // // Print the checktime in ASCII format // to the given stream ///////////////////////// void ChecktimeReport::print( FILE *fptr) { struct tm * timeinfo; const time_t gentime = _time; timeinfo = gmtime ( &gentime ); fprintf(fptr, " ===============================\n"); fprintf(fptr, " Deicing Fluid Checktimes\n"); fprintf(fptr, " Calculated for time %s", asctime(timeinfo)); fprintf(fptr, " Lat: %.3f \n", _lat); fprintf(fptr, " Lon: %.3f \n", _lon); fprintf(fptr, " Alt: %.3f \n", _alt); fprintf(fptr, " Num fluids: %d \n", (int) _fluids.size()); fprintf(fptr, " ===============================\n"); fprintf(fptr, "\n"); for (size_t i=0; i<_fluids.size();i++) { string name = get_fluid_name(_fluids.at(i).fluid_id); int dilution = _fluids.at(i).fluid_dilution; fprintf(fptr, " Fluid: %s %d%% Dilution\n", name.c_str(), dilution); fprintf(fptr, " -----------------------------------------------------------\n"); for (int j=0;j<9;j++) { const time_t fract_time = _fluids.at(i).fract_failure_time[j]; fprintf(fptr, " %d%% failure time:", (j+1)*10); if (fract_time == CHECKTIME_NAN) { fprintf(fptr, "N/A\n"); } else { timeinfo = gmtime(&fract_time); fprintf(fptr, "%s", asctime(timeinfo)); } } const time_t ct = _fluids.at(i).checktime; fprintf(fptr, " Checktime: "); if (ct == CHECKTIME_NAN) { fprintf(fptr, "N/A\n"); } else { timeinfo = gmtime(&ct); fprintf(fptr, "%s", asctime(timeinfo)); } fprintf(fptr, " Status of Checktime Calculation: "); switch (_fluids.at(i).status) { case CT_CHECKTIME_VALID: fprintf(fptr, "CHECKTIME VALID"); break; case CT_UNKNOWN_PRECIP: fprintf(fptr, "TOO MANY UNKNOWN PRECIP REPORTS"); break; case CT_MISSING_DATA: fprintf(fptr, "TOO MUCH MISSING DATA"); break; case CT_NO_FROZEN_PRECIP: fprintf(fptr, "NO FROZEN PRECIP REPORTED"); break; case CT_OTHER: fprintf(fptr, "OTHER"); break; default: break; } fprintf(fptr, "\n\n"); } } // // Print the checktime in ASCII format // to the given stream ///////////////////////// void ChecktimeReport::print(ostream &out) const { struct tm * timeinfo; const time_t gentime = _time; timeinfo = gmtime ( &gentime ); out << " ===============================" << endl; out << " Deicing Fluid Checktimes"<< endl; out << " Calculated for time " << asctime(timeinfo); out << " Lat: " << _lat << endl; out << " Lon: " << _lon << endl; out << " Alt: " << _alt << endl; out << " Num fluids: " << _fluids.size() << endl; out << " ===============================" << endl; out << endl; for (size_t i=0; i<_fluids.size();i++) { string name = get_fluid_name(_fluids.at(i).fluid_id); int dilution = _fluids.at(i).fluid_dilution; out << " Fluid: " << name << " " << dilution << "% Dilution" << endl; out << " -----------------------------------------------------------" << endl; for (int j=0;j<9;j++) { const time_t fract_time = _fluids.at(i).fract_failure_time[j]; out << " " << ((j+1)*10) << "% failure time: "; if (fract_time == CHECKTIME_NAN) { out << "N/A" << endl; } else { timeinfo = gmtime(&fract_time); out << asctime(timeinfo); } } const time_t ct = _fluids.at(i).checktime; out << " Checktime: "; if (ct == CHECKTIME_NAN) { out << "N/A" << endl; } else { timeinfo = gmtime(&ct); out << asctime(timeinfo); } out << " Status of Checktime Calculation: "; switch (_fluids.at(i).status) { case CT_CHECKTIME_VALID: out << "CHECKTIME VALID"; break; case CT_UNKNOWN_PRECIP: out << "TOO MANY UNKNOWN PRECIP REPORTS"; break; case CT_MISSING_DATA: out << "TOO MUCH MISSING DATA"; break; case CT_NO_FROZEN_PRECIP: out << "NO FROZEN PRECIP REPORTED"; break; case CT_OTHER: out << "OTHER"; break; default: break; } out << endl << endl; } } // // Convert a string to the associated fluid integer value ///////////////////////// int ChecktimeReport::get_fluid_value( const string fluid_name ) { int fluid_value = -1; if (fluid_name == "Generic Type I") fluid_value = CT_GENERIC_TYPE_I; if (fluid_name == "Clariant Safewing MP II 1951") fluid_value = CT_CLARIANT_SAFEWING_MP_II_1951; if (fluid_name == "Clariant Safewing MP II 2025 ECO") fluid_value = CT_CLARIANT_SAFEWING_MP_II_2025_ECO; if (fluid_name == "Clariant Safewing MP II Flight") fluid_value = CT_CLARIANT_SAFEWING_MP_II_FLIGHT; if (fluid_name == "Clariant Safewing MP IV 2001") fluid_value = CT_CLARIANT_SAFEWING_MP_IV_2001; if (fluid_name == "Clariant Safewing MP IV 2012 Protect") fluid_value = CT_CLARIANT_SAFEWING_MP_IV_2012_PROTECT; if (fluid_name == "Clariant Safewing MP IV Launch") fluid_value = CT_CLARIANT_SAFEWING_MP_IV_LAUNCH; if (fluid_name == "Kilfrost ABC II PLUS") fluid_value = CT_KILFROST_ABC_II_PLUS; if (fluid_name == "Kilfrost ABC-2000") fluid_value = CT_KILFROST_ABC_2000; if (fluid_name == "Kilfrost ABC-K PLUS") fluid_value = CT_KILFROST_ABC_K_PLUS; if (fluid_name == "Kilfrost ABC-S") fluid_value = CT_KILFROST_ABC_S; if (fluid_name == "Kilfrost ABC-S PLUS") fluid_value = CT_KILFROST_ABC_S_PLUS; if (fluid_name == "Kilfrost ABC-4") fluid_value = CT_KILFROST_ABC_4; if (fluid_name == "Dow UCAR ADF/AAF ULTRA+") fluid_value = CT_DOW_UCAR_ADF_AAF_ULTRA_PLUS; if (fluid_name == "Dow UCAR Endurance EG106") fluid_value = CT_DOW_UCAR_ENDURANCE_EG106; if (fluid_name == "Dow UCAR FlightGuard AD-480") fluid_value = CT_DOW_UCAR_FLIGHTGUARD_AD480; if (fluid_name == "Octagon Max-Flight 04") fluid_value = CT_OCTAGON_MAX_FLIGHT_04; if (fluid_name == "Octagon E Max II") fluid_value = CT_OCTAGON_E_MAX_II; return fluid_value; } // // Convert a fluid integer value to a string ///////////////////////// string ChecktimeReport::get_fluid_name( int fluid_value ) { string fluid_name = ""; switch (fluid_value) { case CT_GENERIC_TYPE_I: fluid_name = "Generic Type I"; break; case CT_CLARIANT_SAFEWING_MP_II_1951: fluid_name = "Clariant Safewing MP II 1951"; break; case CT_CLARIANT_SAFEWING_MP_II_2025_ECO: fluid_name = "Clariant Safewing MP II 2025 ECO"; break; case CT_CLARIANT_SAFEWING_MP_II_FLIGHT: fluid_name = "Clariant Safewing MP II Flight"; break; case CT_CLARIANT_SAFEWING_MP_IV_2001: fluid_name = "Clariant Safewing MP IV 2001"; break; case CT_CLARIANT_SAFEWING_MP_IV_2012_PROTECT: fluid_name = "Clariant Safewing MP IV 2012 Protect"; break; case CT_CLARIANT_SAFEWING_MP_IV_LAUNCH: fluid_name = "Clariant Safewing MP IV Launch"; break; case CT_KILFROST_ABC_II_PLUS: fluid_name = "Kilfrost ABC II PLUS"; break; case CT_KILFROST_ABC_2000: fluid_name = "Kilfrost ABC-2000"; break; case CT_KILFROST_ABC_K_PLUS: fluid_name = "Kilfrost ABC-K PLUS"; break; case CT_KILFROST_ABC_S: fluid_name = "Kilfrost ABC-S"; break; case CT_KILFROST_ABC_S_PLUS: fluid_name = "Kilfrost ABC-S PLUS"; break; case CT_KILFROST_ABC_4: fluid_name = "Kilfrost ABC-4"; break; case CT_DOW_UCAR_ADF_AAF_ULTRA_PLUS: fluid_name = "Dow UCAR ADF/AAF ULTRA+"; break; case CT_DOW_UCAR_ENDURANCE_EG106: fluid_name = "Dow UCAR Endurance EG106"; break; case CT_DOW_UCAR_FLIGHTGUARD_AD480: fluid_name = "Dow UCAR FlightGuard AD-480"; break; case CT_OCTAGON_MAX_FLIGHT_04: fluid_name = "Octagon Max-Flight 04"; break; case CT_OCTAGON_E_MAX_II: fluid_name = "Octagon E Max II"; break; } return fluid_name; }