Gnats 4797: Integer Index slots and SCTs have display issues due to synching. (10-15-2009, Phil Weinstein, CADSWES). There are a couple related problems, and not just related to display. (1) Synchronizing all of the series slots in the model (when the user does not choose to "Exclude Slots with Different Timesteps from Run") changes Integer Indexed slots from their intended Hourly timestep size, starting at the "zero" date/time. This was noted in the bug report, but potentially has implications beyond just display issues. (2) The display issues noted in the bug report could occur even when the timestep and start time for Integer Indexed series slots are correct (Hourly, starting at the "zero" date/time). The display error could occur for Integer Indexed series slots having these two properties: (a) having more than 745 items (rows), i.e. more than the number of hours in January 1800, and (b) having a display units with an irregular "per time" factor, e.g. "per month" or "per year". This second problem occurs because display conversions involving irregular "per time" factors -- including with Integer Indexed slots -- had used the "date/time" of the item to know the actual length of the relevant month or year. Now, when handling integer indexed slots, we the unit conversions which DON'T USE a reference date/time. Those assume 30-day months and 365-day years (i.e. non-leap year). Changes include: (1) Preventing synchronization of Indexed Integer Slots (2) After model loading, FIX timestep spec for Integer Indexed Slots (3) In the Open SeriesSlot Dialog AND in the SCT -- both when showing cell values AND selection summary statistics -- in the case of Integer Indexed slots, don't use the row index's "date/time" as a reference date/time for unit conversion. (4) Also, in the selection summary statistics panels (in both the Open Slot Dialog and the SCT): (a) don't show any timestep date/time information nor time-integrated computations and (b) in the case of "per-month" display units, indicate that 30-day months are assumed. (5) In the SCT, don't show any time-region dividers. (6) Addition of a new Slot Type RootFilter value for choosing Integer Indexed Slots. ---------------------- Sim/SeriesSlot.cpp Sim/SeriesSlot.hpp Sim/AggSeriesSlot.cpp Sim/AggSeriesSlot.hpp ---------------------- (1) New virtual method, implemented in SeriesSlot and AggSeriesSlot: virtual void fixIndexByIntTimeSpec(); ... If 'this' slot is integer indexed AND if the timestep size is not One Hour or the start date/time is not the "zero" date/time (currently January 1800), then resynchronize the series to that time specification, preserving the series data (numeric values and flags). (2) In the following methods, when calling UnitMgr::convertWithinType(), if 'this' slot is Integer Indexed, use the variant of that method which does NOT take a reference Date_Time (since the Date_Time associated with the series index is not meaningful): errstat SeriesSlot::getValue (const Date_Time *when, ... errstat SeriesSlot::getExistingValue (const Date_Time *dateOfValue, ... double *SeriesSlot::getValues (int &n, double usrScale, ... errstat SeriesSlot::getValues (const Date_Time *start, ... errstat SeriesSlot::getValues (const Date_Time *start, int n, ... SetStatus SeriesSlot::p_setValue (double newValue, ... void SeriesSlot::assignStdValue (double stdValue, errstat SeriesSlot::setValuesWithAttrAndDate (const double *newValues, ... void SeriesSlot::changeUsrUnitsNoConvertNoNotify (const RWCString &oldU, ... void SeriesSlot::setUnitType (unit_type newUnitType) errstat SeriesSlot::importData (FILE *fp, bool resize, ... errstat SeriesSlot::exportData (FILE *fp, bool displayFormat, ... bool SeriesSlot::addSetToStream (int set_number ... RplResult::Status SeriesSlot::evaluateExpr (bool evalOnly) -------------- Sim/SimObj.cpp -------------- Change in method: bool SimObj::syncToInterval(const Date_Time *startTime, ... ... Skip synchronization for slots which are Integer Indexed slots, (within the two distinct iterations over the SimObj's slots). ------------- Sim/SimWS.hpp Sim/SimWS.cpp ------------- New method: void SimWS::fixAllIntIndexedSeriesSlotsTimeSpecs(); This method uses four RootSelections to search for all Integer Indexed slots on SimObjs, Accounts, Supplies and Exchanges. (Currently such slots are created only on SimObjs, but if they are ever introduced on the other types of objects, this will work) ... and call the virtual method SeriesSlot::fixIndexByIntTimeSpec() on those slots. (That method has no effect if the slot timestep spec is correct). Addition to method: SimWorkspace::doneLoading (...) Call SimWS::fixAllIntIndexedSeriesSlotsTimeSpecs(), see above. -------------------- Sim/SlotGUIUtils.cpp -------------------- In the following methods, refrain from providing a reference Date_Time for unit conversions if the slot is an Integer Indexed slot: double SlotGUIUtils::convertToStdPrimaryValue (const Slot* ... double SlotGUIUtils::getValue (const Slot* ... ----------------------- Sim/RootFilter.Slot.hpp Sim/RootFilter.Slot.cpp ----------------------- Added "Integer Indexed Slots" filter-value to the Series Type RootFilter. This (and the other defined filter values) are availble to the GUS slot selector, and to programatically defined RootSelections. Added field to RootFilter_SlotType::SlotTypeRec (representing a filter value): bool _onlyIntIndexed; // Only Integer Indexed Series Slots Added members to RootFilter_SlotType: bool _onlyIntIndexed; // Only Integer Indexed Series Slots static const char* allIntegerIndexedStr(); Modified private method: void RootFilter_SlotType::initSlotTypeRecs() Append a new SlotTypeRec instance to cwSlist _slotTypeRecPtrs; for the "Integer Indexed Slots" filter-value. This automatically makes that Slot Type filter value to GUS, and programmatically to RootSelections. Modified method: RootFilter_SlotType::yes (const Root* obj) const Implements "Integer Indexed Slots" filtering. --------------------------- Q3GUI/SlotQDlgSelection.cpp Q3GUI/SlotQDlgSelection.hpp --------------------------- The following fields were added to the classes used to represents the selection of one or more contiguous timsteps within a particular slot, and summary computations of a set of such selections: struct SlotQDlgSelectionStats: bool _anyIntIndexedSlots; class SlotQDlgSelection: bool slotIsIntegerIndexed() const; Change in method: void SlotQDlgSelectionList::computeStats (SlotQDlgSelectionStats& ...) ------------------------------ Q3GUI/SlotQDlgSelStatFrame.cpp ------------------------------ Changes in methods: void SlotQDlgSelStatFrame::refreshStatusBar (bool dataChangeOnly) ... with respect to whether or not the selection includes Integer Indexed slots, including: (1) conversion of summary statistics to display units, and (2) construction of unit string using SlotGUIUtils::scaledUnitDisplayStr QString SlotQDlgSelStatFrame::selStatsSeriesSlotsInfoStr (const SeriesSlot* ... For the first line (of two) status lines, if there is just one cell selected, normally the corresponding Date_Time is shown. Now, that is not shown if the cell is an element of an Integer Indexed slot. ----------------------------- QtSCT/SctDialog.StatusBar.cpp ----------------------------- Change in method: void SctDialog::refreshStatusBar (bool dataChangeOnly) If the selection includes a value from Integer Indexed slots: (1) Don't do the (time-) integrated sum computation (e.g. of flow values to compute a volume). (2) Generally, if a single cell is selected, the corresponding timestep date/time is shown. Don't do that for Integer Indexed slots. -------------------------- QtSCT/SctModelData.hpp QtSCT/SctModelData.cpp QtSCT/SctModelData.Sim.cpp -------------------------- New method: bool SctModelData::slotIsIntegerIndexed (int slotInx) const; Change in methods: bool SctModelData::tstepIndexYearDiff (int t1, int t2) const bool SctModelData::tstepIndexMonthYearDiff (int t1, int t2) const bool SctModelData::tstepIndexIsOnWeekend (int tStepInx) const bool SctModelData::tstepIndexDayDiff(int t1, int t2) const .. if any of the slots in the SctConfig is an Integer Indexed Slot, then return "negatory" for all time comparison differences. This prevents "time" dividers from appearing in an SCT having Integer Indexed slots. Change in methods: okstat SctModelData::getSlotScaleUnitsDisplayStr (int slotInx, ... ... When constructing the Unit Display String, in the case of Integer Indexed slots, use the "Normal" month date/time (30-day month, non-leap year) instead of the bogus date/time associated with the row index. okstat SctModelData::formatSlotScaleUnitValue (int slotInx, ... In the case of Integer Indexed Slots, don't use the bogus date/time associated with the row index when doing the display unit conversion. ------------------------- QtSCT/SctSlotTstepSet.hpp QtSCT/SctSlotTstepSet.cpp ------------------------- New method: bool SctSlotTstepSet::anyIntIndexSlots() const; ---------------------------- QtSCT/SctViewAggTHorz.cpp QtSCT/SctViewAggTVert.cpp QtSCT/SctViewNoAggTHorz.cpp QtSCT/SctViewNoAggTVert.cpp ---------------------------- In the four SctViews (Horz vs Vert, and Aggregated vs. Non-Aggregated), when Integer Indexed Slots are included, Don't create time-range dividers (because Integer Indexed Slots don't have times). Changes in methods: void SctViewAggTHorz::computeColInfo() void SctViewAggTVert::computeRowInfo() void SctViewNoAggTHorz::computeColInfo() void SctViewNoAggTVert::computeRowInfo() ------------------------- Utils/Date_Time.hpp Utils/Date_Time.cpp Utils/libUtilsGlobals.cpp ------------------------- Added computations for: (1) An arbitrary sample Date_Time for a "normal month" (30 days in a non-leap year). (2) The first Non-Leap year in the supported time range. New data member: static Date_Time* _normalMonthDateTime; // in 30-day month in non-leap-yr New methods: static const Date_Time* getDateTimeInNormalMonth(); // 30 days, non-leap static int getFirstNonLeapYear(); Also: Added underscore to these static data member identifiers: Date_Time* Date_Time::_earliestAllowedDateTime; Date_Time* Date_Time::_latestAllowedDateTime; ---