private void StoreTripModeRecords(int hhldID,
                                          Dictionary <PersonChain, DATIterationInformation> hhldData,
                                          ITashaPerson person, float expFactor, int tripID, ITripChain chain, ITrip trip)
        {
            var query = from mc in trip.ModesChosen
                        group mc by mc into g
                        select new { Mode = g.Key, Count = g.Count() };
            DATIterationInformation chainData = null;

            hhldData?.TryGetValue(new PersonChain(person, chain), out chainData);
            if (trip.Purpose == Activity.Home)
            {
                foreach (var modeChoice in query)
                {
                    var mode = modeChoice.Mode;
                    if (mode != _dat)
                    {
                        _modeRecordQueue.Add(new ModeRecord(hhldID, person.Id, tripID, mode.ModeName,
                                                            trip.TripStartTime, trip.TripStartTime + mode.TravelTime(trip.OriginalZone, trip.DestinationZone, trip.TripStartTime),
                                                            modeChoice.Count));
                    }
                    else if (chainData != null)
                    {
                        // we need that defensive check in case of edge cases
                        var travelTime = chainData.ExpectedDATTravelTime(trip);
                        _modeRecordQueue.Add(new ModeRecord(hhldID, person.Id, tripID, mode.ModeName,
                                                            trip.TripStartTime, trip.TripStartTime + Time.FromMinutes(travelTime),
                                                            modeChoice.Count));
                        chainData.StoreStationRecords(_stationRecordQueue, hhldID, person.Id, tripID, trip, chainData);
                    }
                }
            }
            else
            {
                foreach (var modeChoice in query)
                {
                    var mode = modeChoice.Mode;
                    if (mode != _dat)
                    {
                        _modeRecordQueue.Add(new ModeRecord(hhldID, person.Id, tripID, mode.ModeName,
                                                            trip.ActivityStartTime - mode.TravelTime(trip.OriginalZone, trip.DestinationZone, trip.TripStartTime), trip.ActivityStartTime,
                                                            modeChoice.Count));
                    }
                    else if (chainData != null)
                    {
                        var travelTime = chainData.ExpectedDATTravelTime(trip);
                        _modeRecordQueue.Add(new ModeRecord(hhldID, person.Id, tripID, mode.ModeName,
                                                            trip.ActivityStartTime - Time.FromMinutes(travelTime), trip.ActivityStartTime,
                                                            modeChoice.Count));
                        chainData.StoreStationRecords(_stationRecordQueue, hhldID, person.Id, tripID, trip, chainData);
                    }
                }
            }
        }
 public void HouseholdIterationComplete(ITashaHousehold household, int hhldIteration, int totalHouseholdIterations)
 {
     if (_writeThisIteration)
     {
         _activeDATData.TryGetValue(household, out var datData);
         _activePassengerData.TryGetValue(household, out var passengerRecords);
         foreach (var person in household.Persons)
         {
             foreach (var tc in person.TripChains)
             {
                 // this is only true if a station has been selected in the tours past
                 if (tc["AccessStation"] is IZone zone)
                 {
                     // if the household doesn't have data, allocate it
                     if (datData == null)
                     {
                         datData = new Dictionary <PersonChain, DATIterationInformation>();
                         _activeDATData[household] = datData;
                     }
                     var tcRef = new PersonChain(person, tc);
                     // if the trip chain does not have data, allocate it
                     if (!datData.TryGetValue(tcRef, out var tcData))
                     {
                         tcData         = new DATIterationInformation();
                         datData[tcRef] = tcData;
                     }
                     tcData.AddTourData(_dat, tc, hhldIteration, zone, _autoNetwork,
                                        _transitNetwork, _zoneSystem);
                 }
                 foreach (var trip in tc.Trips)
                 {
                     if (trip.Mode == _passenger)
                     {
                         if (trip["Driver"] is ITrip driverTrip)
                         {
                             if (passengerRecords == null)
                             {
                                 _activePassengerData[household] = passengerRecords = new Dictionary <ITrip, PassengerIterationInformation>();
                             }
                             passengerRecords.TryGetValue(trip, out var tripData);
                             if (tripData == null)
                             {
                                 passengerRecords.Add(trip, tripData = new PassengerIterationInformation());
                             }
                             tripData.Add(driverTrip, this);
                         }
                     }
                 }
             }
         }
     }
 }
 internal void StoreStationRecords(BlockingCollection <StationRecord> stationRecordQueue,
                                   int hhldID, int personID, int tripID, ITrip trip, DATIterationInformation chainData)
 {
     // for each trip that we have stored
     if (_tripData.TryGetValue(trip, out var tripData))
     {
         var replicationData = tripData.Data;
         // store the access and egresses per access station
         foreach (var stn in from rec in replicationData
                  group rec by rec.StationIndex into g
                  select new
         {
             StationIndex = g.Key,
             TimesAccessed = g.Count(r => r.First),
             TimesEgressed = g.Count(r => !r.First)
         })
         {
             if (stn.TimesAccessed > 0)
             {
                 stationRecordQueue.Add(new StationRecord(hhldID, personID, tripID, stn.StationIndex, true, stn.TimesAccessed));
             }
             if (stn.TimesEgressed > 0)
             {
                 stationRecordQueue.Add(new StationRecord(hhldID, personID, tripID, stn.StationIndex, false, stn.TimesEgressed));
             }
         }
     }
 }