ROOT logo
/**
 * @defgroup pwglf_forward_trains_helper Analysis helpers
 *
 * @ingroup pwglf_forward_trains
 * 
 * 
 */
/**
 * @file   Railway.C
 * @author Christian Holm Christensen <cholm@master.hehi.nbi.dk>
 * @date   Tue Oct 16 19:00:17 2012
 * 
 * @brief  Base class for analysis helpers
 * 
 * @ingroup pwglf_forward_trains_helper
 * 
 */
#ifndef TRAIN_HELPER_C
#define TRAIN_HELPER_C
#ifndef __CINT__
# include "Option.C"
# include <TUrl.h>
# include <TString.h>
# include <TMap.h>
# include <TObjString.h>
# include <TSystem.h>
# include <TROOT.h>
# include <TError.h>
# include <TObjArray.h>
# include <TFile.h>
# include <AliAnalysisManager.h>
# include <iostream>
#else 
class TString;
class TUrl;
class TMap;
class Option;
class OptionList;
#endif

/**
 * Helper class to set-up an analysis using a train 
 *
 * @ingroup pwglf_forward_trains_helper
 */
struct Railway 
{
  enum EMode { 
    kLocal, 
    kProof, 
    kGrid
  };
  enum EOperation { 
    kTest,
    kOffline,
    kSubmit,
    kTerminate, 
    kFull
  };
  enum EInput { 
    kESD, 
    kAOD, 
    kUser
  };
  Railway(const Railway& o) 
    : fUrl(o.fUrl), fOptions(o.fOptions), fVerbose(o.fVerbose)
  {}
  Railway& operator=(const Railway&) { return *this; }
  /** 
   * Create a helper object. 
   *
   * @param verbose Verbosity 
   * @param url Url describing the job. 
   *
   * - Local mode: 
   *
   * @code
   * local://<path>[#<treeName>][?[recursive[&]]]
   * @endcode 
   *
   * &lt;path&gt; can be a single ROOT file, a text file with one
   * entry per file to add to the chain, or a directory containing the
   * files. If &lt;path&gt; does not start with a '/' then it is
   * interpreted as a relative path.
   *
   * - Grid mode: 
   *
   * @code 
   * alien:///<path>#<pattern>
   * @endcode
   *
   * - PROOF mode: 
   * 
   * Several options 
   *
   * @code 
   * lite:///<path>[?[recursive[&]][workers=<n>]][#treeName]
   * proof:///<path>[?[recursive[&]][workers=<n>]][#treeName]
   * @endcode 
   *
   * @code 
   * proof://<host>/<dsname>[?[workers=<n>[&]][dsname[=<outname>]]][#treeName]
   * @endcode 
   *
   * Note, if &lt;host&gt; is recognised as an Alice Analysis
   * Facility, then the Grid handler (AliAnalysisAlien) is used unless
   * the option <tt>plain</tt> was given. 
   * 
   * @return Newly allocated helper or null 
   */
  static Railway* Create(const TUrl& url, Int_t verbose=0);
  /** 
   * Load a library 
   * 
   * @param name   Name of library 
   * @param slave  If true also load on slaves
   * 
   * @return true on success, false otherwise 
   */
  virtual Bool_t LoadLibrary(const TString& name, 
			     Bool_t slave=true) = 0;
  /** 
   * Load a source file, and compile it 
   * 
   * @param name Name of the source file 
   * @param copy Copy rather than link 
   * 
   * @return true on success
   */
  virtual Bool_t LoadSource(const TString& name, bool copy=false)
  {
    if (!AuxFile(name, copy)) return false;
    TString base(gSystem->BaseName(name));
    gROOT->ProcessLine("gSystem->RedirectOutput(\"build.log\",\"a\");");
    gROOT->LoadMacro(Form("%s++g", base.Data()));
    gROOT->ProcessLine("gSystem->RedirectOutput(0);");
    return true;
  }
  /** 
   * Load auxillary file - not compiled or sourced.  Just copied to
   * working directory
   * 
   * @param name Extra file name 
   * @param copy Copy rather than link 
   *
   * @return true on success 
   */
  virtual Bool_t LoadAux(const TString& name, Bool_t copy=false)
  {
    if (!AuxFile(name, copy)) return false;
    return true;
  }

  /** 
   * Load needed ROOT libaries 
   */
  virtual Bool_t LoadROOT()
  {
    if (gSystem->Load("libTree.so")    < 0) return false;
    if (gSystem->Load("libGeom.so")    < 0) return false;
    if (gSystem->Load("libVMC.so")     < 0) return false;
    if (gSystem->Load("libPhysics.so") < 0) return false;
    if (gSystem->Load("libMinuit.so")  < 0) return false;
    return true;
  }
  /** 
   * Set-up to load the AliROOT libraries 
   * 
   * @return true on success
   */
  virtual Bool_t LoadAliROOT()
  {
    if (!gSystem->Getenv("ALICE_ROOT")) { 
      Error("Railway::LoadAliROOT", "Local AliROOT not available");
      return false;
    }
    if (!LoadLibrary("STEERBase"))     return false;
    if (!LoadLibrary("ESD"))           return false;
    if (!LoadLibrary("AOD"))           return false;
    if (!LoadLibrary("ANALYSIS"))      return false;
    if (!LoadLibrary("OADB"))          return false;
    if (!LoadLibrary("ANALYSISalice")) return false;
    return true;
  }
  /** 
   * Get the execution mode 
   * 
   * @return Execution mode set in set-up URL
   */
  virtual UShort_t Mode() const = 0;
  /**
   * Get the mode string used for AliAnalysisManager::StartAnalysis
   */
  virtual const char* ModeString() const { return "unknown"; }
  /** 
   * Get the operation - this only makes sense for Grid jobs
   * 
   * @return Operation type
   */
  virtual UShort_t Operation() const { return kFull; }
  /** 
   * Get the input data type 
   *
   * @return Input data type 
   */
  virtual Short_t InputType() const
  {
    UShort_t ret = DeduceType(fUrl.GetAnchor());
    if (ret != kUser) return ret;

    if (fOptions.Has("pattern")) ret = DeduceType(fOptions.Get("pattern"));
    if (ret != kUser) return ret;
    
    ret = DeduceType(fUrl.GetFile());
    return ret;
  }
  /** 
   * Check if the MC option was set
   * 
   * @return true if the MC option was given 
   */
  virtual Bool_t IsMC() const { return fOptions.Has("mc"); }
  /** 
   * The file part of tehe output URL - overwritten by derived classes. 
   * 
   * 
   * @return File part of output URL
   */
  virtual TString OutputPath() const { return ""; }
  /** 
   * Get the location of the output data.  Use ful to define second pass 
   * scripts, etc. 
   * 
   * 
   * @return Url string 
   */
  virtual TString OutputLocation() const 
  {
    AliAnalysisManager* mgr = AliAnalysisManager::GetAnalysisManager();
    if (!mgr || !mgr->GetOutputEventHandler()) return "";

    TString path(OutputPath());
    if (path.IsNull()) {
      path = gSystem->WorkingDirectory(); 
      // mgr->GetName();
    }

    TUrl u(fUrl);
    u.SetFile(path);
    u.SetAnchor("aodTree");
    TString opt(u.GetOptions());
    // if (opt.Contains("AliESDs")) 
    opt.ReplaceAll("AliESDs", "AliAOD");
    // else                         opt.Append("&pattern=AliAOD*.root");
    u.SetOptions(opt);

    return u.GetUrl();
  }
  /** 
   * Set-up done before task setup 
   * 
   * @return true on success
   */
  virtual Bool_t PreSetup() = 0;
  /** 
   * Set-up done after task setup 
   * 
   * @return true on success
   */
  virtual Bool_t PostSetup() = 0;
  /** 
   * Run the analysis
   * 
   * @param nEvents Number of events to analyse 
   * 
   * @return The return value of AliAnalysisManager::StartAnalysis
   */
  virtual Long64_t Run(Long64_t nEvents=-1) = 0;
  /** 
   * Print information to standard output 
   * 
   * @return 
   */
  virtual void Print(Option_t* ="") const
  {
    std::cout << "Url: " << fUrl.GetUrl() << std::endl;
    fOptions.Show(std::cout);
  }
  /** 
   * @return URL help string 
   */
  virtual const Char_t* UrlHelp() const  = 0;
  /** 
   * @return Short description string 
   */
  virtual const char* Desc() const = 0;
  /** 
   * Get the input URL 
   * 
   * @return Input URL 
   */
  const TUrl& Url() const { return fUrl; }
  /** 
   * Get the list of options 
   * 
   * @return Reference to list of options 
   */
  const OptionList& Options() const { return fOptions; }
  /** 
   * Write auxillary ROOT (and possible shell) script for more 
   * (post-)processing e.g., terminate
   * 
   */
  virtual void AuxSave(const TString& /*escaped*/, 
		       Bool_t /*asShellScript*/) {}
  /** 
   * Create an instance of a helper class 
   */
  static Railway* CreateObject(const TString& cl, 
			      const TUrl&    url, 
			      Int_t verbose=0)
  {
    if (verbose < 3) gSystem->RedirectOutput("/dev/null","w");
    if (cl.Contains("proof", TString::kIgnoreCase) || 
	cl.Contains("lite",  TString::kIgnoreCase) || 
	cl.Contains("aaf",   TString::kIgnoreCase)) {
      gSystem->Load("libProof");
      gSystem->Load("libProofPlayer");
    }
    // (Always) recompile and with debug symbols 
    gROOT->LoadMacro(Form("%s.C++g",cl.Data()));
    Long_t ptr = gROOT->ProcessLine(Form("new %s(\"%s\", %d);", 
					 cl.Data(), url.GetUrl(), verbose));
    if (verbose < 3) gSystem->RedirectOutput(0);
    if (!ptr) { 
      Warning("Railway::CreateObject", "Failed to instantize a %s", cl.Data());
      return 0;
    }
    Railway* h = reinterpret_cast<Railway*>(ptr);
    return h;
  }
  /** 
   * Show help on URL using the interpreter 
   * 
   * @param cl Railway class 
   */
  static void ShowUrlHelp(const TString& cl)
  {
    Railway* h = CreateObject(cl, "", true);
    if (!h) return;

    std::cout << "   " << h->UrlHelp() << std::endl;
  }
  /** 
   * Show help on URL and options using the interpreter 
   * 
   * @param cl Railway class 
   */
  static void ShowFullHelp(const TString& cl) 
  {
    Railway* h = CreateObject(cl, "", true);
    if (!h) return;
    
    std::cout << h->Desc() << ":\n" 
	      << "==============\n"
	      << "  " << h->UrlHelp() << "\n\n"
	      << "Options: " << std::endl;
    h->Options().Help(std::cout);
    std::cout << std::endl;
  }
  /**
   * Add a monitor object - only for PROOF 
   */
  virtual Bool_t AddMonitor(const TString&) { return true; }
protected:
  /** 
   * Constructor 
   * 
   * @param url Set-up URL
   * @param verbose Verbosity level 
   */
  Railway(const TUrl& url, Int_t verbose) 
    : fUrl(url), fOptions(), fVerbose(verbose)
  {
    fOptions.Add("mc", "Assume simulation input");
  }

  virtual Bool_t ParseOptions()
  {
    //std::cout << "Url options: \"" << fUrl.GetOptions() << "\"" << std::endl;
    return fOptions.Parse(fUrl.GetOptions(), "&");
  }
  /** 
   * Destructor 
   */
  virtual ~Railway()
  {
  }
  /** 
   * Normalize a library name
   * 
   * @param name 
   * 
   * @return 
   */
  const TString& MakeLibraryName(const TString& name)
  {
    static TString libName;

    libName = name;

    if (!libName.BeginsWith("lib")) { 
      // Check if the library corresponds to a compiled macro 
      if (!gSystem->AccessPathName(Form("%s_C.so", libName.Data()))) 
	libName.Append("_C");
      else if (!gSystem->AccessPathName(Form("../%s_C.so", libName.Data()))) 
	libName = Form("../%s_C", libName.Data());
      else 
	libName = Form("lib%s", libName.Data());
    }
    if (!libName.EndsWith(".so"))   libName.Append(".so");

    return libName;
  }
  /** 
   * Link an auxilary file to working directory 
   * 
   * @param name Name of the file
   * @param copy Copy rather than link
   *
   * @return true on success
   */
  virtual Bool_t AuxFile(const TString& name, bool copy=false)
  {
    TString path(gSystem->ExpandPathName(name.Data()));
    // If not absolute, prepend up-one
    if (!path.BeginsWith("/")) path.Prepend("../");
    if (gSystem->AccessPathName(path.Data())) { 
      // File not accessible
      Warning("Railway::AuxFile", "File %s not accessible", path.Data());
      return false;
    }
    TString base(gSystem->BaseName(path.Data()));
    if (gSystem->AccessPathName(base.Data()) == 0) { 
      // File or link exists - remove it 
      if (gSystem->Unlink(base) != 0) { 
	Error("Railway::AuxFile", "Failed to remove old %s", base.Data());
	return false;
      }
    }
    if (copy) 
      TFile::Cp(path, base);
    else 
      gSystem->Exec(Form("ln -s %s .", path.Data()));
    return true;
  }
  /** 
   * Deduce the top of job from a string 
   * 
   * @param str String 
   * 
   * @return Job type
   */
  static UShort_t DeduceType(const TString& str)
  {
    if (str.IsNull()) return kUser;
    if (str.Contains("aod", TString::kIgnoreCase)) return kAOD;
    if (str.Contains("esd", TString::kIgnoreCase)) return kESD;
    return kUser;
  }
  // --- Data members ------------------------------------------------
  TUrl        fUrl;     // The URI
  OptionList  fOptions; 
  Int_t       fVerbose;
};




// ===================================================================
Railway* 
Railway::Create(const TUrl& url, Int_t verbose)
{
  if (!url.IsValid()) { 
    Warning("Railway::Create", "URL is invalid");
    return 0;
  }

  TString prot(url.GetProtocol());
  prot.ToLower();

  TUrl tmp(url);
  TString opts(tmp.GetOptions());
  TString host(url.GetHost());
  TString cl = "";
  if (prot.EqualTo("alien")) { 
    // Create an AliEn helper 
    cl = "GridRailway";
  }
  else if (prot.EqualTo("local")) { 
    // Create Lite helper 
    cl = "LocalRailway";
  }
  else if (prot.EqualTo("proof")) { 
    // Create a Proof helper 
    if (host.IsNull()) 
      cl = "LiteRailway";
    else if (host.BeginsWith("alice-caf")) { 
      // AAF 
      cl = opts.Contains("plugin") ? "AAFPluginRailway" : "AAFRailway";
    }
    else 
      cl = "ProofRailway";
  }
  else if (prot.EqualTo("lite")) { 
    // Create a Proof helper 
    cl = "LiteRailway";
  }
  else if (prot.EqualTo("help")) {
    // Special HELP protocol
    if (host.Contains("options")) {
      std::cout << "Possible URL types and options are:" << std::endl;
      ShowFullHelp("LocalRailway");
      ShowFullHelp("ProofRailway");
      ShowFullHelp("LiteRailway");
      ShowFullHelp("AAFRailway");
      ShowFullHelp("AAFPluginRailway");
      ShowFullHelp("GridRailway");
      return 0;
    }
    std::cout << "Possible URL types are:" << std::endl;
    ShowUrlHelp("LocalRailway");
    ShowUrlHelp("ProofRailway");
    ShowUrlHelp("LiteRailway");
    ShowUrlHelp("AAFRailway");
    ShowUrlHelp("AAFPluginRailway");
    ShowUrlHelp("GridRailway");
    return 0;
  }
  // --- Check if we got a scheme ------------------------------------
  if (cl.IsNull()) {
    Error("Railway::Create", "Unknown scheme: %s", prot.Data());
    return 0;
  }

  // --- Use interpreter to make our object --------------------------
  Railway* helper = CreateObject(cl, url, verbose);
  if (!helper) {
    Error("Railway::Create", "Failed to make object of class %s", cl.Data());
    return 0;
  }

  // --- Parse options -----------------------------------------------
  if (!helper->ParseOptions()) {
    delete helper;
    helper = 0;
  }

  return helper;
}

#endif
 Railway.C:1
 Railway.C:2
 Railway.C:3
 Railway.C:4
 Railway.C:5
 Railway.C:6
 Railway.C:7
 Railway.C:8
 Railway.C:9
 Railway.C:10
 Railway.C:11
 Railway.C:12
 Railway.C:13
 Railway.C:14
 Railway.C:15
 Railway.C:16
 Railway.C:17
 Railway.C:18
 Railway.C:19
 Railway.C:20
 Railway.C:21
 Railway.C:22
 Railway.C:23
 Railway.C:24
 Railway.C:25
 Railway.C:26
 Railway.C:27
 Railway.C:28
 Railway.C:29
 Railway.C:30
 Railway.C:31
 Railway.C:32
 Railway.C:33
 Railway.C:34
 Railway.C:35
 Railway.C:36
 Railway.C:37
 Railway.C:38
 Railway.C:39
 Railway.C:40
 Railway.C:41
 Railway.C:42
 Railway.C:43
 Railway.C:44
 Railway.C:45
 Railway.C:46
 Railway.C:47
 Railway.C:48
 Railway.C:49
 Railway.C:50
 Railway.C:51
 Railway.C:52
 Railway.C:53
 Railway.C:54
 Railway.C:55
 Railway.C:56
 Railway.C:57
 Railway.C:58
 Railway.C:59
 Railway.C:60
 Railway.C:61
 Railway.C:62
 Railway.C:63
 Railway.C:64
 Railway.C:65
 Railway.C:66
 Railway.C:67
 Railway.C:68
 Railway.C:69
 Railway.C:70
 Railway.C:71
 Railway.C:72
 Railway.C:73
 Railway.C:74
 Railway.C:75
 Railway.C:76
 Railway.C:77
 Railway.C:78
 Railway.C:79
 Railway.C:80
 Railway.C:81
 Railway.C:82
 Railway.C:83
 Railway.C:84
 Railway.C:85
 Railway.C:86
 Railway.C:87
 Railway.C:88
 Railway.C:89
 Railway.C:90
 Railway.C:91
 Railway.C:92
 Railway.C:93
 Railway.C:94
 Railway.C:95
 Railway.C:96
 Railway.C:97
 Railway.C:98
 Railway.C:99
 Railway.C:100
 Railway.C:101
 Railway.C:102
 Railway.C:103
 Railway.C:104
 Railway.C:105
 Railway.C:106
 Railway.C:107
 Railway.C:108
 Railway.C:109
 Railway.C:110
 Railway.C:111
 Railway.C:112
 Railway.C:113
 Railway.C:114
 Railway.C:115
 Railway.C:116
 Railway.C:117
 Railway.C:118
 Railway.C:119
 Railway.C:120
 Railway.C:121
 Railway.C:122
 Railway.C:123
 Railway.C:124
 Railway.C:125
 Railway.C:126
 Railway.C:127
 Railway.C:128
 Railway.C:129
 Railway.C:130
 Railway.C:131
 Railway.C:132
 Railway.C:133
 Railway.C:134
 Railway.C:135
 Railway.C:136
 Railway.C:137
 Railway.C:138
 Railway.C:139
 Railway.C:140
 Railway.C:141
 Railway.C:142
 Railway.C:143
 Railway.C:144
 Railway.C:145
 Railway.C:146
 Railway.C:147
 Railway.C:148
 Railway.C:149
 Railway.C:150
 Railway.C:151
 Railway.C:152
 Railway.C:153
 Railway.C:154
 Railway.C:155
 Railway.C:156
 Railway.C:157
 Railway.C:158
 Railway.C:159
 Railway.C:160
 Railway.C:161
 Railway.C:162
 Railway.C:163
 Railway.C:164
 Railway.C:165
 Railway.C:166
 Railway.C:167
 Railway.C:168
 Railway.C:169
 Railway.C:170
 Railway.C:171
 Railway.C:172
 Railway.C:173
 Railway.C:174
 Railway.C:175
 Railway.C:176
 Railway.C:177
 Railway.C:178
 Railway.C:179
 Railway.C:180
 Railway.C:181
 Railway.C:182
 Railway.C:183
 Railway.C:184
 Railway.C:185
 Railway.C:186
 Railway.C:187
 Railway.C:188
 Railway.C:189
 Railway.C:190
 Railway.C:191
 Railway.C:192
 Railway.C:193
 Railway.C:194
 Railway.C:195
 Railway.C:196
 Railway.C:197
 Railway.C:198
 Railway.C:199
 Railway.C:200
 Railway.C:201
 Railway.C:202
 Railway.C:203
 Railway.C:204
 Railway.C:205
 Railway.C:206
 Railway.C:207
 Railway.C:208
 Railway.C:209
 Railway.C:210
 Railway.C:211
 Railway.C:212
 Railway.C:213
 Railway.C:214
 Railway.C:215
 Railway.C:216
 Railway.C:217
 Railway.C:218
 Railway.C:219
 Railway.C:220
 Railway.C:221
 Railway.C:222
 Railway.C:223
 Railway.C:224
 Railway.C:225
 Railway.C:226
 Railway.C:227
 Railway.C:228
 Railway.C:229
 Railway.C:230
 Railway.C:231
 Railway.C:232
 Railway.C:233
 Railway.C:234
 Railway.C:235
 Railway.C:236
 Railway.C:237
 Railway.C:238
 Railway.C:239
 Railway.C:240
 Railway.C:241
 Railway.C:242
 Railway.C:243
 Railway.C:244
 Railway.C:245
 Railway.C:246
 Railway.C:247
 Railway.C:248
 Railway.C:249
 Railway.C:250
 Railway.C:251
 Railway.C:252
 Railway.C:253
 Railway.C:254
 Railway.C:255
 Railway.C:256
 Railway.C:257
 Railway.C:258
 Railway.C:259
 Railway.C:260
 Railway.C:261
 Railway.C:262
 Railway.C:263
 Railway.C:264
 Railway.C:265
 Railway.C:266
 Railway.C:267
 Railway.C:268
 Railway.C:269
 Railway.C:270
 Railway.C:271
 Railway.C:272
 Railway.C:273
 Railway.C:274
 Railway.C:275
 Railway.C:276
 Railway.C:277
 Railway.C:278
 Railway.C:279
 Railway.C:280
 Railway.C:281
 Railway.C:282
 Railway.C:283
 Railway.C:284
 Railway.C:285
 Railway.C:286
 Railway.C:287
 Railway.C:288
 Railway.C:289
 Railway.C:290
 Railway.C:291
 Railway.C:292
 Railway.C:293
 Railway.C:294
 Railway.C:295
 Railway.C:296
 Railway.C:297
 Railway.C:298
 Railway.C:299
 Railway.C:300
 Railway.C:301
 Railway.C:302
 Railway.C:303
 Railway.C:304
 Railway.C:305
 Railway.C:306
 Railway.C:307
 Railway.C:308
 Railway.C:309
 Railway.C:310
 Railway.C:311
 Railway.C:312
 Railway.C:313
 Railway.C:314
 Railway.C:315
 Railway.C:316
 Railway.C:317
 Railway.C:318
 Railway.C:319
 Railway.C:320
 Railway.C:321
 Railway.C:322
 Railway.C:323
 Railway.C:324
 Railway.C:325
 Railway.C:326
 Railway.C:327
 Railway.C:328
 Railway.C:329
 Railway.C:330
 Railway.C:331
 Railway.C:332
 Railway.C:333
 Railway.C:334
 Railway.C:335
 Railway.C:336
 Railway.C:337
 Railway.C:338
 Railway.C:339
 Railway.C:340
 Railway.C:341
 Railway.C:342
 Railway.C:343
 Railway.C:344
 Railway.C:345
 Railway.C:346
 Railway.C:347
 Railway.C:348
 Railway.C:349
 Railway.C:350
 Railway.C:351
 Railway.C:352
 Railway.C:353
 Railway.C:354
 Railway.C:355
 Railway.C:356
 Railway.C:357
 Railway.C:358
 Railway.C:359
 Railway.C:360
 Railway.C:361
 Railway.C:362
 Railway.C:363
 Railway.C:364
 Railway.C:365
 Railway.C:366
 Railway.C:367
 Railway.C:368
 Railway.C:369
 Railway.C:370
 Railway.C:371
 Railway.C:372
 Railway.C:373
 Railway.C:374
 Railway.C:375
 Railway.C:376
 Railway.C:377
 Railway.C:378
 Railway.C:379
 Railway.C:380
 Railway.C:381
 Railway.C:382
 Railway.C:383
 Railway.C:384
 Railway.C:385
 Railway.C:386
 Railway.C:387
 Railway.C:388
 Railway.C:389
 Railway.C:390
 Railway.C:391
 Railway.C:392
 Railway.C:393
 Railway.C:394
 Railway.C:395
 Railway.C:396
 Railway.C:397
 Railway.C:398
 Railway.C:399
 Railway.C:400
 Railway.C:401
 Railway.C:402
 Railway.C:403
 Railway.C:404
 Railway.C:405
 Railway.C:406
 Railway.C:407
 Railway.C:408
 Railway.C:409
 Railway.C:410
 Railway.C:411
 Railway.C:412
 Railway.C:413
 Railway.C:414
 Railway.C:415
 Railway.C:416
 Railway.C:417
 Railway.C:418
 Railway.C:419
 Railway.C:420
 Railway.C:421
 Railway.C:422
 Railway.C:423
 Railway.C:424
 Railway.C:425
 Railway.C:426
 Railway.C:427
 Railway.C:428
 Railway.C:429
 Railway.C:430
 Railway.C:431
 Railway.C:432
 Railway.C:433
 Railway.C:434
 Railway.C:435
 Railway.C:436
 Railway.C:437
 Railway.C:438
 Railway.C:439
 Railway.C:440
 Railway.C:441
 Railway.C:442
 Railway.C:443
 Railway.C:444
 Railway.C:445
 Railway.C:446
 Railway.C:447
 Railway.C:448
 Railway.C:449
 Railway.C:450
 Railway.C:451
 Railway.C:452
 Railway.C:453
 Railway.C:454
 Railway.C:455
 Railway.C:456
 Railway.C:457
 Railway.C:458
 Railway.C:459
 Railway.C:460
 Railway.C:461
 Railway.C:462
 Railway.C:463
 Railway.C:464
 Railway.C:465
 Railway.C:466
 Railway.C:467
 Railway.C:468
 Railway.C:469
 Railway.C:470
 Railway.C:471
 Railway.C:472
 Railway.C:473
 Railway.C:474
 Railway.C:475
 Railway.C:476
 Railway.C:477
 Railway.C:478
 Railway.C:479
 Railway.C:480
 Railway.C:481
 Railway.C:482
 Railway.C:483
 Railway.C:484
 Railway.C:485
 Railway.C:486
 Railway.C:487
 Railway.C:488
 Railway.C:489
 Railway.C:490
 Railway.C:491
 Railway.C:492
 Railway.C:493
 Railway.C:494
 Railway.C:495
 Railway.C:496
 Railway.C:497
 Railway.C:498
 Railway.C:499
 Railway.C:500
 Railway.C:501
 Railway.C:502
 Railway.C:503
 Railway.C:504
 Railway.C:505
 Railway.C:506
 Railway.C:507
 Railway.C:508
 Railway.C:509
 Railway.C:510
 Railway.C:511
 Railway.C:512
 Railway.C:513
 Railway.C:514
 Railway.C:515
 Railway.C:516
 Railway.C:517
 Railway.C:518
 Railway.C:519
 Railway.C:520
 Railway.C:521
 Railway.C:522
 Railway.C:523
 Railway.C:524
 Railway.C:525
 Railway.C:526
 Railway.C:527
 Railway.C:528
 Railway.C:529
 Railway.C:530
 Railway.C:531
 Railway.C:532
 Railway.C:533
 Railway.C:534
 Railway.C:535
 Railway.C:536
 Railway.C:537
 Railway.C:538
 Railway.C:539
 Railway.C:540
 Railway.C:541
 Railway.C:542
 Railway.C:543
 Railway.C:544
 Railway.C:545
 Railway.C:546
 Railway.C:547
 Railway.C:548
 Railway.C:549
 Railway.C:550
 Railway.C:551
 Railway.C:552
 Railway.C:553
 Railway.C:554
 Railway.C:555
 Railway.C:556
 Railway.C:557
 Railway.C:558
 Railway.C:559
 Railway.C:560
 Railway.C:561
 Railway.C:562
 Railway.C:563