如何以编程方式设置 Repast 文件接收器文件名?

How can the Repast file sink filename be set programmatically?

有谁知道是否有一种简单的方法可以根据模型中的一个字段制作文件接收器变量的文件名元素路径? 所以不要使用像 :

这样的修复路径

fixed_path/filename.csv

{variable_path}/filename.csv

附加的 ModelInitializer 展示了如何做到这一点。我还复制了下面的代码,以防附件无法通过。要启用 ModelInitializer,您需要将以下内容添加到 scenario.xml 文件:

 <model.initializer class="PredatorPrey.MyInitializer" />

我在 Predator Prey 演示中对此进行了测试,因此您应该更改 class 程序包名称。在 ModelInitializer 示例中,您需要指定与 context.xml 文件中的上下文 ID 相同的根上下文 ID。并且您应该指定变量输出文件夹名称。此示例需要像往常一样在文件接收器中指定文件名,并插入变量路径。需要注意的是,如果场景保存在 GUI 中,可变文件夹路径将保存在场景中,但是此代码将检查任何现有路径,并简单地将路径替换为 outputFolder 字符串。因此,您应该将整个路径放在 outputFolder 字符串中,而不仅仅是其中的一部分,或者根据需要更改代码行为。

package PredatorPrey;

import java.io.File;

import repast.simphony.data2.engine.FileSinkComponentControllerAction;
import repast.simphony.data2.engine.FileSinkDescriptor;
import repast.simphony.engine.controller.NullAbstractControllerAction;
import repast.simphony.engine.environment.ControllerAction;
import repast.simphony.engine.environment.RunEnvironmentBuilder;
import repast.simphony.engine.environment.RunState;
import repast.simphony.scenario.ModelInitializer;
import repast.simphony.scenario.Scenario;
import repast.simphony.util.collections.Tree;

public class MyInitializer implements ModelInitializer {

      @Override
      public void initialize(final Scenario scen, RunEnvironmentBuilder builder) {

            scen.addMasterControllerAction(new NullAbstractControllerAction() {

            String rootContextID = "Predator Prey";
            String outputFolder = "testoutfolder";

                  @Override
                  public void batchInitialize(RunState runState, Object contextId) {

                        Tree<ControllerAction> scenarioTree = scen.getControllerRegistry().getActionTree(rootContextID);

                        findFileSinkTreeChildren(scenarioTree, scenarioTree.getRoot(), outputFolder);

                        // Reset the scenario dirty flag so the changes made to the file sink 
                        //  descriptors don't prompt a scenario save in the GUI
                        scen.setDirty(false);

                  }

            });
      }

      public static void findFileSinkTreeChildren(Tree<ControllerAction> tree, 
                  ControllerAction parent, String outputFolder){

            // Check each ControllerAction in the scenario and if it is a FileSink,
            //    modify the output path to include the folder
            for (ControllerAction act : tree.getChildren(parent)){
                  if (act instanceof FileSinkComponentControllerAction){
                        FileSinkDescriptor descriptor = ((FileSinkComponentControllerAction)act).getDescriptor();
                        String fileName = descriptor.getFileName();

                        //  remove any prefix directories from the file name
                        int lastSeparatorIndex = fileName.lastIndexOf(File.separator);

                        // Check for backslash separator
                        if (fileName.lastIndexOf('\') > lastSeparatorIndex)
                              lastSeparatorIndex = fileName.lastIndexOf('\');

                        // Check for forward slash operator
                        if (fileName.lastIndexOf('/') > lastSeparatorIndex)
                              lastSeparatorIndex = fileName.lastIndexOf('/');

                        if (lastSeparatorIndex > 0){
                              fileName = fileName.substring(lastSeparatorIndex+1, fileName.length());
                        }

                        descriptor.setFileName(outputFolder + File.separator + fileName);
                  }
                  else findFileSinkTreeChildren(tree, act, outputFolder);
            }
      }
}