From 88d76daa24640a09601a7b2122a3f45d75914123 Mon Sep 17 00:00:00 2001 From: Corin Staves Date: Wed, 23 Oct 2024 00:48:52 +0200 Subject: [PATCH] Destination intervention update, new mode choice models --- .../java/accessibility/RunIntervention.java | 45 ++++++--- .../java/estimation/RunMnlManchester.java | 12 ++- .../estimation/dynamic/RouteDataDynamic.java | 13 ++- .../specifications/manchester/HBA.java | 89 ++++++++++++++++++ .../specifications/manchester/NHBO.java | 94 +++++++++++++++++++ .../specifications/manchester/NHBW.java | 89 ++++++++++++++++++ 6 files changed, 320 insertions(+), 22 deletions(-) create mode 100644 src/main/java/estimation/specifications/manchester/HBA.java create mode 100644 src/main/java/estimation/specifications/manchester/NHBO.java create mode 100644 src/main/java/estimation/specifications/manchester/NHBW.java diff --git a/src/main/java/accessibility/RunIntervention.java b/src/main/java/accessibility/RunIntervention.java index 3328c7e..0627244 100644 --- a/src/main/java/accessibility/RunIntervention.java +++ b/src/main/java/accessibility/RunIntervention.java @@ -3,6 +3,7 @@ import accessibility.decay.*; import accessibility.resources.AccessibilityProperties; import accessibility.resources.AccessibilityResources; +import com.google.common.math.LongMath; import gis.GisUtils; import gis.GpkgReader; import io.ioUtils; @@ -207,40 +208,52 @@ private static void runIntervention(String propertiesFilepath) throws IOExceptio // Write new node locations log.info("Writing new node locations..."); - printNewDestinations(destinationsOutputFile, network, candidateNodeIdMap, demand, newDestinations, newDestinationWeight, destinationDescriptions); + printNewDestinations(destinationsOutputFile, network, candidateNodeIdMap, population, supply, demand, newDestinations, newDestinationWeight, destinationDescriptions); // Write changes in population accessibility if(demandOutputFile != null) { log.info("Writing demand-side output for each (potential) destination node..."); - writeEachIteration(demandOutputFile, network, candidateNodeIdMap, demand, destinationDescriptions); + writeEachIteration(demandOutputFile, network, candidateNodeIdMap, demand, destinationDescriptions,false); } if(supplyOutputFile != null) { log.info("Writing supply-side output for each population location and iteration..."); - writeEachIteration(supplyOutputFile, network, populationNodeIdMap, supply, destinationDescriptions); + writeEachIteration(supplyOutputFile, network, populationNodeIdMap, supply, destinationDescriptions,true); } } // Prints new destinations and details - private static void printNewDestinations(String outputFile, Network network, IdMap nodes, - List,double[]>> demand, List>> newNodes, - double[] newWeights, + private static void printNewDestinations(String outputFile, Network network, IdMap nodes, IdMap population, + List, double[]>> supply, List,double[]>> demand, + List>> newNodes, double[] newWeights, List destinationDescriptions) { PrintWriter out = ioUtils.openFileForSequentialWriting(new File(outputFile),false); assert out != null; // Write header - out.println("type" + SEP + "n" + SEP + "id" + SEP + "nodeId" + SEP + "x" + SEP + "y" + SEP + "weight" + SEP + "demand"); + out.println("type" + SEP + "n" + SEP + "id" + SEP + "nodeId" + SEP + "x" + SEP + "y" + SEP + "weight" + SEP + "demand" + SEP + "supply" + SEP + "supplyRatio"); // Write rows int i = 0; for(List> iteration : newNodes) { int j = 0; - for(Id nodeId : iteration) { - Coord coord = network.getNodes().get(nodeId).getCoord(); - String line = destinationDescriptions.get(j) + SEP + i + SEP + nodes.get(nodeId) + SEP + nodeId.toString() + SEP + - coord.getX() + SEP + coord.getY() + SEP + newWeights[j] + SEP + demand.get(i).get(nodeId)[j]; + for(Id destNodeId : iteration) { + Coord coord = network.getNodes().get(destNodeId).getCoord(); + double supplyRatio = 0; + double supplyTotal = 0; + for(Map.Entry,Double> e : population.entrySet()) { + Id popNodeId = e.getKey(); + double pop = e.getValue(); + double supplyAtNode = supply.get(i+1).get(popNodeId)[j]; + if(supplyAtNode > 0) { + supplyTotal += pop * supplyAtNode; + supplyRatio += pop * (1 - supply.get(0).get(popNodeId)[j] / supplyAtNode); + } + } + String line = destinationDescriptions.get(j) + SEP + i + SEP + nodes.get(destNodeId) + SEP + destNodeId.toString() + SEP + + coord.getX() + SEP + coord.getY() + SEP + newWeights[j] + SEP + demand.get(i).get(destNodeId)[j] + SEP + + supplyTotal + SEP + supplyRatio; out.println(line); j++; } @@ -250,7 +263,7 @@ private static void printNewDestinations(String outputFile, Network network, IdM } private static void writeEachIteration(String outputFile, Network network, IdMap nodes, List,double[]>> results, - List destinationDescriptions) { + List destinationDescriptions, boolean sparse) { PrintWriter out = ioUtils.openFileForSequentialWriting(new File(outputFile),false); assert out != null; @@ -260,7 +273,9 @@ private static void writeEachIteration(String outputFile, Network network, IdMap StringBuilder builder = new StringBuilder(); builder.append("id").append(SEP).append("node").append(SEP).append("x").append(SEP).append("y").append(SEP).append("type"); for(int i = 0 ; i < iterations ; i++) { - builder.append(SEP).append("it_").append(i); + if(i == 0 || LongMath.isPowerOfTwo(i) || !sparse) { + builder.append(SEP).append("it_").append(i); + } } out.println(builder); @@ -271,7 +286,9 @@ private static void writeEachIteration(String outputFile, Network network, IdMap builder = new StringBuilder(); builder.append(e.getValue()).append(SEP).append(e.getKey()).append(SEP).append(coord.getX()).append(SEP).append(coord.getY()).append(SEP).append(destinationDescriptions.get(j)); for (int i = 0; i < iterations; i++) { - builder.append(SEP).append(results.get(i).get(e.getKey())[j]); + if(i == 0 || LongMath.isPowerOfTwo(i) || !sparse) { + builder.append(SEP).append(results.get(i).get(e.getKey())[j]); + } } out.println(builder); } diff --git a/src/main/java/estimation/RunMnlManchester.java b/src/main/java/estimation/RunMnlManchester.java index 6223ed3..0e48c3d 100644 --- a/src/main/java/estimation/RunMnlManchester.java +++ b/src/main/java/estimation/RunMnlManchester.java @@ -1,7 +1,10 @@ package estimation; import estimation.specifications.AbstractModelSpecification; +import estimation.specifications.manchester.HBA; import estimation.specifications.manchester.HBD; +import estimation.specifications.manchester.NHBO; +import estimation.specifications.manchester.NHBW; import gis.GisUtils; import gis.GpkgReader; import io.DiaryReader; @@ -18,6 +21,7 @@ import routing.Bicycle; import routing.travelTime.WalkTravelTime; import smile.classification.ClassLabels; +import trip.Place; import trip.Trip; import java.io.IOException; @@ -89,13 +93,13 @@ public static void main(String[] args) throws IOException, FactoryException { TravelTime ttWalk = new WalkTravelTime(); TravelTime ttBike = bicycle.getTravelTimeFast(networkBike); - // Deal with intrazonal trips – can remove after we get X/Y coordinates for TRADS) - Set OAs = GisUtils.readGpkg("zones/2011/gm_oa.gpkg"); + // Deal with intrazonal trips – can remove after we get X/Y coordinates for TRADS + Set OAs = GisUtils.readGpkg("zones/2011/gm_oa_buf.gpkg"); // Initialise utility specification - u = new HBD(logitData,trip_data,OAs,networkBike,bike,ttBike,networkWalk,null,ttWalk); + u = new NHBO(logitData,trip_data,OAs,networkBike,bike,ttBike,networkWalk,null,ttWalk); } else { - u = new HBD(logitData,null,null,null,null,null,null,null,null); + u = new NHBO(logitData,null,null,null,null,null,null,null,null); } // Start model diff --git a/src/main/java/estimation/dynamic/RouteDataDynamic.java b/src/main/java/estimation/dynamic/RouteDataDynamic.java index 1cad3fb..d02b12c 100644 --- a/src/main/java/estimation/dynamic/RouteDataDynamic.java +++ b/src/main/java/estimation/dynamic/RouteDataDynamic.java @@ -34,7 +34,7 @@ public class RouteDataDynamic implements RouteData, DynamicComponent { - private final static boolean ENABLE_DYNAMIC_ROUTING = false; + private final static boolean ENABLE_DYNAMIC_ROUTING = true; private final static Logger logger = Logger.getLogger(RouteDataDynamic.class); private final int numberOfThreads; final int tripCount; @@ -215,7 +215,7 @@ public double getAttribute(int i, int j) { } public void update(double[] xVarOnly) { - if(ENABLE_DYNAMIC_ROUTING) { + if(ENABLE_DYNAMIC_ROUTING && !attributes.isEmpty()) { updatePathData(xVarOnly); computeRouteStats(); } @@ -392,7 +392,7 @@ private static void computeIntrazonalTripData(PathData pathData, Trip[] trips, A // Determine set of links for each zone Map> linksPerFeature = GisUtils.calculateLinksIntersectingZones(zones,net); - Map> linksPerZone = linksPerFeature.entrySet().stream().collect(Collectors.toMap(e -> ((String) e.getKey().getAttribute("geo_code")), Map.Entry::getValue)); + Map> linksPerZone = linksPerFeature.entrySet().stream().collect(Collectors.toMap(e -> ((String) e.getKey().getAttribute("OA11CD")), Map.Entry::getValue)); // Identify intrazonal trips int intrazonalTripCount = 0; @@ -410,7 +410,12 @@ private static void computeIntrazonalTripData(PathData pathData, Trip[] trips, A } double totLength = 0; double[] totAttributes = new double[attributes.size()]; - for(Id linkId : linksPerZone.get(trips[i].getZone(Place.ORIGIN))) { + IdSet linkIds = linksPerZone.get(trips[i].getZone(ORIGIN)); + if(linkIds == null) { + throw new RuntimeException("No zone data for intrazonal trip, household " + trips[i].getHouseholdId() + + " person " + trips[i].getPersonId() + " trip " + trips[i].getTripId()); + } + for(Id linkId : linkIds) { Link link = net.getLinks().get(linkId); double linkLength = link.getLength(); totLength += linkLength; diff --git a/src/main/java/estimation/specifications/manchester/HBA.java b/src/main/java/estimation/specifications/manchester/HBA.java new file mode 100644 index 0000000..0ad788c --- /dev/null +++ b/src/main/java/estimation/specifications/manchester/HBA.java @@ -0,0 +1,89 @@ +package estimation.specifications.manchester; + +import estimation.LogitData; +import estimation.RouteAttribute; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.network.Network; +import org.matsim.core.router.util.TravelTime; +import org.matsim.vehicles.Vehicle; +import org.opengis.feature.simple.SimpleFeature; +import routing.Gradient; +import routing.disutility.components.JctStress; +import routing.disutility.components.LinkAmbience; +import routing.disutility.components.LinkStress; +import trip.Trip; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class HBA extends MNL_Manchester { + + private final static List SOCIODEMOGRAPHIC_VARIABLES = List.of( + "p.age_group_agg_5_24","p.age_group_agg_40_69","p.age_group_agg_70", + "p.female", + "p.occupation_worker", + "hh.cars_gr_0","hh.cars_gr_2","hh.cars_gr_3"); + + public HBA(LogitData data, Trip[] trips, Set OAs, + Network netBike, Vehicle vehBike, TravelTime ttBike, + Network netWalk, Vehicle vehWalk, TravelTime ttWalk) { + super(data,trips,OAs,netBike,vehBike,ttBike,netWalk,vehWalk,ttWalk); + } + + @Override + List sociodemographicVariables() { + return SOCIODEMOGRAPHIC_VARIABLES; + } + + List streetEnvironmentAttributesBike() { + List bike = new ArrayList<>(); +// bike.add(new RouteAttribute("g_bike_grad", l -> Math.max(Math.min(Gradient.getGradient(l),0.5),0.))); +// bike.add(new RouteAttribute("g_bike_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l)))); +// bike.add(new RouteAttribute("g_bike_stressLink", l -> LinkStress.getStress(l, TransportMode.bike))); + return bike; + } + + List streetEnvironmentAttributesWalk() { + List walk = new ArrayList<>(); + walk.add(new RouteAttribute("g_walk_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l)))); +// walk.add(new RouteAttribute("g_walk_stressJct", l -> JctStress.getStressProp(l,TransportMode.walk))); +// walk.add(new RouteAttribute("g_walk_speed", l -> Math.min(1.,l.getFreespeed() / 22.35))); +// walk.add(new RouteAttribute("g_walk_aadt", l -> Math.min(1.,((int) l.getAttributes().getAttribute("aadt")) * 0.865/6000.))); + return walk; + } + + @Override + protected List fixed() { + List fixed = coefficients().keySet().stream().filter(s -> (s.contains("carD"))).collect(Collectors.toList()); + fixed.add("b_pt_hh.cars_gr_2"); + fixed.add("b_pt_hh.cars_gr_3"); + fixed.add("b_bike_hh.cars_gr_0"); + fixed.add("b_bike_hh.cars_gr_2"); + fixed.add("b_bike_hh.cars_gr_3"); + fixed.add("b_bike_p.female"); + fixed.add("b_walk_hh.cars_gr_2"); + fixed.add("b_pt_p.age_group_agg_5_24"); + fixed.add("b_pt_p.age_group_agg_40_69"); + fixed.add("b_pt_p.age_group_agg_70"); + fixed.add("b_bike_p.age_group_agg_5_24"); + fixed.add("b_bike_p.age_group_agg_40_69"); + fixed.add("b_bike_p.age_group_agg_70"); + fixed.add("b_bike_p.occupation_worker"); +// fixed.add("b_carP_p.age_group_agg_5_14"); +// fixed.add("b_carP_hh.income_agg_high"); +// fixed.add("b_carP_t.full_purpose_HBO"); +// fixed.add("b_bike_p.age_group_agg_40_69"); +// fixed.add("b_bike_hh.income_agg_high"); +// fixed.add("g_bike_vgvi"); +// fixed.add("g_bike_stressJct"); +// fixed.add("g_bike_stressJct_f"); +// fixed.add("g_bike_stressJct_c"); +// fixed.add("g_walk_grad"); +// fixed.add("g_walk_stressLink"); +// fixed.add("g_walk_stressLink_f"); +// fixed.add("g_walk_stressJct_f"); + return fixed; + } +} diff --git a/src/main/java/estimation/specifications/manchester/NHBO.java b/src/main/java/estimation/specifications/manchester/NHBO.java new file mode 100644 index 0000000..9388c4d --- /dev/null +++ b/src/main/java/estimation/specifications/manchester/NHBO.java @@ -0,0 +1,94 @@ +package estimation.specifications.manchester; + +import estimation.LogitData; +import estimation.RouteAttribute; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.network.Network; +import org.matsim.core.router.util.TravelTime; +import org.matsim.vehicles.Vehicle; +import org.opengis.feature.simple.SimpleFeature; +import routing.Gradient; +import routing.disutility.components.JctStress; +import routing.disutility.components.LinkAmbience; +import routing.disutility.components.LinkStress; +import trip.Trip; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class NHBO extends MNL_Manchester { + + private final static List SOCIODEMOGRAPHIC_VARIABLES = List.of( + "p.age_group_agg_5_14","p.age_group_agg_15_24","p.age_group_agg_40_69","p.age_group_agg_70", + "p.female", + "p.occupation_worker", + "hh.cars_gr_0","hh.cars_gr_23"); + + public NHBO(LogitData data, Trip[] trips, Set OAs, + Network netBike, Vehicle vehBike, TravelTime ttBike, + Network netWalk, Vehicle vehWalk, TravelTime ttWalk) { + super(data,trips,OAs,netBike,vehBike,ttBike,netWalk,vehWalk,ttWalk); + } + + @Override + List sociodemographicVariables() { + return SOCIODEMOGRAPHIC_VARIABLES; + } + + List streetEnvironmentAttributesBike() { + List bike = new ArrayList<>(); +// bike.add(new RouteAttribute("g_bike_grad", l -> Math.max(Math.min(Gradient.getGradient(l),0.5),0.))); +// bike.add(new RouteAttribute("g_bike_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l)))); +// bike.add(new RouteAttribute("g_bike_stressLink", l -> LinkStress.getStress(l, TransportMode.bike))); + return bike; + } + + List streetEnvironmentAttributesWalk() { + List walk = new ArrayList<>(); +// walk.add(new RouteAttribute("g_walk_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l)))); +// walk.add(new RouteAttribute("g_walk_stressJct", l -> JctStress.getStressProp(l,TransportMode.walk))); + walk.add(new RouteAttribute("g_walk_speed", l -> Math.min(1.,l.getFreespeed() / 22.35))); +// walk.add(new RouteAttribute("g_walk_aadt", l -> Math.min(1.,((int) l.getAttributes().getAttribute("aadt")) * 0.865/6000.))); +// walk.add(new RouteAttribute("g_walk_speed_aadt", l -> Math.min(1.,l.getFreespeed() / 22.35) * Math.min(1.,((int) l.getAttributes().getAttribute("aadt")) * 0.865/6000.))); + return walk; + } + + @Override + protected List fixed() { + List fixed = coefficients().keySet().stream().filter(s -> (s.contains("carD"))).collect(Collectors.toList()); + fixed.add("b_carP_p.age_group_agg_5_14"); + fixed.add("b_carP_hh.cars_gr_0"); + fixed.add("b_bike_p.age_group_agg_5_14"); + fixed.add("b_bike_p.age_group_agg_15_24"); + fixed.add("b_bike_p.age_group_agg_40_69"); + fixed.add("b_bike_p.age_group_agg_70"); + fixed.add("b_pt_p.age_group_agg_40_69"); + fixed.add("b_pt_p.age_group_agg_70"); +// fixed.add("b_pt_p.occupation_worker"); + fixed.add("b_bike_hh.cars_gr_0"); + fixed.add("b_bike_hh.cars_gr_23"); + fixed.add("b_bike_p.female"); + fixed.add("b_bike_p.occupation_worker"); + fixed.add("b_carP_hh.cars_gr_23"); + fixed.add("b_walk_hh.cars_gr_23"); + fixed.add("b_carP_p.age_group_agg_40_69"); + fixed.add("b_carP_p.age_group_agg_70"); +// fixed.add("b_carP_t.full_purpose_HBO"); +// fixed.add("b_pt_hh.income_agg_high"); + fixed.add("b_walk_p.occupation_worker"); + fixed.add("b_walk_p.female"); + fixed.add("b_pt_p.female"); + +// fixed.add("g_bike_vgvi"); +// fixed.add("g_bike_stressJct"); +// fixed.add("g_bike_stressJct_f"); +// fixed.add("g_bike_stressJct_c"); +// fixed.add("g_walk_grad"); +// fixed.add("g_walk_stressLink"); +// fixed.add("g_walk_stressLink_f"); +// fixed.add("g_walk_stressJct_f"); + return fixed; + } +} diff --git a/src/main/java/estimation/specifications/manchester/NHBW.java b/src/main/java/estimation/specifications/manchester/NHBW.java new file mode 100644 index 0000000..9dee73b --- /dev/null +++ b/src/main/java/estimation/specifications/manchester/NHBW.java @@ -0,0 +1,89 @@ +package estimation.specifications.manchester; + +import estimation.LogitData; +import estimation.RouteAttribute; +import org.matsim.api.core.v01.TransportMode; +import org.matsim.api.core.v01.network.Network; +import org.matsim.core.router.util.TravelTime; +import org.matsim.vehicles.Vehicle; +import org.opengis.feature.simple.SimpleFeature; +import routing.Gradient; +import routing.disutility.components.JctStress; +import routing.disutility.components.LinkAmbience; +import routing.disutility.components.LinkStress; +import trip.Trip; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class NHBW extends MNL_Manchester { + + private final static List SOCIODEMOGRAPHIC_VARIABLES = List.of( + "p.age_group_agg_15_24", + "p.female", + "hh.cars_gr_0","hh.cars_gr_23", + "hh.income_agg_high"); + + public NHBW(LogitData data, Trip[] trips, Set OAs, + Network netBike, Vehicle vehBike, TravelTime ttBike, + Network netWalk, Vehicle vehWalk, TravelTime ttWalk) { + super(data,trips,OAs,netBike,vehBike,ttBike,netWalk,vehWalk,ttWalk); + } + + @Override + List sociodemographicVariables() { + return SOCIODEMOGRAPHIC_VARIABLES; + } + + List streetEnvironmentAttributesBike() { + List bike = new ArrayList<>(); +// bike.add(new RouteAttribute("g_bike_grad", l -> Math.max(Math.min(Gradient.getGradient(l),0.5),0.))); +// bike.add(new RouteAttribute("g_bike_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l)))); +// bike.add(new RouteAttribute("g_bike_stressLink", l -> LinkStress.getStress(l, TransportMode.bike))); + return bike; + } + + List streetEnvironmentAttributesWalk() { + List walk = new ArrayList<>(); +// bike.add(new BuiltEnvironmentAttribute("grad",l -> Math.max(Math.min(Gradient.getGradient(l),0.5),0.),p -> true)); +// walk.add(new RouteAttribute("g_walk_vgvi", l -> Math.max(0.,0.81 - LinkAmbience.getVgviFactor(l)))); +// walk.add(new RouteAttribute("g_walk_stressJct", l -> JctStress.getStressProp(l,TransportMode.walk))); +// walk.add(new RouteAttribute("g_walk_speed", l -> Math.min(1.,l.getFreespeed() / 22.35))); +// walk.add(new RouteAttribute("g_walk_speed_c", "g_walk_speed", i -> value(i,"p.age_group_agg_5_14") == 1)); +// walk.add(new RouteAttribute("g_walk_speed_o", "g_walk_speed", i -> value(i,"p.age_65up") == 1)); +// walk.add(new RouteAttribute("g_walk_aadt", l -> Math.min(1.,((int) l.getAttributes().getAttribute("aadt")) * 0.865/6000.))); +// walk.add(new RouteAttribute("g_walk_aadt_c", "g_walk_aadt", i -> value(i,"p.age_group_agg_5_14") == 1)); +// walk.add(new RouteAttribute("g_walk_aadt_o", "g_walk_aadt", i -> value(i,"p.age_65up") == 1)); + +// walk.add(new RouteAttribute("g_walk_speed_aadt", l -> Math.min(1.,l.getFreespeed() / 22.35) * Math.min(1.,((int) l.getAttributes().getAttribute("aadt")) * 0.865/6000.))); + return walk; + } + + @Override + protected List fixed() { + List fixed = coefficients().keySet().stream().filter(s -> (s.contains("carD") | s.contains("bike"))).collect(Collectors.toList()); + fixed.remove("asc_bike"); + fixed.remove("b_bike_cost"); + fixed.add("b_pt_p.female"); + fixed.add("b_carP_p.female"); + fixed.add("b_walk_p.age_group_agg_15_24"); + fixed.add("b_walk_hh.cars_gr_23"); +// fixed.add("b_carP_p.age_group_agg_5_14"); + fixed.add("b_carP_hh.income_agg_high"); +// fixed.add("b_carP_t.full_purpose_HBO"); +// fixed.add("b_bike_p.age_group_agg_40_69"); +// fixed.add("b_bike_hh.income_agg_high"); +// fixed.add("b_walk_hh.income_agg_high"); +// fixed.add("g_bike_vgvi"); +// fixed.add("g_bike_stressJct"); +// fixed.add("g_bike_stressJct_f"); +// fixed.add("g_bike_stressJct_c"); +// fixed.add("g_walk_grad"); +// fixed.add("g_walk_stressLink"); +// fixed.add("g_walk_stressLink_f"); +// fixed.add("g_walk_stressJct_f"); + return fixed; + } +}