public void Run(TourWrapper subtour)
        {
            if (subtour == null)
            {
                throw new ArgumentNullException("subtour");
            }

            TourTime.InitializeTourTimes();

            subtour.PersonDay.ResetRandom(50 + subtour.Sequence - 1);

            if (subtour == null)
            {
                throw new ArgumentNullException("subtour");
            }

            if (Global.Configuration.IsInEstimationMode)
            {
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME)
                {
                    return;
                }
            }

            var choiceProbabilityCalculator = _helpers[ParallelUtility.threadLocalAssignedIndex.Value].GetChoiceProbabilityCalculator(subtour.Id);

            if (_helpers[ParallelUtility.threadLocalAssignedIndex.Value].ModelIsInEstimationMode)
            {
                if (subtour.DestinationParcel == null || subtour.OriginParcel == null || subtour.Mode <= Global.Settings.Modes.None || subtour.Mode >= Global.Settings.Modes.ParkAndRide)
                {
                    return;
                }

                RunModel(choiceProbabilityCalculator, subtour, new TourTime(subtour.DestinationArrivalTime, subtour.DestinationDepartureTime));

                choiceProbabilityCalculator.WriteObservation();
            }
            else
            {
                RunModel(choiceProbabilityCalculator, subtour);

                var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(subtour.Household.RandomUtility);

                if (chosenAlternative == null)
                {
                    Global.PrintFile.WriteNoAlternativesAvailableWarning(CHOICE_MODEL_NAME, "Run", subtour.PersonDay.Id);
                    if (!Global.Configuration.IsInEstimationMode)
                    {
                        subtour.PersonDay.IsValid = false;
                    }
                    return;
                }

                var choice           = (TourTime)chosenAlternative.Choice;
                var destinationTimes = choice.GetDestinationTimes(subtour);

                subtour.DestinationArrivalTime   = destinationTimes.Start;
                subtour.DestinationDepartureTime = destinationTimes.End;
            }
        }
        public void Run(TourWrapper tour, int knownArrivalTime = 0, int knownDepartureTime = 0)
        {
            if (tour == null)
            {
                throw new ArgumentNullException("tour");
            }

            TourTime.InitializeTourTimes();

            tour.PersonDay.ResetRandom(50 + tour.Sequence - 1);

            if (Global.Configuration.IsInEstimationMode)
            {
                if (Global.Configuration.EstimationModel != CHOICE_MODEL_NAME)
                {
                    return;
                }
            }

            var choiceProbabilityCalculator = _helpers[ParallelUtility.GetBatchFromThreadId()].GetChoiceProbabilityCalculator(tour.Id);

            if (_helpers[ParallelUtility.GetBatchFromThreadId()].ModelIsInEstimationMode)
            {
                if (tour.DestinationParcel == null || tour.OriginParcel == null || tour.Mode <= Global.Settings.Modes.None || tour.Mode >= Global.Settings.Modes.SchoolBus)
                {
                    return;
                }

                RunModel(choiceProbabilityCalculator, tour, knownArrivalTime, knownDepartureTime, new TourTime(tour.DestinationArrivalTime, tour.DestinationDepartureTime));

                choiceProbabilityCalculator.WriteObservation();
            }
            else
            {
                RunModel(choiceProbabilityCalculator, tour, knownArrivalTime, knownDepartureTime);

                var chosenAlternative = choiceProbabilityCalculator.SimulateChoice(tour.Household.RandomUtility);

                if (chosenAlternative == null)
                {
                    Global.PrintFile.WriteNoAlternativesAvailableWarning(CHOICE_MODEL_NAME, "Run", tour.PersonDay.Id);
                    if (!Global.Configuration.IsInEstimationMode)
                    {
                        tour.PersonDay.IsValid = false;
                    }

                    return;
                }

                var choice           = (TourTime)chosenAlternative.Choice;
                var destinationTimes = choice.GetDestinationTimes(tour);

                tour.DestinationArrivalTime   = knownArrivalTime == 0 ? destinationTimes.Start : knownArrivalTime;
                tour.DestinationDepartureTime = knownDepartureTime == 0 ? destinationTimes.End : knownDepartureTime;
            }
        }