예제 #1
0
        private static void SetTourDestination(ITourWrapper tour, int batchNumber)
        {
            if (tour.DestinationPurpose == Global.Settings.Purposes.Work)
            {
                if (Global.Configuration.ShouldRunWorkTourDestinationModel)
                {
                    // sets the destination for the work tour
                    // the usual work location or some another work location
                    ChoiceModelFactory.TotalTimesWorkTourDestinationModelRun[batchNumber]++;
                    Global.ChoiceModelSession.Get <WorkTourDestinationModel>().Run(tour, Global.Configuration.WorkTourDestinationModelSampleSize);
                }

                return;
            }
            else if (tour.DestinationPurpose == Global.Settings.Purposes.School)
            {
                if (!Global.Configuration.IsInEstimationMode)
                {
                    // sets the destination for the school tour
                    tour.DestinationParcelId    = tour.Person.UsualSchoolParcelId;
                    tour.DestinationParcel      = tour.Person.UsualSchoolParcel;
                    tour.DestinationZoneKey     = tour.Person.UsualSchoolZoneKey;
                    tour.DestinationAddressType = Global.Settings.AddressTypes.UsualSchool;
                    //add code to set simulated times of day for mode choice
                    var tourCategory = tour.GetTourCategory();
                    ChoiceModelUtility.DrawRandomTourTimePeriods(tour, tourCategory);
                }

                return;
            }
            else
            {
                if (Global.Configuration.ShouldRunOtherTourDestinationModel)
                {
                    // sets the destination for the work tour
                    // the usual work location or some another work location
                    ChoiceModelFactory.TotalTimesOtherTourDestinationModelRun[batchNumber]++;
                    Global.ChoiceModelSession.Get <OtherTourDestinationModel>().Run(tour, Global.Configuration.OtherTourDestinationModelSampleSize);
                }

                return;
            }
        }
예제 #2
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITourWrapper tour, int sampleSize, IParcelWrapper choice = null)
        {
            var household = tour.Household;
            var person    = tour.Person;
            var personDay = tour.PersonDay;

//			var totalAvailableMinutes =
//				tour.ParentTour == null
//					? personDay.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay)
//					: tour.ParentTour.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay);

            var maxAvailableMinutes =
                tour.ParentTour == null
                                        ? personDay.TimeWindow.MaxAvailableMinutesAfter(121)
                                        : tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime;

//			var hoursAvailableInverse =
//				tour.IsHomeBasedTour
//					? (personDay.HomeBasedTours - personDay.SimulatedHomeBasedTours + 1) / (Math.Max(totalAvailableMinutes - 360, 30) / 60D)
//					: 1 / (Math.Max(totalAvailableMinutes, 1) / 60D);

            var fastestAvailableTimeOfDay =
                tour.IsHomeBasedTour || tour.ParentTour == null
                                        ? 1
                                        : tour.ParentTour.DestinationArrivalTime + (tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime) / 2;

            var tourCategory  = tour.GetTourCategory();
            var primaryFlag   = ChoiceModelUtility.GetPrimaryFlag(tourCategory);
            var secondaryFlag = ChoiceModelUtility.GetSecondaryFlag(tourCategory);

            ChoiceModelUtility.DrawRandomTourTimePeriods(tour, tourCategory);

            var segment                  = Global.Kernel.Get <SamplingWeightsSettingsFactory>().SamplingWeightsSettings.GetTourDestinationSegment(tour.DestinationPurpose, tour.IsHomeBasedTour ? Global.Settings.TourPriorities.HomeBasedTour : Global.Settings.TourPriorities.WorkBasedTour, Global.Settings.Modes.Sov, person.PersonType);
            var excludedParcel           = person.UsualWorkParcel == null || person.UsualWorkParcelId == household.ResidenceParcelId || tour.DestinationPurpose != Global.Settings.Purposes.Work || tour.GetTourCategory() == Global.Settings.TourCategories.WorkBased ? null : person.UsualWorkParcel;
            var destinationSampler       = new DestinationSampler(choiceProbabilityCalculator, segment, sampleSize, tour.OriginParcel, excludedParcel, excludedParcel, choice);
            var tourDestinationUtilities = new TourDestinationUtilities(tour, sampleSize, primaryFlag, secondaryFlag, fastestAvailableTimeOfDay, maxAvailableMinutes);

            destinationSampler.SampleTourDestinations(tourDestinationUtilities);
        }
예제 #3
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITourWrapper tour, int sampleSize, IParcelWrapper choice = null)
        {
            //            var household = tour.Household;
            var person    = tour.Person;
            var personDay = tour.PersonDay;

            //            var totalAvailableMinutes =
            //                tour.ParentTour == null
            //                    ? personDay.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay)
            //                    : tour.ParentTour.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay);

            var maxAvailableMinutes =
                tour.ParentTour == null
                    ? personDay.TimeWindow.MaxAvailableMinutesAfter(121)
                    : tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime;

            //            var hoursAvailableInverse =
            //                tour.IsHomeBasedTour
            //                    ? (personDay.HomeBasedTours - personDay.SimulatedHomeBasedTours + 1) / (Math.Max(totalAvailableMinutes - 360, 30) / 60D)
            //                    : 1 / (Math.Max(totalAvailableMinutes, 1) / 60D);

            var fastestAvailableTimeOfDay =
                tour.IsHomeBasedTour || tour.ParentTour == null
                    ? 1
                    : tour.ParentTour.DestinationArrivalTime + (tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime) / 2;

            var tourCategory = tour.GetTourCategory();
            //            var primaryFlag = ChoiceModelUtility.GetPrimaryFlag(tourCategory);
            var secondaryFlag = ChoiceModelUtility.GetSecondaryFlag(tourCategory);

            ChoiceModelUtility.DrawRandomTourTimePeriods(tour, tourCategory);

            var segment                  = Global.ContainerDaySim.GetInstance <SamplingWeightsSettingsFactory>().SamplingWeightsSettings.GetTourDestinationSegment(tour.DestinationPurpose, tour.IsHomeBasedTour ? Global.Settings.TourPriorities.HomeBasedTour : Global.Settings.TourPriorities.WorkBasedTour, Global.Settings.Modes.Sov, person.PersonType);
            var destinationSampler       = new DestinationSampler(choiceProbabilityCalculator, segment, sampleSize, choice, tour.OriginParcel);
            var tourDestinationUtilities = new TourDestinationUtilities(this, tour, sampleSize, secondaryFlag, personDay.GetIsWorkOrSchoolPattern().ToFlag(), personDay.GetIsOtherPattern().ToFlag(), fastestAvailableTimeOfDay, maxAvailableMinutes);

            destinationSampler.SampleTourDestinations(tourDestinationUtilities);
        }
예제 #4
0
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITourWrapper tour, IHouseholdDayWrapper householdDay, int sampleSize, IParcelWrapper choice = null)
        {
            //            var household = tour.Household;
            IPersonWrapper    person    = tour.Person;
            IPersonDayWrapper personDay = tour.PersonDay;

            //            var totalAvailableMinutes =
            //                tour.ParentTour == null
            //                    ? personDay.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay)
            //                    : tour.ParentTour.TimeWindow.TotalAvailableMinutes(1, Global.Settings.Times.MinutesInADay);


            TimeWindow timeWindow = new TimeWindow();

            if (tour.JointTourSequence > 0)
            {
                foreach (PersonDayWrapper pDay in householdDay.PersonDays)
                {
                    ITourWrapper tInJoint = pDay.Tours.Find(t => t.JointTourSequence == tour.JointTourSequence);
                    if (!(tInJoint == null))
                    {
                        // set jointTour time window
                        timeWindow.IncorporateAnotherTimeWindow(tInJoint.PersonDay.TimeWindow);
                    }
                }
            }
            else if (tour.ParentTour == null)
            {
                timeWindow.IncorporateAnotherTimeWindow(personDay.TimeWindow);
            }

            timeWindow.SetBusyMinutes(Global.Settings.Times.EndOfRelevantWindow, Global.Settings.Times.MinutesInADay + 1);

            int maxAvailableMinutes =
                (tour.JointTourSequence > 0 || tour.ParentTour == null)
                ? timeWindow.MaxAvailableMinutesAfter(Global.Settings.Times.FiveAM)
                    : tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime;


            //            var hoursAvailableInverse =
            //                tour.IsHomeBasedTour
            //                    ? (personDay.HomeBasedTours - personDay.SimulatedHomeBasedTours + 1) / (Math.Max(totalAvailableMinutes - 360, 30) / 60D)
            //                    : 1 / (Math.Max(totalAvailableMinutes, 1) / 60D);

            int fastestAvailableTimeOfDay =
                tour.IsHomeBasedTour || tour.ParentTour == null
                    ? 1
                    : tour.ParentTour.DestinationArrivalTime + (tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime) / 2;

            int tourCategory = tour.GetTourCategory();
            //            var primaryFlag = ChoiceModelUtility.GetPrimaryFlag(tourCategory);
            int secondaryFlag = ChoiceModelUtility.GetSecondaryFlag(tourCategory);

            ChoiceModelUtility.DrawRandomTourTimePeriodsActum(tour, tourCategory);

            int segment = Global.ContainerDaySim.GetInstance <SamplingWeightsSettingsFactory>().SamplingWeightsSettings.GetTourDestinationSegment(tour.DestinationPurpose, tour.IsHomeBasedTour ? Global.Settings.TourPriorities.HomeBasedTour : Global.Settings.TourPriorities.WorkBasedTour, Global.Settings.Modes.Sov, person.PersonType);
            DestinationSampler       destinationSampler       = new DestinationSampler(choiceProbabilityCalculator, segment, sampleSize, choice, tour.OriginParcel);
            TourDestinationUtilities tourDestinationUtilities = new TourDestinationUtilities(tour, sampleSize, secondaryFlag, personDay.GetIsWorkOrSchoolPattern().ToFlag(), personDay.GetIsOtherPattern().ToFlag(), fastestAvailableTimeOfDay, maxAvailableMinutes);

            destinationSampler.SampleTourDestinations(tourDestinationUtilities);
        }
        private void RunModel(ChoiceProbabilityCalculator choiceProbabilityCalculator, ITourWrapper tour, IHouseholdDayWrapper householdDay, int sampleSize, IParcelWrapper choice = null)
        {
            timesStartedRunModel++;
            //Console.WriteLine("Started {0}  Finished {1}", timesStarted,timesStartedRunModel);

            IHouseholdWrapper household = tour.Household;
            IPersonWrapper    person    = tour.Person;
            IPersonDayWrapper personDay = tour.PersonDay;

            Framework.DomainModels.Models.IHouseholdTotals householdTotals = household.HouseholdTotals;
            IParcelWrapper originParcel = tour.OriginParcel;

            int childUnder16Flag         = (person.Age < 16).ToFlag();
            int noCarsInHouseholdFlag    = (household.VehiclesAvailable == 0).ToFlag();
            int fewerCarsThanDriversFlag = household.GetFlagForCarsLessThanDrivers(household.VehiclesAvailable);

            int lowIncomeFlag     = (household.Income >= 0 && household.Income <= 40000).ToFlag();
            int highIncomeFlag    = (household.Income >= 80000).ToFlag();
            int missingIncomeFlag = (household.Income < 0).ToFlag();

            int originTransitBand1 = (originParcel.GetDistanceToTransit() >= 0 && originParcel.GetDistanceToTransit() <= 0.25).ToFlag();
            int originTransitBand3 = (originParcel.GetDistanceToTransit() > 0.5).ToFlag();


            TimeWindow timeWindow = new TimeWindow();

            if (tour.JointTourSequence > 0)
            {
                foreach (IPersonDayWrapper pDay in householdDay.PersonDays)
                {
                    ITourWrapper tInJoint = pDay.Tours.Find(t => t.JointTourSequence == tour.JointTourSequence);
                    if (!(tInJoint == null))
                    {
                        // set jointTour time window
                        timeWindow.IncorporateAnotherTimeWindow(tInJoint.PersonDay.TimeWindow);
                    }
                }
            }
            else if (tour.ParentTour == null)
            {
                timeWindow.IncorporateAnotherTimeWindow(personDay.TimeWindow);
            }

            timeWindow.SetBusyMinutes(Global.Settings.Times.EndOfRelevantWindow, Global.Settings.Times.MinutesInADay + 1);

            int maxAvailableMinutes =
                (tour.JointTourSequence > 0 || tour.ParentTour == null)
                 ? timeWindow.MaxAvailableMinutesAfter(Global.Settings.Times.FiveAM)
                      : tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime;


            bool householdHasChildren   = household.HasChildren;
            bool householdHasNoChildren = householdHasChildren ? false : true;

            int fastestAvailableTimeOfDay =
                tour.IsHomeBasedTour || tour.ParentTour == null
                      ? 1
                      : tour.ParentTour.DestinationArrivalTime + (tour.ParentTour.DestinationDepartureTime - tour.ParentTour.DestinationArrivalTime) / 2;

            int tourCategory            = tour.GetTourCategory();
            int secondaryFlag           = ChoiceModelUtility.GetSecondaryFlag(tourCategory);
            int workOrSchoolPatternFlag = personDay.GetIsWorkOrSchoolPattern().ToFlag();
            int otherPatternFlag        = personDay.GetIsOtherPattern().ToFlag();
            int jointTourFlag           = (tour.JointTourSequence > 0).ToFlag();

            ChoiceModelUtility.DrawRandomTourTimePeriodsActum(tour, tourCategory);

            int segment = Global.ContainerDaySim.GetInstance <SamplingWeightsSettingsFactory>().SamplingWeightsSettings.GetTourDestinationSegment(tour.DestinationPurpose, tour.IsHomeBasedTour ? Global.Settings.TourPriorities.HomeBasedTour : Global.Settings.TourPriorities.WorkBasedTour, Global.Settings.Modes.Sov, person.PersonType);

            DestinationSampler       destinationSampler       = new DestinationSampler(choiceProbabilityCalculator, segment, sampleSize, choice, tour.OriginParcel);
            TourDestinationUtilities tourDestinationUtilities = new TourDestinationUtilities(tour, sampleSize, secondaryFlag, personDay.GetIsWorkOrSchoolPattern().ToFlag(), personDay.GetIsOtherPattern().ToFlag(), fastestAvailableTimeOfDay, maxAvailableMinutes);

            // get destination sample and perform code that used to be in SetUtilities below
            Dictionary <DestinationSampler.TourSampleItem, int> sampleItems = destinationSampler.SampleAndReturnTourDestinations(tourDestinationUtilities);

            int observedMode = 0;

            if (tour.Mode == Global.Settings.Modes.Bike || tour.Mode == Global.Settings.Modes.Walk)
            {
                observedMode = 0;
            }
            else if (tour.Mode == Global.Settings.Modes.Sov)
            {
                observedMode = 1;
            }
            else if (tour.Mode == Global.Settings.Modes.Hov2 || tour.Mode == Global.Settings.Modes.Hov3)
            {
                observedMode = 2;
            }
            else if (tour.Mode == Global.Settings.Modes.Transit)
            {
                observedMode = 3;
            }

            int purpose = tour.DestinationPurpose;

            if (tour.ParentTour != null)
            {
                purpose = 0;
            }
            int prefix = 0;

            int index     = 0;
            int destindex = 0;
            int indChosen = -1;

            foreach (KeyValuePair <DestinationSampler.TourSampleItem, int> sampleItem in sampleItems)
            {
                bool           parcelAvailable   = sampleItem.Key.Available;
                bool           isChosen          = sampleItem.Key.IsChosen;
                double         adjustmentFactor  = sampleItem.Key.AdjustmentFactor;
                IParcelWrapper destinationParcel = ChoiceModelFactory.Parcels[sampleItem.Key.ParcelId];

                destindex++;
                if (isChosen)
                {
                    indChosen = destindex;
                }

                if (!parcelAvailable)
                {
                    continue;
                }


                int destinationTransitBand1 = (destinationParcel.GetDistanceToTransit() >= 0 && destinationParcel.GetDistanceToTransit() <= 0.25).ToFlag();
                int destinationTransitBand3 = (destinationParcel.GetDistanceToTransit() > 0.5).ToFlag();

                //                var destinationSubzone = _zoneSubzones[destinationParcel.ZoneId][destinationTransitBand3];

                IEnumerable <IPathTypeModel> pathTypeModels =
                    PathTypeModelFactory.Singleton.Run(
                        tour.Household.RandomUtility,
                        originParcel.ZoneId,
                        destinationParcel.ZoneId,
                        tour.DestinationArrivalTime,
                        tour.DestinationDepartureTime,
                        tour.DestinationPurpose,
                        tour.CostCoefficient,
                        tour.TimeCoefficient,
                        tour.Person.IsDrivingAge,
                        tour.Household.VehiclesAvailable,
                        tour.Person.TransitPassOwnership,
                        (tour.Household.OwnsAutomatedVehicles > 0),
                        tour.Person.GetTransitFareDiscountFraction(),
                        false,
                        Global.Settings.Modes.Walk, Global.Settings.Modes.Sov, Global.Settings.Modes.Hov2, Global.Settings.Modes.Transit);

                for (int modeIndex = 0; modeIndex <= 3; modeIndex++)
                {
                    IPathTypeModel pathTypeModel = modeIndex == 0 ? pathTypeModels.First(x => x.Mode == Global.Settings.Modes.Walk)
                                       : modeIndex == 1 ? pathTypeModels.First(x => x.Mode == Global.Settings.Modes.Sov)
                                        : modeIndex == 2 ? pathTypeModels.First(x => x.Mode == Global.Settings.Modes.Hov2)
                                                          : pathTypeModels.First(x => x.Mode == Global.Settings.Modes.Transit);
                    bool modeAvailable = pathTypeModel.Available;
                    bool chosen        = modeIndex == observedMode && destinationParcel == tour.DestinationParcel;

                    //if (chosen) Global.PrintFile.WriteLine("Sequence {0}: Chosen parcel {1} Mode {2} Available {3}",timesStartedRunModel,destinationParcel.Id,observedMode,modeAvailable);
                    ChoiceProbabilityCalculator.Alternative alternative = choiceProbabilityCalculator.GetAlternative(index++, modeAvailable, chosen);
                    alternative.Choice = destinationParcel;

                    if (!modeAvailable)
                    {
                        continue;
                    }

                    alternative.AddUtilityTerm(1, tour.Id);
                    alternative.AddUtilityTerm(9, purpose);

                    if (modeIndex == 0)
                    {
                        // WALK
                        alternative.AddUtilityTerm(prefix + 3, pathTypeModel.GeneralizedTimeLogsum);
                        alternative.AddUtilityTerm(prefix + 4, destinationParcel.NetIntersectionDensity2());
                        alternative.AddUtilityTerm(prefix + 5, destinationParcel.MixedUse4Index2());
                    }
                    else if (modeIndex == 1)
                    {
                        // SOV
                        alternative.AddUtilityTerm(prefix + 3, pathTypeModel.GeneralizedTimeLogsum);
                        alternative.AddUtilityTerm(prefix + 11, 1.0);
                        alternative.AddUtilityTerm(prefix + 12, destinationParcel.ParkingOffStreetPaidHourlyPriceBuffer2);
                        alternative.AddUtilityTerm(prefix + 14, fewerCarsThanDriversFlag);
                        alternative.AddUtilityTerm(prefix + 15, lowIncomeFlag);
                        alternative.AddUtilityTerm(prefix + 16, highIncomeFlag);
                        alternative.AddUtilityTerm(prefix + 17, missingIncomeFlag);
                    }
                    else if (modeIndex == 2)
                    {
                        // HOV
                        alternative.AddUtilityTerm(prefix + 3, pathTypeModel.GeneralizedTimeLogsum);
                        alternative.AddUtilityTerm(prefix + 21, 1.0);
                        alternative.AddUtilityTerm(prefix + 22, childUnder16Flag);
                        alternative.AddUtilityTerm(prefix + 23, noCarsInHouseholdFlag);
                        alternative.AddUtilityTerm(prefix + 24, fewerCarsThanDriversFlag);
                        alternative.AddUtilityTerm(prefix + 25, lowIncomeFlag);
                        alternative.AddUtilityTerm(prefix + 26, highIncomeFlag);
                        alternative.AddUtilityTerm(prefix + 27, missingIncomeFlag);
                    }
                    else
                    {
                        // TRANSIT
                        alternative.AddUtilityTerm(prefix + 3, pathTypeModel.GeneralizedTimeLogsum);
                        alternative.AddUtilityTerm(prefix + 31, 1.0);
                        alternative.AddUtilityTerm(prefix + 32, childUnder16Flag);
                        alternative.AddUtilityTerm(prefix + 33, noCarsInHouseholdFlag);
                        alternative.AddUtilityTerm(prefix + 34, fewerCarsThanDriversFlag);
                        alternative.AddUtilityTerm(prefix + 35, lowIncomeFlag);
                        alternative.AddUtilityTerm(prefix + 36, highIncomeFlag);
                        alternative.AddUtilityTerm(prefix + 37, missingIncomeFlag);
                        alternative.AddUtilityTerm(prefix + 38, originTransitBand1);
                        alternative.AddUtilityTerm(prefix + 39, originTransitBand3);
                        //alternative.AddUtilityTerm(prefix + 40, destinationTransitBand3);
                    }



                    alternative.AddUtilityTerm(2, adjustmentFactor);

                    // Size terms
                    alternative.AddUtilityTerm(prefix + 50, destinationParcel.EmploymentService);
                    alternative.AddUtilityTerm(prefix + 51, destinationParcel.EmploymentEducation);
                    alternative.AddUtilityTerm(prefix + 52, destinationParcel.EmploymentGovernment);
                    //alternative.AddUtilityTerm(prefix + 53, destinationParcel.EmploymentIndustrial);
                    alternative.AddUtilityTerm(prefix + 54, destinationParcel.EmploymentOffice);
                    alternative.AddUtilityTerm(prefix + 55, destinationParcel.EmploymentRetail);
                    alternative.AddUtilityTerm(prefix + 56, destinationParcel.EmploymentMedical);
                    alternative.AddUtilityTerm(prefix + 57, destinationParcel.EmploymentFood);
                    //alternative.AddUtilityTerm(prefix + 58, destinationParcel.EmploymentAgricultureConstruction);
                    alternative.AddUtilityTerm(prefix + 59, destinationParcel.Households);
                    //alternative.AddUtilityTerm(prefix + 60, destinationParcel.StudentsK8 + destinationParcel.StudentsHighSchool);
                    //alternative.AddUtilityTerm(prefix + 61, destinationParcel.StudentsUniversity);
                }
            }
            //Global.PrintFile.WriteLine("Sequence {0}: Chosen parcel {1} is sample item {2} of {3}",timesStartedRunModel,tour.DestinationParcelId,indChosen,sampleItems.Count);
        }
예제 #6
0
            public void SetUtilities(ISampleItem sampleItem, int sampleFrequency)
            {
                if (sampleItem == null)
                {
                    throw new ArgumentNullException("sampleItem");
                }

                var alternative = sampleItem.Alternative;

                var household = _tour.Household;
                var person    = _tour.Person;
                var personDay = _tour.PersonDay;
//				var householdHasChildren = household.HasChildren;

                var destinationParcel = ChoiceModelFactory.Parcels[sampleItem.ParcelId];

                var excludedParcel      = person.UsualWorkParcel == null || person.UsualWorkParcelId == household.ResidenceParcelId || _tour.DestinationPurpose != Global.Settings.Purposes.Work || _tour.GetTourCategory() == Global.Settings.TourCategories.WorkBased ? null : person.UsualWorkParcel;
                var usualWorkParcel     = (excludedParcel != null && excludedParcel.Id == destinationParcel.Id);             // only 1 for oddball alternative on tours with oddball alternative
                var usualWorkParcelFlag = usualWorkParcel.ToFlag();

                // Comment out these nesting calls when estimating the conditional flat model
                // model is NL with oddball alternative
                if (usualWorkParcelFlag == 0)
                {
                    // this alternative is in the non-oddball nest
                    alternative.AddNestedAlternative(_sampleSize + 2, 0, 60);                     // associates alternative with non-oddball nest
                }
                else
                {
                    // this is the oddball alternative
                    alternative.AddNestedAlternative(_sampleSize + 3, 1, 60);                     // associates alternative with oddball nest
                }


                if (!alternative.Available)
                {
                    return;
                }


                // use this block of code to eliminate the oddball alternative for estimation of the conditional model
                //if (usualWorkParcelFlag == 1) {
                //	alternative.Available = false;
                //
                //	return;
                //}

                var fastestTravelTime =
                    ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Hov3, Global.Settings.PathTypes.FullNetwork, Global.Settings.ValueOfTimes.DefaultVot, _fastestAvailableTimeOfDay, _tour.OriginParcel, destinationParcel).Variable +
                    ImpedanceRoster.GetValue("ivtime", Global.Settings.Modes.Hov3, Global.Settings.PathTypes.FullNetwork, Global.Settings.ValueOfTimes.DefaultVot, _fastestAvailableTimeOfDay, destinationParcel, _tour.OriginParcel).Variable;

                if (fastestTravelTime >= _maxAvailableMinutes)
                {
                    alternative.Available = false;

                    return;
                }

                alternative.Choice = destinationParcel;

                double tourLogsum;

                if (_tour.IsHomeBasedTour)
                {
                    var nestedAlternative = Global.ChoiceModelSession.Get <WorkTourModeModel>().RunNested(_tour, destinationParcel, household.VehiclesAvailable, person.GetTransitFareDiscountFraction());
                    tourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                }
                else
                {
                    var nestedAlternative = Global.ChoiceModelSession.Get <WorkBasedSubtourModeModel>().RunNested(_tour, destinationParcel);
                    tourLogsum = nestedAlternative == null ? 0 : nestedAlternative.ComputeLogsum();
                }

                //var purpose = _tour.TourPurposeSegment;
                //var nonWorkPurpose = _tour.DestinationPurpose != Global.Settings.Purposes.Work;
                var carOwnership = person.GetCarOwnershipSegment();
                //var votSegment = _tour.VotALSegment;
                //var transitAccess = destinationParcel.TransitAccessSegment();
                //var aggregateLogsum = Global.AggregateLogsums[destinationParcel.ZoneId][purpose][carOwnership][votSegment][transitAccess];
                //var aggregateLogsumHomeBased = Global.AggregateLogsums[destinationParcel.ZoneId][Global.Settings.Purposes.HomeBasedComposite][carOwnership][votSegment][transitAccess];
                //var aggregateLogsumWorkBased = Global.AggregateLogsums[destinationParcel.ZoneId][Global.Settings.Purposes.Work_BASED][carOwnership][votSegment][transitAccess];

                var distanceFromOrigin = _tour.OriginParcel.DistanceFromOrigin(destinationParcel, _tour.DestinationArrivalTime);
//				var distanceFromOrigin0 = Math.Max(0, Math.Min(distanceFromOrigin - .5, 1 - .5));
//				var distanceFromOrigin3 = Math.Max(0, distanceFromOrigin - 1);
//				var distanceFromOrigin4 = Math.Min(distanceFromOrigin, .10);
//				var distanceFromOrigin5 = Math.Max(0, Math.Min(distanceFromOrigin - .1, .5 - .1));
//				var distanceFromOrigin8 = Math.Max(0, Math.Min(distanceFromOrigin - .1, .35 - .1));
//				var distanceFromOrigin9 = Math.Max(0, Math.Min(distanceFromOrigin - .35, 1 - .35));
                var distanceFromOriginLog = Math.Log(1 + distanceFromOrigin);
                var distanceFromWorkLog   = person.UsualWorkParcel.DistanceFromWorkLog(destinationParcel, 1);
                var distanceFromSchoolLog = person.UsualSchoolParcel.DistanceFromSchoolLog(destinationParcel, 1);
//				var millionsSquareFeet = destinationZoneTotals.MillionsSquareFeet();

                var timePressure = Math.Log(1 - fastestTravelTime / _maxAvailableMinutes);

                // log transforms of buffers for Neighborhood effects
                var empEduBuffer = Math.Log(destinationParcel.EmploymentEducationBuffer1 + 1.0);
//				var EMPFOO_B = Math.Log(destinationParcel.EmploymentFoodBuffer1 + 1.0);
//				var EMPGOV_B = Math.Log(destinationParcel.EmploymentGovernmentBuffer1 + 1.0);
                var empOfcBuffer = Math.Log(destinationParcel.EmploymentOfficeBuffer1 + 1.0);
//				var EMPRET_B = Math.Log(destinationParcel.EmploymentRetailBuffer1 + 1.0);
//				var EMPSVC_B = Math.Log(destinationParcel.EmploymentServiceBuffer1 + 1.0);
//				var EMPMED_B = Math.Log(destinationParcel.EmploymentMedicalBuffer1 + 1.0);
                var empIndBuffer = Math.Log(destinationParcel.EmploymentIndustrialBuffer1 + destinationParcel.EmploymentAgricultureConstructionBuffer1 + 1.0);
//				var EMPTOT_B = Math.Log(destinationParcel.EmploymentTotalBuffer1 + 1.0);
                var housesBuffer = Math.Log(destinationParcel.HouseholdsBuffer1 + 1.0);
//				var STUDK12B = Math.Log(destinationParcel.StudentsK8Buffer1 + destinationParcel.StudentsHighSchoolBuffer1 + 1.0);
//				var STUDUNIB = Math.Log(destinationParcel.StudentsUniversityBuffer1 + 1.0);
//				var EMPHOU_B = Math.Log(destinationParcel.EmploymentTotalBuffer1 + destinationParcel.HouseholdsBuffer1 + 1.0);

                // parking attributes
//				var parcelParkingDensity = destinationParcel.ParcelParkingPerTotalEmployment();
//				var zoneParkingDensity = destinationParcel.ZoneParkingPerTotalEmploymentAndK12UniversityStudents(destinationZoneTotals, millionsSquareFeet);
//				var ParkingPaidDailyLogBuffer1 = Math.Log(1 + destinationParcel.ParkingOffStreetPaidDailySpacesBuffer1);

                // connectivity attributes
//				var c34Ratio = destinationParcel.C34RatioBuffer1();

                //				var carDeficitFlag = FlagUtility.GetCarDeficitFlag(carOwnership);  // includes no cars
                //				var carCompetitionFlag = FlagUtility.GetCarCompetitionFlag(carOwnership); // exludes no cars
                var noCarCompetitionFlag = FlagUtility.GetNoCarCompetitionFlag(carOwnership);

                //				var noCarsFlag = FlagUtility.GetNoCarsFlag(carOwnership);

                // Usual location attributes
                alternative.AddUtilityTerm(1, usualWorkParcelFlag);
                alternative.AddUtilityTerm(2, person.IsPartTimeWorker.ToFlag() * usualWorkParcelFlag);
                alternative.AddUtilityTerm(3, person.IsStudentAge.ToFlag() * usualWorkParcelFlag);
                alternative.AddUtilityTerm(4, _primaryFlag * personDay.TwoOrMoreWorkToursExist().ToFlag() * usualWorkParcelFlag);
                alternative.AddUtilityTerm(5, personDay.WorkStopsExist().ToFlag() * usualWorkParcelFlag);
                alternative.AddUtilityTerm(6, _secondaryFlag * usualWorkParcelFlag);

                // non-usual location attributes
                alternative.AddUtilityTerm(11, (!usualWorkParcel).ToFlag() * sampleItem.AdjustmentFactor);
                alternative.AddUtilityTerm(12, _tour.IsHomeBasedTour.ToFlag() * (!usualWorkParcel).ToFlag() * timePressure);

                alternative.AddUtilityTerm(13, (!usualWorkParcel).ToFlag() * person.IsFulltimeWorker.ToFlag() * tourLogsum);
                alternative.AddUtilityTerm(14, (!usualWorkParcel).ToFlag() * person.IsPartTimeWorker.ToFlag() * tourLogsum);
                alternative.AddUtilityTerm(15, (!usualWorkParcel).ToFlag() * person.IsNotFullOrPartTimeWorker.ToFlag() * tourLogsum);
                alternative.AddUtilityTerm(16, (!usualWorkParcel).ToFlag() * person.IsRetiredAdult.ToFlag() * distanceFromOriginLog);

                alternative.AddUtilityTerm(17, (!usualWorkParcel).ToFlag() * distanceFromWorkLog);
                alternative.AddUtilityTerm(18, (!usualWorkParcel).ToFlag() * person.IsStudentAge.ToFlag() * distanceFromSchoolLog);

                alternative.AddUtilityTerm(19, (!usualWorkParcel).ToFlag() * noCarCompetitionFlag * destinationParcel.ParkingHourlyEmploymentCommercialMixBuffer1());

                // non-usual location Neighborhood attributes
                alternative.AddUtilityTerm(31, (!usualWorkParcel).ToFlag() * empEduBuffer);
                alternative.AddUtilityTerm(32, (!usualWorkParcel).ToFlag() * empOfcBuffer);
                alternative.AddUtilityTerm(33, (!usualWorkParcel).ToFlag() * housesBuffer);
                alternative.AddUtilityTerm(34, (!usualWorkParcel).ToFlag() * empIndBuffer);

                // non-usual location Size terms (consider conditioning these by fulltime, parttime, notFTPT, an income (see original sacog spec)
                alternative.AddUtilityTerm(40, (!usualWorkParcel).ToFlag() * destinationParcel.EmploymentEducation);
                alternative.AddUtilityTerm(41, (!usualWorkParcel).ToFlag() * destinationParcel.EmploymentFood);
                alternative.AddUtilityTerm(42, (!usualWorkParcel).ToFlag() * destinationParcel.EmploymentGovernment);
                alternative.AddUtilityTerm(43, (!usualWorkParcel).ToFlag() * destinationParcel.EmploymentOffice);
                alternative.AddUtilityTerm(44, (!usualWorkParcel).ToFlag() * destinationParcel.EmploymentRetail);
                alternative.AddUtilityTerm(45, (!usualWorkParcel).ToFlag() * destinationParcel.EmploymentService);
                alternative.AddUtilityTerm(46, (!usualWorkParcel).ToFlag() * destinationParcel.EmploymentMedical);
                alternative.AddUtilityTerm(47, (!usualWorkParcel).ToFlag() * destinationParcel.EmploymentIndustrial + destinationParcel.EmploymentAgricultureConstruction);
                alternative.AddUtilityTerm(48, (!usualWorkParcel).ToFlag() * destinationParcel.Households);
                alternative.AddUtilityTerm(49, (!usualWorkParcel).ToFlag() * destinationParcel.StudentsUniversity);

                //		// usual location size term
                //		alternative.AddUtilityTerm(50, usualWorkParcelFlag * 1);

                //		// Comment out these nesting calls when estimating the conditional flat model
                //		// model is NL with oddball alternative
                //		if (usualWorkParcelFlag == 0) {
                //			// this alternative is in the non-oddball nest
                //			alternative.AddNestedAlternative(_sampleSize + 2, 0, 60); // associates alternative with non-oddball nest
                //		}
                //		else {
                //			// this is the oddball alternative
                //			alternative.AddNestedAlternative(_sampleSize + 3, 1, 60); // associates alternative with oddball nest
                //		}
            }